Files
linux/drivers/gpu/drm/i915/intel_display.c

16602 lines
463 KiB
C
Raw Normal View History

/*
* Copyright © 2006-2007 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 <eric@anholt.net>
*/
#include <linux/dmi.h>
#include <linux/module.h>
#include <linux/input.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h percpu.h is included by sched.h and module.h and thus ends up being included when building most .c files. percpu.h includes slab.h which in turn includes gfp.h making everything defined by the two files universally available and complicating inclusion dependencies. percpu.h -> slab.h dependency is about to be removed. Prepare for this change by updating users of gfp and slab facilities include those headers directly instead of assuming availability. As this conversion needs to touch large number of source files, the following script is used as the basis of conversion. http://userweb.kernel.org/~tj/misc/slabh-sweep.py The script does the followings. * Scan files for gfp and slab usages and update includes such that only the necessary includes are there. ie. if only gfp is used, gfp.h, if slab is used, slab.h. * When the script inserts a new include, it looks at the include blocks and try to put the new include such that its order conforms to its surrounding. It's put in the include block which contains core kernel includes, in the same order that the rest are ordered - alphabetical, Christmas tree, rev-Xmas-tree or at the end if there doesn't seem to be any matching order. * If the script can't find a place to put a new include (mostly because the file doesn't have fitting include block), it prints out an error message indicating which .h file needs to be added to the file. The conversion was done in the following steps. 1. The initial automatic conversion of all .c files updated slightly over 4000 files, deleting around 700 includes and adding ~480 gfp.h and ~3000 slab.h inclusions. The script emitted errors for ~400 files. 2. Each error was manually checked. Some didn't need the inclusion, some needed manual addition while adding it to implementation .h or embedding .c file was more appropriate for others. This step added inclusions to around 150 files. 3. The script was run again and the output was compared to the edits from #2 to make sure no file was left behind. 4. Several build tests were done and a couple of problems were fixed. e.g. lib/decompress_*.c used malloc/free() wrappers around slab APIs requiring slab.h to be added manually. 5. The script was run on all .h files but without automatically editing them as sprinkling gfp.h and slab.h inclusions around .h files could easily lead to inclusion dependency hell. Most gfp.h inclusion directives were ignored as stuff from gfp.h was usually wildly available and often used in preprocessor macros. Each slab.h inclusion directive was examined and added manually as necessary. 6. percpu.h was updated not to include slab.h. 7. Build test were done on the following configurations and failures were fixed. CONFIG_GCOV_KERNEL was turned off for all tests (as my distributed build env didn't work with gcov compiles) and a few more options had to be turned off depending on archs to make things build (like ipr on powerpc/64 which failed due to missing writeq). * x86 and x86_64 UP and SMP allmodconfig and a custom test config. * powerpc and powerpc64 SMP allmodconfig * sparc and sparc64 SMP allmodconfig * ia64 SMP allmodconfig * s390 SMP allmodconfig * alpha SMP allmodconfig * um on x86_64 SMP allmodconfig 8. percpu.h modifications were reverted so that it could be applied as a separate patch and serve as bisection point. Given the fact that I had only a couple of failures from tests on step 6, I'm fairly confident about the coverage of this conversion patch. If there is a breakage, it's likely to be something in one of the arch headers which should be easily discoverable easily on most builds of the specific arch. Signed-off-by: Tejun Heo <tj@kernel.org> Guess-its-ok-by: Christoph Lameter <cl@linux-foundation.org> Cc: Ingo Molnar <mingo@redhat.com> Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>
2010-03-24 17:04:11 +09:00
#include <linux/slab.h>
#include <linux/vgaarb.h>
drm/i915: pass ELD to HDMI/DP audio driver Add ELD support for Intel Eaglelake, IbexPeak/Ironlake, SandyBridge/CougarPoint and IvyBridge/PantherPoint chips. ELD (EDID-Like Data) describes to the HDMI/DP audio driver the audio capabilities of the plugged monitor. It's built and passed to audio driver in 2 steps: (1) at get_modes time, parse EDID and save ELD to drm_connector.eld[] (2) at mode_set time, write drm_connector.eld[] to the Transcoder's hw ELD buffer and set the ELD_valid bit to inform HDMI/DP audio driver This patch is tested OK on G45/HDMI, IbexPeak/HDMI and IvyBridge/HDMI+DP. Test scheme: plug in the HDMI/DP monitor, and run cat /proc/asound/card0/eld* to check if the monitor name, HDMI/DP type, etc. show up correctly. Minor imperfection: the GEN5_AUD_CNTL_ST/DIP_Port_Select field always reads 0 (reserved). Without knowing the port number, I worked it around by setting the ELD_valid bit for ALL the three ports. It's tested to not be a problem, because the audio driver will find invalid ELD data and hence rightfully abort, even when it sees the ELD_valid indicator. Thanks to Zhenyu and Pierre-Louis for a lot of valuable help and testing. CC: Zhao Yakui <yakui.zhao@intel.com> CC: Wang Zhenyu <zhenyu.z.wang@intel.com> CC: Jeremy Bush <contractfrombelow@gmail.com> CC: Christopher White <c.white@pulseforce.com> CC: Pierre-Louis Bossart <pierre-louis.bossart@intel.com> CC: Paul Menzel <paulepanter@users.sourceforge.net> Signed-off-by: Wu Fengguang <fengguang.wu@intel.com> Signed-off-by: Keith Packard <keithp@keithp.com>
2011-09-05 14:25:34 +08:00
#include <drm/drm_edid.h>
#include <drm/drmP.h>
#include "intel_drv.h"
#include <drm/i915_drm.h>
#include "i915_drv.h"
#include "i915_gem_dmabuf.h"
2016-03-24 12:41:40 +02:00
#include "intel_dsi.h"
#include "i915_trace.h"
drm/i915: Ensure plane->state->fb stays in sync with plane->fb plane->state->fb and plane->fb should always reference the same FB so that atomic and legacy codepaths have the same view of display state. However, there are some places in kernel code that directly set plane->fb and neglect to update plane->state->fb. If we never do a successful update through the atomic pipeline, the RmFB cleanup code will look at the plane->state->fb pointer, which has never actually been set to a legitimate value, and try to clean it up, leading to BUG's. Add a quick helper function to synchronize plane->state->fb with plane->fb and call it everywhere the driver tries to manually set plane->fb outside of the atomic pipeline. In this function, use drm_atomic_set_fb_for_plane instead of writing plane->state->fb directly to keep the reference count right. This is modified from Matt Roper's patch to drm-intel-nightly with commit id commit afd65eb4cc0578a9c07d621acdb8a570e2782bf7 Author: Matt Roper <matthew.d.roper@intel.com> Date: Tue Feb 3 13:10:04 2015 -0800 drm/i915: Ensure plane->state->fb stays in sync with plane->fb However this bug exists in mainline kernel too, so I created this to fix it in mainline kernel. A minor change is to use drm_atomic_set_fb_for_plane instead of update reference count manually. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=88909 Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=93711 Signed-off-by: Xi Ruoyao <xry111@outlook.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> [Jani: included the patch notes in the commit message] Signed-off-by: Jani Nikula <jani.nikula@intel.com>
2015-03-12 20:16:32 +08:00
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_dp_helper.h>
#include <drm/drm_crtc_helper.h>
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
#include <drm/drm_plane_helper.h>
#include <drm/drm_rect.h>
#include <linux/dma_remapping.h>
#include <linux/reservation.h>
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
static bool is_mmio_work(struct intel_flip_work *work)
{
return work->mmio_work.func;
}
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
/* Primary plane formats for gen <= 3 */
static const uint32_t i8xx_primary_formats[] = {
DRM_FORMAT_C8,
DRM_FORMAT_RGB565,
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
DRM_FORMAT_XRGB1555,
DRM_FORMAT_XRGB8888,
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
};
/* Primary plane formats for gen >= 4 */
static const uint32_t i965_primary_formats[] = {
DRM_FORMAT_C8,
DRM_FORMAT_RGB565,
DRM_FORMAT_XRGB8888,
DRM_FORMAT_XBGR8888,
DRM_FORMAT_XRGB2101010,
DRM_FORMAT_XBGR2101010,
};
static const uint32_t skl_primary_formats[] = {
DRM_FORMAT_C8,
DRM_FORMAT_RGB565,
DRM_FORMAT_XRGB8888,
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
DRM_FORMAT_XBGR8888,
DRM_FORMAT_ARGB8888,
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
DRM_FORMAT_ABGR8888,
DRM_FORMAT_XRGB2101010,
DRM_FORMAT_XBGR2101010,
DRM_FORMAT_YUYV,
DRM_FORMAT_YVYU,
DRM_FORMAT_UYVY,
DRM_FORMAT_VYUY,
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
};
drm/i915: Switch to unified plane cursor handling (v4) The DRM core will translate calls to legacy cursor ioctls into universal cursor calls automatically, so there's no need to maintain the legacy cursor support. This greatly simplifies the transition since we don't have to handle reference counting differently depending on which cursor interface was called. The aim here is to transition to the universal plane interface with minimal code change. There's a lot of cleanup that can be done (e.g., using state stored in crtc->cursor->fb rather than intel_crtc) that is left to future patches. v4: - Drop drm_gem_object_unreference() that is no longer needed now that we receive the GEM obj directly rather than looking up the ID. v3: - Pass cursor obj to intel_crtc_cursor_set_obj() if cursor fb changes, even if 'visible' is false. intel_crtc_cursor_set_obj() will notice that the cursor isn't visible and disable it properly, but we still need to get intel_crtc->cursor_addr set properly so that we behave properly if the cursor becomes visible again in the future without changing the cursor buffer (noted by Chris Wilson and verified via i-g-t kms_cursor_crc). - s/drm_plane_init/drm_universal_plane_init/. Due to type compatibility between enum and bool, everything actually works correctly with the wrong init call, except for the type of plane that gets exposed to userspace (it shows up as type 'primary' rather than type 'cursor'). v2: - Remove duplicate dimension checks on cursor - Drop explicit cursor disable from crtc destroy (fb & plane destruction will take care of that now) - Use DRM plane helper to check update parameters Cc: intel-gfx@lists.freedesktop.org Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Pallavi G<pallavi.g@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-10 08:28:13 -07:00
/* Cursor formats */
static const uint32_t intel_cursor_formats[] = {
DRM_FORMAT_ARGB8888,
};
static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config);
static void ironlake_pch_clock_get(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config);
static 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);
static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc);
static void intel_set_pipe_timings(struct intel_crtc *intel_crtc);
static void intel_set_pipe_src_size(struct intel_crtc *intel_crtc);
static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc,
struct intel_link_m_n *m_n,
struct intel_link_m_n *m2_n2);
static void ironlake_set_pipeconf(struct drm_crtc *crtc);
static void haswell_set_pipeconf(struct drm_crtc *crtc);
static void haswell_set_pipemisc(struct drm_crtc *crtc);
static void vlv_prepare_pll(struct intel_crtc *crtc,
const struct intel_crtc_state *pipe_config);
static void chv_prepare_pll(struct intel_crtc *crtc,
const struct intel_crtc_state *pipe_config);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
static void intel_begin_crtc_commit(struct drm_crtc *, struct drm_crtc_state *);
static void intel_finish_crtc_commit(struct drm_crtc *, struct drm_crtc_state *);
static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_crtc,
struct intel_crtc_state *crtc_state);
static void skylake_pfit_enable(struct intel_crtc *crtc);
static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force);
static void ironlake_pfit_enable(struct intel_crtc *crtc);
static void intel_modeset_setup_hw_state(struct drm_device *dev);
static void intel_pre_disable_primary_noatomic(struct drm_crtc *crtc);
static int ilk_max_pixel_rate(struct drm_atomic_state *state);
static int bxt_calc_cdclk(int max_pixclk);
struct intel_limit {
struct {
int min, max;
} dot, vco, n, m, m1, m2, p, p1;
struct {
int dot_limit;
int p2_slow, p2_fast;
} p2;
};
/* returns HPLL frequency in kHz */
static int valleyview_get_vco(struct drm_i915_private *dev_priv)
{
int hpll_freq, vco_freq[] = { 800, 1600, 2000, 2400 };
/* Obtain SKU information */
mutex_lock(&dev_priv->sb_lock);
hpll_freq = vlv_cck_read(dev_priv, CCK_FUSE_REG) &
CCK_FUSE_HPLL_FREQ_MASK;
mutex_unlock(&dev_priv->sb_lock);
return vco_freq[hpll_freq] * 1000;
}
int vlv_get_cck_clock(struct drm_i915_private *dev_priv,
const char *name, u32 reg, int ref_freq)
{
u32 val;
int divider;
mutex_lock(&dev_priv->sb_lock);
val = vlv_cck_read(dev_priv, reg);
mutex_unlock(&dev_priv->sb_lock);
divider = val & CCK_FREQUENCY_VALUES;
WARN((val & CCK_FREQUENCY_STATUS) !=
(divider << CCK_FREQUENCY_STATUS_SHIFT),
"%s change in progress\n", name);
return DIV_ROUND_CLOSEST(ref_freq << 1, divider + 1);
}
static int vlv_get_cck_clock_hpll(struct drm_i915_private *dev_priv,
const char *name, u32 reg)
{
if (dev_priv->hpll_freq == 0)
dev_priv->hpll_freq = valleyview_get_vco(dev_priv);
return vlv_get_cck_clock(dev_priv, name, reg,
dev_priv->hpll_freq);
}
static int
intel_pch_rawclk(struct drm_i915_private *dev_priv)
{
return (I915_READ(PCH_RAWCLK_FREQ) & RAWCLK_FREQ_MASK) * 1000;
}
static int
intel_vlv_hrawclk(struct drm_i915_private *dev_priv)
{
/* RAWCLK_FREQ_VLV register updated from power well code */
return vlv_get_cck_clock_hpll(dev_priv, "hrawclk",
CCK_DISPLAY_REF_CLOCK_CONTROL);
}
static int
intel_g4x_hrawclk(struct drm_i915_private *dev_priv)
{
uint32_t clkcfg;
/* hrawclock is 1/4 the FSB frequency */
clkcfg = I915_READ(CLKCFG);
switch (clkcfg & CLKCFG_FSB_MASK) {
case CLKCFG_FSB_400:
return 100000;
case CLKCFG_FSB_533:
return 133333;
case CLKCFG_FSB_667:
return 166667;
case CLKCFG_FSB_800:
return 200000;
case CLKCFG_FSB_1067:
return 266667;
case CLKCFG_FSB_1333:
return 333333;
/* these two are just a guess; one of them might be right */
case CLKCFG_FSB_1600:
case CLKCFG_FSB_1600_ALT:
return 400000;
default:
return 133333;
}
}
void intel_update_rawclk(struct drm_i915_private *dev_priv)
{
if (HAS_PCH_SPLIT(dev_priv))
dev_priv->rawclk_freq = intel_pch_rawclk(dev_priv);
else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
dev_priv->rawclk_freq = intel_vlv_hrawclk(dev_priv);
else if (IS_G4X(dev_priv) || IS_PINEVIEW(dev_priv))
dev_priv->rawclk_freq = intel_g4x_hrawclk(dev_priv);
else
return; /* no rawclk on other platforms, or no need to know it */
DRM_DEBUG_DRIVER("rawclk rate: %d kHz\n", dev_priv->rawclk_freq);
}
static void intel_update_czclk(struct drm_i915_private *dev_priv)
{
if (!(IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)))
return;
dev_priv->czclk_freq = vlv_get_cck_clock_hpll(dev_priv, "czclk",
CCK_CZ_CLOCK_CONTROL);
DRM_DEBUG_DRIVER("CZ clock rate: %d kHz\n", dev_priv->czclk_freq);
}
static inline u32 /* units of 100MHz */
intel_fdi_link_freq(struct drm_i915_private *dev_priv,
const struct intel_crtc_state *pipe_config)
{
if (HAS_DDI(dev_priv))
return pipe_config->port_clock; /* SPLL */
else if (IS_GEN5(dev_priv))
return ((I915_READ(FDI_PLL_BIOS_0) & FDI_PLL_FB_CLOCK_MASK) + 2) * 10000;
else
return 270000;
}
static const struct intel_limit intel_limits_i8xx_dac = {
.dot = { .min = 25000, .max = 350000 },
.vco = { .min = 908000, .max = 1512000 },
.n = { .min = 2, .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 = 2 },
};
static const struct intel_limit intel_limits_i8xx_dvo = {
.dot = { .min = 25000, .max = 350000 },
.vco = { .min = 908000, .max = 1512000 },
.n = { .min = 2, .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 struct intel_limit intel_limits_i8xx_lvds = {
.dot = { .min = 25000, .max = 350000 },
.vco = { .min = 908000, .max = 1512000 },
.n = { .min = 2, .max = 16 },
.m = { .min = 96, .max = 140 },
.m1 = { .min = 18, .max = 26 },
.m2 = { .min = 6, .max = 16 },
.p = { .min = 4, .max = 128 },
.p1 = { .min = 1, .max = 6 },
.p2 = { .dot_limit = 165000,
.p2_slow = 14, .p2_fast = 7 },
};
static const struct intel_limit intel_limits_i9xx_sdvo = {
.dot = { .min = 20000, .max = 400000 },
.vco = { .min = 1400000, .max = 2800000 },
.n = { .min = 1, .max = 6 },
.m = { .min = 70, .max = 120 },
.m1 = { .min = 8, .max = 18 },
.m2 = { .min = 3, .max = 7 },
.p = { .min = 5, .max = 80 },
.p1 = { .min = 1, .max = 8 },
.p2 = { .dot_limit = 200000,
.p2_slow = 10, .p2_fast = 5 },
};
static const struct intel_limit intel_limits_i9xx_lvds = {
.dot = { .min = 20000, .max = 400000 },
.vco = { .min = 1400000, .max = 2800000 },
.n = { .min = 1, .max = 6 },
.m = { .min = 70, .max = 120 },
.m1 = { .min = 8, .max = 18 },
.m2 = { .min = 3, .max = 7 },
.p = { .min = 7, .max = 98 },
.p1 = { .min = 1, .max = 8 },
.p2 = { .dot_limit = 112000,
.p2_slow = 14, .p2_fast = 7 },
};
static const struct intel_limit intel_limits_g4x_sdvo = {
.dot = { .min = 25000, .max = 270000 },
.vco = { .min = 1750000, .max = 3500000},
.n = { .min = 1, .max = 4 },
.m = { .min = 104, .max = 138 },
.m1 = { .min = 17, .max = 23 },
.m2 = { .min = 5, .max = 11 },
.p = { .min = 10, .max = 30 },
.p1 = { .min = 1, .max = 3},
.p2 = { .dot_limit = 270000,
.p2_slow = 10,
.p2_fast = 10
},
};
static const struct intel_limit intel_limits_g4x_hdmi = {
.dot = { .min = 22000, .max = 400000 },
.vco = { .min = 1750000, .max = 3500000},
.n = { .min = 1, .max = 4 },
.m = { .min = 104, .max = 138 },
.m1 = { .min = 16, .max = 23 },
.m2 = { .min = 5, .max = 11 },
.p = { .min = 5, .max = 80 },
.p1 = { .min = 1, .max = 8},
.p2 = { .dot_limit = 165000,
.p2_slow = 10, .p2_fast = 5 },
};
static const struct intel_limit intel_limits_g4x_single_channel_lvds = {
.dot = { .min = 20000, .max = 115000 },
.vco = { .min = 1750000, .max = 3500000 },
.n = { .min = 1, .max = 3 },
.m = { .min = 104, .max = 138 },
.m1 = { .min = 17, .max = 23 },
.m2 = { .min = 5, .max = 11 },
.p = { .min = 28, .max = 112 },
.p1 = { .min = 2, .max = 8 },
.p2 = { .dot_limit = 0,
.p2_slow = 14, .p2_fast = 14
},
};
static const struct intel_limit intel_limits_g4x_dual_channel_lvds = {
.dot = { .min = 80000, .max = 224000 },
.vco = { .min = 1750000, .max = 3500000 },
.n = { .min = 1, .max = 3 },
.m = { .min = 104, .max = 138 },
.m1 = { .min = 17, .max = 23 },
.m2 = { .min = 5, .max = 11 },
.p = { .min = 14, .max = 42 },
.p1 = { .min = 2, .max = 6 },
.p2 = { .dot_limit = 0,
.p2_slow = 7, .p2_fast = 7
},
};
static const struct intel_limit intel_limits_pineview_sdvo = {
.dot = { .min = 20000, .max = 400000},
.vco = { .min = 1700000, .max = 3500000 },
/* Pineview's Ncounter is a ring counter */
.n = { .min = 3, .max = 6 },
.m = { .min = 2, .max = 256 },
/* Pineview only has one combined m divider, which we treat as m2. */
.m1 = { .min = 0, .max = 0 },
.m2 = { .min = 0, .max = 254 },
.p = { .min = 5, .max = 80 },
.p1 = { .min = 1, .max = 8 },
.p2 = { .dot_limit = 200000,
.p2_slow = 10, .p2_fast = 5 },
};
static const struct intel_limit intel_limits_pineview_lvds = {
.dot = { .min = 20000, .max = 400000 },
.vco = { .min = 1700000, .max = 3500000 },
.n = { .min = 3, .max = 6 },
.m = { .min = 2, .max = 256 },
.m1 = { .min = 0, .max = 0 },
.m2 = { .min = 0, .max = 254 },
.p = { .min = 7, .max = 112 },
.p1 = { .min = 1, .max = 8 },
.p2 = { .dot_limit = 112000,
.p2_slow = 14, .p2_fast = 14 },
};
/* Ironlake / Sandybridge
*
* We calculate clock using (register_value + 2) for N/M1/M2, so here
* the range value for them is (actual_value - 2).
*/
static const struct intel_limit intel_limits_ironlake_dac = {
.dot = { .min = 25000, .max = 350000 },
.vco = { .min = 1760000, .max = 3510000 },
.n = { .min = 1, .max = 5 },
.m = { .min = 79, .max = 127 },
.m1 = { .min = 12, .max = 22 },
.m2 = { .min = 5, .max = 9 },
.p = { .min = 5, .max = 80 },
.p1 = { .min = 1, .max = 8 },
.p2 = { .dot_limit = 225000,
.p2_slow = 10, .p2_fast = 5 },
};
static const struct intel_limit intel_limits_ironlake_single_lvds = {
.dot = { .min = 25000, .max = 350000 },
.vco = { .min = 1760000, .max = 3510000 },
.n = { .min = 1, .max = 3 },
.m = { .min = 79, .max = 118 },
.m1 = { .min = 12, .max = 22 },
.m2 = { .min = 5, .max = 9 },
.p = { .min = 28, .max = 112 },
.p1 = { .min = 2, .max = 8 },
.p2 = { .dot_limit = 225000,
.p2_slow = 14, .p2_fast = 14 },
};
static const struct intel_limit intel_limits_ironlake_dual_lvds = {
.dot = { .min = 25000, .max = 350000 },
.vco = { .min = 1760000, .max = 3510000 },
.n = { .min = 1, .max = 3 },
.m = { .min = 79, .max = 127 },
.m1 = { .min = 12, .max = 22 },
.m2 = { .min = 5, .max = 9 },
.p = { .min = 14, .max = 56 },
.p1 = { .min = 2, .max = 8 },
.p2 = { .dot_limit = 225000,
.p2_slow = 7, .p2_fast = 7 },
};
/* LVDS 100mhz refclk limits. */
static const struct intel_limit intel_limits_ironlake_single_lvds_100m = {
.dot = { .min = 25000, .max = 350000 },
.vco = { .min = 1760000, .max = 3510000 },
.n = { .min = 1, .max = 2 },
.m = { .min = 79, .max = 126 },
.m1 = { .min = 12, .max = 22 },
.m2 = { .min = 5, .max = 9 },
.p = { .min = 28, .max = 112 },
.p1 = { .min = 2, .max = 8 },
.p2 = { .dot_limit = 225000,
.p2_slow = 14, .p2_fast = 14 },
};
static const struct intel_limit intel_limits_ironlake_dual_lvds_100m = {
.dot = { .min = 25000, .max = 350000 },
.vco = { .min = 1760000, .max = 3510000 },
.n = { .min = 1, .max = 3 },
.m = { .min = 79, .max = 126 },
.m1 = { .min = 12, .max = 22 },
.m2 = { .min = 5, .max = 9 },
.p = { .min = 14, .max = 42 },
.p1 = { .min = 2, .max = 6 },
.p2 = { .dot_limit = 225000,
.p2_slow = 7, .p2_fast = 7 },
};
static const struct intel_limit intel_limits_vlv = {
/*
* These are the data rate limits (measured in fast clocks)
* since those are the strictest limits we have. The fast
* clock and actual rate limits are more relaxed, so checking
* them would make no difference.
*/
.dot = { .min = 25000 * 5, .max = 270000 * 5 },
.vco = { .min = 4000000, .max = 6000000 },
.n = { .min = 1, .max = 7 },
.m1 = { .min = 2, .max = 3 },
.m2 = { .min = 11, .max = 156 },
.p1 = { .min = 2, .max = 3 },
.p2 = { .p2_slow = 2, .p2_fast = 20 }, /* slow=min, fast=max */
};
static const struct intel_limit intel_limits_chv = {
/*
* These are the data rate limits (measured in fast clocks)
* since those are the strictest limits we have. The fast
* clock and actual rate limits are more relaxed, so checking
* them would make no difference.
*/
.dot = { .min = 25000 * 5, .max = 540000 * 5},
.vco = { .min = 4800000, .max = 6480000 },
.n = { .min = 1, .max = 1 },
.m1 = { .min = 2, .max = 2 },
.m2 = { .min = 24 << 22, .max = 175 << 22 },
.p1 = { .min = 2, .max = 4 },
.p2 = { .p2_slow = 1, .p2_fast = 14 },
};
static const struct intel_limit intel_limits_bxt = {
/* FIXME: find real dot limits */
.dot = { .min = 0, .max = INT_MAX },
.vco = { .min = 4800000, .max = 6700000 },
.n = { .min = 1, .max = 1 },
.m1 = { .min = 2, .max = 2 },
/* FIXME: find real m2 limits */
.m2 = { .min = 2 << 22, .max = 255 << 22 },
.p1 = { .min = 2, .max = 4 },
.p2 = { .p2_slow = 1, .p2_fast = 20 },
};
static bool
needs_modeset(struct drm_crtc_state *state)
{
return drm_atomic_crtc_needs_modeset(state);
}
/**
* Returns whether any output on the specified pipe is of the specified type
*/
bool intel_pipe_has_type(struct intel_crtc *crtc, enum intel_output_type type)
{
struct drm_device *dev = crtc->base.dev;
struct intel_encoder *encoder;
for_each_encoder_on_crtc(dev, &crtc->base, encoder)
if (encoder->type == type)
return true;
return false;
}
/**
* Returns whether any output on the specified pipe will have the specified
* type after a staged modeset is complete, i.e., the same as
* intel_pipe_has_type() but looking at encoder->new_crtc instead of
* encoder->crtc.
*/
static bool intel_pipe_will_have_type(const struct intel_crtc_state *crtc_state,
int type)
{
struct drm_atomic_state *state = crtc_state->base.state;
struct drm_connector *connector;
struct drm_connector_state *connector_state;
struct intel_encoder *encoder;
int i, num_connectors = 0;
for_each_connector_in_state(state, connector, connector_state, i) {
if (connector_state->crtc != crtc_state->base.crtc)
continue;
num_connectors++;
encoder = to_intel_encoder(connector_state->best_encoder);
if (encoder->type == type)
return true;
}
WARN_ON(num_connectors == 0);
return false;
}
/*
* Platform specific helpers to calculate the port PLL loopback- (clock.m),
* and post-divider (clock.p) values, pre- (clock.vco) and post-divided fast
* (clock.dot) clock rates. This fast dot clock is fed to the port's IO logic.
* The helpers' return value is the rate of the clock that is fed to the
* display engine's pipe which can be the above fast dot clock rate or a
* divided-down version of it.
*/
/* m1 is reserved as 0 in Pineview, n is a ring counter */
static int pnv_calc_dpll_params(int refclk, struct dpll *clock)
{
clock->m = clock->m2 + 2;
clock->p = clock->p1 * clock->p2;
if (WARN_ON(clock->n == 0 || clock->p == 0))
return 0;
clock->vco = DIV_ROUND_CLOSEST(refclk * clock->m, clock->n);
clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);
return clock->dot;
}
static uint32_t i9xx_dpll_compute_m(struct dpll *dpll)
{
return 5 * (dpll->m1 + 2) + (dpll->m2 + 2);
}
static int i9xx_calc_dpll_params(int refclk, struct dpll *clock)
{
clock->m = i9xx_dpll_compute_m(clock);
clock->p = clock->p1 * clock->p2;
if (WARN_ON(clock->n + 2 == 0 || clock->p == 0))
return 0;
clock->vco = DIV_ROUND_CLOSEST(refclk * clock->m, clock->n + 2);
clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);
return clock->dot;
}
static int vlv_calc_dpll_params(int refclk, struct dpll *clock)
{
clock->m = clock->m1 * clock->m2;
clock->p = clock->p1 * clock->p2;
if (WARN_ON(clock->n == 0 || clock->p == 0))
return 0;
clock->vco = DIV_ROUND_CLOSEST(refclk * clock->m, clock->n);
clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);
return clock->dot / 5;
}
int chv_calc_dpll_params(int refclk, struct dpll *clock)
{
clock->m = clock->m1 * clock->m2;
clock->p = clock->p1 * clock->p2;
if (WARN_ON(clock->n == 0 || clock->p == 0))
return 0;
clock->vco = DIV_ROUND_CLOSEST_ULL((uint64_t)refclk * clock->m,
clock->n << 22);
clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);
return clock->dot / 5;
}
#define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0)
/**
* Returns whether the given set of divisors are valid for a given refclk with
* the given connectors.
*/
static bool intel_PLL_is_valid(struct drm_device *dev,
const struct intel_limit *limit,
const struct dpll *clock)
{
if (clock->n < limit->n.min || limit->n.max < clock->n)
INTELPllInvalid("n out of range\n");
if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1)
INTELPllInvalid("p1 out of range\n");
if (clock->m2 < limit->m2.min || limit->m2.max < clock->m2)
INTELPllInvalid("m2 out of range\n");
if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1)
INTELPllInvalid("m1 out of range\n");
if (!IS_PINEVIEW(dev) && !IS_VALLEYVIEW(dev) &&
!IS_CHERRYVIEW(dev) && !IS_BROXTON(dev))
if (clock->m1 <= clock->m2)
INTELPllInvalid("m1 <= m2\n");
if (!IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev) && !IS_BROXTON(dev)) {
if (clock->p < limit->p.min || limit->p.max < clock->p)
INTELPllInvalid("p out of range\n");
if (clock->m < limit->m.min || limit->m.max < clock->m)
INTELPllInvalid("m out of range\n");
}
if (clock->vco < limit->vco.min || limit->vco.max < clock->vco)
INTELPllInvalid("vco out of range\n");
/* XXX: We may need to be checking "Dot clock" depending on the multiplier,
* connector, etc., rather than just a single range.
*/
if (clock->dot < limit->dot.min || limit->dot.max < clock->dot)
INTELPllInvalid("dot out of range\n");
return true;
}
static int
i9xx_select_p2_div(const struct intel_limit *limit,
const struct intel_crtc_state *crtc_state,
int target)
{
struct drm_device *dev = crtc_state->base.crtc->dev;
if (intel_pipe_will_have_type(crtc_state, 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))
return limit->p2.p2_fast;
else
return limit->p2.p2_slow;
} else {
if (target < limit->p2.dot_limit)
return limit->p2.p2_slow;
else
return limit->p2.p2_fast;
}
}
/*
* Returns a set of divisors for the desired target clock with the given
* refclk, or FALSE. The returned values represent the clock equation:
* reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
*
* Target and reference clocks are specified in kHz.
*
* If match_clock is provided, then best_clock P divider must match the P
* divider from @match_clock used for LVDS downclocking.
*/
static bool
i9xx_find_best_dpll(const struct intel_limit *limit,
struct intel_crtc_state *crtc_state,
int target, int refclk, struct dpll *match_clock,
struct dpll *best_clock)
{
struct drm_device *dev = crtc_state->base.crtc->dev;
struct dpll clock;
int err = target;
memset(best_clock, 0, sizeof(*best_clock));
clock.p2 = i9xx_select_p2_div(limit, crtc_state, target);
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++) {
if (clock.m2 >= clock.m1)
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_calc_dpll_params(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);
}
/*
* Returns a set of divisors for the desired target clock with the given
* refclk, or FALSE. The returned values represent the clock equation:
* reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
*
* Target and reference clocks are specified in kHz.
*
* If match_clock is provided, then best_clock P divider must match the P
* divider from @match_clock used for LVDS downclocking.
*/
static bool
pnv_find_best_dpll(const struct intel_limit *limit,
struct intel_crtc_state *crtc_state,
int target, int refclk, struct dpll *match_clock,
struct dpll *best_clock)
{
struct drm_device *dev = crtc_state->base.crtc->dev;
struct dpll clock;
int err = target;
memset(best_clock, 0, sizeof(*best_clock));
clock.p2 = i9xx_select_p2_div(limit, crtc_state, target);
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++) {
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;
pnv_calc_dpll_params(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);
}
/*
* Returns a set of divisors for the desired target clock with the given
* refclk, or FALSE. The returned values represent the clock equation:
* reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
*
* Target and reference clocks are specified in kHz.
*
* If match_clock is provided, then best_clock P divider must match the P
* divider from @match_clock used for LVDS downclocking.
*/
static bool
g4x_find_best_dpll(const struct intel_limit *limit,
struct intel_crtc_state *crtc_state,
int target, int refclk, struct dpll *match_clock,
struct dpll *best_clock)
{
struct drm_device *dev = crtc_state->base.crtc->dev;
struct dpll clock;
int max_n;
bool found = false;
/* approximately equals target * 0.00585 */
int err_most = (target >> 8) + (target >> 9);
memset(best_clock, 0, sizeof(*best_clock));
clock.p2 = i9xx_select_p2_div(limit, crtc_state, target);
max_n = limit->n.max;
/* based on hardware requirement, prefer smaller n to precision */
for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
/* based on hardware requirement, prefere larger m1,m2 */
for (clock.m1 = limit->m1.max;
clock.m1 >= limit->m1.min; clock.m1--) {
for (clock.m2 = limit->m2.max;
clock.m2 >= limit->m2.min; clock.m2--) {
for (clock.p1 = limit->p1.max;
clock.p1 >= limit->p1.min; clock.p1--) {
int this_err;
i9xx_calc_dpll_params(refclk, &clock);
if (!intel_PLL_is_valid(dev, limit,
&clock))
continue;
this_err = abs(clock.dot - target);
if (this_err < err_most) {
*best_clock = clock;
err_most = this_err;
max_n = clock.n;
found = true;
}
}
}
}
}
return found;
}
/*
* Check if the calculated PLL configuration is more optimal compared to the
* best configuration and error found so far. Return the calculated error.
*/
static bool vlv_PLL_is_optimal(struct drm_device *dev, int target_freq,
const struct dpll *calculated_clock,
const struct dpll *best_clock,
unsigned int best_error_ppm,
unsigned int *error_ppm)
{
/*
* For CHV ignore the error and consider only the P value.
* Prefer a bigger P value based on HW requirements.
*/
if (IS_CHERRYVIEW(dev)) {
*error_ppm = 0;
return calculated_clock->p > best_clock->p;
}
if (WARN_ON_ONCE(!target_freq))
return false;
*error_ppm = div_u64(1000000ULL *
abs(target_freq - calculated_clock->dot),
target_freq);
/*
* Prefer a better P value over a better (smaller) error if the error
* is small. Ensure this preference for future configurations too by
* setting the error to 0.
*/
if (*error_ppm < 100 && calculated_clock->p > best_clock->p) {
*error_ppm = 0;
return true;
}
return *error_ppm + 10 < best_error_ppm;
}
/*
* Returns a set of divisors for the desired target clock with the given
* refclk, or FALSE. The returned values represent the clock equation:
* reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
*/
static bool
vlv_find_best_dpll(const struct intel_limit *limit,
struct intel_crtc_state *crtc_state,
int target, int refclk, struct dpll *match_clock,
struct dpll *best_clock)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
struct drm_device *dev = crtc->base.dev;
struct dpll clock;
unsigned int bestppm = 1000000;
/* min update 19.2 MHz */
int max_n = min(limit->n.max, refclk / 19200);
bool found = false;
target *= 5; /* fast clock */
memset(best_clock, 0, sizeof(*best_clock));
/* based on hardware requirement, prefer smaller n to precision */
for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
for (clock.p2 = limit->p2.p2_fast; clock.p2 >= limit->p2.p2_slow;
clock.p2 -= clock.p2 > 10 ? 2 : 1) {
clock.p = clock.p1 * clock.p2;
/* based on hardware requirement, prefer bigger m1,m2 values */
for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) {
unsigned int ppm;
clock.m2 = DIV_ROUND_CLOSEST(target * clock.p * clock.n,
refclk * clock.m1);
vlv_calc_dpll_params(refclk, &clock);
if (!intel_PLL_is_valid(dev, limit,
&clock))
continue;
if (!vlv_PLL_is_optimal(dev, target,
&clock,
best_clock,
bestppm, &ppm))
continue;
*best_clock = clock;
bestppm = ppm;
found = true;
}
}
}
}
return found;
}
/*
* Returns a set of divisors for the desired target clock with the given
* refclk, or FALSE. The returned values represent the clock equation:
* reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
*/
static bool
chv_find_best_dpll(const struct intel_limit *limit,
struct intel_crtc_state *crtc_state,
int target, int refclk, struct dpll *match_clock,
struct dpll *best_clock)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
struct drm_device *dev = crtc->base.dev;
unsigned int best_error_ppm;
struct dpll clock;
uint64_t m2;
int found = false;
memset(best_clock, 0, sizeof(*best_clock));
best_error_ppm = 1000000;
/*
* Based on hardware doc, the n always set to 1, and m1 always
* set to 2. If requires to support 200Mhz refclk, we need to
* revisit this because n may not 1 anymore.
*/
clock.n = 1, clock.m1 = 2;
target *= 5; /* fast clock */
for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
for (clock.p2 = limit->p2.p2_fast;
clock.p2 >= limit->p2.p2_slow;
clock.p2 -= clock.p2 > 10 ? 2 : 1) {
unsigned int error_ppm;
clock.p = clock.p1 * clock.p2;
m2 = DIV_ROUND_CLOSEST_ULL(((uint64_t)target * clock.p *
clock.n) << 22, refclk * clock.m1);
if (m2 > INT_MAX/clock.m1)
continue;
clock.m2 = m2;
chv_calc_dpll_params(refclk, &clock);
if (!intel_PLL_is_valid(dev, limit, &clock))
continue;
if (!vlv_PLL_is_optimal(dev, target, &clock, best_clock,
best_error_ppm, &error_ppm))
continue;
*best_clock = clock;
best_error_ppm = error_ppm;
found = true;
}
}
return found;
}
bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state, int target_clock,
struct dpll *best_clock)
{
int refclk = 100000;
const struct intel_limit *limit = &intel_limits_bxt;
return chv_find_best_dpll(limit, crtc_state,
target_clock, refclk, NULL, best_clock);
}
bool intel_crtc_active(struct drm_crtc *crtc)
{
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
/* Be paranoid as we can arrive here with only partial
* state retrieved from the hardware during setup.
*
* We can ditch the adjusted_mode.crtc_clock check as soon
* as Haswell has gained clock readout/fastboot support.
*
Merge tag 'drm-intel-next-2014-03-21' of git://anongit.freedesktop.org/drm-intel into drm-next - Inherit/reuse firmwar framebuffers (for real this time) from Jesse, less flicker for fastbooting. - More flexible cloning for hdmi (Ville). - Some PPGTT fixes from Ben. - Ring init fixes from Naresh Kumar. - set_cache_level regression fixes for the vma conversion from Ville&Chris. - Conversion to the new dp aux helpers (Jani). - Unification of runtime pm with pc8 support from Paulo, prep work for runtime pm on other platforms than HSW. - Larger cursor sizes (Sagar Kamble). - Piles of improvements and fixes all over, as usual. * tag 'drm-intel-next-2014-03-21' of git://anongit.freedesktop.org/drm-intel: (75 commits) drm/i915: Include a note about the dangers of I915_READ64/I915_WRITE64 drm/i915/sdvo: fix questionable return value check drm/i915: Fix unsafe loop iteration over vma whilst unbinding them drm/i915: Enabling 128x128 and 256x256 ARGB Cursor Support drm/i915: Print how many objects are shared in per-process stats drm/i915: Per-process stats work better when evaluated per-process drm/i915: remove rps local variables drm/i915: Remove extraneous MMIO for RPS drm/i915: Rename and comment all the RPS *stuff* drm/i915: Store the HW min frequency as min_freq drm/i915: Fix coding style for RPS drm/i915: Reorganize the overclock code drm/i915: init pm.suspended earlier drm/i915: update the PC8 and runtime PM documentation drm/i915: rename __hsw_do_{en, dis}able_pc8 drm/i915: kill struct i915_package_c8 drm/i915: move pc8.irqs_disabled to pm.irqs_disabled drm/i915: remove dev_priv->pc8.enabled drm/i915: don't get/put PC8 when getting/putting power wells drm/i915: make intel_aux_display_runtime_get get runtime PM, not PC8 ... Conflicts: drivers/gpu/drm/i915/intel_display.c drivers/gpu/drm/i915/intel_dp.c
2014-04-03 07:51:54 +10:00
* We can ditch the crtc->primary->fb check as soon as we can
* properly reconstruct framebuffers.
*
* FIXME: The intel_crtc->active here should be switched to
* crtc->state->active once we have proper CRTC states wired up
* for atomic.
*/
return intel_crtc->active && crtc->primary->state->fb &&
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
intel_crtc->config->base.adjusted_mode.crtc_clock;
}
drm/i915: add TRANSCODER_EDP Before Haswell we used to have the CPU pipes and the PCH transcoders. We had the same amount of pipes and transcoders, and there was a 1:1 mapping between them. After Haswell what we used to call CPU pipe was split into CPU pipe and CPU transcoder. So now we have 3 CPU pipes (A, B and C), 4 CPU transcoders (A, B, C and EDP) and 1 PCH transcoder (only used for VGA). For all the outputs except for EDP we have an 1:1 mapping on the CPU pipes and CPU transcoders, so if you're using CPU pipe A you have to use CPU transcoder A. When have an eDP output you have to use transcoder EDP and you can attach this CPU transcoder to any of the 3 CPU pipes. When using VGA you need to select a pair of matching CPU pipes/transcoders (A/A, B/B, C/C) and you also need to enable/use the PCH transcoder. For now we're just creating the cpu_transcoder definitions and setting cpu_transcoder to TRANSCODER_EDP on DDI eDP code, but none of the registers was ported to use transcoder instead of pipe. The goal is to keep the code backwards-compatible since on all cases except when using eDP we must have pipe == cpu_transcoder. V2: Comment the haswell_crtc_off chunk, suggested by Damien Lespiau and Daniel Vetter. We currently need the haswell_crtc_off chunk because TRANSCODER_EDP can be used by any CRTC, so when you stop using it you have to stop saying you're using it, otherwise you may have at some point 2 CRTCs claiming they're using TRANSCODER_EDP (a disabled CRTC and an enabled one), then the HW state readout code will get completely confused. In other words: Imagine the following case: xrandr --output eDP1 --auto --crtc 0 xrandr --output eDP1 --off xrandr --output eDP1 --auto --crtc 2 After the last command you could get a "pipe A assertion failure (expected off, current on)" because CRTC 0 still claims it's using TRANSCODER_EDP, so the HW state readout function will read it (through PIPECONF) and expect it to be off, when it's actually on because it's being used by CRTC 2. So when we make "intel_crtc->cpu_transcoder = intel_crtc->pipe" we make sure we're pointing to our own original CRTC which is certainly not used by any other CRTC. Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Reviewed-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-10-24 15:59:34 -02:00
enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
enum pipe pipe)
{
struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
return intel_crtc->config->cpu_transcoder;
drm/i915: add TRANSCODER_EDP Before Haswell we used to have the CPU pipes and the PCH transcoders. We had the same amount of pipes and transcoders, and there was a 1:1 mapping between them. After Haswell what we used to call CPU pipe was split into CPU pipe and CPU transcoder. So now we have 3 CPU pipes (A, B and C), 4 CPU transcoders (A, B, C and EDP) and 1 PCH transcoder (only used for VGA). For all the outputs except for EDP we have an 1:1 mapping on the CPU pipes and CPU transcoders, so if you're using CPU pipe A you have to use CPU transcoder A. When have an eDP output you have to use transcoder EDP and you can attach this CPU transcoder to any of the 3 CPU pipes. When using VGA you need to select a pair of matching CPU pipes/transcoders (A/A, B/B, C/C) and you also need to enable/use the PCH transcoder. For now we're just creating the cpu_transcoder definitions and setting cpu_transcoder to TRANSCODER_EDP on DDI eDP code, but none of the registers was ported to use transcoder instead of pipe. The goal is to keep the code backwards-compatible since on all cases except when using eDP we must have pipe == cpu_transcoder. V2: Comment the haswell_crtc_off chunk, suggested by Damien Lespiau and Daniel Vetter. We currently need the haswell_crtc_off chunk because TRANSCODER_EDP can be used by any CRTC, so when you stop using it you have to stop saying you're using it, otherwise you may have at some point 2 CRTCs claiming they're using TRANSCODER_EDP (a disabled CRTC and an enabled one), then the HW state readout code will get completely confused. In other words: Imagine the following case: xrandr --output eDP1 --auto --crtc 0 xrandr --output eDP1 --off xrandr --output eDP1 --auto --crtc 2 After the last command you could get a "pipe A assertion failure (expected off, current on)" because CRTC 0 still claims it's using TRANSCODER_EDP, so the HW state readout function will read it (through PIPECONF) and expect it to be off, when it's actually on because it's being used by CRTC 2. So when we make "intel_crtc->cpu_transcoder = intel_crtc->pipe" we make sure we're pointing to our own original CRTC which is certainly not used by any other CRTC. Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Reviewed-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-10-24 15:59:34 -02:00
}
static bool pipe_dsl_stopped(struct drm_device *dev, enum pipe pipe)
{
struct drm_i915_private *dev_priv = dev->dev_private;
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
i915_reg_t reg = PIPEDSL(pipe);
u32 line1, line2;
u32 line_mask;
if (IS_GEN2(dev))
line_mask = DSL_LINEMASK_GEN2;
else
line_mask = DSL_LINEMASK_GEN3;
line1 = I915_READ(reg) & line_mask;
msleep(5);
line2 = I915_READ(reg) & line_mask;
return line1 == line2;
}
/*
* intel_wait_for_pipe_off - wait for pipe to turn off
* @crtc: crtc whose pipe to wait for
*
* After disabling a pipe, we can't wait for vblank in the usual way,
* spinning on the vblank interrupt status bit, since we won't actually
* see an interrupt when the pipe is disabled.
*
* On Gen4 and above:
* wait for the pipe register state bit to turn off
*
* Otherwise:
* wait for the display line value to settle (it usually
* ends up stopping at the start of the next frame).
*
*/
static void intel_wait_for_pipe_off(struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
enum pipe pipe = crtc->pipe;
if (INTEL_INFO(dev)->gen >= 4) {
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
i915_reg_t reg = PIPECONF(cpu_transcoder);
/* Wait for the Pipe State to go off */
if (intel_wait_for_register(dev_priv,
reg, I965_PIPECONF_ACTIVE, 0,
100))
WARN(1, "pipe_off wait timed out\n");
} else {
/* Wait for the display line to settle */
if (wait_for(pipe_dsl_stopped(dev, pipe), 100))
WARN(1, "pipe_off wait timed out\n");
}
}
/* Only for pre-ILK configs */
void assert_pll(struct drm_i915_private *dev_priv,
enum pipe pipe, bool state)
{
u32 val;
bool cur_state;
val = I915_READ(DPLL(pipe));
cur_state = !!(val & DPLL_VCO_ENABLE);
I915_STATE_WARN(cur_state != state,
"PLL state assertion failure (expected %s, current %s)\n",
onoff(state), onoff(cur_state));
}
/* XXX: the dsi pll is shared between MIPI DSI ports */
void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state)
{
u32 val;
bool cur_state;
mutex_lock(&dev_priv->sb_lock);
val = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
mutex_unlock(&dev_priv->sb_lock);
cur_state = val & DSI_PLL_VCO_EN;
I915_STATE_WARN(cur_state != state,
"DSI PLL state assertion failure (expected %s, current %s)\n",
onoff(state), onoff(cur_state));
}
static void assert_fdi_tx(struct drm_i915_private *dev_priv,
enum pipe pipe, bool state)
{
bool cur_state;
enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
pipe);
if (HAS_DDI(dev_priv)) {
/* DDI does not have a specific FDI_TX register */
u32 val = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
cur_state = !!(val & TRANS_DDI_FUNC_ENABLE);
} else {
u32 val = I915_READ(FDI_TX_CTL(pipe));
cur_state = !!(val & FDI_TX_ENABLE);
}
I915_STATE_WARN(cur_state != state,
"FDI TX state assertion failure (expected %s, current %s)\n",
onoff(state), onoff(cur_state));
}
#define assert_fdi_tx_enabled(d, p) assert_fdi_tx(d, p, true)
#define assert_fdi_tx_disabled(d, p) assert_fdi_tx(d, p, false)
static void assert_fdi_rx(struct drm_i915_private *dev_priv,
enum pipe pipe, bool state)
{
u32 val;
bool cur_state;
val = I915_READ(FDI_RX_CTL(pipe));
cur_state = !!(val & FDI_RX_ENABLE);
I915_STATE_WARN(cur_state != state,
"FDI RX state assertion failure (expected %s, current %s)\n",
onoff(state), onoff(cur_state));
}
#define assert_fdi_rx_enabled(d, p) assert_fdi_rx(d, p, true)
#define assert_fdi_rx_disabled(d, p) assert_fdi_rx(d, p, false)
static void assert_fdi_tx_pll_enabled(struct drm_i915_private *dev_priv,
enum pipe pipe)
{
u32 val;
/* ILK FDI PLL is always enabled */
if (IS_GEN5(dev_priv))
return;
/* On Haswell, DDI ports are responsible for the FDI PLL setup */
if (HAS_DDI(dev_priv))
return;
val = I915_READ(FDI_TX_CTL(pipe));
I915_STATE_WARN(!(val & FDI_TX_PLL_ENABLE), "FDI TX PLL assertion failure, should be active but is disabled\n");
}
void assert_fdi_rx_pll(struct drm_i915_private *dev_priv,
enum pipe pipe, bool state)
{
u32 val;
bool cur_state;
val = I915_READ(FDI_RX_CTL(pipe));
cur_state = !!(val & FDI_RX_PLL_ENABLE);
I915_STATE_WARN(cur_state != state,
"FDI RX PLL assertion failure (expected %s, current %s)\n",
onoff(state), onoff(cur_state));
}
void assert_panel_unlocked(struct drm_i915_private *dev_priv,
enum pipe pipe)
{
struct drm_device *dev = dev_priv->dev;
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
i915_reg_t pp_reg;
u32 val;
enum pipe panel_pipe = PIPE_A;
bool locked = true;
if (WARN_ON(HAS_DDI(dev)))
return;
if (HAS_PCH_SPLIT(dev)) {
u32 port_sel;
pp_reg = PCH_PP_CONTROL;
port_sel = I915_READ(PCH_PP_ON_DELAYS) & PANEL_PORT_SELECT_MASK;
if (port_sel == PANEL_PORT_SELECT_LVDS &&
I915_READ(PCH_LVDS) & LVDS_PIPEB_SELECT)
panel_pipe = PIPE_B;
/* XXX: else fix for eDP */
} else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
/* presumably write lock depends on pipe, not port select */
pp_reg = VLV_PIPE_PP_CONTROL(pipe);
panel_pipe = pipe;
} else {
pp_reg = PP_CONTROL;
if (I915_READ(LVDS) & LVDS_PIPEB_SELECT)
panel_pipe = PIPE_B;
}
val = I915_READ(pp_reg);
if (!(val & PANEL_POWER_ON) ||
((val & PANEL_UNLOCK_MASK) == PANEL_UNLOCK_REGS))
locked = false;
I915_STATE_WARN(panel_pipe == pipe && locked,
"panel assertion failure, pipe %c regs locked\n",
pipe_name(pipe));
}
static void assert_cursor(struct drm_i915_private *dev_priv,
enum pipe pipe, bool state)
{
struct drm_device *dev = dev_priv->dev;
bool cur_state;
if (IS_845G(dev) || IS_I865G(dev))
cur_state = I915_READ(CURCNTR(PIPE_A)) & CURSOR_ENABLE;
else
cur_state = I915_READ(CURCNTR(pipe)) & CURSOR_MODE;
I915_STATE_WARN(cur_state != state,
"cursor on pipe %c assertion failure (expected %s, current %s)\n",
pipe_name(pipe), onoff(state), onoff(cur_state));
}
#define assert_cursor_enabled(d, p) assert_cursor(d, p, true)
#define assert_cursor_disabled(d, p) assert_cursor(d, p, false)
drm/i915: add SNB and IVB video sprite support v6 The video sprites support various video surface formats natively and can handle scaling as well. So add support for them using the new DRM core sprite support functions. v2: use drm specific fourcc header and defines v3: address Daniel's comments: - don't take struct mutex around register access (only needed for regs in the GT power well) - don't hold struct mutex across vblank waits - fix up update_plane API (pass obj instead of GTT offset) - add interlaced defines for sprite regs - drop unnecessary 'reg' variables - comment double buffered reg flushing Also fix w/h confusion when writing the scaling reg. v4: more fixes, address more comments from Daniel, and include Hai's fix - prevent divide by zero in scaling calculation (Hai Lan) - update to Ville's new DRM_FORMAT_* types - fix sprite watermark handling (calc based on CRTC size, separate from normal display wm) - remove private refcounts now that the fb cleanups handles things v5: add linear surface support v6: remove color key clearing & setting from update_plane For this version, I tested DPMS since it came up in the last review; DPMS off/on works ok when a video player is working under X, but for power saving we'll probably want to do something smarter. I'll leave that for a separate patch on top. Likewise with the refcounting/fb layer handling, which are really separate cleanups. Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Keith Packard <keithp@keithp.com>
2011-12-13 13:19:38 -08:00
void assert_pipe(struct drm_i915_private *dev_priv,
enum pipe pipe, bool state)
{
bool cur_state;
enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
pipe);
enum intel_display_power_domain power_domain;
/* if we need the pipe quirk it must be always on */
if ((pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
(pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
state = true;
power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder);
if (intel_display_power_get_if_enabled(dev_priv, power_domain)) {
u32 val = I915_READ(PIPECONF(cpu_transcoder));
cur_state = !!(val & PIPECONF_ENABLE);
intel_display_power_put(dev_priv, power_domain);
} else {
cur_state = false;
}
I915_STATE_WARN(cur_state != state,
"pipe %c assertion failure (expected %s, current %s)\n",
pipe_name(pipe), onoff(state), onoff(cur_state));
}
static void assert_plane(struct drm_i915_private *dev_priv,
enum plane plane, bool state)
{
u32 val;
bool cur_state;
val = I915_READ(DSPCNTR(plane));
cur_state = !!(val & DISPLAY_PLANE_ENABLE);
I915_STATE_WARN(cur_state != state,
"plane %c assertion failure (expected %s, current %s)\n",
plane_name(plane), onoff(state), onoff(cur_state));
}
#define assert_plane_enabled(d, p) assert_plane(d, p, true)
#define assert_plane_disabled(d, p) assert_plane(d, p, false)
static void assert_planes_disabled(struct drm_i915_private *dev_priv,
enum pipe pipe)
{
struct drm_device *dev = dev_priv->dev;
int i;
/* Primary planes are fixed to pipes on gen4+ */
if (INTEL_INFO(dev)->gen >= 4) {
u32 val = I915_READ(DSPCNTR(pipe));
I915_STATE_WARN(val & DISPLAY_PLANE_ENABLE,
"plane %c assertion failure, should be disabled but not\n",
plane_name(pipe));
return;
}
/* Need to check both planes against the pipe */
for_each_pipe(dev_priv, i) {
u32 val = I915_READ(DSPCNTR(i));
enum pipe cur_pipe = (val & DISPPLANE_SEL_PIPE_MASK) >>
DISPPLANE_SEL_PIPE_SHIFT;
I915_STATE_WARN((val & DISPLAY_PLANE_ENABLE) && pipe == cur_pipe,
"plane %c assertion failure, should be off on pipe %c but is still active\n",
plane_name(i), pipe_name(pipe));
}
}
static void assert_sprites_disabled(struct drm_i915_private *dev_priv,
enum pipe pipe)
{
struct drm_device *dev = dev_priv->dev;
int sprite;
if (INTEL_INFO(dev)->gen >= 9) {
for_each_sprite(dev_priv, pipe, sprite) {
u32 val = I915_READ(PLANE_CTL(pipe, sprite));
I915_STATE_WARN(val & PLANE_CTL_ENABLE,
"plane %d assertion failure, should be off on pipe %c but is still active\n",
sprite, pipe_name(pipe));
}
} else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
for_each_sprite(dev_priv, pipe, sprite) {
u32 val = I915_READ(SPCNTR(pipe, sprite));
I915_STATE_WARN(val & SP_ENABLE,
"sprite %c assertion failure, should be off on pipe %c but is still active\n",
sprite_name(pipe, sprite), pipe_name(pipe));
}
} else if (INTEL_INFO(dev)->gen >= 7) {
u32 val = I915_READ(SPRCTL(pipe));
I915_STATE_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) {
u32 val = I915_READ(DVSCNTR(pipe));
I915_STATE_WARN(val & DVS_ENABLE,
"sprite %c assertion failure, should be off on pipe %c but is still active\n",
plane_name(pipe), pipe_name(pipe));
}
}
static void assert_vblank_disabled(struct drm_crtc *crtc)
{
if (I915_STATE_WARN_ON(drm_crtc_vblank_get(crtc) == 0))
drm_crtc_vblank_put(crtc);
}
void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv,
enum pipe pipe)
{
u32 val;
bool enabled;
val = I915_READ(PCH_TRANSCONF(pipe));
enabled = !!(val & TRANS_ENABLE);
I915_STATE_WARN(enabled,
"transcoder assertion failed, should be off on pipe %c but is still active\n",
pipe_name(pipe));
}
static bool dp_pipe_enabled(struct drm_i915_private *dev_priv,
enum pipe pipe, u32 port_sel, u32 val)
{
if ((val & DP_PORT_EN) == 0)
return false;
if (HAS_PCH_CPT(dev_priv)) {
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
u32 trans_dp_ctl = I915_READ(TRANS_DP_CTL(pipe));
if ((trans_dp_ctl & TRANS_DP_PORT_SEL_MASK) != port_sel)
return false;
} else if (IS_CHERRYVIEW(dev_priv)) {
if ((val & DP_PIPE_MASK_CHV) != DP_PIPE_SELECT_CHV(pipe))
return false;
} else {
if ((val & DP_PIPE_MASK) != (pipe << 30))
return false;
}
return true;
}
static bool hdmi_pipe_enabled(struct drm_i915_private *dev_priv,
enum pipe pipe, u32 val)
{
if ((val & SDVO_ENABLE) == 0)
return false;
if (HAS_PCH_CPT(dev_priv)) {
if ((val & SDVO_PIPE_SEL_MASK_CPT) != SDVO_PIPE_SEL_CPT(pipe))
return false;
} else if (IS_CHERRYVIEW(dev_priv)) {
if ((val & SDVO_PIPE_SEL_MASK_CHV) != SDVO_PIPE_SEL_CHV(pipe))
return false;
} else {
if ((val & SDVO_PIPE_SEL_MASK) != SDVO_PIPE_SEL(pipe))
return false;
}
return true;
}
static bool lvds_pipe_enabled(struct drm_i915_private *dev_priv,
enum pipe pipe, u32 val)
{
if ((val & LVDS_PORT_EN) == 0)
return false;
if (HAS_PCH_CPT(dev_priv)) {
if ((val & PORT_TRANS_SEL_MASK) != PORT_TRANS_SEL_CPT(pipe))
return false;
} else {
if ((val & LVDS_PIPE_MASK) != LVDS_PIPE(pipe))
return false;
}
return true;
}
static bool adpa_pipe_enabled(struct drm_i915_private *dev_priv,
enum pipe pipe, u32 val)
{
if ((val & ADPA_DAC_ENABLE) == 0)
return false;
if (HAS_PCH_CPT(dev_priv)) {
if ((val & PORT_TRANS_SEL_MASK) != PORT_TRANS_SEL_CPT(pipe))
return false;
} else {
if ((val & ADPA_PIPE_SELECT_MASK) != ADPA_PIPE_SELECT(pipe))
return false;
}
return true;
}
static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv,
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
enum pipe pipe, i915_reg_t reg,
u32 port_sel)
{
u32 val = I915_READ(reg);
I915_STATE_WARN(dp_pipe_enabled(dev_priv, pipe, port_sel, val),
"PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n",
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
i915_mmio_reg_offset(reg), pipe_name(pipe));
I915_STATE_WARN(HAS_PCH_IBX(dev_priv) && (val & DP_PORT_EN) == 0
&& (val & DP_PIPEB_SELECT),
"IBX PCH dp port still using transcoder B\n");
}
static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv,
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
enum pipe pipe, i915_reg_t reg)
{
u32 val = I915_READ(reg);
I915_STATE_WARN(hdmi_pipe_enabled(dev_priv, pipe, val),
"PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n",
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
i915_mmio_reg_offset(reg), pipe_name(pipe));
I915_STATE_WARN(HAS_PCH_IBX(dev_priv) && (val & SDVO_ENABLE) == 0
&& (val & SDVO_PIPE_B_SELECT),
"IBX PCH hdmi port still using transcoder B\n");
}
static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
enum pipe pipe)
{
u32 val;
assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_B, TRANS_DP_PORT_SEL_B);
assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_C, TRANS_DP_PORT_SEL_C);
assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_D, TRANS_DP_PORT_SEL_D);
val = I915_READ(PCH_ADPA);
I915_STATE_WARN(adpa_pipe_enabled(dev_priv, pipe, val),
"PCH VGA enabled on transcoder %c, should be disabled\n",
pipe_name(pipe));
val = I915_READ(PCH_LVDS);
I915_STATE_WARN(lvds_pipe_enabled(dev_priv, pipe, val),
"PCH LVDS enabled on transcoder %c, should be disabled\n",
pipe_name(pipe));
assert_pch_hdmi_disabled(dev_priv, pipe, PCH_HDMIB);
assert_pch_hdmi_disabled(dev_priv, pipe, PCH_HDMIC);
assert_pch_hdmi_disabled(dev_priv, pipe, PCH_HDMID);
}
static void _vlv_enable_pll(struct intel_crtc *crtc,
const struct intel_crtc_state *pipe_config)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe;
I915_WRITE(DPLL(pipe), pipe_config->dpll_hw_state.dpll);
POSTING_READ(DPLL(pipe));
udelay(150);
if (intel_wait_for_register(dev_priv,
DPLL(pipe),
DPLL_LOCK_VLV,
DPLL_LOCK_VLV,
1))
DRM_ERROR("DPLL %d failed to lock\n", pipe);
}
static void vlv_enable_pll(struct intel_crtc *crtc,
const struct intel_crtc_state *pipe_config)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe;
assert_pipe_disabled(dev_priv, pipe);
/* PLL is protected by panel, make sure we can write it */
assert_panel_unlocked(dev_priv, pipe);
if (pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE)
_vlv_enable_pll(crtc, pipe_config);
I915_WRITE(DPLL_MD(pipe), pipe_config->dpll_hw_state.dpll_md);
POSTING_READ(DPLL_MD(pipe));
}
static void _chv_enable_pll(struct intel_crtc *crtc,
const struct intel_crtc_state *pipe_config)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe;
enum dpio_channel port = vlv_pipe_to_channel(pipe);
u32 tmp;
mutex_lock(&dev_priv->sb_lock);
/* Enable back the 10bit clock to display controller */
tmp = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port));
tmp |= DPIO_DCLKP_EN;
vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), tmp);
mutex_unlock(&dev_priv->sb_lock);
/*
* Need to wait > 100ns between dclkp clock enable bit and PLL enable.
*/
udelay(1);
/* Enable PLL */
I915_WRITE(DPLL(pipe), pipe_config->dpll_hw_state.dpll);
/* Check PLL is locked */
if (intel_wait_for_register(dev_priv,
DPLL(pipe), DPLL_LOCK_VLV, DPLL_LOCK_VLV,
1))
DRM_ERROR("PLL %d failed to lock\n", pipe);
}
static void chv_enable_pll(struct intel_crtc *crtc,
const struct intel_crtc_state *pipe_config)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe;
assert_pipe_disabled(dev_priv, pipe);
/* PLL is protected by panel, make sure we can write it */
assert_panel_unlocked(dev_priv, pipe);
if (pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE)
_chv_enable_pll(crtc, pipe_config);
drm/i915: Implement WaPixelRepeatModeFixForC0:chv DPLL_MD(PIPE_C) is AWOL on CHV. Instead of fixing it someone added chicken bits to propagate the pixel multiplier from DPLL_MD(PIPE_B) to either pipe B or C. So do that to make pixel repeat work on pipes B and C. Pipe A is fine without any tricks. Fortunately the pixel repeat propagation appears to be a oneshot operation, so once the value has been written we can clear the chicken bits. So it is still possible to drive pipe B and C with different pixel multipliers simultaneosly. Looks like DPLL_VGA_MODE_DIS must also be set in DPLL(PIPE_B) for this to work. But since we keep that bit always set in all DPLLs there's no problem. This of course means we can't reliably read out the pixel multiplier for pipes B and C. That would make the state checker unhappy, so I added shadow copies of those registers in to dev_priv. The other option would have been to skip pixel multiplier, dpll_md an dotclock checks entirely on CHV, but that feels like a serious loss of cross checking, so just pretending that we have working DPLL MD registers seemed better. Obviously with the shadow copies we can't detect if the pixel multiplier was properly configured, nor can we take over its state from the BIOS, but hopefully people won't have displays that would be limitd to such crappy modes. There is one strange flicker still remaining. It's visible on pipe C/HDMID when HDMIB is enabled while driven by pipe B. It doesn't occur if pipe A drives HDMIB, nor is there any glitch on pipe B/HDMIB when port C/HDMID starts up. I don't have a board with HDMIC so not sure if it happens there too. So I'm not sure if it's somehow tied in with this strange linkage between pipe B and C. Sadly I was unable to find an enable sequence that would avoid the glitch, but at least it's not fatal ie. the output recovers afterwards. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1458052809-23426-4-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula <jani.nikula@intel.com>
2016-03-15 16:39:56 +02:00
if (pipe != PIPE_A) {
/*
* WaPixelRepeatModeFixForC0:chv
*
* DPLLCMD is AWOL. Use chicken bits to propagate
* the value from DPLLBMD to either pipe B or C.
*/
I915_WRITE(CBR4_VLV, pipe == PIPE_B ? CBR_DPLLBMD_PIPE_B : CBR_DPLLBMD_PIPE_C);
I915_WRITE(DPLL_MD(PIPE_B), pipe_config->dpll_hw_state.dpll_md);
I915_WRITE(CBR4_VLV, 0);
dev_priv->chv_dpll_md[pipe] = pipe_config->dpll_hw_state.dpll_md;
/*
* DPLLB VGA mode also seems to cause problems.
* We should always have it disabled.
*/
WARN_ON((I915_READ(DPLL(PIPE_B)) & DPLL_VGA_MODE_DIS) == 0);
} else {
I915_WRITE(DPLL_MD(pipe), pipe_config->dpll_hw_state.dpll_md);
POSTING_READ(DPLL_MD(pipe));
}
}
static int intel_num_dvo_pipes(struct drm_device *dev)
{
struct intel_crtc *crtc;
int count = 0;
for_each_intel_crtc(dev, crtc)
count += crtc->base.state->active &&
intel_pipe_has_type(crtc, INTEL_OUTPUT_DVO);
return count;
}
static void i9xx_enable_pll(struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
i915_reg_t reg = DPLL(crtc->pipe);
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
u32 dpll = crtc->config->dpll_hw_state.dpll;
assert_pipe_disabled(dev_priv, crtc->pipe);
/* PLL is protected by panel, make sure we can write it */
if (IS_MOBILE(dev) && !IS_I830(dev))
assert_panel_unlocked(dev_priv, crtc->pipe);
/* Enable DVO 2x clock on both PLLs if necessary */
if (IS_I830(dev) && intel_num_dvo_pipes(dev) > 0) {
/*
* It appears to be important that we don't enable this
* for the current pipe before otherwise configuring the
* PLL. No idea how this should be handled if multiple
* DVO outputs are enabled simultaneosly.
*/
dpll |= DPLL_DVO_2X_MODE;
I915_WRITE(DPLL(!crtc->pipe),
I915_READ(DPLL(!crtc->pipe)) | DPLL_DVO_2X_MODE);
}
drm/i915: Enable DPLL VGA mode before P1/P2 divider write Apparently writing the DPLL register P1/P2 divider fields won't trigger an actual change in the DPLL output unless VGA mode is enabled for prior to the register write that changes the P1/P2 dividers. The write with the new P1/P2 divider can itself disable VGA mode again without problems. I tested the behaviour on my 946GZ, and when manually frobbing the register with the display on, the behaviour is very clear. However I can't explain why this machine actually works. The P1/P2 divider changes caused by normal modesets do seem to make it through to the hardware somehow since I get a stable picture on the monitor with any resolution. Maybe it's the "three times for luck" stuff that somehow masks the problem, or something. But apparently there are machines (eg. Nick Bowler's G45) where that isn't the case and we fail to get the correct clock from the DPLL. Things used to work because we enabled VGA mode for disabled DPLLs, so when re-enabling the DPLL VGA mode was enabled just prior to the first register write, and hence the P1/P2 change went through without a hitch. That got changed in b8afb9113c51 drm/i915: Keep GMCH DPLL VGA mode always disabled in the name of consistency. In order to keep the consistency part, leave VGA mode disabled for disabled DPLLs, but turn it on just prior to updating the P1/P2 dividers to make sure the hardware picks up on the new values. Cc: Nick Bowler <nbowler@draconx.ca> Reported-by: Nick Bowler <nbowler@draconx.ca> Tested-by: Nick Bowler <nbowler@draconx.ca> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
2015-10-07 22:08:25 +03:00
/*
* Apparently we need to have VGA mode enabled prior to changing
* the P1/P2 dividers. Otherwise the DPLL will keep using the old
* dividers, even though the register value does change.
*/
I915_WRITE(reg, 0);
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),
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
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, dpll);
POSTING_READ(reg);
udelay(150); /* wait for warmup */
I915_WRITE(reg, dpll);
POSTING_READ(reg);
udelay(150); /* wait for warmup */
I915_WRITE(reg, dpll);
POSTING_READ(reg);
udelay(150); /* wait for warmup */
}
/**
* i9xx_disable_pll - disable a PLL
* @dev_priv: i915 private structure
* @pipe: pipe PLL to disable
*
* Disable the PLL for @pipe, making sure the pipe is off first.
*
* Note! This is for pre-ILK only.
*/
static void i9xx_disable_pll(struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
enum pipe pipe = crtc->pipe;
/* Disable DVO 2x clock on both PLLs if necessary */
if (IS_I830(dev) &&
intel_pipe_has_type(crtc, INTEL_OUTPUT_DVO) &&
!intel_num_dvo_pipes(dev)) {
I915_WRITE(DPLL(PIPE_B),
I915_READ(DPLL(PIPE_B)) & ~DPLL_DVO_2X_MODE);
I915_WRITE(DPLL(PIPE_A),
I915_READ(DPLL(PIPE_A)) & ~DPLL_DVO_2X_MODE);
}
/* Don't disable pipe or pipe PLLs if needed */
if ((pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
(pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
return;
/* Make sure the pipe isn't still relying on us */
assert_pipe_disabled(dev_priv, pipe);
I915_WRITE(DPLL(pipe), DPLL_VGA_MODE_DIS);
POSTING_READ(DPLL(pipe));
}
static void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
{
u32 val;
/* Make sure the pipe isn't still relying on us */
assert_pipe_disabled(dev_priv, pipe);
val = DPLL_INTEGRATED_REF_CLK_VLV |
DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
if (pipe != PIPE_A)
val |= DPLL_INTEGRATED_CRI_CLK_VLV;
I915_WRITE(DPLL(pipe), val);
POSTING_READ(DPLL(pipe));
}
static void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
{
enum dpio_channel port = vlv_pipe_to_channel(pipe);
u32 val;
/* Make sure the pipe isn't still relying on us */
assert_pipe_disabled(dev_priv, pipe);
val = DPLL_SSC_REF_CLK_CHV |
DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
if (pipe != PIPE_A)
val |= DPLL_INTEGRATED_CRI_CLK_VLV;
I915_WRITE(DPLL(pipe), val);
POSTING_READ(DPLL(pipe));
mutex_lock(&dev_priv->sb_lock);
/* Disable 10bit clock to display controller */
val = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port));
val &= ~DPIO_DCLKP_EN;
vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), val);
mutex_unlock(&dev_priv->sb_lock);
}
void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
struct intel_digital_port *dport,
unsigned int expected_mask)
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
{
u32 port_mask;
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
i915_reg_t dpll_reg;
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
switch (dport->port) {
case PORT_B:
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
port_mask = DPLL_PORTB_READY_MASK;
dpll_reg = DPLL(0);
break;
case PORT_C:
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
port_mask = DPLL_PORTC_READY_MASK;
dpll_reg = DPLL(0);
expected_mask <<= 4;
break;
case PORT_D:
port_mask = DPLL_PORTD_READY_MASK;
dpll_reg = DPIO_PHY_STATUS;
break;
default:
BUG();
}
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
if (intel_wait_for_register(dev_priv,
dpll_reg, port_mask, expected_mask,
1000))
WARN(1, "timed out waiting for port %c ready: got 0x%x, expected 0x%x\n",
port_name(dport->port), I915_READ(dpll_reg) & port_mask, expected_mask);
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
}
static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv,
enum pipe pipe)
{
drm/i915: CPT+ pch transcoder workaround We need to set the timing override chicken bit after fdi link training has completed and before we enable the transcoder. We also have to clear that bit again after disabling the pch transcoder. See "Graphics BSpec: vol4g North Display Engine Registers [IVB], Display Mode Set Sequence" and "Graphics BSpec: vol4h South Display Engine Registers [CPT, PPT], South Display Engine Transcoder and FDI Control, Transcoder Debug and DFT, TRANS_CHICKEN_2" bit 31: "Workaround : Enable the override prior to enabling the transcoder. Disable the override after disabling the transcoder." While at it, use the _PIPE macro for the other TRANS_DP register. v2: Keep the w/a as-is, but kill the original (but wrongly placed) workaround introduced in commit 3bcf603f6d5d18bd9d076dc280de71f48add4101 Author: Jesse Barnes <jbarnes@virtuousgeek.org> Date: Wed Jul 27 11:51:40 2011 -0700 drm/i915: apply timing generator bug workaround on CPT and PPT and commit d4270e57efe9e2536798c59e1ed2fd0a1e5cdfcf Author: Jesse Barnes <jbarnes@virtuousgeek.org> Date: Tue Oct 11 10:43:02 2011 -0700 drm/i915: export a CPT mode set verification function Note that this old code has unconditionally set the w/a, which might explain why fdi link training sometimes silently fails, and especially why the auto-train did not seem to work properly. v3: Paulo Zanoni pointed out that this workaround is also required on the LPT PCH. And Arthur Ranyan confirmed that this workaround is requierd for all ports on the pch, not just DP: The important part is that the bit is set whenever the pch transcoder is enabled, and that it is _not_ set while the fdi link is trained. It is also important that the pch transcoder is fully disabled, i.e. we have to wait for bit 30 to clear before clearing the w/a bit. Hence move to workaround into enable/disable_transcoder, where the pch transcoder gets enabled/disabled. v4: Whitespace changes dropped. v5: Don't run the w/a on IBX, we only need it on CPT/PPT and LPT. v6: - resolve conflicts with Paulo's big hsw vga rework - s/!IBX/CPT since hsw paths are now all separate, and Paulo's patch to implement the equivalent w/a for LPT is already merged. Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Cc: Paulo Zanoni <przanoni@gmail.com> Cc: Arthur Ranyan <arthur.j.runyan@intel.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> (v5) Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> (v5) Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-11-01 09:15:30 +01:00
struct drm_device *dev = dev_priv->dev;
struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
drm/i915: switch crtc->shared_dpll from a pointer to an enum 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ä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-06-07 23:10:03 +02:00
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
i915_reg_t reg;
uint32_t val, pipeconf_val;
/* Make sure PCH DPLL is enabled */
assert_shared_dpll_enabled(dev_priv, intel_crtc->config->shared_dpll);
/* FDI must be feeding us bits for PCH ports */
assert_fdi_tx_enabled(dev_priv, pipe);
assert_fdi_rx_enabled(dev_priv, pipe);
drm/i915: CPT+ pch transcoder workaround We need to set the timing override chicken bit after fdi link training has completed and before we enable the transcoder. We also have to clear that bit again after disabling the pch transcoder. See "Graphics BSpec: vol4g North Display Engine Registers [IVB], Display Mode Set Sequence" and "Graphics BSpec: vol4h South Display Engine Registers [CPT, PPT], South Display Engine Transcoder and FDI Control, Transcoder Debug and DFT, TRANS_CHICKEN_2" bit 31: "Workaround : Enable the override prior to enabling the transcoder. Disable the override after disabling the transcoder." While at it, use the _PIPE macro for the other TRANS_DP register. v2: Keep the w/a as-is, but kill the original (but wrongly placed) workaround introduced in commit 3bcf603f6d5d18bd9d076dc280de71f48add4101 Author: Jesse Barnes <jbarnes@virtuousgeek.org> Date: Wed Jul 27 11:51:40 2011 -0700 drm/i915: apply timing generator bug workaround on CPT and PPT and commit d4270e57efe9e2536798c59e1ed2fd0a1e5cdfcf Author: Jesse Barnes <jbarnes@virtuousgeek.org> Date: Tue Oct 11 10:43:02 2011 -0700 drm/i915: export a CPT mode set verification function Note that this old code has unconditionally set the w/a, which might explain why fdi link training sometimes silently fails, and especially why the auto-train did not seem to work properly. v3: Paulo Zanoni pointed out that this workaround is also required on the LPT PCH. And Arthur Ranyan confirmed that this workaround is requierd for all ports on the pch, not just DP: The important part is that the bit is set whenever the pch transcoder is enabled, and that it is _not_ set while the fdi link is trained. It is also important that the pch transcoder is fully disabled, i.e. we have to wait for bit 30 to clear before clearing the w/a bit. Hence move to workaround into enable/disable_transcoder, where the pch transcoder gets enabled/disabled. v4: Whitespace changes dropped. v5: Don't run the w/a on IBX, we only need it on CPT/PPT and LPT. v6: - resolve conflicts with Paulo's big hsw vga rework - s/!IBX/CPT since hsw paths are now all separate, and Paulo's patch to implement the equivalent w/a for LPT is already merged. Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Cc: Paulo Zanoni <przanoni@gmail.com> Cc: Arthur Ranyan <arthur.j.runyan@intel.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> (v5) Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> (v5) Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-11-01 09:15:30 +01:00
if (HAS_PCH_CPT(dev)) {
/* Workaround: Set the timing override bit before enabling the
* pch transcoder. */
reg = TRANS_CHICKEN2(pipe);
val = I915_READ(reg);
val |= TRANS_CHICKEN2_TIMING_OVERRIDE;
I915_WRITE(reg, val);
}
drm/i915: CPT+ pch transcoder workaround We need to set the timing override chicken bit after fdi link training has completed and before we enable the transcoder. We also have to clear that bit again after disabling the pch transcoder. See "Graphics BSpec: vol4g North Display Engine Registers [IVB], Display Mode Set Sequence" and "Graphics BSpec: vol4h South Display Engine Registers [CPT, PPT], South Display Engine Transcoder and FDI Control, Transcoder Debug and DFT, TRANS_CHICKEN_2" bit 31: "Workaround : Enable the override prior to enabling the transcoder. Disable the override after disabling the transcoder." While at it, use the _PIPE macro for the other TRANS_DP register. v2: Keep the w/a as-is, but kill the original (but wrongly placed) workaround introduced in commit 3bcf603f6d5d18bd9d076dc280de71f48add4101 Author: Jesse Barnes <jbarnes@virtuousgeek.org> Date: Wed Jul 27 11:51:40 2011 -0700 drm/i915: apply timing generator bug workaround on CPT and PPT and commit d4270e57efe9e2536798c59e1ed2fd0a1e5cdfcf Author: Jesse Barnes <jbarnes@virtuousgeek.org> Date: Tue Oct 11 10:43:02 2011 -0700 drm/i915: export a CPT mode set verification function Note that this old code has unconditionally set the w/a, which might explain why fdi link training sometimes silently fails, and especially why the auto-train did not seem to work properly. v3: Paulo Zanoni pointed out that this workaround is also required on the LPT PCH. And Arthur Ranyan confirmed that this workaround is requierd for all ports on the pch, not just DP: The important part is that the bit is set whenever the pch transcoder is enabled, and that it is _not_ set while the fdi link is trained. It is also important that the pch transcoder is fully disabled, i.e. we have to wait for bit 30 to clear before clearing the w/a bit. Hence move to workaround into enable/disable_transcoder, where the pch transcoder gets enabled/disabled. v4: Whitespace changes dropped. v5: Don't run the w/a on IBX, we only need it on CPT/PPT and LPT. v6: - resolve conflicts with Paulo's big hsw vga rework - s/!IBX/CPT since hsw paths are now all separate, and Paulo's patch to implement the equivalent w/a for LPT is already merged. Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Cc: Paulo Zanoni <przanoni@gmail.com> Cc: Arthur Ranyan <arthur.j.runyan@intel.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> (v5) Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> (v5) Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-11-01 09:15:30 +01:00
reg = PCH_TRANSCONF(pipe);
val = I915_READ(reg);
pipeconf_val = I915_READ(PIPECONF(pipe));
if (HAS_PCH_IBX(dev_priv)) {
/*
* Make the BPC in transcoder be consistent with
* that in pipeconf reg. For HDMI we must use 8bpc
* here for both 8bpc and 12bpc.
*/
val &= ~PIPECONF_BPC_MASK;
if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_HDMI))
val |= PIPECONF_8BPC;
else
val |= pipeconf_val & PIPECONF_BPC_MASK;
}
val &= ~TRANS_INTERLACE_MASK;
if ((pipeconf_val & PIPECONF_INTERLACE_MASK) == PIPECONF_INTERLACED_ILK)
if (HAS_PCH_IBX(dev_priv) &&
intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_SDVO))
val |= TRANS_LEGACY_INTERLACED_ILK;
else
val |= TRANS_INTERLACED;
else
val |= TRANS_PROGRESSIVE;
I915_WRITE(reg, val | TRANS_ENABLE);
if (intel_wait_for_register(dev_priv,
reg, TRANS_STATE_ENABLE, TRANS_STATE_ENABLE,
100))
DRM_ERROR("failed to enable transcoder %c\n", pipe_name(pipe));
}
static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv,
enum transcoder cpu_transcoder)
{
u32 val, pipeconf_val;
/* FDI must be feeding us bits for PCH ports */
assert_fdi_tx_enabled(dev_priv, (enum pipe) cpu_transcoder);
assert_fdi_rx_enabled(dev_priv, TRANSCODER_A);
/* Workaround: set timing override bit. */
val = I915_READ(TRANS_CHICKEN2(PIPE_A));
drm/i915: CPT+ pch transcoder workaround We need to set the timing override chicken bit after fdi link training has completed and before we enable the transcoder. We also have to clear that bit again after disabling the pch transcoder. See "Graphics BSpec: vol4g North Display Engine Registers [IVB], Display Mode Set Sequence" and "Graphics BSpec: vol4h South Display Engine Registers [CPT, PPT], South Display Engine Transcoder and FDI Control, Transcoder Debug and DFT, TRANS_CHICKEN_2" bit 31: "Workaround : Enable the override prior to enabling the transcoder. Disable the override after disabling the transcoder." While at it, use the _PIPE macro for the other TRANS_DP register. v2: Keep the w/a as-is, but kill the original (but wrongly placed) workaround introduced in commit 3bcf603f6d5d18bd9d076dc280de71f48add4101 Author: Jesse Barnes <jbarnes@virtuousgeek.org> Date: Wed Jul 27 11:51:40 2011 -0700 drm/i915: apply timing generator bug workaround on CPT and PPT and commit d4270e57efe9e2536798c59e1ed2fd0a1e5cdfcf Author: Jesse Barnes <jbarnes@virtuousgeek.org> Date: Tue Oct 11 10:43:02 2011 -0700 drm/i915: export a CPT mode set verification function Note that this old code has unconditionally set the w/a, which might explain why fdi link training sometimes silently fails, and especially why the auto-train did not seem to work properly. v3: Paulo Zanoni pointed out that this workaround is also required on the LPT PCH. And Arthur Ranyan confirmed that this workaround is requierd for all ports on the pch, not just DP: The important part is that the bit is set whenever the pch transcoder is enabled, and that it is _not_ set while the fdi link is trained. It is also important that the pch transcoder is fully disabled, i.e. we have to wait for bit 30 to clear before clearing the w/a bit. Hence move to workaround into enable/disable_transcoder, where the pch transcoder gets enabled/disabled. v4: Whitespace changes dropped. v5: Don't run the w/a on IBX, we only need it on CPT/PPT and LPT. v6: - resolve conflicts with Paulo's big hsw vga rework - s/!IBX/CPT since hsw paths are now all separate, and Paulo's patch to implement the equivalent w/a for LPT is already merged. Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Cc: Paulo Zanoni <przanoni@gmail.com> Cc: Arthur Ranyan <arthur.j.runyan@intel.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> (v5) Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> (v5) Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-11-01 09:15:30 +01:00
val |= TRANS_CHICKEN2_TIMING_OVERRIDE;
I915_WRITE(TRANS_CHICKEN2(PIPE_A), val);
val = TRANS_ENABLE;
pipeconf_val = I915_READ(PIPECONF(cpu_transcoder));
if ((pipeconf_val & PIPECONF_INTERLACE_MASK_HSW) ==
PIPECONF_INTERLACED_ILK)
val |= TRANS_INTERLACED;
else
val |= TRANS_PROGRESSIVE;
I915_WRITE(LPT_TRANSCONF, val);
if (intel_wait_for_register(dev_priv,
LPT_TRANSCONF,
TRANS_STATE_ENABLE,
TRANS_STATE_ENABLE,
100))
DRM_ERROR("Failed to enable PCH transcoder\n");
}
static void ironlake_disable_pch_transcoder(struct drm_i915_private *dev_priv,
enum pipe pipe)
{
drm/i915: CPT+ pch transcoder workaround We need to set the timing override chicken bit after fdi link training has completed and before we enable the transcoder. We also have to clear that bit again after disabling the pch transcoder. See "Graphics BSpec: vol4g North Display Engine Registers [IVB], Display Mode Set Sequence" and "Graphics BSpec: vol4h South Display Engine Registers [CPT, PPT], South Display Engine Transcoder and FDI Control, Transcoder Debug and DFT, TRANS_CHICKEN_2" bit 31: "Workaround : Enable the override prior to enabling the transcoder. Disable the override after disabling the transcoder." While at it, use the _PIPE macro for the other TRANS_DP register. v2: Keep the w/a as-is, but kill the original (but wrongly placed) workaround introduced in commit 3bcf603f6d5d18bd9d076dc280de71f48add4101 Author: Jesse Barnes <jbarnes@virtuousgeek.org> Date: Wed Jul 27 11:51:40 2011 -0700 drm/i915: apply timing generator bug workaround on CPT and PPT and commit d4270e57efe9e2536798c59e1ed2fd0a1e5cdfcf Author: Jesse Barnes <jbarnes@virtuousgeek.org> Date: Tue Oct 11 10:43:02 2011 -0700 drm/i915: export a CPT mode set verification function Note that this old code has unconditionally set the w/a, which might explain why fdi link training sometimes silently fails, and especially why the auto-train did not seem to work properly. v3: Paulo Zanoni pointed out that this workaround is also required on the LPT PCH. And Arthur Ranyan confirmed that this workaround is requierd for all ports on the pch, not just DP: The important part is that the bit is set whenever the pch transcoder is enabled, and that it is _not_ set while the fdi link is trained. It is also important that the pch transcoder is fully disabled, i.e. we have to wait for bit 30 to clear before clearing the w/a bit. Hence move to workaround into enable/disable_transcoder, where the pch transcoder gets enabled/disabled. v4: Whitespace changes dropped. v5: Don't run the w/a on IBX, we only need it on CPT/PPT and LPT. v6: - resolve conflicts with Paulo's big hsw vga rework - s/!IBX/CPT since hsw paths are now all separate, and Paulo's patch to implement the equivalent w/a for LPT is already merged. Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Cc: Paulo Zanoni <przanoni@gmail.com> Cc: Arthur Ranyan <arthur.j.runyan@intel.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> (v5) Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> (v5) Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-11-01 09:15:30 +01:00
struct drm_device *dev = dev_priv->dev;
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
i915_reg_t reg;
uint32_t val;
/* FDI relies on the transcoder */
assert_fdi_tx_disabled(dev_priv, pipe);
assert_fdi_rx_disabled(dev_priv, pipe);
/* Ports must be off as well */
assert_pch_ports_disabled(dev_priv, pipe);
reg = PCH_TRANSCONF(pipe);
val = I915_READ(reg);
val &= ~TRANS_ENABLE;
I915_WRITE(reg, val);
/* wait for PCH transcoder off, transcoder state */
if (intel_wait_for_register(dev_priv,
reg, TRANS_STATE_ENABLE, 0,
50))
DRM_ERROR("failed to disable transcoder %c\n", pipe_name(pipe));
drm/i915: CPT+ pch transcoder workaround We need to set the timing override chicken bit after fdi link training has completed and before we enable the transcoder. We also have to clear that bit again after disabling the pch transcoder. See "Graphics BSpec: vol4g North Display Engine Registers [IVB], Display Mode Set Sequence" and "Graphics BSpec: vol4h South Display Engine Registers [CPT, PPT], South Display Engine Transcoder and FDI Control, Transcoder Debug and DFT, TRANS_CHICKEN_2" bit 31: "Workaround : Enable the override prior to enabling the transcoder. Disable the override after disabling the transcoder." While at it, use the _PIPE macro for the other TRANS_DP register. v2: Keep the w/a as-is, but kill the original (but wrongly placed) workaround introduced in commit 3bcf603f6d5d18bd9d076dc280de71f48add4101 Author: Jesse Barnes <jbarnes@virtuousgeek.org> Date: Wed Jul 27 11:51:40 2011 -0700 drm/i915: apply timing generator bug workaround on CPT and PPT and commit d4270e57efe9e2536798c59e1ed2fd0a1e5cdfcf Author: Jesse Barnes <jbarnes@virtuousgeek.org> Date: Tue Oct 11 10:43:02 2011 -0700 drm/i915: export a CPT mode set verification function Note that this old code has unconditionally set the w/a, which might explain why fdi link training sometimes silently fails, and especially why the auto-train did not seem to work properly. v3: Paulo Zanoni pointed out that this workaround is also required on the LPT PCH. And Arthur Ranyan confirmed that this workaround is requierd for all ports on the pch, not just DP: The important part is that the bit is set whenever the pch transcoder is enabled, and that it is _not_ set while the fdi link is trained. It is also important that the pch transcoder is fully disabled, i.e. we have to wait for bit 30 to clear before clearing the w/a bit. Hence move to workaround into enable/disable_transcoder, where the pch transcoder gets enabled/disabled. v4: Whitespace changes dropped. v5: Don't run the w/a on IBX, we only need it on CPT/PPT and LPT. v6: - resolve conflicts with Paulo's big hsw vga rework - s/!IBX/CPT since hsw paths are now all separate, and Paulo's patch to implement the equivalent w/a for LPT is already merged. Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Cc: Paulo Zanoni <przanoni@gmail.com> Cc: Arthur Ranyan <arthur.j.runyan@intel.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> (v5) Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> (v5) Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-11-01 09:15:30 +01:00
if (HAS_PCH_CPT(dev)) {
drm/i915: CPT+ pch transcoder workaround We need to set the timing override chicken bit after fdi link training has completed and before we enable the transcoder. We also have to clear that bit again after disabling the pch transcoder. See "Graphics BSpec: vol4g North Display Engine Registers [IVB], Display Mode Set Sequence" and "Graphics BSpec: vol4h South Display Engine Registers [CPT, PPT], South Display Engine Transcoder and FDI Control, Transcoder Debug and DFT, TRANS_CHICKEN_2" bit 31: "Workaround : Enable the override prior to enabling the transcoder. Disable the override after disabling the transcoder." While at it, use the _PIPE macro for the other TRANS_DP register. v2: Keep the w/a as-is, but kill the original (but wrongly placed) workaround introduced in commit 3bcf603f6d5d18bd9d076dc280de71f48add4101 Author: Jesse Barnes <jbarnes@virtuousgeek.org> Date: Wed Jul 27 11:51:40 2011 -0700 drm/i915: apply timing generator bug workaround on CPT and PPT and commit d4270e57efe9e2536798c59e1ed2fd0a1e5cdfcf Author: Jesse Barnes <jbarnes@virtuousgeek.org> Date: Tue Oct 11 10:43:02 2011 -0700 drm/i915: export a CPT mode set verification function Note that this old code has unconditionally set the w/a, which might explain why fdi link training sometimes silently fails, and especially why the auto-train did not seem to work properly. v3: Paulo Zanoni pointed out that this workaround is also required on the LPT PCH. And Arthur Ranyan confirmed that this workaround is requierd for all ports on the pch, not just DP: The important part is that the bit is set whenever the pch transcoder is enabled, and that it is _not_ set while the fdi link is trained. It is also important that the pch transcoder is fully disabled, i.e. we have to wait for bit 30 to clear before clearing the w/a bit. Hence move to workaround into enable/disable_transcoder, where the pch transcoder gets enabled/disabled. v4: Whitespace changes dropped. v5: Don't run the w/a on IBX, we only need it on CPT/PPT and LPT. v6: - resolve conflicts with Paulo's big hsw vga rework - s/!IBX/CPT since hsw paths are now all separate, and Paulo's patch to implement the equivalent w/a for LPT is already merged. Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Cc: Paulo Zanoni <przanoni@gmail.com> Cc: Arthur Ranyan <arthur.j.runyan@intel.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> (v5) Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> (v5) Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-11-01 09:15:30 +01:00
/* Workaround: Clear the timing override chicken bit again. */
reg = TRANS_CHICKEN2(pipe);
val = I915_READ(reg);
val &= ~TRANS_CHICKEN2_TIMING_OVERRIDE;
I915_WRITE(reg, val);
}
}
static void lpt_disable_pch_transcoder(struct drm_i915_private *dev_priv)
{
u32 val;
val = I915_READ(LPT_TRANSCONF);
val &= ~TRANS_ENABLE;
I915_WRITE(LPT_TRANSCONF, val);
/* wait for PCH transcoder off, transcoder state */
if (intel_wait_for_register(dev_priv,
LPT_TRANSCONF, TRANS_STATE_ENABLE, 0,
50))
DRM_ERROR("Failed to disable PCH transcoder\n");
/* Workaround: clear timing override bit. */
val = I915_READ(TRANS_CHICKEN2(PIPE_A));
drm/i915: CPT+ pch transcoder workaround We need to set the timing override chicken bit after fdi link training has completed and before we enable the transcoder. We also have to clear that bit again after disabling the pch transcoder. See "Graphics BSpec: vol4g North Display Engine Registers [IVB], Display Mode Set Sequence" and "Graphics BSpec: vol4h South Display Engine Registers [CPT, PPT], South Display Engine Transcoder and FDI Control, Transcoder Debug and DFT, TRANS_CHICKEN_2" bit 31: "Workaround : Enable the override prior to enabling the transcoder. Disable the override after disabling the transcoder." While at it, use the _PIPE macro for the other TRANS_DP register. v2: Keep the w/a as-is, but kill the original (but wrongly placed) workaround introduced in commit 3bcf603f6d5d18bd9d076dc280de71f48add4101 Author: Jesse Barnes <jbarnes@virtuousgeek.org> Date: Wed Jul 27 11:51:40 2011 -0700 drm/i915: apply timing generator bug workaround on CPT and PPT and commit d4270e57efe9e2536798c59e1ed2fd0a1e5cdfcf Author: Jesse Barnes <jbarnes@virtuousgeek.org> Date: Tue Oct 11 10:43:02 2011 -0700 drm/i915: export a CPT mode set verification function Note that this old code has unconditionally set the w/a, which might explain why fdi link training sometimes silently fails, and especially why the auto-train did not seem to work properly. v3: Paulo Zanoni pointed out that this workaround is also required on the LPT PCH. And Arthur Ranyan confirmed that this workaround is requierd for all ports on the pch, not just DP: The important part is that the bit is set whenever the pch transcoder is enabled, and that it is _not_ set while the fdi link is trained. It is also important that the pch transcoder is fully disabled, i.e. we have to wait for bit 30 to clear before clearing the w/a bit. Hence move to workaround into enable/disable_transcoder, where the pch transcoder gets enabled/disabled. v4: Whitespace changes dropped. v5: Don't run the w/a on IBX, we only need it on CPT/PPT and LPT. v6: - resolve conflicts with Paulo's big hsw vga rework - s/!IBX/CPT since hsw paths are now all separate, and Paulo's patch to implement the equivalent w/a for LPT is already merged. Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Cc: Paulo Zanoni <przanoni@gmail.com> Cc: Arthur Ranyan <arthur.j.runyan@intel.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> (v5) Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> (v5) Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-11-01 09:15:30 +01:00
val &= ~TRANS_CHICKEN2_TIMING_OVERRIDE;
I915_WRITE(TRANS_CHICKEN2(PIPE_A), val);
}
/**
* intel_enable_pipe - enable a pipe, asserting requirements
* @crtc: crtc responsible for the pipe
*
* Enable @crtc's pipe, making sure that various hardware specific requirements
* are met, if applicable, e.g. PLL enabled, LVDS pairs enabled, etc.
*/
static void intel_enable_pipe(struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
enum pipe pipe = crtc->pipe;
enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
enum pipe pch_transcoder;
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
i915_reg_t reg;
u32 val;
DRM_DEBUG_KMS("enabling pipe %c\n", pipe_name(pipe));
assert_planes_disabled(dev_priv, pipe);
assert_cursor_disabled(dev_priv, pipe);
assert_sprites_disabled(dev_priv, pipe);
if (HAS_PCH_LPT(dev_priv))
pch_transcoder = TRANSCODER_A;
else
pch_transcoder = pipe;
/*
* A pipe without a PLL won't actually be able to drive bits from
* a plane. On ILK+ the pipe PLLs are integrated, so we don't
* need the check.
*/
if (HAS_GMCH_DISPLAY(dev_priv))
if (crtc->config->has_dsi_encoder)
assert_dsi_pll_enabled(dev_priv);
else
assert_pll_enabled(dev_priv, pipe);
else {
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (crtc->config->has_pch_encoder) {
/* if driving the PCH, we need FDI enabled */
assert_fdi_rx_pll_enabled(dev_priv, pch_transcoder);
assert_fdi_tx_pll_enabled(dev_priv,
(enum pipe) cpu_transcoder);
}
/* FIXME: assert CPU port conditions for SNB+ */
}
reg = PIPECONF(cpu_transcoder);
val = I915_READ(reg);
if (val & PIPECONF_ENABLE) {
WARN_ON(!((pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
(pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE)));
return;
}
I915_WRITE(reg, val | PIPECONF_ENABLE);
POSTING_READ(reg);
/*
* Until the pipe starts DSL will read as 0, which would cause
* an apparent vblank timestamp jump, which messes up also the
* frame count when it's derived from the timestamps. So let's
* wait for the pipe to start properly before we call
* drm_crtc_vblank_on()
*/
if (dev->max_vblank_count == 0 &&
wait_for(intel_get_crtc_scanline(crtc) != crtc->scanline_offset, 50))
DRM_ERROR("pipe %c didn't start\n", pipe_name(pipe));
}
/**
* intel_disable_pipe - disable a pipe, asserting requirements
* @crtc: crtc whose pipes is to be disabled
*
* Disable the pipe of @crtc, making sure that various hardware
* specific requirements are met, if applicable, e.g. plane
* disabled, panel fitter off, etc.
*
* Will wait until the pipe has shut down before returning.
*/
static void intel_disable_pipe(struct intel_crtc *crtc)
{
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
enum pipe pipe = crtc->pipe;
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
i915_reg_t reg;
u32 val;
DRM_DEBUG_KMS("disabling pipe %c\n", pipe_name(pipe));
/*
* Make sure planes won't keep trying to pump pixels to us,
* or we might hang the display.
*/
assert_planes_disabled(dev_priv, pipe);
assert_cursor_disabled(dev_priv, pipe);
assert_sprites_disabled(dev_priv, pipe);
reg = PIPECONF(cpu_transcoder);
val = I915_READ(reg);
if ((val & PIPECONF_ENABLE) == 0)
return;
/*
* Double wide has implications for planes
* so best keep it disabled when not needed.
*/
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (crtc->config->double_wide)
val &= ~PIPECONF_DOUBLE_WIDE;
/* Don't disable pipe or pipe PLLs if needed */
if (!(pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) &&
!(pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
val &= ~PIPECONF_ENABLE;
I915_WRITE(reg, val);
if ((val & PIPECONF_ENABLE) == 0)
intel_wait_for_pipe_off(crtc);
}
static bool need_vtd_wa(struct drm_device *dev)
{
#ifdef CONFIG_INTEL_IOMMU
if (INTEL_INFO(dev)->gen >= 6 && intel_iommu_gfx_mapped)
return true;
#endif
return false;
}
static unsigned int intel_tile_size(const struct drm_i915_private *dev_priv)
{
return IS_GEN2(dev_priv) ? 2048 : 4096;
}
static unsigned int intel_tile_width_bytes(const struct drm_i915_private *dev_priv,
uint64_t fb_modifier, unsigned int cpp)
{
switch (fb_modifier) {
case DRM_FORMAT_MOD_NONE:
return cpp;
case I915_FORMAT_MOD_X_TILED:
if (IS_GEN2(dev_priv))
return 128;
else
return 512;
case I915_FORMAT_MOD_Y_TILED:
if (IS_GEN2(dev_priv) || HAS_128_BYTE_Y_TILING(dev_priv))
return 128;
else
return 512;
case I915_FORMAT_MOD_Yf_TILED:
switch (cpp) {
case 1:
return 64;
case 2:
case 4:
return 128;
case 8:
case 16:
return 256;
default:
MISSING_CASE(cpp);
return cpp;
}
break;
default:
MISSING_CASE(fb_modifier);
return cpp;
}
}
unsigned int intel_tile_height(const struct drm_i915_private *dev_priv,
uint64_t fb_modifier, unsigned int cpp)
{
if (fb_modifier == DRM_FORMAT_MOD_NONE)
return 1;
else
return intel_tile_size(dev_priv) /
intel_tile_width_bytes(dev_priv, fb_modifier, cpp);
}
/* Return the tile dimensions in pixel units */
static void intel_tile_dims(const struct drm_i915_private *dev_priv,
unsigned int *tile_width,
unsigned int *tile_height,
uint64_t fb_modifier,
unsigned int cpp)
{
unsigned int tile_width_bytes =
intel_tile_width_bytes(dev_priv, fb_modifier, cpp);
*tile_width = tile_width_bytes / cpp;
*tile_height = intel_tile_size(dev_priv) / tile_width_bytes;
}
unsigned int
intel_fb_align_height(struct drm_device *dev, unsigned int height,
uint32_t pixel_format, uint64_t fb_modifier)
{
unsigned int cpp = drm_format_plane_cpp(pixel_format, 0);
unsigned int tile_height = intel_tile_height(to_i915(dev), fb_modifier, cpp);
return ALIGN(height, tile_height);
}
unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info)
{
unsigned int size = 0;
int i;
for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++)
size += rot_info->plane[i].width * rot_info->plane[i].height;
return size;
}
static void
intel_fill_fb_ggtt_view(struct i915_ggtt_view *view,
const struct drm_framebuffer *fb,
unsigned int rotation)
{
if (intel_rotation_90_or_270(rotation)) {
*view = i915_ggtt_view_rotated;
view->params.rotated = to_intel_framebuffer(fb)->rot_info;
} else {
*view = i915_ggtt_view_normal;
}
}
drm/i915/skl: Support secondary (rotated) frame buffer mapping 90/270 rotated scanout needs a rotated GTT view of the framebuffer. This is put in a separate VMA with a dedicated ggtt view and wired such that it is created when a framebuffer is pinned to a 90/270 rotated plane. Rotation is only possible with Yb/Yf buffers and error is propagated to user space in case of a mismatch. Special rotated page view is constructed at the VMA creation time by borrowing the DMA addresses from obj->pages. v2: * Do not bother with pages for rotated sg list, just populate the DMA addresses. (Daniel Vetter) * Checkpatch cleanup. v3: * Rebased on top of new plane handling (create rotated mapping when setting the rotation property). * Unpin rotated VMA on unpinning from display plane. * Simplify rotation check using bitwise AND. (Chris Wilson) v4: * Fix unpinning of optional rotated mapping so it is really considered to be optional. v5: * Rebased for fb modifier changes. * Rebased for atomic commit. * Only pin needed view for display. (Ville Syrjälä, Daniel Vetter) v6: * Rebased after preparatory work has been extracted out. (Daniel Vetter) v7: * Slightly simplified tiling geometry calculation. * Moved rotated GGTT view implementation into i915_gem_gtt.c (Daniel Vetter) v8: * Do not use i915_gem_obj_size to get object size since that actually returns the size of an VMA which may not exist. * Rebased for ggtt view changes. v9: * Rebased after code review changes on the preceding patches. * Tidy function definitions. (Joonas Lahtinen) For: VIZ-4726 Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Reviewed-by: Michel Thierry <michel.thierry@intel.com> (v4) Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-03-23 11:10:36 +00:00
static void
intel_fill_fb_info(struct drm_i915_private *dev_priv,
struct drm_framebuffer *fb)
{
struct intel_rotation_info *info = &to_intel_framebuffer(fb)->rot_info;
unsigned int tile_size, tile_width, tile_height, cpp;
drm/i915/skl: Support secondary (rotated) frame buffer mapping 90/270 rotated scanout needs a rotated GTT view of the framebuffer. This is put in a separate VMA with a dedicated ggtt view and wired such that it is created when a framebuffer is pinned to a 90/270 rotated plane. Rotation is only possible with Yb/Yf buffers and error is propagated to user space in case of a mismatch. Special rotated page view is constructed at the VMA creation time by borrowing the DMA addresses from obj->pages. v2: * Do not bother with pages for rotated sg list, just populate the DMA addresses. (Daniel Vetter) * Checkpatch cleanup. v3: * Rebased on top of new plane handling (create rotated mapping when setting the rotation property). * Unpin rotated VMA on unpinning from display plane. * Simplify rotation check using bitwise AND. (Chris Wilson) v4: * Fix unpinning of optional rotated mapping so it is really considered to be optional. v5: * Rebased for fb modifier changes. * Rebased for atomic commit. * Only pin needed view for display. (Ville Syrjälä, Daniel Vetter) v6: * Rebased after preparatory work has been extracted out. (Daniel Vetter) v7: * Slightly simplified tiling geometry calculation. * Moved rotated GGTT view implementation into i915_gem_gtt.c (Daniel Vetter) v8: * Do not use i915_gem_obj_size to get object size since that actually returns the size of an VMA which may not exist. * Rebased for ggtt view changes. v9: * Rebased after code review changes on the preceding patches. * Tidy function definitions. (Joonas Lahtinen) For: VIZ-4726 Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Reviewed-by: Michel Thierry <michel.thierry@intel.com> (v4) Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-03-23 11:10:36 +00:00
tile_size = intel_tile_size(dev_priv);
cpp = drm_format_plane_cpp(fb->pixel_format, 0);
intel_tile_dims(dev_priv, &tile_width, &tile_height,
fb->modifier[0], cpp);
info->plane[0].width = DIV_ROUND_UP(fb->pitches[0], tile_width * cpp);
info->plane[0].height = DIV_ROUND_UP(fb->height, tile_height);
if (info->pixel_format == DRM_FORMAT_NV12) {
cpp = drm_format_plane_cpp(fb->pixel_format, 1);
intel_tile_dims(dev_priv, &tile_width, &tile_height,
fb->modifier[1], cpp);
info->uv_offset = fb->offsets[1];
info->plane[1].width = DIV_ROUND_UP(fb->pitches[1], tile_width * cpp);
info->plane[1].height = DIV_ROUND_UP(fb->height / 2, tile_height);
}
}
static unsigned int intel_linear_alignment(const struct drm_i915_private *dev_priv)
{
if (INTEL_INFO(dev_priv)->gen >= 9)
return 256 * 1024;
else if (IS_BROADWATER(dev_priv) || IS_CRESTLINE(dev_priv) ||
IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
return 128 * 1024;
else if (INTEL_INFO(dev_priv)->gen >= 4)
return 4 * 1024;
else
return 0;
}
static unsigned int intel_surf_alignment(const struct drm_i915_private *dev_priv,
uint64_t fb_modifier)
{
switch (fb_modifier) {
case DRM_FORMAT_MOD_NONE:
return intel_linear_alignment(dev_priv);
case I915_FORMAT_MOD_X_TILED:
if (INTEL_INFO(dev_priv)->gen >= 9)
return 256 * 1024;
return 0;
case I915_FORMAT_MOD_Y_TILED:
case I915_FORMAT_MOD_Yf_TILED:
return 1 * 1024 * 1024;
default:
MISSING_CASE(fb_modifier);
return 0;
}
}
int
intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
unsigned int rotation)
{
struct drm_device *dev = fb->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj = intel_fb_obj(fb);
struct i915_ggtt_view view;
u32 alignment;
int ret;
WARN_ON(!mutex_is_locked(&dev->struct_mutex));
alignment = intel_surf_alignment(dev_priv, fb->modifier[0]);
intel_fill_fb_ggtt_view(&view, fb, rotation);
/* Note that the w/a also requires 64 PTE of padding following the
* bo. We currently fill all unused PTE with the shadow page and so
* we should always have valid PTE following the scanout preventing
* the VT-d warning.
*/
if (need_vtd_wa(dev) && alignment < 256 * 1024)
alignment = 256 * 1024;
drm/i915: fix plane/cursor handling when runtime suspended If we're runtime suspended and try to use the plane interfaces, we will get a lot of WARNs saying we did the wrong thing. We need to get runtime PM references to pin the objects, and to change the fences. The pin functions are the ideal places for this, but intel_crtc_cursor_set_obj() doesn't call them, so we also have to add get/put calls inside it. There is no problem if we runtime suspend right after these functions are finished, because the registers written are forwarded to system memory. Note: for a complete fix of the cursor-dpms test case, we also need the patch named "drm/i915: Don't try to enable cursor from setplane when crtc is disabled". v2: - Narrow the put/get calls on intel_crtc_cursor_set_obj() (Daniel) v3: - Make get/put also surround the fence and unpin calls (Daniel and Ville). - Merge all the plane changes into a single patch since they're the same fix. - Add the comment requested by Daniel. v4: - Remove spurious whitespace (Ville). v5: - Remove intel_crtc_update_cursor() chunk since Ville did an equivalent fix in another patch (Ville). v6: - Remove unpin chunk: it will be on a separate patch (Ville, Chris, Daniel). v7: - Same thing, new color. Testcase: igt/pm_rpm/cursor Testcase: igt/pm_rpm/cursor-dpms Testcase: igt/pm_rpm/legacy-planes Testcase: igt/pm_rpm/legacy-planes-dpms Testcase: igt/pm_rpm/universal-planes Testcase: igt/pm_rpm/universal-planes-dpms Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=81645 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=82603 Cc: stable@vger.kernel.org Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
2014-08-15 15:59:32 -03:00
/*
* Global gtt pte registers are special registers which actually forward
* writes to a chunk of system memory. Which means that there is no risk
* that the register values disappear as soon as we call
* intel_runtime_pm_put(), so it is correct to wrap only the
* pin/unpin/fence and not more.
*/
intel_runtime_pm_get(dev_priv);
ret = i915_gem_object_pin_to_display_plane(obj, alignment,
&view);
if (ret)
goto err_pm;
/* Install a fence for tiled scan-out. Pre-i965 always needs a
* fence, whereas 965+ only requires a fence if using
* framebuffer compression. For simplicity, we always install
* a fence as the cost is not that onerous.
*/
if (view.type == I915_GGTT_VIEW_NORMAL) {
ret = i915_gem_object_get_fence(obj);
if (ret == -EDEADLK) {
/*
* -EDEADLK means there are no free fences
* no pending flips.
*
* This is propagated to atomic, but it uses
* -EDEADLK to force a locking recovery, so
* change the returned error to -EBUSY.
*/
ret = -EBUSY;
goto err_unpin;
} else if (ret)
goto err_unpin;
i915_gem_object_pin_fence(obj);
}
drm/i915: fix plane/cursor handling when runtime suspended If we're runtime suspended and try to use the plane interfaces, we will get a lot of WARNs saying we did the wrong thing. We need to get runtime PM references to pin the objects, and to change the fences. The pin functions are the ideal places for this, but intel_crtc_cursor_set_obj() doesn't call them, so we also have to add get/put calls inside it. There is no problem if we runtime suspend right after these functions are finished, because the registers written are forwarded to system memory. Note: for a complete fix of the cursor-dpms test case, we also need the patch named "drm/i915: Don't try to enable cursor from setplane when crtc is disabled". v2: - Narrow the put/get calls on intel_crtc_cursor_set_obj() (Daniel) v3: - Make get/put also surround the fence and unpin calls (Daniel and Ville). - Merge all the plane changes into a single patch since they're the same fix. - Add the comment requested by Daniel. v4: - Remove spurious whitespace (Ville). v5: - Remove intel_crtc_update_cursor() chunk since Ville did an equivalent fix in another patch (Ville). v6: - Remove unpin chunk: it will be on a separate patch (Ville, Chris, Daniel). v7: - Same thing, new color. Testcase: igt/pm_rpm/cursor Testcase: igt/pm_rpm/cursor-dpms Testcase: igt/pm_rpm/legacy-planes Testcase: igt/pm_rpm/legacy-planes-dpms Testcase: igt/pm_rpm/universal-planes Testcase: igt/pm_rpm/universal-planes-dpms Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=81645 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=82603 Cc: stable@vger.kernel.org Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
2014-08-15 15:59:32 -03:00
intel_runtime_pm_put(dev_priv);
return 0;
err_unpin:
i915_gem_object_unpin_from_display_plane(obj, &view);
err_pm:
drm/i915: fix plane/cursor handling when runtime suspended If we're runtime suspended and try to use the plane interfaces, we will get a lot of WARNs saying we did the wrong thing. We need to get runtime PM references to pin the objects, and to change the fences. The pin functions are the ideal places for this, but intel_crtc_cursor_set_obj() doesn't call them, so we also have to add get/put calls inside it. There is no problem if we runtime suspend right after these functions are finished, because the registers written are forwarded to system memory. Note: for a complete fix of the cursor-dpms test case, we also need the patch named "drm/i915: Don't try to enable cursor from setplane when crtc is disabled". v2: - Narrow the put/get calls on intel_crtc_cursor_set_obj() (Daniel) v3: - Make get/put also surround the fence and unpin calls (Daniel and Ville). - Merge all the plane changes into a single patch since they're the same fix. - Add the comment requested by Daniel. v4: - Remove spurious whitespace (Ville). v5: - Remove intel_crtc_update_cursor() chunk since Ville did an equivalent fix in another patch (Ville). v6: - Remove unpin chunk: it will be on a separate patch (Ville, Chris, Daniel). v7: - Same thing, new color. Testcase: igt/pm_rpm/cursor Testcase: igt/pm_rpm/cursor-dpms Testcase: igt/pm_rpm/legacy-planes Testcase: igt/pm_rpm/legacy-planes-dpms Testcase: igt/pm_rpm/universal-planes Testcase: igt/pm_rpm/universal-planes-dpms Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=81645 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=82603 Cc: stable@vger.kernel.org Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
2014-08-15 15:59:32 -03:00
intel_runtime_pm_put(dev_priv);
return ret;
}
void intel_unpin_fb_obj(struct drm_framebuffer *fb, unsigned int rotation)
{
struct drm_i915_gem_object *obj = intel_fb_obj(fb);
struct i915_ggtt_view view;
WARN_ON(!mutex_is_locked(&obj->base.dev->struct_mutex));
intel_fill_fb_ggtt_view(&view, fb, rotation);
if (view.type == I915_GGTT_VIEW_NORMAL)
i915_gem_object_unpin_fence(obj);
i915_gem_object_unpin_from_display_plane(obj, &view);
}
/*
* Adjust the tile offset by moving the difference into
* the x/y offsets.
*
* Input tile dimensions and pitch must already be
* rotated to match x and y, and in pixel units.
*/
static u32 intel_adjust_tile_offset(int *x, int *y,
unsigned int tile_width,
unsigned int tile_height,
unsigned int tile_size,
unsigned int pitch_tiles,
u32 old_offset,
u32 new_offset)
{
unsigned int tiles;
WARN_ON(old_offset & (tile_size - 1));
WARN_ON(new_offset & (tile_size - 1));
WARN_ON(new_offset > old_offset);
tiles = (old_offset - new_offset) / tile_size;
*y += tiles / pitch_tiles * tile_height;
*x += tiles % pitch_tiles * tile_width;
return new_offset;
}
/*
* Computes the linear offset to the base tile and adjusts
* x, y. bytes per pixel is assumed to be a power-of-two.
*
* In the 90/270 rotated case, x and y are assumed
* to be already rotated to match the rotated GTT view, and
* pitch is the tile_height aligned framebuffer height.
*/
u32 intel_compute_tile_offset(int *x, int *y,
const struct drm_framebuffer *fb, int plane,
unsigned int pitch,
unsigned int rotation)
{
const struct drm_i915_private *dev_priv = to_i915(fb->dev);
uint64_t fb_modifier = fb->modifier[plane];
unsigned int cpp = drm_format_plane_cpp(fb->pixel_format, plane);
u32 offset, offset_aligned, alignment;
alignment = intel_surf_alignment(dev_priv, fb_modifier);
if (alignment)
alignment--;
if (fb_modifier != DRM_FORMAT_MOD_NONE) {
unsigned int tile_size, tile_width, tile_height;
unsigned int tile_rows, tiles, pitch_tiles;
tile_size = intel_tile_size(dev_priv);
intel_tile_dims(dev_priv, &tile_width, &tile_height,
fb_modifier, cpp);
if (intel_rotation_90_or_270(rotation)) {
pitch_tiles = pitch / tile_height;
swap(tile_width, tile_height);
} else {
pitch_tiles = pitch / (tile_width * cpp);
}
tile_rows = *y / tile_height;
*y %= tile_height;
tiles = *x / tile_width;
*x %= tile_width;
offset = (tile_rows * pitch_tiles + tiles) * tile_size;
offset_aligned = offset & ~alignment;
intel_adjust_tile_offset(x, y, tile_width, tile_height,
tile_size, pitch_tiles,
offset, offset_aligned);
} else {
offset = *y * pitch + *x * cpp;
offset_aligned = offset & ~alignment;
*y = (offset & alignment) / pitch;
*x = ((offset & alignment) - *y * pitch) / cpp;
}
return offset_aligned;
}
static int i9xx_format_to_fourcc(int format)
{
switch (format) {
case DISPPLANE_8BPP:
return DRM_FORMAT_C8;
case DISPPLANE_BGRX555:
return DRM_FORMAT_XRGB1555;
case DISPPLANE_BGRX565:
return DRM_FORMAT_RGB565;
default:
case DISPPLANE_BGRX888:
return DRM_FORMAT_XRGB8888;
case DISPPLANE_RGBX888:
return DRM_FORMAT_XBGR8888;
case DISPPLANE_BGRX101010:
return DRM_FORMAT_XRGB2101010;
case DISPPLANE_RGBX101010:
return DRM_FORMAT_XBGR2101010;
}
}
static int skl_format_to_fourcc(int format, bool rgb_order, bool alpha)
{
switch (format) {
case PLANE_CTL_FORMAT_RGB_565:
return DRM_FORMAT_RGB565;
default:
case PLANE_CTL_FORMAT_XRGB_8888:
if (rgb_order) {
if (alpha)
return DRM_FORMAT_ABGR8888;
else
return DRM_FORMAT_XBGR8888;
} else {
if (alpha)
return DRM_FORMAT_ARGB8888;
else
return DRM_FORMAT_XRGB8888;
}
case PLANE_CTL_FORMAT_XRGB_2101010:
if (rgb_order)
return DRM_FORMAT_XBGR2101010;
else
return DRM_FORMAT_XRGB2101010;
}
}
static bool
intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
struct intel_initial_plane_config *plane_config)
{
struct drm_device *dev = crtc->base.dev;
drm/i915: don't allocate fbcon from stolen memory if it's too big Technology has evolved and now we have eDP panels with 3200x1800 resolution. In the meantime, the BIOS guys didn't change the default 32mb for stolen memory. On top of that, we can't assume our users will be able to increase the default stolen memory size to more than 32mb - I'm not even sure all BIOSes allow that. So just the fbcon buffer alone eats 22mb of my stolen memroy, and due to the BDW/SKL restriction of not using the last 8mb of stolen memory, all that's left for FBC is 2mb! Since fbcon is not the coolest feature ever, I think it's better to save our precious stolen resource to FBC and the other guys. On the other hand, we really want to use as much stolen memory as possible, since on some older systems the stolen memory may be a considerable percentage of the total available memory. This patch tries to achieve a little balance using a simple heuristic: if the fbcon wants more than half of the available stolen memory, don't use stolen memory in order to leave some for FBC and the other features. The long term plan should be to implement a way to set priorities for stolen memory allocation and then evict low priority users when the high priority ones need the memory. While we still don't have that, let's try to make FBC usable with the simple solution. Cc: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-09-23 12:52:23 -03:00
struct drm_i915_private *dev_priv = to_i915(dev);
struct i915_ggtt *ggtt = &dev_priv->ggtt;
struct drm_i915_gem_object *obj = NULL;
struct drm_mode_fb_cmd2 mode_cmd = { 0 };
struct drm_framebuffer *fb = &plane_config->fb->base;
u32 base_aligned = round_down(plane_config->base, PAGE_SIZE);
u32 size_aligned = round_up(plane_config->base + plane_config->size,
PAGE_SIZE);
size_aligned -= base_aligned;
if (plane_config->size == 0)
return false;
drm/i915: don't allocate fbcon from stolen memory if it's too big Technology has evolved and now we have eDP panels with 3200x1800 resolution. In the meantime, the BIOS guys didn't change the default 32mb for stolen memory. On top of that, we can't assume our users will be able to increase the default stolen memory size to more than 32mb - I'm not even sure all BIOSes allow that. So just the fbcon buffer alone eats 22mb of my stolen memroy, and due to the BDW/SKL restriction of not using the last 8mb of stolen memory, all that's left for FBC is 2mb! Since fbcon is not the coolest feature ever, I think it's better to save our precious stolen resource to FBC and the other guys. On the other hand, we really want to use as much stolen memory as possible, since on some older systems the stolen memory may be a considerable percentage of the total available memory. This patch tries to achieve a little balance using a simple heuristic: if the fbcon wants more than half of the available stolen memory, don't use stolen memory in order to leave some for FBC and the other features. The long term plan should be to implement a way to set priorities for stolen memory allocation and then evict low priority users when the high priority ones need the memory. While we still don't have that, let's try to make FBC usable with the simple solution. Cc: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-09-23 12:52:23 -03:00
/* If the FB is too big, just don't use it since fbdev is not very
* important and we should probably use that space with FBC or other
* features. */
if (size_aligned * 2 > ggtt->stolen_usable_size)
drm/i915: don't allocate fbcon from stolen memory if it's too big Technology has evolved and now we have eDP panels with 3200x1800 resolution. In the meantime, the BIOS guys didn't change the default 32mb for stolen memory. On top of that, we can't assume our users will be able to increase the default stolen memory size to more than 32mb - I'm not even sure all BIOSes allow that. So just the fbcon buffer alone eats 22mb of my stolen memroy, and due to the BDW/SKL restriction of not using the last 8mb of stolen memory, all that's left for FBC is 2mb! Since fbcon is not the coolest feature ever, I think it's better to save our precious stolen resource to FBC and the other guys. On the other hand, we really want to use as much stolen memory as possible, since on some older systems the stolen memory may be a considerable percentage of the total available memory. This patch tries to achieve a little balance using a simple heuristic: if the fbcon wants more than half of the available stolen memory, don't use stolen memory in order to leave some for FBC and the other features. The long term plan should be to implement a way to set priorities for stolen memory allocation and then evict low priority users when the high priority ones need the memory. While we still don't have that, let's try to make FBC usable with the simple solution. Cc: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-09-23 12:52:23 -03:00
return false;
mutex_lock(&dev->struct_mutex);
obj = i915_gem_object_create_stolen_for_preallocated(dev,
base_aligned,
base_aligned,
size_aligned);
if (!obj) {
mutex_unlock(&dev->struct_mutex);
return false;
}
obj->tiling_mode = plane_config->tiling;
if (obj->tiling_mode == I915_TILING_X)
obj->stride = fb->pitches[0];
mode_cmd.pixel_format = fb->pixel_format;
mode_cmd.width = fb->width;
mode_cmd.height = fb->height;
mode_cmd.pitches[0] = fb->pitches[0];
mode_cmd.modifier[0] = fb->modifier[0];
mode_cmd.flags = DRM_MODE_FB_MODIFIERS;
if (intel_framebuffer_init(dev, to_intel_framebuffer(fb),
&mode_cmd, obj)) {
DRM_DEBUG_KMS("intel fb init failed\n");
goto out_unref_obj;
}
mutex_unlock(&dev->struct_mutex);
DRM_DEBUG_KMS("initial plane fb obj %p\n", obj);
return true;
out_unref_obj:
drm_gem_object_unreference(&obj->base);
mutex_unlock(&dev->struct_mutex);
return false;
}
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
/* Update plane->state->fb to match plane->fb after driver-internal updates */
static void
update_state_fb(struct drm_plane *plane)
{
if (plane->fb == plane->state->fb)
return;
if (plane->state->fb)
drm_framebuffer_unreference(plane->state->fb);
plane->state->fb = plane->fb;
if (plane->state->fb)
drm_framebuffer_reference(plane->state->fb);
}
static void
intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
struct intel_initial_plane_config *plane_config)
{
struct drm_device *dev = intel_crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *c;
struct intel_crtc *i;
struct drm_i915_gem_object *obj;
struct drm_plane *primary = intel_crtc->base.primary;
struct drm_plane_state *plane_state = primary->state;
struct drm_crtc_state *crtc_state = intel_crtc->base.state;
struct intel_plane *intel_plane = to_intel_plane(primary);
struct intel_plane_state *intel_state =
to_intel_plane_state(plane_state);
struct drm_framebuffer *fb;
if (!plane_config->fb)
return;
if (intel_alloc_initial_plane_obj(intel_crtc, plane_config)) {
fb = &plane_config->fb->base;
goto valid_fb;
drm/i915: Don't try to reference the fb in get_initial_plane_config() Tvrtko noticed a new warning on boot: WARNING: CPU: 1 PID: 353 at include/linux/kref.h:47 drm_framebuffer_reference+0x6c/0x80 [drm]() Call Trace: [<ffffffff8161f10c>] dump_stack+0x4f/0x7b [<ffffffff81052caa>] warn_slowpath_common+0xaa/0xd0 [<ffffffff81052d8a>] warn_slowpath_null+0x1a/0x20 [<ffffffffa00d035c>] drm_framebuffer_reference+0x6c/0x80 [drm] [<ffffffffa01c0df7>] update_state_fb.isra.54+0x47/0x50 [i915] [<ffffffffa01ccd5c>] skylake_get_initial_plane_config+0x93c/0x950 [i915] [<ffffffffa01e8721>] intel_modeset_init+0x1551/0x17c0 [i915] [<ffffffffa02476e0>] i915_driver_load+0xed0/0x11e0 [i915] [<ffffffff81627aa1>] ? _raw_spin_unlock_irqrestore+0x51/0x70 [<ffffffffa00ca8b7>] drm_dev_register+0x77/0x110 [drm] [<ffffffffa00cda3b>] drm_get_pci_dev+0x11b/0x1f0 [drm] [<ffffffff81098e3d>] ? trace_hardirqs_on+0xd/0x10 [<ffffffff81627aa1>] ? _raw_spin_unlock_irqrestore+0x51/0x70 [<ffffffffa0145276>] i915_pci_probe+0x56/0x60 [i915] [<ffffffff813ad59c>] pci_device_probe+0x7c/0x100 [<ffffffff81466aad>] driver_probe_device+0x16d/0x380 We cannot take a reference at this point, not before intel_framebuffer_init() and the underlying drm_framebuffer_init(). Introduced in: commit 706dc7b549175e47f23e913b7f1e52874a7d0f56 Author: Matt Roper <matthew.d.roper@intel.com> Date: Tue Feb 3 13:10:04 2015 -0800 drm/i915: Ensure plane->state->fb stays in sync with plane->fb v2: Don't move update_state_fb(). It was moved around because I originally put update_state_fb() in intel_alloc_plane_obj() before finding a better place. (Matt) Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Reported-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Matt Roper <matthew.d.roper@intel.com> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-02-05 18:30:20 +00:00
}
kfree(plane_config->fb);
/*
* Failed to alloc the obj, check to see if we should share
* an fb with another CRTC instead
*/
for_each_crtc(dev, c) {
i = to_intel_crtc(c);
if (c == &intel_crtc->base)
continue;
if (!i->active)
continue;
fb = c->primary->fb;
if (!fb)
continue;
obj = intel_fb_obj(fb);
if (i915_gem_obj_ggtt_offset(obj) == plane_config->base) {
drm_framebuffer_reference(fb);
goto valid_fb;
}
}
/*
* We've failed to reconstruct the BIOS FB. Current display state
* indicates that the primary plane is visible, but has a NULL FB,
* which will lead to problems later if we don't fix it up. The
* simplest solution is to just disable the primary plane now and
* pretend the BIOS never had it enabled.
*/
to_intel_plane_state(plane_state)->visible = false;
crtc_state->plane_mask &= ~(1 << drm_plane_index(primary));
intel_pre_disable_primary_noatomic(&intel_crtc->base);
intel_plane->disable_plane(primary, &intel_crtc->base);
return;
valid_fb:
plane_state->src_x = 0;
plane_state->src_y = 0;
plane_state->src_w = fb->width << 16;
plane_state->src_h = fb->height << 16;
plane_state->crtc_x = 0;
plane_state->crtc_y = 0;
plane_state->crtc_w = fb->width;
plane_state->crtc_h = fb->height;
intel_state->src.x1 = plane_state->src_x;
intel_state->src.y1 = plane_state->src_y;
intel_state->src.x2 = plane_state->src_x + plane_state->src_w;
intel_state->src.y2 = plane_state->src_y + plane_state->src_h;
intel_state->dst.x1 = plane_state->crtc_x;
intel_state->dst.y1 = plane_state->crtc_y;
intel_state->dst.x2 = plane_state->crtc_x + plane_state->crtc_w;
intel_state->dst.y2 = plane_state->crtc_y + plane_state->crtc_h;
obj = intel_fb_obj(fb);
if (obj->tiling_mode != I915_TILING_NONE)
dev_priv->preserve_bios_swizzle = true;
drm_framebuffer_reference(fb);
primary->fb = primary->state->fb = fb;
primary->crtc = primary->state->crtc = &intel_crtc->base;
intel_crtc->base.state->plane_mask |= (1 << drm_plane_index(primary));
obj->frontbuffer_bits |= to_intel_plane(primary)->frontbuffer_bit;
}
static void i9xx_update_primary_plane(struct drm_plane *primary,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
struct drm_device *dev = primary->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
struct drm_framebuffer *fb = plane_state->base.fb;
struct drm_i915_gem_object *obj = intel_fb_obj(fb);
int plane = intel_crtc->plane;
u32 linear_offset;
u32 dspcntr;
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
i915_reg_t reg = DSPCNTR(plane);
unsigned int rotation = plane_state->base.rotation;
int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
int x = plane_state->src.x1 >> 16;
int y = plane_state->src.y1 >> 16;
dspcntr = DISPPLANE_GAMMA_ENABLE;
dspcntr |= DISPLAY_PLANE_ENABLE;
if (INTEL_INFO(dev)->gen < 4) {
if (intel_crtc->pipe == PIPE_B)
dspcntr |= DISPPLANE_SEL_PIPE_B;
/* pipesrc and dspsize control the size that is scaled from,
* which should always be the user's requested size.
*/
I915_WRITE(DSPSIZE(plane),
((crtc_state->pipe_src_h - 1) << 16) |
(crtc_state->pipe_src_w - 1));
I915_WRITE(DSPPOS(plane), 0);
} else if (IS_CHERRYVIEW(dev) && plane == PLANE_B) {
I915_WRITE(PRIMSIZE(plane),
((crtc_state->pipe_src_h - 1) << 16) |
(crtc_state->pipe_src_w - 1));
I915_WRITE(PRIMPOS(plane), 0);
I915_WRITE(PRIMCNSTALPHA(plane), 0);
}
switch (fb->pixel_format) {
case DRM_FORMAT_C8:
dspcntr |= DISPPLANE_8BPP;
break;
case DRM_FORMAT_XRGB1555:
dspcntr |= DISPPLANE_BGRX555;
break;
case DRM_FORMAT_RGB565:
dspcntr |= DISPPLANE_BGRX565;
break;
case DRM_FORMAT_XRGB8888:
dspcntr |= DISPPLANE_BGRX888;
break;
case DRM_FORMAT_XBGR8888:
dspcntr |= DISPPLANE_RGBX888;
break;
case DRM_FORMAT_XRGB2101010:
dspcntr |= DISPPLANE_BGRX101010;
break;
case DRM_FORMAT_XBGR2101010:
dspcntr |= DISPPLANE_RGBX101010;
break;
default:
BUG();
}
if (INTEL_INFO(dev)->gen >= 4 &&
obj->tiling_mode != I915_TILING_NONE)
dspcntr |= DISPPLANE_TILED;
if (IS_G4X(dev))
dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
linear_offset = y * fb->pitches[0] + x * cpp;
if (INTEL_INFO(dev)->gen >= 4) {
intel_crtc->dspaddr_offset =
intel_compute_tile_offset(&x, &y, fb, 0,
fb->pitches[0], rotation);
linear_offset -= intel_crtc->dspaddr_offset;
} else {
intel_crtc->dspaddr_offset = linear_offset;
}
if (rotation == BIT(DRM_ROTATE_180)) {
drm/i915: Add 180 degree primary plane rotation support Primary planes support 180 degree rotation. Expose the feature through rotation drm property. v2: Calculating linear/tiled offsets based on pipe source width and height. Added 180 degree rotation support in ironlake_update_plane. v3: Checking if CRTC is active before issueing update_plane. Added wait for vblank to make sure we dont overtake page flips. Disabling FBC since it does not work with rotated planes. v4: Updated rotation checks for pending flips, fbc disable. Creating rotation property only for Gen4 onwards. Property resetting as part of lastclose. v5: Resetting property in i915_driver_lastclose properly for planes and crtcs. Fixed linear offset calculation that was off by 1 w.r.t width in i9xx_update_plane and ironlake_update_plane. Removed tab based indentation and unnecessary braces in intel_crtc_set_property and intel_update_fbc. FBC and flip related checks should be done only for valid crtcs. v6: Minor nits in FBC disable checks for comments in intel_crtc_set_property and positioning the disable code in intel_update_fbc. v7: In case rotation property on inactive crtc is updated, we return successfully printing debug log as crtc is inactive and only property change is preserved. v8: update_plane is changed to update_primary_plane, crtc->fb is changed to crtc->primary->fb and return value of update_primary_plane is ignored. v9: added rotation property to primary plane instead of crtc. Removing reset of rotation property from lastclose. rotation_property is moved to drm_mode_config, so drm layer will take care of resetting. Adding updation of fbc when rotation is set to 0. Allowing rotation only if value is different than old one. v10: Calling intel_primary_plane_setplane instead of update_primary_plane in set_property(Daniel). v11: Using same set_property function for both primary and sprite, Adding primary plane specific code in the same function (Matt). v12: Removing disabling/ enabling of fbc from set_property because it is done from intel_pipe_set_base. Other formatting v13: we need to call disable_fbc before changing the rotation to 180, disable_fbc from intel_pipe_set_base gets called very late, that will be used to re-enable fbc if rotation is set to 0 (Ville). Testcase: igt/kms_rotation_crc Signed-off-by: Uma Shankar <uma.shankar@intel.com> Signed-off-by: Sagar Kamble <sagar.a.kamble@intel.com> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com> [danvet: Add FIXME to explain why we need the open-coded update_fbc hunk to disable fbc when rotated 180 degree. And make checkpatch happier.] Acked-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-08-22 14:06:04 +05:30
dspcntr |= DISPPLANE_ROTATE_180;
x += (crtc_state->pipe_src_w - 1);
y += (crtc_state->pipe_src_h - 1);
drm/i915: Add 180 degree primary plane rotation support Primary planes support 180 degree rotation. Expose the feature through rotation drm property. v2: Calculating linear/tiled offsets based on pipe source width and height. Added 180 degree rotation support in ironlake_update_plane. v3: Checking if CRTC is active before issueing update_plane. Added wait for vblank to make sure we dont overtake page flips. Disabling FBC since it does not work with rotated planes. v4: Updated rotation checks for pending flips, fbc disable. Creating rotation property only for Gen4 onwards. Property resetting as part of lastclose. v5: Resetting property in i915_driver_lastclose properly for planes and crtcs. Fixed linear offset calculation that was off by 1 w.r.t width in i9xx_update_plane and ironlake_update_plane. Removed tab based indentation and unnecessary braces in intel_crtc_set_property and intel_update_fbc. FBC and flip related checks should be done only for valid crtcs. v6: Minor nits in FBC disable checks for comments in intel_crtc_set_property and positioning the disable code in intel_update_fbc. v7: In case rotation property on inactive crtc is updated, we return successfully printing debug log as crtc is inactive and only property change is preserved. v8: update_plane is changed to update_primary_plane, crtc->fb is changed to crtc->primary->fb and return value of update_primary_plane is ignored. v9: added rotation property to primary plane instead of crtc. Removing reset of rotation property from lastclose. rotation_property is moved to drm_mode_config, so drm layer will take care of resetting. Adding updation of fbc when rotation is set to 0. Allowing rotation only if value is different than old one. v10: Calling intel_primary_plane_setplane instead of update_primary_plane in set_property(Daniel). v11: Using same set_property function for both primary and sprite, Adding primary plane specific code in the same function (Matt). v12: Removing disabling/ enabling of fbc from set_property because it is done from intel_pipe_set_base. Other formatting v13: we need to call disable_fbc before changing the rotation to 180, disable_fbc from intel_pipe_set_base gets called very late, that will be used to re-enable fbc if rotation is set to 0 (Ville). Testcase: igt/kms_rotation_crc Signed-off-by: Uma Shankar <uma.shankar@intel.com> Signed-off-by: Sagar Kamble <sagar.a.kamble@intel.com> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com> [danvet: Add FIXME to explain why we need the open-coded update_fbc hunk to disable fbc when rotated 180 degree. And make checkpatch happier.] Acked-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-08-22 14:06:04 +05:30
/* Finding the last pixel of the last line of the display
data and adding to linear_offset*/
linear_offset +=
(crtc_state->pipe_src_h - 1) * fb->pitches[0] +
(crtc_state->pipe_src_w - 1) * cpp;
drm/i915: Add 180 degree primary plane rotation support Primary planes support 180 degree rotation. Expose the feature through rotation drm property. v2: Calculating linear/tiled offsets based on pipe source width and height. Added 180 degree rotation support in ironlake_update_plane. v3: Checking if CRTC is active before issueing update_plane. Added wait for vblank to make sure we dont overtake page flips. Disabling FBC since it does not work with rotated planes. v4: Updated rotation checks for pending flips, fbc disable. Creating rotation property only for Gen4 onwards. Property resetting as part of lastclose. v5: Resetting property in i915_driver_lastclose properly for planes and crtcs. Fixed linear offset calculation that was off by 1 w.r.t width in i9xx_update_plane and ironlake_update_plane. Removed tab based indentation and unnecessary braces in intel_crtc_set_property and intel_update_fbc. FBC and flip related checks should be done only for valid crtcs. v6: Minor nits in FBC disable checks for comments in intel_crtc_set_property and positioning the disable code in intel_update_fbc. v7: In case rotation property on inactive crtc is updated, we return successfully printing debug log as crtc is inactive and only property change is preserved. v8: update_plane is changed to update_primary_plane, crtc->fb is changed to crtc->primary->fb and return value of update_primary_plane is ignored. v9: added rotation property to primary plane instead of crtc. Removing reset of rotation property from lastclose. rotation_property is moved to drm_mode_config, so drm layer will take care of resetting. Adding updation of fbc when rotation is set to 0. Allowing rotation only if value is different than old one. v10: Calling intel_primary_plane_setplane instead of update_primary_plane in set_property(Daniel). v11: Using same set_property function for both primary and sprite, Adding primary plane specific code in the same function (Matt). v12: Removing disabling/ enabling of fbc from set_property because it is done from intel_pipe_set_base. Other formatting v13: we need to call disable_fbc before changing the rotation to 180, disable_fbc from intel_pipe_set_base gets called very late, that will be used to re-enable fbc if rotation is set to 0 (Ville). Testcase: igt/kms_rotation_crc Signed-off-by: Uma Shankar <uma.shankar@intel.com> Signed-off-by: Sagar Kamble <sagar.a.kamble@intel.com> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com> [danvet: Add FIXME to explain why we need the open-coded update_fbc hunk to disable fbc when rotated 180 degree. And make checkpatch happier.] Acked-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-08-22 14:06:04 +05:30
}
intel_crtc->adjusted_x = x;
intel_crtc->adjusted_y = y;
drm/i915: Add 180 degree primary plane rotation support Primary planes support 180 degree rotation. Expose the feature through rotation drm property. v2: Calculating linear/tiled offsets based on pipe source width and height. Added 180 degree rotation support in ironlake_update_plane. v3: Checking if CRTC is active before issueing update_plane. Added wait for vblank to make sure we dont overtake page flips. Disabling FBC since it does not work with rotated planes. v4: Updated rotation checks for pending flips, fbc disable. Creating rotation property only for Gen4 onwards. Property resetting as part of lastclose. v5: Resetting property in i915_driver_lastclose properly for planes and crtcs. Fixed linear offset calculation that was off by 1 w.r.t width in i9xx_update_plane and ironlake_update_plane. Removed tab based indentation and unnecessary braces in intel_crtc_set_property and intel_update_fbc. FBC and flip related checks should be done only for valid crtcs. v6: Minor nits in FBC disable checks for comments in intel_crtc_set_property and positioning the disable code in intel_update_fbc. v7: In case rotation property on inactive crtc is updated, we return successfully printing debug log as crtc is inactive and only property change is preserved. v8: update_plane is changed to update_primary_plane, crtc->fb is changed to crtc->primary->fb and return value of update_primary_plane is ignored. v9: added rotation property to primary plane instead of crtc. Removing reset of rotation property from lastclose. rotation_property is moved to drm_mode_config, so drm layer will take care of resetting. Adding updation of fbc when rotation is set to 0. Allowing rotation only if value is different than old one. v10: Calling intel_primary_plane_setplane instead of update_primary_plane in set_property(Daniel). v11: Using same set_property function for both primary and sprite, Adding primary plane specific code in the same function (Matt). v12: Removing disabling/ enabling of fbc from set_property because it is done from intel_pipe_set_base. Other formatting v13: we need to call disable_fbc before changing the rotation to 180, disable_fbc from intel_pipe_set_base gets called very late, that will be used to re-enable fbc if rotation is set to 0 (Ville). Testcase: igt/kms_rotation_crc Signed-off-by: Uma Shankar <uma.shankar@intel.com> Signed-off-by: Sagar Kamble <sagar.a.kamble@intel.com> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com> [danvet: Add FIXME to explain why we need the open-coded update_fbc hunk to disable fbc when rotated 180 degree. And make checkpatch happier.] Acked-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-08-22 14:06:04 +05:30
I915_WRITE(reg, dspcntr);
I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
if (INTEL_INFO(dev)->gen >= 4) {
I915_WRITE(DSPSURF(plane),
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), i915_gem_obj_ggtt_offset(obj) + linear_offset);
POSTING_READ(reg);
}
static void i9xx_disable_primary_plane(struct drm_plane *primary,
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 plane = intel_crtc->plane;
I915_WRITE(DSPCNTR(plane), 0);
if (INTEL_INFO(dev_priv)->gen >= 4)
I915_WRITE(DSPSURF(plane), 0);
else
I915_WRITE(DSPADDR(plane), 0);
POSTING_READ(DSPCNTR(plane));
}
static void ironlake_update_primary_plane(struct drm_plane *primary,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
struct drm_device *dev = primary->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
struct drm_framebuffer *fb = plane_state->base.fb;
struct drm_i915_gem_object *obj = intel_fb_obj(fb);
int plane = intel_crtc->plane;
u32 linear_offset;
u32 dspcntr;
i915_reg_t reg = DSPCNTR(plane);
unsigned int rotation = plane_state->base.rotation;
int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
int x = plane_state->src.x1 >> 16;
int y = plane_state->src.y1 >> 16;
dspcntr = DISPPLANE_GAMMA_ENABLE;
dspcntr |= DISPLAY_PLANE_ENABLE;
if (IS_HASWELL(dev) || IS_BROADWELL(dev))
dspcntr |= DISPPLANE_PIPE_CSC_ENABLE;
switch (fb->pixel_format) {
case DRM_FORMAT_C8:
dspcntr |= DISPPLANE_8BPP;
break;
case DRM_FORMAT_RGB565:
dspcntr |= DISPPLANE_BGRX565;
break;
case DRM_FORMAT_XRGB8888:
dspcntr |= DISPPLANE_BGRX888;
break;
case DRM_FORMAT_XBGR8888:
dspcntr |= DISPPLANE_RGBX888;
break;
case DRM_FORMAT_XRGB2101010:
dspcntr |= DISPPLANE_BGRX101010;
break;
case DRM_FORMAT_XBGR2101010:
dspcntr |= DISPPLANE_RGBX101010;
break;
default:
BUG();
}
if (obj->tiling_mode != I915_TILING_NONE)
dspcntr |= DISPPLANE_TILED;
if (!IS_HASWELL(dev) && !IS_BROADWELL(dev))
dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
linear_offset = y * fb->pitches[0] + x * cpp;
intel_crtc->dspaddr_offset =
intel_compute_tile_offset(&x, &y, fb, 0,
fb->pitches[0], rotation);
linear_offset -= intel_crtc->dspaddr_offset;
if (rotation == BIT(DRM_ROTATE_180)) {
drm/i915: Add 180 degree primary plane rotation support Primary planes support 180 degree rotation. Expose the feature through rotation drm property. v2: Calculating linear/tiled offsets based on pipe source width and height. Added 180 degree rotation support in ironlake_update_plane. v3: Checking if CRTC is active before issueing update_plane. Added wait for vblank to make sure we dont overtake page flips. Disabling FBC since it does not work with rotated planes. v4: Updated rotation checks for pending flips, fbc disable. Creating rotation property only for Gen4 onwards. Property resetting as part of lastclose. v5: Resetting property in i915_driver_lastclose properly for planes and crtcs. Fixed linear offset calculation that was off by 1 w.r.t width in i9xx_update_plane and ironlake_update_plane. Removed tab based indentation and unnecessary braces in intel_crtc_set_property and intel_update_fbc. FBC and flip related checks should be done only for valid crtcs. v6: Minor nits in FBC disable checks for comments in intel_crtc_set_property and positioning the disable code in intel_update_fbc. v7: In case rotation property on inactive crtc is updated, we return successfully printing debug log as crtc is inactive and only property change is preserved. v8: update_plane is changed to update_primary_plane, crtc->fb is changed to crtc->primary->fb and return value of update_primary_plane is ignored. v9: added rotation property to primary plane instead of crtc. Removing reset of rotation property from lastclose. rotation_property is moved to drm_mode_config, so drm layer will take care of resetting. Adding updation of fbc when rotation is set to 0. Allowing rotation only if value is different than old one. v10: Calling intel_primary_plane_setplane instead of update_primary_plane in set_property(Daniel). v11: Using same set_property function for both primary and sprite, Adding primary plane specific code in the same function (Matt). v12: Removing disabling/ enabling of fbc from set_property because it is done from intel_pipe_set_base. Other formatting v13: we need to call disable_fbc before changing the rotation to 180, disable_fbc from intel_pipe_set_base gets called very late, that will be used to re-enable fbc if rotation is set to 0 (Ville). Testcase: igt/kms_rotation_crc Signed-off-by: Uma Shankar <uma.shankar@intel.com> Signed-off-by: Sagar Kamble <sagar.a.kamble@intel.com> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com> [danvet: Add FIXME to explain why we need the open-coded update_fbc hunk to disable fbc when rotated 180 degree. And make checkpatch happier.] Acked-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-08-22 14:06:04 +05:30
dspcntr |= DISPPLANE_ROTATE_180;
if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) {
x += (crtc_state->pipe_src_w - 1);
y += (crtc_state->pipe_src_h - 1);
drm/i915: Add 180 degree primary plane rotation support Primary planes support 180 degree rotation. Expose the feature through rotation drm property. v2: Calculating linear/tiled offsets based on pipe source width and height. Added 180 degree rotation support in ironlake_update_plane. v3: Checking if CRTC is active before issueing update_plane. Added wait for vblank to make sure we dont overtake page flips. Disabling FBC since it does not work with rotated planes. v4: Updated rotation checks for pending flips, fbc disable. Creating rotation property only for Gen4 onwards. Property resetting as part of lastclose. v5: Resetting property in i915_driver_lastclose properly for planes and crtcs. Fixed linear offset calculation that was off by 1 w.r.t width in i9xx_update_plane and ironlake_update_plane. Removed tab based indentation and unnecessary braces in intel_crtc_set_property and intel_update_fbc. FBC and flip related checks should be done only for valid crtcs. v6: Minor nits in FBC disable checks for comments in intel_crtc_set_property and positioning the disable code in intel_update_fbc. v7: In case rotation property on inactive crtc is updated, we return successfully printing debug log as crtc is inactive and only property change is preserved. v8: update_plane is changed to update_primary_plane, crtc->fb is changed to crtc->primary->fb and return value of update_primary_plane is ignored. v9: added rotation property to primary plane instead of crtc. Removing reset of rotation property from lastclose. rotation_property is moved to drm_mode_config, so drm layer will take care of resetting. Adding updation of fbc when rotation is set to 0. Allowing rotation only if value is different than old one. v10: Calling intel_primary_plane_setplane instead of update_primary_plane in set_property(Daniel). v11: Using same set_property function for both primary and sprite, Adding primary plane specific code in the same function (Matt). v12: Removing disabling/ enabling of fbc from set_property because it is done from intel_pipe_set_base. Other formatting v13: we need to call disable_fbc before changing the rotation to 180, disable_fbc from intel_pipe_set_base gets called very late, that will be used to re-enable fbc if rotation is set to 0 (Ville). Testcase: igt/kms_rotation_crc Signed-off-by: Uma Shankar <uma.shankar@intel.com> Signed-off-by: Sagar Kamble <sagar.a.kamble@intel.com> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com> [danvet: Add FIXME to explain why we need the open-coded update_fbc hunk to disable fbc when rotated 180 degree. And make checkpatch happier.] Acked-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-08-22 14:06:04 +05:30
/* Finding the last pixel of the last line of the display
data and adding to linear_offset*/
linear_offset +=
(crtc_state->pipe_src_h - 1) * fb->pitches[0] +
(crtc_state->pipe_src_w - 1) * cpp;
drm/i915: Add 180 degree primary plane rotation support Primary planes support 180 degree rotation. Expose the feature through rotation drm property. v2: Calculating linear/tiled offsets based on pipe source width and height. Added 180 degree rotation support in ironlake_update_plane. v3: Checking if CRTC is active before issueing update_plane. Added wait for vblank to make sure we dont overtake page flips. Disabling FBC since it does not work with rotated planes. v4: Updated rotation checks for pending flips, fbc disable. Creating rotation property only for Gen4 onwards. Property resetting as part of lastclose. v5: Resetting property in i915_driver_lastclose properly for planes and crtcs. Fixed linear offset calculation that was off by 1 w.r.t width in i9xx_update_plane and ironlake_update_plane. Removed tab based indentation and unnecessary braces in intel_crtc_set_property and intel_update_fbc. FBC and flip related checks should be done only for valid crtcs. v6: Minor nits in FBC disable checks for comments in intel_crtc_set_property and positioning the disable code in intel_update_fbc. v7: In case rotation property on inactive crtc is updated, we return successfully printing debug log as crtc is inactive and only property change is preserved. v8: update_plane is changed to update_primary_plane, crtc->fb is changed to crtc->primary->fb and return value of update_primary_plane is ignored. v9: added rotation property to primary plane instead of crtc. Removing reset of rotation property from lastclose. rotation_property is moved to drm_mode_config, so drm layer will take care of resetting. Adding updation of fbc when rotation is set to 0. Allowing rotation only if value is different than old one. v10: Calling intel_primary_plane_setplane instead of update_primary_plane in set_property(Daniel). v11: Using same set_property function for both primary and sprite, Adding primary plane specific code in the same function (Matt). v12: Removing disabling/ enabling of fbc from set_property because it is done from intel_pipe_set_base. Other formatting v13: we need to call disable_fbc before changing the rotation to 180, disable_fbc from intel_pipe_set_base gets called very late, that will be used to re-enable fbc if rotation is set to 0 (Ville). Testcase: igt/kms_rotation_crc Signed-off-by: Uma Shankar <uma.shankar@intel.com> Signed-off-by: Sagar Kamble <sagar.a.kamble@intel.com> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com> [danvet: Add FIXME to explain why we need the open-coded update_fbc hunk to disable fbc when rotated 180 degree. And make checkpatch happier.] Acked-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-08-22 14:06:04 +05:30
}
}
intel_crtc->adjusted_x = x;
intel_crtc->adjusted_y = y;
drm/i915: Add 180 degree primary plane rotation support Primary planes support 180 degree rotation. Expose the feature through rotation drm property. v2: Calculating linear/tiled offsets based on pipe source width and height. Added 180 degree rotation support in ironlake_update_plane. v3: Checking if CRTC is active before issueing update_plane. Added wait for vblank to make sure we dont overtake page flips. Disabling FBC since it does not work with rotated planes. v4: Updated rotation checks for pending flips, fbc disable. Creating rotation property only for Gen4 onwards. Property resetting as part of lastclose. v5: Resetting property in i915_driver_lastclose properly for planes and crtcs. Fixed linear offset calculation that was off by 1 w.r.t width in i9xx_update_plane and ironlake_update_plane. Removed tab based indentation and unnecessary braces in intel_crtc_set_property and intel_update_fbc. FBC and flip related checks should be done only for valid crtcs. v6: Minor nits in FBC disable checks for comments in intel_crtc_set_property and positioning the disable code in intel_update_fbc. v7: In case rotation property on inactive crtc is updated, we return successfully printing debug log as crtc is inactive and only property change is preserved. v8: update_plane is changed to update_primary_plane, crtc->fb is changed to crtc->primary->fb and return value of update_primary_plane is ignored. v9: added rotation property to primary plane instead of crtc. Removing reset of rotation property from lastclose. rotation_property is moved to drm_mode_config, so drm layer will take care of resetting. Adding updation of fbc when rotation is set to 0. Allowing rotation only if value is different than old one. v10: Calling intel_primary_plane_setplane instead of update_primary_plane in set_property(Daniel). v11: Using same set_property function for both primary and sprite, Adding primary plane specific code in the same function (Matt). v12: Removing disabling/ enabling of fbc from set_property because it is done from intel_pipe_set_base. Other formatting v13: we need to call disable_fbc before changing the rotation to 180, disable_fbc from intel_pipe_set_base gets called very late, that will be used to re-enable fbc if rotation is set to 0 (Ville). Testcase: igt/kms_rotation_crc Signed-off-by: Uma Shankar <uma.shankar@intel.com> Signed-off-by: Sagar Kamble <sagar.a.kamble@intel.com> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com> [danvet: Add FIXME to explain why we need the open-coded update_fbc hunk to disable fbc when rotated 180 degree. And make checkpatch happier.] Acked-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-08-22 14:06:04 +05:30
I915_WRITE(reg, dspcntr);
I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
I915_WRITE(DSPSURF(plane),
i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset);
if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
I915_WRITE(DSPOFFSET(plane), (y << 16) | x);
} else {
I915_WRITE(DSPTILEOFF(plane), (y << 16) | x);
I915_WRITE(DSPLINOFF(plane), linear_offset);
}
POSTING_READ(reg);
}
u32 intel_fb_stride_alignment(const struct drm_i915_private *dev_priv,
uint64_t fb_modifier, uint32_t pixel_format)
{
if (fb_modifier == DRM_FORMAT_MOD_NONE) {
return 64;
} else {
int cpp = drm_format_plane_cpp(pixel_format, 0);
return intel_tile_width_bytes(dev_priv, fb_modifier, cpp);
}
}
u32 intel_plane_obj_offset(struct intel_plane *intel_plane,
struct drm_i915_gem_object *obj,
unsigned int plane)
{
struct i915_ggtt_view view;
struct i915_vma *vma;
u64 offset;
drm/i915: Fix NULL plane->fb oops on SKL In this atomic age, we can't trust the plane->fb pointer anymore. It might get update too late. Instead we are supposed to use the plane_state->fb pointer instead. Let's do that in intel_plane_obj_offset() and avoid problems from dereferencing the potentially stale plane->fb pointer. Paulo found this with 'kms_frontbuffer_tracking --show-hidden --run-subtest nop-1p-rte' but it can be reproduced with just plain old kms_setplane. I was too lazy to bisect this, so not sure exactly when it broke. The most obvious candidate commit ce7f17285639 ("drm/i915: Fix i915_ggtt_view_equal to handle rotation correctly") was actually still fine, so it must have broken some time after that. Here's the resulting fireworks: BUG: unable to handle kernel NULL pointer dereference at (null) IP: [<ffffffffa02d2d9a>] intel_fill_fb_ggtt_view+0x1b/0x15a [i915] PGD 8a5f6067 PUD 8a5f5067 PMD 0 Oops: 0000 [#1] PREEMPT SMP Modules linked in: i915 i2c_algo_bit drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops drm intel_gtt agpgart netconsole mousedev hid_generic psmouse usbhid atkbd libps2 coretemp hwmon efi_pstore intel_rapl iosf_mbi x86_pkg_temp_thermal efivars pcspkr e1000e sdhci_pci ptp pps_core sdhci i2c_i801 mmc_core i2c_hid hid i8042 serio evdev sch_fq_codel ip_tables x_tables ipv6 autofs4 CPU: 1 PID: 260 Comm: kms_plane Not tainted 4.4.0-skl+ #171 Hardware name: Intel Corporation Skylake Client platform/Skylake Y LPDDR3 RVP3, BIOS SKLSE2R1.R00.B104.B00.1511030553 11/03/2015 task: ffff88008bde2d80 ti: ffff88008a6ec000 task.ti: ffff88008a6ec000 RIP: 0010:[<ffffffffa02d2d9a>] [<ffffffffa02d2d9a>] intel_fill_fb_ggtt_view+0x1b/0x15a [i915] RSP: 0018:ffff88008a6efa10 EFLAGS: 00010086 RAX: 0000000000000001 RBX: ffff8801674f4240 RCX: 0000000000000014 RDX: ffff88008a7440c0 RSI: 0000000000000000 RDI: ffff88008a6efa40 RBP: ffff88008a6efa30 R08: ffff88008bde3598 R09: 0000000000000001 R10: ffff88008b782000 R11: 0000000000000000 R12: 0000000000000000 R13: ffff88008a7440c0 R14: 0000000000000000 R15: ffff88008a7449c0 FS: 00007fa0c07a28c0(0000) GS:ffff88016ec40000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 000000008a6ff000 CR4: 00000000003406e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Stack: ffff8801674f4240 0000000000000000 ffff88008a7440c0 0000000000000000 ffff88008a6efaa0 ffffffffa02daf25 ffffffff814ec80e 0000000000070298 ffff8800850d0000 ffff88008a6efaa0 ffffffffa02c49c2 0000000000000002 Call Trace: [<ffffffffa02daf25>] intel_plane_obj_offset+0x2d/0xa9 [i915] [<ffffffff814ec80e>] ? _raw_spin_unlock_irqrestore+0x4b/0x60 [<ffffffffa02c49c2>] ? gen9_write32+0x2e8/0x3b8 [i915] [<ffffffffa02eecfc>] skl_update_plane+0x203/0x4c5 [i915] [<ffffffffa02ca1ab>] intel_plane_atomic_update+0x53/0x6a [i915] [<ffffffffa02494a4>] drm_atomic_helper_commit_planes_on_crtc+0x142/0x1d5 [drm_kms_helper] [<ffffffffa02de44b>] intel_atomic_commit+0x1262/0x1350 [i915] [<ffffffffa024a0ee>] ? __drm_atomic_helper_crtc_duplicate_state+0x2f/0x41 [drm_kms_helper] [<ffffffffa01ef089>] ? drm_atomic_check_only+0x3e3/0x552 [drm] [<ffffffffa01ef245>] drm_atomic_commit+0x4d/0x52 [drm] [<ffffffffa024996b>] drm_atomic_helper_update_plane+0xcb/0x118 [drm_kms_helper] [<ffffffffa01e42e8>] __setplane_internal+0x1c8/0x224 [drm] [<ffffffffa01e477f>] drm_mode_setplane+0x14e/0x172 [drm] [<ffffffffa01d8117>] drm_ioctl+0x265/0x3ad [drm] [<ffffffffa01e4631>] ? drm_mode_cursor_common+0x158/0x158 [drm] [<ffffffff810d00ab>] ? current_kernel_time64+0x5e/0x98 [<ffffffff810a76ea>] ? trace_hardirqs_on_caller+0x17a/0x196 [<ffffffff8119880f>] do_vfs_ioctl+0x42b/0x4ea [<ffffffff811a2b72>] ? __fget_light+0x4d/0x71 [<ffffffff81198911>] SyS_ioctl+0x43/0x61 [<ffffffff814ed057>] entry_SYSCALL_64_fastpath+0x12/0x6f Cc: drm-intel-fixes@lists.freedesktop.org Cc: Paulo Zanoni <paulo.r.zanoni@intel.com> Testcase: igt/kms_plane Reported-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1453220597-28973-1-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2016-01-19 18:23:17 +02:00
intel_fill_fb_ggtt_view(&view, intel_plane->base.state->fb,
intel_plane->base.state->rotation);
vma = i915_gem_obj_to_ggtt_view(obj, &view);
if (WARN(!vma, "ggtt vma for display object not found! (view=%u)\n",
view.type))
return -1;
offset = vma->node.start;
if (plane == 1) {
offset += vma->ggtt_view.params.rotated.uv_start_page *
PAGE_SIZE;
}
WARN_ON(upper_32_bits(offset));
return lower_32_bits(offset);
}
static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id)
{
struct drm_device *dev = intel_crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
I915_WRITE(SKL_PS_CTRL(intel_crtc->pipe, id), 0);
I915_WRITE(SKL_PS_WIN_POS(intel_crtc->pipe, id), 0);
I915_WRITE(SKL_PS_WIN_SZ(intel_crtc->pipe, id), 0);
}
/*
* This function detaches (aka. unbinds) unused scalers in hardware
*/
static void skl_detach_scalers(struct intel_crtc *intel_crtc)
{
struct intel_crtc_scaler_state *scaler_state;
int i;
scaler_state = &intel_crtc->config->scaler_state;
/* loop through and disable scalers that aren't in use */
for (i = 0; i < intel_crtc->num_scalers; i++) {
if (!scaler_state->scalers[i].in_use)
skl_detach_scaler(intel_crtc, i);
}
}
u32 skl_plane_ctl_format(uint32_t pixel_format)
{
switch (pixel_format) {
case DRM_FORMAT_C8:
return PLANE_CTL_FORMAT_INDEXED;
case DRM_FORMAT_RGB565:
return PLANE_CTL_FORMAT_RGB_565;
case DRM_FORMAT_XBGR8888:
return PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX;
case DRM_FORMAT_XRGB8888:
return PLANE_CTL_FORMAT_XRGB_8888;
/*
* XXX: For ARBG/ABGR formats we default to expecting scanout buffers
* to be already pre-multiplied. We need to add a knob (or a different
* DRM_FORMAT) for user-space to configure that.
*/
case DRM_FORMAT_ABGR8888:
return PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX |
PLANE_CTL_ALPHA_SW_PREMULTIPLY;
case DRM_FORMAT_ARGB8888:
return PLANE_CTL_FORMAT_XRGB_8888 |
PLANE_CTL_ALPHA_SW_PREMULTIPLY;
case DRM_FORMAT_XRGB2101010:
return PLANE_CTL_FORMAT_XRGB_2101010;
case DRM_FORMAT_XBGR2101010:
return PLANE_CTL_ORDER_RGBX | PLANE_CTL_FORMAT_XRGB_2101010;
case DRM_FORMAT_YUYV:
return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV;
case DRM_FORMAT_YVYU:
return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YVYU;
case DRM_FORMAT_UYVY:
return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY;
case DRM_FORMAT_VYUY:
return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY;
default:
MISSING_CASE(pixel_format);
}
return 0;
}
u32 skl_plane_ctl_tiling(uint64_t fb_modifier)
{
switch (fb_modifier) {
case DRM_FORMAT_MOD_NONE:
break;
case I915_FORMAT_MOD_X_TILED:
return PLANE_CTL_TILED_X;
case I915_FORMAT_MOD_Y_TILED:
return PLANE_CTL_TILED_Y;
case I915_FORMAT_MOD_Yf_TILED:
return PLANE_CTL_TILED_YF;
default:
MISSING_CASE(fb_modifier);
}
return 0;
}
u32 skl_plane_ctl_rotation(unsigned int rotation)
{
switch (rotation) {
case BIT(DRM_ROTATE_0):
break;
/*
* DRM_ROTATE_ is counter clockwise to stay compatible with Xrandr
* while i915 HW rotation is clockwise, thats why this swapping.
*/
case BIT(DRM_ROTATE_90):
return PLANE_CTL_ROTATE_270;
case BIT(DRM_ROTATE_180):
return PLANE_CTL_ROTATE_180;
case BIT(DRM_ROTATE_270):
return PLANE_CTL_ROTATE_90;
default:
MISSING_CASE(rotation);
}
return 0;
}
static void skylake_update_primary_plane(struct drm_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
struct drm_device *dev = plane->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
struct drm_framebuffer *fb = plane_state->base.fb;
struct drm_i915_gem_object *obj = intel_fb_obj(fb);
int pipe = intel_crtc->pipe;
u32 plane_ctl, stride_div, stride;
u32 tile_height, plane_offset, plane_size;
unsigned int rotation = plane_state->base.rotation;
int x_offset, y_offset;
u32 surf_addr;
int scaler_id = plane_state->scaler_id;
int src_x = plane_state->src.x1 >> 16;
int src_y = plane_state->src.y1 >> 16;
int src_w = drm_rect_width(&plane_state->src) >> 16;
int src_h = drm_rect_height(&plane_state->src) >> 16;
int dst_x = plane_state->dst.x1;
int dst_y = plane_state->dst.y1;
int dst_w = drm_rect_width(&plane_state->dst);
int dst_h = drm_rect_height(&plane_state->dst);
plane_ctl = PLANE_CTL_ENABLE |
PLANE_CTL_PIPE_GAMMA_ENABLE |
PLANE_CTL_PIPE_CSC_ENABLE;
plane_ctl |= skl_plane_ctl_format(fb->pixel_format);
plane_ctl |= skl_plane_ctl_tiling(fb->modifier[0]);
plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
plane_ctl |= skl_plane_ctl_rotation(rotation);
stride_div = intel_fb_stride_alignment(dev_priv, fb->modifier[0],
fb->pixel_format);
surf_addr = intel_plane_obj_offset(to_intel_plane(plane), obj, 0);
WARN_ON(drm_rect_width(&plane_state->src) == 0);
if (intel_rotation_90_or_270(rotation)) {
int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
/* stride = Surface height in tiles */
tile_height = intel_tile_height(dev_priv, fb->modifier[0], cpp);
stride = DIV_ROUND_UP(fb->height, tile_height);
x_offset = stride * tile_height - src_y - src_h;
y_offset = src_x;
plane_size = (src_w - 1) << 16 | (src_h - 1);
} else {
stride = fb->pitches[0] / stride_div;
x_offset = src_x;
y_offset = src_y;
plane_size = (src_h - 1) << 16 | (src_w - 1);
}
plane_offset = y_offset << 16 | x_offset;
intel_crtc->adjusted_x = x_offset;
intel_crtc->adjusted_y = y_offset;
I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
I915_WRITE(PLANE_OFFSET(pipe, 0), plane_offset);
I915_WRITE(PLANE_SIZE(pipe, 0), plane_size);
I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
if (scaler_id >= 0) {
uint32_t ps_ctrl = 0;
WARN_ON(!dst_w || !dst_h);
ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(0) |
crtc_state->scaler_state.scalers[scaler_id].mode;
I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (dst_x << 16) | dst_y);
I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id), (dst_w << 16) | dst_h);
I915_WRITE(PLANE_POS(pipe, 0), 0);
} else {
I915_WRITE(PLANE_POS(pipe, 0), (dst_y << 16) | dst_x);
}
I915_WRITE(PLANE_SURF(pipe, 0), surf_addr);
POSTING_READ(PLANE_SURF(pipe, 0));
}
static void skylake_disable_primary_plane(struct drm_plane *primary,
struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
int pipe = to_intel_crtc(crtc)->pipe;
I915_WRITE(PLANE_CTL(pipe, 0), 0);
I915_WRITE(PLANE_SURF(pipe, 0), 0);
POSTING_READ(PLANE_SURF(pipe, 0));
}
/* Assume fb object is pinned & idle & fenced and just update base pointers */
static int
intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
int x, int y, enum mode_set_atomic state)
{
/* Support for kgdboc is disabled, this needs a major rework. */
DRM_ERROR("legacy panic handler not supported any more.\n");
return -ENODEV;
}
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
static void intel_complete_page_flips(struct drm_i915_private *dev_priv)
{
struct intel_crtc *crtc;
for_each_intel_crtc(dev_priv->dev, crtc)
intel_finish_page_flip_cs(dev_priv, crtc->pipe);
}
static void intel_update_primary_planes(struct drm_device *dev)
{
struct drm_crtc *crtc;
for_each_crtc(dev, crtc) {
struct intel_plane *plane = to_intel_plane(crtc->primary);
struct intel_plane_state *plane_state;
drm_modeset_lock_crtc(crtc, &plane->base);
plane_state = to_intel_plane_state(plane->base.state);
if (plane_state->visible)
plane->update_plane(&plane->base,
to_intel_crtc_state(crtc->state),
plane_state);
drm_modeset_unlock_crtc(crtc);
}
}
void intel_prepare_reset(struct drm_i915_private *dev_priv)
{
/* no reset support for gen2 */
if (IS_GEN2(dev_priv))
return;
/* reset doesn't touch the display */
if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv))
return;
drm_modeset_lock_all(dev_priv->dev);
/*
* Disabling the crtcs gracefully seems nicer. Also the
* g33 docs say we should at least disable all the planes.
*/
intel_display_suspend(dev_priv->dev);
}
void intel_finish_reset(struct drm_i915_private *dev_priv)
{
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
/*
* Flips in the rings will be nuked by the reset,
* so complete all pending flips so that user space
* will get its events and not get stuck.
*/
intel_complete_page_flips(dev_priv);
/* no reset support for gen2 */
if (IS_GEN2(dev_priv))
return;
/* reset doesn't touch the display */
if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv)) {
/*
* Flips in the rings have been nuked by the reset,
* so update the base address of all primary
* planes to the the last fb to make sure we're
* showing the correct fb after a reset.
*
* FIXME: Atomic will make this obsolete since we won't schedule
* CS-based flips (which might get lost in gpu resets) any more.
*/
intel_update_primary_planes(dev_priv->dev);
return;
}
/*
* The display has been reset as well,
* so need a full re-initialization.
*/
intel_runtime_pm_disable_interrupts(dev_priv);
intel_runtime_pm_enable_interrupts(dev_priv);
intel_modeset_init_hw(dev_priv->dev);
spin_lock_irq(&dev_priv->irq_lock);
if (dev_priv->display.hpd_irq_setup)
drm/i915: Small display interrupt handlers tidy I have noticed some of our interrupt handlers use both dev and dev_priv while they could get away with only dev_priv in the huge majority of cases. Tidying that up had a cascading effect on changing functions prototypes, so relatively big churn factor, but I think it is for the better. For example even where changes cascade out of i915_irq.c, for functions prefixed with intel_, genX_ or <plat>_, it makes more sense to take dev_priv directly anyway. This allows us to eliminate local variables and intermixed usage of dev and dev_priv where only one is good enough. End result is shrinkage of both source and the resulting binary. i915.ko: - .text 000b0899 + .text 000b0619 Or if we look at the Gen8 display irq chain: -00000000000006ad t gen8_irq_handler +0000000000000663 t gen8_irq_handler -0000000000000028 T intel_opregion_asle_intr +0000000000000024 T intel_opregion_asle_intr -000000000000008c t ilk_hpd_irq_handler +000000000000007f t ilk_hpd_irq_handler -0000000000000116 T intel_check_page_flip +0000000000000112 T intel_check_page_flip -000000000000011a T intel_prepare_page_flip +0000000000000119 T intel_prepare_page_flip -0000000000000014 T intel_finish_page_flip_plane +0000000000000013 T intel_finish_page_flip_plane -0000000000000053 t hsw_pipe_crc_irq_handler +000000000000004c t hsw_pipe_crc_irq_handler -000000000000022e t cpt_irq_handler +0000000000000213 t cpt_irq_handler So small shrinkage but it is all fast paths so doesn't harm. Situation is similar in other interrupt handlers as well. v2: Tidy intel_queue_rps_boost_for_request as well. (Chris Wilson) Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
2016-05-06 14:48:28 +01:00
dev_priv->display.hpd_irq_setup(dev_priv);
spin_unlock_irq(&dev_priv->irq_lock);
intel_display_resume(dev_priv->dev);
intel_hpd_init(dev_priv);
drm_modeset_unlock_all(dev_priv->dev);
}
static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc)
{
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
struct drm_device *dev = crtc->dev;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
unsigned reset_counter;
bool pending;
reset_counter = i915_reset_counter(&to_i915(dev)->gpu_error);
if (intel_crtc->reset_counter != reset_counter)
return false;
spin_lock_irq(&dev->event_lock);
pending = to_intel_crtc(crtc)->flip_work != NULL;
spin_unlock_irq(&dev->event_lock);
return pending;
}
static void intel_update_pipe_config(struct intel_crtc *crtc,
struct intel_crtc_state *old_crtc_state)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc_state *pipe_config =
to_intel_crtc_state(crtc->base.state);
/* drm_atomic_helper_update_legacy_modeset_state might not be called. */
crtc->base.mode = crtc->base.state->mode;
DRM_DEBUG_KMS("Updating pipe size %ix%i -> %ix%i\n",
old_crtc_state->pipe_src_w, old_crtc_state->pipe_src_h,
pipe_config->pipe_src_w, pipe_config->pipe_src_h);
/*
* Update pipe size and adjust fitter if needed: the reason for this is
* that in compute_mode_changes we check the native mode (not the pfit
* mode) to see if we can flip rather than do a full mode set. In the
* fastboot case, we'll flip, but if we don't update the pipesrc and
* pfit state, we'll end up with a big fb scanned out into the wrong
* sized surface.
*/
I915_WRITE(PIPESRC(crtc->pipe),
((pipe_config->pipe_src_w - 1) << 16) |
(pipe_config->pipe_src_h - 1));
/* on skylake this is done by detaching scalers */
if (INTEL_INFO(dev)->gen >= 9) {
skl_detach_scalers(crtc);
if (pipe_config->pch_pfit.enabled)
skylake_pfit_enable(crtc);
} else if (HAS_PCH_SPLIT(dev)) {
if (pipe_config->pch_pfit.enabled)
ironlake_pfit_enable(crtc);
else if (old_crtc_state->pch_pfit.enabled)
ironlake_pfit_disable(crtc, true);
}
}
static void intel_fdi_normal_train(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;
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
i915_reg_t reg;
u32 temp;
/* enable normal train */
reg = FDI_TX_CTL(pipe);
temp = I915_READ(reg);
if (IS_IVYBRIDGE(dev)) {
temp &= ~FDI_LINK_TRAIN_NONE_IVB;
temp |= FDI_LINK_TRAIN_NONE_IVB | FDI_TX_ENHANCE_FRAME_ENABLE;
} else {
temp &= ~FDI_LINK_TRAIN_NONE;
temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE;
}
I915_WRITE(reg, temp);
reg = FDI_RX_CTL(pipe);
temp = I915_READ(reg);
if (HAS_PCH_CPT(dev)) {
temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
temp |= FDI_LINK_TRAIN_NORMAL_CPT;
} else {
temp &= ~FDI_LINK_TRAIN_NONE;
temp |= FDI_LINK_TRAIN_NONE;
}
I915_WRITE(reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE);
/* wait one idle pattern time */
POSTING_READ(reg);
udelay(1000);
/* IVB wants error correction enabled */
if (IS_IVYBRIDGE(dev))
I915_WRITE(reg, I915_READ(reg) | FDI_FS_ERRC_ENABLE |
FDI_FE_ERRC_ENABLE);
}
/* The FDI link training functions for ILK/Ibexpeak. */
static void ironlake_fdi_link_train(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;
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
i915_reg_t reg;
u32 temp, tries;
/* FDI needs bits from pipe first */
assert_pipe_enabled(dev_priv, pipe);
/* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
for train result */
reg = FDI_RX_IMR(pipe);
temp = I915_READ(reg);
temp &= ~FDI_RX_SYMBOL_LOCK;
temp &= ~FDI_RX_BIT_LOCK;
I915_WRITE(reg, temp);
I915_READ(reg);
udelay(150);
/* enable CPU FDI TX and PCH FDI RX */
reg = FDI_TX_CTL(pipe);
temp = I915_READ(reg);
temp &= ~FDI_DP_PORT_WIDTH_MASK;
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
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);
reg = FDI_RX_CTL(pipe);
temp = I915_READ(reg);
temp &= ~FDI_LINK_TRAIN_NONE;
temp |= FDI_LINK_TRAIN_PATTERN_1;
I915_WRITE(reg, temp | FDI_RX_ENABLE);
POSTING_READ(reg);
udelay(150);
/* Ironlake workaround, enable clock pointer after FDI enable*/
I915_WRITE(FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_OVR);
I915_WRITE(FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_OVR |
FDI_RX_PHASE_SYNC_POINTER_EN);
reg = FDI_RX_IIR(pipe);
for (tries = 0; tries < 5; tries++) {
temp = I915_READ(reg);
DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp);
if ((temp & FDI_RX_BIT_LOCK)) {
DRM_DEBUG_KMS("FDI train 1 done.\n");
I915_WRITE(reg, temp | FDI_RX_BIT_LOCK);
break;
}
}
if (tries == 5)
DRM_ERROR("FDI train 1 fail!\n");
/* Train 2 */
reg = FDI_TX_CTL(pipe);
temp = I915_READ(reg);
temp &= ~FDI_LINK_TRAIN_NONE;
temp |= FDI_LINK_TRAIN_PATTERN_2;
I915_WRITE(reg, temp);
reg = FDI_RX_CTL(pipe);
temp = I915_READ(reg);
temp &= ~FDI_LINK_TRAIN_NONE;
temp |= FDI_LINK_TRAIN_PATTERN_2;
I915_WRITE(reg, temp);
POSTING_READ(reg);
udelay(150);
reg = FDI_RX_IIR(pipe);
for (tries = 0; tries < 5; tries++) {
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.\n");
break;
}
}
if (tries == 5)
DRM_ERROR("FDI train 2 fail!\n");
DRM_DEBUG_KMS("FDI train done\n");
}
static const int snb_b_fdi_train_param[] = {
FDI_LINK_TRAIN_400MV_0DB_SNB_B,
FDI_LINK_TRAIN_400MV_6DB_SNB_B,
FDI_LINK_TRAIN_600MV_3_5DB_SNB_B,
FDI_LINK_TRAIN_800MV_0DB_SNB_B,
};
/* The FDI link training functions for SNB/Cougarpoint. */
static void gen6_fdi_link_train(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;
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
i915_reg_t reg;
u32 temp, i, retry;
/* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
for train result */
reg = FDI_RX_IMR(pipe);
temp = I915_READ(reg);
temp &= ~FDI_RX_SYMBOL_LOCK;
temp &= ~FDI_RX_BIT_LOCK;
I915_WRITE(reg, temp);
POSTING_READ(reg);
udelay(150);
/* enable CPU FDI TX and PCH FDI RX */
reg = FDI_TX_CTL(pipe);
temp = I915_READ(reg);
temp &= ~FDI_DP_PORT_WIDTH_MASK;
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
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;
/* SNB-B */
temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B;
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);
if (HAS_PCH_CPT(dev)) {
temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
} else {
temp &= ~FDI_LINK_TRAIN_NONE;
temp |= FDI_LINK_TRAIN_PATTERN_1;
}
I915_WRITE(reg, temp | FDI_RX_ENABLE);
POSTING_READ(reg);
udelay(150);
for (i = 0; i < 4; i++) {
reg = FDI_TX_CTL(pipe);
temp = I915_READ(reg);
temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
temp |= snb_b_fdi_train_param[i];
I915_WRITE(reg, temp);
POSTING_READ(reg);
udelay(500);
for (retry = 0; retry < 5; retry++) {
reg = FDI_RX_IIR(pipe);
temp = I915_READ(reg);
DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp);
if (temp & FDI_RX_BIT_LOCK) {
I915_WRITE(reg, temp | FDI_RX_BIT_LOCK);
DRM_DEBUG_KMS("FDI train 1 done.\n");
break;
}
udelay(50);
}
if (retry < 5)
break;
}
if (i == 4)
DRM_ERROR("FDI train 1 fail!\n");
/* Train 2 */
reg = FDI_TX_CTL(pipe);
temp = I915_READ(reg);
temp &= ~FDI_LINK_TRAIN_NONE;
temp |= FDI_LINK_TRAIN_PATTERN_2;
if (IS_GEN6(dev)) {
temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
/* SNB-B */
temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B;
}
I915_WRITE(reg, temp);
reg = FDI_RX_CTL(pipe);
temp = I915_READ(reg);
if (HAS_PCH_CPT(dev)) {
temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
temp |= FDI_LINK_TRAIN_PATTERN_2_CPT;
} else {
temp &= ~FDI_LINK_TRAIN_NONE;
temp |= FDI_LINK_TRAIN_PATTERN_2;
}
I915_WRITE(reg, temp);
POSTING_READ(reg);
udelay(150);
for (i = 0; i < 4; i++) {
reg = FDI_TX_CTL(pipe);
temp = I915_READ(reg);
temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
temp |= snb_b_fdi_train_param[i];
I915_WRITE(reg, temp);
POSTING_READ(reg);
udelay(500);
for (retry = 0; retry < 5; retry++) {
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.\n");
break;
}
udelay(50);
}
if (retry < 5)
break;
}
if (i == 4)
DRM_ERROR("FDI train 2 fail!\n");
DRM_DEBUG_KMS("FDI train done.\n");
}
/* Manual link training for Ivy Bridge A0 parts */
static void ivb_manual_fdi_link_train(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;
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
i915_reg_t reg;
u32 temp, i, j;
/* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
for train result */
reg = FDI_RX_IMR(pipe);
temp = I915_READ(reg);
temp &= ~FDI_RX_SYMBOL_LOCK;
temp &= ~FDI_RX_BIT_LOCK;
I915_WRITE(reg, temp);
POSTING_READ(reg);
udelay(150);
drm/i915: check fdi B/C lane sharing constraint And properly toggle the chicken bit in the pch to enable/disable fdi C rx. If we don't set this bit correctly, the rx gets confused in link training, which can result in an fdi link that silently fails to train the link (since the corresponding register reports success). Note that both fdi link B and C can suffer when this bit is not set correctly. The code as-is has a few deficiencies: - We presume all pipes use the pch which is not the case for cpu edp. - We don't bother with disabling both pipes when we could make things work, e.g. when pipe B switched from 4 to 2 lanes due to a mode change, we don't bother updating the w/a bit. - It's ugly. All of these are because we compute ->fdi_lanes way too late, when we're already setting up individual pipes. We need to have this information in ->modeset_global_resources already, to set things up correctly. But that is a much larger reorg of the code. Note that we actually hit the 2 lanes limit in practice rather quickly: Even though the 1920x1200 mode native mode of my screen fits into 2 lanes, it needs 3 lanes for the 1920x1080 (since that somehow has much more blanking ...). Not obeying this restriction seems to results in cute-looking digital noise. v2: Only ever clear the chicken bit when both pipes are off. v3: Use the new ->modeset_global_resources callback. v4: Move the WARNs to the right place. Oh how I hate hacks. v5: Fix spelling, noticed by Paulo Zanoni. Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-10-27 15:58:40 +02:00
DRM_DEBUG_KMS("FDI_RX_IIR before link train 0x%x\n",
I915_READ(FDI_RX_IIR(pipe)));
/* 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);
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);
/* enable CPU FDI TX and PCH FDI RX */
reg = FDI_TX_CTL(pipe);
temp = I915_READ(reg);
temp &= ~FDI_DP_PORT_WIDTH_MASK;
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
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[j/2];
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_PATTERN_1_CPT;
temp |= FDI_COMPOSITE_SYNC;
I915_WRITE(reg, temp | FDI_RX_ENABLE);
POSTING_READ(reg);
udelay(1); /* should be 0.5us */
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_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;
}
/* Train 2 */
reg = FDI_TX_CTL(pipe);
temp = I915_READ(reg);
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(2); /* should be 1.5us */
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_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);
}
train_done:
DRM_DEBUG_KMS("FDI train done.\n");
}
static void ironlake_fdi_pll_enable(struct intel_crtc *intel_crtc)
{
struct drm_device *dev = intel_crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
int pipe = intel_crtc->pipe;
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
i915_reg_t reg;
u32 temp;
/* enable PCH FDI RX PLL, wait warmup plus DMI latency */
reg = FDI_RX_CTL(pipe);
temp = I915_READ(reg);
temp &= ~(FDI_DP_PORT_WIDTH_MASK | (0x7 << 16));
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
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);
POSTING_READ(reg);
udelay(200);
/* Switch from Rawclk to PCDclk */
temp = I915_READ(reg);
I915_WRITE(reg, temp | FDI_PCDCLK);
POSTING_READ(reg);
udelay(200);
/* Enable CPU FDI TX PLL, always on for Ironlake */
reg = FDI_TX_CTL(pipe);
temp = I915_READ(reg);
if ((temp & FDI_TX_PLL_ENABLE) == 0) {
I915_WRITE(reg, temp | FDI_TX_PLL_ENABLE);
POSTING_READ(reg);
udelay(100);
}
}
static void ironlake_fdi_pll_disable(struct intel_crtc *intel_crtc)
{
struct drm_device *dev = intel_crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
int pipe = intel_crtc->pipe;
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
i915_reg_t reg;
u32 temp;
/* Switch from PCDclk to Rawclk */
reg = FDI_RX_CTL(pipe);
temp = I915_READ(reg);
I915_WRITE(reg, temp & ~FDI_PCDCLK);
/* Disable CPU FDI TX PLL */
reg = FDI_TX_CTL(pipe);
temp = I915_READ(reg);
I915_WRITE(reg, temp & ~FDI_TX_PLL_ENABLE);
POSTING_READ(reg);
udelay(100);
reg = FDI_RX_CTL(pipe);
temp = I915_READ(reg);
I915_WRITE(reg, temp & ~FDI_RX_PLL_ENABLE);
/* Wait for the clocks to turn off. */
POSTING_READ(reg);
udelay(100);
}
static void ironlake_fdi_disable(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;
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
i915_reg_t reg;
u32 temp;
/* disable CPU FDI tx and PCH FDI rx */
reg = FDI_TX_CTL(pipe);
temp = I915_READ(reg);
I915_WRITE(reg, temp & ~FDI_TX_ENABLE);
POSTING_READ(reg);
reg = FDI_RX_CTL(pipe);
temp = I915_READ(reg);
temp &= ~(0x7 << 16);
temp |= (I915_READ(PIPECONF(pipe)) & PIPECONF_BPC_MASK) << 11;
I915_WRITE(reg, temp & ~FDI_RX_ENABLE);
POSTING_READ(reg);
udelay(100);
/* Ironlake workaround, disable clock pointer after downing FDI */
if (HAS_PCH_IBX(dev))
I915_WRITE(FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_OVR);
/* still set train pattern 1 */
reg = FDI_TX_CTL(pipe);
temp = I915_READ(reg);
temp &= ~FDI_LINK_TRAIN_NONE;
temp |= FDI_LINK_TRAIN_PATTERN_1;
I915_WRITE(reg, temp);
reg = FDI_RX_CTL(pipe);
temp = I915_READ(reg);
if (HAS_PCH_CPT(dev)) {
temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
} else {
temp &= ~FDI_LINK_TRAIN_NONE;
temp |= FDI_LINK_TRAIN_PATTERN_1;
}
/* BPC in FDI rx is consistent with that in PIPECONF */
temp &= ~(0x07 << 16);
temp |= (I915_READ(PIPECONF(pipe)) & PIPECONF_BPC_MASK) << 11;
I915_WRITE(reg, temp);
POSTING_READ(reg);
udelay(100);
}
bool intel_has_pending_fb_unpin(struct drm_device *dev)
{
struct intel_crtc *crtc;
/* Note that we don't need to be called with mode_config.lock here
* as our list of CRTC objects is static for the lifetime of the
* device and so cannot disappear as we iterate. Similarly, we can
* happily treat the predicates as racy, atomic checks as userspace
* cannot claim and pin a new fb without at least acquring the
* struct_mutex and so serialising with us.
*/
for_each_intel_crtc(dev, crtc) {
if (atomic_read(&crtc->unpin_work_count) == 0)
continue;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
if (crtc->flip_work)
intel_wait_for_vblank(dev, crtc->pipe);
return true;
}
return false;
}
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
static void page_flip_completed(struct intel_crtc *intel_crtc)
drm/i915: Check for a stalled page flip after each vblank Long ago, back in the racy haydays of 915gm interrupt handling, page flips would occasionally go astray and leave the hardware stuck, and the display not updating. This annoyed people who relied on their systems being able to display continuously updating information 24/7, and so some code to detect when the driver missed the page flip completion signal was added. Until recently, it was presumed that the interrupt handling was now flawless, but once again Simon Farnsworth has found a system whose display will stall. Reinstate the pageflip stall detection, which works by checking to see if the hardware has been updated to the new framebuffer address following each vblank. If the hardware is scanning out from the new framebuffer, but we still think the flip is pending, then we kick our driver into submision. This is a continuation of the effort started with commit 4e5359cd053bfb7d8dabe4a63624a5726848ffbc Author: Simon Farnsworth <simon.farnsworth@onelan.co.uk> Date: Wed Sep 1 17:47:52 2010 +0100 drm/i915: Avoid pageflipping freeze when we miss the flip prepare interrupt This now includes a belt-and-braces approach to make sure the driver (or the hardware) doesn't miss an interrupt and cause us to stop updating the display should the unthinkable happen and the pageflip fail - i.e. that the user is able to continue submitting flips. v2: Cleanup, refactor, and rename v3: Only start counting vblanks after the flip command has been seen by the hardware. v4: Record the seqno after we touch the ring, or else there may be no seqno allocated yet. v5: Rebase on mmio-flip. v6: Rebase, rebase. Reported-by: Simon Farnsworth <simon@farnz.org.uk> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=75502 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> [v4] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-09-05 07:13:24 +01:00
{
struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
struct intel_flip_work *work = intel_crtc->flip_work;
intel_crtc->flip_work = NULL;
drm/i915: Check for a stalled page flip after each vblank Long ago, back in the racy haydays of 915gm interrupt handling, page flips would occasionally go astray and leave the hardware stuck, and the display not updating. This annoyed people who relied on their systems being able to display continuously updating information 24/7, and so some code to detect when the driver missed the page flip completion signal was added. Until recently, it was presumed that the interrupt handling was now flawless, but once again Simon Farnsworth has found a system whose display will stall. Reinstate the pageflip stall detection, which works by checking to see if the hardware has been updated to the new framebuffer address following each vblank. If the hardware is scanning out from the new framebuffer, but we still think the flip is pending, then we kick our driver into submision. This is a continuation of the effort started with commit 4e5359cd053bfb7d8dabe4a63624a5726848ffbc Author: Simon Farnsworth <simon.farnsworth@onelan.co.uk> Date: Wed Sep 1 17:47:52 2010 +0100 drm/i915: Avoid pageflipping freeze when we miss the flip prepare interrupt This now includes a belt-and-braces approach to make sure the driver (or the hardware) doesn't miss an interrupt and cause us to stop updating the display should the unthinkable happen and the pageflip fail - i.e. that the user is able to continue submitting flips. v2: Cleanup, refactor, and rename v3: Only start counting vblanks after the flip command has been seen by the hardware. v4: Record the seqno after we touch the ring, or else there may be no seqno allocated yet. v5: Rebase on mmio-flip. v6: Rebase, rebase. Reported-by: Simon Farnsworth <simon@farnz.org.uk> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=75502 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> [v4] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-09-05 07:13:24 +01:00
if (work->event)
drm_crtc_send_vblank_event(&intel_crtc->base, work->event);
drm/i915: Check for a stalled page flip after each vblank Long ago, back in the racy haydays of 915gm interrupt handling, page flips would occasionally go astray and leave the hardware stuck, and the display not updating. This annoyed people who relied on their systems being able to display continuously updating information 24/7, and so some code to detect when the driver missed the page flip completion signal was added. Until recently, it was presumed that the interrupt handling was now flawless, but once again Simon Farnsworth has found a system whose display will stall. Reinstate the pageflip stall detection, which works by checking to see if the hardware has been updated to the new framebuffer address following each vblank. If the hardware is scanning out from the new framebuffer, but we still think the flip is pending, then we kick our driver into submision. This is a continuation of the effort started with commit 4e5359cd053bfb7d8dabe4a63624a5726848ffbc Author: Simon Farnsworth <simon.farnsworth@onelan.co.uk> Date: Wed Sep 1 17:47:52 2010 +0100 drm/i915: Avoid pageflipping freeze when we miss the flip prepare interrupt This now includes a belt-and-braces approach to make sure the driver (or the hardware) doesn't miss an interrupt and cause us to stop updating the display should the unthinkable happen and the pageflip fail - i.e. that the user is able to continue submitting flips. v2: Cleanup, refactor, and rename v3: Only start counting vblanks after the flip command has been seen by the hardware. v4: Record the seqno after we touch the ring, or else there may be no seqno allocated yet. v5: Rebase on mmio-flip. v6: Rebase, rebase. Reported-by: Simon Farnsworth <simon@farnz.org.uk> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=75502 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> [v4] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-09-05 07:13:24 +01:00
drm_crtc_vblank_put(&intel_crtc->base);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
wake_up_all(&dev_priv->pending_flip_queue);
queue_work(dev_priv->wq, &work->unpin_work);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
trace_i915_flip_complete(intel_crtc->plane,
work->pending_flip_obj);
drm/i915: Check for a stalled page flip after each vblank Long ago, back in the racy haydays of 915gm interrupt handling, page flips would occasionally go astray and leave the hardware stuck, and the display not updating. This annoyed people who relied on their systems being able to display continuously updating information 24/7, and so some code to detect when the driver missed the page flip completion signal was added. Until recently, it was presumed that the interrupt handling was now flawless, but once again Simon Farnsworth has found a system whose display will stall. Reinstate the pageflip stall detection, which works by checking to see if the hardware has been updated to the new framebuffer address following each vblank. If the hardware is scanning out from the new framebuffer, but we still think the flip is pending, then we kick our driver into submision. This is a continuation of the effort started with commit 4e5359cd053bfb7d8dabe4a63624a5726848ffbc Author: Simon Farnsworth <simon.farnsworth@onelan.co.uk> Date: Wed Sep 1 17:47:52 2010 +0100 drm/i915: Avoid pageflipping freeze when we miss the flip prepare interrupt This now includes a belt-and-braces approach to make sure the driver (or the hardware) doesn't miss an interrupt and cause us to stop updating the display should the unthinkable happen and the pageflip fail - i.e. that the user is able to continue submitting flips. v2: Cleanup, refactor, and rename v3: Only start counting vblanks after the flip command has been seen by the hardware. v4: Record the seqno after we touch the ring, or else there may be no seqno allocated yet. v5: Rebase on mmio-flip. v6: Rebase, rebase. Reported-by: Simon Farnsworth <simon@farnz.org.uk> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=75502 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> [v4] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-09-05 07:13:24 +01:00
}
static int intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
long ret;
WARN_ON(waitqueue_active(&dev_priv->pending_flip_queue));
ret = wait_event_interruptible_timeout(
dev_priv->pending_flip_queue,
!intel_crtc_has_pending_flip(crtc),
60*HZ);
if (ret < 0)
return ret;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
if (ret == 0) {
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_flip_work *work;
spin_lock_irq(&dev->event_lock);
work = intel_crtc->flip_work;
if (work && !is_mmio_work(work)) {
WARN_ONCE(1, "Removing stuck page flip\n");
page_flip_completed(intel_crtc);
}
spin_unlock_irq(&dev->event_lock);
}
return 0;
}
static void lpt_disable_iclkip(struct drm_i915_private *dev_priv)
{
u32 temp;
I915_WRITE(PIXCLK_GATE, PIXCLK_GATE_GATE);
mutex_lock(&dev_priv->sb_lock);
temp = intel_sbi_read(dev_priv, SBI_SSCCTL6, SBI_ICLK);
temp |= SBI_SSCCTL_DISABLE;
intel_sbi_write(dev_priv, SBI_SSCCTL6, temp, SBI_ICLK);
mutex_unlock(&dev_priv->sb_lock);
}
/* Program iCLKIP clock to the desired frequency */
static void lpt_program_iclkip(struct drm_crtc *crtc)
{
struct drm_i915_private *dev_priv = to_i915(crtc->dev);
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
int clock = to_intel_crtc(crtc)->config->base.adjusted_mode.crtc_clock;
u32 divsel, phaseinc, auxdiv, phasedir = 0;
u32 temp;
lpt_disable_iclkip(dev_priv);
/* The iCLK virtual clock root frequency is in MHz,
* but the adjusted_mode->crtc_clock in in KHz. To get the
* divisors, it is necessary to divide one by another, so we
* convert the virtual clock precision to KHz here for higher
* precision.
*/
for (auxdiv = 0; auxdiv < 2; auxdiv++) {
u32 iclk_virtual_root_freq = 172800 * 1000;
u32 iclk_pi_range = 64;
u32 desired_divisor;
desired_divisor = DIV_ROUND_CLOSEST(iclk_virtual_root_freq,
clock << auxdiv);
divsel = (desired_divisor / iclk_pi_range) - 2;
phaseinc = desired_divisor % iclk_pi_range;
/*
* Near 20MHz is a corner case which is
* out of range for the 7-bit divisor
*/
if (divsel <= 0x7f)
break;
}
/* This should not happen with any sane values */
WARN_ON(SBI_SSCDIVINTPHASE_DIVSEL(divsel) &
~SBI_SSCDIVINTPHASE_DIVSEL_MASK);
WARN_ON(SBI_SSCDIVINTPHASE_DIR(phasedir) &
~SBI_SSCDIVINTPHASE_INCVAL_MASK);
DRM_DEBUG_KMS("iCLKIP clock: found settings for %dKHz refresh rate: auxdiv=%x, divsel=%x, phasedir=%x, phaseinc=%x\n",
clock,
auxdiv,
divsel,
phasedir,
phaseinc);
mutex_lock(&dev_priv->sb_lock);
/* Program SSCDIVINTPHASE6 */
temp = intel_sbi_read(dev_priv, SBI_SSCDIVINTPHASE6, SBI_ICLK);
temp &= ~SBI_SSCDIVINTPHASE_DIVSEL_MASK;
temp |= SBI_SSCDIVINTPHASE_DIVSEL(divsel);
temp &= ~SBI_SSCDIVINTPHASE_INCVAL_MASK;
temp |= SBI_SSCDIVINTPHASE_INCVAL(phaseinc);
temp |= SBI_SSCDIVINTPHASE_DIR(phasedir);
temp |= SBI_SSCDIVINTPHASE_PROPAGATE;
intel_sbi_write(dev_priv, SBI_SSCDIVINTPHASE6, temp, SBI_ICLK);
/* Program SSCAUXDIV */
temp = intel_sbi_read(dev_priv, SBI_SSCAUXDIV6, SBI_ICLK);
temp &= ~SBI_SSCAUXDIV_FINALDIV2SEL(1);
temp |= SBI_SSCAUXDIV_FINALDIV2SEL(auxdiv);
intel_sbi_write(dev_priv, SBI_SSCAUXDIV6, temp, SBI_ICLK);
/* Enable modulator and associated divider */
temp = intel_sbi_read(dev_priv, SBI_SSCCTL6, SBI_ICLK);
temp &= ~SBI_SSCCTL_DISABLE;
intel_sbi_write(dev_priv, SBI_SSCCTL6, temp, SBI_ICLK);
mutex_unlock(&dev_priv->sb_lock);
/* Wait for initialization time */
udelay(24);
I915_WRITE(PIXCLK_GATE, PIXCLK_GATE_UNGATE);
}
int lpt_get_iclkip(struct drm_i915_private *dev_priv)
{
u32 divsel, phaseinc, auxdiv;
u32 iclk_virtual_root_freq = 172800 * 1000;
u32 iclk_pi_range = 64;
u32 desired_divisor;
u32 temp;
if ((I915_READ(PIXCLK_GATE) & PIXCLK_GATE_UNGATE) == 0)
return 0;
mutex_lock(&dev_priv->sb_lock);
temp = intel_sbi_read(dev_priv, SBI_SSCCTL6, SBI_ICLK);
if (temp & SBI_SSCCTL_DISABLE) {
mutex_unlock(&dev_priv->sb_lock);
return 0;
}
temp = intel_sbi_read(dev_priv, SBI_SSCDIVINTPHASE6, SBI_ICLK);
divsel = (temp & SBI_SSCDIVINTPHASE_DIVSEL_MASK) >>
SBI_SSCDIVINTPHASE_DIVSEL_SHIFT;
phaseinc = (temp & SBI_SSCDIVINTPHASE_INCVAL_MASK) >>
SBI_SSCDIVINTPHASE_INCVAL_SHIFT;
temp = intel_sbi_read(dev_priv, SBI_SSCAUXDIV6, SBI_ICLK);
auxdiv = (temp & SBI_SSCAUXDIV_FINALDIV2SEL_MASK) >>
SBI_SSCAUXDIV_FINALDIV2SEL_SHIFT;
mutex_unlock(&dev_priv->sb_lock);
desired_divisor = (divsel + 2) * iclk_pi_range + phaseinc;
return DIV_ROUND_CLOSEST(iclk_virtual_root_freq,
desired_divisor << auxdiv);
}
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;
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
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)));
}
static void cpt_set_fdi_bc_bifurcation(struct drm_device *dev, bool enable)
drm/i915: Fix the PPT fdi lane bifurcate state handling on ivb Originally I've thought that this is leftover hw state dirt from the BIOS. But after way too much helpless flailing around on my part I've noticed that the actual bug is when we change the state of an already active pipe. For example when we change the fdi lines from 2 to 3 without switching off outputs in-between we'll never see the crucial on->off transition in the ->modeset_global_resources hook the current logic relies on. Patch version 2 got this right by instead also checking whether the pipe is indeed active. But that in turn broke things when pipes have been turned off through dpms since the bifurcate enabling is done in the ->crtc_mode_set callback. To address this issues discussed with Ville in the patch review move the setting of the bifurcate bit into the ->crtc_enable hook. That way we won't wreak havoc with this state when userspace puts all other outputs into dpms off state. This also moves us forward with our overall goal to unify the modeset and dpms on paths (which we need to have to allow runtime pm in the dpms off state). Unfortunately this requires us to move the bifurcate helpers around a bit. Also update the commit message, I've misanalyzed the bug rather badly. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70507 Tested-by: Jan-Michael Brummer <jan.brummer@tabos.org> Cc: stable@vger.kernel.org Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-10-29 12:04:08 +01:00
{
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t temp;
temp = I915_READ(SOUTH_CHICKEN1);
if (!!(temp & FDI_BC_BIFURCATION_SELECT) == enable)
drm/i915: Fix the PPT fdi lane bifurcate state handling on ivb Originally I've thought that this is leftover hw state dirt from the BIOS. But after way too much helpless flailing around on my part I've noticed that the actual bug is when we change the state of an already active pipe. For example when we change the fdi lines from 2 to 3 without switching off outputs in-between we'll never see the crucial on->off transition in the ->modeset_global_resources hook the current logic relies on. Patch version 2 got this right by instead also checking whether the pipe is indeed active. But that in turn broke things when pipes have been turned off through dpms since the bifurcate enabling is done in the ->crtc_mode_set callback. To address this issues discussed with Ville in the patch review move the setting of the bifurcate bit into the ->crtc_enable hook. That way we won't wreak havoc with this state when userspace puts all other outputs into dpms off state. This also moves us forward with our overall goal to unify the modeset and dpms on paths (which we need to have to allow runtime pm in the dpms off state). Unfortunately this requires us to move the bifurcate helpers around a bit. Also update the commit message, I've misanalyzed the bug rather badly. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70507 Tested-by: Jan-Michael Brummer <jan.brummer@tabos.org> Cc: stable@vger.kernel.org Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-10-29 12:04:08 +01:00
return;
WARN_ON(I915_READ(FDI_RX_CTL(PIPE_B)) & FDI_RX_ENABLE);
WARN_ON(I915_READ(FDI_RX_CTL(PIPE_C)) & FDI_RX_ENABLE);
temp &= ~FDI_BC_BIFURCATION_SELECT;
if (enable)
temp |= FDI_BC_BIFURCATION_SELECT;
DRM_DEBUG_KMS("%sabling fdi C rx\n", enable ? "en" : "dis");
drm/i915: Fix the PPT fdi lane bifurcate state handling on ivb Originally I've thought that this is leftover hw state dirt from the BIOS. But after way too much helpless flailing around on my part I've noticed that the actual bug is when we change the state of an already active pipe. For example when we change the fdi lines from 2 to 3 without switching off outputs in-between we'll never see the crucial on->off transition in the ->modeset_global_resources hook the current logic relies on. Patch version 2 got this right by instead also checking whether the pipe is indeed active. But that in turn broke things when pipes have been turned off through dpms since the bifurcate enabling is done in the ->crtc_mode_set callback. To address this issues discussed with Ville in the patch review move the setting of the bifurcate bit into the ->crtc_enable hook. That way we won't wreak havoc with this state when userspace puts all other outputs into dpms off state. This also moves us forward with our overall goal to unify the modeset and dpms on paths (which we need to have to allow runtime pm in the dpms off state). Unfortunately this requires us to move the bifurcate helpers around a bit. Also update the commit message, I've misanalyzed the bug rather badly. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70507 Tested-by: Jan-Michael Brummer <jan.brummer@tabos.org> Cc: stable@vger.kernel.org Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-10-29 12:04:08 +01:00
I915_WRITE(SOUTH_CHICKEN1, temp);
POSTING_READ(SOUTH_CHICKEN1);
}
static void ivybridge_update_fdi_bc_bifurcation(struct intel_crtc *intel_crtc)
{
struct drm_device *dev = intel_crtc->base.dev;
switch (intel_crtc->pipe) {
case PIPE_A:
break;
case PIPE_B:
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (intel_crtc->config->fdi_lanes > 2)
cpt_set_fdi_bc_bifurcation(dev, false);
drm/i915: Fix the PPT fdi lane bifurcate state handling on ivb Originally I've thought that this is leftover hw state dirt from the BIOS. But after way too much helpless flailing around on my part I've noticed that the actual bug is when we change the state of an already active pipe. For example when we change the fdi lines from 2 to 3 without switching off outputs in-between we'll never see the crucial on->off transition in the ->modeset_global_resources hook the current logic relies on. Patch version 2 got this right by instead also checking whether the pipe is indeed active. But that in turn broke things when pipes have been turned off through dpms since the bifurcate enabling is done in the ->crtc_mode_set callback. To address this issues discussed with Ville in the patch review move the setting of the bifurcate bit into the ->crtc_enable hook. That way we won't wreak havoc with this state when userspace puts all other outputs into dpms off state. This also moves us forward with our overall goal to unify the modeset and dpms on paths (which we need to have to allow runtime pm in the dpms off state). Unfortunately this requires us to move the bifurcate helpers around a bit. Also update the commit message, I've misanalyzed the bug rather badly. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70507 Tested-by: Jan-Michael Brummer <jan.brummer@tabos.org> Cc: stable@vger.kernel.org Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-10-29 12:04:08 +01:00
else
cpt_set_fdi_bc_bifurcation(dev, true);
drm/i915: Fix the PPT fdi lane bifurcate state handling on ivb Originally I've thought that this is leftover hw state dirt from the BIOS. But after way too much helpless flailing around on my part I've noticed that the actual bug is when we change the state of an already active pipe. For example when we change the fdi lines from 2 to 3 without switching off outputs in-between we'll never see the crucial on->off transition in the ->modeset_global_resources hook the current logic relies on. Patch version 2 got this right by instead also checking whether the pipe is indeed active. But that in turn broke things when pipes have been turned off through dpms since the bifurcate enabling is done in the ->crtc_mode_set callback. To address this issues discussed with Ville in the patch review move the setting of the bifurcate bit into the ->crtc_enable hook. That way we won't wreak havoc with this state when userspace puts all other outputs into dpms off state. This also moves us forward with our overall goal to unify the modeset and dpms on paths (which we need to have to allow runtime pm in the dpms off state). Unfortunately this requires us to move the bifurcate helpers around a bit. Also update the commit message, I've misanalyzed the bug rather badly. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70507 Tested-by: Jan-Michael Brummer <jan.brummer@tabos.org> Cc: stable@vger.kernel.org Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-10-29 12:04:08 +01:00
break;
case PIPE_C:
cpt_set_fdi_bc_bifurcation(dev, true);
drm/i915: Fix the PPT fdi lane bifurcate state handling on ivb Originally I've thought that this is leftover hw state dirt from the BIOS. But after way too much helpless flailing around on my part I've noticed that the actual bug is when we change the state of an already active pipe. For example when we change the fdi lines from 2 to 3 without switching off outputs in-between we'll never see the crucial on->off transition in the ->modeset_global_resources hook the current logic relies on. Patch version 2 got this right by instead also checking whether the pipe is indeed active. But that in turn broke things when pipes have been turned off through dpms since the bifurcate enabling is done in the ->crtc_mode_set callback. To address this issues discussed with Ville in the patch review move the setting of the bifurcate bit into the ->crtc_enable hook. That way we won't wreak havoc with this state when userspace puts all other outputs into dpms off state. This also moves us forward with our overall goal to unify the modeset and dpms on paths (which we need to have to allow runtime pm in the dpms off state). Unfortunately this requires us to move the bifurcate helpers around a bit. Also update the commit message, I've misanalyzed the bug rather badly. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70507 Tested-by: Jan-Michael Brummer <jan.brummer@tabos.org> Cc: stable@vger.kernel.org Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-10-29 12:04:08 +01:00
break;
default:
BUG();
}
}
/* Return which DP Port should be selected for Transcoder DP control */
static enum port
intel_trans_dp_port_sel(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
struct intel_encoder *encoder;
for_each_encoder_on_crtc(dev, crtc, encoder) {
if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
encoder->type == INTEL_OUTPUT_EDP)
return enc_to_dig_port(&encoder->base)->port;
}
return -1;
}
/*
* Enable PCH resources required for PCH ports:
* - PCH PLLs
* - FDI training & RX/TX
* - update transcoder timings
* - DP transcoding bits
* - transcoder
*/
static void ironlake_pch_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);
int pipe = intel_crtc->pipe;
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
u32 temp;
assert_pch_transcoder_disabled(dev_priv, pipe);
drm/i915: Fix the PPT fdi lane bifurcate state handling on ivb Originally I've thought that this is leftover hw state dirt from the BIOS. But after way too much helpless flailing around on my part I've noticed that the actual bug is when we change the state of an already active pipe. For example when we change the fdi lines from 2 to 3 without switching off outputs in-between we'll never see the crucial on->off transition in the ->modeset_global_resources hook the current logic relies on. Patch version 2 got this right by instead also checking whether the pipe is indeed active. But that in turn broke things when pipes have been turned off through dpms since the bifurcate enabling is done in the ->crtc_mode_set callback. To address this issues discussed with Ville in the patch review move the setting of the bifurcate bit into the ->crtc_enable hook. That way we won't wreak havoc with this state when userspace puts all other outputs into dpms off state. This also moves us forward with our overall goal to unify the modeset and dpms on paths (which we need to have to allow runtime pm in the dpms off state). Unfortunately this requires us to move the bifurcate helpers around a bit. Also update the commit message, I've misanalyzed the bug rather badly. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70507 Tested-by: Jan-Michael Brummer <jan.brummer@tabos.org> Cc: stable@vger.kernel.org Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-10-29 12:04:08 +01:00
if (IS_IVYBRIDGE(dev))
ivybridge_update_fdi_bc_bifurcation(intel_crtc);
/* Write the TU size bits before fdi link training, so that error
* detection works. */
I915_WRITE(FDI_RX_TUSIZE1(pipe),
I915_READ(PIPE_DATA_M1(pipe)) & TU_SIZE_MASK);
/* For PCH output, training FDI link */
dev_priv->display.fdi_link_train(crtc);
/* We need to program the right clock selection before writing the pixel
* mutliplier into the DPLL. */
if (HAS_PCH_CPT(dev)) {
u32 sel;
temp = I915_READ(PCH_DPLL_SEL);
temp |= TRANS_DPLL_ENABLE(pipe);
sel = TRANS_DPLLB_SEL(pipe);
if (intel_crtc->config->shared_dpll ==
intel_get_shared_dpll_by_id(dev_priv, DPLL_ID_PCH_PLL_B))
temp |= sel;
else
temp &= ~sel;
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. */
intel_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);
intel_fdi_normal_train(crtc);
/* For PCH DP, enable TRANS_DP_CTL */
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (HAS_PCH_CPT(dev) && intel_crtc->config->has_dp_encoder) {
const struct drm_display_mode *adjusted_mode =
&intel_crtc->config->base.adjusted_mode;
u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPECONF_BPC_MASK) >> 5;
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
i915_reg_t reg = TRANS_DP_CTL(pipe);
temp = I915_READ(reg);
temp &= ~(TRANS_DP_PORT_SEL_MASK |
TRANS_DP_SYNC_MASK |
TRANS_DP_BPC_MASK);
temp |= TRANS_DP_OUTPUT_ENABLE;
temp |= bpc << 9; /* same format but at 11:9 */
if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
temp |= TRANS_DP_HSYNC_ACTIVE_HIGH;
if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
temp |= TRANS_DP_VSYNC_ACTIVE_HIGH;
switch (intel_trans_dp_port_sel(crtc)) {
case PORT_B:
temp |= TRANS_DP_PORT_SEL_B;
break;
case PORT_C:
temp |= TRANS_DP_PORT_SEL_C;
break;
case PORT_D:
temp |= TRANS_DP_PORT_SEL_D;
break;
default:
BUG();
}
I915_WRITE(reg, temp);
}
ironlake_enable_pch_transcoder(dev_priv, pipe);
}
static void lpt_pch_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);
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
assert_pch_transcoder_disabled(dev_priv, TRANSCODER_A);
lpt_program_iclkip(crtc);
/* Set transcoder timing. */
ironlake_pch_transcoder_set_timings(intel_crtc, PIPE_A);
lpt_enable_pch_transcoder(dev_priv, cpu_transcoder);
}
static void cpt_verify_modeset(struct drm_device *dev, int pipe)
{
struct drm_i915_private *dev_priv = dev->dev_private;
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
i915_reg_t dslreg = PIPEDSL(pipe);
u32 temp;
temp = I915_READ(dslreg);
udelay(500);
if (wait_for(I915_READ(dslreg) != temp, 5)) {
if (wait_for(I915_READ(dslreg) != temp, 5))
DRM_ERROR("mode set failed: pipe %c stuck\n", pipe_name(pipe));
}
}
static int
skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
unsigned scaler_user, int *scaler_id, unsigned int rotation,
int src_w, int src_h, int dst_w, int dst_h)
{
struct intel_crtc_scaler_state *scaler_state =
&crtc_state->scaler_state;
struct intel_crtc *intel_crtc =
to_intel_crtc(crtc_state->base.crtc);
int need_scaling;
need_scaling = intel_rotation_90_or_270(rotation) ?
(src_h != dst_w || src_w != dst_h):
(src_w != dst_w || src_h != dst_h);
/*
* if plane is being disabled or scaler is no more required or force detach
* - free scaler binded to this plane/crtc
* - in order to do this, update crtc->scaler_usage
*
* Here scaler state in crtc_state is set free so that
* scaler can be assigned to other user. Actual register
* update to free the scaler is done in plane/panel-fit programming.
* For this purpose crtc/plane_state->scaler_id isn't reset here.
*/
if (force_detach || !need_scaling) {
if (*scaler_id >= 0) {
scaler_state->scaler_users &= ~(1 << scaler_user);
scaler_state->scalers[*scaler_id].in_use = 0;
DRM_DEBUG_KMS("scaler_user index %u.%u: "
"Staged freeing scaler id %d scaler_users = 0x%x\n",
intel_crtc->pipe, scaler_user, *scaler_id,
scaler_state->scaler_users);
*scaler_id = -1;
}
return 0;
}
/* range checks */
if (src_w < SKL_MIN_SRC_W || src_h < SKL_MIN_SRC_H ||
dst_w < SKL_MIN_DST_W || dst_h < SKL_MIN_DST_H ||
src_w > SKL_MAX_SRC_W || src_h > SKL_MAX_SRC_H ||
dst_w > SKL_MAX_DST_W || dst_h > SKL_MAX_DST_H) {
DRM_DEBUG_KMS("scaler_user index %u.%u: src %ux%u dst %ux%u "
"size is out of scaler range\n",
intel_crtc->pipe, scaler_user, src_w, src_h, dst_w, dst_h);
return -EINVAL;
}
/* mark this plane as a scaler user in crtc_state */
scaler_state->scaler_users |= (1 << scaler_user);
DRM_DEBUG_KMS("scaler_user index %u.%u: "
"staged scaling request for %ux%u->%ux%u scaler_users = 0x%x\n",
intel_crtc->pipe, scaler_user, src_w, src_h, dst_w, dst_h,
scaler_state->scaler_users);
return 0;
}
/**
* skl_update_scaler_crtc - Stages update to scaler state for a given crtc.
*
* @state: crtc's scaler state
*
* Return
* 0 - scaler_usage updated successfully
* error - requested scaling cannot be supported or other error condition
*/
int skl_update_scaler_crtc(struct intel_crtc_state *state)
{
struct intel_crtc *intel_crtc = to_intel_crtc(state->base.crtc);
const struct drm_display_mode *adjusted_mode = &state->base.adjusted_mode;
DRM_DEBUG_KMS("Updating scaler for [CRTC:%d:%s] scaler_user index %u.%u\n",
intel_crtc->base.base.id, intel_crtc->base.name,
intel_crtc->pipe, SKL_CRTC_INDEX);
return skl_update_scaler(state, !state->base.active, SKL_CRTC_INDEX,
&state->scaler_state.scaler_id, BIT(DRM_ROTATE_0),
state->pipe_src_w, state->pipe_src_h,
adjusted_mode->crtc_hdisplay, adjusted_mode->crtc_vdisplay);
}
/**
* skl_update_scaler_plane - Stages update to scaler state for a given plane.
*
* @state: crtc's scaler state
* @plane_state: atomic plane state to update
*
* Return
* 0 - scaler_usage updated successfully
* error - requested scaling cannot be supported or other error condition
*/
static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
struct intel_plane_state *plane_state)
{
struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
struct intel_plane *intel_plane =
to_intel_plane(plane_state->base.plane);
struct drm_framebuffer *fb = plane_state->base.fb;
int ret;
bool force_detach = !fb || !plane_state->visible;
DRM_DEBUG_KMS("Updating scaler for [PLANE:%d:%s] scaler_user index %u.%u\n",
intel_plane->base.base.id, intel_plane->base.name,
intel_crtc->pipe, drm_plane_index(&intel_plane->base));
ret = skl_update_scaler(crtc_state, force_detach,
drm_plane_index(&intel_plane->base),
&plane_state->scaler_id,
plane_state->base.rotation,
drm_rect_width(&plane_state->src) >> 16,
drm_rect_height(&plane_state->src) >> 16,
drm_rect_width(&plane_state->dst),
drm_rect_height(&plane_state->dst));
if (ret || plane_state->scaler_id < 0)
return ret;
/* check colorkey */
if (plane_state->ckey.flags != I915_SET_COLORKEY_NONE) {
DRM_DEBUG_KMS("[PLANE:%d:%s] scaling with color key not allowed",
intel_plane->base.base.id,
intel_plane->base.name);
return -EINVAL;
}
/* Check src format */
switch (fb->pixel_format) {
case DRM_FORMAT_RGB565:
case DRM_FORMAT_XBGR8888:
case DRM_FORMAT_XRGB8888:
case DRM_FORMAT_ABGR8888:
case DRM_FORMAT_ARGB8888:
case DRM_FORMAT_XRGB2101010:
case DRM_FORMAT_XBGR2101010:
case DRM_FORMAT_YUYV:
case DRM_FORMAT_YVYU:
case DRM_FORMAT_UYVY:
case DRM_FORMAT_VYUY:
break;
default:
DRM_DEBUG_KMS("[PLANE:%d:%s] FB:%d unsupported scaling format 0x%x\n",
intel_plane->base.base.id, intel_plane->base.name,
fb->base.id, fb->pixel_format);
return -EINVAL;
}
return 0;
}
static void skylake_scaler_disable(struct intel_crtc *crtc)
{
int i;
for (i = 0; i < crtc->num_scalers; i++)
skl_detach_scaler(crtc, i);
}
static void skylake_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;
struct intel_crtc_scaler_state *scaler_state =
&crtc->config->scaler_state;
DRM_DEBUG_KMS("for crtc_state = %p\n", crtc->config);
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (crtc->config->pch_pfit.enabled) {
int id;
if (WARN_ON(crtc->config->scaler_state.scaler_id < 0)) {
DRM_ERROR("Requesting pfit without getting a scaler first\n");
return;
}
id = scaler_state->scaler_id;
I915_WRITE(SKL_PS_CTRL(pipe, id), PS_SCALER_EN |
PS_FILTER_MEDIUM | scaler_state->scalers[id].mode);
I915_WRITE(SKL_PS_WIN_POS(pipe, id), crtc->config->pch_pfit.pos);
I915_WRITE(SKL_PS_WIN_SZ(pipe, id), crtc->config->pch_pfit.size);
DRM_DEBUG_KMS("for crtc_state = %p scaler_id = %d\n", crtc->config, id);
}
}
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;
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (crtc->config->pch_pfit.enabled) {
/* 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);
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
I915_WRITE(PF_WIN_POS(pipe), crtc->config->pch_pfit.pos);
I915_WRITE(PF_WIN_SZ(pipe), crtc->config->pch_pfit.size);
}
}
void hsw_enable_ips(struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (!crtc->config->ips_enabled)
return;
/*
* We can only enable IPS after we enable a plane and wait for a vblank
* This function is called from post_plane_update, which is run after
* a vblank wait.
*/
assert_plane_enabled(dev_priv, crtc->plane);
if (IS_BROADWELL(dev)) {
mutex_lock(&dev_priv->rps.hw_lock);
WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0xc0000000));
mutex_unlock(&dev_priv->rps.hw_lock);
/* Quoting Art Runyan: "its not safe to expect any particular
* value in IPS_CTL bit 31 after enabling IPS through the
* mailbox." Moreover, the mailbox may return a bogus state,
* so we need to just enable it and continue on.
*/
} else {
I915_WRITE(IPS_CTL, IPS_ENABLE);
/* The bit only becomes 1 in the next vblank, so this wait here
* is essentially intel_wait_for_vblank. If we don't have this
* and don't wait for vblanks until the end of crtc_enable, then
* the HW state readout code will complain that the expected
* IPS_CTL value is not the one we read. */
if (intel_wait_for_register(dev_priv,
IPS_CTL, IPS_ENABLE, IPS_ENABLE,
50))
DRM_ERROR("Timed out waiting for IPS enable\n");
}
}
void hsw_disable_ips(struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (!crtc->config->ips_enabled)
return;
assert_plane_enabled(dev_priv, crtc->plane);
if (IS_BROADWELL(dev)) {
mutex_lock(&dev_priv->rps.hw_lock);
WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0));
mutex_unlock(&dev_priv->rps.hw_lock);
/* wait for pcode to finish disabling IPS, which may take up to 42ms */
if (intel_wait_for_register(dev_priv,
IPS_CTL, IPS_ENABLE, 0,
42))
DRM_ERROR("Timed out waiting for IPS disable\n");
} else {
I915_WRITE(IPS_CTL, 0);
POSTING_READ(IPS_CTL);
}
/* We need to wait for a vblank before we can disable the plane. */
intel_wait_for_vblank(dev, crtc->pipe);
}
static void intel_crtc_dpms_overlay_disable(struct intel_crtc *intel_crtc)
{
if (intel_crtc->overlay) {
struct drm_device *dev = intel_crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
mutex_lock(&dev->struct_mutex);
dev_priv->mm.interruptible = false;
(void) intel_overlay_switch_off(intel_crtc->overlay);
dev_priv->mm.interruptible = true;
mutex_unlock(&dev->struct_mutex);
}
/* Let userspace switch the overlay on again. In most cases userspace
* has to recompute where to put it anyway.
*/
}
/**
* intel_post_enable_primary - Perform operations after enabling primary plane
* @crtc: the CRTC whose primary plane was just enabled
*
* Performs potentially sleeping operations that must be done after the primary
* plane is enabled, such as updating FBC and IPS. Note that this may be
* called due to an explicit primary plane update, or due to an implicit
* re-enable that is caused when a sprite plane is updated to no longer
* completely hide the primary plane.
*/
static void
intel_post_enable_primary(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;
/*
* FIXME IPS should be fine as long as one plane is
* enabled, but in practice it seems to have problems
* when going from primary only to sprite only and vice
* versa.
*/
hsw_enable_ips(intel_crtc);
drm/i915: Track frontbuffer invalidation/flushing So these are the guts of the new beast. This tracks when a frontbuffer gets invalidated (due to frontbuffer rendering) and hence should be constantly scaned out, and when it's flushed again and can be compressed/one-shot-upload. Rules for flushing are simple: The frontbuffer needs one more full upload starting from the next vblank. Which means that the flushing can _only_ be called once the frontbuffer update has been latched. But this poses a problem for pageflips: We can't just delay the flushing until the pageflip is latched, since that would pose the risk that we override frontbuffer rendering that has been scheduled in-between the pageflip ioctl and the actual latching. To handle this track asynchronous invalidations (and also pageflip) state per-ring and delay any in-between flushing until the rendering has completed. And also cancel any delayed flushing if we get a new invalidation request (whether delayed or not). Also call intel_mark_fb_busy in both cases in all cases to make sure that we keep the screen at the highest refresh rate both on flips, synchronous plane updates and for frontbuffer rendering. v2: Lots of improvements Suggestions from Chris: - Move invalidate/flush in flush_*_domain and set_to_*_domain. - Drop the flush in busy_ioctl since it's redundant. Was a leftover from an earlier concept to track flips/delayed flushes. - Don't forget about the initial modeset enable/final disable. Suggested by Chris. Track flips accurately, too. Since flips complete independently of rendering we need to track pending flips in a separate mask. Again if an invalidate happens we need to cancel the evenutal flush to avoid races. v3: Provide correct header declarations for flip functions. Currently not needed outside of intel_display.c, but part of the proper interface. v4: Add proper domain management to fbcon so that the fbcon buffer is also tracked correctly. v5: Fixup locking around the fbcon set_to_gtt_domain call. v6: More comments from Chris: - Split out fbcon changes. - Drop superflous checks for potential scanout before calling intel_fb functions - we can micro-optimize this later. - s/intel_fb_/intel_fb_obj_/ to make it clear that this deals in gem object. We already have precedence for fb_obj in the pin_and_fence functions. v7: Clarify the semantics of the flip flush handling by renaming things a bit: - Don't go through a gem object but take the relevant frontbuffer bits directly. These functions center on the plane, the actual object is irrelevant - even a flip to the same object as already active should cause a flush. - Add a new intel_frontbuffer_flip for synchronous plane updates. It currently just calls intel_frontbuffer_flush since the implemenation differs. This way we achieve a clear split between one-shot update events on one side and frontbuffer rendering with potentially a very long delay between the invalidate and flush. Chris and I also had some discussions about mark_busy and whether it is appropriate to call from flush. But mark busy is a state which should be derived from the 3 events (invalidate, flush, flip) we now have by the users, like psr does by tracking relevant information in psr.busy_frontbuffer_bits. DRRS (the only real use of mark_busy for frontbuffer) needs to have similar logic. With that the overall mark_busy in the core could be removed. v8: Only when retiring gpu buffers only flush frontbuffer bits we actually invalidated in a batch. Just for safety since before any additional usage/invalidate we should always retire current rendering. Suggested by Chris Wilson. v9: Actually use intel_frontbuffer_flip in all appropriate places. Spotted by Chris. v10: Address more comments from Chris: - Don't call _flip in set_base when the crtc is inactive, avoids redunancy in the modeset case with the initial enabling of all planes. - Add comments explaining that the initial/final plane enable/disable still has work left to do before it's fully generic. v11: Only invalidate for gtt/cpu access when writing. Spotted by Chris. v12: s/_flush/_flip/ in intel_overlay.c per Chris' comment. Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-19 16:01:59 +02:00
/*
* Gen2 reports pipe underruns whenever all planes are disabled.
* So don't enable underrun reporting before at least some planes
* are enabled.
* FIXME: Need to fix the logic to work when we turn off all planes
* but leave the pipe running.
drm/i915: Track frontbuffer invalidation/flushing So these are the guts of the new beast. This tracks when a frontbuffer gets invalidated (due to frontbuffer rendering) and hence should be constantly scaned out, and when it's flushed again and can be compressed/one-shot-upload. Rules for flushing are simple: The frontbuffer needs one more full upload starting from the next vblank. Which means that the flushing can _only_ be called once the frontbuffer update has been latched. But this poses a problem for pageflips: We can't just delay the flushing until the pageflip is latched, since that would pose the risk that we override frontbuffer rendering that has been scheduled in-between the pageflip ioctl and the actual latching. To handle this track asynchronous invalidations (and also pageflip) state per-ring and delay any in-between flushing until the rendering has completed. And also cancel any delayed flushing if we get a new invalidation request (whether delayed or not). Also call intel_mark_fb_busy in both cases in all cases to make sure that we keep the screen at the highest refresh rate both on flips, synchronous plane updates and for frontbuffer rendering. v2: Lots of improvements Suggestions from Chris: - Move invalidate/flush in flush_*_domain and set_to_*_domain. - Drop the flush in busy_ioctl since it's redundant. Was a leftover from an earlier concept to track flips/delayed flushes. - Don't forget about the initial modeset enable/final disable. Suggested by Chris. Track flips accurately, too. Since flips complete independently of rendering we need to track pending flips in a separate mask. Again if an invalidate happens we need to cancel the evenutal flush to avoid races. v3: Provide correct header declarations for flip functions. Currently not needed outside of intel_display.c, but part of the proper interface. v4: Add proper domain management to fbcon so that the fbcon buffer is also tracked correctly. v5: Fixup locking around the fbcon set_to_gtt_domain call. v6: More comments from Chris: - Split out fbcon changes. - Drop superflous checks for potential scanout before calling intel_fb functions - we can micro-optimize this later. - s/intel_fb_/intel_fb_obj_/ to make it clear that this deals in gem object. We already have precedence for fb_obj in the pin_and_fence functions. v7: Clarify the semantics of the flip flush handling by renaming things a bit: - Don't go through a gem object but take the relevant frontbuffer bits directly. These functions center on the plane, the actual object is irrelevant - even a flip to the same object as already active should cause a flush. - Add a new intel_frontbuffer_flip for synchronous plane updates. It currently just calls intel_frontbuffer_flush since the implemenation differs. This way we achieve a clear split between one-shot update events on one side and frontbuffer rendering with potentially a very long delay between the invalidate and flush. Chris and I also had some discussions about mark_busy and whether it is appropriate to call from flush. But mark busy is a state which should be derived from the 3 events (invalidate, flush, flip) we now have by the users, like psr does by tracking relevant information in psr.busy_frontbuffer_bits. DRRS (the only real use of mark_busy for frontbuffer) needs to have similar logic. With that the overall mark_busy in the core could be removed. v8: Only when retiring gpu buffers only flush frontbuffer bits we actually invalidated in a batch. Just for safety since before any additional usage/invalidate we should always retire current rendering. Suggested by Chris Wilson. v9: Actually use intel_frontbuffer_flip in all appropriate places. Spotted by Chris. v10: Address more comments from Chris: - Don't call _flip in set_base when the crtc is inactive, avoids redunancy in the modeset case with the initial enabling of all planes. - Add comments explaining that the initial/final plane enable/disable still has work left to do before it's fully generic. v11: Only invalidate for gtt/cpu access when writing. Spotted by Chris. v12: s/_flush/_flip/ in intel_overlay.c per Chris' comment. Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-19 16:01:59 +02:00
*/
if (IS_GEN2(dev))
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
/* Underruns don't always raise interrupts, so check manually. */
intel_check_cpu_fifo_underruns(dev_priv);
intel_check_pch_fifo_underruns(dev_priv);
}
/* FIXME move all this to pre_plane_update() with proper state tracking */
static void
intel_pre_disable_primary(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;
/*
* Gen2 reports pipe underruns whenever all planes are disabled.
* So diasble underrun reporting before all the planes get disabled.
* FIXME: Need to fix the logic to work when we turn off all planes
* but leave the pipe running.
*/
if (IS_GEN2(dev))
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
/*
* FIXME IPS should be fine as long as one plane is
* enabled, but in practice it seems to have problems
* when going from primary only to sprite only and vice
* versa.
*/
hsw_disable_ips(intel_crtc);
}
/* FIXME get rid of this and use pre_plane_update */
static void
intel_pre_disable_primary_noatomic(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;
intel_pre_disable_primary(crtc);
/*
* Vblank time updates from the shadow to live plane control register
* are blocked if the memory self-refresh mode is active at that
* moment. So to make sure the plane gets truly disabled, disable
* first the self-refresh mode. The self-refresh enable bit in turn
* will be checked/applied by the HW only at the next frame start
* event which is after the vblank start event, so we need to have a
* wait-for-vblank between disabling the plane and the pipe.
*/
if (HAS_GMCH_DISPLAY(dev)) {
intel_set_memory_cxsr(dev_priv, false);
dev_priv->wm.vlv.cxsr = false;
intel_wait_for_vblank(dev, pipe);
}
}
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
struct drm_atomic_state *old_state = old_crtc_state->base.state;
struct intel_crtc_state *pipe_config =
to_intel_crtc_state(crtc->base.state);
struct drm_device *dev = crtc->base.dev;
struct drm_plane *primary = crtc->base.primary;
struct drm_plane_state *old_pri_state =
drm_atomic_get_existing_plane_state(old_state, primary);
intel_frontbuffer_flip(dev, pipe_config->fb_bits);
crtc->wm.cxsr_allowed = true;
if (pipe_config->update_wm_post && pipe_config->base.active)
intel_update_watermarks(&crtc->base);
if (old_pri_state) {
struct intel_plane_state *primary_state =
to_intel_plane_state(primary->state);
struct intel_plane_state *old_primary_state =
to_intel_plane_state(old_pri_state);
intel_fbc_post_update(crtc);
if (primary_state->visible &&
(needs_modeset(&pipe_config->base) ||
!old_primary_state->visible))
intel_post_enable_primary(&crtc->base);
}
}
static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc_state *pipe_config =
to_intel_crtc_state(crtc->base.state);
struct drm_atomic_state *old_state = old_crtc_state->base.state;
struct drm_plane *primary = crtc->base.primary;
struct drm_plane_state *old_pri_state =
drm_atomic_get_existing_plane_state(old_state, primary);
bool modeset = needs_modeset(&pipe_config->base);
if (old_pri_state) {
struct intel_plane_state *primary_state =
to_intel_plane_state(primary->state);
struct intel_plane_state *old_primary_state =
to_intel_plane_state(old_pri_state);
intel_fbc_pre_update(crtc, pipe_config, primary_state);
if (old_primary_state->visible &&
(modeset || !primary_state->visible))
intel_pre_disable_primary(&crtc->base);
}
if (pipe_config->disable_cxsr && HAS_GMCH_DISPLAY(dev)) {
crtc->wm.cxsr_allowed = false;
drm/i915: Do not disable cxsr when crtc is disabled. It's safe to assume cxsr is already disabled when the crtc is off. This prevents an unclaimed register warning when the required power wells are not enabled. [ 262.864984] ------------[ cut here ]------------ [ 262.865025] WARNING: CPU: 1 PID: 6799 at drivers/gpu/drm/i915/intel_uncore.c:638 __unclaimed_reg_debug+0x68/0x80 [i915]() [ 262.865029] Unclaimed register detected before reading register 0x186500 [ 262.865032] Modules linked in: i915 intel_powerclamp [ 262.865057] CPU: 1 PID: 6799 Comm: kms_pipe_crc_ba Tainted: G U W 4.4.0-gfxbench+ #1 [ 262.865060] Hardware name: DN2820FYK, BIOS FYBYT10H.86A.0038.2014.0717.1455 07/17/2014 [ 262.865064] ffffffffa0338cf8 ffff88007448ba78 ffffffff813df90c ffff88007448bac0 [ 262.865071] ffff88007448bab0 ffffffff810746e1 0000000000186500 0000000000000001 [ 262.865077] 0000000000000001 ffff880074420000 0000000000000000 ffff88007448bb10 [ 262.865083] Call Trace: [ 262.865092] [<ffffffff813df90c>] dump_stack+0x4e/0x82 [ 262.865098] [<ffffffff810746e1>] warn_slowpath_common+0x81/0xc0 [ 262.865102] [<ffffffff81074767>] warn_slowpath_fmt+0x47/0x50 [ 262.865128] [<ffffffffa02a07e8>] __unclaimed_reg_debug+0x68/0x80 [i915] [ 262.865154] [<ffffffffa02a0e4e>] vlv_read32+0x2de/0x370 [i915] [ 262.865173] [<ffffffffa0256837>] intel_set_memory_cxsr+0x87/0x1a0 [i915] [ 262.865200] [<ffffffffa02c4cb3>] intel_pre_plane_update+0xb3/0xf0 [i915] [ 262.865228] [<ffffffffa02c54b5>] intel_atomic_commit+0x3b5/0x17c0 [i915] [ 262.865234] [<ffffffff8150dc45>] ? drm_atomic_check_only+0x145/0x660 [ 262.865239] [<ffffffff8150d75a>] ? drm_atomic_set_crtc_for_connector+0x6a/0xe0 [ 262.865243] [<ffffffff8150e192>] drm_atomic_commit+0x32/0x50 [ 262.865249] [<ffffffff814eb155>] drm_atomic_helper_set_config+0x75/0xb0 [ 262.865253] [<ffffffff814fd090>] drm_mode_set_config_internal+0x60/0x110 [ 262.865258] [<ffffffff81501e26>] drm_mode_setcrtc+0x186/0x4f0 [ 262.865263] [<ffffffff814f3eed>] drm_ioctl+0x13d/0x590 [ 262.865267] [<ffffffff81501ca0>] ? drm_mode_setplane+0x1b0/0x1b0 [ 262.865273] [<ffffffff811d4c4c>] do_vfs_ioctl+0x2fc/0x550 [ 262.865278] [<ffffffff8118d5ea>] ? vm_munmap+0x4a/0x60 [ 262.865283] [<ffffffff811e06ba>] ? __fget_light+0x6a/0x90 [ 262.865287] [<ffffffff811d4edc>] SyS_ioctl+0x3c/0x70 [ 262.865292] [<ffffffff8179a75b>] entry_SYSCALL_64_fastpath+0x16/0x73 [ 262.865296] ---[ end trace 6387a0ad001bb39f ]--- Testcase: kms_flip.basic-flip-vs-wf_vblank Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93698 Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1454514805-10595-4-git-send-email-maarten.lankhorst@linux.intel.com Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
2016-02-03 16:53:25 +01:00
/*
* Vblank time updates from the shadow to live plane control register
* are blocked if the memory self-refresh mode is active at that
* moment. So to make sure the plane gets truly disabled, disable
* first the self-refresh mode. The self-refresh enable bit in turn
* will be checked/applied by the HW only at the next frame start
* event which is after the vblank start event, so we need to have a
* wait-for-vblank between disabling the plane and the pipe.
*/
if (old_crtc_state->base.active) {
drm/i915: Do not disable cxsr when crtc is disabled. It's safe to assume cxsr is already disabled when the crtc is off. This prevents an unclaimed register warning when the required power wells are not enabled. [ 262.864984] ------------[ cut here ]------------ [ 262.865025] WARNING: CPU: 1 PID: 6799 at drivers/gpu/drm/i915/intel_uncore.c:638 __unclaimed_reg_debug+0x68/0x80 [i915]() [ 262.865029] Unclaimed register detected before reading register 0x186500 [ 262.865032] Modules linked in: i915 intel_powerclamp [ 262.865057] CPU: 1 PID: 6799 Comm: kms_pipe_crc_ba Tainted: G U W 4.4.0-gfxbench+ #1 [ 262.865060] Hardware name: DN2820FYK, BIOS FYBYT10H.86A.0038.2014.0717.1455 07/17/2014 [ 262.865064] ffffffffa0338cf8 ffff88007448ba78 ffffffff813df90c ffff88007448bac0 [ 262.865071] ffff88007448bab0 ffffffff810746e1 0000000000186500 0000000000000001 [ 262.865077] 0000000000000001 ffff880074420000 0000000000000000 ffff88007448bb10 [ 262.865083] Call Trace: [ 262.865092] [<ffffffff813df90c>] dump_stack+0x4e/0x82 [ 262.865098] [<ffffffff810746e1>] warn_slowpath_common+0x81/0xc0 [ 262.865102] [<ffffffff81074767>] warn_slowpath_fmt+0x47/0x50 [ 262.865128] [<ffffffffa02a07e8>] __unclaimed_reg_debug+0x68/0x80 [i915] [ 262.865154] [<ffffffffa02a0e4e>] vlv_read32+0x2de/0x370 [i915] [ 262.865173] [<ffffffffa0256837>] intel_set_memory_cxsr+0x87/0x1a0 [i915] [ 262.865200] [<ffffffffa02c4cb3>] intel_pre_plane_update+0xb3/0xf0 [i915] [ 262.865228] [<ffffffffa02c54b5>] intel_atomic_commit+0x3b5/0x17c0 [i915] [ 262.865234] [<ffffffff8150dc45>] ? drm_atomic_check_only+0x145/0x660 [ 262.865239] [<ffffffff8150d75a>] ? drm_atomic_set_crtc_for_connector+0x6a/0xe0 [ 262.865243] [<ffffffff8150e192>] drm_atomic_commit+0x32/0x50 [ 262.865249] [<ffffffff814eb155>] drm_atomic_helper_set_config+0x75/0xb0 [ 262.865253] [<ffffffff814fd090>] drm_mode_set_config_internal+0x60/0x110 [ 262.865258] [<ffffffff81501e26>] drm_mode_setcrtc+0x186/0x4f0 [ 262.865263] [<ffffffff814f3eed>] drm_ioctl+0x13d/0x590 [ 262.865267] [<ffffffff81501ca0>] ? drm_mode_setplane+0x1b0/0x1b0 [ 262.865273] [<ffffffff811d4c4c>] do_vfs_ioctl+0x2fc/0x550 [ 262.865278] [<ffffffff8118d5ea>] ? vm_munmap+0x4a/0x60 [ 262.865283] [<ffffffff811e06ba>] ? __fget_light+0x6a/0x90 [ 262.865287] [<ffffffff811d4edc>] SyS_ioctl+0x3c/0x70 [ 262.865292] [<ffffffff8179a75b>] entry_SYSCALL_64_fastpath+0x16/0x73 [ 262.865296] ---[ end trace 6387a0ad001bb39f ]--- Testcase: kms_flip.basic-flip-vs-wf_vblank Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93698 Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1454514805-10595-4-git-send-email-maarten.lankhorst@linux.intel.com Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
2016-02-03 16:53:25 +01:00
intel_set_memory_cxsr(dev_priv, false);
dev_priv->wm.vlv.cxsr = false;
intel_wait_for_vblank(dev, crtc->pipe);
}
}
drm/i915: Add two-stage ILK-style watermark programming (v11) In addition to calculating final watermarks, let's also pre-calculate a set of intermediate watermark values at atomic check time. These intermediate watermarks are a combination of the watermarks for the old state and the new state; they should satisfy the requirements of both states which means they can be programmed immediately when we commit the atomic state (without waiting for a vblank). Once the vblank does happen, we can then re-program watermarks to the more optimal final value. v2: Significant rebasing/rewriting. v3: - Move 'need_postvbl_update' flag to CRTC state (Daniel) - Don't forget to check intermediate watermark values for validity (Maarten) - Don't due async watermark optimization; just do it at the end of the atomic transaction, after waiting for vblanks. We do want it to be async eventually, but adding that now will cause more trouble for Maarten's in-progress work. (Maarten) - Don't allocate space in crtc_state for intermediate watermarks on platforms that don't need it (gen9+). - Move WaCxSRDisabledForSpriteScaling:ivb into intel_begin_crtc_commit now that ilk_update_wm is gone. v4: - Add a wm_mutex to cover updates to intel_crtc->active and the need_postvbl_update flag. Since we don't have async yet it isn't terribly important yet, but might as well add it now. - Change interface to program watermarks. Platforms will now expose .initial_watermarks() and .optimize_watermarks() functions to do watermark programming. These should lock wm_mutex, copy the appropriate state values into intel_crtc->active, and then call the internal program watermarks function. v5: - Skip intermediate watermark calculation/check during initial hardware readout since we don't trust the existing HW values (and don't have valid values of our own yet). - Don't try to call .optimize_watermarks() on platforms that don't have atomic watermarks yet. (Maarten) v6: - Rebase v7: - Further rebase v8: - A few minor indentation and line length fixes v9: - Yet another rebase since Maarten's patches reworked a bunch of the code (wm_pre, wm_post, etc.) that this was previously based on. v10: - Move wm_mutex to dev_priv to protect against racing commits against disjoint CRTC sets. (Maarten) - Drop unnecessary clearing of cstate->wm.need_postvbl_update (Maarten) v11: - Now that we've moved to atomic watermark updates, make sure we call the proper function to program watermarks in {ironlake,haswell}_crtc_enable(); the failure to do so on the previous patch iteration led to us not actually programming the watermarks before turning on the CRTC, which was the cause of the underruns that the CI system was seeing. - Fix inverted logic for determining when to optimize watermarks. We were needlessly optimizing when the intermediate/optimal values were the same (harmless), but not actually optimizing when they differed (also harmless, but wasteful from a power/bandwidth perspective). Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1456276813-5689-1-git-send-email-matthew.d.roper@intel.com
2016-02-23 17:20:13 -08:00
/*
* IVB workaround: must disable low power watermarks for at least
* one frame before enabling scaling. LP watermarks can be re-enabled
* when scaling is disabled.
*
* WaCxSRDisabledForSpriteScaling:ivb
*/
if (pipe_config->disable_lp_wm) {
ilk_disable_lp_wm(dev);
intel_wait_for_vblank(dev, crtc->pipe);
}
/*
* If we're doing a modeset, we're done. No need to do any pre-vblank
* watermark programming here.
*/
if (needs_modeset(&pipe_config->base))
return;
/*
* For platforms that support atomic watermarks, program the
* 'intermediate' watermarks immediately. On pre-gen9 platforms, these
* will be the intermediate values that are safe for both pre- and
* post- vblank; when vblank happens, the 'active' values will be set
* to the final 'target' values and we'll do this again to get the
* optimal watermarks. For gen9+ platforms, the values we program here
* will be the final target values which will get automatically latched
* at vblank time; no further programming will be necessary.
*
* If a platform hasn't been transitioned to atomic watermarks yet,
* we'll continue to update watermarks the old way, if flags tell
* us to.
*/
if (dev_priv->display.initial_watermarks != NULL)
dev_priv->display.initial_watermarks(pipe_config);
else if (pipe_config->update_wm_pre)
intel_update_watermarks(&crtc->base);
}
static void intel_crtc_disable_planes(struct drm_crtc *crtc, unsigned plane_mask)
{
struct drm_device *dev = crtc->dev;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct drm_plane *p;
int pipe = intel_crtc->pipe;
intel_crtc_dpms_overlay_disable(intel_crtc);
drm_for_each_plane_mask(p, dev, plane_mask)
to_intel_plane(p)->disable_plane(p, crtc);
drm/i915: Track frontbuffer invalidation/flushing So these are the guts of the new beast. This tracks when a frontbuffer gets invalidated (due to frontbuffer rendering) and hence should be constantly scaned out, and when it's flushed again and can be compressed/one-shot-upload. Rules for flushing are simple: The frontbuffer needs one more full upload starting from the next vblank. Which means that the flushing can _only_ be called once the frontbuffer update has been latched. But this poses a problem for pageflips: We can't just delay the flushing until the pageflip is latched, since that would pose the risk that we override frontbuffer rendering that has been scheduled in-between the pageflip ioctl and the actual latching. To handle this track asynchronous invalidations (and also pageflip) state per-ring and delay any in-between flushing until the rendering has completed. And also cancel any delayed flushing if we get a new invalidation request (whether delayed or not). Also call intel_mark_fb_busy in both cases in all cases to make sure that we keep the screen at the highest refresh rate both on flips, synchronous plane updates and for frontbuffer rendering. v2: Lots of improvements Suggestions from Chris: - Move invalidate/flush in flush_*_domain and set_to_*_domain. - Drop the flush in busy_ioctl since it's redundant. Was a leftover from an earlier concept to track flips/delayed flushes. - Don't forget about the initial modeset enable/final disable. Suggested by Chris. Track flips accurately, too. Since flips complete independently of rendering we need to track pending flips in a separate mask. Again if an invalidate happens we need to cancel the evenutal flush to avoid races. v3: Provide correct header declarations for flip functions. Currently not needed outside of intel_display.c, but part of the proper interface. v4: Add proper domain management to fbcon so that the fbcon buffer is also tracked correctly. v5: Fixup locking around the fbcon set_to_gtt_domain call. v6: More comments from Chris: - Split out fbcon changes. - Drop superflous checks for potential scanout before calling intel_fb functions - we can micro-optimize this later. - s/intel_fb_/intel_fb_obj_/ to make it clear that this deals in gem object. We already have precedence for fb_obj in the pin_and_fence functions. v7: Clarify the semantics of the flip flush handling by renaming things a bit: - Don't go through a gem object but take the relevant frontbuffer bits directly. These functions center on the plane, the actual object is irrelevant - even a flip to the same object as already active should cause a flush. - Add a new intel_frontbuffer_flip for synchronous plane updates. It currently just calls intel_frontbuffer_flush since the implemenation differs. This way we achieve a clear split between one-shot update events on one side and frontbuffer rendering with potentially a very long delay between the invalidate and flush. Chris and I also had some discussions about mark_busy and whether it is appropriate to call from flush. But mark busy is a state which should be derived from the 3 events (invalidate, flush, flip) we now have by the users, like psr does by tracking relevant information in psr.busy_frontbuffer_bits. DRRS (the only real use of mark_busy for frontbuffer) needs to have similar logic. With that the overall mark_busy in the core could be removed. v8: Only when retiring gpu buffers only flush frontbuffer bits we actually invalidated in a batch. Just for safety since before any additional usage/invalidate we should always retire current rendering. Suggested by Chris Wilson. v9: Actually use intel_frontbuffer_flip in all appropriate places. Spotted by Chris. v10: Address more comments from Chris: - Don't call _flip in set_base when the crtc is inactive, avoids redunancy in the modeset case with the initial enabling of all planes. - Add comments explaining that the initial/final plane enable/disable still has work left to do before it's fully generic. v11: Only invalidate for gtt/cpu access when writing. Spotted by Chris. v12: s/_flush/_flip/ in intel_overlay.c per Chris' comment. Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-19 16:01:59 +02:00
/*
* FIXME: Once we grow proper nuclear flip support out of this we need
* to compute the mask of flip planes precisely. For the time being
* consider this a flip to a NULL plane.
*/
intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_ALL_MASK(pipe));
}
static void ironlake_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;
struct intel_crtc_state *pipe_config =
to_intel_crtc_state(crtc->state);
if (WARN_ON(intel_crtc->active))
return;
drm/i915: Try to shut up more ILK underruns Take a bigger hammer to the underrun suppression on ILK. Instead of trying to suppress them at specific points in the modeset sequence just silence them across the entire sequence. This gets rid of some underruns at least on my ILK. Note that this changes SNB and IVB to follow the same approach just to keep the code less convoluted. The difference is that on those platforms we won't suppress CPU underruns for port A since it doesn't seem to be necessary. My ILK has port A eDP and two PCH HDMI ports, so I can't be sure this is as effective on other PCH port types. Perhaps we still need some of Daniel's extra vblank waits [2]? I've still been able to trigger an underrun on the other pipe, but fixing that perhaps needs the LP1+ disable trick I implemented here [1] which never got merged. A few details which hamper stress testing on my ILK are that sometimes the PCH transcoder gets messed up and refuses to shut down, and sometimes even the panel power sequencer apparently gets stuck on the always on position. [1] https://lists.freedesktop.org/archives/intel-gfx/2014-March/041317.html [2] https://lists.freedesktop.org/archives/intel-gfx/2016-January/086397.html v2: Add a note that we also get underruns when enabling PCH ports Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> (v1) Link: http://patchwork.freedesktop.org/patch/msgid/1459536799-18109-2-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Patrik Jakobsson <patrik.jakobsson@linux.intel.com>
2016-04-01 21:53:17 +03:00
/*
* Sometimes spurious CPU pipe underruns happen during FDI
* training, at least with VGA+HDMI cloning. Suppress them.
*
* On ILK we get an occasional spurious CPU pipe underruns
* between eDP port A enable and vdd enable. Also PCH port
* enable seems to result in the occasional CPU pipe underrun.
*
* Spurious PCH underruns also occur during PCH enabling.
*/
if (intel_crtc->config->has_pch_encoder || IS_GEN5(dev_priv))
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
if (intel_crtc->config->has_pch_encoder)
intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, false);
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (intel_crtc->config->has_pch_encoder)
intel_prepare_shared_dpll(intel_crtc);
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (intel_crtc->config->has_dp_encoder)
intel_dp_set_m_n(intel_crtc, M1_N1);
intel_set_pipe_timings(intel_crtc);
intel_set_pipe_src_size(intel_crtc);
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (intel_crtc->config->has_pch_encoder) {
intel_cpu_transcoder_set_m_n(intel_crtc,
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
&intel_crtc->config->fdi_m_n, NULL);
}
ironlake_set_pipeconf(crtc);
intel_crtc->active = true;
for_each_encoder_on_crtc(dev, crtc, encoder)
if (encoder->pre_enable)
encoder->pre_enable(encoder);
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (intel_crtc->config->has_pch_encoder) {
/* Note: FDI PLL enabling _must_ be done before we enable the
* cpu pipes, hence this is separate from all the other fdi/pch
* enabling. */
ironlake_fdi_pll_enable(intel_crtc);
} else {
assert_fdi_tx_disabled(dev_priv, pipe);
assert_fdi_rx_disabled(dev_priv, pipe);
}
ironlake_pfit_enable(intel_crtc);
/*
* On ILK+ LUT must be loaded before the pipe is running but with
* clocks enabled
*/
intel_color_load_luts(&pipe_config->base);
if (dev_priv->display.initial_watermarks != NULL)
dev_priv->display.initial_watermarks(intel_crtc->config);
intel_enable_pipe(intel_crtc);
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (intel_crtc->config->has_pch_encoder)
ironlake_pch_enable(crtc);
drm/i915: Push vblank enable/disable past encoder->enable/disable It is platform/output depenedent when exactly the pipe will start running. Sometimes we just need the (cpu) pipe enabled, in other cases the pch transcoder is enough and in yet other cases the (DP) port is sending the frame start signal. In a perfect world we'd put the drm_crtc_vblank_on call exactly where the pipe starts running, but due to cloning and similar things this will get messy. And the current approach of picking the most conservative place for all combinations also doesn't work since that results in legit vblank waits (in encoder->enable hooks, e.g. the 2 vblank waits for sdvo) failing. Completely going back to the old world before commit 51e31d49c89055299e34b8f44d13f70e19aaaad1 Author: Daniel Vetter <daniel.vetter@ffwll.ch> Date: Mon Sep 15 12:36:02 2014 +0200 drm/i915: Use generic vblank wait isn't great either since screaming when the vblank wait work because the pipe is off is kinda nice. Pick a compromise and move the drm_crtc_vblank_on right before the encoder->enable call. This is a lie on some outputs/platforms, but after the ->enable callback the pipe is guaranteed to run everywhere. So not that bad really. Suggested by Ville. v2: Same treatment for drm_crtc_vblank_off and encoder->disable: I've missed the ibx pipe B select w/a, which also has a vblank wait in the disable function (while the pipe is obviously still running). Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2015-01-07 13:54:39 +01:00
assert_vblank_disabled(crtc);
drm_crtc_vblank_on(crtc);
for_each_encoder_on_crtc(dev, crtc, encoder)
encoder->enable(encoder);
if (HAS_PCH_CPT(dev))
cpt_verify_modeset(dev, intel_crtc->pipe);
/* Must wait for vblank to avoid spurious PCH FIFO underruns */
if (intel_crtc->config->has_pch_encoder)
intel_wait_for_vblank(dev, pipe);
drm/i915: Try to shut up more ILK underruns Take a bigger hammer to the underrun suppression on ILK. Instead of trying to suppress them at specific points in the modeset sequence just silence them across the entire sequence. This gets rid of some underruns at least on my ILK. Note that this changes SNB and IVB to follow the same approach just to keep the code less convoluted. The difference is that on those platforms we won't suppress CPU underruns for port A since it doesn't seem to be necessary. My ILK has port A eDP and two PCH HDMI ports, so I can't be sure this is as effective on other PCH port types. Perhaps we still need some of Daniel's extra vblank waits [2]? I've still been able to trigger an underrun on the other pipe, but fixing that perhaps needs the LP1+ disable trick I implemented here [1] which never got merged. A few details which hamper stress testing on my ILK are that sometimes the PCH transcoder gets messed up and refuses to shut down, and sometimes even the panel power sequencer apparently gets stuck on the always on position. [1] https://lists.freedesktop.org/archives/intel-gfx/2014-March/041317.html [2] https://lists.freedesktop.org/archives/intel-gfx/2016-January/086397.html v2: Add a note that we also get underruns when enabling PCH ports Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> (v1) Link: http://patchwork.freedesktop.org/patch/msgid/1459536799-18109-2-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Patrik Jakobsson <patrik.jakobsson@linux.intel.com>
2016-04-01 21:53:17 +03:00
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true);
}
/* IPS only exists on ULT machines and is tied to pipe A. */
static bool hsw_crtc_supports_ips(struct intel_crtc *crtc)
{
return HAS_IPS(crtc->base.dev) && crtc->pipe == PIPE_A;
}
static void haswell_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, hsw_workaround_pipe;
enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
struct intel_crtc_state *pipe_config =
to_intel_crtc_state(crtc->state);
if (WARN_ON(intel_crtc->active))
return;
if (intel_crtc->config->has_pch_encoder)
intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
false);
for_each_encoder_on_crtc(dev, crtc, encoder)
if (encoder->pre_pll_enable)
encoder->pre_pll_enable(encoder);
if (intel_crtc->config->shared_dpll)
intel_enable_shared_dpll(intel_crtc);
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (intel_crtc->config->has_dp_encoder)
intel_dp_set_m_n(intel_crtc, M1_N1);
if (!intel_crtc->config->has_dsi_encoder)
intel_set_pipe_timings(intel_crtc);
intel_set_pipe_src_size(intel_crtc);
if (cpu_transcoder != TRANSCODER_EDP &&
!transcoder_is_dsi(cpu_transcoder)) {
I915_WRITE(PIPE_MULT(cpu_transcoder),
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
intel_crtc->config->pixel_multiplier - 1);
}
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (intel_crtc->config->has_pch_encoder) {
intel_cpu_transcoder_set_m_n(intel_crtc,
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
&intel_crtc->config->fdi_m_n, NULL);
}
if (!intel_crtc->config->has_dsi_encoder)
haswell_set_pipeconf(crtc);
haswell_set_pipemisc(crtc);
intel_color_set_csc(&pipe_config->base);
intel_crtc->active = true;
if (intel_crtc->config->has_pch_encoder)
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
else
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
for_each_encoder_on_crtc(dev, crtc, encoder) {
if (encoder->pre_enable)
encoder->pre_enable(encoder);
}
if (intel_crtc->config->has_pch_encoder)
dev_priv->display.fdi_link_train(crtc);
if (!intel_crtc->config->has_dsi_encoder)
intel_ddi_enable_pipe_clock(intel_crtc);
if (INTEL_INFO(dev)->gen >= 9)
skylake_pfit_enable(intel_crtc);
else
ironlake_pfit_enable(intel_crtc);
/*
* On ILK+ LUT must be loaded before the pipe is running but with
* clocks enabled
*/
intel_color_load_luts(&pipe_config->base);
intel_ddi_set_pipe_settings(crtc);
if (!intel_crtc->config->has_dsi_encoder)
intel_ddi_enable_transcoder_func(crtc);
if (dev_priv->display.initial_watermarks != NULL)
dev_priv->display.initial_watermarks(pipe_config);
else
intel_update_watermarks(crtc);
/* XXX: Do the pipe assertions at the right place for BXT DSI. */
if (!intel_crtc->config->has_dsi_encoder)
intel_enable_pipe(intel_crtc);
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (intel_crtc->config->has_pch_encoder)
lpt_pch_enable(crtc);
if (intel_crtc->config->dp_encoder_is_mst)
2014-05-02 14:02:48 +10:00
intel_ddi_set_vc_payload_alloc(crtc, true);
drm/i915: Push vblank enable/disable past encoder->enable/disable It is platform/output depenedent when exactly the pipe will start running. Sometimes we just need the (cpu) pipe enabled, in other cases the pch transcoder is enough and in yet other cases the (DP) port is sending the frame start signal. In a perfect world we'd put the drm_crtc_vblank_on call exactly where the pipe starts running, but due to cloning and similar things this will get messy. And the current approach of picking the most conservative place for all combinations also doesn't work since that results in legit vblank waits (in encoder->enable hooks, e.g. the 2 vblank waits for sdvo) failing. Completely going back to the old world before commit 51e31d49c89055299e34b8f44d13f70e19aaaad1 Author: Daniel Vetter <daniel.vetter@ffwll.ch> Date: Mon Sep 15 12:36:02 2014 +0200 drm/i915: Use generic vblank wait isn't great either since screaming when the vblank wait work because the pipe is off is kinda nice. Pick a compromise and move the drm_crtc_vblank_on right before the encoder->enable call. This is a lie on some outputs/platforms, but after the ->enable callback the pipe is guaranteed to run everywhere. So not that bad really. Suggested by Ville. v2: Same treatment for drm_crtc_vblank_off and encoder->disable: I've missed the ibx pipe B select w/a, which also has a vblank wait in the disable function (while the pipe is obviously still running). Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2015-01-07 13:54:39 +01:00
assert_vblank_disabled(crtc);
drm_crtc_vblank_on(crtc);
for_each_encoder_on_crtc(dev, crtc, encoder) {
encoder->enable(encoder);
intel_opregion_notify_encoder(encoder, true);
}
if (intel_crtc->config->has_pch_encoder) {
intel_wait_for_vblank(dev, pipe);
intel_wait_for_vblank(dev, pipe);
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
true);
}
/* If we change the relative order between pipe/planes enabling, we need
* to change the workaround. */
hsw_workaround_pipe = pipe_config->hsw_workaround_pipe;
if (IS_HASWELL(dev) && hsw_workaround_pipe != INVALID_PIPE) {
intel_wait_for_vblank(dev, hsw_workaround_pipe);
intel_wait_for_vblank(dev, hsw_workaround_pipe);
}
}
static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force)
{
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 (force || crtc->config->pch_pfit.enabled) {
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;
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;
drm/i915: Try to shut up more ILK underruns Take a bigger hammer to the underrun suppression on ILK. Instead of trying to suppress them at specific points in the modeset sequence just silence them across the entire sequence. This gets rid of some underruns at least on my ILK. Note that this changes SNB and IVB to follow the same approach just to keep the code less convoluted. The difference is that on those platforms we won't suppress CPU underruns for port A since it doesn't seem to be necessary. My ILK has port A eDP and two PCH HDMI ports, so I can't be sure this is as effective on other PCH port types. Perhaps we still need some of Daniel's extra vblank waits [2]? I've still been able to trigger an underrun on the other pipe, but fixing that perhaps needs the LP1+ disable trick I implemented here [1] which never got merged. A few details which hamper stress testing on my ILK are that sometimes the PCH transcoder gets messed up and refuses to shut down, and sometimes even the panel power sequencer apparently gets stuck on the always on position. [1] https://lists.freedesktop.org/archives/intel-gfx/2014-March/041317.html [2] https://lists.freedesktop.org/archives/intel-gfx/2016-January/086397.html v2: Add a note that we also get underruns when enabling PCH ports Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> (v1) Link: http://patchwork.freedesktop.org/patch/msgid/1459536799-18109-2-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Patrik Jakobsson <patrik.jakobsson@linux.intel.com>
2016-04-01 21:53:17 +03:00
/*
* Sometimes spurious CPU pipe underruns happen when the
* pipe is already disabled, but FDI RX/TX is still enabled.
* Happens at least with VGA+HDMI cloning. Suppress them.
*/
if (intel_crtc->config->has_pch_encoder) {
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, false);
drm/i915: Try to shut up more ILK underruns Take a bigger hammer to the underrun suppression on ILK. Instead of trying to suppress them at specific points in the modeset sequence just silence them across the entire sequence. This gets rid of some underruns at least on my ILK. Note that this changes SNB and IVB to follow the same approach just to keep the code less convoluted. The difference is that on those platforms we won't suppress CPU underruns for port A since it doesn't seem to be necessary. My ILK has port A eDP and two PCH HDMI ports, so I can't be sure this is as effective on other PCH port types. Perhaps we still need some of Daniel's extra vblank waits [2]? I've still been able to trigger an underrun on the other pipe, but fixing that perhaps needs the LP1+ disable trick I implemented here [1] which never got merged. A few details which hamper stress testing on my ILK are that sometimes the PCH transcoder gets messed up and refuses to shut down, and sometimes even the panel power sequencer apparently gets stuck on the always on position. [1] https://lists.freedesktop.org/archives/intel-gfx/2014-March/041317.html [2] https://lists.freedesktop.org/archives/intel-gfx/2016-January/086397.html v2: Add a note that we also get underruns when enabling PCH ports Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> (v1) Link: http://patchwork.freedesktop.org/patch/msgid/1459536799-18109-2-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Patrik Jakobsson <patrik.jakobsson@linux.intel.com>
2016-04-01 21:53:17 +03:00
}
drm/i915: push commit_output_state past the crtc/encoder preparing With this change we can (finally!) rip out a few of the temporary hacks and clean up a few other things: - Kill intel_crtc_prepare_encoders, now unused. - Kill the hacks in the crtc_disable/enable functions to always call the encoder callbacks, we now always call the crtc functions with the right encoder -> crtc links. - Also push down the crtc->enable, encoder and connector dpms state updates. Unfortunately we can't add a WARN in the crtc_disable callbacks to ensure that the crtc is always still enabled when disabling an output pipe - the crtc sanitizer of the hw readout path can hit this when it needs to disable an active pipe without any enabled outputs. - Only call crtc->disable if the pipe is already enabled - again avoids running afoul of the new WARN. v2: Copy&paste our own version of crtc_in_use, too. v3: We need to update the dpms an encoder->connectors_active states, too. v4: I've forgotten to kill the unconditional encoder->disable calls in the crtc_disable functions. v5: Rip out leftover debug printk. v6: Properly clear intel_encoder->connectors_active. This wasn't properly cleared when disabling an encoder because it was no longer on the new connector list, but the crtc was still enabled (i.e. switching the encoder of an active crtc). Reported by Jani Nikula. v7: Don't clobber the encoder->connectors_active state of untouched encoders. Since X likes to first disable all outputs with dpms off before setting a new framebuffer, this hit a few warnings. Reported by Paulo Zanoni. v8: Kill the now stale comment warning that intel_crtc->active is not always updated at the right times. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-10 10:42:52 +02:00
for_each_encoder_on_crtc(dev, crtc, encoder)
encoder->disable(encoder);
drm/i915: Push vblank enable/disable past encoder->enable/disable It is platform/output depenedent when exactly the pipe will start running. Sometimes we just need the (cpu) pipe enabled, in other cases the pch transcoder is enough and in yet other cases the (DP) port is sending the frame start signal. In a perfect world we'd put the drm_crtc_vblank_on call exactly where the pipe starts running, but due to cloning and similar things this will get messy. And the current approach of picking the most conservative place for all combinations also doesn't work since that results in legit vblank waits (in encoder->enable hooks, e.g. the 2 vblank waits for sdvo) failing. Completely going back to the old world before commit 51e31d49c89055299e34b8f44d13f70e19aaaad1 Author: Daniel Vetter <daniel.vetter@ffwll.ch> Date: Mon Sep 15 12:36:02 2014 +0200 drm/i915: Use generic vblank wait isn't great either since screaming when the vblank wait work because the pipe is off is kinda nice. Pick a compromise and move the drm_crtc_vblank_on right before the encoder->enable call. This is a lie on some outputs/platforms, but after the ->enable callback the pipe is guaranteed to run everywhere. So not that bad really. Suggested by Ville. v2: Same treatment for drm_crtc_vblank_off and encoder->disable: I've missed the ibx pipe B select w/a, which also has a vblank wait in the disable function (while the pipe is obviously still running). Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2015-01-07 13:54:39 +01:00
drm_crtc_vblank_off(crtc);
assert_vblank_disabled(crtc);
intel_disable_pipe(intel_crtc);
ironlake_pfit_disable(intel_crtc, false);
drm/i915: Try to shut up more ILK underruns Take a bigger hammer to the underrun suppression on ILK. Instead of trying to suppress them at specific points in the modeset sequence just silence them across the entire sequence. This gets rid of some underruns at least on my ILK. Note that this changes SNB and IVB to follow the same approach just to keep the code less convoluted. The difference is that on those platforms we won't suppress CPU underruns for port A since it doesn't seem to be necessary. My ILK has port A eDP and two PCH HDMI ports, so I can't be sure this is as effective on other PCH port types. Perhaps we still need some of Daniel's extra vblank waits [2]? I've still been able to trigger an underrun on the other pipe, but fixing that perhaps needs the LP1+ disable trick I implemented here [1] which never got merged. A few details which hamper stress testing on my ILK are that sometimes the PCH transcoder gets messed up and refuses to shut down, and sometimes even the panel power sequencer apparently gets stuck on the always on position. [1] https://lists.freedesktop.org/archives/intel-gfx/2014-March/041317.html [2] https://lists.freedesktop.org/archives/intel-gfx/2016-January/086397.html v2: Add a note that we also get underruns when enabling PCH ports Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> (v1) Link: http://patchwork.freedesktop.org/patch/msgid/1459536799-18109-2-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Patrik Jakobsson <patrik.jakobsson@linux.intel.com>
2016-04-01 21:53:17 +03:00
if (intel_crtc->config->has_pch_encoder)
ironlake_fdi_disable(crtc);
for_each_encoder_on_crtc(dev, crtc, encoder)
if (encoder->post_disable)
encoder->post_disable(encoder);
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (intel_crtc->config->has_pch_encoder) {
ironlake_disable_pch_transcoder(dev_priv, pipe);
if (HAS_PCH_CPT(dev)) {
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
i915_reg_t reg;
u32 temp;
/* 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);
temp &= ~(TRANS_DPLL_ENABLE(pipe) | TRANS_DPLLB_SEL(pipe));
I915_WRITE(PCH_DPLL_SEL, temp);
}
ironlake_fdi_pll_disable(intel_crtc);
}
drm/i915: Try to shut up more ILK underruns Take a bigger hammer to the underrun suppression on ILK. Instead of trying to suppress them at specific points in the modeset sequence just silence them across the entire sequence. This gets rid of some underruns at least on my ILK. Note that this changes SNB and IVB to follow the same approach just to keep the code less convoluted. The difference is that on those platforms we won't suppress CPU underruns for port A since it doesn't seem to be necessary. My ILK has port A eDP and two PCH HDMI ports, so I can't be sure this is as effective on other PCH port types. Perhaps we still need some of Daniel's extra vblank waits [2]? I've still been able to trigger an underrun on the other pipe, but fixing that perhaps needs the LP1+ disable trick I implemented here [1] which never got merged. A few details which hamper stress testing on my ILK are that sometimes the PCH transcoder gets messed up and refuses to shut down, and sometimes even the panel power sequencer apparently gets stuck on the always on position. [1] https://lists.freedesktop.org/archives/intel-gfx/2014-March/041317.html [2] https://lists.freedesktop.org/archives/intel-gfx/2016-January/086397.html v2: Add a note that we also get underruns when enabling PCH ports Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> (v1) Link: http://patchwork.freedesktop.org/patch/msgid/1459536799-18109-2-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Patrik Jakobsson <patrik.jakobsson@linux.intel.com>
2016-04-01 21:53:17 +03:00
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true);
}
static void haswell_crtc_disable(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;
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
if (intel_crtc->config->has_pch_encoder)
intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
false);
for_each_encoder_on_crtc(dev, crtc, encoder) {
intel_opregion_notify_encoder(encoder, false);
encoder->disable(encoder);
}
drm/i915: Push vblank enable/disable past encoder->enable/disable It is platform/output depenedent when exactly the pipe will start running. Sometimes we just need the (cpu) pipe enabled, in other cases the pch transcoder is enough and in yet other cases the (DP) port is sending the frame start signal. In a perfect world we'd put the drm_crtc_vblank_on call exactly where the pipe starts running, but due to cloning and similar things this will get messy. And the current approach of picking the most conservative place for all combinations also doesn't work since that results in legit vblank waits (in encoder->enable hooks, e.g. the 2 vblank waits for sdvo) failing. Completely going back to the old world before commit 51e31d49c89055299e34b8f44d13f70e19aaaad1 Author: Daniel Vetter <daniel.vetter@ffwll.ch> Date: Mon Sep 15 12:36:02 2014 +0200 drm/i915: Use generic vblank wait isn't great either since screaming when the vblank wait work because the pipe is off is kinda nice. Pick a compromise and move the drm_crtc_vblank_on right before the encoder->enable call. This is a lie on some outputs/platforms, but after the ->enable callback the pipe is guaranteed to run everywhere. So not that bad really. Suggested by Ville. v2: Same treatment for drm_crtc_vblank_off and encoder->disable: I've missed the ibx pipe B select w/a, which also has a vblank wait in the disable function (while the pipe is obviously still running). Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2015-01-07 13:54:39 +01:00
drm_crtc_vblank_off(crtc);
assert_vblank_disabled(crtc);
/* XXX: Do the pipe assertions at the right place for BXT DSI. */
if (!intel_crtc->config->has_dsi_encoder)
intel_disable_pipe(intel_crtc);
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (intel_crtc->config->dp_encoder_is_mst)
intel_ddi_set_vc_payload_alloc(crtc, false);
if (!intel_crtc->config->has_dsi_encoder)
intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder);
if (INTEL_INFO(dev)->gen >= 9)
skylake_scaler_disable(intel_crtc);
else
ironlake_pfit_disable(intel_crtc, false);
if (!intel_crtc->config->has_dsi_encoder)
intel_ddi_disable_pipe_clock(intel_crtc);
for_each_encoder_on_crtc(dev, crtc, encoder)
if (encoder->post_disable)
encoder->post_disable(encoder);
if (intel_crtc->config->has_pch_encoder) {
lpt_disable_pch_transcoder(dev_priv);
lpt_disable_iclkip(dev_priv);
intel_ddi_fdi_disable(crtc);
intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
true);
}
}
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;
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
struct intel_crtc_state *pipe_config = crtc->config;
if (!pipe_config->gmch_pfit.control)
return;
/*
* The panel fitter should only be adjusted whilst the pipe is disabled,
* according to register description and PRM.
*/
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);
/* 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 enum intel_display_power_domain port_to_power_domain(enum port port)
{
switch (port) {
case PORT_A:
return POWER_DOMAIN_PORT_DDI_A_LANES;
case PORT_B:
return POWER_DOMAIN_PORT_DDI_B_LANES;
case PORT_C:
return POWER_DOMAIN_PORT_DDI_C_LANES;
case PORT_D:
return POWER_DOMAIN_PORT_DDI_D_LANES;
case PORT_E:
return POWER_DOMAIN_PORT_DDI_E_LANES;
default:
MISSING_CASE(port);
return POWER_DOMAIN_PORT_OTHER;
}
}
static enum intel_display_power_domain port_to_aux_power_domain(enum port port)
{
switch (port) {
case PORT_A:
return POWER_DOMAIN_AUX_A;
case PORT_B:
return POWER_DOMAIN_AUX_B;
case PORT_C:
return POWER_DOMAIN_AUX_C;
case PORT_D:
return POWER_DOMAIN_AUX_D;
case PORT_E:
/* FIXME: Check VBT for actual wiring of PORT E */
return POWER_DOMAIN_AUX_D;
default:
MISSING_CASE(port);
return POWER_DOMAIN_AUX_A;
}
}
enum intel_display_power_domain
intel_display_port_power_domain(struct intel_encoder *intel_encoder)
{
struct drm_device *dev = intel_encoder->base.dev;
struct intel_digital_port *intel_dig_port;
switch (intel_encoder->type) {
case INTEL_OUTPUT_UNKNOWN:
/* Only DDI platforms should ever use this output type */
WARN_ON_ONCE(!HAS_DDI(dev));
case INTEL_OUTPUT_DISPLAYPORT:
case INTEL_OUTPUT_HDMI:
case INTEL_OUTPUT_EDP:
intel_dig_port = enc_to_dig_port(&intel_encoder->base);
return port_to_power_domain(intel_dig_port->port);
2014-05-02 14:02:48 +10:00
case INTEL_OUTPUT_DP_MST:
intel_dig_port = enc_to_mst(&intel_encoder->base)->primary;
return port_to_power_domain(intel_dig_port->port);
case INTEL_OUTPUT_ANALOG:
return POWER_DOMAIN_PORT_CRT;
case INTEL_OUTPUT_DSI:
return POWER_DOMAIN_PORT_DSI;
default:
return POWER_DOMAIN_PORT_OTHER;
}
}
enum intel_display_power_domain
intel_display_port_aux_power_domain(struct intel_encoder *intel_encoder)
{
struct drm_device *dev = intel_encoder->base.dev;
struct intel_digital_port *intel_dig_port;
switch (intel_encoder->type) {
case INTEL_OUTPUT_UNKNOWN:
case INTEL_OUTPUT_HDMI:
/*
* Only DDI platforms should ever use these output types.
* We can get here after the HDMI detect code has already set
* the type of the shared encoder. Since we can't be sure
* what's the status of the given connectors, play safe and
* run the DP detection too.
*/
WARN_ON_ONCE(!HAS_DDI(dev));
case INTEL_OUTPUT_DISPLAYPORT:
case INTEL_OUTPUT_EDP:
intel_dig_port = enc_to_dig_port(&intel_encoder->base);
return port_to_aux_power_domain(intel_dig_port->port);
case INTEL_OUTPUT_DP_MST:
intel_dig_port = enc_to_mst(&intel_encoder->base)->primary;
return port_to_aux_power_domain(intel_dig_port->port);
default:
MISSING_CASE(intel_encoder->type);
return POWER_DOMAIN_AUX_A;
}
}
static unsigned long get_crtc_power_domains(struct drm_crtc *crtc,
struct intel_crtc_state *crtc_state)
{
struct drm_device *dev = crtc->dev;
struct drm_encoder *encoder;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
enum pipe pipe = intel_crtc->pipe;
unsigned long mask;
enum transcoder transcoder = crtc_state->cpu_transcoder;
if (!crtc_state->base.active)
return 0;
mask = BIT(POWER_DOMAIN_PIPE(pipe));
mask |= BIT(POWER_DOMAIN_TRANSCODER(transcoder));
if (crtc_state->pch_pfit.enabled ||
crtc_state->pch_pfit.force_thru)
mask |= BIT(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe));
drm_for_each_encoder_mask(encoder, dev, crtc_state->base.encoder_mask) {
struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
mask |= BIT(intel_display_port_power_domain(intel_encoder));
}
if (crtc_state->shared_dpll)
mask |= BIT(POWER_DOMAIN_PLLS);
return mask;
}
static unsigned long
modeset_get_crtc_power_domains(struct drm_crtc *crtc,
struct intel_crtc_state *crtc_state)
{
struct drm_i915_private *dev_priv = crtc->dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
enum intel_display_power_domain domain;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
unsigned long domains, new_domains, old_domains;
old_domains = intel_crtc->enabled_power_domains;
intel_crtc->enabled_power_domains = new_domains =
get_crtc_power_domains(crtc, crtc_state);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
domains = new_domains & ~old_domains;
for_each_power_domain(domain, domains)
intel_display_power_get(dev_priv, domain);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
return old_domains & ~new_domains;
}
static void modeset_put_power_domains(struct drm_i915_private *dev_priv,
unsigned long domains)
{
enum intel_display_power_domain domain;
for_each_power_domain(domain, domains)
intel_display_power_put(dev_priv, domain);
}
static int intel_compute_max_dotclk(struct drm_i915_private *dev_priv)
{
int max_cdclk_freq = dev_priv->max_cdclk_freq;
if (INTEL_INFO(dev_priv)->gen >= 9 ||
IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
return max_cdclk_freq;
else if (IS_CHERRYVIEW(dev_priv))
return max_cdclk_freq*95/100;
else if (INTEL_INFO(dev_priv)->gen < 4)
return 2*max_cdclk_freq*90/100;
else
return max_cdclk_freq*90/100;
}
static int skl_calc_cdclk(int max_pixclk, int vco);
static void intel_update_max_cdclk(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
u32 limit = I915_READ(SKL_DFSM) & SKL_DFSM_CDCLK_LIMIT_MASK;
int max_cdclk, vco;
vco = dev_priv->skl_preferred_vco_freq;
WARN_ON(vco != 8100000 && vco != 8640000);
/*
* Use the lower (vco 8640) cdclk values as a
* first guess. skl_calc_cdclk() will correct it
* if the preferred vco is 8100 instead.
*/
if (limit == SKL_DFSM_CDCLK_LIMIT_675)
max_cdclk = 617143;
else if (limit == SKL_DFSM_CDCLK_LIMIT_540)
max_cdclk = 540000;
else if (limit == SKL_DFSM_CDCLK_LIMIT_450)
max_cdclk = 432000;
else
max_cdclk = 308571;
dev_priv->max_cdclk_freq = skl_calc_cdclk(max_cdclk, vco);
} else if (IS_BROXTON(dev)) {
dev_priv->max_cdclk_freq = 624000;
} else if (IS_BROADWELL(dev)) {
/*
* FIXME with extra cooling we can allow
* 540 MHz for ULX and 675 Mhz for ULT.
* How can we know if extra cooling is
* available? PCI ID, VTB, something else?
*/
if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT)
dev_priv->max_cdclk_freq = 450000;
else if (IS_BDW_ULX(dev))
dev_priv->max_cdclk_freq = 450000;
else if (IS_BDW_ULT(dev))
dev_priv->max_cdclk_freq = 540000;
else
dev_priv->max_cdclk_freq = 675000;
} else if (IS_CHERRYVIEW(dev)) {
dev_priv->max_cdclk_freq = 320000;
} else if (IS_VALLEYVIEW(dev)) {
dev_priv->max_cdclk_freq = 400000;
} else {
/* otherwise assume cdclk is fixed */
dev_priv->max_cdclk_freq = dev_priv->cdclk_freq;
}
dev_priv->max_dotclk_freq = intel_compute_max_dotclk(dev_priv);
DRM_DEBUG_DRIVER("Max CD clock rate: %d kHz\n",
dev_priv->max_cdclk_freq);
DRM_DEBUG_DRIVER("Max dotclock rate: %d kHz\n",
dev_priv->max_dotclk_freq);
}
static void intel_update_cdclk(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
dev_priv->cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
if (INTEL_GEN(dev_priv) >= 9)
DRM_DEBUG_DRIVER("Current CD clock rate: %d kHz, VCO: %d kHz, ref: %d kHz\n",
dev_priv->cdclk_freq, dev_priv->cdclk_pll.vco,
dev_priv->cdclk_pll.ref);
else
DRM_DEBUG_DRIVER("Current CD clock rate: %d kHz\n",
dev_priv->cdclk_freq);
/*
* 9:0 CMBUS [sic] CDCLK frequency (cdfreq):
* Programmng [sic] note: bit[9:2] should be programmed to the number
* of cdclk that generates 4MHz reference clock freq which is used to
* generate GMBus clock. This will vary with the cdclk freq.
*/
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
I915_WRITE(GMBUSFREQ_VLV, DIV_ROUND_UP(dev_priv->cdclk_freq, 1000));
}
/* convert from kHz to .1 fixpoint MHz with -1MHz offset */
static int skl_cdclk_decimal(int cdclk)
{
return DIV_ROUND_CLOSEST(cdclk - 1000, 500);
}
static int bxt_de_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
{
int ratio;
if (cdclk == dev_priv->cdclk_pll.ref)
return 0;
switch (cdclk) {
default:
MISSING_CASE(cdclk);
case 144000:
case 288000:
case 384000:
case 576000:
ratio = 60;
break;
case 624000:
ratio = 65;
break;
}
return dev_priv->cdclk_pll.ref * ratio;
}
static void bxt_de_pll_disable(struct drm_i915_private *dev_priv)
{
I915_WRITE(BXT_DE_PLL_ENABLE, 0);
/* Timeout 200us */
if (intel_wait_for_register(dev_priv,
BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 0,
1))
DRM_ERROR("timeout waiting for DE PLL unlock\n");
dev_priv->cdclk_pll.vco = 0;
}
static void bxt_de_pll_enable(struct drm_i915_private *dev_priv, int vco)
{
int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->cdclk_pll.ref);
u32 val;
val = I915_READ(BXT_DE_PLL_CTL);
val &= ~BXT_DE_PLL_RATIO_MASK;
val |= BXT_DE_PLL_RATIO(ratio);
I915_WRITE(BXT_DE_PLL_CTL, val);
I915_WRITE(BXT_DE_PLL_ENABLE, BXT_DE_PLL_PLL_ENABLE);
/* Timeout 200us */
if (intel_wait_for_register(dev_priv,
BXT_DE_PLL_ENABLE,
BXT_DE_PLL_LOCK,
BXT_DE_PLL_LOCK,
1))
DRM_ERROR("timeout waiting for DE PLL lock\n");
dev_priv->cdclk_pll.vco = vco;
}
static void bxt_set_cdclk(struct drm_i915_private *dev_priv, int cdclk)
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
{
u32 val, divider;
int vco, ret;
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
vco = bxt_de_pll_vco(dev_priv, cdclk);
DRM_DEBUG_DRIVER("Changing CDCLK to %d kHz (VCO %d kHz)\n", cdclk, vco);
/* cdclk = vco / 2 / div{1,1.5,2,4} */
switch (DIV_ROUND_CLOSEST(vco, cdclk)) {
case 8:
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
divider = BXT_CDCLK_CD2X_DIV_SEL_4;
break;
case 4:
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
divider = BXT_CDCLK_CD2X_DIV_SEL_2;
break;
case 3:
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
divider = BXT_CDCLK_CD2X_DIV_SEL_1_5;
break;
case 2:
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
divider = BXT_CDCLK_CD2X_DIV_SEL_1;
break;
default:
WARN_ON(cdclk != dev_priv->cdclk_pll.ref);
WARN_ON(vco != 0);
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
divider = BXT_CDCLK_CD2X_DIV_SEL_1;
break;
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
}
/* Inform power controller of upcoming frequency change */
mutex_lock(&dev_priv->rps.hw_lock);
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
0x80000000);
mutex_unlock(&dev_priv->rps.hw_lock);
if (ret) {
DRM_ERROR("PCode CDCLK freq change notify failed (err %d, freq %d)\n",
ret, cdclk);
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
return;
}
if (dev_priv->cdclk_pll.vco != 0 &&
dev_priv->cdclk_pll.vco != vco)
bxt_de_pll_disable(dev_priv);
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
if (dev_priv->cdclk_pll.vco != vco)
bxt_de_pll_enable(dev_priv, vco);
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
val = divider | skl_cdclk_decimal(cdclk);
/*
* FIXME if only the cd2x divider needs changing, it could be done
* without shutting off the pipe (if only one pipe is active).
*/
val |= BXT_CDCLK_CD2X_PIPE_NONE;
/*
* Disable SSA Precharge when CD clock frequency < 500 MHz,
* enable otherwise.
*/
if (cdclk >= 500000)
val |= BXT_CDCLK_SSA_PRECHARGE_ENABLE;
I915_WRITE(CDCLK_CTL, val);
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
mutex_lock(&dev_priv->rps.hw_lock);
ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
DIV_ROUND_UP(cdclk, 25000));
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
mutex_unlock(&dev_priv->rps.hw_lock);
if (ret) {
DRM_ERROR("PCode CDCLK freq set failed, (err %d, freq %d)\n",
ret, cdclk);
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
return;
}
intel_update_cdclk(dev_priv->dev);
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
}
static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv)
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
{
u32 cdctl, expected;
intel_update_cdclk(dev_priv->dev);
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
if (dev_priv->cdclk_pll.vco == 0 ||
dev_priv->cdclk_freq == dev_priv->cdclk_pll.ref)
goto sanitize;
/* DPLL okay; verify the cdclock
*
* Some BIOS versions leave an incorrect decimal frequency value and
* set reserved MBZ bits in CDCLK_CTL at least during exiting from S4,
* so sanitize this register.
*/
cdctl = I915_READ(CDCLK_CTL);
/*
* Let's ignore the pipe field, since BIOS could have configured the
* dividers both synching to an active pipe, or asynchronously
* (PIPE_NONE).
*/
cdctl &= ~BXT_CDCLK_CD2X_PIPE_NONE;
expected = (cdctl & BXT_CDCLK_CD2X_DIV_SEL_MASK) |
skl_cdclk_decimal(dev_priv->cdclk_freq);
/*
* Disable SSA Precharge when CD clock frequency < 500 MHz,
* enable otherwise.
*/
if (dev_priv->cdclk_freq >= 500000)
expected |= BXT_CDCLK_SSA_PRECHARGE_ENABLE;
if (cdctl == expected)
/* All well; nothing to sanitize */
return;
sanitize:
DRM_DEBUG_KMS("Sanitizing cdclk programmed by pre-os\n");
/* force cdclk programming */
dev_priv->cdclk_freq = 0;
/* force full PLL disable + enable */
dev_priv->cdclk_pll.vco = -1;
}
void bxt_init_cdclk(struct drm_i915_private *dev_priv)
{
bxt_sanitize_cdclk(dev_priv);
if (dev_priv->cdclk_freq != 0 && dev_priv->cdclk_pll.vco != 0)
return;
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
/*
* FIXME:
* - The initial CDCLK needs to be read from VBT.
* Need to make this change after VBT has changes for BXT.
*/
bxt_set_cdclk(dev_priv, bxt_calc_cdclk(0));
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
}
void bxt_uninit_cdclk(struct drm_i915_private *dev_priv)
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
{
bxt_set_cdclk(dev_priv, dev_priv->cdclk_pll.ref);
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
}
static int skl_calc_cdclk(int max_pixclk, int vco)
{
if (vco == 8640000) {
if (max_pixclk > 540000)
return 617143;
else if (max_pixclk > 432000)
return 540000;
else if (max_pixclk > 308571)
return 432000;
else
return 308571;
} else {
if (max_pixclk > 540000)
return 675000;
else if (max_pixclk > 450000)
return 540000;
else if (max_pixclk > 337500)
return 450000;
else
return 337500;
}
}
static void
skl_dpll0_update(struct drm_i915_private *dev_priv)
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
{
u32 val;
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
dev_priv->cdclk_pll.ref = 24000;
dev_priv->cdclk_pll.vco = 0;
val = I915_READ(LCPLL1_CTL);
if ((val & LCPLL_PLL_ENABLE) == 0)
return;
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
if (WARN_ON((val & LCPLL_PLL_LOCK) == 0))
return;
val = I915_READ(DPLL_CTRL1);
if (WARN_ON((val & (DPLL_CTRL1_HDMI_MODE(SKL_DPLL0) |
DPLL_CTRL1_SSC(SKL_DPLL0) |
DPLL_CTRL1_OVERRIDE(SKL_DPLL0))) !=
DPLL_CTRL1_OVERRIDE(SKL_DPLL0)))
return;
switch (val & DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0)) {
case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, SKL_DPLL0):
case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, SKL_DPLL0):
case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, SKL_DPLL0):
case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, SKL_DPLL0):
dev_priv->cdclk_pll.vco = 8100000;
break;
case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080, SKL_DPLL0):
case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2160, SKL_DPLL0):
dev_priv->cdclk_pll.vco = 8640000;
break;
default:
MISSING_CASE(val & DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0));
break;
}
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
}
void skl_set_preferred_cdclk_vco(struct drm_i915_private *dev_priv, int vco)
{
bool changed = dev_priv->skl_preferred_vco_freq != vco;
dev_priv->skl_preferred_vco_freq = vco;
if (changed)
intel_update_max_cdclk(dev_priv->dev);
}
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
static void
skl_dpll0_enable(struct drm_i915_private *dev_priv, int vco)
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
{
int min_cdclk = skl_calc_cdclk(0, vco);
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
u32 val;
WARN_ON(vco != 8100000 && vco != 8640000);
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
/* select the minimum CDCLK before enabling DPLL 0 */
val = CDCLK_FREQ_337_308 | skl_cdclk_decimal(min_cdclk);
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
I915_WRITE(CDCLK_CTL, val);
POSTING_READ(CDCLK_CTL);
/*
* We always enable DPLL0 with the lowest link rate possible, but still
* taking into account the VCO required to operate the eDP panel at the
* desired frequency. The usual DP link rates operate with a VCO of
* 8100 while the eDP 1.4 alternate link rates need a VCO of 8640.
* The modeset code is responsible for the selection of the exact link
* rate later on, with the constraint of choosing a frequency that
* works with vco.
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
*/
val = I915_READ(DPLL_CTRL1);
val &= ~(DPLL_CTRL1_HDMI_MODE(SKL_DPLL0) | DPLL_CTRL1_SSC(SKL_DPLL0) |
DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0));
val |= DPLL_CTRL1_OVERRIDE(SKL_DPLL0);
if (vco == 8640000)
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
val |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080,
SKL_DPLL0);
else
val |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810,
SKL_DPLL0);
I915_WRITE(DPLL_CTRL1, val);
POSTING_READ(DPLL_CTRL1);
I915_WRITE(LCPLL1_CTL, I915_READ(LCPLL1_CTL) | LCPLL_PLL_ENABLE);
if (intel_wait_for_register(dev_priv,
LCPLL1_CTL, LCPLL_PLL_LOCK, LCPLL_PLL_LOCK,
5))
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
DRM_ERROR("DPLL0 not locked\n");
dev_priv->cdclk_pll.vco = vco;
/* We'll want to keep using the current vco from now on. */
skl_set_preferred_cdclk_vco(dev_priv, vco);
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
}
static void
skl_dpll0_disable(struct drm_i915_private *dev_priv)
{
I915_WRITE(LCPLL1_CTL, I915_READ(LCPLL1_CTL) & ~LCPLL_PLL_ENABLE);
if (intel_wait_for_register(dev_priv,
LCPLL1_CTL, LCPLL_PLL_LOCK, 0,
1))
DRM_ERROR("Couldn't disable DPLL0\n");
dev_priv->cdclk_pll.vco = 0;
}
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
static bool skl_cdclk_pcu_ready(struct drm_i915_private *dev_priv)
{
int ret;
u32 val;
/* inform PCU we want to change CDCLK */
val = SKL_CDCLK_PREPARE_FOR_CHANGE;
mutex_lock(&dev_priv->rps.hw_lock);
ret = sandybridge_pcode_read(dev_priv, SKL_PCODE_CDCLK_CONTROL, &val);
mutex_unlock(&dev_priv->rps.hw_lock);
return ret == 0 && (val & SKL_CDCLK_READY_FOR_CHANGE);
}
static bool skl_cdclk_wait_for_pcu_ready(struct drm_i915_private *dev_priv)
{
unsigned int i;
for (i = 0; i < 15; i++) {
if (skl_cdclk_pcu_ready(dev_priv))
return true;
udelay(10);
}
return false;
}
static void skl_set_cdclk(struct drm_i915_private *dev_priv, int cdclk, int vco)
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
{
struct drm_device *dev = dev_priv->dev;
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
u32 freq_select, pcu_ack;
WARN_ON((cdclk == 24000) != (vco == 0));
DRM_DEBUG_DRIVER("Changing CDCLK to %d kHz (VCO %d kHz)\n", cdclk, vco);
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
if (!skl_cdclk_wait_for_pcu_ready(dev_priv)) {
DRM_ERROR("failed to inform PCU about cdclk change\n");
return;
}
/* set CDCLK_CTL */
switch (cdclk) {
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
case 450000:
case 432000:
freq_select = CDCLK_FREQ_450_432;
pcu_ack = 1;
break;
case 540000:
freq_select = CDCLK_FREQ_540;
pcu_ack = 2;
break;
case 308571:
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
case 337500:
default:
freq_select = CDCLK_FREQ_337_308;
pcu_ack = 0;
break;
case 617143:
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
case 675000:
freq_select = CDCLK_FREQ_675_617;
pcu_ack = 3;
break;
}
if (dev_priv->cdclk_pll.vco != 0 &&
dev_priv->cdclk_pll.vco != vco)
skl_dpll0_disable(dev_priv);
if (dev_priv->cdclk_pll.vco != vco)
skl_dpll0_enable(dev_priv, vco);
I915_WRITE(CDCLK_CTL, freq_select | skl_cdclk_decimal(cdclk));
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
POSTING_READ(CDCLK_CTL);
/* inform PCU of the change */
mutex_lock(&dev_priv->rps.hw_lock);
sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, pcu_ack);
mutex_unlock(&dev_priv->rps.hw_lock);
intel_update_cdclk(dev);
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
}
static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv);
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
void skl_uninit_cdclk(struct drm_i915_private *dev_priv)
{
skl_set_cdclk(dev_priv, dev_priv->cdclk_pll.ref, 0);
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
}
void skl_init_cdclk(struct drm_i915_private *dev_priv)
{
int cdclk, vco;
skl_sanitize_cdclk(dev_priv);
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
if (dev_priv->cdclk_freq != 0 && dev_priv->cdclk_pll.vco != 0) {
/*
* Use the current vco as our initial
* guess as to what the preferred vco is.
*/
if (dev_priv->skl_preferred_vco_freq == 0)
skl_set_preferred_cdclk_vco(dev_priv,
dev_priv->cdclk_pll.vco);
return;
}
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
vco = dev_priv->skl_preferred_vco_freq;
if (vco == 0)
vco = 8100000;
cdclk = skl_calc_cdclk(0, vco);
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
skl_set_cdclk(dev_priv, cdclk, vco);
drm/i915/skl: Deinit/init the display at suspend/resume We need to re-init the display hardware when going out of suspend. This includes: - Hooking the PCH to the reset logic - Restoring CDCDLK - Enabling the DDB power Among those, only the CDCDLK one is a bit tricky. There's some complexity in that: - DPLL0 (which is the source for CDCLK) has two VCOs, each with a set of supported frequencies. As eDP also uses DPLL0 for its link rate, once DPLL0 is on, we restrict the possible eDP link rates the chosen VCO. - CDCLK also limits the bandwidth available to push pixels. So, as a first step, this commit restore what the BIOS set, until I can do more testing. In case that's of interest for the reviewer, I've unit tested the function that derives the decimal frequency field: #include <stdio.h> #include <stdint.h> #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) static const struct dpll_freq { unsigned int freq; unsigned int decimal; } freqs[] = { { .freq = 308570, .decimal = 0b01001100111}, { .freq = 337500, .decimal = 0b01010100001}, { .freq = 432000, .decimal = 0b01101011110}, { .freq = 450000, .decimal = 0b01110000010}, { .freq = 540000, .decimal = 0b10000110110}, { .freq = 617140, .decimal = 0b10011010000}, { .freq = 675000, .decimal = 0b10101000100}, }; static void intbits(unsigned int v) { int i; for(i = 10; i >= 0; i--) putchar('0' + ((v >> i) & 1)); } static unsigned int freq_decimal(unsigned int freq /* in kHz */) { return (freq - 1000) / 500; } static void test_freq(const struct dpll_freq *entry) { unsigned int decimal = freq_decimal(entry->freq); printf("freq: %d, expected: ", entry->freq); intbits(entry->decimal); printf(", got: "); intbits(decimal); putchar('\n'); assert(decimal == entry->decimal); } int main(int argc, char **argv) { int i; for (i = 0; i < ARRAY_SIZE(freqs); i++) test_freq(&freqs[i]); return 0; } v2: - Rebase on top of -nightly - Use (freq - 1000) / 500 for the decimal frequency (Ville) - Fix setting the enable bit of HSW_NDE_RSTWRN_OPT (Ville) - Rename skl_display_{resume,suspend} to skl_{init,uninit}_cdclk to be consistent with the BXT code (Ville) - Store boot CDCLK in ddi_pll_init (Ville) - Merge dev_priv's skl_boot_cdclk into cdclk_freq - Use LCPLL_PLL_LOCK instead of (1 << 30) (Ville) - Replace various '0' by SKL_DPLL0 to be a bit more explicit that we're programming DPLL0 - Busy poll the PCU before doing the frequency change. It takes about 3/4 cycles, each separated by 10us, to get the ACK from the CPU (Ville) v3: - Restore dev_priv->skl_boot_cdclk, leaving unification with dev_priv->cdclk_freq for a later patch (Daniel, Ville) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-05-21 16:37:48 +01:00
}
static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv)
{
uint32_t cdctl, expected;
/*
* check if the pre-os intialized the display
* There is SWF18 scratchpad register defined which is set by the
* pre-os which can be used by the OS drivers to check the status
*/
if ((I915_READ(SWF_ILK(0x18)) & 0x00FFFFFF) == 0)
goto sanitize;
intel_update_cdclk(dev_priv->dev);
/* Is PLL enabled and locked ? */
if (dev_priv->cdclk_pll.vco == 0 ||
dev_priv->cdclk_freq == dev_priv->cdclk_pll.ref)
goto sanitize;
/* DPLL okay; verify the cdclock
*
* Noticed in some instances that the freq selection is correct but
* decimal part is programmed wrong from BIOS where pre-os does not
* enable display. Verify the same as well.
*/
cdctl = I915_READ(CDCLK_CTL);
expected = (cdctl & CDCLK_FREQ_SEL_MASK) |
skl_cdclk_decimal(dev_priv->cdclk_freq);
if (cdctl == expected)
/* All well; nothing to sanitize */
return;
drm/i915/skl: SKL CDCLK change on modeset tracking VCO WARNING: Using ChromeOS with an eDP panel and a 4K@60 DP monitor connected to DDI1 the system will hard hang during a cold boot. Occurs when DDI1 is enabled when the cdclk is less then required. DP connected to DDI2 and HPD on either port works correctly. Set cdclk based on the max required pixel clock based on VCO selected. Track boot vco instead of boot cdclk. The vco is now tracked at the atomic level and all CRTCs updated if the required vco is changed. Not tested with eDP v1.4 panels that require 8640 vco due to availability. V1: initial version V2: add vco tracking in intel_dp_compute_config(), rename skl_boot_cdclk. V3: rebase, V2 feedback not possible as encoders are not aware of atomic. V4: track target vco is atomic state. modeset all CRTCs if vco changes V5: rename atomic variable, cleaner if/else logic, use existing vco if encoder does not return a new vco value. check_patch.pl cleanup V6: simplify logic in intel_modeset_checks. V7: reorder an IF for readability and whitespace fix. V8: use dev_cdclk for tracking new cdclk during atomic V9: correctly handle vco 8640 when crtcs==0 V10: Clean up if else in crtcs==0 V11: Rebase for new intel_dpll_mgr.c Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Clint Taylor <clinton.a.taylor@intel.com> [vsyrjala: rebased due to churn] Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1463172100-24715-3-git-send-email-ville.syrjala@linux.intel.com
2016-05-13 23:41:21 +03:00
sanitize:
DRM_DEBUG_KMS("Sanitizing cdclk programmed by pre-os\n");
/* force cdclk programming */
dev_priv->cdclk_freq = 0;
/* force full PLL disable + enable */
dev_priv->cdclk_pll.vco = -1;
}
/* Adjust CDclk dividers to allow high res or save power if possible */
static void valleyview_set_cdclk(struct drm_device *dev, int cdclk)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 val, cmd;
WARN_ON(dev_priv->display.get_display_clock_speed(dev)
!= dev_priv->cdclk_freq);
if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */
cmd = 2;
else if (cdclk == 266667)
cmd = 1;
else
cmd = 0;
mutex_lock(&dev_priv->rps.hw_lock);
val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
val &= ~DSPFREQGUAR_MASK;
val |= (cmd << DSPFREQGUAR_SHIFT);
vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, val);
if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) &
DSPFREQSTAT_MASK) == (cmd << DSPFREQSTAT_SHIFT),
50)) {
DRM_ERROR("timed out waiting for CDclk change\n");
}
mutex_unlock(&dev_priv->rps.hw_lock);
mutex_lock(&dev_priv->sb_lock);
if (cdclk == 400000) {
u32 divider;
divider = DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, cdclk) - 1;
/* adjust cdclk divider */
val = vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL);
val &= ~CCK_FREQUENCY_VALUES;
val |= divider;
vlv_cck_write(dev_priv, CCK_DISPLAY_CLOCK_CONTROL, val);
if (wait_for((vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL) &
CCK_FREQUENCY_STATUS) == (divider << CCK_FREQUENCY_STATUS_SHIFT),
50))
DRM_ERROR("timed out waiting for CDclk change\n");
}
/* adjust self-refresh exit latency value */
val = vlv_bunit_read(dev_priv, BUNIT_REG_BISOC);
val &= ~0x7f;
/*
* For high bandwidth configs, we set a higher latency in the bunit
* so that the core display fetch happens in time to avoid underruns.
*/
if (cdclk == 400000)
val |= 4500 / 250; /* 4.5 usec */
else
val |= 3000 / 250; /* 3.0 usec */
vlv_bunit_write(dev_priv, BUNIT_REG_BISOC, val);
mutex_unlock(&dev_priv->sb_lock);
intel_update_cdclk(dev);
}
static void cherryview_set_cdclk(struct drm_device *dev, int cdclk)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 val, cmd;
WARN_ON(dev_priv->display.get_display_clock_speed(dev)
!= dev_priv->cdclk_freq);
switch (cdclk) {
case 333333:
case 320000:
case 266667:
case 200000:
break;
default:
drm/i915: Use BUILD_BUG if possible in the i915 WARN_ON Faster feedback to errors is always better. This is inspired by the addition to WARN_ONs to mask/enable helpers for registers to make sure callers have the arguments ordered correctly: Pretty much always the arguments are static. We use WARN_ON(1) a lot in default switch statements though where we should always handle all cases. So add a new macro specifically for that. The idea to use __builtin_constant_p is from Chris Wilson. v2: Use the ({}) gcc-ism to avoid the static inline, suggested by Dave. My first attempt used __cond as the temp var, which is the same used by BUILD_BUG_ON, but with inverted sense. Hilarity ensued, so sprinkle i915 into the name. Also use a temporary variable to only evaluate the condition once, suggested by Damien. v3: It's crazy but apparently 32bit gcc can't compile out the BUILD_BUG_ON in a lot of cases and just falls over. I have no idea why, but until clue grows just disable this nifty idea on 32bit builds. Reported by 0-day builder. v4: Got it all wrong, apparently its the gcc version. We need 4.9+. Now reported by Imre. v5: Chris suggested to add the case to MISSING_CASE for speedier debug. v6: Even some gcc 4.9 versions don't see through the maze, so give up for now. Keep the skeleton and MISSING_CASE stuff though. Cc: Imre Deak <imre.deak@intel.com> Cc: Damien Lespiau <damien.lespiau@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: Jani Nikula <jani.nikula@linux.intel.com> Cc: Dave Gordon <david.s.gordon@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2014-12-08 16:40:10 +01:00
MISSING_CASE(cdclk);
return;
}
/*
* Specs are full of misinformation, but testing on actual
* hardware has shown that we just need to write the desired
* CCK divider into the Punit register.
*/
cmd = DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, cdclk) - 1;
mutex_lock(&dev_priv->rps.hw_lock);
val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
val &= ~DSPFREQGUAR_MASK_CHV;
val |= (cmd << DSPFREQGUAR_SHIFT_CHV);
vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, val);
if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) &
DSPFREQSTAT_MASK_CHV) == (cmd << DSPFREQSTAT_SHIFT_CHV),
50)) {
DRM_ERROR("timed out waiting for CDclk change\n");
}
mutex_unlock(&dev_priv->rps.hw_lock);
intel_update_cdclk(dev);
}
static int valleyview_calc_cdclk(struct drm_i915_private *dev_priv,
int max_pixclk)
{
int freq_320 = (dev_priv->hpll_freq << 1) % 320000 != 0 ? 333333 : 320000;
int limit = IS_CHERRYVIEW(dev_priv) ? 95 : 90;
/*
* Really only a few cases to deal with, as only 4 CDclks are supported:
* 200MHz
* 267MHz
* 320/333MHz (depends on HPLL freq)
* 400MHz (VLV only)
* So we check to see whether we're above 90% (VLV) or 95% (CHV)
* of the lower bin and adjust if needed.
*
* We seem to get an unstable or solid color picture at 200MHz.
* Not sure what's wrong. For now use 200MHz only when all pipes
* are off.
*/
if (!IS_CHERRYVIEW(dev_priv) &&
max_pixclk > freq_320*limit/100)
return 400000;
else if (max_pixclk > 266667*limit/100)
return freq_320;
else if (max_pixclk > 0)
return 266667;
else
return 200000;
}
static int bxt_calc_cdclk(int max_pixclk)
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
{
if (max_pixclk > 576000)
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
return 624000;
else if (max_pixclk > 384000)
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
return 576000;
else if (max_pixclk > 288000)
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
return 384000;
else if (max_pixclk > 144000)
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
return 288000;
else
return 144000;
}
/* Compute the max pixel clock for new configuration. */
static int intel_mode_max_pixclk(struct drm_device *dev,
struct drm_atomic_state *state)
{
struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state;
unsigned max_pixclk = 0, i;
enum pipe pipe;
memcpy(intel_state->min_pixclk, dev_priv->min_pixclk,
sizeof(intel_state->min_pixclk));
for_each_crtc_in_state(state, crtc, crtc_state, i) {
int pixclk = 0;
if (crtc_state->enable)
pixclk = crtc_state->adjusted_mode.crtc_clock;
intel_state->min_pixclk[i] = pixclk;
}
for_each_pipe(dev_priv, pipe)
max_pixclk = max(intel_state->min_pixclk[pipe], max_pixclk);
return max_pixclk;
}
static int valleyview_modeset_calc_cdclk(struct drm_atomic_state *state)
{
struct drm_device *dev = state->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
int max_pixclk = intel_mode_max_pixclk(dev, state);
struct intel_atomic_state *intel_state =
to_intel_atomic_state(state);
intel_state->cdclk = intel_state->dev_cdclk =
valleyview_calc_cdclk(dev_priv, max_pixclk);
if (!intel_state->active_crtcs)
intel_state->dev_cdclk = valleyview_calc_cdclk(dev_priv, 0);
return 0;
}
static int bxt_modeset_calc_cdclk(struct drm_atomic_state *state)
{
int max_pixclk = ilk_max_pixel_rate(state);
struct intel_atomic_state *intel_state =
to_intel_atomic_state(state);
intel_state->cdclk = intel_state->dev_cdclk =
bxt_calc_cdclk(max_pixclk);
if (!intel_state->active_crtcs)
intel_state->dev_cdclk = bxt_calc_cdclk(0);
return 0;
}
static void vlv_program_pfi_credits(struct drm_i915_private *dev_priv)
{
unsigned int credits, default_credits;
if (IS_CHERRYVIEW(dev_priv))
default_credits = PFI_CREDIT(12);
else
default_credits = PFI_CREDIT(8);
if (dev_priv->cdclk_freq >= dev_priv->czclk_freq) {
/* CHV suggested value is 31 or 63 */
if (IS_CHERRYVIEW(dev_priv))
credits = PFI_CREDIT_63;
else
credits = PFI_CREDIT(15);
} else {
credits = default_credits;
}
/*
* WA - write default credits before re-programming
* FIXME: should we also set the resend bit here?
*/
I915_WRITE(GCI_CONTROL, VGA_FAST_MODE_DISABLE |
default_credits);
I915_WRITE(GCI_CONTROL, VGA_FAST_MODE_DISABLE |
credits | PFI_CREDIT_RESEND);
/*
* FIXME is this guaranteed to clear
* immediately or should we poll for it?
*/
WARN_ON(I915_READ(GCI_CONTROL) & PFI_CREDIT_RESEND);
}
static void valleyview_modeset_commit_cdclk(struct drm_atomic_state *old_state)
{
struct drm_device *dev = old_state->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_atomic_state *old_intel_state =
to_intel_atomic_state(old_state);
unsigned req_cdclk = old_intel_state->dev_cdclk;
/*
* FIXME: We can end up here with all power domains off, yet
* with a CDCLK frequency other than the minimum. To account
* for this take the PIPE-A power domain, which covers the HW
* blocks needed for the following programming. This can be
* removed once it's guaranteed that we get here either with
* the minimum CDCLK set, or the required power domains
* enabled.
*/
intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A);
if (IS_CHERRYVIEW(dev))
cherryview_set_cdclk(dev, req_cdclk);
else
valleyview_set_cdclk(dev, req_cdclk);
vlv_program_pfi_credits(dev_priv);
intel_display_power_put(dev_priv, POWER_DOMAIN_PIPE_A);
}
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
static void valleyview_crtc_enable(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = to_i915(dev);
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_encoder *encoder;
struct intel_crtc_state *pipe_config =
to_intel_crtc_state(crtc->state);
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
int pipe = intel_crtc->pipe;
if (WARN_ON(intel_crtc->active))
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
return;
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (intel_crtc->config->has_dp_encoder)
intel_dp_set_m_n(intel_crtc, M1_N1);
intel_set_pipe_timings(intel_crtc);
intel_set_pipe_src_size(intel_crtc);
if (IS_CHERRYVIEW(dev) && pipe == PIPE_B) {
struct drm_i915_private *dev_priv = dev->dev_private;
I915_WRITE(CHV_BLEND(pipe), CHV_BLEND_LEGACY);
I915_WRITE(CHV_CANVAS(pipe), 0);
}
i9xx_set_pipeconf(intel_crtc);
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
intel_crtc->active = true;
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
for_each_encoder_on_crtc(dev, crtc, encoder)
if (encoder->pre_pll_enable)
encoder->pre_pll_enable(encoder);
if (IS_CHERRYVIEW(dev)) {
chv_prepare_pll(intel_crtc, intel_crtc->config);
chv_enable_pll(intel_crtc, intel_crtc->config);
} else {
vlv_prepare_pll(intel_crtc, intel_crtc->config);
vlv_enable_pll(intel_crtc, intel_crtc->config);
}
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
for_each_encoder_on_crtc(dev, crtc, encoder)
if (encoder->pre_enable)
encoder->pre_enable(encoder);
i9xx_pfit_enable(intel_crtc);
intel_color_load_luts(&pipe_config->base);
intel_update_watermarks(crtc);
intel_enable_pipe(intel_crtc);
assert_vblank_disabled(crtc);
drm_crtc_vblank_on(crtc);
drm/i915: Push vblank enable/disable past encoder->enable/disable It is platform/output depenedent when exactly the pipe will start running. Sometimes we just need the (cpu) pipe enabled, in other cases the pch transcoder is enough and in yet other cases the (DP) port is sending the frame start signal. In a perfect world we'd put the drm_crtc_vblank_on call exactly where the pipe starts running, but due to cloning and similar things this will get messy. And the current approach of picking the most conservative place for all combinations also doesn't work since that results in legit vblank waits (in encoder->enable hooks, e.g. the 2 vblank waits for sdvo) failing. Completely going back to the old world before commit 51e31d49c89055299e34b8f44d13f70e19aaaad1 Author: Daniel Vetter <daniel.vetter@ffwll.ch> Date: Mon Sep 15 12:36:02 2014 +0200 drm/i915: Use generic vblank wait isn't great either since screaming when the vblank wait work because the pipe is off is kinda nice. Pick a compromise and move the drm_crtc_vblank_on right before the encoder->enable call. This is a lie on some outputs/platforms, but after the ->enable callback the pipe is guaranteed to run everywhere. So not that bad really. Suggested by Ville. v2: Same treatment for drm_crtc_vblank_off and encoder->disable: I've missed the ibx pipe B select w/a, which also has a vblank wait in the disable function (while the pipe is obviously still running). Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2015-01-07 13:54:39 +01:00
for_each_encoder_on_crtc(dev, crtc, encoder)
encoder->enable(encoder);
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
}
static void i9xx_set_pll_dividers(struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
I915_WRITE(FP0(crtc->pipe), crtc->config->dpll_hw_state.fp0);
I915_WRITE(FP1(crtc->pipe), crtc->config->dpll_hw_state.fp1);
}
static void i9xx_crtc_enable(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = to_i915(dev);
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_encoder *encoder;
struct intel_crtc_state *pipe_config =
to_intel_crtc_state(crtc->state);
enum pipe pipe = intel_crtc->pipe;
if (WARN_ON(intel_crtc->active))
return;
i9xx_set_pll_dividers(intel_crtc);
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (intel_crtc->config->has_dp_encoder)
intel_dp_set_m_n(intel_crtc, M1_N1);
intel_set_pipe_timings(intel_crtc);
intel_set_pipe_src_size(intel_crtc);
i9xx_set_pipeconf(intel_crtc);
intel_crtc->active = true;
if (!IS_GEN2(dev))
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
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_color_load_luts(&pipe_config->base);
intel_update_watermarks(crtc);
intel_enable_pipe(intel_crtc);
assert_vblank_disabled(crtc);
drm_crtc_vblank_on(crtc);
drm/i915: Push vblank enable/disable past encoder->enable/disable It is platform/output depenedent when exactly the pipe will start running. Sometimes we just need the (cpu) pipe enabled, in other cases the pch transcoder is enough and in yet other cases the (DP) port is sending the frame start signal. In a perfect world we'd put the drm_crtc_vblank_on call exactly where the pipe starts running, but due to cloning and similar things this will get messy. And the current approach of picking the most conservative place for all combinations also doesn't work since that results in legit vblank waits (in encoder->enable hooks, e.g. the 2 vblank waits for sdvo) failing. Completely going back to the old world before commit 51e31d49c89055299e34b8f44d13f70e19aaaad1 Author: Daniel Vetter <daniel.vetter@ffwll.ch> Date: Mon Sep 15 12:36:02 2014 +0200 drm/i915: Use generic vblank wait isn't great either since screaming when the vblank wait work because the pipe is off is kinda nice. Pick a compromise and move the drm_crtc_vblank_on right before the encoder->enable call. This is a lie on some outputs/platforms, but after the ->enable callback the pipe is guaranteed to run everywhere. So not that bad really. Suggested by Ville. v2: Same treatment for drm_crtc_vblank_off and encoder->disable: I've missed the ibx pipe B select w/a, which also has a vblank wait in the disable function (while the pipe is obviously still running). Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2015-01-07 13:54:39 +01:00
for_each_encoder_on_crtc(dev, crtc, encoder)
encoder->enable(encoder);
}
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;
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (!crtc->config->gmch_pfit.control)
return;
assert_pipe_disabled(dev_priv, crtc->pipe);
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)
{
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;
/*
* On gen2 planes are double buffered but the pipe isn't, so we must
* wait for planes to fully turn off before disabling the pipe.
*/
if (IS_GEN2(dev))
intel_wait_for_vblank(dev, pipe);
for_each_encoder_on_crtc(dev, crtc, encoder)
encoder->disable(encoder);
drm/i915: Push vblank enable/disable past encoder->enable/disable It is platform/output depenedent when exactly the pipe will start running. Sometimes we just need the (cpu) pipe enabled, in other cases the pch transcoder is enough and in yet other cases the (DP) port is sending the frame start signal. In a perfect world we'd put the drm_crtc_vblank_on call exactly where the pipe starts running, but due to cloning and similar things this will get messy. And the current approach of picking the most conservative place for all combinations also doesn't work since that results in legit vblank waits (in encoder->enable hooks, e.g. the 2 vblank waits for sdvo) failing. Completely going back to the old world before commit 51e31d49c89055299e34b8f44d13f70e19aaaad1 Author: Daniel Vetter <daniel.vetter@ffwll.ch> Date: Mon Sep 15 12:36:02 2014 +0200 drm/i915: Use generic vblank wait isn't great either since screaming when the vblank wait work because the pipe is off is kinda nice. Pick a compromise and move the drm_crtc_vblank_on right before the encoder->enable call. This is a lie on some outputs/platforms, but after the ->enable callback the pipe is guaranteed to run everywhere. So not that bad really. Suggested by Ville. v2: Same treatment for drm_crtc_vblank_off and encoder->disable: I've missed the ibx pipe B select w/a, which also has a vblank wait in the disable function (while the pipe is obviously still running). Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2015-01-07 13:54:39 +01:00
drm_crtc_vblank_off(crtc);
assert_vblank_disabled(crtc);
intel_disable_pipe(intel_crtc);
i9xx_pfit_disable(intel_crtc);
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
for_each_encoder_on_crtc(dev, crtc, encoder)
if (encoder->post_disable)
encoder->post_disable(encoder);
if (!intel_crtc->config->has_dsi_encoder) {
if (IS_CHERRYVIEW(dev))
chv_disable_pll(dev_priv, pipe);
else if (IS_VALLEYVIEW(dev))
vlv_disable_pll(dev_priv, pipe);
else
i9xx_disable_pll(intel_crtc);
}
for_each_encoder_on_crtc(dev, crtc, encoder)
if (encoder->post_pll_disable)
encoder->post_pll_disable(encoder);
if (!IS_GEN2(dev))
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
}
static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
{
drm/i915: Update state before setting watermarks, v2. When intel_update_watermarks is called on skylake from the hw state readout disable function it calls intel_update_watermarks. intel_update_watermarks inspects crtc->state, which should be set to disabled. This wasn't the case, and this resulted in a divide-by-zero in skl_update_wm when intel_update_watermarks got called. ------------[ cut here ]------------ WARNING: CPU: 1 PID: 295 at drivers/gpu/drm/i915/intel_pm.c:2834 skl_update_pipe_wm+0x102/0x8c0 [i915]() WARN_ON(!config->num_pipes_active) Modules linked in: coretemp i915(+) xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx CPU: 1 PID: 295 Comm: systemd-udevd Tainted: G U W 4.5.0-rc4 -xxxxxx #25 Hardware name: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 0000000000000000 ffff88003777f5a8 ffffffff813485c2 ffff88003777f5f0 ffffffffa0236240 ffff88003777f5e0 ffffffff81050fce ffff8800aa420000 ffff8800aba18000 ffff8800aba18000 ffff880037304c00 ffff8800aa420000 Call Trace: [<ffffffff813485c2>] dump_stack+0x67/0x95 [<ffffffff81050fce>] warn_slowpath_common+0x9e/0xc0 [<ffffffff8105103c>] warn_slowpath_fmt+0x4c/0x50 [<ffffffff8106945e>] ? flush_work+0x8e/0x280 [<ffffffff810693d5>] ? flush_work+0x5/0x280 [<ffffffffa016add2>] skl_update_pipe_wm+0x102/0x8c0 [i915] [<ffffffffa016b96f>] skl_update_wm+0xff/0x5f0 [i915] [<ffffffff810928ee>] ? trace_hardirqs_on_caller+0x15e/0x1d0 [<ffffffff8109296d>] ? trace_hardirqs_on+0xd/0x10 [<ffffffffa016ce6e>] intel_update_watermarks+0x1e/0x30 [i915] [<ffffffffa01d3ee2>] intel_crtc_disable_noatomic+0xd2/0x150 [i915] [<ffffffffa01dd3d2>] intel_modeset_setup_hw_state+0xdd2/0xde0 [i915] [<ffffffffa01dfd83>] intel_modeset_init+0x15a3/0x1950 [i915] [<ffffffffa02160b6>] i915_driver_load+0x13c6/0x1720 [i915] [<ffffffff81522160>] ? add_sysfs_fw_map_entry+0x9b/0x9b [<ffffffffa00b15ef>] drm_dev_register+0x6f/0xb0 [drm] [<ffffffffa00b3b3a>] drm_get_pci_dev+0x10a/0x1d0 [drm] [<ffffffffa01582d9>] i915_pci_probe+0x49/0x50 [i915] [<ffffffff8138ae30>] pci_device_probe+0x80/0xf0 [<ffffffff8143e2ac>] driver_probe_device+0x1bc/0x3d0 [<ffffffff8143e526>] __driver_attach+0x66/0x90 [<ffffffff8143e4c0>] ? driver_probe_device+0x3d0/0x3d0 [<ffffffff8143be3b>] bus_for_each_dev+0x5b/0xa0 [<ffffffff8143db3e>] driver_attach+0x1e/0x20 [<ffffffff8143d461>] bus_add_driver+0x151/0x270 [<ffffffff8143eabc>] driver_register+0x8c/0xd0 [<ffffffff8138a2ed>] __pci_register_driver+0x5d/0x60 [<ffffffffa00b3c58>] drm_pci_init+0x58/0xf0 [drm] [<ffffffff8109296d>] ? trace_hardirqs_on+0xd/0x10 [<ffffffffa02aa000>] ? 0xffffffffa02aa000 [<ffffffffa02aa094>] i915_init+0x94/0x9b [i915] [<ffffffff81000423>] do_one_initcall+0x113/0x1f0 [<ffffffff810a4b21>] ? rcu_read_lock_sched_held+0x61/0x90 [<ffffffff811601dc>] ? kmem_cache_alloc_trace+0x1cc/0x280 [<ffffffff8111110a>] do_init_module+0x60/0x1c8 [<ffffffff810c731b>] load_module+0x1ceb/0x2410 [<ffffffff810c3a60>] ? store_uevent+0x40/0x40 [<ffffffff811763d1>] ? kernel_read+0x41/0x60 [<ffffffff810c7c1d>] SYSC_finit_module+0x8d/0xa0 [<ffffffff810c7c4e>] SyS_finit_module+0xe/0x10 [<ffffffff815f1e97>] entry_SYSCALL_64_fastpath+0x12/0x6f ---[ end trace 1149e9ab3695a423 ]--- ------------[ cut here ]------------ Changes since v1: - Clear state before calling any function after .crtc_disable. Reported-by: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/56D6FD21.7020907@linux.intel.com Tested-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com>
2016-03-02 15:48:01 +01:00
struct intel_encoder *encoder;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->dev);
enum intel_display_power_domain domain;
unsigned long domains;
if (!intel_crtc->active)
return;
if (to_intel_plane_state(crtc->primary->state)->visible) {
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
WARN_ON(intel_crtc->flip_work);
intel_pre_disable_primary_noatomic(crtc);
intel_crtc_disable_planes(crtc, 1 << drm_plane_index(crtc->primary));
to_intel_plane_state(crtc->primary->state)->visible = false;
}
dev_priv->display.crtc_disable(crtc);
drm/i915: Update state before setting watermarks, v2. When intel_update_watermarks is called on skylake from the hw state readout disable function it calls intel_update_watermarks. intel_update_watermarks inspects crtc->state, which should be set to disabled. This wasn't the case, and this resulted in a divide-by-zero in skl_update_wm when intel_update_watermarks got called. ------------[ cut here ]------------ WARNING: CPU: 1 PID: 295 at drivers/gpu/drm/i915/intel_pm.c:2834 skl_update_pipe_wm+0x102/0x8c0 [i915]() WARN_ON(!config->num_pipes_active) Modules linked in: coretemp i915(+) xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx CPU: 1 PID: 295 Comm: systemd-udevd Tainted: G U W 4.5.0-rc4 -xxxxxx #25 Hardware name: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 0000000000000000 ffff88003777f5a8 ffffffff813485c2 ffff88003777f5f0 ffffffffa0236240 ffff88003777f5e0 ffffffff81050fce ffff8800aa420000 ffff8800aba18000 ffff8800aba18000 ffff880037304c00 ffff8800aa420000 Call Trace: [<ffffffff813485c2>] dump_stack+0x67/0x95 [<ffffffff81050fce>] warn_slowpath_common+0x9e/0xc0 [<ffffffff8105103c>] warn_slowpath_fmt+0x4c/0x50 [<ffffffff8106945e>] ? flush_work+0x8e/0x280 [<ffffffff810693d5>] ? flush_work+0x5/0x280 [<ffffffffa016add2>] skl_update_pipe_wm+0x102/0x8c0 [i915] [<ffffffffa016b96f>] skl_update_wm+0xff/0x5f0 [i915] [<ffffffff810928ee>] ? trace_hardirqs_on_caller+0x15e/0x1d0 [<ffffffff8109296d>] ? trace_hardirqs_on+0xd/0x10 [<ffffffffa016ce6e>] intel_update_watermarks+0x1e/0x30 [i915] [<ffffffffa01d3ee2>] intel_crtc_disable_noatomic+0xd2/0x150 [i915] [<ffffffffa01dd3d2>] intel_modeset_setup_hw_state+0xdd2/0xde0 [i915] [<ffffffffa01dfd83>] intel_modeset_init+0x15a3/0x1950 [i915] [<ffffffffa02160b6>] i915_driver_load+0x13c6/0x1720 [i915] [<ffffffff81522160>] ? add_sysfs_fw_map_entry+0x9b/0x9b [<ffffffffa00b15ef>] drm_dev_register+0x6f/0xb0 [drm] [<ffffffffa00b3b3a>] drm_get_pci_dev+0x10a/0x1d0 [drm] [<ffffffffa01582d9>] i915_pci_probe+0x49/0x50 [i915] [<ffffffff8138ae30>] pci_device_probe+0x80/0xf0 [<ffffffff8143e2ac>] driver_probe_device+0x1bc/0x3d0 [<ffffffff8143e526>] __driver_attach+0x66/0x90 [<ffffffff8143e4c0>] ? driver_probe_device+0x3d0/0x3d0 [<ffffffff8143be3b>] bus_for_each_dev+0x5b/0xa0 [<ffffffff8143db3e>] driver_attach+0x1e/0x20 [<ffffffff8143d461>] bus_add_driver+0x151/0x270 [<ffffffff8143eabc>] driver_register+0x8c/0xd0 [<ffffffff8138a2ed>] __pci_register_driver+0x5d/0x60 [<ffffffffa00b3c58>] drm_pci_init+0x58/0xf0 [drm] [<ffffffff8109296d>] ? trace_hardirqs_on+0xd/0x10 [<ffffffffa02aa000>] ? 0xffffffffa02aa000 [<ffffffffa02aa094>] i915_init+0x94/0x9b [i915] [<ffffffff81000423>] do_one_initcall+0x113/0x1f0 [<ffffffff810a4b21>] ? rcu_read_lock_sched_held+0x61/0x90 [<ffffffff811601dc>] ? kmem_cache_alloc_trace+0x1cc/0x280 [<ffffffff8111110a>] do_init_module+0x60/0x1c8 [<ffffffff810c731b>] load_module+0x1ceb/0x2410 [<ffffffff810c3a60>] ? store_uevent+0x40/0x40 [<ffffffff811763d1>] ? kernel_read+0x41/0x60 [<ffffffff810c7c1d>] SYSC_finit_module+0x8d/0xa0 [<ffffffff810c7c4e>] SyS_finit_module+0xe/0x10 [<ffffffff815f1e97>] entry_SYSCALL_64_fastpath+0x12/0x6f ---[ end trace 1149e9ab3695a423 ]--- ------------[ cut here ]------------ Changes since v1: - Clear state before calling any function after .crtc_disable. Reported-by: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/56D6FD21.7020907@linux.intel.com Tested-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com>
2016-03-02 15:48:01 +01:00
DRM_DEBUG_KMS("[CRTC:%d:%s] hw state adjusted, was enabled, now disabled\n",
crtc->base.id, crtc->name);
drm/i915: Update state before setting watermarks, v2. When intel_update_watermarks is called on skylake from the hw state readout disable function it calls intel_update_watermarks. intel_update_watermarks inspects crtc->state, which should be set to disabled. This wasn't the case, and this resulted in a divide-by-zero in skl_update_wm when intel_update_watermarks got called. ------------[ cut here ]------------ WARNING: CPU: 1 PID: 295 at drivers/gpu/drm/i915/intel_pm.c:2834 skl_update_pipe_wm+0x102/0x8c0 [i915]() WARN_ON(!config->num_pipes_active) Modules linked in: coretemp i915(+) xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx CPU: 1 PID: 295 Comm: systemd-udevd Tainted: G U W 4.5.0-rc4 -xxxxxx #25 Hardware name: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 0000000000000000 ffff88003777f5a8 ffffffff813485c2 ffff88003777f5f0 ffffffffa0236240 ffff88003777f5e0 ffffffff81050fce ffff8800aa420000 ffff8800aba18000 ffff8800aba18000 ffff880037304c00 ffff8800aa420000 Call Trace: [<ffffffff813485c2>] dump_stack+0x67/0x95 [<ffffffff81050fce>] warn_slowpath_common+0x9e/0xc0 [<ffffffff8105103c>] warn_slowpath_fmt+0x4c/0x50 [<ffffffff8106945e>] ? flush_work+0x8e/0x280 [<ffffffff810693d5>] ? flush_work+0x5/0x280 [<ffffffffa016add2>] skl_update_pipe_wm+0x102/0x8c0 [i915] [<ffffffffa016b96f>] skl_update_wm+0xff/0x5f0 [i915] [<ffffffff810928ee>] ? trace_hardirqs_on_caller+0x15e/0x1d0 [<ffffffff8109296d>] ? trace_hardirqs_on+0xd/0x10 [<ffffffffa016ce6e>] intel_update_watermarks+0x1e/0x30 [i915] [<ffffffffa01d3ee2>] intel_crtc_disable_noatomic+0xd2/0x150 [i915] [<ffffffffa01dd3d2>] intel_modeset_setup_hw_state+0xdd2/0xde0 [i915] [<ffffffffa01dfd83>] intel_modeset_init+0x15a3/0x1950 [i915] [<ffffffffa02160b6>] i915_driver_load+0x13c6/0x1720 [i915] [<ffffffff81522160>] ? add_sysfs_fw_map_entry+0x9b/0x9b [<ffffffffa00b15ef>] drm_dev_register+0x6f/0xb0 [drm] [<ffffffffa00b3b3a>] drm_get_pci_dev+0x10a/0x1d0 [drm] [<ffffffffa01582d9>] i915_pci_probe+0x49/0x50 [i915] [<ffffffff8138ae30>] pci_device_probe+0x80/0xf0 [<ffffffff8143e2ac>] driver_probe_device+0x1bc/0x3d0 [<ffffffff8143e526>] __driver_attach+0x66/0x90 [<ffffffff8143e4c0>] ? driver_probe_device+0x3d0/0x3d0 [<ffffffff8143be3b>] bus_for_each_dev+0x5b/0xa0 [<ffffffff8143db3e>] driver_attach+0x1e/0x20 [<ffffffff8143d461>] bus_add_driver+0x151/0x270 [<ffffffff8143eabc>] driver_register+0x8c/0xd0 [<ffffffff8138a2ed>] __pci_register_driver+0x5d/0x60 [<ffffffffa00b3c58>] drm_pci_init+0x58/0xf0 [drm] [<ffffffff8109296d>] ? trace_hardirqs_on+0xd/0x10 [<ffffffffa02aa000>] ? 0xffffffffa02aa000 [<ffffffffa02aa094>] i915_init+0x94/0x9b [i915] [<ffffffff81000423>] do_one_initcall+0x113/0x1f0 [<ffffffff810a4b21>] ? rcu_read_lock_sched_held+0x61/0x90 [<ffffffff811601dc>] ? kmem_cache_alloc_trace+0x1cc/0x280 [<ffffffff8111110a>] do_init_module+0x60/0x1c8 [<ffffffff810c731b>] load_module+0x1ceb/0x2410 [<ffffffff810c3a60>] ? store_uevent+0x40/0x40 [<ffffffff811763d1>] ? kernel_read+0x41/0x60 [<ffffffff810c7c1d>] SYSC_finit_module+0x8d/0xa0 [<ffffffff810c7c4e>] SyS_finit_module+0xe/0x10 [<ffffffff815f1e97>] entry_SYSCALL_64_fastpath+0x12/0x6f ---[ end trace 1149e9ab3695a423 ]--- ------------[ cut here ]------------ Changes since v1: - Clear state before calling any function after .crtc_disable. Reported-by: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/56D6FD21.7020907@linux.intel.com Tested-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com>
2016-03-02 15:48:01 +01:00
WARN_ON(drm_atomic_set_mode_for_crtc(crtc->state, NULL) < 0);
crtc->state->active = false;
intel_crtc->active = false;
drm/i915: Update state before setting watermarks, v2. When intel_update_watermarks is called on skylake from the hw state readout disable function it calls intel_update_watermarks. intel_update_watermarks inspects crtc->state, which should be set to disabled. This wasn't the case, and this resulted in a divide-by-zero in skl_update_wm when intel_update_watermarks got called. ------------[ cut here ]------------ WARNING: CPU: 1 PID: 295 at drivers/gpu/drm/i915/intel_pm.c:2834 skl_update_pipe_wm+0x102/0x8c0 [i915]() WARN_ON(!config->num_pipes_active) Modules linked in: coretemp i915(+) xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx CPU: 1 PID: 295 Comm: systemd-udevd Tainted: G U W 4.5.0-rc4 -xxxxxx #25 Hardware name: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 0000000000000000 ffff88003777f5a8 ffffffff813485c2 ffff88003777f5f0 ffffffffa0236240 ffff88003777f5e0 ffffffff81050fce ffff8800aa420000 ffff8800aba18000 ffff8800aba18000 ffff880037304c00 ffff8800aa420000 Call Trace: [<ffffffff813485c2>] dump_stack+0x67/0x95 [<ffffffff81050fce>] warn_slowpath_common+0x9e/0xc0 [<ffffffff8105103c>] warn_slowpath_fmt+0x4c/0x50 [<ffffffff8106945e>] ? flush_work+0x8e/0x280 [<ffffffff810693d5>] ? flush_work+0x5/0x280 [<ffffffffa016add2>] skl_update_pipe_wm+0x102/0x8c0 [i915] [<ffffffffa016b96f>] skl_update_wm+0xff/0x5f0 [i915] [<ffffffff810928ee>] ? trace_hardirqs_on_caller+0x15e/0x1d0 [<ffffffff8109296d>] ? trace_hardirqs_on+0xd/0x10 [<ffffffffa016ce6e>] intel_update_watermarks+0x1e/0x30 [i915] [<ffffffffa01d3ee2>] intel_crtc_disable_noatomic+0xd2/0x150 [i915] [<ffffffffa01dd3d2>] intel_modeset_setup_hw_state+0xdd2/0xde0 [i915] [<ffffffffa01dfd83>] intel_modeset_init+0x15a3/0x1950 [i915] [<ffffffffa02160b6>] i915_driver_load+0x13c6/0x1720 [i915] [<ffffffff81522160>] ? add_sysfs_fw_map_entry+0x9b/0x9b [<ffffffffa00b15ef>] drm_dev_register+0x6f/0xb0 [drm] [<ffffffffa00b3b3a>] drm_get_pci_dev+0x10a/0x1d0 [drm] [<ffffffffa01582d9>] i915_pci_probe+0x49/0x50 [i915] [<ffffffff8138ae30>] pci_device_probe+0x80/0xf0 [<ffffffff8143e2ac>] driver_probe_device+0x1bc/0x3d0 [<ffffffff8143e526>] __driver_attach+0x66/0x90 [<ffffffff8143e4c0>] ? driver_probe_device+0x3d0/0x3d0 [<ffffffff8143be3b>] bus_for_each_dev+0x5b/0xa0 [<ffffffff8143db3e>] driver_attach+0x1e/0x20 [<ffffffff8143d461>] bus_add_driver+0x151/0x270 [<ffffffff8143eabc>] driver_register+0x8c/0xd0 [<ffffffff8138a2ed>] __pci_register_driver+0x5d/0x60 [<ffffffffa00b3c58>] drm_pci_init+0x58/0xf0 [drm] [<ffffffff8109296d>] ? trace_hardirqs_on+0xd/0x10 [<ffffffffa02aa000>] ? 0xffffffffa02aa000 [<ffffffffa02aa094>] i915_init+0x94/0x9b [i915] [<ffffffff81000423>] do_one_initcall+0x113/0x1f0 [<ffffffff810a4b21>] ? rcu_read_lock_sched_held+0x61/0x90 [<ffffffff811601dc>] ? kmem_cache_alloc_trace+0x1cc/0x280 [<ffffffff8111110a>] do_init_module+0x60/0x1c8 [<ffffffff810c731b>] load_module+0x1ceb/0x2410 [<ffffffff810c3a60>] ? store_uevent+0x40/0x40 [<ffffffff811763d1>] ? kernel_read+0x41/0x60 [<ffffffff810c7c1d>] SYSC_finit_module+0x8d/0xa0 [<ffffffff810c7c4e>] SyS_finit_module+0xe/0x10 [<ffffffff815f1e97>] entry_SYSCALL_64_fastpath+0x12/0x6f ---[ end trace 1149e9ab3695a423 ]--- ------------[ cut here ]------------ Changes since v1: - Clear state before calling any function after .crtc_disable. Reported-by: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/56D6FD21.7020907@linux.intel.com Tested-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com>
2016-03-02 15:48:01 +01:00
crtc->enabled = false;
crtc->state->connector_mask = 0;
crtc->state->encoder_mask = 0;
for_each_encoder_on_crtc(crtc->dev, crtc, encoder)
encoder->base.crtc = NULL;
intel_fbc_disable(intel_crtc);
intel_update_watermarks(crtc);
intel_disable_shared_dpll(intel_crtc);
domains = intel_crtc->enabled_power_domains;
for_each_power_domain(domain, domains)
intel_display_power_put(dev_priv, domain);
intel_crtc->enabled_power_domains = 0;
dev_priv->active_crtcs &= ~(1 << intel_crtc->pipe);
dev_priv->min_pixclk[intel_crtc->pipe] = 0;
}
/*
* turn all crtc's off, but do not adjust state
* This has to be paired with a call to intel_modeset_setup_hw_state.
*/
int intel_display_suspend(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_atomic_state *state;
int ret;
state = drm_atomic_helper_suspend(dev);
ret = PTR_ERR_OR_ZERO(state);
if (ret)
DRM_ERROR("Suspending crtc's failed with %i\n", ret);
else
dev_priv->modeset_restore_state = state;
return ret;
}
void intel_encoder_destroy(struct drm_encoder *encoder)
{
struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
drm_encoder_cleanup(encoder);
kfree(intel_encoder);
}
/* Cross check the actual hw state with our own modeset state tracking (and it's
* internal consistency). */
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
static void intel_connector_verify_state(struct intel_connector *connector)
{
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
struct drm_crtc *crtc = connector->base.state->crtc;
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
connector->base.base.id,
connector->base.name);
if (connector->get_hw_state(connector)) {
struct intel_encoder *encoder = connector->encoder;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
struct drm_connector_state *conn_state = connector->base.state;
I915_STATE_WARN(!crtc,
"connector enabled without attached crtc\n");
if (!crtc)
return;
I915_STATE_WARN(!crtc->state->active,
"connector is active, but attached crtc isn't\n");
if (!encoder || encoder->type == INTEL_OUTPUT_DP_MST)
return;
I915_STATE_WARN(conn_state->best_encoder != &encoder->base,
"atomic encoder doesn't match attached encoder\n");
I915_STATE_WARN(conn_state->crtc != encoder->base.crtc,
"attached encoder crtc differs from connector crtc\n");
} else {
I915_STATE_WARN(crtc && crtc->state->active,
"attached crtc is active, but connector isn't\n");
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
I915_STATE_WARN(!crtc && connector->base.state->best_encoder,
"best encoder set without crtc!\n");
}
}
int intel_connector_init(struct intel_connector *connector)
{
drm_atomic_helper_connector_reset(&connector->base);
if (!connector->base.state)
return -ENOMEM;
return 0;
}
struct intel_connector *intel_connector_alloc(void)
{
struct intel_connector *connector;
connector = kzalloc(sizeof *connector, GFP_KERNEL);
if (!connector)
return NULL;
if (intel_connector_init(connector) < 0) {
kfree(connector);
return NULL;
}
return connector;
}
/* Simple connector->get_hw_state implementation for encoders that support only
* one connector and no cloning and hence the encoder state determines the state
* of the connector. */
bool intel_connector_get_hw_state(struct intel_connector *connector)
{
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
enum pipe pipe = 0;
struct intel_encoder *encoder = connector->encoder;
return encoder->get_hw_state(encoder, &pipe);
}
static int pipe_required_fdi_lanes(struct intel_crtc_state *crtc_state)
{
if (crtc_state->base.enable && crtc_state->has_pch_encoder)
return crtc_state->fdi_lanes;
return 0;
}
static int ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
struct intel_crtc_state *pipe_config)
{
struct drm_atomic_state *state = pipe_config->base.state;
struct intel_crtc *other_crtc;
struct intel_crtc_state *other_crtc_state;
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 -EINVAL;
}
if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
if (pipe_config->fdi_lanes > 2) {
DRM_DEBUG_KMS("only 2 lanes on haswell, required: %i lanes\n",
pipe_config->fdi_lanes);
return -EINVAL;
} else {
return 0;
}
}
if (INTEL_INFO(dev)->num_pipes == 2)
return 0;
/* Ivybridge 3 pipe is really complicated */
switch (pipe) {
case PIPE_A:
return 0;
case PIPE_B:
if (pipe_config->fdi_lanes <= 2)
return 0;
other_crtc = to_intel_crtc(intel_get_crtc_for_pipe(dev, PIPE_C));
other_crtc_state =
intel_atomic_get_crtc_state(state, other_crtc);
if (IS_ERR(other_crtc_state))
return PTR_ERR(other_crtc_state);
if (pipe_required_fdi_lanes(other_crtc_state) > 0) {
DRM_DEBUG_KMS("invalid shared fdi lane config on pipe %c: %i lanes\n",
pipe_name(pipe), pipe_config->fdi_lanes);
return -EINVAL;
}
return 0;
case PIPE_C:
if (pipe_config->fdi_lanes > 2) {
DRM_DEBUG_KMS("only 2 lanes on pipe %c: required %i lanes\n",
pipe_name(pipe), pipe_config->fdi_lanes);
return -EINVAL;
}
other_crtc = to_intel_crtc(intel_get_crtc_for_pipe(dev, PIPE_B));
other_crtc_state =
intel_atomic_get_crtc_state(state, other_crtc);
if (IS_ERR(other_crtc_state))
return PTR_ERR(other_crtc_state);
if (pipe_required_fdi_lanes(other_crtc_state) > 2) {
DRM_DEBUG_KMS("fdi link B uses too many lanes to enable link C\n");
return -EINVAL;
}
return 0;
default:
BUG();
}
}
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 <imre.deak@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-02-21 00:00:16 +01:00
#define RETRY 1
static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = intel_crtc->base.dev;
const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
int lane, link_bw, fdi_dotclock, ret;
bool needs_recompute = false;
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 <imre.deak@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-02-21 00:00:16 +01:00
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
* 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(to_i915(dev), pipe_config);
fdi_dotclock = adjusted_mode->crtc_clock;
lane = ironlake_get_lanes_required(fdi_dotclock, link_bw,
pipe_config->pipe_bpp);
pipe_config->fdi_lanes = lane;
intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock,
link_bw, &pipe_config->fdi_m_n);
ret = ironlake_check_fdi_lanes(dev, intel_crtc->pipe, pipe_config);
if (ret == -EINVAL && pipe_config->pipe_bpp > 6*3) {
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 <imre.deak@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-02-21 00:00:16 +01:00
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 ret;
}
static bool pipe_config_supports_ips(struct drm_i915_private *dev_priv,
struct intel_crtc_state *pipe_config)
{
if (pipe_config->pipe_bpp > 24)
return false;
/* HSW can handle pixel rate up to cdclk? */
if (IS_HASWELL(dev_priv))
return true;
/*
* We compare against max which means we must take
* the increased cdclk requirement into account when
* calculating the new cdclk.
*
* Should measure whether using a lower cdclk w/o IPS
*/
return ilk_pipe_pixel_rate(pipe_config) <=
dev_priv->max_cdclk_freq * 95 / 100;
}
static void hsw_compute_ips_config(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
pipe_config->ips_enabled = i915.enable_ips &&
hsw_crtc_supports_ips(crtc) &&
pipe_config_supports_ips(dev_priv, pipe_config);
}
static bool intel_crtc_supports_double_wide(const struct intel_crtc *crtc)
{
const struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
/* GDG double wide on either pipe, otherwise pipe A only */
return INTEL_INFO(dev_priv)->gen < 4 &&
(crtc->pipe == PIPE_A || IS_I915G(dev_priv));
}
static int intel_crtc_compute_config(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
int clock_limit = dev_priv->max_dotclk_freq;
if (INTEL_INFO(dev)->gen < 4) {
clock_limit = dev_priv->max_cdclk_freq * 9 / 10;
/*
* Enable double wide mode when the dot clock
* is > 90% of the (display) core speed.
*/
if (intel_crtc_supports_double_wide(crtc) &&
adjusted_mode->crtc_clock > clock_limit) {
clock_limit = dev_priv->max_dotclk_freq;
pipe_config->double_wide = true;
}
}
if (adjusted_mode->crtc_clock > clock_limit) {
DRM_DEBUG_KMS("requested pixel clock (%d kHz) too high (max: %d kHz, double wide: %s)\n",
adjusted_mode->crtc_clock, clock_limit,
yesno(pipe_config->double_wide));
return -EINVAL;
}
/*
* Pipe horizontal size must be even in:
* - DVO ganged mode
* - LVDS dual channel mode
* - Double wide pipe
*/
if ((intel_pipe_will_have_type(pipe_config, INTEL_OUTPUT_LVDS) &&
intel_is_dual_link_lvds(dev)) || pipe_config->double_wide)
pipe_config->pipe_src_w &= ~1;
/* 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->crtc_hsync_start == adjusted_mode->crtc_hdisplay)
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 <imre.deak@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-02-21 00:00:16 +01:00
return -EINVAL;
if (HAS_IPS(dev))
hsw_compute_ips_config(crtc, pipe_config);
if (pipe_config->has_pch_encoder)
return ironlake_fdi_compute_config(crtc, pipe_config);
return 0;
}
static int skylake_get_display_clock_speed(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = to_i915(dev);
uint32_t cdctl;
skl_dpll0_update(dev_priv);
if (dev_priv->cdclk_pll.vco == 0)
return dev_priv->cdclk_pll.ref;
cdctl = I915_READ(CDCLK_CTL);
if (dev_priv->cdclk_pll.vco == 8640000) {
switch (cdctl & CDCLK_FREQ_SEL_MASK) {
case CDCLK_FREQ_450_432:
return 432000;
case CDCLK_FREQ_337_308:
return 308571;
case CDCLK_FREQ_540:
return 540000;
case CDCLK_FREQ_675_617:
return 617143;
default:
MISSING_CASE(cdctl & CDCLK_FREQ_SEL_MASK);
}
} else {
switch (cdctl & CDCLK_FREQ_SEL_MASK) {
case CDCLK_FREQ_450_432:
return 450000;
case CDCLK_FREQ_337_308:
return 337500;
case CDCLK_FREQ_540:
return 540000;
case CDCLK_FREQ_675_617:
return 675000;
default:
MISSING_CASE(cdctl & CDCLK_FREQ_SEL_MASK);
}
}
return dev_priv->cdclk_pll.ref;
}
static void bxt_de_pll_update(struct drm_i915_private *dev_priv)
{
u32 val;
dev_priv->cdclk_pll.ref = 19200;
dev_priv->cdclk_pll.vco = 0;
val = I915_READ(BXT_DE_PLL_ENABLE);
if ((val & BXT_DE_PLL_PLL_ENABLE) == 0)
return;
if (WARN_ON((val & BXT_DE_PLL_LOCK) == 0))
return;
val = I915_READ(BXT_DE_PLL_CTL);
dev_priv->cdclk_pll.vco = (val & BXT_DE_PLL_RATIO_MASK) *
dev_priv->cdclk_pll.ref;
}
static int broxton_get_display_clock_speed(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = to_i915(dev);
u32 divider;
int div, vco;
bxt_de_pll_update(dev_priv);
vco = dev_priv->cdclk_pll.vco;
if (vco == 0)
return dev_priv->cdclk_pll.ref;
divider = I915_READ(CDCLK_CTL) & BXT_CDCLK_CD2X_DIV_SEL_MASK;
switch (divider) {
case BXT_CDCLK_CD2X_DIV_SEL_1:
div = 2;
break;
case BXT_CDCLK_CD2X_DIV_SEL_1_5:
div = 3;
break;
case BXT_CDCLK_CD2X_DIV_SEL_2:
div = 4;
break;
case BXT_CDCLK_CD2X_DIV_SEL_4:
div = 8;
break;
default:
MISSING_CASE(divider);
return dev_priv->cdclk_pll.ref;
}
return DIV_ROUND_CLOSEST(vco, div);
}
static int broadwell_get_display_clock_speed(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t lcpll = I915_READ(LCPLL_CTL);
uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK;
if (lcpll & LCPLL_CD_SOURCE_FCLK)
return 800000;
else if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT)
return 450000;
else if (freq == LCPLL_CLK_FREQ_450)
return 450000;
else if (freq == LCPLL_CLK_FREQ_54O_BDW)
return 540000;
else if (freq == LCPLL_CLK_FREQ_337_5_BDW)
return 337500;
else
return 675000;
}
static int haswell_get_display_clock_speed(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t lcpll = I915_READ(LCPLL_CTL);
uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK;
if (lcpll & LCPLL_CD_SOURCE_FCLK)
return 800000;
else if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT)
return 450000;
else if (freq == LCPLL_CLK_FREQ_450)
return 450000;
else if (IS_HSW_ULT(dev))
return 337500;
else
return 540000;
}
static int valleyview_get_display_clock_speed(struct drm_device *dev)
{
return vlv_get_cck_clock_hpll(to_i915(dev), "cdclk",
CCK_DISPLAY_CLOCK_CONTROL);
}
static int ilk_get_display_clock_speed(struct drm_device *dev)
{
return 450000;
}
static int i945_get_display_clock_speed(struct drm_device *dev)
{
return 400000;
}
static int i915_get_display_clock_speed(struct drm_device *dev)
{
return 333333;
}
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 266667;
case GC_DISPLAY_CLOCK_333_MHZ_PNV:
return 333333;
case GC_DISPLAY_CLOCK_444_MHZ_PNV:
return 444444;
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 133333;
case GC_DISPLAY_CLOCK_167_MHZ_PNV:
return 166667;
}
}
static int i915gm_get_display_clock_speed(struct drm_device *dev)
{
u16 gcfgc = 0;
pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
if (gcfgc & GC_LOW_FREQUENCY_ENABLE)
return 133333;
else {
switch (gcfgc & GC_DISPLAY_CLOCK_MASK) {
case GC_DISPLAY_CLOCK_333_MHZ:
return 333333;
default:
case GC_DISPLAY_CLOCK_190_200_MHZ:
return 190000;
}
}
}
static int i865_get_display_clock_speed(struct drm_device *dev)
{
return 266667;
}
static int i85x_get_display_clock_speed(struct drm_device *dev)
{
u16 hpllcc = 0;
/*
* 852GM/852GMV only supports 133 MHz and the HPLLCC
* encoding is different :(
* FIXME is this the right way to detect 852GM/852GMV?
*/
if (dev->pdev->revision == 0x1)
return 133333;
pci_bus_read_config_word(dev->pdev->bus,
PCI_DEVFN(0, 3), HPLLCC, &hpllcc);
/* Assume that the hardware is in the high speed state. This
* should be the default.
*/
switch (hpllcc & GC_CLOCK_CONTROL_MASK) {
case GC_CLOCK_133_200:
case GC_CLOCK_133_200_2:
case GC_CLOCK_100_200:
return 200000;
case GC_CLOCK_166_250:
return 250000;
case GC_CLOCK_100_133:
return 133333;
case GC_CLOCK_133_266:
case GC_CLOCK_133_266_2:
case GC_CLOCK_166_266:
return 266667;
}
/* Shouldn't happen */
return 0;
}
static int i830_get_display_clock_speed(struct drm_device *dev)
{
return 133333;
}
static unsigned int intel_hpll_vco(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
static const unsigned int blb_vco[8] = {
[0] = 3200000,
[1] = 4000000,
[2] = 5333333,
[3] = 4800000,
[4] = 6400000,
};
static const unsigned int pnv_vco[8] = {
[0] = 3200000,
[1] = 4000000,
[2] = 5333333,
[3] = 4800000,
[4] = 2666667,
};
static const unsigned int cl_vco[8] = {
[0] = 3200000,
[1] = 4000000,
[2] = 5333333,
[3] = 6400000,
[4] = 3333333,
[5] = 3566667,
[6] = 4266667,
};
static const unsigned int elk_vco[8] = {
[0] = 3200000,
[1] = 4000000,
[2] = 5333333,
[3] = 4800000,
};
static const unsigned int ctg_vco[8] = {
[0] = 3200000,
[1] = 4000000,
[2] = 5333333,
[3] = 6400000,
[4] = 2666667,
[5] = 4266667,
};
const unsigned int *vco_table;
unsigned int vco;
uint8_t tmp = 0;
/* FIXME other chipsets? */
if (IS_GM45(dev))
vco_table = ctg_vco;
else if (IS_G4X(dev))
vco_table = elk_vco;
else if (IS_CRESTLINE(dev))
vco_table = cl_vco;
else if (IS_PINEVIEW(dev))
vco_table = pnv_vco;
else if (IS_G33(dev))
vco_table = blb_vco;
else
return 0;
tmp = I915_READ(IS_MOBILE(dev) ? HPLLVCO_MOBILE : HPLLVCO);
vco = vco_table[tmp & 0x7];
if (vco == 0)
DRM_ERROR("Bad HPLL VCO (HPLLVCO=0x%02x)\n", tmp);
else
DRM_DEBUG_KMS("HPLL VCO %u kHz\n", vco);
return vco;
}
static int gm45_get_display_clock_speed(struct drm_device *dev)
{
unsigned int cdclk_sel, vco = intel_hpll_vco(dev);
uint16_t tmp = 0;
pci_read_config_word(dev->pdev, GCFGC, &tmp);
cdclk_sel = (tmp >> 12) & 0x1;
switch (vco) {
case 2666667:
case 4000000:
case 5333333:
return cdclk_sel ? 333333 : 222222;
case 3200000:
return cdclk_sel ? 320000 : 228571;
default:
DRM_ERROR("Unable to determine CDCLK. HPLL VCO=%u, CFGC=0x%04x\n", vco, tmp);
return 222222;
}
}
static int i965gm_get_display_clock_speed(struct drm_device *dev)
{
static const uint8_t div_3200[] = { 16, 10, 8 };
static const uint8_t div_4000[] = { 20, 12, 10 };
static const uint8_t div_5333[] = { 24, 16, 14 };
const uint8_t *div_table;
unsigned int cdclk_sel, vco = intel_hpll_vco(dev);
uint16_t tmp = 0;
pci_read_config_word(dev->pdev, GCFGC, &tmp);
cdclk_sel = ((tmp >> 8) & 0x1f) - 1;
if (cdclk_sel >= ARRAY_SIZE(div_3200))
goto fail;
switch (vco) {
case 3200000:
div_table = div_3200;
break;
case 4000000:
div_table = div_4000;
break;
case 5333333:
div_table = div_5333;
break;
default:
goto fail;
}
return DIV_ROUND_CLOSEST(vco, div_table[cdclk_sel]);
fail:
DRM_ERROR("Unable to determine CDCLK. HPLL VCO=%u kHz, CFGC=0x%04x\n", vco, tmp);
return 200000;
}
static int g33_get_display_clock_speed(struct drm_device *dev)
{
static const uint8_t div_3200[] = { 12, 10, 8, 7, 5, 16 };
static const uint8_t div_4000[] = { 14, 12, 10, 8, 6, 20 };
static const uint8_t div_4800[] = { 20, 14, 12, 10, 8, 24 };
static const uint8_t div_5333[] = { 20, 16, 12, 12, 8, 28 };
const uint8_t *div_table;
unsigned int cdclk_sel, vco = intel_hpll_vco(dev);
uint16_t tmp = 0;
pci_read_config_word(dev->pdev, GCFGC, &tmp);
cdclk_sel = (tmp >> 4) & 0x7;
if (cdclk_sel >= ARRAY_SIZE(div_3200))
goto fail;
switch (vco) {
case 3200000:
div_table = div_3200;
break;
case 4000000:
div_table = div_4000;
break;
case 4800000:
div_table = div_4800;
break;
case 5333333:
div_table = div_5333;
break;
default:
goto fail;
}
return DIV_ROUND_CLOSEST(vco, div_table[cdclk_sel]);
fail:
DRM_ERROR("Unable to determine CDCLK. HPLL VCO=%u kHz, CFGC=0x%08x\n", vco, tmp);
return 190476;
}
static void
intel_reduce_m_n_ratio(uint32_t *num, uint32_t *den)
{
while (*num > DATA_LINK_M_N_MASK ||
*den > DATA_LINK_M_N_MASK) {
*num >>= 1;
*den >>= 1;
}
}
static void compute_m_n(unsigned int m, unsigned int n,
uint32_t *ret_m, uint32_t *ret_n)
{
*ret_n = min_t(unsigned int, roundup_pow_of_two(n), DATA_LINK_N_MAX);
*ret_m = div_u64((uint64_t) m * *ret_n, n);
intel_reduce_m_n_ratio(ret_m, ret_n);
}
void
intel_link_compute_m_n(int bits_per_pixel, int nlanes,
int pixel_clock, int link_clock,
struct intel_link_m_n *m_n)
{
m_n->tu = 64;
compute_m_n(bits_per_pixel * pixel_clock,
link_clock * nlanes * 8,
&m_n->gmch_m, &m_n->gmch_n);
compute_m_n(pixel_clock, link_clock,
&m_n->link_m, &m_n->link_n);
}
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->vbt.lvds_use_ssc
&& !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE);
}
static uint32_t pnv_dpll_compute_fp(struct dpll *dpll)
{
return (1 << dpll->n) << 16 | 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,
struct intel_crtc_state *crtc_state,
struct dpll *reduced_clock)
{
struct drm_device *dev = crtc->base.dev;
u32 fp, fp2 = 0;
if (IS_PINEVIEW(dev)) {
fp = pnv_dpll_compute_fp(&crtc_state->dpll);
if (reduced_clock)
fp2 = pnv_dpll_compute_fp(reduced_clock);
} else {
fp = i9xx_dpll_compute_fp(&crtc_state->dpll);
if (reduced_clock)
fp2 = i9xx_dpll_compute_fp(reduced_clock);
}
crtc_state->dpll_hw_state.fp0 = fp;
crtc->lowfreq_avail = false;
if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) &&
reduced_clock) {
crtc_state->dpll_hw_state.fp1 = fp2;
crtc->lowfreq_avail = true;
} else {
crtc_state->dpll_hw_state.fp1 = fp;
}
}
static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv, enum pipe
pipe)
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
{
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 = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW9(1));
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
reg_val &= 0xffffff00;
reg_val |= 0x00000030;
vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW9(1), reg_val);
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
reg_val = vlv_dpio_read(dev_priv, pipe, VLV_REF_DW13);
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
reg_val &= 0x8cffffff;
reg_val = 0x8c000000;
vlv_dpio_write(dev_priv, pipe, VLV_REF_DW13, reg_val);
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
reg_val = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW9(1));
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
reg_val &= 0xffffff00;
vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW9(1), reg_val);
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
reg_val = vlv_dpio_read(dev_priv, pipe, VLV_REF_DW13);
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
reg_val &= 0x00ffffff;
reg_val |= 0xb0000000;
vlv_dpio_write(dev_priv, pipe, VLV_REF_DW13, reg_val);
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
}
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(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,
struct intel_link_m_n *m_n,
struct intel_link_m_n *m2_n2)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
int pipe = crtc->pipe;
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
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);
/* M2_N2 registers to be set only for gen < 8 (M2_N2 available
* for gen < 8) and if DRRS is supported (to make sure the
* registers are not unnecessarily accessed).
*/
if (m2_n2 && (IS_CHERRYVIEW(dev) || INTEL_INFO(dev)->gen < 8) &&
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
crtc->config->has_drrs) {
I915_WRITE(PIPE_DATA_M2(transcoder),
TU_SIZE(m2_n2->tu) | m2_n2->gmch_m);
I915_WRITE(PIPE_DATA_N2(transcoder), m2_n2->gmch_n);
I915_WRITE(PIPE_LINK_M2(transcoder), m2_n2->link_m);
I915_WRITE(PIPE_LINK_N2(transcoder), m2_n2->link_n);
}
} else {
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);
}
}
void intel_dp_set_m_n(struct intel_crtc *crtc, enum link_m_n_set m_n)
{
struct intel_link_m_n *dp_m_n, *dp_m2_n2 = NULL;
if (m_n == M1_N1) {
dp_m_n = &crtc->config->dp_m_n;
dp_m2_n2 = &crtc->config->dp_m2_n2;
} else if (m_n == M2_N2) {
/*
* M2_N2 registers are not supported. Hence m2_n2 divider value
* needs to be programmed into M1_N1.
*/
dp_m_n = &crtc->config->dp_m2_n2;
} else {
DRM_ERROR("Unsupported divider value\n");
return;
}
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (crtc->config->has_pch_encoder)
intel_pch_transcoder_set_m_n(crtc, &crtc->config->dp_m_n);
else
intel_cpu_transcoder_set_m_n(crtc, dp_m_n, dp_m2_n2);
}
static void vlv_compute_dpll(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config)
{
pipe_config->dpll_hw_state.dpll = DPLL_INTEGRATED_REF_CLK_VLV |
DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
if (crtc->pipe != PIPE_A)
pipe_config->dpll_hw_state.dpll |= DPLL_INTEGRATED_CRI_CLK_VLV;
/* DPLL not used with DSI, but still need the rest set up */
drm/i915: Fix oops in vlv_force_pll_on() intel_pipe_will_have_type() doesn't just look at the passied in pipe_config, instead it expects there to be a full atomic state behind it. Obviously that won't go so well when vlv_force_pll_on() just uses a temp pipe_config. Fix things by using pipe_config->has_dsi_encoder instead intel_pipe_will_have_type(INTEL_OUTPUT_DSI) to check if we need to actually enable the DPLL. Here's an example oops for reference: BUG: unable to handle kernel NULL pointer dereference at 0000000000000030 IP: [<ffffffffa0389a5b>] intel_pipe_will_have_type+0x15/0x7b [i915] PGD 7acda067 PUD 72696067 PMD 0 Oops: 0000 [#1] PREEMPT SMP Modules linked in: i915 i2c_algo_bit drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops drm intel_gtt agpgart netconsole psmouse atkbd iTCO_wdt libps2 coretemp hwmon efi_pstore intel_rapl punit_atom_debug efivars pcspkr i2c_i801 r8169 lpc_ich mii processor_thermal_device snd_soc_rt5670 intel_soc_dts_iosf snd_soc_rl6231 i2c_hid hid snd_intel_sst_acpi snd_intel_sst_core snd_soc_sst_mfld_platform snd_soc_sst_match snd_soc_core i8042 serio snd_compress snd_pcm snd_timer snd i2c_designware_platform sdhci_acpi i2c_designware_core soundcore sdhci pwm_lpss_platform mmc_core pwm_lpss spi_pxa2xx_platform evdev int3403_thermal int3400_thermal int340x_thermal_zone acpi_thermal_rel sch_fq_codel ip_tables x_tables ipv6 autofs4 CPU: 3 PID: 290 Comm: Xorg Tainted: G U 4.6.0-rc4-bsw+ #2876 Hardware name: Intel Corporation CHERRYVIEW C0 PLATFORM/Braswell CRB, BIOS BRAS.X64.X088.R00.1510270350 10/27/2015 task: ffff88007a8dd200 ti: ffff880173ac4000 task.ti: ffff880173ac4000 RIP: 0010:[<ffffffffa0389a5b>] [<ffffffffa0389a5b>] intel_pipe_will_have_type+0x15/0x7b [i915] RSP: 0018:ffff880173ac7928 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffff880176594000 RCX: 0000000000000000 RDX: 0000000000000000 RSI: 0000000000000009 RDI: ffff880176594000 RBP: ffff880173ac7930 R08: 0000000000019290 R09: 0000000000000000 R10: ffff880173ac7890 R11: 00000000000080cf R12: ffff88017fbd4000 R13: ffffffffa03e3c44 R14: ffff88007492c000 R15: ffff88007492c000 FS: 00007ff8936a6940(0000) GS:ffff88017ef80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000030 CR3: 0000000177e08000 CR4: 00000000001006e0 Stack: ffff880176594000 ffff880173ac7948 ffffffffa0389b42 ffff880176594000 ffff880173ac7978 ffffffffa0396e02 ffff8801765b0000 ffff88007af660d8 0000000000000000 0000000000000004 ffff880173ac79c0 ffffffffa03b6b64 Call Trace: [<ffffffffa0389b42>] chv_compute_dpll.isra.39+0x33/0x55 [i915] [<ffffffffa0396e02>] vlv_force_pll_on+0x80/0xc6 [i915] [<ffffffffa03b6b64>] vlv_power_sequencer_pipe+0x29b/0x3dd [i915] [<ffffffffa03b6cd4>] _pp_stat_reg+0x2e/0x38 [i915] [<ffffffffa03b6dc1>] wait_panel_status+0x4c/0x1ec [i915] [<ffffffffa03b6fcb>] wait_panel_power_cycle+0x6a/0xb4 [i915] [<ffffffffa03b70da>] edp_panel_vdd_on+0xc5/0x1d1 [i915] [<ffffffffa03b861b>] intel_dp_aux_ch+0x55/0x572 [i915] [<ffffffff810af5c8>] ? mark_held_locks+0x5d/0x74 [<ffffffff81518e61>] ? mutex_lock_nested+0x321/0x346 [<ffffffff81094007>] ? preempt_count_sub+0xf2/0x102 [<ffffffffa03b8cb4>] intel_dp_aux_transfer+0x17c/0x1b5 [i915] [<ffffffffa03028ef>] drm_dp_dpcd_access+0x62/0xed [drm_kms_helper] [<ffffffffa0302995>] drm_dp_dpcd_read+0x1b/0x1f [drm_kms_helper] [<ffffffffa03b5147>] intel_dp_dpcd_read_wake+0x31/0x69 [i915] [<ffffffffa03bb36a>] intel_dp_long_pulse+0x15f/0x5ed [i915] [<ffffffffa03bbb09>] intel_dp_detect+0x79/0x95 [i915] [<ffffffffa030340e>] drm_helper_probe_single_connector_modes+0xc7/0x3db [drm_kms_helper] [<ffffffffa029de23>] drm_mode_getconnector+0xe9/0x333 [drm] [<ffffffff810b1cfb>] ? lock_acquire+0x137/0x1df [<ffffffffa0292364>] drm_ioctl+0x266/0x3ae [drm] [<ffffffffa029dd3a>] ? drm_mode_getcrtc+0x126/0x126 [drm] [<ffffffff811af082>] vfs_ioctl+0x18/0x34 [<ffffffff811af682>] do_vfs_ioctl+0x547/0x5fe [<ffffffff811b9acb>] ? __fget_light+0x62/0x71 [<ffffffff811af77c>] SyS_ioctl+0x43/0x61 [<ffffffff81001a82>] do_syscall_64+0x63/0xf8 [<ffffffff8151bc9a>] entry_SYSCALL64_slow_path+0x25/0x25 Code: 35 00 40 a0 e8 97 4b ce e0 b8 17 00 00 00 5d c3 b8 17 00 00 00 c3 0f 1f 44 00 00 55 31 c0 31 d2 48 89 e5 53 48 8b 8f e8 01 00 00 <44> 8b 49 30 41 39 c1 7e 2d 4c 8b 51 38 4c 8b 41 40 49 83 3c c2 RIP [<ffffffffa0389a5b>] intel_pipe_will_have_type+0x15/0x7b [i915] RSP <ffff880173ac7928> CR2: 0000000000000030 The regressing patch wasn't exactly new (as in first posted more than six months ago), so I'm a bit baffled how I didn't manage to hit this myself so far. Cc: Jani Nikula <jani.nikula@intel.com> Cc: Marius Vlad <marius.c.vlad@intel.com> Reported-by: Marius Vlad <marius.c.vlad@intel.com> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94995 Fixes: cd2d34d9b61f ("drm/i915: Setup DPLL/DPLLMD for DSI too on VLV/CHV") Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1461000844-20543-1-git-send-email-ville.syrjala@linux.intel.com Tested-by: Marius Vlad <marius.c.vlad@intel.com> Reviewed-by: Jani Nikula <jani.nikula@intel.com>
2016-04-18 20:34:04 +03:00
if (!pipe_config->has_dsi_encoder)
pipe_config->dpll_hw_state.dpll |= DPLL_VCO_ENABLE |
DPLL_EXT_BUFFER_ENABLE_VLV;
pipe_config->dpll_hw_state.dpll_md =
(pipe_config->pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT;
}
static void chv_compute_dpll(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config)
{
pipe_config->dpll_hw_state.dpll = DPLL_SSC_REF_CLK_CHV |
DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
if (crtc->pipe != PIPE_A)
pipe_config->dpll_hw_state.dpll |= DPLL_INTEGRATED_CRI_CLK_VLV;
/* DPLL not used with DSI, but still need the rest set up */
drm/i915: Fix oops in vlv_force_pll_on() intel_pipe_will_have_type() doesn't just look at the passied in pipe_config, instead it expects there to be a full atomic state behind it. Obviously that won't go so well when vlv_force_pll_on() just uses a temp pipe_config. Fix things by using pipe_config->has_dsi_encoder instead intel_pipe_will_have_type(INTEL_OUTPUT_DSI) to check if we need to actually enable the DPLL. Here's an example oops for reference: BUG: unable to handle kernel NULL pointer dereference at 0000000000000030 IP: [<ffffffffa0389a5b>] intel_pipe_will_have_type+0x15/0x7b [i915] PGD 7acda067 PUD 72696067 PMD 0 Oops: 0000 [#1] PREEMPT SMP Modules linked in: i915 i2c_algo_bit drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops drm intel_gtt agpgart netconsole psmouse atkbd iTCO_wdt libps2 coretemp hwmon efi_pstore intel_rapl punit_atom_debug efivars pcspkr i2c_i801 r8169 lpc_ich mii processor_thermal_device snd_soc_rt5670 intel_soc_dts_iosf snd_soc_rl6231 i2c_hid hid snd_intel_sst_acpi snd_intel_sst_core snd_soc_sst_mfld_platform snd_soc_sst_match snd_soc_core i8042 serio snd_compress snd_pcm snd_timer snd i2c_designware_platform sdhci_acpi i2c_designware_core soundcore sdhci pwm_lpss_platform mmc_core pwm_lpss spi_pxa2xx_platform evdev int3403_thermal int3400_thermal int340x_thermal_zone acpi_thermal_rel sch_fq_codel ip_tables x_tables ipv6 autofs4 CPU: 3 PID: 290 Comm: Xorg Tainted: G U 4.6.0-rc4-bsw+ #2876 Hardware name: Intel Corporation CHERRYVIEW C0 PLATFORM/Braswell CRB, BIOS BRAS.X64.X088.R00.1510270350 10/27/2015 task: ffff88007a8dd200 ti: ffff880173ac4000 task.ti: ffff880173ac4000 RIP: 0010:[<ffffffffa0389a5b>] [<ffffffffa0389a5b>] intel_pipe_will_have_type+0x15/0x7b [i915] RSP: 0018:ffff880173ac7928 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffff880176594000 RCX: 0000000000000000 RDX: 0000000000000000 RSI: 0000000000000009 RDI: ffff880176594000 RBP: ffff880173ac7930 R08: 0000000000019290 R09: 0000000000000000 R10: ffff880173ac7890 R11: 00000000000080cf R12: ffff88017fbd4000 R13: ffffffffa03e3c44 R14: ffff88007492c000 R15: ffff88007492c000 FS: 00007ff8936a6940(0000) GS:ffff88017ef80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000030 CR3: 0000000177e08000 CR4: 00000000001006e0 Stack: ffff880176594000 ffff880173ac7948 ffffffffa0389b42 ffff880176594000 ffff880173ac7978 ffffffffa0396e02 ffff8801765b0000 ffff88007af660d8 0000000000000000 0000000000000004 ffff880173ac79c0 ffffffffa03b6b64 Call Trace: [<ffffffffa0389b42>] chv_compute_dpll.isra.39+0x33/0x55 [i915] [<ffffffffa0396e02>] vlv_force_pll_on+0x80/0xc6 [i915] [<ffffffffa03b6b64>] vlv_power_sequencer_pipe+0x29b/0x3dd [i915] [<ffffffffa03b6cd4>] _pp_stat_reg+0x2e/0x38 [i915] [<ffffffffa03b6dc1>] wait_panel_status+0x4c/0x1ec [i915] [<ffffffffa03b6fcb>] wait_panel_power_cycle+0x6a/0xb4 [i915] [<ffffffffa03b70da>] edp_panel_vdd_on+0xc5/0x1d1 [i915] [<ffffffffa03b861b>] intel_dp_aux_ch+0x55/0x572 [i915] [<ffffffff810af5c8>] ? mark_held_locks+0x5d/0x74 [<ffffffff81518e61>] ? mutex_lock_nested+0x321/0x346 [<ffffffff81094007>] ? preempt_count_sub+0xf2/0x102 [<ffffffffa03b8cb4>] intel_dp_aux_transfer+0x17c/0x1b5 [i915] [<ffffffffa03028ef>] drm_dp_dpcd_access+0x62/0xed [drm_kms_helper] [<ffffffffa0302995>] drm_dp_dpcd_read+0x1b/0x1f [drm_kms_helper] [<ffffffffa03b5147>] intel_dp_dpcd_read_wake+0x31/0x69 [i915] [<ffffffffa03bb36a>] intel_dp_long_pulse+0x15f/0x5ed [i915] [<ffffffffa03bbb09>] intel_dp_detect+0x79/0x95 [i915] [<ffffffffa030340e>] drm_helper_probe_single_connector_modes+0xc7/0x3db [drm_kms_helper] [<ffffffffa029de23>] drm_mode_getconnector+0xe9/0x333 [drm] [<ffffffff810b1cfb>] ? lock_acquire+0x137/0x1df [<ffffffffa0292364>] drm_ioctl+0x266/0x3ae [drm] [<ffffffffa029dd3a>] ? drm_mode_getcrtc+0x126/0x126 [drm] [<ffffffff811af082>] vfs_ioctl+0x18/0x34 [<ffffffff811af682>] do_vfs_ioctl+0x547/0x5fe [<ffffffff811b9acb>] ? __fget_light+0x62/0x71 [<ffffffff811af77c>] SyS_ioctl+0x43/0x61 [<ffffffff81001a82>] do_syscall_64+0x63/0xf8 [<ffffffff8151bc9a>] entry_SYSCALL64_slow_path+0x25/0x25 Code: 35 00 40 a0 e8 97 4b ce e0 b8 17 00 00 00 5d c3 b8 17 00 00 00 c3 0f 1f 44 00 00 55 31 c0 31 d2 48 89 e5 53 48 8b 8f e8 01 00 00 <44> 8b 49 30 41 39 c1 7e 2d 4c 8b 51 38 4c 8b 41 40 49 83 3c c2 RIP [<ffffffffa0389a5b>] intel_pipe_will_have_type+0x15/0x7b [i915] RSP <ffff880173ac7928> CR2: 0000000000000030 The regressing patch wasn't exactly new (as in first posted more than six months ago), so I'm a bit baffled how I didn't manage to hit this myself so far. Cc: Jani Nikula <jani.nikula@intel.com> Cc: Marius Vlad <marius.c.vlad@intel.com> Reported-by: Marius Vlad <marius.c.vlad@intel.com> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94995 Fixes: cd2d34d9b61f ("drm/i915: Setup DPLL/DPLLMD for DSI too on VLV/CHV") Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1461000844-20543-1-git-send-email-ville.syrjala@linux.intel.com Tested-by: Marius Vlad <marius.c.vlad@intel.com> Reviewed-by: Jani Nikula <jani.nikula@intel.com>
2016-04-18 20:34:04 +03:00
if (!pipe_config->has_dsi_encoder)
pipe_config->dpll_hw_state.dpll |= DPLL_VCO_ENABLE;
pipe_config->dpll_hw_state.dpll_md =
(pipe_config->pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT;
}
static void vlv_prepare_pll(struct intel_crtc *crtc,
const struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
enum pipe pipe = crtc->pipe;
u32 mdiv;
u32 bestn, bestm1, bestm2, bestp1, bestp2;
u32 coreclk, reg_val;
/* Enable Refclk */
I915_WRITE(DPLL(pipe),
pipe_config->dpll_hw_state.dpll &
~(DPLL_VCO_ENABLE | DPLL_EXT_BUFFER_ENABLE_VLV));
/* No need to actually set up the DPLL with DSI */
if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
return;
mutex_lock(&dev_priv->sb_lock);
bestn = pipe_config->dpll.n;
bestm1 = pipe_config->dpll.m1;
bestm2 = pipe_config->dpll.m2;
bestp1 = pipe_config->dpll.p1;
bestp2 = pipe_config->dpll.p2;
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
/* See eDP HDMI DPIO driver vbios notes doc */
/* PLL B needs special handling */
if (pipe == PIPE_B)
vlv_pllb_recal_opamp(dev_priv, pipe);
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
/* Set up Tx target for periodic Rcomp update */
vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW9_BCAST, 0x0100000f);
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
/* Disable target IRef on PLL */
reg_val = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW8(pipe));
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
reg_val &= 0x00ffffff;
vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW8(pipe), reg_val);
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
/* Disable fast lock */
vlv_dpio_write(dev_priv, pipe, VLV_CMN_DW0, 0x610);
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
/* 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_K_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);
vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW3(pipe), mdiv);
mdiv |= DPIO_ENABLE_CALIBRATION;
vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW3(pipe), mdiv);
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
/* Set HBR and RBR LPF coefficients */
if (pipe_config->port_clock == 162000 ||
intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG) ||
intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI))
vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW10(pipe),
0x009f0003);
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
else
vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW10(pipe),
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
0x00d0000f);
if (pipe_config->has_dp_encoder) {
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
/* Use SSC source */
if (pipe == PIPE_A)
vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
0x0df40000);
else
vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
0x0df70000);
} else { /* HDMI or VGA */
/* Use bend source */
if (pipe == PIPE_A)
vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
0x0df70000);
else
vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
0x0df40000);
}
coreclk = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW7(pipe));
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
coreclk = (coreclk & 0x0000ff00) | 0x01c00000;
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) ||
intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
coreclk |= 0x01000000;
vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW7(pipe), coreclk);
vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW11(pipe), 0x87871000);
mutex_unlock(&dev_priv->sb_lock);
}
static void chv_prepare_pll(struct intel_crtc *crtc,
const struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
enum pipe pipe = crtc->pipe;
enum dpio_channel port = vlv_pipe_to_channel(pipe);
u32 loopfilter, tribuf_calcntr;
u32 bestn, bestm1, bestm2, bestp1, bestp2, bestm2_frac;
u32 dpio_val;
int vco;
/* Enable Refclk and SSC */
I915_WRITE(DPLL(pipe),
pipe_config->dpll_hw_state.dpll & ~DPLL_VCO_ENABLE);
/* No need to actually set up the DPLL with DSI */
if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
return;
bestn = pipe_config->dpll.n;
bestm2_frac = pipe_config->dpll.m2 & 0x3fffff;
bestm1 = pipe_config->dpll.m1;
bestm2 = pipe_config->dpll.m2 >> 22;
bestp1 = pipe_config->dpll.p1;
bestp2 = pipe_config->dpll.p2;
vco = pipe_config->dpll.vco;
dpio_val = 0;
loopfilter = 0;
mutex_lock(&dev_priv->sb_lock);
/* p1 and p2 divider */
vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW13(port),
5 << DPIO_CHV_S1_DIV_SHIFT |
bestp1 << DPIO_CHV_P1_DIV_SHIFT |
bestp2 << DPIO_CHV_P2_DIV_SHIFT |
1 << DPIO_CHV_K_DIV_SHIFT);
/* Feedback post-divider - m2 */
vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW0(port), bestm2);
/* Feedback refclk divider - n and m1 */
vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW1(port),
DPIO_CHV_M1_DIV_BY_2 |
1 << DPIO_CHV_N_DIV_SHIFT);
/* M2 fraction division */
vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW2(port), bestm2_frac);
/* M2 fraction division enable */
dpio_val = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW3(port));
dpio_val &= ~(DPIO_CHV_FEEDFWD_GAIN_MASK | DPIO_CHV_FRAC_DIV_EN);
dpio_val |= (2 << DPIO_CHV_FEEDFWD_GAIN_SHIFT);
if (bestm2_frac)
dpio_val |= DPIO_CHV_FRAC_DIV_EN;
vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW3(port), dpio_val);
/* Program digital lock detect threshold */
dpio_val = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW9(port));
dpio_val &= ~(DPIO_CHV_INT_LOCK_THRESHOLD_MASK |
DPIO_CHV_INT_LOCK_THRESHOLD_SEL_COARSE);
dpio_val |= (0x5 << DPIO_CHV_INT_LOCK_THRESHOLD_SHIFT);
if (!bestm2_frac)
dpio_val |= DPIO_CHV_INT_LOCK_THRESHOLD_SEL_COARSE;
vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW9(port), dpio_val);
/* Loop filter */
if (vco == 5400000) {
loopfilter |= (0x3 << DPIO_CHV_PROP_COEFF_SHIFT);
loopfilter |= (0x8 << DPIO_CHV_INT_COEFF_SHIFT);
loopfilter |= (0x1 << DPIO_CHV_GAIN_CTRL_SHIFT);
tribuf_calcntr = 0x9;
} else if (vco <= 6200000) {
loopfilter |= (0x5 << DPIO_CHV_PROP_COEFF_SHIFT);
loopfilter |= (0xB << DPIO_CHV_INT_COEFF_SHIFT);
loopfilter |= (0x3 << DPIO_CHV_GAIN_CTRL_SHIFT);
tribuf_calcntr = 0x9;
} else if (vco <= 6480000) {
loopfilter |= (0x4 << DPIO_CHV_PROP_COEFF_SHIFT);
loopfilter |= (0x9 << DPIO_CHV_INT_COEFF_SHIFT);
loopfilter |= (0x3 << DPIO_CHV_GAIN_CTRL_SHIFT);
tribuf_calcntr = 0x8;
} else {
/* Not supported. Apply the same limits as in the max case */
loopfilter |= (0x4 << DPIO_CHV_PROP_COEFF_SHIFT);
loopfilter |= (0x9 << DPIO_CHV_INT_COEFF_SHIFT);
loopfilter |= (0x3 << DPIO_CHV_GAIN_CTRL_SHIFT);
tribuf_calcntr = 0;
}
vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW6(port), loopfilter);
dpio_val = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW8(port));
dpio_val &= ~DPIO_CHV_TDC_TARGET_CNT_MASK;
dpio_val |= (tribuf_calcntr << DPIO_CHV_TDC_TARGET_CNT_SHIFT);
vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW8(port), dpio_val);
/* AFC Recal */
vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port),
vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port)) |
DPIO_AFC_RECAL);
mutex_unlock(&dev_priv->sb_lock);
}
/**
* vlv_force_pll_on - forcibly enable just the PLL
* @dev_priv: i915 private structure
* @pipe: pipe PLL to enable
* @dpll: PLL configuration
*
* Enable the PLL for @pipe using the supplied @dpll config. To be used
* in cases where we need the PLL enabled even when @pipe is not going to
* be enabled.
*/
int vlv_force_pll_on(struct drm_device *dev, enum pipe pipe,
const struct dpll *dpll)
{
struct intel_crtc *crtc =
to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe));
struct intel_crtc_state *pipe_config;
pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
if (!pipe_config)
return -ENOMEM;
pipe_config->base.crtc = &crtc->base;
pipe_config->pixel_multiplier = 1;
pipe_config->dpll = *dpll;
if (IS_CHERRYVIEW(dev)) {
chv_compute_dpll(crtc, pipe_config);
chv_prepare_pll(crtc, pipe_config);
chv_enable_pll(crtc, pipe_config);
} else {
vlv_compute_dpll(crtc, pipe_config);
vlv_prepare_pll(crtc, pipe_config);
vlv_enable_pll(crtc, pipe_config);
}
kfree(pipe_config);
return 0;
}
/**
* vlv_force_pll_off - forcibly disable just the PLL
* @dev_priv: i915 private structure
* @pipe: pipe PLL to disable
*
* Disable the PLL for @pipe. To be used in cases where we need
* the PLL enabled even when @pipe is not going to be enabled.
*/
void vlv_force_pll_off(struct drm_device *dev, enum pipe pipe)
{
if (IS_CHERRYVIEW(dev))
chv_disable_pll(to_i915(dev), pipe);
else
vlv_disable_pll(to_i915(dev), pipe);
}
static void i9xx_compute_dpll(struct intel_crtc *crtc,
struct intel_crtc_state *crtc_state,
struct dpll *reduced_clock)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 dpll;
bool is_sdvo;
struct dpll *clock = &crtc_state->dpll;
i9xx_update_pll_dividers(crtc, crtc_state, reduced_clock);
is_sdvo = intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_SDVO) ||
intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_HDMI);
dpll = DPLL_VGA_MODE_DIS;
if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS))
dpll |= DPLLB_MODE_LVDS;
else
dpll |= DPLLB_MODE_DAC_SERIAL;
if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) {
dpll |= (crtc_state->pixel_multiplier - 1)
<< SDVO_MULTIPLIER_SHIFT_HIRES;
}
if (is_sdvo)
dpll |= DPLL_SDVO_HIGH_SPEED;
if (crtc_state->has_dp_encoder)
dpll |= DPLL_SDVO_HIGH_SPEED;
/* compute bitmask from p1 value */
if (IS_PINEVIEW(dev))
dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW;
else {
dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
if (IS_G4X(dev) && reduced_clock)
dpll |= (1 << (reduced_clock->p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
}
switch (clock->p2) {
case 5:
dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
break;
case 7:
dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
break;
case 10:
dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
break;
case 14:
dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
break;
}
if (INTEL_INFO(dev)->gen >= 4)
dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
if (crtc_state->sdvo_tv_clock)
dpll |= PLL_REF_INPUT_TVCLKINBC;
else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) &&
intel_panel_use_ssc(dev_priv))
dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
else
dpll |= PLL_REF_INPUT_DREFCLK;
dpll |= DPLL_VCO_ENABLE;
crtc_state->dpll_hw_state.dpll = dpll;
if (INTEL_INFO(dev)->gen >= 4) {
u32 dpll_md = (crtc_state->pixel_multiplier - 1)
<< DPLL_MD_UDI_MULTIPLIER_SHIFT;
crtc_state->dpll_hw_state.dpll_md = dpll_md;
}
}
static void i8xx_compute_dpll(struct intel_crtc *crtc,
struct intel_crtc_state *crtc_state,
struct dpll *reduced_clock)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 dpll;
struct dpll *clock = &crtc_state->dpll;
i9xx_update_pll_dividers(crtc, crtc_state, reduced_clock);
dpll = DPLL_VGA_MODE_DIS;
if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
} else {
if (clock->p1 == 2)
dpll |= PLL_P1_DIVIDE_BY_TWO;
else
dpll |= (clock->p1 - 2) << DPLL_FPA01_P1_POST_DIV_SHIFT;
if (clock->p2 == 4)
dpll |= PLL_P2_DIVIDE_BY_4;
}
if (!IS_I830(dev) && intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_DVO))
dpll |= DPLL_DVO_2X_MODE;
if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) &&
intel_panel_use_ssc(dev_priv))
dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
else
dpll |= PLL_REF_INPUT_DREFCLK;
dpll |= DPLL_VCO_ENABLE;
crtc_state->dpll_hw_state.dpll = dpll;
}
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;
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
const struct drm_display_mode *adjusted_mode = &intel_crtc->config->base.adjusted_mode;
uint32_t crtc_vtotal, crtc_vblank_end;
int vsyncshift = 0;
/* 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 (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
/* the chip adds 2 halflines automatically */
crtc_vtotal -= 1;
crtc_vblank_end -= 1;
if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_SDVO))
vsyncshift = (adjusted_mode->crtc_htotal - 1) / 2;
else
vsyncshift = adjusted_mode->crtc_hsync_start -
adjusted_mode->crtc_htotal / 2;
if (vsyncshift < 0)
vsyncshift += adjusted_mode->crtc_htotal;
}
if (INTEL_INFO(dev)->gen > 3)
I915_WRITE(VSYNCSHIFT(cpu_transcoder), vsyncshift);
I915_WRITE(HTOTAL(cpu_transcoder),
(adjusted_mode->crtc_hdisplay - 1) |
((adjusted_mode->crtc_htotal - 1) << 16));
I915_WRITE(HBLANK(cpu_transcoder),
(adjusted_mode->crtc_hblank_start - 1) |
((adjusted_mode->crtc_hblank_end - 1) << 16));
I915_WRITE(HSYNC(cpu_transcoder),
(adjusted_mode->crtc_hsync_start - 1) |
((adjusted_mode->crtc_hsync_end - 1) << 16));
I915_WRITE(VTOTAL(cpu_transcoder),
(adjusted_mode->crtc_vdisplay - 1) |
((crtc_vtotal - 1) << 16));
I915_WRITE(VBLANK(cpu_transcoder),
(adjusted_mode->crtc_vblank_start - 1) |
((crtc_vblank_end - 1) << 16));
I915_WRITE(VSYNC(cpu_transcoder),
(adjusted_mode->crtc_vsync_start - 1) |
((adjusted_mode->crtc_vsync_end - 1) << 16));
/* Workaround: when the EDP input selection is B, the VTOTAL_B must be
* programmed with the VTOTAL_EDP value. Same for VTOTAL_C. This is
* documented on the DDI_FUNC_CTL register description, EDP Input Select
* bits. */
if (IS_HASWELL(dev) && cpu_transcoder == TRANSCODER_EDP &&
(pipe == PIPE_B || pipe == PIPE_C))
I915_WRITE(VTOTAL(pipe), I915_READ(VTOTAL(cpu_transcoder)));
}
static void intel_set_pipe_src_size(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;
/* pipesrc controls the size that is scaled from, which should
* always be the user's requested size.
*/
I915_WRITE(PIPESRC(pipe),
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
((intel_crtc->config->pipe_src_w - 1) << 16) |
(intel_crtc->config->pipe_src_h - 1));
}
static void intel_get_pipe_timings(struct intel_crtc *crtc,
struct intel_crtc_state *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->base.adjusted_mode.crtc_hdisplay = (tmp & 0xffff) + 1;
pipe_config->base.adjusted_mode.crtc_htotal = ((tmp >> 16) & 0xffff) + 1;
tmp = I915_READ(HBLANK(cpu_transcoder));
pipe_config->base.adjusted_mode.crtc_hblank_start = (tmp & 0xffff) + 1;
pipe_config->base.adjusted_mode.crtc_hblank_end = ((tmp >> 16) & 0xffff) + 1;
tmp = I915_READ(HSYNC(cpu_transcoder));
pipe_config->base.adjusted_mode.crtc_hsync_start = (tmp & 0xffff) + 1;
pipe_config->base.adjusted_mode.crtc_hsync_end = ((tmp >> 16) & 0xffff) + 1;
tmp = I915_READ(VTOTAL(cpu_transcoder));
pipe_config->base.adjusted_mode.crtc_vdisplay = (tmp & 0xffff) + 1;
pipe_config->base.adjusted_mode.crtc_vtotal = ((tmp >> 16) & 0xffff) + 1;
tmp = I915_READ(VBLANK(cpu_transcoder));
pipe_config->base.adjusted_mode.crtc_vblank_start = (tmp & 0xffff) + 1;
pipe_config->base.adjusted_mode.crtc_vblank_end = ((tmp >> 16) & 0xffff) + 1;
tmp = I915_READ(VSYNC(cpu_transcoder));
pipe_config->base.adjusted_mode.crtc_vsync_start = (tmp & 0xffff) + 1;
pipe_config->base.adjusted_mode.crtc_vsync_end = ((tmp >> 16) & 0xffff) + 1;
if (I915_READ(PIPECONF(cpu_transcoder)) & PIPECONF_INTERLACE_MASK) {
pipe_config->base.adjusted_mode.flags |= DRM_MODE_FLAG_INTERLACE;
pipe_config->base.adjusted_mode.crtc_vtotal += 1;
pipe_config->base.adjusted_mode.crtc_vblank_end += 1;
}
}
static void intel_get_pipe_src_size(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 tmp;
tmp = I915_READ(PIPESRC(crtc->pipe));
pipe_config->pipe_src_h = (tmp & 0xffff) + 1;
pipe_config->pipe_src_w = ((tmp >> 16) & 0xffff) + 1;
pipe_config->base.mode.vdisplay = pipe_config->pipe_src_h;
pipe_config->base.mode.hdisplay = pipe_config->pipe_src_w;
}
void intel_mode_from_pipe_config(struct drm_display_mode *mode,
struct intel_crtc_state *pipe_config)
{
mode->hdisplay = pipe_config->base.adjusted_mode.crtc_hdisplay;
mode->htotal = pipe_config->base.adjusted_mode.crtc_htotal;
mode->hsync_start = pipe_config->base.adjusted_mode.crtc_hsync_start;
mode->hsync_end = pipe_config->base.adjusted_mode.crtc_hsync_end;
mode->vdisplay = pipe_config->base.adjusted_mode.crtc_vdisplay;
mode->vtotal = pipe_config->base.adjusted_mode.crtc_vtotal;
mode->vsync_start = pipe_config->base.adjusted_mode.crtc_vsync_start;
mode->vsync_end = pipe_config->base.adjusted_mode.crtc_vsync_end;
mode->flags = pipe_config->base.adjusted_mode.flags;
mode->type = DRM_MODE_TYPE_DRIVER;
mode->clock = pipe_config->base.adjusted_mode.crtc_clock;
mode->flags |= pipe_config->base.adjusted_mode.flags;
mode->hsync = drm_mode_hsync(mode);
mode->vrefresh = drm_mode_vrefresh(mode);
drm_mode_set_name(mode);
}
static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
{
struct drm_device *dev = intel_crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t pipeconf;
pipeconf = 0;
if ((intel_crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
(intel_crtc->pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
pipeconf |= I915_READ(PIPECONF(intel_crtc->pipe)) & PIPECONF_ENABLE;
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (intel_crtc->config->double_wide)
pipeconf |= PIPECONF_DOUBLE_WIDE;
drm/i915: implement high-bpc + pipeconf-dither support for g4x/vlv 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ä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-04-24 14:57:17 +02:00
/* only g4x and later have fancy bpc/dither controls */
if (IS_G4X(dev) || IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
drm/i915: implement high-bpc + pipeconf-dither support for g4x/vlv 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ä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-04-24 14:57:17 +02:00
/* Bspec claims that we can't use dithering for 30bpp pipes. */
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (intel_crtc->config->dither && intel_crtc->config->pipe_bpp != 30)
drm/i915: implement high-bpc + pipeconf-dither support for g4x/vlv 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ä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-04-24 14:57:17 +02:00
pipeconf |= PIPECONF_DITHER_EN |
PIPECONF_DITHER_TYPE_SP;
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
switch (intel_crtc->config->pipe_bpp) {
drm/i915: implement high-bpc + pipeconf-dither support for g4x/vlv 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ä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-04-24 14:57:17 +02:00
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();
}
}
if (HAS_PIPE_CXSR(dev)) {
if (intel_crtc->lowfreq_avail) {
DRM_DEBUG_KMS("enabling CxSR downclocking\n");
pipeconf |= PIPECONF_CXSR_DOWNCLOCK;
} else {
DRM_DEBUG_KMS("disabling CxSR downclocking\n");
}
}
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
if (INTEL_INFO(dev)->gen < 4 ||
intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_SDVO))
pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
else
pipeconf |= PIPECONF_INTERLACE_W_SYNC_SHIFT;
} else
pipeconf |= PIPECONF_PROGRESSIVE;
if ((IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(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));
}
static int i8xx_crtc_compute_clock(struct intel_crtc *crtc,
struct intel_crtc_state *crtc_state)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
const struct intel_limit *limit;
int refclk = 48000;
memset(&crtc_state->dpll_hw_state, 0,
sizeof(crtc_state->dpll_hw_state));
if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
if (intel_panel_use_ssc(dev_priv)) {
refclk = dev_priv->vbt.lvds_ssc_freq;
DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk);
}
limit = &intel_limits_i8xx_lvds;
} else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_DVO)) {
limit = &intel_limits_i8xx_dvo;
} else {
limit = &intel_limits_i8xx_dac;
}
if (!crtc_state->clock_set &&
!i9xx_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
refclk, NULL, &crtc_state->dpll)) {
DRM_ERROR("Couldn't find PLL settings for mode!\n");
return -EINVAL;
}
i8xx_compute_dpll(crtc, crtc_state, NULL);
return 0;
}
static int g4x_crtc_compute_clock(struct intel_crtc *crtc,
struct intel_crtc_state *crtc_state)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
const struct intel_limit *limit;
int refclk = 96000;
memset(&crtc_state->dpll_hw_state, 0,
sizeof(crtc_state->dpll_hw_state));
if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
if (intel_panel_use_ssc(dev_priv)) {
refclk = dev_priv->vbt.lvds_ssc_freq;
DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk);
}
if (intel_is_dual_link_lvds(dev))
limit = &intel_limits_g4x_dual_channel_lvds;
else
limit = &intel_limits_g4x_single_channel_lvds;
} else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_HDMI) ||
intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_ANALOG)) {
limit = &intel_limits_g4x_hdmi;
} else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_SDVO)) {
limit = &intel_limits_g4x_sdvo;
} else {
/* The option is for other outputs */
limit = &intel_limits_i9xx_sdvo;
}
if (!crtc_state->clock_set &&
!g4x_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
refclk, NULL, &crtc_state->dpll)) {
DRM_ERROR("Couldn't find PLL settings for mode!\n");
return -EINVAL;
}
i9xx_compute_dpll(crtc, crtc_state, NULL);
return 0;
}
static int pnv_crtc_compute_clock(struct intel_crtc *crtc,
struct intel_crtc_state *crtc_state)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
const struct intel_limit *limit;
int refclk = 96000;
memset(&crtc_state->dpll_hw_state, 0,
sizeof(crtc_state->dpll_hw_state));
if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
if (intel_panel_use_ssc(dev_priv)) {
refclk = dev_priv->vbt.lvds_ssc_freq;
DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk);
}
limit = &intel_limits_pineview_lvds;
} else {
limit = &intel_limits_pineview_sdvo;
}
if (!crtc_state->clock_set &&
!pnv_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
refclk, NULL, &crtc_state->dpll)) {
DRM_ERROR("Couldn't find PLL settings for mode!\n");
return -EINVAL;
}
i9xx_compute_dpll(crtc, crtc_state, NULL);
return 0;
}
static int i9xx_crtc_compute_clock(struct intel_crtc *crtc,
struct intel_crtc_state *crtc_state)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
const struct intel_limit *limit;
int refclk = 96000;
memset(&crtc_state->dpll_hw_state, 0,
sizeof(crtc_state->dpll_hw_state));
if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
if (intel_panel_use_ssc(dev_priv)) {
refclk = dev_priv->vbt.lvds_ssc_freq;
DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk);
}
limit = &intel_limits_i9xx_lvds;
} else {
limit = &intel_limits_i9xx_sdvo;
}
if (!crtc_state->clock_set &&
!i9xx_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
refclk, NULL, &crtc_state->dpll)) {
DRM_ERROR("Couldn't find PLL settings for mode!\n");
return -EINVAL;
}
i9xx_compute_dpll(crtc, crtc_state, NULL);
return 0;
}
static int chv_crtc_compute_clock(struct intel_crtc *crtc,
struct intel_crtc_state *crtc_state)
{
int refclk = 100000;
const struct intel_limit *limit = &intel_limits_chv;
memset(&crtc_state->dpll_hw_state, 0,
sizeof(crtc_state->dpll_hw_state));
if (!crtc_state->clock_set &&
!chv_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
refclk, NULL, &crtc_state->dpll)) {
DRM_ERROR("Couldn't find PLL settings for mode!\n");
return -EINVAL;
}
chv_compute_dpll(crtc, crtc_state);
return 0;
}
static int vlv_crtc_compute_clock(struct intel_crtc *crtc,
struct intel_crtc_state *crtc_state)
{
int refclk = 100000;
const struct intel_limit *limit = &intel_limits_vlv;
memset(&crtc_state->dpll_hw_state, 0,
sizeof(crtc_state->dpll_hw_state));
if (!crtc_state->clock_set &&
!vlv_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
refclk, NULL, &crtc_state->dpll)) {
DRM_ERROR("Couldn't find PLL settings for mode!\n");
return -EINVAL;
}
vlv_compute_dpll(crtc, crtc_state);
return 0;
}
static void i9xx_get_pfit_config(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t tmp;
if (INTEL_INFO(dev)->gen <= 3 && (IS_I830(dev) || !IS_MOBILE(dev)))
return;
tmp = I915_READ(PFIT_CONTROL);
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 <Knut_Petersen@t-online.de> Cc: Knut Petersen <Knut_Petersen@t-online.de> Cc: Chris Wilson <chris@chris-wilson.co.uk> References: http://lists.freedesktop.org/archives/intel-gfx/2013-July/030092.html Tested-by: Knut Petersen <Knut_Petersen@t-online.de> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-07-11 13:35:40 +02:00
if (!(tmp & PFIT_ENABLE))
return;
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 <Knut_Petersen@t-online.de> Cc: Knut Petersen <Knut_Petersen@t-online.de> Cc: Chris Wilson <chris@chris-wilson.co.uk> References: http://lists.freedesktop.org/archives/intel-gfx/2013-July/030092.html Tested-by: Knut Petersen <Knut_Petersen@t-online.de> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-07-11 13:35:40 +02:00
/* Check whether the pfit is attached to our pipe. */
if (INTEL_INFO(dev)->gen < 4) {
if (crtc->pipe != PIPE_B)
return;
} else {
if ((tmp & PFIT_PIPE_MASK) != (crtc->pipe << PFIT_PIPE_SHIFT))
return;
}
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 <Knut_Petersen@t-online.de> Cc: Knut Petersen <Knut_Petersen@t-online.de> Cc: Chris Wilson <chris@chris-wilson.co.uk> References: http://lists.freedesktop.org/archives/intel-gfx/2013-July/030092.html Tested-by: Knut Petersen <Knut_Petersen@t-online.de> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-07-11 13:35:40 +02:00
pipe_config->gmch_pfit.control = tmp;
pipe_config->gmch_pfit.pgm_ratios = I915_READ(PFIT_PGM_RATIOS);
}
static void vlv_crtc_clock_get(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
int pipe = pipe_config->cpu_transcoder;
struct dpll clock;
u32 mdiv;
int refclk = 100000;
/* In case of DSI, DPLL will not be used */
if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
return;
mutex_lock(&dev_priv->sb_lock);
mdiv = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW3(pipe));
mutex_unlock(&dev_priv->sb_lock);
clock.m1 = (mdiv >> DPIO_M1DIV_SHIFT) & 7;
clock.m2 = mdiv & DPIO_M2DIV_MASK;
clock.n = (mdiv >> DPIO_N_SHIFT) & 0xf;
clock.p1 = (mdiv >> DPIO_P1_SHIFT) & 7;
clock.p2 = (mdiv >> DPIO_P2_SHIFT) & 0x1f;
pipe_config->port_clock = vlv_calc_dpll_params(refclk, &clock);
}
static void
i9xx_get_initial_plane_config(struct intel_crtc *crtc,
struct intel_initial_plane_config *plane_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 val, base, offset;
int pipe = crtc->pipe, plane = crtc->plane;
int fourcc, pixel_format;
unsigned int aligned_height;
struct drm_framebuffer *fb;
struct intel_framebuffer *intel_fb;
val = I915_READ(DSPCNTR(plane));
if (!(val & DISPLAY_PLANE_ENABLE))
return;
intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
if (!intel_fb) {
DRM_DEBUG_KMS("failed to alloc fb\n");
return;
}
fb = &intel_fb->base;
if (INTEL_INFO(dev)->gen >= 4) {
if (val & DISPPLANE_TILED) {
plane_config->tiling = I915_TILING_X;
fb->modifier[0] = I915_FORMAT_MOD_X_TILED;
}
}
pixel_format = val & DISPPLANE_PIXFORMAT_MASK;
fourcc = i9xx_format_to_fourcc(pixel_format);
fb->pixel_format = fourcc;
fb->bits_per_pixel = drm_format_plane_cpp(fourcc, 0) * 8;
if (INTEL_INFO(dev)->gen >= 4) {
if (plane_config->tiling)
offset = I915_READ(DSPTILEOFF(plane));
else
offset = I915_READ(DSPLINOFF(plane));
base = I915_READ(DSPSURF(plane)) & 0xfffff000;
} else {
base = I915_READ(DSPADDR(plane));
}
plane_config->base = base;
val = I915_READ(PIPESRC(pipe));
fb->width = ((val >> 16) & 0xfff) + 1;
fb->height = ((val >> 0) & 0xfff) + 1;
val = I915_READ(DSPSTRIDE(pipe));
fb->pitches[0] = val & 0xffffffc0;
aligned_height = intel_fb_align_height(dev, fb->height,
fb->pixel_format,
fb->modifier[0]);
plane_config->size = fb->pitches[0] * aligned_height;
DRM_DEBUG_KMS("pipe/plane %c/%d with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
pipe_name(pipe), plane, fb->width, fb->height,
fb->bits_per_pixel, base, fb->pitches[0],
plane_config->size);
plane_config->fb = intel_fb;
}
static void chv_crtc_clock_get(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
int pipe = pipe_config->cpu_transcoder;
enum dpio_channel port = vlv_pipe_to_channel(pipe);
struct dpll clock;
u32 cmn_dw13, pll_dw0, pll_dw1, pll_dw2, pll_dw3;
int refclk = 100000;
/* In case of DSI, DPLL will not be used */
if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
return;
mutex_lock(&dev_priv->sb_lock);
cmn_dw13 = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW13(port));
pll_dw0 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW0(port));
pll_dw1 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW1(port));
pll_dw2 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW2(port));
pll_dw3 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW3(port));
mutex_unlock(&dev_priv->sb_lock);
clock.m1 = (pll_dw1 & 0x7) == DPIO_CHV_M1_DIV_BY_2 ? 2 : 0;
clock.m2 = (pll_dw0 & 0xff) << 22;
if (pll_dw3 & DPIO_CHV_FRAC_DIV_EN)
clock.m2 |= pll_dw2 & 0x3fffff;
clock.n = (pll_dw1 >> DPIO_CHV_N_DIV_SHIFT) & 0xf;
clock.p1 = (cmn_dw13 >> DPIO_CHV_P1_DIV_SHIFT) & 0x7;
clock.p2 = (cmn_dw13 >> DPIO_CHV_P2_DIV_SHIFT) & 0x1f;
pipe_config->port_clock = chv_calc_dpll_params(refclk, &clock);
}
static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
enum intel_display_power_domain power_domain;
uint32_t tmp;
bool ret;
power_domain = POWER_DOMAIN_PIPE(crtc->pipe);
if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
return false;
pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
pipe_config->shared_dpll = NULL;
ret = false;
tmp = I915_READ(PIPECONF(crtc->pipe));
if (!(tmp & PIPECONF_ENABLE))
goto out;
if (IS_G4X(dev) || IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
switch (tmp & PIPECONF_BPC_MASK) {
case PIPECONF_6BPC:
pipe_config->pipe_bpp = 18;
break;
case PIPECONF_8BPC:
pipe_config->pipe_bpp = 24;
break;
case PIPECONF_10BPC:
pipe_config->pipe_bpp = 30;
break;
default:
break;
}
}
if ((IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) &&
(tmp & PIPECONF_COLOR_RANGE_SELECT))
pipe_config->limited_color_range = true;
if (INTEL_INFO(dev)->gen < 4)
pipe_config->double_wide = tmp & PIPECONF_DOUBLE_WIDE;
intel_get_pipe_timings(crtc, pipe_config);
intel_get_pipe_src_size(crtc, pipe_config);
i9xx_get_pfit_config(crtc, pipe_config);
if (INTEL_INFO(dev)->gen >= 4) {
drm/i915: Implement WaPixelRepeatModeFixForC0:chv DPLL_MD(PIPE_C) is AWOL on CHV. Instead of fixing it someone added chicken bits to propagate the pixel multiplier from DPLL_MD(PIPE_B) to either pipe B or C. So do that to make pixel repeat work on pipes B and C. Pipe A is fine without any tricks. Fortunately the pixel repeat propagation appears to be a oneshot operation, so once the value has been written we can clear the chicken bits. So it is still possible to drive pipe B and C with different pixel multipliers simultaneosly. Looks like DPLL_VGA_MODE_DIS must also be set in DPLL(PIPE_B) for this to work. But since we keep that bit always set in all DPLLs there's no problem. This of course means we can't reliably read out the pixel multiplier for pipes B and C. That would make the state checker unhappy, so I added shadow copies of those registers in to dev_priv. The other option would have been to skip pixel multiplier, dpll_md an dotclock checks entirely on CHV, but that feels like a serious loss of cross checking, so just pretending that we have working DPLL MD registers seemed better. Obviously with the shadow copies we can't detect if the pixel multiplier was properly configured, nor can we take over its state from the BIOS, but hopefully people won't have displays that would be limitd to such crappy modes. There is one strange flicker still remaining. It's visible on pipe C/HDMID when HDMIB is enabled while driven by pipe B. It doesn't occur if pipe A drives HDMIB, nor is there any glitch on pipe B/HDMIB when port C/HDMID starts up. I don't have a board with HDMIC so not sure if it happens there too. So I'm not sure if it's somehow tied in with this strange linkage between pipe B and C. Sadly I was unable to find an enable sequence that would avoid the glitch, but at least it's not fatal ie. the output recovers afterwards. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1458052809-23426-4-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula <jani.nikula@intel.com>
2016-03-15 16:39:56 +02:00
/* No way to read it out on pipes B and C */
if (IS_CHERRYVIEW(dev) && crtc->pipe != PIPE_A)
tmp = dev_priv->chv_dpll_md[crtc->pipe];
else
tmp = I915_READ(DPLL_MD(crtc->pipe));
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 =
((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;
}
pipe_config->dpll_hw_state.dpll = I915_READ(DPLL(crtc->pipe));
if (!IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev)) {
/*
* DPLL_DVO_2X_MODE must be enabled for both DPLLs
* on 830. Filter it out here so that we don't
* report errors due to that.
*/
if (IS_I830(dev))
pipe_config->dpll_hw_state.dpll &= ~DPLL_DVO_2X_MODE;
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);
}
if (IS_CHERRYVIEW(dev))
chv_crtc_clock_get(crtc, pipe_config);
else if (IS_VALLEYVIEW(dev))
vlv_crtc_clock_get(crtc, pipe_config);
else
i9xx_crtc_clock_get(crtc, pipe_config);
/*
* Normally the dotclock is filled in by the encoder .get_config()
* but in case the pipe is enabled w/o any ports we need a sane
* default.
*/
pipe_config->base.adjusted_mode.crtc_clock =
pipe_config->port_clock / pipe_config->pixel_multiplier;
ret = true;
out:
intel_display_power_put(dev_priv, power_domain);
return ret;
}
static void ironlake_init_pch_refclk(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_encoder *encoder;
drm/i915/ilk: Don't disable SSC source if it's in use Thanks to Ville Syrjälä for pointing me towards the cause of this issue. Unfortunately one of the sideaffects of having the refclk for a DPLL set to SSC is that as long as it's set to SSC, the GPU will prevent us from powering down any of the pipes or transcoders using it. A couple of BIOSes enable SSC in both PCH_DREF_CONTROL and in the DPLL configurations. This causes issues on the first modeset, since we don't expect SSC to be left on and as a result, can't successfully power down the pipes or the transcoders using it. Here's an example from this Dell OptiPlex 990: [drm:intel_modeset_init] SSC enabled by BIOS, overriding VBT which says disabled [drm:intel_modeset_init] 2 display pipes available. [drm:intel_update_cdclk] Current CD clock rate: 400000 kHz [drm:intel_update_max_cdclk] Max CD clock rate: 400000 kHz [drm:intel_update_max_cdclk] Max dotclock rate: 360000 kHz vgaarb: device changed decodes: PCI:0000:00:02.0,olddecodes=io+mem,decodes=io+mem:owns=io+mem [drm:intel_crt_reset] crt adpa set to 0xf40000 [drm:intel_dp_init_connector] Adding DP connector on port C [drm:intel_dp_aux_init] registering DPDDC-C bus for card0-DP-1 [drm:ironlake_init_pch_refclk] has_panel 0 has_lvds 0 has_ck505 0 [drm:ironlake_init_pch_refclk] Disabling SSC entirely … later we try committing the first modeset … [drm:intel_dump_pipe_config] [CRTC:26][modeset] config ffff88041b02e800 for pipe A [drm:intel_dump_pipe_config] cpu_transcoder: A … [drm:intel_dump_pipe_config] dpll_hw_state: dpll: 0xc4016001, dpll_md: 0x0, fp0: 0x20e08, fp1: 0x30d07 [drm:intel_dump_pipe_config] planes on this crtc [drm:intel_dump_pipe_config] STANDARD PLANE:23 plane: 0.0 idx: 0 enabled [drm:intel_dump_pipe_config] FB:42, fb = 800x600 format = 0x34325258 [drm:intel_dump_pipe_config] scaler:0 src (0, 0) 800x600 dst (0, 0) 800x600 [drm:intel_dump_pipe_config] CURSOR PLANE:25 plane: 0.1 idx: 1 disabled, scaler_id = 0 [drm:intel_dump_pipe_config] STANDARD PLANE:27 plane: 0.1 idx: 2 disabled, scaler_id = 0 [drm:intel_get_shared_dpll] CRTC:26 allocated PCH DPLL A [drm:intel_get_shared_dpll] using PCH DPLL A for pipe A [drm:ilk_audio_codec_disable] Disable audio codec on port C, pipe A [drm:intel_disable_pipe] disabling pipe A ------------[ cut here ]------------ WARNING: CPU: 1 PID: 130 at drivers/gpu/drm/i915/intel_display.c:1146 intel_disable_pipe+0x297/0x2d0 [i915] pipe_off wait timed out … ---[ end trace 94fc8aa03ae139e8 ]--- [drm:intel_dp_link_down] [drm:ironlake_crtc_disable [i915]] *ERROR* failed to disable transcoder A Later modesets succeed since they reset the DPLL's configuration anyway, but this is enough to get stuck with a big fat warning in dmesg. A better solution would be to add refcounts for the SSC source, but for now leaving the source clock on should suffice. Changes since v4: - Fix calculation of final for systems with LVDS panels (fixes BUG() on CI test suite) Changes since v3: - Move temp variable into loop - Move checks for using_ssc_source to after we've figured out has_ck505 - Add using_ssc_source to debug output Changes since v2: - Fix debug output for when we disable the CPU source Changes since v1: - Leave the SSC source clock on instead of just shutting it off on all of the DPLL configurations. Cc: stable@vger.kernel.org Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Lyude <cpaul@redhat.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/1465916649-10228-1-git-send-email-cpaul@redhat.com
2016-06-14 11:04:09 -04:00
int i;
u32 val, final;
bool has_lvds = false;
bool has_cpu_edp = false;
bool has_panel = false;
bool has_ck505 = false;
bool can_ssc = false;
drm/i915/ilk: Don't disable SSC source if it's in use Thanks to Ville Syrjälä for pointing me towards the cause of this issue. Unfortunately one of the sideaffects of having the refclk for a DPLL set to SSC is that as long as it's set to SSC, the GPU will prevent us from powering down any of the pipes or transcoders using it. A couple of BIOSes enable SSC in both PCH_DREF_CONTROL and in the DPLL configurations. This causes issues on the first modeset, since we don't expect SSC to be left on and as a result, can't successfully power down the pipes or the transcoders using it. Here's an example from this Dell OptiPlex 990: [drm:intel_modeset_init] SSC enabled by BIOS, overriding VBT which says disabled [drm:intel_modeset_init] 2 display pipes available. [drm:intel_update_cdclk] Current CD clock rate: 400000 kHz [drm:intel_update_max_cdclk] Max CD clock rate: 400000 kHz [drm:intel_update_max_cdclk] Max dotclock rate: 360000 kHz vgaarb: device changed decodes: PCI:0000:00:02.0,olddecodes=io+mem,decodes=io+mem:owns=io+mem [drm:intel_crt_reset] crt adpa set to 0xf40000 [drm:intel_dp_init_connector] Adding DP connector on port C [drm:intel_dp_aux_init] registering DPDDC-C bus for card0-DP-1 [drm:ironlake_init_pch_refclk] has_panel 0 has_lvds 0 has_ck505 0 [drm:ironlake_init_pch_refclk] Disabling SSC entirely … later we try committing the first modeset … [drm:intel_dump_pipe_config] [CRTC:26][modeset] config ffff88041b02e800 for pipe A [drm:intel_dump_pipe_config] cpu_transcoder: A … [drm:intel_dump_pipe_config] dpll_hw_state: dpll: 0xc4016001, dpll_md: 0x0, fp0: 0x20e08, fp1: 0x30d07 [drm:intel_dump_pipe_config] planes on this crtc [drm:intel_dump_pipe_config] STANDARD PLANE:23 plane: 0.0 idx: 0 enabled [drm:intel_dump_pipe_config] FB:42, fb = 800x600 format = 0x34325258 [drm:intel_dump_pipe_config] scaler:0 src (0, 0) 800x600 dst (0, 0) 800x600 [drm:intel_dump_pipe_config] CURSOR PLANE:25 plane: 0.1 idx: 1 disabled, scaler_id = 0 [drm:intel_dump_pipe_config] STANDARD PLANE:27 plane: 0.1 idx: 2 disabled, scaler_id = 0 [drm:intel_get_shared_dpll] CRTC:26 allocated PCH DPLL A [drm:intel_get_shared_dpll] using PCH DPLL A for pipe A [drm:ilk_audio_codec_disable] Disable audio codec on port C, pipe A [drm:intel_disable_pipe] disabling pipe A ------------[ cut here ]------------ WARNING: CPU: 1 PID: 130 at drivers/gpu/drm/i915/intel_display.c:1146 intel_disable_pipe+0x297/0x2d0 [i915] pipe_off wait timed out … ---[ end trace 94fc8aa03ae139e8 ]--- [drm:intel_dp_link_down] [drm:ironlake_crtc_disable [i915]] *ERROR* failed to disable transcoder A Later modesets succeed since they reset the DPLL's configuration anyway, but this is enough to get stuck with a big fat warning in dmesg. A better solution would be to add refcounts for the SSC source, but for now leaving the source clock on should suffice. Changes since v4: - Fix calculation of final for systems with LVDS panels (fixes BUG() on CI test suite) Changes since v3: - Move temp variable into loop - Move checks for using_ssc_source to after we've figured out has_ck505 - Add using_ssc_source to debug output Changes since v2: - Fix debug output for when we disable the CPU source Changes since v1: - Leave the SSC source clock on instead of just shutting it off on all of the DPLL configurations. Cc: stable@vger.kernel.org Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Lyude <cpaul@redhat.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/1465916649-10228-1-git-send-email-cpaul@redhat.com
2016-06-14 11:04:09 -04:00
bool using_ssc_source = false;
/* We need to take the global config into account */
for_each_intel_encoder(dev, encoder) {
switch (encoder->type) {
case INTEL_OUTPUT_LVDS:
has_panel = true;
has_lvds = true;
break;
case INTEL_OUTPUT_EDP:
has_panel = true;
if (enc_to_dig_port(&encoder->base)->port == PORT_A)
has_cpu_edp = true;
break;
default:
break;
}
}
if (HAS_PCH_IBX(dev)) {
has_ck505 = dev_priv->vbt.display_clock_mode;
can_ssc = has_ck505;
} else {
has_ck505 = false;
can_ssc = true;
}
drm/i915/ilk: Don't disable SSC source if it's in use Thanks to Ville Syrjälä for pointing me towards the cause of this issue. Unfortunately one of the sideaffects of having the refclk for a DPLL set to SSC is that as long as it's set to SSC, the GPU will prevent us from powering down any of the pipes or transcoders using it. A couple of BIOSes enable SSC in both PCH_DREF_CONTROL and in the DPLL configurations. This causes issues on the first modeset, since we don't expect SSC to be left on and as a result, can't successfully power down the pipes or the transcoders using it. Here's an example from this Dell OptiPlex 990: [drm:intel_modeset_init] SSC enabled by BIOS, overriding VBT which says disabled [drm:intel_modeset_init] 2 display pipes available. [drm:intel_update_cdclk] Current CD clock rate: 400000 kHz [drm:intel_update_max_cdclk] Max CD clock rate: 400000 kHz [drm:intel_update_max_cdclk] Max dotclock rate: 360000 kHz vgaarb: device changed decodes: PCI:0000:00:02.0,olddecodes=io+mem,decodes=io+mem:owns=io+mem [drm:intel_crt_reset] crt adpa set to 0xf40000 [drm:intel_dp_init_connector] Adding DP connector on port C [drm:intel_dp_aux_init] registering DPDDC-C bus for card0-DP-1 [drm:ironlake_init_pch_refclk] has_panel 0 has_lvds 0 has_ck505 0 [drm:ironlake_init_pch_refclk] Disabling SSC entirely … later we try committing the first modeset … [drm:intel_dump_pipe_config] [CRTC:26][modeset] config ffff88041b02e800 for pipe A [drm:intel_dump_pipe_config] cpu_transcoder: A … [drm:intel_dump_pipe_config] dpll_hw_state: dpll: 0xc4016001, dpll_md: 0x0, fp0: 0x20e08, fp1: 0x30d07 [drm:intel_dump_pipe_config] planes on this crtc [drm:intel_dump_pipe_config] STANDARD PLANE:23 plane: 0.0 idx: 0 enabled [drm:intel_dump_pipe_config] FB:42, fb = 800x600 format = 0x34325258 [drm:intel_dump_pipe_config] scaler:0 src (0, 0) 800x600 dst (0, 0) 800x600 [drm:intel_dump_pipe_config] CURSOR PLANE:25 plane: 0.1 idx: 1 disabled, scaler_id = 0 [drm:intel_dump_pipe_config] STANDARD PLANE:27 plane: 0.1 idx: 2 disabled, scaler_id = 0 [drm:intel_get_shared_dpll] CRTC:26 allocated PCH DPLL A [drm:intel_get_shared_dpll] using PCH DPLL A for pipe A [drm:ilk_audio_codec_disable] Disable audio codec on port C, pipe A [drm:intel_disable_pipe] disabling pipe A ------------[ cut here ]------------ WARNING: CPU: 1 PID: 130 at drivers/gpu/drm/i915/intel_display.c:1146 intel_disable_pipe+0x297/0x2d0 [i915] pipe_off wait timed out … ---[ end trace 94fc8aa03ae139e8 ]--- [drm:intel_dp_link_down] [drm:ironlake_crtc_disable [i915]] *ERROR* failed to disable transcoder A Later modesets succeed since they reset the DPLL's configuration anyway, but this is enough to get stuck with a big fat warning in dmesg. A better solution would be to add refcounts for the SSC source, but for now leaving the source clock on should suffice. Changes since v4: - Fix calculation of final for systems with LVDS panels (fixes BUG() on CI test suite) Changes since v3: - Move temp variable into loop - Move checks for using_ssc_source to after we've figured out has_ck505 - Add using_ssc_source to debug output Changes since v2: - Fix debug output for when we disable the CPU source Changes since v1: - Leave the SSC source clock on instead of just shutting it off on all of the DPLL configurations. Cc: stable@vger.kernel.org Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Lyude <cpaul@redhat.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/1465916649-10228-1-git-send-email-cpaul@redhat.com
2016-06-14 11:04:09 -04:00
/* Check if any DPLLs are using the SSC source */
for (i = 0; i < dev_priv->num_shared_dpll; i++) {
u32 temp = I915_READ(PCH_DPLL(i));
if (!(temp & DPLL_VCO_ENABLE))
continue;
if ((temp & PLL_REF_INPUT_MASK) ==
PLLB_REF_INPUT_SPREADSPECTRUMIN) {
using_ssc_source = true;
break;
}
}
DRM_DEBUG_KMS("has_panel %d has_lvds %d has_ck505 %d using_ssc_source %d\n",
has_panel, has_lvds, has_ck505, using_ssc_source);
/* Ironlake: try to setup display ref clock before DPLL
* enabling. This is only under driver's control after
* PCH B stepping, previous chipset stepping should be
* ignoring this setting.
*/
val = I915_READ(PCH_DREF_CONTROL);
/* As we must carefully and slowly disable/enable each source in turn,
* compute the final state we want first and check if we need to
* make any changes at all.
*/
final = val;
final &= ~DREF_NONSPREAD_SOURCE_MASK;
if (has_ck505)
final |= DREF_NONSPREAD_CK505_ENABLE;
else
final |= DREF_NONSPREAD_SOURCE_ENABLE;
final &= ~DREF_SSC_SOURCE_MASK;
final &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
final &= ~DREF_SSC1_ENABLE;
if (has_panel) {
final |= DREF_SSC_SOURCE_ENABLE;
if (intel_panel_use_ssc(dev_priv) && can_ssc)
final |= DREF_SSC1_ENABLE;
if (has_cpu_edp) {
if (intel_panel_use_ssc(dev_priv) && can_ssc)
final |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD;
else
final |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
} else
final |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
drm/i915/ilk: Don't disable SSC source if it's in use Thanks to Ville Syrjälä for pointing me towards the cause of this issue. Unfortunately one of the sideaffects of having the refclk for a DPLL set to SSC is that as long as it's set to SSC, the GPU will prevent us from powering down any of the pipes or transcoders using it. A couple of BIOSes enable SSC in both PCH_DREF_CONTROL and in the DPLL configurations. This causes issues on the first modeset, since we don't expect SSC to be left on and as a result, can't successfully power down the pipes or the transcoders using it. Here's an example from this Dell OptiPlex 990: [drm:intel_modeset_init] SSC enabled by BIOS, overriding VBT which says disabled [drm:intel_modeset_init] 2 display pipes available. [drm:intel_update_cdclk] Current CD clock rate: 400000 kHz [drm:intel_update_max_cdclk] Max CD clock rate: 400000 kHz [drm:intel_update_max_cdclk] Max dotclock rate: 360000 kHz vgaarb: device changed decodes: PCI:0000:00:02.0,olddecodes=io+mem,decodes=io+mem:owns=io+mem [drm:intel_crt_reset] crt adpa set to 0xf40000 [drm:intel_dp_init_connector] Adding DP connector on port C [drm:intel_dp_aux_init] registering DPDDC-C bus for card0-DP-1 [drm:ironlake_init_pch_refclk] has_panel 0 has_lvds 0 has_ck505 0 [drm:ironlake_init_pch_refclk] Disabling SSC entirely … later we try committing the first modeset … [drm:intel_dump_pipe_config] [CRTC:26][modeset] config ffff88041b02e800 for pipe A [drm:intel_dump_pipe_config] cpu_transcoder: A … [drm:intel_dump_pipe_config] dpll_hw_state: dpll: 0xc4016001, dpll_md: 0x0, fp0: 0x20e08, fp1: 0x30d07 [drm:intel_dump_pipe_config] planes on this crtc [drm:intel_dump_pipe_config] STANDARD PLANE:23 plane: 0.0 idx: 0 enabled [drm:intel_dump_pipe_config] FB:42, fb = 800x600 format = 0x34325258 [drm:intel_dump_pipe_config] scaler:0 src (0, 0) 800x600 dst (0, 0) 800x600 [drm:intel_dump_pipe_config] CURSOR PLANE:25 plane: 0.1 idx: 1 disabled, scaler_id = 0 [drm:intel_dump_pipe_config] STANDARD PLANE:27 plane: 0.1 idx: 2 disabled, scaler_id = 0 [drm:intel_get_shared_dpll] CRTC:26 allocated PCH DPLL A [drm:intel_get_shared_dpll] using PCH DPLL A for pipe A [drm:ilk_audio_codec_disable] Disable audio codec on port C, pipe A [drm:intel_disable_pipe] disabling pipe A ------------[ cut here ]------------ WARNING: CPU: 1 PID: 130 at drivers/gpu/drm/i915/intel_display.c:1146 intel_disable_pipe+0x297/0x2d0 [i915] pipe_off wait timed out … ---[ end trace 94fc8aa03ae139e8 ]--- [drm:intel_dp_link_down] [drm:ironlake_crtc_disable [i915]] *ERROR* failed to disable transcoder A Later modesets succeed since they reset the DPLL's configuration anyway, but this is enough to get stuck with a big fat warning in dmesg. A better solution would be to add refcounts for the SSC source, but for now leaving the source clock on should suffice. Changes since v4: - Fix calculation of final for systems with LVDS panels (fixes BUG() on CI test suite) Changes since v3: - Move temp variable into loop - Move checks for using_ssc_source to after we've figured out has_ck505 - Add using_ssc_source to debug output Changes since v2: - Fix debug output for when we disable the CPU source Changes since v1: - Leave the SSC source clock on instead of just shutting it off on all of the DPLL configurations. Cc: stable@vger.kernel.org Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Lyude <cpaul@redhat.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/1465916649-10228-1-git-send-email-cpaul@redhat.com
2016-06-14 11:04:09 -04:00
} else if (using_ssc_source) {
final |= DREF_SSC_SOURCE_ENABLE;
final |= DREF_SSC1_ENABLE;
}
if (final == val)
return;
/* Always enable nonspread source */
val &= ~DREF_NONSPREAD_SOURCE_MASK;
if (has_ck505)
val |= DREF_NONSPREAD_CK505_ENABLE;
else
val |= DREF_NONSPREAD_SOURCE_ENABLE;
if (has_panel) {
val &= ~DREF_SSC_SOURCE_MASK;
val |= DREF_SSC_SOURCE_ENABLE;
/* SSC must be turned on before enabling the CPU output */
if (intel_panel_use_ssc(dev_priv) && can_ssc) {
DRM_DEBUG_KMS("Using SSC on panel\n");
val |= DREF_SSC1_ENABLE;
} else
val &= ~DREF_SSC1_ENABLE;
/* Get SSC going before enabling the outputs */
I915_WRITE(PCH_DREF_CONTROL, val);
POSTING_READ(PCH_DREF_CONTROL);
udelay(200);
val &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
/* Enable CPU source on CPU attached eDP */
if (has_cpu_edp) {
if (intel_panel_use_ssc(dev_priv) && can_ssc) {
DRM_DEBUG_KMS("Using SSC on eDP\n");
val |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD;
} else
val |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
} else
val |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
I915_WRITE(PCH_DREF_CONTROL, val);
POSTING_READ(PCH_DREF_CONTROL);
udelay(200);
} else {
drm/i915/ilk: Don't disable SSC source if it's in use Thanks to Ville Syrjälä for pointing me towards the cause of this issue. Unfortunately one of the sideaffects of having the refclk for a DPLL set to SSC is that as long as it's set to SSC, the GPU will prevent us from powering down any of the pipes or transcoders using it. A couple of BIOSes enable SSC in both PCH_DREF_CONTROL and in the DPLL configurations. This causes issues on the first modeset, since we don't expect SSC to be left on and as a result, can't successfully power down the pipes or the transcoders using it. Here's an example from this Dell OptiPlex 990: [drm:intel_modeset_init] SSC enabled by BIOS, overriding VBT which says disabled [drm:intel_modeset_init] 2 display pipes available. [drm:intel_update_cdclk] Current CD clock rate: 400000 kHz [drm:intel_update_max_cdclk] Max CD clock rate: 400000 kHz [drm:intel_update_max_cdclk] Max dotclock rate: 360000 kHz vgaarb: device changed decodes: PCI:0000:00:02.0,olddecodes=io+mem,decodes=io+mem:owns=io+mem [drm:intel_crt_reset] crt adpa set to 0xf40000 [drm:intel_dp_init_connector] Adding DP connector on port C [drm:intel_dp_aux_init] registering DPDDC-C bus for card0-DP-1 [drm:ironlake_init_pch_refclk] has_panel 0 has_lvds 0 has_ck505 0 [drm:ironlake_init_pch_refclk] Disabling SSC entirely … later we try committing the first modeset … [drm:intel_dump_pipe_config] [CRTC:26][modeset] config ffff88041b02e800 for pipe A [drm:intel_dump_pipe_config] cpu_transcoder: A … [drm:intel_dump_pipe_config] dpll_hw_state: dpll: 0xc4016001, dpll_md: 0x0, fp0: 0x20e08, fp1: 0x30d07 [drm:intel_dump_pipe_config] planes on this crtc [drm:intel_dump_pipe_config] STANDARD PLANE:23 plane: 0.0 idx: 0 enabled [drm:intel_dump_pipe_config] FB:42, fb = 800x600 format = 0x34325258 [drm:intel_dump_pipe_config] scaler:0 src (0, 0) 800x600 dst (0, 0) 800x600 [drm:intel_dump_pipe_config] CURSOR PLANE:25 plane: 0.1 idx: 1 disabled, scaler_id = 0 [drm:intel_dump_pipe_config] STANDARD PLANE:27 plane: 0.1 idx: 2 disabled, scaler_id = 0 [drm:intel_get_shared_dpll] CRTC:26 allocated PCH DPLL A [drm:intel_get_shared_dpll] using PCH DPLL A for pipe A [drm:ilk_audio_codec_disable] Disable audio codec on port C, pipe A [drm:intel_disable_pipe] disabling pipe A ------------[ cut here ]------------ WARNING: CPU: 1 PID: 130 at drivers/gpu/drm/i915/intel_display.c:1146 intel_disable_pipe+0x297/0x2d0 [i915] pipe_off wait timed out … ---[ end trace 94fc8aa03ae139e8 ]--- [drm:intel_dp_link_down] [drm:ironlake_crtc_disable [i915]] *ERROR* failed to disable transcoder A Later modesets succeed since they reset the DPLL's configuration anyway, but this is enough to get stuck with a big fat warning in dmesg. A better solution would be to add refcounts for the SSC source, but for now leaving the source clock on should suffice. Changes since v4: - Fix calculation of final for systems with LVDS panels (fixes BUG() on CI test suite) Changes since v3: - Move temp variable into loop - Move checks for using_ssc_source to after we've figured out has_ck505 - Add using_ssc_source to debug output Changes since v2: - Fix debug output for when we disable the CPU source Changes since v1: - Leave the SSC source clock on instead of just shutting it off on all of the DPLL configurations. Cc: stable@vger.kernel.org Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Lyude <cpaul@redhat.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/1465916649-10228-1-git-send-email-cpaul@redhat.com
2016-06-14 11:04:09 -04:00
DRM_DEBUG_KMS("Disabling CPU source output\n");
val &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
/* Turn off CPU output */
val |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
I915_WRITE(PCH_DREF_CONTROL, val);
POSTING_READ(PCH_DREF_CONTROL);
udelay(200);
drm/i915/ilk: Don't disable SSC source if it's in use Thanks to Ville Syrjälä for pointing me towards the cause of this issue. Unfortunately one of the sideaffects of having the refclk for a DPLL set to SSC is that as long as it's set to SSC, the GPU will prevent us from powering down any of the pipes or transcoders using it. A couple of BIOSes enable SSC in both PCH_DREF_CONTROL and in the DPLL configurations. This causes issues on the first modeset, since we don't expect SSC to be left on and as a result, can't successfully power down the pipes or the transcoders using it. Here's an example from this Dell OptiPlex 990: [drm:intel_modeset_init] SSC enabled by BIOS, overriding VBT which says disabled [drm:intel_modeset_init] 2 display pipes available. [drm:intel_update_cdclk] Current CD clock rate: 400000 kHz [drm:intel_update_max_cdclk] Max CD clock rate: 400000 kHz [drm:intel_update_max_cdclk] Max dotclock rate: 360000 kHz vgaarb: device changed decodes: PCI:0000:00:02.0,olddecodes=io+mem,decodes=io+mem:owns=io+mem [drm:intel_crt_reset] crt adpa set to 0xf40000 [drm:intel_dp_init_connector] Adding DP connector on port C [drm:intel_dp_aux_init] registering DPDDC-C bus for card0-DP-1 [drm:ironlake_init_pch_refclk] has_panel 0 has_lvds 0 has_ck505 0 [drm:ironlake_init_pch_refclk] Disabling SSC entirely … later we try committing the first modeset … [drm:intel_dump_pipe_config] [CRTC:26][modeset] config ffff88041b02e800 for pipe A [drm:intel_dump_pipe_config] cpu_transcoder: A … [drm:intel_dump_pipe_config] dpll_hw_state: dpll: 0xc4016001, dpll_md: 0x0, fp0: 0x20e08, fp1: 0x30d07 [drm:intel_dump_pipe_config] planes on this crtc [drm:intel_dump_pipe_config] STANDARD PLANE:23 plane: 0.0 idx: 0 enabled [drm:intel_dump_pipe_config] FB:42, fb = 800x600 format = 0x34325258 [drm:intel_dump_pipe_config] scaler:0 src (0, 0) 800x600 dst (0, 0) 800x600 [drm:intel_dump_pipe_config] CURSOR PLANE:25 plane: 0.1 idx: 1 disabled, scaler_id = 0 [drm:intel_dump_pipe_config] STANDARD PLANE:27 plane: 0.1 idx: 2 disabled, scaler_id = 0 [drm:intel_get_shared_dpll] CRTC:26 allocated PCH DPLL A [drm:intel_get_shared_dpll] using PCH DPLL A for pipe A [drm:ilk_audio_codec_disable] Disable audio codec on port C, pipe A [drm:intel_disable_pipe] disabling pipe A ------------[ cut here ]------------ WARNING: CPU: 1 PID: 130 at drivers/gpu/drm/i915/intel_display.c:1146 intel_disable_pipe+0x297/0x2d0 [i915] pipe_off wait timed out … ---[ end trace 94fc8aa03ae139e8 ]--- [drm:intel_dp_link_down] [drm:ironlake_crtc_disable [i915]] *ERROR* failed to disable transcoder A Later modesets succeed since they reset the DPLL's configuration anyway, but this is enough to get stuck with a big fat warning in dmesg. A better solution would be to add refcounts for the SSC source, but for now leaving the source clock on should suffice. Changes since v4: - Fix calculation of final for systems with LVDS panels (fixes BUG() on CI test suite) Changes since v3: - Move temp variable into loop - Move checks for using_ssc_source to after we've figured out has_ck505 - Add using_ssc_source to debug output Changes since v2: - Fix debug output for when we disable the CPU source Changes since v1: - Leave the SSC source clock on instead of just shutting it off on all of the DPLL configurations. Cc: stable@vger.kernel.org Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Lyude <cpaul@redhat.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/1465916649-10228-1-git-send-email-cpaul@redhat.com
2016-06-14 11:04:09 -04:00
if (!using_ssc_source) {
DRM_DEBUG_KMS("Disabling SSC source\n");
drm/i915/ilk: Don't disable SSC source if it's in use Thanks to Ville Syrjälä for pointing me towards the cause of this issue. Unfortunately one of the sideaffects of having the refclk for a DPLL set to SSC is that as long as it's set to SSC, the GPU will prevent us from powering down any of the pipes or transcoders using it. A couple of BIOSes enable SSC in both PCH_DREF_CONTROL and in the DPLL configurations. This causes issues on the first modeset, since we don't expect SSC to be left on and as a result, can't successfully power down the pipes or the transcoders using it. Here's an example from this Dell OptiPlex 990: [drm:intel_modeset_init] SSC enabled by BIOS, overriding VBT which says disabled [drm:intel_modeset_init] 2 display pipes available. [drm:intel_update_cdclk] Current CD clock rate: 400000 kHz [drm:intel_update_max_cdclk] Max CD clock rate: 400000 kHz [drm:intel_update_max_cdclk] Max dotclock rate: 360000 kHz vgaarb: device changed decodes: PCI:0000:00:02.0,olddecodes=io+mem,decodes=io+mem:owns=io+mem [drm:intel_crt_reset] crt adpa set to 0xf40000 [drm:intel_dp_init_connector] Adding DP connector on port C [drm:intel_dp_aux_init] registering DPDDC-C bus for card0-DP-1 [drm:ironlake_init_pch_refclk] has_panel 0 has_lvds 0 has_ck505 0 [drm:ironlake_init_pch_refclk] Disabling SSC entirely … later we try committing the first modeset … [drm:intel_dump_pipe_config] [CRTC:26][modeset] config ffff88041b02e800 for pipe A [drm:intel_dump_pipe_config] cpu_transcoder: A … [drm:intel_dump_pipe_config] dpll_hw_state: dpll: 0xc4016001, dpll_md: 0x0, fp0: 0x20e08, fp1: 0x30d07 [drm:intel_dump_pipe_config] planes on this crtc [drm:intel_dump_pipe_config] STANDARD PLANE:23 plane: 0.0 idx: 0 enabled [drm:intel_dump_pipe_config] FB:42, fb = 800x600 format = 0x34325258 [drm:intel_dump_pipe_config] scaler:0 src (0, 0) 800x600 dst (0, 0) 800x600 [drm:intel_dump_pipe_config] CURSOR PLANE:25 plane: 0.1 idx: 1 disabled, scaler_id = 0 [drm:intel_dump_pipe_config] STANDARD PLANE:27 plane: 0.1 idx: 2 disabled, scaler_id = 0 [drm:intel_get_shared_dpll] CRTC:26 allocated PCH DPLL A [drm:intel_get_shared_dpll] using PCH DPLL A for pipe A [drm:ilk_audio_codec_disable] Disable audio codec on port C, pipe A [drm:intel_disable_pipe] disabling pipe A ------------[ cut here ]------------ WARNING: CPU: 1 PID: 130 at drivers/gpu/drm/i915/intel_display.c:1146 intel_disable_pipe+0x297/0x2d0 [i915] pipe_off wait timed out … ---[ end trace 94fc8aa03ae139e8 ]--- [drm:intel_dp_link_down] [drm:ironlake_crtc_disable [i915]] *ERROR* failed to disable transcoder A Later modesets succeed since they reset the DPLL's configuration anyway, but this is enough to get stuck with a big fat warning in dmesg. A better solution would be to add refcounts for the SSC source, but for now leaving the source clock on should suffice. Changes since v4: - Fix calculation of final for systems with LVDS panels (fixes BUG() on CI test suite) Changes since v3: - Move temp variable into loop - Move checks for using_ssc_source to after we've figured out has_ck505 - Add using_ssc_source to debug output Changes since v2: - Fix debug output for when we disable the CPU source Changes since v1: - Leave the SSC source clock on instead of just shutting it off on all of the DPLL configurations. Cc: stable@vger.kernel.org Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Lyude <cpaul@redhat.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/1465916649-10228-1-git-send-email-cpaul@redhat.com
2016-06-14 11:04:09 -04:00
/* Turn off the SSC source */
val &= ~DREF_SSC_SOURCE_MASK;
val |= DREF_SSC_SOURCE_DISABLE;
drm/i915/ilk: Don't disable SSC source if it's in use Thanks to Ville Syrjälä for pointing me towards the cause of this issue. Unfortunately one of the sideaffects of having the refclk for a DPLL set to SSC is that as long as it's set to SSC, the GPU will prevent us from powering down any of the pipes or transcoders using it. A couple of BIOSes enable SSC in both PCH_DREF_CONTROL and in the DPLL configurations. This causes issues on the first modeset, since we don't expect SSC to be left on and as a result, can't successfully power down the pipes or the transcoders using it. Here's an example from this Dell OptiPlex 990: [drm:intel_modeset_init] SSC enabled by BIOS, overriding VBT which says disabled [drm:intel_modeset_init] 2 display pipes available. [drm:intel_update_cdclk] Current CD clock rate: 400000 kHz [drm:intel_update_max_cdclk] Max CD clock rate: 400000 kHz [drm:intel_update_max_cdclk] Max dotclock rate: 360000 kHz vgaarb: device changed decodes: PCI:0000:00:02.0,olddecodes=io+mem,decodes=io+mem:owns=io+mem [drm:intel_crt_reset] crt adpa set to 0xf40000 [drm:intel_dp_init_connector] Adding DP connector on port C [drm:intel_dp_aux_init] registering DPDDC-C bus for card0-DP-1 [drm:ironlake_init_pch_refclk] has_panel 0 has_lvds 0 has_ck505 0 [drm:ironlake_init_pch_refclk] Disabling SSC entirely … later we try committing the first modeset … [drm:intel_dump_pipe_config] [CRTC:26][modeset] config ffff88041b02e800 for pipe A [drm:intel_dump_pipe_config] cpu_transcoder: A … [drm:intel_dump_pipe_config] dpll_hw_state: dpll: 0xc4016001, dpll_md: 0x0, fp0: 0x20e08, fp1: 0x30d07 [drm:intel_dump_pipe_config] planes on this crtc [drm:intel_dump_pipe_config] STANDARD PLANE:23 plane: 0.0 idx: 0 enabled [drm:intel_dump_pipe_config] FB:42, fb = 800x600 format = 0x34325258 [drm:intel_dump_pipe_config] scaler:0 src (0, 0) 800x600 dst (0, 0) 800x600 [drm:intel_dump_pipe_config] CURSOR PLANE:25 plane: 0.1 idx: 1 disabled, scaler_id = 0 [drm:intel_dump_pipe_config] STANDARD PLANE:27 plane: 0.1 idx: 2 disabled, scaler_id = 0 [drm:intel_get_shared_dpll] CRTC:26 allocated PCH DPLL A [drm:intel_get_shared_dpll] using PCH DPLL A for pipe A [drm:ilk_audio_codec_disable] Disable audio codec on port C, pipe A [drm:intel_disable_pipe] disabling pipe A ------------[ cut here ]------------ WARNING: CPU: 1 PID: 130 at drivers/gpu/drm/i915/intel_display.c:1146 intel_disable_pipe+0x297/0x2d0 [i915] pipe_off wait timed out … ---[ end trace 94fc8aa03ae139e8 ]--- [drm:intel_dp_link_down] [drm:ironlake_crtc_disable [i915]] *ERROR* failed to disable transcoder A Later modesets succeed since they reset the DPLL's configuration anyway, but this is enough to get stuck with a big fat warning in dmesg. A better solution would be to add refcounts for the SSC source, but for now leaving the source clock on should suffice. Changes since v3: - Move temp variable into loop - Move checks for using_ssc_source to after we've figured out has_ck505 - Add using_ssc_source to debug output Changes since v2: - Fix debug output for when we disable the CPU source Changes since v1: - Leave the SSC source clock on instead of just shutting it off on all of the DPLL configurations. Cc: stable@vger.kernel.org Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Lyude <cpaul@redhat.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/1464199863-9397-1-git-send-email-cpaul@redhat.com
2016-05-25 14:11:02 -04:00
drm/i915/ilk: Don't disable SSC source if it's in use Thanks to Ville Syrjälä for pointing me towards the cause of this issue. Unfortunately one of the sideaffects of having the refclk for a DPLL set to SSC is that as long as it's set to SSC, the GPU will prevent us from powering down any of the pipes or transcoders using it. A couple of BIOSes enable SSC in both PCH_DREF_CONTROL and in the DPLL configurations. This causes issues on the first modeset, since we don't expect SSC to be left on and as a result, can't successfully power down the pipes or the transcoders using it. Here's an example from this Dell OptiPlex 990: [drm:intel_modeset_init] SSC enabled by BIOS, overriding VBT which says disabled [drm:intel_modeset_init] 2 display pipes available. [drm:intel_update_cdclk] Current CD clock rate: 400000 kHz [drm:intel_update_max_cdclk] Max CD clock rate: 400000 kHz [drm:intel_update_max_cdclk] Max dotclock rate: 360000 kHz vgaarb: device changed decodes: PCI:0000:00:02.0,olddecodes=io+mem,decodes=io+mem:owns=io+mem [drm:intel_crt_reset] crt adpa set to 0xf40000 [drm:intel_dp_init_connector] Adding DP connector on port C [drm:intel_dp_aux_init] registering DPDDC-C bus for card0-DP-1 [drm:ironlake_init_pch_refclk] has_panel 0 has_lvds 0 has_ck505 0 [drm:ironlake_init_pch_refclk] Disabling SSC entirely … later we try committing the first modeset … [drm:intel_dump_pipe_config] [CRTC:26][modeset] config ffff88041b02e800 for pipe A [drm:intel_dump_pipe_config] cpu_transcoder: A … [drm:intel_dump_pipe_config] dpll_hw_state: dpll: 0xc4016001, dpll_md: 0x0, fp0: 0x20e08, fp1: 0x30d07 [drm:intel_dump_pipe_config] planes on this crtc [drm:intel_dump_pipe_config] STANDARD PLANE:23 plane: 0.0 idx: 0 enabled [drm:intel_dump_pipe_config] FB:42, fb = 800x600 format = 0x34325258 [drm:intel_dump_pipe_config] scaler:0 src (0, 0) 800x600 dst (0, 0) 800x600 [drm:intel_dump_pipe_config] CURSOR PLANE:25 plane: 0.1 idx: 1 disabled, scaler_id = 0 [drm:intel_dump_pipe_config] STANDARD PLANE:27 plane: 0.1 idx: 2 disabled, scaler_id = 0 [drm:intel_get_shared_dpll] CRTC:26 allocated PCH DPLL A [drm:intel_get_shared_dpll] using PCH DPLL A for pipe A [drm:ilk_audio_codec_disable] Disable audio codec on port C, pipe A [drm:intel_disable_pipe] disabling pipe A ------------[ cut here ]------------ WARNING: CPU: 1 PID: 130 at drivers/gpu/drm/i915/intel_display.c:1146 intel_disable_pipe+0x297/0x2d0 [i915] pipe_off wait timed out … ---[ end trace 94fc8aa03ae139e8 ]--- [drm:intel_dp_link_down] [drm:ironlake_crtc_disable [i915]] *ERROR* failed to disable transcoder A Later modesets succeed since they reset the DPLL's configuration anyway, but this is enough to get stuck with a big fat warning in dmesg. A better solution would be to add refcounts for the SSC source, but for now leaving the source clock on should suffice. Changes since v4: - Fix calculation of final for systems with LVDS panels (fixes BUG() on CI test suite) Changes since v3: - Move temp variable into loop - Move checks for using_ssc_source to after we've figured out has_ck505 - Add using_ssc_source to debug output Changes since v2: - Fix debug output for when we disable the CPU source Changes since v1: - Leave the SSC source clock on instead of just shutting it off on all of the DPLL configurations. Cc: stable@vger.kernel.org Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Lyude <cpaul@redhat.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/1465916649-10228-1-git-send-email-cpaul@redhat.com
2016-06-14 11:04:09 -04:00
/* Turn off SSC1 */
val &= ~DREF_SSC1_ENABLE;
I915_WRITE(PCH_DREF_CONTROL, val);
POSTING_READ(PCH_DREF_CONTROL);
udelay(200);
}
}
BUG_ON(val != final);
}
static void lpt_reset_fdi_mphy(struct drm_i915_private *dev_priv)
{
uint32_t tmp;
tmp = I915_READ(SOUTH_CHICKEN2);
tmp |= FDI_MPHY_IOSFSB_RESET_CTL;
I915_WRITE(SOUTH_CHICKEN2, tmp);
if (wait_for_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);
if (wait_for_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);
tmp |= (0x12 << 24);
intel_sbi_write(dev_priv, 0x8008, tmp, SBI_MPHY);
tmp = intel_sbi_read(dev_priv, 0x2008, SBI_MPHY);
tmp |= (1 << 11);
intel_sbi_write(dev_priv, 0x2008, tmp, SBI_MPHY);
tmp = intel_sbi_read(dev_priv, 0x2108, SBI_MPHY);
tmp |= (1 << 11);
intel_sbi_write(dev_priv, 0x2108, 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);
tmp = intel_sbi_read(dev_priv, 0x216C, SBI_MPHY);
tmp |= (1 << 24) | (1 << 21) | (1 << 18);
intel_sbi_write(dev_priv, 0x216C, 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, 0x208C, SBI_MPHY);
tmp &= ~0xFF;
tmp |= 0x1C;
intel_sbi_write(dev_priv, 0x208C, tmp, SBI_MPHY);
tmp = intel_sbi_read(dev_priv, 0x218C, SBI_MPHY);
tmp &= ~0xFF;
tmp |= 0x1C;
intel_sbi_write(dev_priv, 0x218C, tmp, SBI_MPHY);
tmp = intel_sbi_read(dev_priv, 0x2098, SBI_MPHY);
tmp &= ~(0xFF << 16);
tmp |= (0x1C << 16);
intel_sbi_write(dev_priv, 0x2098, tmp, SBI_MPHY);
tmp = intel_sbi_read(dev_priv, 0x2198, SBI_MPHY);
tmp &= ~(0xFF << 16);
tmp |= (0x1C << 16);
intel_sbi_write(dev_priv, 0x2198, 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, 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);
}
/* 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 reg, tmp;
if (WARN(with_fdi && !with_spread, "FDI requires downspread\n"))
with_spread = true;
if (WARN(HAS_PCH_LPT_LP(dev) && with_fdi, "LP PCH doesn't have FDI\n"))
with_fdi = false;
mutex_lock(&dev_priv->sb_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);
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);
if (with_fdi) {
lpt_reset_fdi_mphy(dev_priv);
lpt_program_fdi_mphy(dev_priv);
}
}
reg = HAS_PCH_LPT_LP(dev) ? 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->sb_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->sb_lock);
reg = HAS_PCH_LPT_LP(dev) ? 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->sb_lock);
}
#define BEND_IDX(steps) ((50 + (steps)) / 5)
static const uint16_t sscdivintphase[] = {
[BEND_IDX( 50)] = 0x3B23,
[BEND_IDX( 45)] = 0x3B23,
[BEND_IDX( 40)] = 0x3C23,
[BEND_IDX( 35)] = 0x3C23,
[BEND_IDX( 30)] = 0x3D23,
[BEND_IDX( 25)] = 0x3D23,
[BEND_IDX( 20)] = 0x3E23,
[BEND_IDX( 15)] = 0x3E23,
[BEND_IDX( 10)] = 0x3F23,
[BEND_IDX( 5)] = 0x3F23,
[BEND_IDX( 0)] = 0x0025,
[BEND_IDX( -5)] = 0x0025,
[BEND_IDX(-10)] = 0x0125,
[BEND_IDX(-15)] = 0x0125,
[BEND_IDX(-20)] = 0x0225,
[BEND_IDX(-25)] = 0x0225,
[BEND_IDX(-30)] = 0x0325,
[BEND_IDX(-35)] = 0x0325,
[BEND_IDX(-40)] = 0x0425,
[BEND_IDX(-45)] = 0x0425,
[BEND_IDX(-50)] = 0x0525,
};
/*
* Bend CLKOUT_DP
* steps -50 to 50 inclusive, in steps of 5
* < 0 slow down the clock, > 0 speed up the clock, 0 == no bend (135MHz)
* change in clock period = -(steps / 10) * 5.787 ps
*/
static void lpt_bend_clkout_dp(struct drm_i915_private *dev_priv, int steps)
{
uint32_t tmp;
int idx = BEND_IDX(steps);
if (WARN_ON(steps % 5 != 0))
return;
if (WARN_ON(idx >= ARRAY_SIZE(sscdivintphase)))
return;
mutex_lock(&dev_priv->sb_lock);
if (steps % 10 != 0)
tmp = 0xAAAAAAAB;
else
tmp = 0x00000000;
intel_sbi_write(dev_priv, SBI_SSCDITHPHASE, tmp, SBI_ICLK);
tmp = intel_sbi_read(dev_priv, SBI_SSCDIVINTPHASE, SBI_ICLK);
tmp &= 0xffff0000;
tmp |= sscdivintphase[idx];
intel_sbi_write(dev_priv, SBI_SSCDIVINTPHASE, tmp, SBI_ICLK);
mutex_unlock(&dev_priv->sb_lock);
}
#undef BEND_IDX
static void lpt_init_pch_refclk(struct drm_device *dev)
{
struct intel_encoder *encoder;
bool has_vga = false;
for_each_intel_encoder(dev, encoder) {
switch (encoder->type) {
case INTEL_OUTPUT_ANALOG:
has_vga = true;
break;
default:
break;
}
}
if (has_vga) {
lpt_bend_clkout_dp(to_i915(dev), 0);
lpt_enable_clkout_dp(dev, true, true);
} else {
lpt_disable_clkout_dp(dev);
}
}
/*
* Initialize reference clocks when the driver loads
*/
void intel_init_pch_refclk(struct drm_device *dev)
{
if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
ironlake_init_pch_refclk(dev);
else if (HAS_PCH_LPT(dev))
lpt_init_pch_refclk(dev);
}
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);
int pipe = intel_crtc->pipe;
uint32_t val;
val = 0;
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
switch (intel_crtc->config->pipe_bpp) {
case 18:
val |= PIPECONF_6BPC;
break;
case 24:
val |= PIPECONF_8BPC;
break;
case 30:
val |= PIPECONF_10BPC;
break;
case 36:
val |= PIPECONF_12BPC;
break;
default:
/* Case prevented by intel_choose_pipe_bpp_dither. */
BUG();
}
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (intel_crtc->config->dither)
val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
val |= PIPECONF_INTERLACED_ILK;
else
val |= PIPECONF_PROGRESSIVE;
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (intel_crtc->config->limited_color_range)
val |= PIPECONF_COLOR_RANGE_SELECT;
I915_WRITE(PIPECONF(pipe), val);
POSTING_READ(PIPECONF(pipe));
}
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);
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
u32 val = 0;
if (IS_HASWELL(dev_priv) && intel_crtc->config->dither)
val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
val |= PIPECONF_INTERLACED_ILK;
else
val |= PIPECONF_PROGRESSIVE;
I915_WRITE(PIPECONF(cpu_transcoder), val);
POSTING_READ(PIPECONF(cpu_transcoder));
}
static void haswell_set_pipemisc(struct drm_crtc *crtc)
{
struct drm_i915_private *dev_priv = crtc->dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
if (IS_BROADWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 9) {
u32 val = 0;
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
switch (intel_crtc->config->pipe_bpp) {
case 18:
val |= PIPEMISC_DITHER_6_BPC;
break;
case 24:
val |= PIPEMISC_DITHER_8_BPC;
break;
case 30:
val |= PIPEMISC_DITHER_10_BPC;
break;
case 36:
val |= PIPEMISC_DITHER_12_BPC;
break;
default:
/* Case prevented by pipe_config_set_bpp. */
BUG();
}
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
if (intel_crtc->config->dither)
val |= PIPEMISC_DITHER_ENABLE | PIPEMISC_DITHER_TYPE_SP;
I915_WRITE(PIPEMISC(intel_crtc->pipe), val);
}
}
int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp)
{
/*
* Account for spread spectrum to avoid
* oversubscribing the link. Max center spread
* is 2.5%; use 5% for safety's sake.
*/
u32 bps = target_clock * bpp * 21 / 20;
return DIV_ROUND_UP(bps, link_bw * 8);
}
static bool ironlake_needs_fb_cb_tune(struct dpll *dpll, int factor)
drm/i915: clear up the fdi/dp set_m_n confusion There's a rather decent confusion going on around transcoder m_n values. So let's clarify: - All dp encoders need this, either on the pch transcoder if it's a pch port, or on the cpu transcoder/pipe if it's a cpu port. - fdi links need to have the right m_n values for the fdi link set in the cpu transcoder. To handle the pch vs transcoder stuff a bit better, extract transcoder set_m_n helpers. To make them simpler, set intel_crtc->cpu_transcoder als in ironlake_crtc_mode_set, so that gen5+ (where the cpu m_n registers are all at the same offset) can use it. Haswell modeset is decently confused about dp vs. edp vs. fdi. dp vs. edp works exactly the same as dp (since there's no pch dp any more), so use that as a check. And only set up the fdi m_n values if we really have a pch encoder present (which means we have a VGA encoder). On ilk+ we've called ironlake_set_m_n both for cpu_edp and for pch encoders. Now that dp_set_m_n handles all dp links (thanks to the pch encoder check), we can ditch the cpu_edp stuff from the fdi_set_m_n function. Since the dp_m_n values are not readily available, we need to carefully coax the edp values out of the encoder. Hence we can't (yet) kill this superflous complexity. v2: Rebase on top of the ivb fdi B/C check patch - we need to properly clear intel_crtc->fdi_lane, otherwise those checks will misfire. v3: Rebased on top of a s/IS_HASWELL/HAS_DDI/ patch from Paulo Zanoni. v4: Drop the addition of has_dp_encoder, it's in the wrong patch (Jesse). Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-04-02 23:38:10 +02:00
{
return i9xx_dpll_compute_m(dpll) < factor * dpll->n;
}
static void ironlake_compute_dpll(struct intel_crtc *intel_crtc,
struct intel_crtc_state *crtc_state,
struct dpll *reduced_clock)
{
struct drm_crtc *crtc = &intel_crtc->base;
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_atomic_state *state = crtc_state->base.state;
struct drm_connector *connector;
struct drm_connector_state *connector_state;
struct intel_encoder *encoder;
u32 dpll, fp, fp2;
int factor, i;
bool is_lvds = false, is_sdvo = false;
for_each_connector_in_state(state, connector, connector_state, i) {
if (connector_state->crtc != crtc_state->base.crtc)
continue;
encoder = to_intel_encoder(connector_state->best_encoder);
switch (encoder->type) {
case INTEL_OUTPUT_LVDS:
is_lvds = true;
break;
case INTEL_OUTPUT_SDVO:
case INTEL_OUTPUT_HDMI:
is_sdvo = true;
break;
default:
break;
}
}
/* Enable autotuning of the PLL clock (if permissible) */
factor = 21;
if (is_lvds) {
if ((intel_panel_use_ssc(dev_priv) &&
dev_priv->vbt.lvds_ssc_freq == 100000) ||
(HAS_PCH_IBX(dev) && intel_is_dual_link_lvds(dev)))
factor = 25;
} else if (crtc_state->sdvo_tv_clock)
factor = 20;
fp = i9xx_dpll_compute_fp(&crtc_state->dpll);
if (ironlake_needs_fb_cb_tune(&crtc_state->dpll, factor))
fp |= FP_CB_TUNE;
if (reduced_clock) {
fp2 = i9xx_dpll_compute_fp(reduced_clock);
if (reduced_clock->m < factor * reduced_clock->n)
fp2 |= FP_CB_TUNE;
} else {
fp2 = fp;
}
dpll = 0;
if (is_lvds)
dpll |= DPLLB_MODE_LVDS;
else
dpll |= DPLLB_MODE_DAC_SERIAL;
dpll |= (crtc_state->pixel_multiplier - 1)
<< PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
if (is_sdvo)
dpll |= DPLL_SDVO_HIGH_SPEED;
if (crtc_state->has_dp_encoder)
dpll |= DPLL_SDVO_HIGH_SPEED;
/* compute bitmask from p1 value */
dpll |= (1 << (crtc_state->dpll.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
/* also FPA1 */
dpll |= (1 << (crtc_state->dpll.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
switch (crtc_state->dpll.p2) {
case 5:
dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
break;
case 7:
dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
break;
case 10:
dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
break;
case 14:
dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
break;
}
if (is_lvds && intel_panel_use_ssc(dev_priv))
dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
else
dpll |= PLL_REF_INPUT_DREFCLK;
dpll |= DPLL_VCO_ENABLE;
crtc_state->dpll_hw_state.dpll = dpll;
crtc_state->dpll_hw_state.fp0 = fp;
crtc_state->dpll_hw_state.fp1 = fp2;
}
static int ironlake_crtc_compute_clock(struct intel_crtc *crtc,
struct intel_crtc_state *crtc_state)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct dpll reduced_clock;
bool has_reduced_clock = false;
drm/i915: switch crtc->shared_dpll from a pointer to an enum 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ä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-06-07 23:10:03 +02:00
struct intel_shared_dpll *pll;
const struct intel_limit *limit;
int refclk = 120000;
memset(&crtc_state->dpll_hw_state, 0,
sizeof(crtc_state->dpll_hw_state));
crtc->lowfreq_avail = false;
/* CPU eDP is the only output that doesn't need a PCH PLL of its own. */
if (!crtc_state->has_pch_encoder)
return 0;
if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
if (intel_panel_use_ssc(dev_priv)) {
DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n",
dev_priv->vbt.lvds_ssc_freq);
refclk = dev_priv->vbt.lvds_ssc_freq;
}
if (intel_is_dual_link_lvds(dev)) {
if (refclk == 100000)
limit = &intel_limits_ironlake_dual_lvds_100m;
else
limit = &intel_limits_ironlake_dual_lvds;
} else {
if (refclk == 100000)
limit = &intel_limits_ironlake_single_lvds_100m;
else
limit = &intel_limits_ironlake_single_lvds;
}
} else {
limit = &intel_limits_ironlake_dac;
}
if (!crtc_state->clock_set &&
!g4x_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
refclk, NULL, &crtc_state->dpll)) {
DRM_ERROR("Couldn't find PLL settings for mode!\n");
return -EINVAL;
}
ironlake_compute_dpll(crtc, crtc_state,
has_reduced_clock ? &reduced_clock : NULL);
pll = intel_get_shared_dpll(crtc, crtc_state, NULL);
if (pll == NULL) {
DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
pipe_name(crtc->pipe));
return -EINVAL;
}
if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) &&
has_reduced_clock)
crtc->lowfreq_avail = true;
drm/i915: switch crtc->shared_dpll from a pointer to an enum 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ä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-06-07 23:10:03 +02:00
return 0;
}
static void intel_pch_transcoder_get_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;
enum pipe pipe = crtc->pipe;
m_n->link_m = I915_READ(PCH_TRANS_LINK_M1(pipe));
m_n->link_n = I915_READ(PCH_TRANS_LINK_N1(pipe));
m_n->gmch_m = I915_READ(PCH_TRANS_DATA_M1(pipe))
& ~TU_SIZE_MASK;
m_n->gmch_n = I915_READ(PCH_TRANS_DATA_N1(pipe));
m_n->tu = ((I915_READ(PCH_TRANS_DATA_M1(pipe))
& TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1;
}
static void intel_cpu_transcoder_get_m_n(struct intel_crtc *crtc,
enum transcoder transcoder,
drm/i915: State readout and cross-checking for dp_m2_n2 Adding relevant read out comparison code, in check_crtc_state, for the new member of crtc_config, dp_m2_n2, which was introduced to store link_m_n values for a DP downclock mode (if available). Suggested by Daniel. v2: Changed patch title. Daniel's review comments incorporated. Added relevant state readout code for M2_N2. dp_m2_n2 comparison to be done only when high RR is not in use (This is because alternate m_n register programming will be done only when low RR is being used). v3: Modified call to get_m2_n2 which had dp_m_n as param by mistake. Compare dp_m_n and dp_m2_n2 for gen 7 and below. compare the structures based on DRRS state for gen 8 and above. Save and restore M2 N2 registers for gen 7 and below v4: For Gen>=8, check M_N registers against dp_m_n and dp_m2_n2 as there is only one set of M_N registers v5: Removed the chunk which saves and restores M2_N2 registers. Modified get_m_n() to get M2_N2 registers as well. Modified the macro which compares hw.dp_m_n against sw.dp_m2_n2/sw.dp_m_n for gen > 8. v6: Added check to compare dp_m2_n2 only when DRRS is enabled v7: Modified drrs check to use has_drrs v8: Add has_drrs check before reading M2_N2 registers Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Jani Nikula <jani.nikula@linux.intel.com> Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-08-05 07:51:23 -07:00
struct intel_link_m_n *m_n,
struct intel_link_m_n *m2_n2)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
enum pipe pipe = crtc->pipe;
if (INTEL_INFO(dev)->gen >= 5) {
m_n->link_m = I915_READ(PIPE_LINK_M1(transcoder));
m_n->link_n = I915_READ(PIPE_LINK_N1(transcoder));
m_n->gmch_m = I915_READ(PIPE_DATA_M1(transcoder))
& ~TU_SIZE_MASK;
m_n->gmch_n = I915_READ(PIPE_DATA_N1(transcoder));
m_n->tu = ((I915_READ(PIPE_DATA_M1(transcoder))
& TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1;
drm/i915: State readout and cross-checking for dp_m2_n2 Adding relevant read out comparison code, in check_crtc_state, for the new member of crtc_config, dp_m2_n2, which was introduced to store link_m_n values for a DP downclock mode (if available). Suggested by Daniel. v2: Changed patch title. Daniel's review comments incorporated. Added relevant state readout code for M2_N2. dp_m2_n2 comparison to be done only when high RR is not in use (This is because alternate m_n register programming will be done only when low RR is being used). v3: Modified call to get_m2_n2 which had dp_m_n as param by mistake. Compare dp_m_n and dp_m2_n2 for gen 7 and below. compare the structures based on DRRS state for gen 8 and above. Save and restore M2 N2 registers for gen 7 and below v4: For Gen>=8, check M_N registers against dp_m_n and dp_m2_n2 as there is only one set of M_N registers v5: Removed the chunk which saves and restores M2_N2 registers. Modified get_m_n() to get M2_N2 registers as well. Modified the macro which compares hw.dp_m_n against sw.dp_m2_n2/sw.dp_m_n for gen > 8. v6: Added check to compare dp_m2_n2 only when DRRS is enabled v7: Modified drrs check to use has_drrs v8: Add has_drrs check before reading M2_N2 registers Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Jani Nikula <jani.nikula@linux.intel.com> Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-08-05 07:51:23 -07:00
/* Read M2_N2 registers only for gen < 8 (M2_N2 available for
* gen < 8) and if DRRS is supported (to make sure the
* registers are not unnecessarily read).
*/
if (m2_n2 && INTEL_INFO(dev)->gen < 8 &&
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
crtc->config->has_drrs) {
drm/i915: State readout and cross-checking for dp_m2_n2 Adding relevant read out comparison code, in check_crtc_state, for the new member of crtc_config, dp_m2_n2, which was introduced to store link_m_n values for a DP downclock mode (if available). Suggested by Daniel. v2: Changed patch title. Daniel's review comments incorporated. Added relevant state readout code for M2_N2. dp_m2_n2 comparison to be done only when high RR is not in use (This is because alternate m_n register programming will be done only when low RR is being used). v3: Modified call to get_m2_n2 which had dp_m_n as param by mistake. Compare dp_m_n and dp_m2_n2 for gen 7 and below. compare the structures based on DRRS state for gen 8 and above. Save and restore M2 N2 registers for gen 7 and below v4: For Gen>=8, check M_N registers against dp_m_n and dp_m2_n2 as there is only one set of M_N registers v5: Removed the chunk which saves and restores M2_N2 registers. Modified get_m_n() to get M2_N2 registers as well. Modified the macro which compares hw.dp_m_n against sw.dp_m2_n2/sw.dp_m_n for gen > 8. v6: Added check to compare dp_m2_n2 only when DRRS is enabled v7: Modified drrs check to use has_drrs v8: Add has_drrs check before reading M2_N2 registers Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Jani Nikula <jani.nikula@linux.intel.com> Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-08-05 07:51:23 -07:00
m2_n2->link_m = I915_READ(PIPE_LINK_M2(transcoder));
m2_n2->link_n = I915_READ(PIPE_LINK_N2(transcoder));
m2_n2->gmch_m = I915_READ(PIPE_DATA_M2(transcoder))
& ~TU_SIZE_MASK;
m2_n2->gmch_n = I915_READ(PIPE_DATA_N2(transcoder));
m2_n2->tu = ((I915_READ(PIPE_DATA_M2(transcoder))
& TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1;
}
} else {
m_n->link_m = I915_READ(PIPE_LINK_M_G4X(pipe));
m_n->link_n = I915_READ(PIPE_LINK_N_G4X(pipe));
m_n->gmch_m = I915_READ(PIPE_DATA_M_G4X(pipe))
& ~TU_SIZE_MASK;
m_n->gmch_n = I915_READ(PIPE_DATA_N_G4X(pipe));
m_n->tu = ((I915_READ(PIPE_DATA_M_G4X(pipe))
& TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1;
}
}
void intel_dp_get_m_n(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config)
{
if (pipe_config->has_pch_encoder)
intel_pch_transcoder_get_m_n(crtc, &pipe_config->dp_m_n);
else
intel_cpu_transcoder_get_m_n(crtc, pipe_config->cpu_transcoder,
drm/i915: State readout and cross-checking for dp_m2_n2 Adding relevant read out comparison code, in check_crtc_state, for the new member of crtc_config, dp_m2_n2, which was introduced to store link_m_n values for a DP downclock mode (if available). Suggested by Daniel. v2: Changed patch title. Daniel's review comments incorporated. Added relevant state readout code for M2_N2. dp_m2_n2 comparison to be done only when high RR is not in use (This is because alternate m_n register programming will be done only when low RR is being used). v3: Modified call to get_m2_n2 which had dp_m_n as param by mistake. Compare dp_m_n and dp_m2_n2 for gen 7 and below. compare the structures based on DRRS state for gen 8 and above. Save and restore M2 N2 registers for gen 7 and below v4: For Gen>=8, check M_N registers against dp_m_n and dp_m2_n2 as there is only one set of M_N registers v5: Removed the chunk which saves and restores M2_N2 registers. Modified get_m_n() to get M2_N2 registers as well. Modified the macro which compares hw.dp_m_n against sw.dp_m2_n2/sw.dp_m_n for gen > 8. v6: Added check to compare dp_m2_n2 only when DRRS is enabled v7: Modified drrs check to use has_drrs v8: Add has_drrs check before reading M2_N2 registers Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Jani Nikula <jani.nikula@linux.intel.com> Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-08-05 07:51:23 -07:00
&pipe_config->dp_m_n,
&pipe_config->dp_m2_n2);
}
static void ironlake_get_fdi_m_n_config(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config)
{
intel_cpu_transcoder_get_m_n(crtc, pipe_config->cpu_transcoder,
drm/i915: State readout and cross-checking for dp_m2_n2 Adding relevant read out comparison code, in check_crtc_state, for the new member of crtc_config, dp_m2_n2, which was introduced to store link_m_n values for a DP downclock mode (if available). Suggested by Daniel. v2: Changed patch title. Daniel's review comments incorporated. Added relevant state readout code for M2_N2. dp_m2_n2 comparison to be done only when high RR is not in use (This is because alternate m_n register programming will be done only when low RR is being used). v3: Modified call to get_m2_n2 which had dp_m_n as param by mistake. Compare dp_m_n and dp_m2_n2 for gen 7 and below. compare the structures based on DRRS state for gen 8 and above. Save and restore M2 N2 registers for gen 7 and below v4: For Gen>=8, check M_N registers against dp_m_n and dp_m2_n2 as there is only one set of M_N registers v5: Removed the chunk which saves and restores M2_N2 registers. Modified get_m_n() to get M2_N2 registers as well. Modified the macro which compares hw.dp_m_n against sw.dp_m2_n2/sw.dp_m_n for gen > 8. v6: Added check to compare dp_m2_n2 only when DRRS is enabled v7: Modified drrs check to use has_drrs v8: Add has_drrs check before reading M2_N2 registers Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Jani Nikula <jani.nikula@linux.intel.com> Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-08-05 07:51:23 -07:00
&pipe_config->fdi_m_n, NULL);
}
static void skylake_get_pfit_config(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc_scaler_state *scaler_state = &pipe_config->scaler_state;
uint32_t ps_ctrl = 0;
int id = -1;
int i;
/* find scaler attached to this pipe */
for (i = 0; i < crtc->num_scalers; i++) {
ps_ctrl = I915_READ(SKL_PS_CTRL(crtc->pipe, i));
if (ps_ctrl & PS_SCALER_EN && !(ps_ctrl & PS_PLANE_SEL_MASK)) {
id = i;
pipe_config->pch_pfit.enabled = true;
pipe_config->pch_pfit.pos = I915_READ(SKL_PS_WIN_POS(crtc->pipe, i));
pipe_config->pch_pfit.size = I915_READ(SKL_PS_WIN_SZ(crtc->pipe, i));
break;
}
}
scaler_state->scaler_id = id;
if (id >= 0) {
scaler_state->scaler_users |= (1 << SKL_CRTC_INDEX);
} else {
scaler_state->scaler_users &= ~(1 << SKL_CRTC_INDEX);
}
}
static void
skylake_get_initial_plane_config(struct intel_crtc *crtc,
struct intel_initial_plane_config *plane_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 val, base, offset, stride_mult, tiling;
int pipe = crtc->pipe;
int fourcc, pixel_format;
unsigned int aligned_height;
struct drm_framebuffer *fb;
struct intel_framebuffer *intel_fb;
intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
if (!intel_fb) {
DRM_DEBUG_KMS("failed to alloc fb\n");
return;
}
fb = &intel_fb->base;
val = I915_READ(PLANE_CTL(pipe, 0));
if (!(val & PLANE_CTL_ENABLE))
goto error;
pixel_format = val & PLANE_CTL_FORMAT_MASK;
fourcc = skl_format_to_fourcc(pixel_format,
val & PLANE_CTL_ORDER_RGBX,
val & PLANE_CTL_ALPHA_MASK);
fb->pixel_format = fourcc;
fb->bits_per_pixel = drm_format_plane_cpp(fourcc, 0) * 8;
tiling = val & PLANE_CTL_TILED_MASK;
switch (tiling) {
case PLANE_CTL_TILED_LINEAR:
fb->modifier[0] = DRM_FORMAT_MOD_NONE;
break;
case PLANE_CTL_TILED_X:
plane_config->tiling = I915_TILING_X;
fb->modifier[0] = I915_FORMAT_MOD_X_TILED;
break;
case PLANE_CTL_TILED_Y:
fb->modifier[0] = I915_FORMAT_MOD_Y_TILED;
break;
case PLANE_CTL_TILED_YF:
fb->modifier[0] = I915_FORMAT_MOD_Yf_TILED;
break;
default:
MISSING_CASE(tiling);
goto error;
}
base = I915_READ(PLANE_SURF(pipe, 0)) & 0xfffff000;
plane_config->base = base;
offset = I915_READ(PLANE_OFFSET(pipe, 0));
val = I915_READ(PLANE_SIZE(pipe, 0));
fb->height = ((val >> 16) & 0xfff) + 1;
fb->width = ((val >> 0) & 0x1fff) + 1;
val = I915_READ(PLANE_STRIDE(pipe, 0));
stride_mult = intel_fb_stride_alignment(dev_priv, fb->modifier[0],
fb->pixel_format);
fb->pitches[0] = (val & 0x3ff) * stride_mult;
aligned_height = intel_fb_align_height(dev, fb->height,
fb->pixel_format,
fb->modifier[0]);
plane_config->size = fb->pitches[0] * aligned_height;
DRM_DEBUG_KMS("pipe %c with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
pipe_name(pipe), fb->width, fb->height,
fb->bits_per_pixel, base, fb->pitches[0],
plane_config->size);
plane_config->fb = intel_fb;
return;
error:
kfree(fb);
}
static void ironlake_get_pfit_config(struct intel_crtc *crtc,
struct intel_crtc_state *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.enabled = true;
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));
}
}
}
static void
ironlake_get_initial_plane_config(struct intel_crtc *crtc,
struct intel_initial_plane_config *plane_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 val, base, offset;
int pipe = crtc->pipe;
int fourcc, pixel_format;
unsigned int aligned_height;
struct drm_framebuffer *fb;
struct intel_framebuffer *intel_fb;
val = I915_READ(DSPCNTR(pipe));
if (!(val & DISPLAY_PLANE_ENABLE))
return;
intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
if (!intel_fb) {
DRM_DEBUG_KMS("failed to alloc fb\n");
return;
}
fb = &intel_fb->base;
if (INTEL_INFO(dev)->gen >= 4) {
if (val & DISPPLANE_TILED) {
plane_config->tiling = I915_TILING_X;
fb->modifier[0] = I915_FORMAT_MOD_X_TILED;
}
}
pixel_format = val & DISPPLANE_PIXFORMAT_MASK;
fourcc = i9xx_format_to_fourcc(pixel_format);
fb->pixel_format = fourcc;
fb->bits_per_pixel = drm_format_plane_cpp(fourcc, 0) * 8;
base = I915_READ(DSPSURF(pipe)) & 0xfffff000;
if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
offset = I915_READ(DSPOFFSET(pipe));
} else {
if (plane_config->tiling)
offset = I915_READ(DSPTILEOFF(pipe));
else
offset = I915_READ(DSPLINOFF(pipe));
}
plane_config->base = base;
val = I915_READ(PIPESRC(pipe));
fb->width = ((val >> 16) & 0xfff) + 1;
fb->height = ((val >> 0) & 0xfff) + 1;
val = I915_READ(DSPSTRIDE(pipe));
fb->pitches[0] = val & 0xffffffc0;
aligned_height = intel_fb_align_height(dev, fb->height,
fb->pixel_format,
fb->modifier[0]);
plane_config->size = fb->pitches[0] * aligned_height;
DRM_DEBUG_KMS("pipe %c with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
pipe_name(pipe), fb->width, fb->height,
fb->bits_per_pixel, base, fb->pitches[0],
plane_config->size);
plane_config->fb = intel_fb;
}
static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
enum intel_display_power_domain power_domain;
uint32_t tmp;
bool ret;
power_domain = POWER_DOMAIN_PIPE(crtc->pipe);
if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
return false;
pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
pipe_config->shared_dpll = NULL;
ret = false;
tmp = I915_READ(PIPECONF(crtc->pipe));
if (!(tmp & PIPECONF_ENABLE))
goto out;
switch (tmp & PIPECONF_BPC_MASK) {
case PIPECONF_6BPC:
pipe_config->pipe_bpp = 18;
break;
case PIPECONF_8BPC:
pipe_config->pipe_bpp = 24;
break;
case PIPECONF_10BPC:
pipe_config->pipe_bpp = 30;
break;
case PIPECONF_12BPC:
pipe_config->pipe_bpp = 36;
break;
default:
break;
}
if (tmp & PIPECONF_COLOR_RANGE_SELECT)
pipe_config->limited_color_range = true;
if (I915_READ(PCH_TRANSCONF(crtc->pipe)) & TRANS_ENABLE) {
struct intel_shared_dpll *pll;
enum intel_dpll_id pll_id;
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;
ironlake_get_fdi_m_n_config(crtc, pipe_config);
if (HAS_PCH_IBX(dev_priv)) {
/*
* The pipe->pch transcoder and pch transcoder->pll
* mapping is fixed.
*/
pll_id = (enum intel_dpll_id) crtc->pipe;
drm/i915: hw state readout for shared pch plls 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ä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-06-07 23:11:08 +02:00
} else {
tmp = I915_READ(PCH_DPLL_SEL);
if (tmp & TRANS_DPLLB_SEL(crtc->pipe))
pll_id = DPLL_ID_PCH_PLL_B;
drm/i915: hw state readout for shared pch plls 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ä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-06-07 23:11:08 +02:00
else
pll_id= DPLL_ID_PCH_PLL_A;
drm/i915: hw state readout for shared pch plls 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ä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-06-07 23:11:08 +02:00
}
pipe_config->shared_dpll =
intel_get_shared_dpll_by_id(dev_priv, pll_id);
pll = pipe_config->shared_dpll;
WARN_ON(!pll->funcs.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;
ironlake_pch_clock_get(crtc, pipe_config);
} else {
pipe_config->pixel_multiplier = 1;
}
intel_get_pipe_timings(crtc, pipe_config);
intel_get_pipe_src_size(crtc, pipe_config);
ironlake_get_pfit_config(crtc, pipe_config);
ret = true;
out:
intel_display_power_put(dev_priv, power_domain);
return ret;
}
static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv)
{
struct drm_device *dev = dev_priv->dev;
struct intel_crtc *crtc;
for_each_intel_crtc(dev, crtc)
I915_STATE_WARN(crtc->active, "CRTC for pipe %c enabled\n",
pipe_name(crtc->pipe));
I915_STATE_WARN(I915_READ(HSW_PWR_WELL_DRIVER), "Power well on\n");
I915_STATE_WARN(I915_READ(SPLL_CTL) & SPLL_PLL_ENABLE, "SPLL enabled\n");
I915_STATE_WARN(I915_READ(WRPLL_CTL(0)) & WRPLL_PLL_ENABLE, "WRPLL1 enabled\n");
I915_STATE_WARN(I915_READ(WRPLL_CTL(1)) & WRPLL_PLL_ENABLE, "WRPLL2 enabled\n");
I915_STATE_WARN(I915_READ(PCH_PP_STATUS) & PP_ON, "Panel power on\n");
I915_STATE_WARN(I915_READ(BLC_PWM_CPU_CTL2) & BLM_PWM_ENABLE,
"CPU PWM1 enabled\n");
if (IS_HASWELL(dev))
I915_STATE_WARN(I915_READ(HSW_BLC_PWM2_CTL) & BLM_PWM_ENABLE,
"CPU PWM2 enabled\n");
I915_STATE_WARN(I915_READ(BLC_PWM_PCH_CTL1) & BLM_PCH_PWM_ENABLE,
"PCH PWM1 enabled\n");
I915_STATE_WARN(I915_READ(UTIL_PIN_CTL) & UTIL_PIN_ENABLE,
"Utility pin enabled\n");
I915_STATE_WARN(I915_READ(PCH_GTC_CTL) & PCH_GTC_ENABLE, "PCH GTC enabled\n");
/*
* In theory we can still leave IRQs enabled, as long as only the HPD
* interrupts remain enabled. We used to check for that, but since it's
* gen-specific and since we only disable LCPLL after we fully disable
* the interrupts, the check below should be enough.
*/
I915_STATE_WARN(intel_irqs_enabled(dev_priv), "IRQs enabled\n");
}
static uint32_t hsw_read_dcomp(struct drm_i915_private *dev_priv)
{
struct drm_device *dev = dev_priv->dev;
if (IS_HASWELL(dev))
return I915_READ(D_COMP_HSW);
else
return I915_READ(D_COMP_BDW);
}
static void hsw_write_dcomp(struct drm_i915_private *dev_priv, uint32_t val)
{
struct drm_device *dev = dev_priv->dev;
if (IS_HASWELL(dev)) {
mutex_lock(&dev_priv->rps.hw_lock);
if (sandybridge_pcode_write(dev_priv, GEN6_PCODE_WRITE_D_COMP,
val))
DRM_ERROR("Failed to write to D_COMP\n");
mutex_unlock(&dev_priv->rps.hw_lock);
} else {
I915_WRITE(D_COMP_BDW, val);
POSTING_READ(D_COMP_BDW);
}
}
/*
* 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.
*/
static 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_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 (intel_wait_for_register(dev_priv, LCPLL_CTL, LCPLL_PLL_LOCK, 0, 1))
DRM_ERROR("LCPLL still locked\n");
val = hsw_read_dcomp(dev_priv);
val |= D_COMP_COMP_DISABLE;
hsw_write_dcomp(dev_priv, val);
ndelay(100);
if (wait_for((hsw_read_dcomp(dev_priv) & 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.
*/
static 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;
drm/i915: make PC8 be part of runtime PM suspend/resume Currently, when our driver becomes idle for i915.pc8_timeout (default: 5s) we enable PC8, so we save some power, but not everything we can. Then, while PC8 is enabled, if we stay idle for more autosuspend_delay_ms (default: 10s) we'll enter runtime PM and put the graphics device in D3 state, saving even more power. The two features are separate things with increasing levels of power savings, but if we disable PC8 we'll never get into D3. While from the modularity point of view it would be nice to keep these features as separate, we have reasons to merge them: - We are not aware of anybody wanting a "PC8 without D3" environment. - If we keep both features as separate, we'll have to to test both PC8 and PC8+D3 code paths. We're already having a major pain to make QA do automated testing of just one thing, testing both paths will cost even more. - Only Haswell+ supports PC8, so if we want to add runtime PM support to, for example, IVB, we'll have to copy some code from the PC8 feature to runtime PM, so merging both features as a single thing will make it easier for enabling runtime PM on other platforms. This patch only does the very basic steps required to have PC8 and runtime PM merged on a single feature: the next patches will take care of cleaning up everything. v2: - Rebase. v3: - Rebase. - Fully remove the deprecated i915 params since Daniel doesn't consider them as part of the ABI. v4: - Rebase. - Fix typo in the commit message. v5: - Rebase, again. - Add a huge comment explaining the different forcewake usage (Chris, Daniel). - Use open-coded forcewake functions (Daniel). Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-03-07 20:08:05 -03:00
/*
* Make sure we're not on PC8 state before disabling PC8, otherwise
* we'll hang the machine. To prevent PC8 state, just enable force_wake.
*/
intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
if (val & LCPLL_POWER_DOWN_ALLOW) {
val &= ~LCPLL_POWER_DOWN_ALLOW;
I915_WRITE(LCPLL_CTL, val);
POSTING_READ(LCPLL_CTL);
}
val = hsw_read_dcomp(dev_priv);
val |= D_COMP_COMP_FORCE;
val &= ~D_COMP_COMP_DISABLE;
hsw_write_dcomp(dev_priv, val);
val = I915_READ(LCPLL_CTL);
val &= ~LCPLL_PLL_DISABLE;
I915_WRITE(LCPLL_CTL, val);
if (intel_wait_for_register(dev_priv,
LCPLL_CTL, LCPLL_PLL_LOCK, 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_us((I915_READ(LCPLL_CTL) &
LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1))
DRM_ERROR("Switching back to LCPLL failed\n");
}
intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
intel_update_cdclk(dev_priv->dev);
}
/*
* 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 going into runtime PM.
*
* The requirements for PC8+ are that all the outputs are disabled, the power
* well is disabled and most interrupts are disabled, and these are also
* requirements for runtime PM. When these conditions are met, we manually do
* the other conditions: disable the interrupts, clocks and switch LCPLL refclk
* to Fclk. If we're in PC8+ and we get an non-hotplug interrupt, we can hard
* hang the machine.
*
* 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. Notice that this happens even
* if we don't put the device in PCI D3 state (which is what currently happens
* because of the runtime PM support).
*
* For more, read "Display Sequences for Package C8" on the hardware
* documentation.
*/
void hsw_enable_pc8(struct drm_i915_private *dev_priv)
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 <paulo.r.zanoni@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-08-19 13:18:09 -03:00
{
struct drm_device *dev = dev_priv->dev;
uint32_t val;
DRM_DEBUG_KMS("Enabling package C8+\n");
if (HAS_PCH_LPT_LP(dev)) {
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 <paulo.r.zanoni@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-08-19 13:18:09 -03:00
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_disable_lcpll(dev_priv, true, true);
}
void hsw_disable_pc8(struct drm_i915_private *dev_priv)
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 <paulo.r.zanoni@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-08-19 13:18:09 -03:00
{
struct drm_device *dev = dev_priv->dev;
uint32_t val;
DRM_DEBUG_KMS("Disabling package C8+\n");
hsw_restore_lcpll(dev_priv);
lpt_init_pch_refclk(dev);
if (HAS_PCH_LPT_LP(dev)) {
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 <paulo.r.zanoni@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-08-19 13:18:09 -03:00
val = I915_READ(SOUTH_DSPCLK_GATE_D);
val |= PCH_LP_PARTITION_LEVEL_DISABLE;
I915_WRITE(SOUTH_DSPCLK_GATE_D, val);
}
}
static void bxt_modeset_commit_cdclk(struct drm_atomic_state *old_state)
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
{
struct drm_device *dev = old_state->dev;
struct intel_atomic_state *old_intel_state =
to_intel_atomic_state(old_state);
unsigned int req_cdclk = old_intel_state->dev_cdclk;
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
bxt_set_cdclk(to_i915(dev), req_cdclk);
drm/i915/bxt: add display initialize/uninitialize sequence (CDCLK) Add CDCLK specific display clock initialization sequence as per BSpec. Note that the CDCLK initialization/uninitialization are done at their current place only for simplicity, in a future patch - when more of the runtime PM features will be enabled - these will be moved to power well#1 and modeset encoder enabling/disabling hooks respectively. This also means that atm dynamic power gating power well #1 is effectively disabled. The call to uninitialize CDCLK during system/runtime suspend will be added later in this patchset. v1: Added function definitions in header files v2: Imre's review comments addressed - Moved CDCLK related definitions to i915_reg.h - Removed defintions for CDCLK frequency - Split uninit_cdclk() by adding a phy_uninit function - Calculate freq and decimal based on input frequency - Program SSA precharge based on input frequency - Use wait_for 1ms instead 200us udelay for DE PLL locking - Removed initial value for divider, freq, decimal, ratio. - Replaced polling loops with wait_for - Parameterized latency optim setting - Fix the parts where DE PLL has to be disabled. - Call CDCLK selection from mode set v3: (imre) - add note about the plan to move the cdclk/phy init to a better place - take rps.hw_lock around pcode access - move DE PLL register macros here from another patch since they are used here first - add BXT_ prefix to CDCLK flags - add missing masking when programming CDCLK_FREQ_DECIMAL v4: (ville) - split the CDCLK/PHY parts into two patches, update commit message accordingly - s/DISPLAY_PCU_CONTROL/HSW_PCODE_DE_WRITE_FREQ_REQ/ - simplify BXT_DE_PLL_RATIO macros - fix BXT_DE_PLL_RATIO_MASK - s/bxt_select_cdclk_freq/broxton_set_cdclk_freq/ - move cdclk init/uninit/set code from intel_ddi.c to intel_display.c - remove redundant code comments for broxton_set_cdclk_freq() - sanitize fixed point<->integer frequency value conversion - use DRM_ERROR instead of WARN - do RMW when programming BXT_DE_PLL_CTL for safety - add note about PLL lock timeout being exactly 200us - make PCU error messages more descriptive - instead of using 0 freq to mean PLL off/bypass freq use 19200 for clarity, as the latter one is the actual rate - simplify pcode programming, removing duplicated sandybridge_pcode_write() call - sanitize code flow, remove unnecessary scratch vars in broxton_set_cdclk() (imre) - Remove bound check for maxmimum freq to match current code. This check will be added later at a more proper platform independent place once atomic support lands. - add note to remove freq guard band which isn't needed on BXT - add note to reduce freq to minimum if no pipe is enabled - combine broxton_modeset_global_pipes() with valleyview_modeset_global_pipes() Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-24 13:37:39 +05:30
}
/* compute the max rate for new configuration */
static int ilk_max_pixel_rate(struct drm_atomic_state *state)
{
struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
struct drm_i915_private *dev_priv = state->dev->dev_private;
struct drm_crtc *crtc;
struct drm_crtc_state *cstate;
struct intel_crtc_state *crtc_state;
unsigned max_pixel_rate = 0, i;
enum pipe pipe;
memcpy(intel_state->min_pixclk, dev_priv->min_pixclk,
sizeof(intel_state->min_pixclk));
for_each_crtc_in_state(state, crtc, cstate, i) {
int pixel_rate;
crtc_state = to_intel_crtc_state(cstate);
if (!crtc_state->base.enable) {
intel_state->min_pixclk[i] = 0;
continue;
}
pixel_rate = ilk_pipe_pixel_rate(crtc_state);
/* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */
if (IS_BROADWELL(dev_priv) && crtc_state->ips_enabled)
pixel_rate = DIV_ROUND_UP(pixel_rate * 100, 95);
intel_state->min_pixclk[i] = pixel_rate;
}
for_each_pipe(dev_priv, pipe)
max_pixel_rate = max(intel_state->min_pixclk[pipe], max_pixel_rate);
return max_pixel_rate;
}
static void broadwell_set_cdclk(struct drm_device *dev, int cdclk)
{
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t val, data;
int ret;
if (WARN((I915_READ(LCPLL_CTL) &
(LCPLL_PLL_DISABLE | LCPLL_PLL_LOCK |
LCPLL_CD_CLOCK_DISABLE | LCPLL_ROOT_CD_CLOCK_DISABLE |
LCPLL_CD2X_CLOCK_DISABLE | LCPLL_POWER_DOWN_ALLOW |
LCPLL_CD_SOURCE_FCLK)) != LCPLL_PLL_LOCK,
"trying to change cdclk frequency with cdclk not enabled\n"))
return;
mutex_lock(&dev_priv->rps.hw_lock);
ret = sandybridge_pcode_write(dev_priv,
BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ, 0x0);
mutex_unlock(&dev_priv->rps.hw_lock);
if (ret) {
DRM_ERROR("failed to inform pcode about cdclk change\n");
return;
}
val = I915_READ(LCPLL_CTL);
val |= LCPLL_CD_SOURCE_FCLK;
I915_WRITE(LCPLL_CTL, val);
if (wait_for_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_CLK_FREQ_MASK;
switch (cdclk) {
case 450000:
val |= LCPLL_CLK_FREQ_450;
data = 0;
break;
case 540000:
val |= LCPLL_CLK_FREQ_54O_BDW;
data = 1;
break;
case 337500:
val |= LCPLL_CLK_FREQ_337_5_BDW;
data = 2;
break;
case 675000:
val |= LCPLL_CLK_FREQ_675_BDW;
data = 3;
break;
default:
WARN(1, "invalid cdclk frequency\n");
return;
}
I915_WRITE(LCPLL_CTL, val);
val = I915_READ(LCPLL_CTL);
val &= ~LCPLL_CD_SOURCE_FCLK;
I915_WRITE(LCPLL_CTL, val);
if (wait_for_us((I915_READ(LCPLL_CTL) &
LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1))
DRM_ERROR("Switching back to LCPLL failed\n");
mutex_lock(&dev_priv->rps.hw_lock);
sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, data);
mutex_unlock(&dev_priv->rps.hw_lock);
I915_WRITE(CDCLK_FREQ, DIV_ROUND_CLOSEST(cdclk, 1000) - 1);
intel_update_cdclk(dev);
WARN(cdclk != dev_priv->cdclk_freq,
"cdclk requested %d kHz but got %d kHz\n",
cdclk, dev_priv->cdclk_freq);
}
static int broadwell_calc_cdclk(int max_pixclk)
{
if (max_pixclk > 540000)
return 675000;
else if (max_pixclk > 450000)
return 540000;
else if (max_pixclk > 337500)
return 450000;
else
return 337500;
}
static int broadwell_modeset_calc_cdclk(struct drm_atomic_state *state)
{
struct drm_i915_private *dev_priv = to_i915(state->dev);
struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
int max_pixclk = ilk_max_pixel_rate(state);
int cdclk;
/*
* FIXME should also account for plane ratio
* once 64bpp pixel formats are supported.
*/
cdclk = broadwell_calc_cdclk(max_pixclk);
if (cdclk > dev_priv->max_cdclk_freq) {
DRM_DEBUG_KMS("requested cdclk (%d kHz) exceeds max (%d kHz)\n",
cdclk, dev_priv->max_cdclk_freq);
return -EINVAL;
}
intel_state->cdclk = intel_state->dev_cdclk = cdclk;
if (!intel_state->active_crtcs)
intel_state->dev_cdclk = broadwell_calc_cdclk(0);
return 0;
}
static void broadwell_modeset_commit_cdclk(struct drm_atomic_state *old_state)
{
struct drm_device *dev = old_state->dev;
struct intel_atomic_state *old_intel_state =
to_intel_atomic_state(old_state);
unsigned req_cdclk = old_intel_state->dev_cdclk;
broadwell_set_cdclk(dev, req_cdclk);
}
drm/i915/skl: SKL CDCLK change on modeset tracking VCO WARNING: Using ChromeOS with an eDP panel and a 4K@60 DP monitor connected to DDI1 the system will hard hang during a cold boot. Occurs when DDI1 is enabled when the cdclk is less then required. DP connected to DDI2 and HPD on either port works correctly. Set cdclk based on the max required pixel clock based on VCO selected. Track boot vco instead of boot cdclk. The vco is now tracked at the atomic level and all CRTCs updated if the required vco is changed. Not tested with eDP v1.4 panels that require 8640 vco due to availability. V1: initial version V2: add vco tracking in intel_dp_compute_config(), rename skl_boot_cdclk. V3: rebase, V2 feedback not possible as encoders are not aware of atomic. V4: track target vco is atomic state. modeset all CRTCs if vco changes V5: rename atomic variable, cleaner if/else logic, use existing vco if encoder does not return a new vco value. check_patch.pl cleanup V6: simplify logic in intel_modeset_checks. V7: reorder an IF for readability and whitespace fix. V8: use dev_cdclk for tracking new cdclk during atomic V9: correctly handle vco 8640 when crtcs==0 V10: Clean up if else in crtcs==0 V11: Rebase for new intel_dpll_mgr.c Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Clint Taylor <clinton.a.taylor@intel.com> [vsyrjala: rebased due to churn] Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1463172100-24715-3-git-send-email-ville.syrjala@linux.intel.com
2016-05-13 23:41:21 +03:00
static int skl_modeset_calc_cdclk(struct drm_atomic_state *state)
{
struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
struct drm_i915_private *dev_priv = to_i915(state->dev);
const int max_pixclk = ilk_max_pixel_rate(state);
int vco = intel_state->cdclk_pll_vco;
drm/i915/skl: SKL CDCLK change on modeset tracking VCO WARNING: Using ChromeOS with an eDP panel and a 4K@60 DP monitor connected to DDI1 the system will hard hang during a cold boot. Occurs when DDI1 is enabled when the cdclk is less then required. DP connected to DDI2 and HPD on either port works correctly. Set cdclk based on the max required pixel clock based on VCO selected. Track boot vco instead of boot cdclk. The vco is now tracked at the atomic level and all CRTCs updated if the required vco is changed. Not tested with eDP v1.4 panels that require 8640 vco due to availability. V1: initial version V2: add vco tracking in intel_dp_compute_config(), rename skl_boot_cdclk. V3: rebase, V2 feedback not possible as encoders are not aware of atomic. V4: track target vco is atomic state. modeset all CRTCs if vco changes V5: rename atomic variable, cleaner if/else logic, use existing vco if encoder does not return a new vco value. check_patch.pl cleanup V6: simplify logic in intel_modeset_checks. V7: reorder an IF for readability and whitespace fix. V8: use dev_cdclk for tracking new cdclk during atomic V9: correctly handle vco 8640 when crtcs==0 V10: Clean up if else in crtcs==0 V11: Rebase for new intel_dpll_mgr.c Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Clint Taylor <clinton.a.taylor@intel.com> [vsyrjala: rebased due to churn] Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1463172100-24715-3-git-send-email-ville.syrjala@linux.intel.com
2016-05-13 23:41:21 +03:00
int cdclk;
/*
* FIXME should also account for plane ratio
* once 64bpp pixel formats are supported.
*/
cdclk = skl_calc_cdclk(max_pixclk, vco);
drm/i915/skl: SKL CDCLK change on modeset tracking VCO WARNING: Using ChromeOS with an eDP panel and a 4K@60 DP monitor connected to DDI1 the system will hard hang during a cold boot. Occurs when DDI1 is enabled when the cdclk is less then required. DP connected to DDI2 and HPD on either port works correctly. Set cdclk based on the max required pixel clock based on VCO selected. Track boot vco instead of boot cdclk. The vco is now tracked at the atomic level and all CRTCs updated if the required vco is changed. Not tested with eDP v1.4 panels that require 8640 vco due to availability. V1: initial version V2: add vco tracking in intel_dp_compute_config(), rename skl_boot_cdclk. V3: rebase, V2 feedback not possible as encoders are not aware of atomic. V4: track target vco is atomic state. modeset all CRTCs if vco changes V5: rename atomic variable, cleaner if/else logic, use existing vco if encoder does not return a new vco value. check_patch.pl cleanup V6: simplify logic in intel_modeset_checks. V7: reorder an IF for readability and whitespace fix. V8: use dev_cdclk for tracking new cdclk during atomic V9: correctly handle vco 8640 when crtcs==0 V10: Clean up if else in crtcs==0 V11: Rebase for new intel_dpll_mgr.c Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Clint Taylor <clinton.a.taylor@intel.com> [vsyrjala: rebased due to churn] Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1463172100-24715-3-git-send-email-ville.syrjala@linux.intel.com
2016-05-13 23:41:21 +03:00
/*
* FIXME move the cdclk caclulation to
* compute_config() so we can fail gracegully.
*/
if (cdclk > dev_priv->max_cdclk_freq) {
DRM_ERROR("requested cdclk (%d kHz) exceeds max (%d kHz)\n",
cdclk, dev_priv->max_cdclk_freq);
cdclk = dev_priv->max_cdclk_freq;
}
intel_state->cdclk = intel_state->dev_cdclk = cdclk;
if (!intel_state->active_crtcs)
intel_state->dev_cdclk = skl_calc_cdclk(0, vco);
drm/i915/skl: SKL CDCLK change on modeset tracking VCO WARNING: Using ChromeOS with an eDP panel and a 4K@60 DP monitor connected to DDI1 the system will hard hang during a cold boot. Occurs when DDI1 is enabled when the cdclk is less then required. DP connected to DDI2 and HPD on either port works correctly. Set cdclk based on the max required pixel clock based on VCO selected. Track boot vco instead of boot cdclk. The vco is now tracked at the atomic level and all CRTCs updated if the required vco is changed. Not tested with eDP v1.4 panels that require 8640 vco due to availability. V1: initial version V2: add vco tracking in intel_dp_compute_config(), rename skl_boot_cdclk. V3: rebase, V2 feedback not possible as encoders are not aware of atomic. V4: track target vco is atomic state. modeset all CRTCs if vco changes V5: rename atomic variable, cleaner if/else logic, use existing vco if encoder does not return a new vco value. check_patch.pl cleanup V6: simplify logic in intel_modeset_checks. V7: reorder an IF for readability and whitespace fix. V8: use dev_cdclk for tracking new cdclk during atomic V9: correctly handle vco 8640 when crtcs==0 V10: Clean up if else in crtcs==0 V11: Rebase for new intel_dpll_mgr.c Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Clint Taylor <clinton.a.taylor@intel.com> [vsyrjala: rebased due to churn] Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1463172100-24715-3-git-send-email-ville.syrjala@linux.intel.com
2016-05-13 23:41:21 +03:00
return 0;
}
static void skl_modeset_commit_cdclk(struct drm_atomic_state *old_state)
{
struct drm_i915_private *dev_priv = to_i915(old_state->dev);
struct intel_atomic_state *intel_state = to_intel_atomic_state(old_state);
unsigned int req_cdclk = intel_state->dev_cdclk;
unsigned int req_vco = intel_state->cdclk_pll_vco;
drm/i915/skl: SKL CDCLK change on modeset tracking VCO WARNING: Using ChromeOS with an eDP panel and a 4K@60 DP monitor connected to DDI1 the system will hard hang during a cold boot. Occurs when DDI1 is enabled when the cdclk is less then required. DP connected to DDI2 and HPD on either port works correctly. Set cdclk based on the max required pixel clock based on VCO selected. Track boot vco instead of boot cdclk. The vco is now tracked at the atomic level and all CRTCs updated if the required vco is changed. Not tested with eDP v1.4 panels that require 8640 vco due to availability. V1: initial version V2: add vco tracking in intel_dp_compute_config(), rename skl_boot_cdclk. V3: rebase, V2 feedback not possible as encoders are not aware of atomic. V4: track target vco is atomic state. modeset all CRTCs if vco changes V5: rename atomic variable, cleaner if/else logic, use existing vco if encoder does not return a new vco value. check_patch.pl cleanup V6: simplify logic in intel_modeset_checks. V7: reorder an IF for readability and whitespace fix. V8: use dev_cdclk for tracking new cdclk during atomic V9: correctly handle vco 8640 when crtcs==0 V10: Clean up if else in crtcs==0 V11: Rebase for new intel_dpll_mgr.c Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Clint Taylor <clinton.a.taylor@intel.com> [vsyrjala: rebased due to churn] Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1463172100-24715-3-git-send-email-ville.syrjala@linux.intel.com
2016-05-13 23:41:21 +03:00
skl_set_cdclk(dev_priv, req_cdclk, req_vco);
drm/i915/skl: SKL CDCLK change on modeset tracking VCO WARNING: Using ChromeOS with an eDP panel and a 4K@60 DP monitor connected to DDI1 the system will hard hang during a cold boot. Occurs when DDI1 is enabled when the cdclk is less then required. DP connected to DDI2 and HPD on either port works correctly. Set cdclk based on the max required pixel clock based on VCO selected. Track boot vco instead of boot cdclk. The vco is now tracked at the atomic level and all CRTCs updated if the required vco is changed. Not tested with eDP v1.4 panels that require 8640 vco due to availability. V1: initial version V2: add vco tracking in intel_dp_compute_config(), rename skl_boot_cdclk. V3: rebase, V2 feedback not possible as encoders are not aware of atomic. V4: track target vco is atomic state. modeset all CRTCs if vco changes V5: rename atomic variable, cleaner if/else logic, use existing vco if encoder does not return a new vco value. check_patch.pl cleanup V6: simplify logic in intel_modeset_checks. V7: reorder an IF for readability and whitespace fix. V8: use dev_cdclk for tracking new cdclk during atomic V9: correctly handle vco 8640 when crtcs==0 V10: Clean up if else in crtcs==0 V11: Rebase for new intel_dpll_mgr.c Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Clint Taylor <clinton.a.taylor@intel.com> [vsyrjala: rebased due to churn] Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1463172100-24715-3-git-send-email-ville.syrjala@linux.intel.com
2016-05-13 23:41:21 +03:00
}
static int haswell_crtc_compute_clock(struct intel_crtc *crtc,
struct intel_crtc_state *crtc_state)
{
struct intel_encoder *intel_encoder =
intel_ddi_get_crtc_new_encoder(crtc_state);
if (intel_encoder->type != INTEL_OUTPUT_DSI) {
if (!intel_ddi_pll_select(crtc, crtc_state))
return -EINVAL;
}
crtc->lowfreq_avail = false;
return 0;
}
static void bxt_get_ddi_pll(struct drm_i915_private *dev_priv,
enum port port,
struct intel_crtc_state *pipe_config)
{
enum intel_dpll_id id;
switch (port) {
case PORT_A:
pipe_config->ddi_pll_sel = SKL_DPLL0;
id = DPLL_ID_SKL_DPLL0;
break;
case PORT_B:
pipe_config->ddi_pll_sel = SKL_DPLL1;
id = DPLL_ID_SKL_DPLL1;
break;
case PORT_C:
pipe_config->ddi_pll_sel = SKL_DPLL2;
id = DPLL_ID_SKL_DPLL2;
break;
default:
DRM_ERROR("Incorrect port type\n");
return;
}
pipe_config->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, id);
}
static void skylake_get_ddi_pll(struct drm_i915_private *dev_priv,
enum port port,
struct intel_crtc_state *pipe_config)
{
enum intel_dpll_id id;
u32 temp;
temp = I915_READ(DPLL_CTRL2) & DPLL_CTRL2_DDI_CLK_SEL_MASK(port);
pipe_config->ddi_pll_sel = temp >> (port * 3 + 1);
switch (pipe_config->ddi_pll_sel) {
case SKL_DPLL0:
id = DPLL_ID_SKL_DPLL0;
break;
case SKL_DPLL1:
id = DPLL_ID_SKL_DPLL1;
break;
case SKL_DPLL2:
id = DPLL_ID_SKL_DPLL2;
break;
case SKL_DPLL3:
id = DPLL_ID_SKL_DPLL3;
break;
default:
MISSING_CASE(pipe_config->ddi_pll_sel);
return;
}
pipe_config->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, id);
}
static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv,
enum port port,
struct intel_crtc_state *pipe_config)
{
enum intel_dpll_id id;
pipe_config->ddi_pll_sel = I915_READ(PORT_CLK_SEL(port));
switch (pipe_config->ddi_pll_sel) {
case PORT_CLK_SEL_WRPLL1:
id = DPLL_ID_WRPLL1;
break;
case PORT_CLK_SEL_WRPLL2:
id = DPLL_ID_WRPLL2;
break;
case PORT_CLK_SEL_SPLL:
id = DPLL_ID_SPLL;
break;
case PORT_CLK_SEL_LCPLL_810:
id = DPLL_ID_LCPLL_810;
break;
case PORT_CLK_SEL_LCPLL_1350:
id = DPLL_ID_LCPLL_1350;
break;
case PORT_CLK_SEL_LCPLL_2700:
id = DPLL_ID_LCPLL_2700;
break;
default:
MISSING_CASE(pipe_config->ddi_pll_sel);
/* fall through */
case PORT_CLK_SEL_NONE:
return;
}
pipe_config->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, id);
}
static bool hsw_get_transcoder_state(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config,
unsigned long *power_domain_mask)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
enum intel_display_power_domain power_domain;
u32 tmp;
/*
* The pipe->transcoder mapping is fixed with the exception of the eDP
* transcoder handled below.
*/
pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
/*
* XXX: Do intel_display_power_get_if_enabled before reading this (for
* consistency and less surprising code; it's in always on power).
*/
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;
}
power_domain = POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder);
if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
return false;
*power_domain_mask |= BIT(power_domain);
tmp = I915_READ(PIPECONF(pipe_config->cpu_transcoder));
return tmp & PIPECONF_ENABLE;
}
static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config,
unsigned long *power_domain_mask)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
enum intel_display_power_domain power_domain;
enum port port;
enum transcoder cpu_transcoder;
u32 tmp;
pipe_config->has_dsi_encoder = false;
for_each_port_masked(port, BIT(PORT_A) | BIT(PORT_C)) {
if (port == PORT_A)
cpu_transcoder = TRANSCODER_DSI_A;
else
cpu_transcoder = TRANSCODER_DSI_C;
power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder);
if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
continue;
*power_domain_mask |= BIT(power_domain);
2016-03-24 12:41:40 +02:00
/*
* The PLL needs to be enabled with a valid divider
* configuration, otherwise accessing DSI registers will hang
* the machine. See BSpec North Display Engine
* registers/MIPI[BXT]. We can break out here early, since we
* need the same DSI PLL to be enabled for both DSI ports.
*/
if (!intel_dsi_pll_is_enabled(dev_priv))
break;
/* XXX: this works for video mode only */
tmp = I915_READ(BXT_MIPI_PORT_CTRL(port));
if (!(tmp & DPI_ENABLE))
continue;
tmp = I915_READ(MIPI_CTRL(port));
if ((tmp & BXT_PIPE_SELECT_MASK) != BXT_PIPE_SELECT(crtc->pipe))
continue;
pipe_config->cpu_transcoder = cpu_transcoder;
pipe_config->has_dsi_encoder = true;
break;
}
return pipe_config->has_dsi_encoder;
}
static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_shared_dpll *pll;
enum port port;
uint32_t tmp;
tmp = I915_READ(TRANS_DDI_FUNC_CTL(pipe_config->cpu_transcoder));
port = (tmp & TRANS_DDI_PORT_MASK) >> TRANS_DDI_PORT_SHIFT;
if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
skylake_get_ddi_pll(dev_priv, port, pipe_config);
else if (IS_BROXTON(dev))
bxt_get_ddi_pll(dev_priv, port, pipe_config);
else
haswell_get_ddi_pll(dev_priv, port, pipe_config);
pll = pipe_config->shared_dpll;
if (pll) {
WARN_ON(!pll->funcs.get_hw_state(dev_priv, pll,
&pipe_config->dpll_hw_state));
}
/*
* 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.
*/
if (INTEL_INFO(dev)->gen < 9 &&
(port == PORT_E) && I915_READ(LPT_TRANSCONF) & 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;
ironlake_get_fdi_m_n_config(crtc, pipe_config);
}
}
static bool haswell_get_pipe_config(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
enum intel_display_power_domain power_domain;
unsigned long power_domain_mask;
bool active;
power_domain = POWER_DOMAIN_PIPE(crtc->pipe);
if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
return false;
power_domain_mask = BIT(power_domain);
pipe_config->shared_dpll = NULL;
drm/i915: hw state readout for shared pch plls 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ä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-06-07 23:11:08 +02:00
active = hsw_get_transcoder_state(crtc, pipe_config, &power_domain_mask);
if (IS_BROXTON(dev_priv)) {
bxt_get_dsi_transcoder_state(crtc, pipe_config,
&power_domain_mask);
WARN_ON(active && pipe_config->has_dsi_encoder);
if (pipe_config->has_dsi_encoder)
active = true;
}
if (!active)
goto out;
if (!pipe_config->has_dsi_encoder) {
haswell_get_ddi_port_state(crtc, pipe_config);
intel_get_pipe_timings(crtc, pipe_config);
}
intel_get_pipe_src_size(crtc, pipe_config);
pipe_config->gamma_mode =
I915_READ(GAMMA_MODE(crtc->pipe)) & GAMMA_MODE_MODE_MASK;
if (INTEL_INFO(dev)->gen >= 9) {
skl_init_scalers(dev, crtc, pipe_config);
}
if (INTEL_INFO(dev)->gen >= 9) {
pipe_config->scaler_state.scaler_id = -1;
pipe_config->scaler_state.scaler_users &= ~(1 << SKL_CRTC_INDEX);
}
power_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe);
if (intel_display_power_get_if_enabled(dev_priv, power_domain)) {
power_domain_mask |= BIT(power_domain);
if (INTEL_INFO(dev)->gen >= 9)
skylake_get_pfit_config(crtc, pipe_config);
else
ironlake_get_pfit_config(crtc, pipe_config);
}
if (IS_HASWELL(dev))
pipe_config->ips_enabled = hsw_crtc_supports_ips(crtc) &&
(I915_READ(IPS_CTL) & IPS_ENABLE);
if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
!transcoder_is_dsi(pipe_config->cpu_transcoder)) {
pipe_config->pixel_multiplier =
I915_READ(PIPE_MULT(pipe_config->cpu_transcoder)) + 1;
} else {
pipe_config->pixel_multiplier = 1;
}
out:
for_each_power_domain(power_domain, power_domain_mask)
intel_display_power_put(dev_priv, power_domain);
return active;
}
static void i845_update_cursor(struct drm_crtc *crtc, u32 base,
const struct intel_plane_state *plane_state)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
uint32_t cntl = 0, size = 0;
if (plane_state && plane_state->visible) {
unsigned int width = plane_state->base.crtc_w;
unsigned int height = plane_state->base.crtc_h;
unsigned int stride = roundup_pow_of_two(width) * 4;
switch (stride) {
default:
WARN_ONCE(1, "Invalid cursor width/stride, width=%u, stride=%u\n",
width, stride);
stride = 256;
/* fallthrough */
case 256:
case 512:
case 1024:
case 2048:
break;
}
cntl |= CURSOR_ENABLE |
CURSOR_GAMMA_ENABLE |
CURSOR_FORMAT_ARGB |
CURSOR_STRIDE(stride);
size = (height << 12) | width;
}
if (intel_crtc->cursor_cntl != 0 &&
(intel_crtc->cursor_base != base ||
intel_crtc->cursor_size != size ||
intel_crtc->cursor_cntl != cntl)) {
/* On these chipsets we can only modify the base/size/stride
* whilst the cursor is disabled.
*/
I915_WRITE(CURCNTR(PIPE_A), 0);
POSTING_READ(CURCNTR(PIPE_A));
intel_crtc->cursor_cntl = 0;
}
if (intel_crtc->cursor_base != base) {
I915_WRITE(CURBASE(PIPE_A), base);
intel_crtc->cursor_base = base;
}
if (intel_crtc->cursor_size != size) {
I915_WRITE(CURSIZE, size);
intel_crtc->cursor_size = size;
}
if (intel_crtc->cursor_cntl != cntl) {
I915_WRITE(CURCNTR(PIPE_A), cntl);
POSTING_READ(CURCNTR(PIPE_A));
intel_crtc->cursor_cntl = cntl;
}
}
static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base,
const struct intel_plane_state *plane_state)
{
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;
uint32_t cntl = 0;
if (plane_state && plane_state->visible) {
cntl = MCURSOR_GAMMA_ENABLE;
switch (plane_state->base.crtc_w) {
case 64:
cntl |= CURSOR_MODE_64_ARGB_AX;
break;
case 128:
cntl |= CURSOR_MODE_128_ARGB_AX;
break;
case 256:
cntl |= CURSOR_MODE_256_ARGB_AX;
break;
default:
MISSING_CASE(plane_state->base.crtc_w);
return;
}
cntl |= pipe << 28; /* Connect to correct pipe */
if (HAS_DDI(dev))
cntl |= CURSOR_PIPE_CSC_ENABLE;
if (plane_state->base.rotation == BIT(DRM_ROTATE_180))
cntl |= CURSOR_ROTATE_180;
}
if (intel_crtc->cursor_cntl != cntl) {
I915_WRITE(CURCNTR(pipe), cntl);
POSTING_READ(CURCNTR(pipe));
intel_crtc->cursor_cntl = cntl;
}
/* and commit changes on next vblank */
I915_WRITE(CURBASE(pipe), base);
POSTING_READ(CURBASE(pipe));
intel_crtc->cursor_base = base;
}
/* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */
static void intel_crtc_update_cursor(struct drm_crtc *crtc,
const struct intel_plane_state *plane_state)
{
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;
u32 base = intel_crtc->cursor_addr;
u32 pos = 0;
if (plane_state) {
int x = plane_state->base.crtc_x;
int y = plane_state->base.crtc_y;
if (x < 0) {
pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
x = -x;
}
pos |= x << CURSOR_X_SHIFT;
if (y < 0) {
pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT;
y = -y;
}
pos |= y << CURSOR_Y_SHIFT;
/* ILK+ do this automagically */
if (HAS_GMCH_DISPLAY(dev) &&
plane_state->base.rotation == BIT(DRM_ROTATE_180)) {
base += (plane_state->base.crtc_h *
plane_state->base.crtc_w - 1) * 4;
}
}
I915_WRITE(CURPOS(pipe), pos);
if (IS_845G(dev) || IS_I865G(dev))
i845_update_cursor(crtc, base, plane_state);
else
i9xx_update_cursor(crtc, base, plane_state);
}
static bool cursor_size_ok(struct drm_device *dev,
uint32_t width, uint32_t height)
{
if (width == 0 || height == 0)
return false;
/*
* 845g/865g are special in that they are only limited by
* the width of their cursors, the height is arbitrary up to
* the precision of the register. Everything else requires
* square cursors, limited to a few power-of-two sizes.
*/
if (IS_845G(dev) || IS_I865G(dev)) {
if ((width & 63) != 0)
return false;
if (width > (IS_845G(dev) ? 64 : 512))
return false;
if (height > 1023)
return false;
} else {
switch (width | height) {
case 256:
case 128:
if (IS_GEN2(dev))
return false;
case 64:
break;
default:
return false;
}
}
return true;
}
/* VESA 640x480x72Hz mode to set on the pipe */
static struct drm_display_mode load_detect_mode = {
DRM_MODE("640x480", DRM_MODE_TYPE_DEFAULT, 31500, 640, 664,
704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
};
struct drm_framebuffer *
__intel_framebuffer_create(struct drm_device *dev,
struct drm_mode_fb_cmd2 *mode_cmd,
struct drm_i915_gem_object *obj)
{
struct intel_framebuffer *intel_fb;
int ret;
intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
drm/i915: On fb alloc failure, unref gem object where it gets refed Currently when allocating a framebuffer fails, the gem object gets unrefed at the bottom of the call stack in __intel_framebuffer_create, not where it gets refed, which is in intel_framebuffer_create_for_mode (via i915_gem_alloc_object) and in intel_user_framebuffer_create (via drm_gem_object_lookup). This invites mistakes: __intel_framebuffer_create is also called from intelfb_alloc, and as discovered by Tvrtko Ursulin, a double unref was introduced there with a8bb6818270c ("drm/i915: Fix error path leak in fbdev fb allocation"). As suggested by Ville Syrjälä, fix the double unref and improve code clarity by moving the unref away from __intel_framebuffer_create to where the gem object gets refed. Based on Tvrtko Ursulin's original v2. v3: On fb alloc failure, unref gem object where it gets refed, fix double unref in separate commit (Ville Syrjälä) v4: Lock struct_mutex on unref (Chris Wilson) v5: Rebase on drm-intel-nightly 2015y-09m-01d-09h-06m-08s UTC, rephrase commit message (Jani Nicula) Tested-by: Pierre Moreau <pierre.morrow@free.fr> [MBP 5,3 2009 nvidia MCP79 + G96 pre-retina] Tested-by: Paul Hordiienko <pvt.gord@gmail.com> [MBP 6,2 2010 intel ILK + nvidia GT216 pre-retina] Tested-by: William Brown <william@blackhats.net.au> [MBP 8,2 2011 intel SNB + amd turks pre-retina] Tested-by: Lukas Wunner <lukas@wunner.de> [MBP 9,1 2012 intel IVB + nvidia GK107 pre-retina] Tested-by: Bruno Bierbaumer <bruno@bierbaumer.net> [MBP 11,3 2013 intel HSW + nvidia GK107 retina] Fixes: a8bb6818270c ("drm/i915: Fix error path leak in fbdev fb allocation") Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Lukas Wunner <lukas@wunner.de> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/2161c5062ef5d6458f8ae14d924a26d4d1dba317.1446892879.git.lukas@wunner.de Signed-off-by: Jani Nikula <jani.nikula@intel.com>
2015-07-04 11:50:58 +02:00
if (!intel_fb)
return ERR_PTR(-ENOMEM);
ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj);
if (ret)
goto err;
return &intel_fb->base;
drm/i915: On fb alloc failure, unref gem object where it gets refed Currently when allocating a framebuffer fails, the gem object gets unrefed at the bottom of the call stack in __intel_framebuffer_create, not where it gets refed, which is in intel_framebuffer_create_for_mode (via i915_gem_alloc_object) and in intel_user_framebuffer_create (via drm_gem_object_lookup). This invites mistakes: __intel_framebuffer_create is also called from intelfb_alloc, and as discovered by Tvrtko Ursulin, a double unref was introduced there with a8bb6818270c ("drm/i915: Fix error path leak in fbdev fb allocation"). As suggested by Ville Syrjälä, fix the double unref and improve code clarity by moving the unref away from __intel_framebuffer_create to where the gem object gets refed. Based on Tvrtko Ursulin's original v2. v3: On fb alloc failure, unref gem object where it gets refed, fix double unref in separate commit (Ville Syrjälä) v4: Lock struct_mutex on unref (Chris Wilson) v5: Rebase on drm-intel-nightly 2015y-09m-01d-09h-06m-08s UTC, rephrase commit message (Jani Nicula) Tested-by: Pierre Moreau <pierre.morrow@free.fr> [MBP 5,3 2009 nvidia MCP79 + G96 pre-retina] Tested-by: Paul Hordiienko <pvt.gord@gmail.com> [MBP 6,2 2010 intel ILK + nvidia GT216 pre-retina] Tested-by: William Brown <william@blackhats.net.au> [MBP 8,2 2011 intel SNB + amd turks pre-retina] Tested-by: Lukas Wunner <lukas@wunner.de> [MBP 9,1 2012 intel IVB + nvidia GK107 pre-retina] Tested-by: Bruno Bierbaumer <bruno@bierbaumer.net> [MBP 11,3 2013 intel HSW + nvidia GK107 retina] Fixes: a8bb6818270c ("drm/i915: Fix error path leak in fbdev fb allocation") Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Lukas Wunner <lukas@wunner.de> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/2161c5062ef5d6458f8ae14d924a26d4d1dba317.1446892879.git.lukas@wunner.de Signed-off-by: Jani Nikula <jani.nikula@intel.com>
2015-07-04 11:50:58 +02:00
err:
kfree(intel_fb);
return ERR_PTR(ret);
}
static struct drm_framebuffer *
intel_framebuffer_create(struct drm_device *dev,
struct drm_mode_fb_cmd2 *mode_cmd,
struct drm_i915_gem_object *obj)
{
struct drm_framebuffer *fb;
int ret;
ret = i915_mutex_lock_interruptible(dev);
if (ret)
return ERR_PTR(ret);
fb = __intel_framebuffer_create(dev, mode_cmd, obj);
mutex_unlock(&dev->struct_mutex);
return fb;
}
static u32
intel_framebuffer_pitch_for_width(int width, int bpp)
{
u32 pitch = DIV_ROUND_UP(width * bpp, 8);
return ALIGN(pitch, 64);
}
static u32
intel_framebuffer_size_for_mode(struct drm_display_mode *mode, int bpp)
{
u32 pitch = intel_framebuffer_pitch_for_width(mode->hdisplay, bpp);
return PAGE_ALIGN(pitch * mode->vdisplay);
}
static struct drm_framebuffer *
intel_framebuffer_create_for_mode(struct drm_device *dev,
struct drm_display_mode *mode,
int depth, int bpp)
{
drm/i915: On fb alloc failure, unref gem object where it gets refed Currently when allocating a framebuffer fails, the gem object gets unrefed at the bottom of the call stack in __intel_framebuffer_create, not where it gets refed, which is in intel_framebuffer_create_for_mode (via i915_gem_alloc_object) and in intel_user_framebuffer_create (via drm_gem_object_lookup). This invites mistakes: __intel_framebuffer_create is also called from intelfb_alloc, and as discovered by Tvrtko Ursulin, a double unref was introduced there with a8bb6818270c ("drm/i915: Fix error path leak in fbdev fb allocation"). As suggested by Ville Syrjälä, fix the double unref and improve code clarity by moving the unref away from __intel_framebuffer_create to where the gem object gets refed. Based on Tvrtko Ursulin's original v2. v3: On fb alloc failure, unref gem object where it gets refed, fix double unref in separate commit (Ville Syrjälä) v4: Lock struct_mutex on unref (Chris Wilson) v5: Rebase on drm-intel-nightly 2015y-09m-01d-09h-06m-08s UTC, rephrase commit message (Jani Nicula) Tested-by: Pierre Moreau <pierre.morrow@free.fr> [MBP 5,3 2009 nvidia MCP79 + G96 pre-retina] Tested-by: Paul Hordiienko <pvt.gord@gmail.com> [MBP 6,2 2010 intel ILK + nvidia GT216 pre-retina] Tested-by: William Brown <william@blackhats.net.au> [MBP 8,2 2011 intel SNB + amd turks pre-retina] Tested-by: Lukas Wunner <lukas@wunner.de> [MBP 9,1 2012 intel IVB + nvidia GK107 pre-retina] Tested-by: Bruno Bierbaumer <bruno@bierbaumer.net> [MBP 11,3 2013 intel HSW + nvidia GK107 retina] Fixes: a8bb6818270c ("drm/i915: Fix error path leak in fbdev fb allocation") Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Lukas Wunner <lukas@wunner.de> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/2161c5062ef5d6458f8ae14d924a26d4d1dba317.1446892879.git.lukas@wunner.de Signed-off-by: Jani Nikula <jani.nikula@intel.com>
2015-07-04 11:50:58 +02:00
struct drm_framebuffer *fb;
struct drm_i915_gem_object *obj;
struct drm_mode_fb_cmd2 mode_cmd = { 0 };
obj = i915_gem_object_create(dev,
intel_framebuffer_size_for_mode(mode, bpp));
if (IS_ERR(obj))
return ERR_CAST(obj);
mode_cmd.width = mode->hdisplay;
mode_cmd.height = mode->vdisplay;
mode_cmd.pitches[0] = intel_framebuffer_pitch_for_width(mode_cmd.width,
bpp);
mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth);
drm/i915: On fb alloc failure, unref gem object where it gets refed Currently when allocating a framebuffer fails, the gem object gets unrefed at the bottom of the call stack in __intel_framebuffer_create, not where it gets refed, which is in intel_framebuffer_create_for_mode (via i915_gem_alloc_object) and in intel_user_framebuffer_create (via drm_gem_object_lookup). This invites mistakes: __intel_framebuffer_create is also called from intelfb_alloc, and as discovered by Tvrtko Ursulin, a double unref was introduced there with a8bb6818270c ("drm/i915: Fix error path leak in fbdev fb allocation"). As suggested by Ville Syrjälä, fix the double unref and improve code clarity by moving the unref away from __intel_framebuffer_create to where the gem object gets refed. Based on Tvrtko Ursulin's original v2. v3: On fb alloc failure, unref gem object where it gets refed, fix double unref in separate commit (Ville Syrjälä) v4: Lock struct_mutex on unref (Chris Wilson) v5: Rebase on drm-intel-nightly 2015y-09m-01d-09h-06m-08s UTC, rephrase commit message (Jani Nicula) Tested-by: Pierre Moreau <pierre.morrow@free.fr> [MBP 5,3 2009 nvidia MCP79 + G96 pre-retina] Tested-by: Paul Hordiienko <pvt.gord@gmail.com> [MBP 6,2 2010 intel ILK + nvidia GT216 pre-retina] Tested-by: William Brown <william@blackhats.net.au> [MBP 8,2 2011 intel SNB + amd turks pre-retina] Tested-by: Lukas Wunner <lukas@wunner.de> [MBP 9,1 2012 intel IVB + nvidia GK107 pre-retina] Tested-by: Bruno Bierbaumer <bruno@bierbaumer.net> [MBP 11,3 2013 intel HSW + nvidia GK107 retina] Fixes: a8bb6818270c ("drm/i915: Fix error path leak in fbdev fb allocation") Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Lukas Wunner <lukas@wunner.de> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/2161c5062ef5d6458f8ae14d924a26d4d1dba317.1446892879.git.lukas@wunner.de Signed-off-by: Jani Nikula <jani.nikula@intel.com>
2015-07-04 11:50:58 +02:00
fb = intel_framebuffer_create(dev, &mode_cmd, obj);
if (IS_ERR(fb))
drm_gem_object_unreference_unlocked(&obj->base);
return fb;
}
static struct drm_framebuffer *
mode_fits_in_fbdev(struct drm_device *dev,
struct drm_display_mode *mode)
{
#ifdef CONFIG_DRM_FBDEV_EMULATION
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj;
struct drm_framebuffer *fb;
if (!dev_priv->fbdev)
return NULL;
if (!dev_priv->fbdev->fb)
return NULL;
obj = dev_priv->fbdev->fb->obj;
BUG_ON(!obj);
fb = &dev_priv->fbdev->fb->base;
if (fb->pitches[0] < intel_framebuffer_pitch_for_width(mode->hdisplay,
fb->bits_per_pixel))
return NULL;
if (obj->base.size < mode->vdisplay * fb->pitches[0])
return NULL;
drm_framebuffer_reference(fb);
return fb;
#else
return NULL;
#endif
}
static int intel_modeset_setup_plane_state(struct drm_atomic_state *state,
struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_framebuffer *fb,
int x, int y)
{
struct drm_plane_state *plane_state;
int hdisplay, vdisplay;
int ret;
plane_state = drm_atomic_get_plane_state(state, crtc->primary);
if (IS_ERR(plane_state))
return PTR_ERR(plane_state);
if (mode)
drm_crtc_get_hv_timing(mode, &hdisplay, &vdisplay);
else
hdisplay = vdisplay = 0;
ret = drm_atomic_set_crtc_for_plane(plane_state, fb ? crtc : NULL);
if (ret)
return ret;
drm_atomic_set_fb_for_plane(plane_state, fb);
plane_state->crtc_x = 0;
plane_state->crtc_y = 0;
plane_state->crtc_w = hdisplay;
plane_state->crtc_h = vdisplay;
plane_state->src_x = x << 16;
plane_state->src_y = y << 16;
plane_state->src_w = hdisplay << 16;
plane_state->src_h = vdisplay << 16;
return 0;
}
bool intel_get_load_detect_pipe(struct drm_connector *connector,
struct drm_display_mode *mode,
struct intel_load_detect_pipe *old,
struct drm_modeset_acquire_ctx *ctx)
{
struct intel_crtc *intel_crtc;
struct intel_encoder *intel_encoder =
intel_attached_encoder(connector);
struct drm_crtc *possible_crtc;
struct drm_encoder *encoder = &intel_encoder->base;
struct drm_crtc *crtc = NULL;
struct drm_device *dev = encoder->dev;
struct drm_framebuffer *fb;
struct drm_mode_config *config = &dev->mode_config;
struct drm_atomic_state *state = NULL, *restore_state = NULL;
struct drm_connector_state *connector_state;
struct intel_crtc_state *crtc_state;
int ret, i = -1;
DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
connector->base.id, connector->name,
encoder->base.id, encoder->name);
old->restore_state = NULL;
retry:
ret = drm_modeset_lock(&config->connection_mutex, ctx);
if (ret)
goto fail;
drm: Split connection_mutex out of mode_config.mutex (v3) After the split-out of crtc locks from the big mode_config.mutex there's still two major areas it protects: - Various connector probe states, like connector->status, EDID properties, probed mode lists and similar information. - The links from connector->encoder and encoder->crtc and other modeset-relevant connector state (e.g. properties which control the panel fitter). The later is used by modeset operations. But they don't really care about the former since it's allowed to e.g. enable a disconnected VGA output or with a mode not in the probed list. Thus far this hasn't been a problem, but for the atomic modeset conversion Rob Clark needs to convert all modeset relevant locks into w/w locks. This is required because the order of acquisition is determined by how userspace supplies the atomic modeset data. This has run into troubles in the detect path since the i915 load detect code needs _both_ protections offered by the mode_config.mutex: It updates probe state and it needs to change the modeset configuration to enable the temporary load detect pipe. The big deal here is that for the probe/detect users of this lock a plain mutex fits best, but for atomic modesets we really want a w/w mutex. To fix this lets split out a new connection_mutex lock for the modeset relevant parts. For simplicity I've decided to only add one additional lock for all connector/encoder links and modeset configuration states. We have piles of different modeset objects in addition to those (like bridges or panels), so adding per-object locks would be much more effort. Also, we're guaranteed (at least for now) to do a full modeset if we need to acquire this lock. Which means that fine-grained locking is fairly irrelevant compared to the amount of time the full modeset will take. I've done a full audit, and there's just a few things that justify special focus: - Locking in drm_sysfs.c is almost completely absent. We should sprinkle mode_config.connection_mutex over this file a bit, but since it already lacks mode_config.mutex this patch wont make the situation any worse. This is material for a follow-up patch. - omap has a omap_framebuffer_flush function which walks the connector->encoder->crtc links and is called from many contexts. Some look like they don't acquire mode_config.mutex, so this is already racy. Again fixing this is material for a separate patch. - The radeon hot_plug function to retrain DP links looks at connector->dpms. Currently this happens without any locking, so is already racy. I think radeon_hotplug_work_func should gain mutex_lock/unlock calls for the mode_config.connection_mutex. - Same applies to i915's intel_dp_hot_plug. But again, this is already racy. - i915 load_detect code needs to acquire this lock. Which means the w/w dance due to Rob's work will be nicely contained to _just_ this function. I've added fixme comments everywhere where it looks suspicious but in the sysfs code. After a quick irc discussion with Dave Airlie it sounds like the lack of locking in there is due to sysfs cleanup fun at module unload. v1: original (only compile tested) v2: missing mutex_init(), etc (from Rob Clark) v3: i915 needs more care in the conversion: - Protect the edp pp logic with the connection_mutex. - Use connection_mutex in the backlight code due to get_pipe_from_connector. - Use drm_modeset_lock_all in suspend/resume paths. - Update lock checks in the overlay code. Cc: Alex Deucher <alexdeucher@gmail.com> Cc: Rob Clark <robdclark@gmail.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Rob Clark <robdclark@gmail.com>
2014-05-29 23:54:47 +02:00
/*
* Algorithm gets a little messy:
*
* - if the connector already has an assigned crtc, use it (but make
* sure it's on first)
*
* - try to find the first unused crtc that can drive this connector,
* and use that if we find one
*/
/* See if we already have a CRTC for this connector */
if (connector->state->crtc) {
crtc = connector->state->crtc;
ret = drm_modeset_lock(&crtc->mutex, ctx);
drm: Per-plane locking Turned out to be much simpler on top of my latest atomic stuff than what I've feared. Some details: - Drop the modeset_lock_all snakeoil in drm_plane_init. Same justification as for the equivalent change in drm_crtc_init done in commit d0fa1af40e784aaf7ebb7ba8a17b229bb3fa4c21 Author: Daniel Vetter <daniel.vetter@ffwll.ch> Date: Mon Sep 8 09:02:49 2014 +0200 drm: Drop modeset locking from crtc init function Without these the drm_modeset_lock_init would fall over the exact same way. - Since the atomic core code wraps the locking switching it to per-plane locks was a one-line change. - For the legacy ioctls add a plane argument to the locking helper so that we can grab the right plane lock (cursor or primary). Since the universal cursor plane might not be there, or someone really crazy might forgoe the primary plane even accept NULL. - Add some locking WARN_ON to the atomic helpers for good paranoid measure and to check that it all works out. Tested on my exynos atomic hackfest with full lockdep checks and ww backoff injection. v2: I've forgotten about the load-detect code in i915. v3: Thierry reported that in latest 3.18-rc vmwgfx doesn't compile any more due to commit 21e88620aa21b48d4f62d29275e3e2944a5ea2b5 Author: Rob Clark <robdclark@gmail.com> Date: Thu Oct 30 13:39:04 2014 -0400 drm/vmwgfx: fix lock breakage Rebased and fix this up. Cc: Thierry Reding <thierry.reding@gmail.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> Reviewed-by: Sean Paul <seanpaul@chromium.org> Signed-off-by: Dave Airlie <airlied@redhat.com>
2014-11-11 10:12:00 +01:00
if (ret)
goto fail;
/* Make sure the crtc and connector are running */
goto found;
}
/* Find an unused one (if possible) */
for_each_crtc(dev, possible_crtc) {
i++;
if (!(encoder->possible_crtcs & (1 << i)))
continue;
ret = drm_modeset_lock(&possible_crtc->mutex, ctx);
if (ret)
goto fail;
if (possible_crtc->state->enable) {
drm_modeset_unlock(&possible_crtc->mutex);
continue;
}
crtc = possible_crtc;
break;
}
/*
* If we didn't find an unused CRTC, don't use any.
*/
if (!crtc) {
DRM_DEBUG_KMS("no pipe available for load-detect\n");
goto fail;
}
found:
intel_crtc = to_intel_crtc(crtc);
drm: Per-plane locking Turned out to be much simpler on top of my latest atomic stuff than what I've feared. Some details: - Drop the modeset_lock_all snakeoil in drm_plane_init. Same justification as for the equivalent change in drm_crtc_init done in commit d0fa1af40e784aaf7ebb7ba8a17b229bb3fa4c21 Author: Daniel Vetter <daniel.vetter@ffwll.ch> Date: Mon Sep 8 09:02:49 2014 +0200 drm: Drop modeset locking from crtc init function Without these the drm_modeset_lock_init would fall over the exact same way. - Since the atomic core code wraps the locking switching it to per-plane locks was a one-line change. - For the legacy ioctls add a plane argument to the locking helper so that we can grab the right plane lock (cursor or primary). Since the universal cursor plane might not be there, or someone really crazy might forgoe the primary plane even accept NULL. - Add some locking WARN_ON to the atomic helpers for good paranoid measure and to check that it all works out. Tested on my exynos atomic hackfest with full lockdep checks and ww backoff injection. v2: I've forgotten about the load-detect code in i915. v3: Thierry reported that in latest 3.18-rc vmwgfx doesn't compile any more due to commit 21e88620aa21b48d4f62d29275e3e2944a5ea2b5 Author: Rob Clark <robdclark@gmail.com> Date: Thu Oct 30 13:39:04 2014 -0400 drm/vmwgfx: fix lock breakage Rebased and fix this up. Cc: Thierry Reding <thierry.reding@gmail.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> Reviewed-by: Sean Paul <seanpaul@chromium.org> Signed-off-by: Dave Airlie <airlied@redhat.com>
2014-11-11 10:12:00 +01:00
ret = drm_modeset_lock(&crtc->primary->mutex, ctx);
if (ret)
goto fail;
state = drm_atomic_state_alloc(dev);
restore_state = drm_atomic_state_alloc(dev);
if (!state || !restore_state) {
ret = -ENOMEM;
goto fail;
}
state->acquire_ctx = ctx;
restore_state->acquire_ctx = ctx;
connector_state = drm_atomic_get_connector_state(state, connector);
if (IS_ERR(connector_state)) {
ret = PTR_ERR(connector_state);
goto fail;
}
ret = drm_atomic_set_crtc_for_connector(connector_state, crtc);
if (ret)
goto fail;
crtc_state = intel_atomic_get_crtc_state(state, intel_crtc);
if (IS_ERR(crtc_state)) {
ret = PTR_ERR(crtc_state);
goto fail;
}
drm/i915: Always keep crtc_state->active in sync with enable With the recent modeset internal rework, we wind up setting crtc_state->enable to false, but leave crtc_state->active as true following a drmModeSetCrtc(fb=0), which is incorrect. This mismatch gets caught by drm_atomic_crtc_check() and causes subsequent atomic operations (such as plane updates while the CRTC is disabled) to fail. Bisect points to commit dad9a7d6d96630182fb52aae7c3856e9e7285e13 Author: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Date: Tue Apr 21 17:13:19 2015 +0300 drm/i915: Use atomic helpers for computing changed flags as the commit that actually triggers the regression. The difference compared to (which this patch reverts) commit 90d469067d0808ddbd9be2c97a4a8e14037b5e46 Author: Matt Roper <matthew.d.roper@intel.com> Date: Thu May 7 14:31:28 2015 -0700 drm/i915: Set crtc_state->active to false when CRTC is disabled (v2) is that we know keep state->active/enable in sync for all legacy modeset paths, as it should be. Cc: Matt Roper <matthew.d.roper@intel.com> Cc: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reported-and-Tested-by: Kenneth Graunke <kenneth@whitecape.org> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> [danvet: Directly squash in the revert and augment the commit message.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Revert "drm/i915: Set crtc_state->active to false when CRTC is disabled (v2)" This reverts commit 90d469067d0808ddbd9be2c97a4a8e14037b5e46.
2015-05-11 10:45:15 +02:00
crtc_state->base.active = crtc_state->base.enable = true;
if (!mode)
mode = &load_detect_mode;
/* We need a framebuffer large enough to accommodate all accesses
* that the plane may generate whilst we perform load detection.
* We can not rely on the fbcon either being present (we get called
* during its initialisation to detect all boot displays, or it may
* not even exist) or that it is large enough to satisfy the
* requested mode.
*/
fb = mode_fits_in_fbdev(dev, mode);
if (fb == NULL) {
DRM_DEBUG_KMS("creating tmp fb for load-detection\n");
fb = intel_framebuffer_create_for_mode(dev, mode, 24, 32);
} else
DRM_DEBUG_KMS("reusing fbdev for load-detection framebuffer\n");
if (IS_ERR(fb)) {
DRM_DEBUG_KMS("failed to allocate framebuffer for load-detection\n");
goto fail;
}
ret = intel_modeset_setup_plane_state(state, crtc, mode, fb, 0, 0);
if (ret)
goto fail;
drm_framebuffer_unreference(fb);
ret = drm_atomic_set_mode_for_crtc(&crtc_state->base, mode);
if (ret)
goto fail;
ret = PTR_ERR_OR_ZERO(drm_atomic_get_connector_state(restore_state, connector));
if (!ret)
ret = PTR_ERR_OR_ZERO(drm_atomic_get_crtc_state(restore_state, crtc));
if (!ret)
ret = PTR_ERR_OR_ZERO(drm_atomic_get_plane_state(restore_state, crtc->primary));
if (ret) {
DRM_DEBUG_KMS("Failed to create a copy of old state to restore: %i\n", ret);
goto fail;
}
ret = drm_atomic_commit(state);
if (ret) {
DRM_DEBUG_KMS("failed to set mode on load-detect pipe\n");
goto fail;
}
old->restore_state = restore_state;
/* let the connector get through one full cycle before testing */
intel_wait_for_vblank(dev, intel_crtc->pipe);
return true;
fail:
drm_atomic_state_free(state);
drm_atomic_state_free(restore_state);
restore_state = state = NULL;
if (ret == -EDEADLK) {
drm_modeset_backoff(ctx);
goto retry;
}
return false;
}
void intel_release_load_detect_pipe(struct drm_connector *connector,
struct intel_load_detect_pipe *old,
struct drm_modeset_acquire_ctx *ctx)
{
struct intel_encoder *intel_encoder =
intel_attached_encoder(connector);
struct drm_encoder *encoder = &intel_encoder->base;
struct drm_atomic_state *state = old->restore_state;
int ret;
DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
connector->base.id, connector->name,
encoder->base.id, encoder->name);
if (!state)
return;
ret = drm_atomic_commit(state);
if (ret) {
DRM_DEBUG_KMS("Couldn't release load detect pipe: %i\n", ret);
drm_atomic_state_free(state);
}
}
static int i9xx_pll_refclk(struct drm_device *dev,
const struct intel_crtc_state *pipe_config)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 dpll = pipe_config->dpll_hw_state.dpll;
if ((dpll & PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN)
return dev_priv->vbt.lvds_ssc_freq;
else if (HAS_PCH_SPLIT(dev))
return 120000;
else if (!IS_GEN2(dev))
return 96000;
else
return 48000;
}
/* Returns the clock of the currently programmed mode of the given pipe. */
static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
int pipe = pipe_config->cpu_transcoder;
u32 dpll = pipe_config->dpll_hw_state.dpll;
u32 fp;
struct dpll clock;
int port_clock;
int refclk = i9xx_pll_refclk(dev, pipe_config);
if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
fp = pipe_config->dpll_hw_state.fp0;
else
fp = pipe_config->dpll_hw_state.fp1;
clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
if (IS_PINEVIEW(dev)) {
clock.n = ffs((fp & FP_N_PINEVIEW_DIV_MASK) >> FP_N_DIV_SHIFT) - 1;
clock.m2 = (fp & FP_M2_PINEVIEW_DIV_MASK) >> FP_M2_DIV_SHIFT;
} else {
clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
}
if (!IS_GEN2(dev)) {
if (IS_PINEVIEW(dev))
clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW) >>
DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW);
else
clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >>
DPLL_FPA01_P1_POST_DIV_SHIFT);
switch (dpll & DPLL_MODE_MASK) {
case DPLLB_MODE_DAC_SERIAL:
clock.p2 = dpll & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ?
5 : 10;
break;
case DPLLB_MODE_LVDS:
clock.p2 = dpll & DPLLB_LVDS_P2_CLOCK_DIV_7 ?
7 : 14;
break;
default:
DRM_DEBUG_KMS("Unknown DPLL mode %08x in programmed "
"mode\n", (int)(dpll & DPLL_MODE_MASK));
return;
}
if (IS_PINEVIEW(dev))
port_clock = pnv_calc_dpll_params(refclk, &clock);
else
port_clock = i9xx_calc_dpll_params(refclk, &clock);
} else {
u32 lvds = IS_I830(dev) ? 0 : I915_READ(LVDS);
bool is_lvds = (pipe == 1) && (lvds & LVDS_PORT_EN);
if (is_lvds) {
clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >>
DPLL_FPA01_P1_POST_DIV_SHIFT);
if (lvds & LVDS_CLKB_POWER_UP)
clock.p2 = 7;
else
clock.p2 = 14;
} else {
if (dpll & PLL_P1_DIVIDE_BY_TWO)
clock.p1 = 2;
else {
clock.p1 = ((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830) >>
DPLL_FPA01_P1_POST_DIV_SHIFT) + 2;
}
if (dpll & PLL_P2_DIVIDE_BY_4)
clock.p2 = 4;
else
clock.p2 = 2;
}
port_clock = i9xx_calc_dpll_params(refclk, &clock);
}
/*
* This value includes pixel_multiplier. We will use
* port_clock to compute adjusted_mode.crtc_clock in the
* encoder's get_config() function.
*/
pipe_config->port_clock = port_clock;
}
int intel_dotclock_calculate(int link_freq,
const struct intel_link_m_n *m_n)
{
/*
* The calculation for the data clock is:
* pixel_clock = ((m/n)*(link_clock * nr_lanes))/bpp
* But we want to avoid losing precison if possible, so:
* pixel_clock = ((m * link_clock * nr_lanes)/(n*bpp))
*
* and the link clock is simpler:
* link_clock = (m * link_clock) / n
*/
if (!m_n->link_n)
return 0;
return div_u64((u64)m_n->link_m * link_freq, m_n->link_n);
}
static void ironlake_pch_clock_get(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
/* read out port_clock from the DPLL */
i9xx_crtc_clock_get(crtc, pipe_config);
/*
* In case there is an active pipe without active ports,
* we may need some idea for the dotclock anyway.
* Calculate one based on the FDI configuration.
*/
pipe_config->base.adjusted_mode.crtc_clock =
intel_dotclock_calculate(intel_fdi_link_freq(dev_priv, pipe_config),
&pipe_config->fdi_m_n);
}
/** Returns the currently programmed mode of the given pipe. */
struct drm_display_mode *intel_crtc_mode_get(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);
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
struct drm_display_mode *mode;
struct intel_crtc_state *pipe_config;
int htot = I915_READ(HTOTAL(cpu_transcoder));
int hsync = I915_READ(HSYNC(cpu_transcoder));
int vtot = I915_READ(VTOTAL(cpu_transcoder));
int vsync = I915_READ(VSYNC(cpu_transcoder));
enum pipe pipe = intel_crtc->pipe;
mode = kzalloc(sizeof(*mode), GFP_KERNEL);
if (!mode)
return NULL;
pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
if (!pipe_config) {
kfree(mode);
return NULL;
}
/*
* 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 = (enum transcoder) pipe;
pipe_config->pixel_multiplier = 1;
pipe_config->dpll_hw_state.dpll = I915_READ(DPLL(pipe));
pipe_config->dpll_hw_state.fp0 = I915_READ(FP0(pipe));
pipe_config->dpll_hw_state.fp1 = I915_READ(FP1(pipe));
i9xx_crtc_clock_get(intel_crtc, pipe_config);
mode->clock = pipe_config->port_clock / pipe_config->pixel_multiplier;
mode->hdisplay = (htot & 0xffff) + 1;
mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
mode->hsync_start = (hsync & 0xffff) + 1;
mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1;
mode->vdisplay = (vtot & 0xffff) + 1;
mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1;
mode->vsync_start = (vsync & 0xffff) + 1;
mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1;
drm_mode_set_name(mode);
kfree(pipe_config);
return mode;
}
static void intel_crtc_destroy(struct drm_crtc *crtc)
{
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct intel_flip_work *work;
spin_lock_irq(&dev->event_lock);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
work = intel_crtc->flip_work;
intel_crtc->flip_work = NULL;
spin_unlock_irq(&dev->event_lock);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
if (work) {
cancel_work_sync(&work->mmio_work);
cancel_work_sync(&work->unpin_work);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
kfree(work);
}
drm_crtc_cleanup(crtc);
kfree(intel_crtc);
}
static void intel_unpin_work_fn(struct work_struct *__work)
{
struct intel_flip_work *work =
container_of(__work, struct intel_flip_work, unpin_work);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
struct intel_crtc *crtc = to_intel_crtc(work->crtc);
struct drm_device *dev = crtc->base.dev;
struct drm_plane *primary = crtc->base.primary;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
if (is_mmio_work(work))
flush_work(&work->mmio_work);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
mutex_lock(&dev->struct_mutex);
intel_unpin_fb_obj(work->old_fb, primary->state->rotation);
drm_gem_object_unreference(&work->pending_flip_obj->base);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
if (work->flip_queued_req)
i915_gem_request_assign(&work->flip_queued_req, NULL);
mutex_unlock(&dev->struct_mutex);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
intel_frontbuffer_flip_complete(dev, to_intel_plane(primary)->frontbuffer_bit);
intel_fbc_post_update(crtc);
drm_framebuffer_unreference(work->old_fb);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
BUG_ON(atomic_read(&crtc->unpin_work_count) == 0);
atomic_dec(&crtc->unpin_work_count);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
kfree(work);
}
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
/* Is 'a' after or equal to 'b'? */
static bool g4x_flip_count_after_eq(u32 a, u32 b)
{
return !((a - b) & 0x80000000);
}
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
static bool __pageflip_finished_cs(struct intel_crtc *crtc,
struct intel_flip_work *work)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
unsigned reset_counter;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
reset_counter = i915_reset_counter(&dev_priv->gpu_error);
if (crtc->reset_counter != reset_counter)
return true;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
/*
* The relevant registers doen't exist on pre-ctg.
* As the flip done interrupt doesn't trigger for mmio
* flips on gmch platforms, a flip count check isn't
* really needed there. But since ctg has the registers,
* include it in the check anyway.
*/
if (INTEL_INFO(dev)->gen < 5 && !IS_G4X(dev))
return true;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
/*
* BDW signals flip done immediately if the plane
* is disabled, even if the plane enable is already
* armed to occur at the next vblank :(
*/
drm/i915: Track frontbuffer invalidation/flushing So these are the guts of the new beast. This tracks when a frontbuffer gets invalidated (due to frontbuffer rendering) and hence should be constantly scaned out, and when it's flushed again and can be compressed/one-shot-upload. Rules for flushing are simple: The frontbuffer needs one more full upload starting from the next vblank. Which means that the flushing can _only_ be called once the frontbuffer update has been latched. But this poses a problem for pageflips: We can't just delay the flushing until the pageflip is latched, since that would pose the risk that we override frontbuffer rendering that has been scheduled in-between the pageflip ioctl and the actual latching. To handle this track asynchronous invalidations (and also pageflip) state per-ring and delay any in-between flushing until the rendering has completed. And also cancel any delayed flushing if we get a new invalidation request (whether delayed or not). Also call intel_mark_fb_busy in both cases in all cases to make sure that we keep the screen at the highest refresh rate both on flips, synchronous plane updates and for frontbuffer rendering. v2: Lots of improvements Suggestions from Chris: - Move invalidate/flush in flush_*_domain and set_to_*_domain. - Drop the flush in busy_ioctl since it's redundant. Was a leftover from an earlier concept to track flips/delayed flushes. - Don't forget about the initial modeset enable/final disable. Suggested by Chris. Track flips accurately, too. Since flips complete independently of rendering we need to track pending flips in a separate mask. Again if an invalidate happens we need to cancel the evenutal flush to avoid races. v3: Provide correct header declarations for flip functions. Currently not needed outside of intel_display.c, but part of the proper interface. v4: Add proper domain management to fbcon so that the fbcon buffer is also tracked correctly. v5: Fixup locking around the fbcon set_to_gtt_domain call. v6: More comments from Chris: - Split out fbcon changes. - Drop superflous checks for potential scanout before calling intel_fb functions - we can micro-optimize this later. - s/intel_fb_/intel_fb_obj_/ to make it clear that this deals in gem object. We already have precedence for fb_obj in the pin_and_fence functions. v7: Clarify the semantics of the flip flush handling by renaming things a bit: - Don't go through a gem object but take the relevant frontbuffer bits directly. These functions center on the plane, the actual object is irrelevant - even a flip to the same object as already active should cause a flush. - Add a new intel_frontbuffer_flip for synchronous plane updates. It currently just calls intel_frontbuffer_flush since the implemenation differs. This way we achieve a clear split between one-shot update events on one side and frontbuffer rendering with potentially a very long delay between the invalidate and flush. Chris and I also had some discussions about mark_busy and whether it is appropriate to call from flush. But mark busy is a state which should be derived from the 3 events (invalidate, flush, flip) we now have by the users, like psr does by tracking relevant information in psr.busy_frontbuffer_bits. DRRS (the only real use of mark_busy for frontbuffer) needs to have similar logic. With that the overall mark_busy in the core could be removed. v8: Only when retiring gpu buffers only flush frontbuffer bits we actually invalidated in a batch. Just for safety since before any additional usage/invalidate we should always retire current rendering. Suggested by Chris Wilson. v9: Actually use intel_frontbuffer_flip in all appropriate places. Spotted by Chris. v10: Address more comments from Chris: - Don't call _flip in set_base when the crtc is inactive, avoids redunancy in the modeset case with the initial enabling of all planes. - Add comments explaining that the initial/final plane enable/disable still has work left to do before it's fully generic. v11: Only invalidate for gtt/cpu access when writing. Spotted by Chris. v12: s/_flush/_flip/ in intel_overlay.c per Chris' comment. Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-19 16:01:59 +02:00
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
/*
* A DSPSURFLIVE check isn't enough in case the mmio and CS flips
* used the same base address. In that case the mmio flip might
* have completed, but the CS hasn't even executed the flip yet.
*
* A flip count check isn't enough as the CS might have updated
* the base address just after start of vblank, but before we
* managed to process the interrupt. This means we'd complete the
* CS flip too soon.
*
* Combining both checks should get us a good enough result. It may
* still happen that the CS flip has been executed, but has not
* yet actually completed. But in case the base address is the same
* anyway, we don't really care.
*/
return (I915_READ(DSPSURFLIVE(crtc->plane)) & ~0xfff) ==
crtc->flip_work->gtt_offset &&
g4x_flip_count_after_eq(I915_READ(PIPE_FLIPCOUNT_G4X(crtc->pipe)),
crtc->flip_work->flip_count);
}
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
static bool
__pageflip_finished_mmio(struct intel_crtc *crtc,
struct intel_flip_work *work)
{
/*
* MMIO work completes when vblank is different from
* flip_queued_vblank.
*
* Reset counter value doesn't matter, this is handled by
* i915_wait_request finishing early, so no need to handle
* reset here.
*/
return intel_crtc_get_vblank_counter(crtc) != work->flip_queued_vblank;
}
static bool pageflip_finished(struct intel_crtc *crtc,
struct intel_flip_work *work)
{
if (!atomic_read(&work->pending))
return false;
smp_rmb();
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
if (is_mmio_work(work))
return __pageflip_finished_mmio(crtc, work);
else
return __pageflip_finished_cs(crtc, work);
}
void intel_finish_page_flip_cs(struct drm_i915_private *dev_priv, int pipe)
{
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);
struct intel_flip_work *work;
unsigned long flags;
/* Ignore early vblank irqs */
if (!crtc)
return;
/*
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
* This is called both by irq handlers and the reset code (to complete
* lost pageflips) so needs the full irqsave spinlocks.
*/
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
spin_lock_irqsave(&dev->event_lock, flags);
work = intel_crtc->flip_work;
if (work != NULL &&
!is_mmio_work(work) &&
pageflip_finished(intel_crtc, work))
page_flip_completed(intel_crtc);
spin_unlock_irqrestore(&dev->event_lock, flags);
drm/i915: Fix mmio vs. CS flip race on ILK+ Starting from ILK, mmio flips also cause a flip done interrupt to be signalled. This means if we first do a set_base and follow it immediately with the CS flip, we might mistake the flip done interrupt caused by the set_base as the flip done interrupt caused by the CS flip. The hardware has a flip counter which increments every time a mmio or CS flip is issued. It basically counts the number of DSPSURF register writes. This means we can sample the counter before we put the CS flip into the ring, and then when we get a flip done interrupt we can check whether the CS flip has actually performed the surface address update, or if the interrupt was caused by a previous but yet unfinished mmio flip. Even with the flip counter we still have a race condition of the CS flip base address update happens after the mmio flip done interrupt was raised but not yet processed by the driver. When the interrupt is eventually processed, the flip counter will already indicate that the CS flip has been executed, but it would not actually complete until the next start of vblank. We can use the DSPSURFLIVE register to check whether the hardware is actually scanning out of the buffer we expect, or if we managed hit this race window. This covers all the cases where the CS flip actually changes the base address. If the base address remains unchanged, we might still complete the CS flip before it has actually completed. But since the address didn't change anyway, the premature flip completion can't result in userspace overwriting data that's still being scanned out. CTG already has the flip counter and DSPSURFLIVE registers, and although the flip done interrupt is still limited to CS flips alone, the code now also checks the flip counter on CTG as well. v2: s/dspsurf/gtt_offset/ (Chris) Testcase: igt/kms_mmio_vs_cs_flip/setcrtc_vs_cs_flip Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=73027 Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@gmail.com> [danvet: Add g4x_ prefix to flip_count_after_eq.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-04-15 21:41:34 +03:00
}
void intel_finish_page_flip_mmio(struct drm_i915_private *dev_priv, int pipe)
{
drm/i915: Small display interrupt handlers tidy I have noticed some of our interrupt handlers use both dev and dev_priv while they could get away with only dev_priv in the huge majority of cases. Tidying that up had a cascading effect on changing functions prototypes, so relatively big churn factor, but I think it is for the better. For example even where changes cascade out of i915_irq.c, for functions prefixed with intel_, genX_ or <plat>_, it makes more sense to take dev_priv directly anyway. This allows us to eliminate local variables and intermixed usage of dev and dev_priv where only one is good enough. End result is shrinkage of both source and the resulting binary. i915.ko: - .text 000b0899 + .text 000b0619 Or if we look at the Gen8 display irq chain: -00000000000006ad t gen8_irq_handler +0000000000000663 t gen8_irq_handler -0000000000000028 T intel_opregion_asle_intr +0000000000000024 T intel_opregion_asle_intr -000000000000008c t ilk_hpd_irq_handler +000000000000007f t ilk_hpd_irq_handler -0000000000000116 T intel_check_page_flip +0000000000000112 T intel_check_page_flip -000000000000011a T intel_prepare_page_flip +0000000000000119 T intel_prepare_page_flip -0000000000000014 T intel_finish_page_flip_plane +0000000000000013 T intel_finish_page_flip_plane -0000000000000053 t hsw_pipe_crc_irq_handler +000000000000004c t hsw_pipe_crc_irq_handler -000000000000022e t cpt_irq_handler +0000000000000213 t cpt_irq_handler So small shrinkage but it is all fast paths so doesn't harm. Situation is similar in other interrupt handlers as well. v2: Tidy intel_queue_rps_boost_for_request as well. (Chris Wilson) Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
2016-05-06 14:48:28 +01:00
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);
struct intel_flip_work *work;
unsigned long flags;
/* Ignore early vblank irqs */
if (!crtc)
return;
/*
* This is called both by irq handlers and the reset code (to complete
* lost pageflips) so needs the full irqsave spinlocks.
*/
spin_lock_irqsave(&dev->event_lock, flags);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
work = intel_crtc->flip_work;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
if (work != NULL &&
is_mmio_work(work) &&
pageflip_finished(intel_crtc, work))
page_flip_completed(intel_crtc);
spin_unlock_irqrestore(&dev->event_lock, flags);
}
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
static inline void intel_mark_page_flip_active(struct intel_crtc *crtc,
struct intel_flip_work *work)
drm/i915: Replaced Blitter ring based flips with MMIO flips This patch enables the framework for using MMIO based flip calls, in contrast with the CS based flip calls which are being used currently. MMIO based flip calls can be enabled on architectures where Render and Blitter engines reside in different power wells. The decision to use MMIO flips can be made based on workloads to give 100% residency for Media power well. v2: The MMIO flips now use the interrupt driven mechanism for issuing the flips when target seqno is reached. (Incorporating Ville's idea) v3: Rebasing on latest code. Code restructuring after incorporating Damien's comments v4: Addressing Ville's review comments -general cleanup -updating only base addr instead of calling update_primary_plane -extending patch for gen5+ platforms v5: Addressed Ville's review comments -Making mmio flip vs cs flip selection based on module parameter -Adding check for DRIVER_MODESET feature in notify_ring before calling notify mmio flip. -Other changes mostly in function arguments v6: -Having a seperate function to check condition for using mmio flips (Ville) -propogating error code from i915_gem_check_olr (Ville) v7: -Adding __must_check with i915_gem_check_olr (Chris) -Renaming mmio_flip_data to mmio_flip (Chris) -Rebasing on latest nightly v8: -Rebasing on latest code -squash 3rd patch in series(mmio setbase vs page flip race) with this patch -Added new tiling mode update in intel_do_mmio_flip (Chris) v9: -check for obj->last_write_seqno being 0 instead of obj->ring being NULL in intel_postpone_flip, as this is a more restrictive condition (Chris) v10: -Applied Chris's suggestions for squashing patches 2,3 into this patch. These patches make the selection of CS vs MMIO flip at the page flip time, and make the module parameter for using mmio flips as tristate, the states being 'force CS flips', 'force mmio flips', 'driver discretion'. Changed the logic for driver discretion (Chris) v11: Minor code cleanup(better readability, fixing whitespace errors, using lockdep to check mutex locked status in postpone_flip, removal of __must_check in function definition) (Chris) Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Sourab Gupta <sourab.gupta@intel.com> Signed-off-by: Akash Goel <akash.goel@intel.com> Tested-by: Chris Wilson <chris@chris-wilson.co.uk> # snb, ivb [danvet: Fix up parameter alignement checkpatch spotted.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-02 16:47:17 +05:30
{
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
work->flip_queued_vblank = intel_crtc_get_vblank_counter(crtc);
drm/i915: Replaced Blitter ring based flips with MMIO flips This patch enables the framework for using MMIO based flip calls, in contrast with the CS based flip calls which are being used currently. MMIO based flip calls can be enabled on architectures where Render and Blitter engines reside in different power wells. The decision to use MMIO flips can be made based on workloads to give 100% residency for Media power well. v2: The MMIO flips now use the interrupt driven mechanism for issuing the flips when target seqno is reached. (Incorporating Ville's idea) v3: Rebasing on latest code. Code restructuring after incorporating Damien's comments v4: Addressing Ville's review comments -general cleanup -updating only base addr instead of calling update_primary_plane -extending patch for gen5+ platforms v5: Addressed Ville's review comments -Making mmio flip vs cs flip selection based on module parameter -Adding check for DRIVER_MODESET feature in notify_ring before calling notify mmio flip. -Other changes mostly in function arguments v6: -Having a seperate function to check condition for using mmio flips (Ville) -propogating error code from i915_gem_check_olr (Ville) v7: -Adding __must_check with i915_gem_check_olr (Chris) -Renaming mmio_flip_data to mmio_flip (Chris) -Rebasing on latest nightly v8: -Rebasing on latest code -squash 3rd patch in series(mmio setbase vs page flip race) with this patch -Added new tiling mode update in intel_do_mmio_flip (Chris) v9: -check for obj->last_write_seqno being 0 instead of obj->ring being NULL in intel_postpone_flip, as this is a more restrictive condition (Chris) v10: -Applied Chris's suggestions for squashing patches 2,3 into this patch. These patches make the selection of CS vs MMIO flip at the page flip time, and make the module parameter for using mmio flips as tristate, the states being 'force CS flips', 'force mmio flips', 'driver discretion'. Changed the logic for driver discretion (Chris) v11: Minor code cleanup(better readability, fixing whitespace errors, using lockdep to check mutex locked status in postpone_flip, removal of __must_check in function definition) (Chris) Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Sourab Gupta <sourab.gupta@intel.com> Signed-off-by: Akash Goel <akash.goel@intel.com> Tested-by: Chris Wilson <chris@chris-wilson.co.uk> # snb, ivb [danvet: Fix up parameter alignement checkpatch spotted.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-02 16:47:17 +05:30
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
/* Ensure that the work item is consistent when activating it ... */
smp_mb__before_atomic();
atomic_set(&work->pending, 1);
}
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
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_request *req,
uint32_t flags)
{
struct intel_engine_cs *engine = req->engine;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
u32 flip_mask;
int ret;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
ret = intel_ring_begin(req, 6);
if (ret)
return ret;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
/* Can't queue multiple flips, so wait for the previous
* one to finish before executing the next.
*/
if (intel_crtc->plane)
flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
else
flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
intel_ring_emit(engine, MI_WAIT_FOR_EVENT | flip_mask);
intel_ring_emit(engine, MI_NOOP);
intel_ring_emit(engine, MI_DISPLAY_FLIP |
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
intel_ring_emit(engine, fb->pitches[0]);
intel_ring_emit(engine, intel_crtc->flip_work->gtt_offset);
intel_ring_emit(engine, 0); /* aux display base address, unused */
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
return 0;
}
drm/i915: Replaced Blitter ring based flips with MMIO flips This patch enables the framework for using MMIO based flip calls, in contrast with the CS based flip calls which are being used currently. MMIO based flip calls can be enabled on architectures where Render and Blitter engines reside in different power wells. The decision to use MMIO flips can be made based on workloads to give 100% residency for Media power well. v2: The MMIO flips now use the interrupt driven mechanism for issuing the flips when target seqno is reached. (Incorporating Ville's idea) v3: Rebasing on latest code. Code restructuring after incorporating Damien's comments v4: Addressing Ville's review comments -general cleanup -updating only base addr instead of calling update_primary_plane -extending patch for gen5+ platforms v5: Addressed Ville's review comments -Making mmio flip vs cs flip selection based on module parameter -Adding check for DRIVER_MODESET feature in notify_ring before calling notify mmio flip. -Other changes mostly in function arguments v6: -Having a seperate function to check condition for using mmio flips (Ville) -propogating error code from i915_gem_check_olr (Ville) v7: -Adding __must_check with i915_gem_check_olr (Chris) -Renaming mmio_flip_data to mmio_flip (Chris) -Rebasing on latest nightly v8: -Rebasing on latest code -squash 3rd patch in series(mmio setbase vs page flip race) with this patch -Added new tiling mode update in intel_do_mmio_flip (Chris) v9: -check for obj->last_write_seqno being 0 instead of obj->ring being NULL in intel_postpone_flip, as this is a more restrictive condition (Chris) v10: -Applied Chris's suggestions for squashing patches 2,3 into this patch. These patches make the selection of CS vs MMIO flip at the page flip time, and make the module parameter for using mmio flips as tristate, the states being 'force CS flips', 'force mmio flips', 'driver discretion'. Changed the logic for driver discretion (Chris) v11: Minor code cleanup(better readability, fixing whitespace errors, using lockdep to check mutex locked status in postpone_flip, removal of __must_check in function definition) (Chris) Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Sourab Gupta <sourab.gupta@intel.com> Signed-off-by: Akash Goel <akash.goel@intel.com> Tested-by: Chris Wilson <chris@chris-wilson.co.uk> # snb, ivb [danvet: Fix up parameter alignement checkpatch spotted.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-02 16:47:17 +05:30
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
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_request *req,
uint32_t flags)
{
struct intel_engine_cs *engine = req->engine;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
u32 flip_mask;
int ret;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
ret = intel_ring_begin(req, 6);
if (ret)
return ret;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
if (intel_crtc->plane)
flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
else
flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
intel_ring_emit(engine, MI_WAIT_FOR_EVENT | flip_mask);
intel_ring_emit(engine, MI_NOOP);
intel_ring_emit(engine, MI_DISPLAY_FLIP_I915 |
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
intel_ring_emit(engine, fb->pitches[0]);
intel_ring_emit(engine, intel_crtc->flip_work->gtt_offset);
intel_ring_emit(engine, MI_NOOP);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
return 0;
}
drm/i915: Replaced Blitter ring based flips with MMIO flips This patch enables the framework for using MMIO based flip calls, in contrast with the CS based flip calls which are being used currently. MMIO based flip calls can be enabled on architectures where Render and Blitter engines reside in different power wells. The decision to use MMIO flips can be made based on workloads to give 100% residency for Media power well. v2: The MMIO flips now use the interrupt driven mechanism for issuing the flips when target seqno is reached. (Incorporating Ville's idea) v3: Rebasing on latest code. Code restructuring after incorporating Damien's comments v4: Addressing Ville's review comments -general cleanup -updating only base addr instead of calling update_primary_plane -extending patch for gen5+ platforms v5: Addressed Ville's review comments -Making mmio flip vs cs flip selection based on module parameter -Adding check for DRIVER_MODESET feature in notify_ring before calling notify mmio flip. -Other changes mostly in function arguments v6: -Having a seperate function to check condition for using mmio flips (Ville) -propogating error code from i915_gem_check_olr (Ville) v7: -Adding __must_check with i915_gem_check_olr (Chris) -Renaming mmio_flip_data to mmio_flip (Chris) -Rebasing on latest nightly v8: -Rebasing on latest code -squash 3rd patch in series(mmio setbase vs page flip race) with this patch -Added new tiling mode update in intel_do_mmio_flip (Chris) v9: -check for obj->last_write_seqno being 0 instead of obj->ring being NULL in intel_postpone_flip, as this is a more restrictive condition (Chris) v10: -Applied Chris's suggestions for squashing patches 2,3 into this patch. These patches make the selection of CS vs MMIO flip at the page flip time, and make the module parameter for using mmio flips as tristate, the states being 'force CS flips', 'force mmio flips', 'driver discretion'. Changed the logic for driver discretion (Chris) v11: Minor code cleanup(better readability, fixing whitespace errors, using lockdep to check mutex locked status in postpone_flip, removal of __must_check in function definition) (Chris) Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Sourab Gupta <sourab.gupta@intel.com> Signed-off-by: Akash Goel <akash.goel@intel.com> Tested-by: Chris Wilson <chris@chris-wilson.co.uk> # snb, ivb [danvet: Fix up parameter alignement checkpatch spotted.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-02 16:47:17 +05:30
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
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_request *req,
uint32_t flags)
{
struct intel_engine_cs *engine = req->engine;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
uint32_t pf, pipesrc;
int ret;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
ret = intel_ring_begin(req, 4);
if (ret)
return ret;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
/* i965+ uses the linear or tiled offsets from the
* Display Registers (which do not change across a page-flip)
* so we need only reprogram the base address.
*/
intel_ring_emit(engine, MI_DISPLAY_FLIP |
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
intel_ring_emit(engine, fb->pitches[0]);
intel_ring_emit(engine, intel_crtc->flip_work->gtt_offset |
obj->tiling_mode);
/* XXX Enabling the panel-fitter across page-flip is so far
* untested on non-native modes, so ignore it for now.
* pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE;
*/
pf = 0;
pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
intel_ring_emit(engine, pf | pipesrc);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
return 0;
}
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
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_request *req,
uint32_t flags)
{
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
struct intel_engine_cs *engine = req->engine;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
uint32_t pf, pipesrc;
int ret;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
ret = intel_ring_begin(req, 4);
if (ret)
return ret;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
intel_ring_emit(engine, MI_DISPLAY_FLIP |
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
intel_ring_emit(engine, fb->pitches[0] | obj->tiling_mode);
intel_ring_emit(engine, intel_crtc->flip_work->gtt_offset);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
/* Contrary to the suggestions in the documentation,
* "Enable Panel Fitter" does not seem to be required when page
* flipping with a non-native mode, and worse causes a normal
* modeset to fail.
* pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE;
*/
pf = 0;
pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
intel_ring_emit(engine, pf | pipesrc);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
return 0;
}
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
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_request *req,
uint32_t flags)
{
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
struct intel_engine_cs *engine = req->engine;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
uint32_t plane_bit = 0;
int len, ret;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
switch (intel_crtc->plane) {
case PLANE_A:
plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_A;
break;
case PLANE_B:
plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_B;
break;
case PLANE_C:
plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_C;
break;
default:
WARN_ONCE(1, "unknown plane in flip command\n");
return -ENODEV;
}
len = 4;
if (engine->id == RCS) {
len += 6;
/*
* On Gen 8, SRM is now taking an extra dword to accommodate
* 48bits addresses, and we need a NOOP for the batch size to
* stay even.
*/
if (IS_GEN8(dev))
len += 2;
}
/*
* BSpec MI_DISPLAY_FLIP for IVB:
* "The full packet must be contained within the same cache line."
*
* Currently the LRI+SRM+MI_DISPLAY_FLIP all fit within the same
* cacheline, if we ever start emitting more commands before
* the MI_DISPLAY_FLIP we may need to first emit everything else,
* then do the cacheline alignment, and finally emit the
* MI_DISPLAY_FLIP.
*/
ret = intel_ring_cacheline_align(req);
if (ret)
return ret;
ret = intel_ring_begin(req, len);
if (ret)
return ret;
/* 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 (engine->id == RCS) {
intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(1));
intel_ring_emit_reg(engine, DERRMR);
intel_ring_emit(engine, ~(DERRMR_PIPEA_PRI_FLIP_DONE |
DERRMR_PIPEB_PRI_FLIP_DONE |
DERRMR_PIPEC_PRI_FLIP_DONE));
if (IS_GEN8(dev))
intel_ring_emit(engine, MI_STORE_REGISTER_MEM_GEN8 |
MI_SRM_LRM_GLOBAL_GTT);
else
intel_ring_emit(engine, MI_STORE_REGISTER_MEM |
MI_SRM_LRM_GLOBAL_GTT);
intel_ring_emit_reg(engine, DERRMR);
intel_ring_emit(engine, engine->scratch.gtt_offset + 256);
if (IS_GEN8(dev)) {
intel_ring_emit(engine, 0);
intel_ring_emit(engine, MI_NOOP);
}
}
intel_ring_emit(engine, MI_DISPLAY_FLIP_I915 | plane_bit);
intel_ring_emit(engine, (fb->pitches[0] | obj->tiling_mode));
intel_ring_emit(engine, intel_crtc->flip_work->gtt_offset);
intel_ring_emit(engine, (MI_NOOP));
return 0;
}
static bool use_mmio_flip(struct intel_engine_cs *engine,
struct drm_i915_gem_object *obj)
{
struct reservation_object *resv;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
/*
* This is not being used for older platforms, because
* non-availability of flip done interrupt forces us to use
* CS flips. Older platforms derive flip done using some clever
* tricks involving the flip_pending status bits and vblank irqs.
* So using MMIO flips there would disrupt this mechanism.
*/
if (engine == NULL)
return true;
if (INTEL_GEN(engine->i915) < 5)
return false;
if (i915.use_mmio_flip < 0)
return false;
else if (i915.use_mmio_flip > 0)
return true;
else if (i915.enable_execlists)
return true;
resv = i915_gem_object_get_dmabuf_resv(obj);
if (resv && !reservation_object_test_signaled_rcu(resv, false))
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
return true;
return engine != i915_gem_request_get_engine(obj->last_write_req);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
}
static void skl_do_mmio_flip(struct intel_crtc *intel_crtc,
unsigned int rotation,
struct intel_flip_work *work)
{
struct drm_device *dev = intel_crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_framebuffer *fb = intel_crtc->base.primary->fb;
const enum pipe pipe = intel_crtc->pipe;
u32 ctl, stride, tile_height;
ctl = I915_READ(PLANE_CTL(pipe, 0));
ctl &= ~PLANE_CTL_TILED_MASK;
switch (fb->modifier[0]) {
case DRM_FORMAT_MOD_NONE:
break;
case I915_FORMAT_MOD_X_TILED:
ctl |= PLANE_CTL_TILED_X;
break;
case I915_FORMAT_MOD_Y_TILED:
ctl |= PLANE_CTL_TILED_Y;
break;
case I915_FORMAT_MOD_Yf_TILED:
ctl |= PLANE_CTL_TILED_YF;
break;
default:
MISSING_CASE(fb->modifier[0]);
}
/*
* The stride is either expressed as a multiple of 64 bytes chunks for
* linear buffers or in number of tiles for tiled buffers.
*/
if (intel_rotation_90_or_270(rotation)) {
/* stride = Surface height in tiles */
tile_height = intel_tile_height(dev_priv, fb->modifier[0], 0);
stride = DIV_ROUND_UP(fb->height, tile_height);
} else {
stride = fb->pitches[0] /
intel_fb_stride_alignment(dev_priv, fb->modifier[0],
fb->pixel_format);
}
/*
* Both PLANE_CTL and PLANE_STRIDE are not updated on vblank but on
* PLANE_SURF updates, the update is then guaranteed to be atomic.
*/
I915_WRITE(PLANE_CTL(pipe, 0), ctl);
I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
I915_WRITE(PLANE_SURF(pipe, 0), work->gtt_offset);
POSTING_READ(PLANE_SURF(pipe, 0));
}
static void ilk_do_mmio_flip(struct intel_crtc *intel_crtc,
struct intel_flip_work *work)
{
struct drm_device *dev = intel_crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_framebuffer *intel_fb =
to_intel_framebuffer(intel_crtc->base.primary->fb);
struct drm_i915_gem_object *obj = intel_fb->obj;
i915_reg_t reg = DSPCNTR(intel_crtc->plane);
u32 dspcntr;
dspcntr = I915_READ(reg);
if (obj->tiling_mode != I915_TILING_NONE)
dspcntr |= DISPPLANE_TILED;
else
dspcntr &= ~DISPPLANE_TILED;
I915_WRITE(reg, dspcntr);
I915_WRITE(DSPSURF(intel_crtc->plane), work->gtt_offset);
POSTING_READ(DSPSURF(intel_crtc->plane));
}
static void intel_mmio_flip_work_func(struct work_struct *w)
{
struct intel_flip_work *work =
container_of(w, struct intel_flip_work, mmio_work);
struct intel_crtc *crtc = to_intel_crtc(work->crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_framebuffer *intel_fb =
to_intel_framebuffer(crtc->base.primary->fb);
struct drm_i915_gem_object *obj = intel_fb->obj;
struct reservation_object *resv;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
if (work->flip_queued_req)
WARN_ON(__i915_wait_request(work->flip_queued_req,
false, NULL,
&dev_priv->rps.mmioflips));
/* For framebuffer backed by dmabuf, wait for fence */
resv = i915_gem_object_get_dmabuf_resv(obj);
if (resv)
WARN_ON(reservation_object_wait_timeout_rcu(resv, false, false,
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
MAX_SCHEDULE_TIMEOUT) < 0);
intel_pipe_update_start(crtc);
if (INTEL_GEN(dev_priv) >= 9)
skl_do_mmio_flip(crtc, work->rotation, work);
else
/* use_mmio_flip() retricts MMIO flips to ilk+ */
ilk_do_mmio_flip(crtc, work);
intel_pipe_update_end(crtc, work);
}
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_request *req,
uint32_t flags)
{
return -ENODEV;
}
static bool __pageflip_stall_check_cs(struct drm_i915_private *dev_priv,
struct intel_crtc *intel_crtc,
struct intel_flip_work *work)
{
u32 addr, vblank;
if (!atomic_read(&work->pending))
return false;
smp_rmb();
vblank = intel_crtc_get_vblank_counter(intel_crtc);
if (work->flip_ready_vblank == 0) {
if (work->flip_queued_req &&
!i915_gem_request_completed(work->flip_queued_req))
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
return false;
work->flip_ready_vblank = vblank;
}
if (vblank - work->flip_ready_vblank < 3)
return false;
/* Potential stall - if we see that the flip has happened,
* assume a missed interrupt. */
if (INTEL_GEN(dev_priv) >= 4)
addr = I915_HI_DISPBASE(I915_READ(DSPSURF(intel_crtc->plane)));
else
addr = I915_READ(DSPADDR(intel_crtc->plane));
/* There is a potential issue here with a false positive after a flip
* to the same address. We could address this by checking for a
* non-incrementing frame counter.
*/
return addr == work->gtt_offset;
}
void intel_check_page_flip(struct drm_i915_private *dev_priv, int pipe)
{
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);
struct intel_flip_work *work;
WARN_ON(!in_interrupt());
if (crtc == NULL)
return;
spin_lock(&dev->event_lock);
work = intel_crtc->flip_work;
if (work != NULL && !is_mmio_work(work) &&
__pageflip_stall_check_cs(dev_priv, intel_crtc, work)) {
WARN_ONCE(1,
"Kicking stuck page flip: queued at %d, now %d\n",
work->flip_queued_vblank, intel_crtc_get_vblank_counter(intel_crtc));
page_flip_completed(intel_crtc);
work = NULL;
}
if (work != NULL && !is_mmio_work(work) &&
intel_crtc_get_vblank_counter(intel_crtc) - work->flip_queued_vblank > 1)
intel_queue_rps_boost_for_request(work->flip_queued_req);
spin_unlock(&dev->event_lock);
}
static int intel_crtc_page_flip(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
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;
struct drm_framebuffer *old_fb = crtc->primary->fb;
struct drm_i915_gem_object *obj = intel_fb_obj(fb);
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct drm_plane *primary = crtc->primary;
enum pipe pipe = intel_crtc->pipe;
struct intel_flip_work *work;
struct intel_engine_cs *engine;
bool mmio_flip;
struct drm_i915_gem_request *request = NULL;
int ret;
/*
* drm_mode_page_flip_ioctl() should already catch this, but double
* check to be safe. In the future we may enable pageflipping from
* a disabled primary plane.
*/
if (WARN_ON(intel_fb_obj(old_fb) == NULL))
return -EBUSY;
/* Can't change pixel format via MI display flips. */
if (fb->pixel_format != crtc->primary->fb->pixel_format)
return -EINVAL;
/*
* TILEOFF/LINOFF registers can't be changed via MI display flips.
* Note that pitch changes could also affect these register.
*/
if (INTEL_INFO(dev)->gen > 3 &&
(fb->offsets[0] != crtc->primary->fb->offsets[0] ||
fb->pitches[0] != crtc->primary->fb->pitches[0]))
return -EINVAL;
if (i915_terminally_wedged(&dev_priv->gpu_error))
goto out_hang;
work = kzalloc(sizeof(*work), GFP_KERNEL);
if (work == NULL)
return -ENOMEM;
work->event = event;
work->crtc = crtc;
work->old_fb = old_fb;
INIT_WORK(&work->unpin_work, intel_unpin_work_fn);
ret = drm_crtc_vblank_get(crtc);
if (ret)
goto free_work;
/* We borrow the event spin lock for protecting flip_work */
spin_lock_irq(&dev->event_lock);
if (intel_crtc->flip_work) {
/* Before declaring the flip queue wedged, check if
* the hardware completed the operation behind our backs.
*/
if (pageflip_finished(intel_crtc, intel_crtc->flip_work)) {
DRM_DEBUG_DRIVER("flip queue: previous flip completed, continuing\n");
page_flip_completed(intel_crtc);
} else {
DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
spin_unlock_irq(&dev->event_lock);
drm_crtc_vblank_put(crtc);
kfree(work);
return -EBUSY;
}
}
intel_crtc->flip_work = work;
spin_unlock_irq(&dev->event_lock);
if (atomic_read(&intel_crtc->unpin_work_count) >= 2)
flush_workqueue(dev_priv->wq);
/* Reference the objects for the scheduled work. */
drm_framebuffer_reference(work->old_fb);
drm_gem_object_reference(&obj->base);
crtc->primary->fb = fb;
update_state_fb(crtc->primary);
intel_fbc_pre_update(intel_crtc, intel_crtc->config,
to_intel_plane_state(primary->state));
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
work->pending_flip_obj = obj;
ret = i915_mutex_lock_interruptible(dev);
if (ret)
goto cleanup;
intel_crtc->reset_counter = i915_reset_counter(&dev_priv->gpu_error);
if (__i915_reset_in_progress_or_wedged(intel_crtc->reset_counter)) {
ret = -EIO;
goto cleanup;
}
atomic_inc(&intel_crtc->unpin_work_count);
if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev))
work->flip_count = I915_READ(PIPE_FLIPCOUNT_G4X(pipe)) + 1;
if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
engine = &dev_priv->engine[BCS];
if (obj->tiling_mode != intel_fb_obj(work->old_fb)->tiling_mode)
/* vlv: DISPLAY_FLIP fails to change tiling */
engine = NULL;
} else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) {
engine = &dev_priv->engine[BCS];
} else if (INTEL_INFO(dev)->gen >= 7) {
engine = i915_gem_request_get_engine(obj->last_write_req);
if (engine == NULL || engine->id != RCS)
engine = &dev_priv->engine[BCS];
} else {
engine = &dev_priv->engine[RCS];
}
mmio_flip = use_mmio_flip(engine, obj);
/* When using CS flips, we want to emit semaphores between rings.
* However, when using mmio flips we will create a task to do the
* synchronisation, so all we want here is to pin the framebuffer
* into the display plane and skip any waits.
*/
if (!mmio_flip) {
ret = i915_gem_object_sync(obj, engine, &request);
if (!ret && !request) {
request = i915_gem_request_alloc(engine, NULL);
ret = PTR_ERR_OR_ZERO(request);
}
if (ret)
goto cleanup_pending;
}
ret = intel_pin_and_fence_fb_obj(fb, primary->state->rotation);
if (ret)
goto cleanup_pending;
work->gtt_offset = intel_plane_obj_offset(to_intel_plane(primary),
obj, 0);
work->gtt_offset += intel_crtc->dspaddr_offset;
work->rotation = crtc->primary->state->rotation;
if (mmio_flip) {
INIT_WORK(&work->mmio_work, intel_mmio_flip_work_func);
i915_gem_request_assign(&work->flip_queued_req,
obj->last_write_req);
schedule_work(&work->mmio_work);
} else {
i915_gem_request_assign(&work->flip_queued_req, request);
ret = dev_priv->display.queue_flip(dev, crtc, fb, obj, request,
page_flip_flags);
if (ret)
goto cleanup_unpin;
intel_mark_page_flip_active(intel_crtc, work);
i915_add_request_no_flush(request);
}
i915_gem_track_fb(intel_fb_obj(old_fb), obj,
to_intel_plane(primary)->frontbuffer_bit);
mutex_unlock(&dev->struct_mutex);
intel_frontbuffer_flip_prepare(dev,
to_intel_plane(primary)->frontbuffer_bit);
trace_i915_flip_request(intel_crtc->plane, obj);
return 0;
cleanup_unpin:
intel_unpin_fb_obj(fb, crtc->primary->state->rotation);
cleanup_pending:
if (!IS_ERR_OR_NULL(request))
i915_add_request_no_flush(request);
atomic_dec(&intel_crtc->unpin_work_count);
mutex_unlock(&dev->struct_mutex);
cleanup:
crtc->primary->fb = old_fb;
update_state_fb(crtc->primary);
drm_gem_object_unreference_unlocked(&obj->base);
drm_framebuffer_unreference(work->old_fb);
spin_lock_irq(&dev->event_lock);
intel_crtc->flip_work = NULL;
spin_unlock_irq(&dev->event_lock);
drm_crtc_vblank_put(crtc);
free_work:
kfree(work);
if (ret == -EIO) {
struct drm_atomic_state *state;
struct drm_plane_state *plane_state;
out_hang:
state = drm_atomic_state_alloc(dev);
if (!state)
return -ENOMEM;
state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
retry:
plane_state = drm_atomic_get_plane_state(state, primary);
ret = PTR_ERR_OR_ZERO(plane_state);
if (!ret) {
drm_atomic_set_fb_for_plane(plane_state, fb);
ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);
if (!ret)
ret = drm_atomic_commit(state);
}
if (ret == -EDEADLK) {
drm_modeset_backoff(state->acquire_ctx);
drm_atomic_state_clear(state);
goto retry;
}
if (ret)
drm_atomic_state_free(state);
if (ret == 0 && event) {
spin_lock_irq(&dev->event_lock);
drm_crtc_send_vblank_event(crtc, event);
spin_unlock_irq(&dev->event_lock);
}
}
return ret;
}
/**
* intel_wm_need_update - Check whether watermarks need updating
* @plane: drm plane
* @state: new plane state
*
* Check current plane state versus the new one to determine whether
* watermarks need to be recalculated.
*
* Returns true or false.
*/
static bool intel_wm_need_update(struct drm_plane *plane,
struct drm_plane_state *state)
{
struct intel_plane_state *new = to_intel_plane_state(state);
struct intel_plane_state *cur = to_intel_plane_state(plane->state);
/* Update watermarks on tiling or size changes. */
if (new->visible != cur->visible)
return true;
if (!cur->base.fb || !new->base.fb)
return false;
if (cur->base.fb->modifier[0] != new->base.fb->modifier[0] ||
cur->base.rotation != new->base.rotation ||
drm_rect_width(&new->src) != drm_rect_width(&cur->src) ||
drm_rect_height(&new->src) != drm_rect_height(&cur->src) ||
drm_rect_width(&new->dst) != drm_rect_width(&cur->dst) ||
drm_rect_height(&new->dst) != drm_rect_height(&cur->dst))
return true;
return false;
}
static bool needs_scaling(struct intel_plane_state *state)
{
int src_w = drm_rect_width(&state->src) >> 16;
int src_h = drm_rect_height(&state->src) >> 16;
int dst_w = drm_rect_width(&state->dst);
int dst_h = drm_rect_height(&state->dst);
return (src_w != dst_w || src_h != dst_h);
}
int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
struct drm_plane_state *plane_state)
{
struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc_state);
struct drm_crtc *crtc = crtc_state->crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct drm_plane *plane = plane_state->plane;
struct drm_device *dev = crtc->dev;
drm/i915: Add two-stage ILK-style watermark programming (v11) In addition to calculating final watermarks, let's also pre-calculate a set of intermediate watermark values at atomic check time. These intermediate watermarks are a combination of the watermarks for the old state and the new state; they should satisfy the requirements of both states which means they can be programmed immediately when we commit the atomic state (without waiting for a vblank). Once the vblank does happen, we can then re-program watermarks to the more optimal final value. v2: Significant rebasing/rewriting. v3: - Move 'need_postvbl_update' flag to CRTC state (Daniel) - Don't forget to check intermediate watermark values for validity (Maarten) - Don't due async watermark optimization; just do it at the end of the atomic transaction, after waiting for vblanks. We do want it to be async eventually, but adding that now will cause more trouble for Maarten's in-progress work. (Maarten) - Don't allocate space in crtc_state for intermediate watermarks on platforms that don't need it (gen9+). - Move WaCxSRDisabledForSpriteScaling:ivb into intel_begin_crtc_commit now that ilk_update_wm is gone. v4: - Add a wm_mutex to cover updates to intel_crtc->active and the need_postvbl_update flag. Since we don't have async yet it isn't terribly important yet, but might as well add it now. - Change interface to program watermarks. Platforms will now expose .initial_watermarks() and .optimize_watermarks() functions to do watermark programming. These should lock wm_mutex, copy the appropriate state values into intel_crtc->active, and then call the internal program watermarks function. v5: - Skip intermediate watermark calculation/check during initial hardware readout since we don't trust the existing HW values (and don't have valid values of our own yet). - Don't try to call .optimize_watermarks() on platforms that don't have atomic watermarks yet. (Maarten) v6: - Rebase v7: - Further rebase v8: - A few minor indentation and line length fixes v9: - Yet another rebase since Maarten's patches reworked a bunch of the code (wm_pre, wm_post, etc.) that this was previously based on. v10: - Move wm_mutex to dev_priv to protect against racing commits against disjoint CRTC sets. (Maarten) - Drop unnecessary clearing of cstate->wm.need_postvbl_update (Maarten) v11: - Now that we've moved to atomic watermark updates, make sure we call the proper function to program watermarks in {ironlake,haswell}_crtc_enable(); the failure to do so on the previous patch iteration led to us not actually programming the watermarks before turning on the CRTC, which was the cause of the underruns that the CI system was seeing. - Fix inverted logic for determining when to optimize watermarks. We were needlessly optimizing when the intermediate/optimal values were the same (harmless), but not actually optimizing when they differed (also harmless, but wasteful from a power/bandwidth perspective). Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1456276813-5689-1-git-send-email-matthew.d.roper@intel.com
2016-02-23 17:20:13 -08:00
struct drm_i915_private *dev_priv = to_i915(dev);
struct intel_plane_state *old_plane_state =
to_intel_plane_state(plane->state);
bool mode_changed = needs_modeset(crtc_state);
bool was_crtc_enabled = crtc->state->active;
bool is_crtc_enabled = crtc_state->active;
bool turn_off, turn_on, visible, was_visible;
struct drm_framebuffer *fb = plane_state->fb;
int ret;
if (INTEL_GEN(dev) >= 9 && plane->type != DRM_PLANE_TYPE_CURSOR) {
ret = skl_update_scaler_plane(
to_intel_crtc_state(crtc_state),
to_intel_plane_state(plane_state));
if (ret)
return ret;
}
was_visible = old_plane_state->visible;
visible = to_intel_plane_state(plane_state)->visible;
if (!was_crtc_enabled && WARN_ON(was_visible))
was_visible = false;
/*
* Visibility is calculated as if the crtc was on, but
* after scaler setup everything depends on it being off
* when the crtc isn't active.
*
* FIXME this is wrong for watermarks. Watermarks should also
* be computed as if the pipe would be active. Perhaps move
* per-plane wm computation to the .check_plane() hook, and
* only combine the results from all planes in the current place?
*/
if (!is_crtc_enabled)
to_intel_plane_state(plane_state)->visible = visible = false;
if (!was_visible && !visible)
return 0;
if (fb != old_plane_state->base.fb)
pipe_config->fb_changed = true;
turn_off = was_visible && (!visible || mode_changed);
turn_on = visible && (!was_visible || mode_changed);
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] has [PLANE:%d:%s] with fb %i\n",
intel_crtc->base.base.id,
intel_crtc->base.name,
plane->base.id, plane->name,
fb ? fb->base.id : -1);
DRM_DEBUG_ATOMIC("[PLANE:%d:%s] visible %i -> %i, off %i, on %i, ms %i\n",
plane->base.id, plane->name,
was_visible, visible,
turn_off, turn_on, mode_changed);
if (turn_on) {
pipe_config->update_wm_pre = true;
/* must disable cxsr around plane enable/disable */
if (plane->type != DRM_PLANE_TYPE_CURSOR)
pipe_config->disable_cxsr = true;
} else if (turn_off) {
pipe_config->update_wm_post = true;
/* must disable cxsr around plane enable/disable */
if (plane->type != DRM_PLANE_TYPE_CURSOR)
pipe_config->disable_cxsr = true;
} else if (intel_wm_need_update(plane, plane_state)) {
/* FIXME bollocks */
pipe_config->update_wm_pre = true;
pipe_config->update_wm_post = true;
}
drm/i915: Add two-stage ILK-style watermark programming (v11) In addition to calculating final watermarks, let's also pre-calculate a set of intermediate watermark values at atomic check time. These intermediate watermarks are a combination of the watermarks for the old state and the new state; they should satisfy the requirements of both states which means they can be programmed immediately when we commit the atomic state (without waiting for a vblank). Once the vblank does happen, we can then re-program watermarks to the more optimal final value. v2: Significant rebasing/rewriting. v3: - Move 'need_postvbl_update' flag to CRTC state (Daniel) - Don't forget to check intermediate watermark values for validity (Maarten) - Don't due async watermark optimization; just do it at the end of the atomic transaction, after waiting for vblanks. We do want it to be async eventually, but adding that now will cause more trouble for Maarten's in-progress work. (Maarten) - Don't allocate space in crtc_state for intermediate watermarks on platforms that don't need it (gen9+). - Move WaCxSRDisabledForSpriteScaling:ivb into intel_begin_crtc_commit now that ilk_update_wm is gone. v4: - Add a wm_mutex to cover updates to intel_crtc->active and the need_postvbl_update flag. Since we don't have async yet it isn't terribly important yet, but might as well add it now. - Change interface to program watermarks. Platforms will now expose .initial_watermarks() and .optimize_watermarks() functions to do watermark programming. These should lock wm_mutex, copy the appropriate state values into intel_crtc->active, and then call the internal program watermarks function. v5: - Skip intermediate watermark calculation/check during initial hardware readout since we don't trust the existing HW values (and don't have valid values of our own yet). - Don't try to call .optimize_watermarks() on platforms that don't have atomic watermarks yet. (Maarten) v6: - Rebase v7: - Further rebase v8: - A few minor indentation and line length fixes v9: - Yet another rebase since Maarten's patches reworked a bunch of the code (wm_pre, wm_post, etc.) that this was previously based on. v10: - Move wm_mutex to dev_priv to protect against racing commits against disjoint CRTC sets. (Maarten) - Drop unnecessary clearing of cstate->wm.need_postvbl_update (Maarten) v11: - Now that we've moved to atomic watermark updates, make sure we call the proper function to program watermarks in {ironlake,haswell}_crtc_enable(); the failure to do so on the previous patch iteration led to us not actually programming the watermarks before turning on the CRTC, which was the cause of the underruns that the CI system was seeing. - Fix inverted logic for determining when to optimize watermarks. We were needlessly optimizing when the intermediate/optimal values were the same (harmless), but not actually optimizing when they differed (also harmless, but wasteful from a power/bandwidth perspective). Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1456276813-5689-1-git-send-email-matthew.d.roper@intel.com
2016-02-23 17:20:13 -08:00
/* Pre-gen9 platforms need two-step watermark updates */
if ((pipe_config->update_wm_pre || pipe_config->update_wm_post) &&
INTEL_INFO(dev)->gen < 9 && dev_priv->display.optimize_watermarks)
drm/i915: Add two-stage ILK-style watermark programming (v11) In addition to calculating final watermarks, let's also pre-calculate a set of intermediate watermark values at atomic check time. These intermediate watermarks are a combination of the watermarks for the old state and the new state; they should satisfy the requirements of both states which means they can be programmed immediately when we commit the atomic state (without waiting for a vblank). Once the vblank does happen, we can then re-program watermarks to the more optimal final value. v2: Significant rebasing/rewriting. v3: - Move 'need_postvbl_update' flag to CRTC state (Daniel) - Don't forget to check intermediate watermark values for validity (Maarten) - Don't due async watermark optimization; just do it at the end of the atomic transaction, after waiting for vblanks. We do want it to be async eventually, but adding that now will cause more trouble for Maarten's in-progress work. (Maarten) - Don't allocate space in crtc_state for intermediate watermarks on platforms that don't need it (gen9+). - Move WaCxSRDisabledForSpriteScaling:ivb into intel_begin_crtc_commit now that ilk_update_wm is gone. v4: - Add a wm_mutex to cover updates to intel_crtc->active and the need_postvbl_update flag. Since we don't have async yet it isn't terribly important yet, but might as well add it now. - Change interface to program watermarks. Platforms will now expose .initial_watermarks() and .optimize_watermarks() functions to do watermark programming. These should lock wm_mutex, copy the appropriate state values into intel_crtc->active, and then call the internal program watermarks function. v5: - Skip intermediate watermark calculation/check during initial hardware readout since we don't trust the existing HW values (and don't have valid values of our own yet). - Don't try to call .optimize_watermarks() on platforms that don't have atomic watermarks yet. (Maarten) v6: - Rebase v7: - Further rebase v8: - A few minor indentation and line length fixes v9: - Yet another rebase since Maarten's patches reworked a bunch of the code (wm_pre, wm_post, etc.) that this was previously based on. v10: - Move wm_mutex to dev_priv to protect against racing commits against disjoint CRTC sets. (Maarten) - Drop unnecessary clearing of cstate->wm.need_postvbl_update (Maarten) v11: - Now that we've moved to atomic watermark updates, make sure we call the proper function to program watermarks in {ironlake,haswell}_crtc_enable(); the failure to do so on the previous patch iteration led to us not actually programming the watermarks before turning on the CRTC, which was the cause of the underruns that the CI system was seeing. - Fix inverted logic for determining when to optimize watermarks. We were needlessly optimizing when the intermediate/optimal values were the same (harmless), but not actually optimizing when they differed (also harmless, but wasteful from a power/bandwidth perspective). Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1456276813-5689-1-git-send-email-matthew.d.roper@intel.com
2016-02-23 17:20:13 -08:00
to_intel_crtc_state(crtc_state)->wm.need_postvbl_update = true;
if (visible || was_visible)
pipe_config->fb_bits |= to_intel_plane(plane)->frontbuffer_bit;
/*
* WaCxSRDisabledForSpriteScaling:ivb
*
* cstate->update_wm was already set above, so this flag will
* take effect when we commit and program watermarks.
*/
if (plane->type == DRM_PLANE_TYPE_OVERLAY && IS_IVYBRIDGE(dev) &&
needs_scaling(to_intel_plane_state(plane_state)) &&
!needs_scaling(old_plane_state))
pipe_config->disable_lp_wm = true;
return 0;
}
static bool encoders_cloneable(const struct intel_encoder *a,
const struct intel_encoder *b)
{
/* masks could be asymmetric, so check both ways */
return a == b || (a->cloneable & (1 << b->type) &&
b->cloneable & (1 << a->type));
}
static bool check_single_encoder_cloning(struct drm_atomic_state *state,
struct intel_crtc *crtc,
struct intel_encoder *encoder)
{
struct intel_encoder *source_encoder;
struct drm_connector *connector;
struct drm_connector_state *connector_state;
int i;
for_each_connector_in_state(state, connector, connector_state, i) {
if (connector_state->crtc != &crtc->base)
continue;
source_encoder =
to_intel_encoder(connector_state->best_encoder);
if (!encoders_cloneable(encoder, source_encoder))
return false;
}
return true;
}
static bool check_encoder_cloning(struct drm_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_encoder *encoder;
struct drm_connector *connector;
struct drm_connector_state *connector_state;
int i;
for_each_connector_in_state(state, connector, connector_state, i) {
if (connector_state->crtc != &crtc->base)
continue;
encoder = to_intel_encoder(connector_state->best_encoder);
if (!check_single_encoder_cloning(state, crtc, encoder))
return false;
}
return true;
}
static int intel_crtc_atomic_check(struct drm_crtc *crtc,
struct drm_crtc_state *crtc_state)
{
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_crtc_state *pipe_config =
to_intel_crtc_state(crtc_state);
struct drm_atomic_state *state = crtc_state->state;
int ret;
bool mode_changed = needs_modeset(crtc_state);
if (mode_changed && !check_encoder_cloning(state, intel_crtc)) {
DRM_DEBUG_KMS("rejecting invalid cloning configuration\n");
return -EINVAL;
}
if (mode_changed && !crtc_state->active)
pipe_config->update_wm_post = true;
if (mode_changed && crtc_state->enable &&
dev_priv->display.crtc_compute_clock &&
!WARN_ON(pipe_config->shared_dpll)) {
ret = dev_priv->display.crtc_compute_clock(intel_crtc,
pipe_config);
if (ret)
return ret;
}
if (crtc_state->color_mgmt_changed) {
ret = intel_color_check(crtc, crtc_state);
if (ret)
return ret;
}
ret = 0;
drm/i915: Calculate ILK-style watermarks during atomic check (v3) Calculate pipe watermarks during atomic calculation phase, based on the contents of the atomic transaction's state structure. We still program the watermarks at the same time we did before, but the computation now happens much earlier. While this patch isn't too exciting by itself, it paves the way for future patches. The eventual goal (which will be realized in future patches in this series) is to calculate multiple sets up watermark values up front, and then program them at different times (pre- vs post-vblank) on the platforms that need a two-step watermark update. While we're at it, s/intel_compute_pipe_wm/ilk_compute_pipe_wm/ since this function only applies to ILK-style watermarks and we have a completely different function for SKL-style watermarks. Note that the original code had a memcmp() in ilk_update_wm() to avoid calling ilk_program_watermarks() if the watermarks hadn't changed. This memcmp vanishes here, which means we may do some unnecessary result generation and merging in cases where watermarks didn't change, but the lower-level function ilk_write_wm_values already makes sure that we don't actually try to program the watermark registers again. v2: Squash a few commits from the original series together; no longer leave pre-calculated wm's in a separate temporary structure since it's easier to follow the logic if we just cut over to using the pre-calculated values directly. v3: - Pass intel_crtc instead of drm_crtc to .compute_pipe_wm() entrypoint and use intel_atomic_get_crtc_state() to avoid need for extra casting. (Ander) - Drop unused intel_check_crtc() function prototype. (Ander) Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Smoke-tested-by: Paulo Zanoni <przanoni@gmail.com> Link: http://patchwork.freedesktop.org/patch/60363/
2015-09-24 15:53:16 -07:00
if (dev_priv->display.compute_pipe_wm) {
ret = dev_priv->display.compute_pipe_wm(pipe_config);
drm/i915: Add two-stage ILK-style watermark programming (v11) In addition to calculating final watermarks, let's also pre-calculate a set of intermediate watermark values at atomic check time. These intermediate watermarks are a combination of the watermarks for the old state and the new state; they should satisfy the requirements of both states which means they can be programmed immediately when we commit the atomic state (without waiting for a vblank). Once the vblank does happen, we can then re-program watermarks to the more optimal final value. v2: Significant rebasing/rewriting. v3: - Move 'need_postvbl_update' flag to CRTC state (Daniel) - Don't forget to check intermediate watermark values for validity (Maarten) - Don't due async watermark optimization; just do it at the end of the atomic transaction, after waiting for vblanks. We do want it to be async eventually, but adding that now will cause more trouble for Maarten's in-progress work. (Maarten) - Don't allocate space in crtc_state for intermediate watermarks on platforms that don't need it (gen9+). - Move WaCxSRDisabledForSpriteScaling:ivb into intel_begin_crtc_commit now that ilk_update_wm is gone. v4: - Add a wm_mutex to cover updates to intel_crtc->active and the need_postvbl_update flag. Since we don't have async yet it isn't terribly important yet, but might as well add it now. - Change interface to program watermarks. Platforms will now expose .initial_watermarks() and .optimize_watermarks() functions to do watermark programming. These should lock wm_mutex, copy the appropriate state values into intel_crtc->active, and then call the internal program watermarks function. v5: - Skip intermediate watermark calculation/check during initial hardware readout since we don't trust the existing HW values (and don't have valid values of our own yet). - Don't try to call .optimize_watermarks() on platforms that don't have atomic watermarks yet. (Maarten) v6: - Rebase v7: - Further rebase v8: - A few minor indentation and line length fixes v9: - Yet another rebase since Maarten's patches reworked a bunch of the code (wm_pre, wm_post, etc.) that this was previously based on. v10: - Move wm_mutex to dev_priv to protect against racing commits against disjoint CRTC sets. (Maarten) - Drop unnecessary clearing of cstate->wm.need_postvbl_update (Maarten) v11: - Now that we've moved to atomic watermark updates, make sure we call the proper function to program watermarks in {ironlake,haswell}_crtc_enable(); the failure to do so on the previous patch iteration led to us not actually programming the watermarks before turning on the CRTC, which was the cause of the underruns that the CI system was seeing. - Fix inverted logic for determining when to optimize watermarks. We were needlessly optimizing when the intermediate/optimal values were the same (harmless), but not actually optimizing when they differed (also harmless, but wasteful from a power/bandwidth perspective). Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1456276813-5689-1-git-send-email-matthew.d.roper@intel.com
2016-02-23 17:20:13 -08:00
if (ret) {
DRM_DEBUG_KMS("Target pipe watermarks are invalid\n");
return ret;
}
}
if (dev_priv->display.compute_intermediate_wm &&
!to_intel_atomic_state(state)->skip_intermediate_wm) {
if (WARN_ON(!dev_priv->display.compute_pipe_wm))
return 0;
/*
* Calculate 'intermediate' watermarks that satisfy both the
* old state and the new state. We can program these
* immediately.
*/
ret = dev_priv->display.compute_intermediate_wm(crtc->dev,
intel_crtc,
pipe_config);
if (ret) {
DRM_DEBUG_KMS("No valid intermediate pipe watermarks are possible\n");
drm/i915: Calculate ILK-style watermarks during atomic check (v3) Calculate pipe watermarks during atomic calculation phase, based on the contents of the atomic transaction's state structure. We still program the watermarks at the same time we did before, but the computation now happens much earlier. While this patch isn't too exciting by itself, it paves the way for future patches. The eventual goal (which will be realized in future patches in this series) is to calculate multiple sets up watermark values up front, and then program them at different times (pre- vs post-vblank) on the platforms that need a two-step watermark update. While we're at it, s/intel_compute_pipe_wm/ilk_compute_pipe_wm/ since this function only applies to ILK-style watermarks and we have a completely different function for SKL-style watermarks. Note that the original code had a memcmp() in ilk_update_wm() to avoid calling ilk_program_watermarks() if the watermarks hadn't changed. This memcmp vanishes here, which means we may do some unnecessary result generation and merging in cases where watermarks didn't change, but the lower-level function ilk_write_wm_values already makes sure that we don't actually try to program the watermark registers again. v2: Squash a few commits from the original series together; no longer leave pre-calculated wm's in a separate temporary structure since it's easier to follow the logic if we just cut over to using the pre-calculated values directly. v3: - Pass intel_crtc instead of drm_crtc to .compute_pipe_wm() entrypoint and use intel_atomic_get_crtc_state() to avoid need for extra casting. (Ander) - Drop unused intel_check_crtc() function prototype. (Ander) Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Smoke-tested-by: Paulo Zanoni <przanoni@gmail.com> Link: http://patchwork.freedesktop.org/patch/60363/
2015-09-24 15:53:16 -07:00
return ret;
drm/i915: Add two-stage ILK-style watermark programming (v11) In addition to calculating final watermarks, let's also pre-calculate a set of intermediate watermark values at atomic check time. These intermediate watermarks are a combination of the watermarks for the old state and the new state; they should satisfy the requirements of both states which means they can be programmed immediately when we commit the atomic state (without waiting for a vblank). Once the vblank does happen, we can then re-program watermarks to the more optimal final value. v2: Significant rebasing/rewriting. v3: - Move 'need_postvbl_update' flag to CRTC state (Daniel) - Don't forget to check intermediate watermark values for validity (Maarten) - Don't due async watermark optimization; just do it at the end of the atomic transaction, after waiting for vblanks. We do want it to be async eventually, but adding that now will cause more trouble for Maarten's in-progress work. (Maarten) - Don't allocate space in crtc_state for intermediate watermarks on platforms that don't need it (gen9+). - Move WaCxSRDisabledForSpriteScaling:ivb into intel_begin_crtc_commit now that ilk_update_wm is gone. v4: - Add a wm_mutex to cover updates to intel_crtc->active and the need_postvbl_update flag. Since we don't have async yet it isn't terribly important yet, but might as well add it now. - Change interface to program watermarks. Platforms will now expose .initial_watermarks() and .optimize_watermarks() functions to do watermark programming. These should lock wm_mutex, copy the appropriate state values into intel_crtc->active, and then call the internal program watermarks function. v5: - Skip intermediate watermark calculation/check during initial hardware readout since we don't trust the existing HW values (and don't have valid values of our own yet). - Don't try to call .optimize_watermarks() on platforms that don't have atomic watermarks yet. (Maarten) v6: - Rebase v7: - Further rebase v8: - A few minor indentation and line length fixes v9: - Yet another rebase since Maarten's patches reworked a bunch of the code (wm_pre, wm_post, etc.) that this was previously based on. v10: - Move wm_mutex to dev_priv to protect against racing commits against disjoint CRTC sets. (Maarten) - Drop unnecessary clearing of cstate->wm.need_postvbl_update (Maarten) v11: - Now that we've moved to atomic watermark updates, make sure we call the proper function to program watermarks in {ironlake,haswell}_crtc_enable(); the failure to do so on the previous patch iteration led to us not actually programming the watermarks before turning on the CRTC, which was the cause of the underruns that the CI system was seeing. - Fix inverted logic for determining when to optimize watermarks. We were needlessly optimizing when the intermediate/optimal values were the same (harmless), but not actually optimizing when they differed (also harmless, but wasteful from a power/bandwidth perspective). Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1456276813-5689-1-git-send-email-matthew.d.roper@intel.com
2016-02-23 17:20:13 -08:00
}
drm/i915: Ignore stale wm register values on resume on ilk-bdw (v2) When we resume the watermark register may contain some BIOS leftovers, or just the hardware reset values. We should ignore those as the pipes will be off anyway, and so frobbing around with intermediate watermarks doesn't make much sense. In fact I think we should just throw the skip_intermediate_wm flag out, and instead properly sanitize the "active" watermarks to match the current plane and pipe states. The actual wm state readout might also need a bit of work. But for now, let's continue with the skip_intermediate_wm to keep the fix more minimal. Fixes this sort of errors on resume [drm:ilk_validate_pipe_wm] LP0 watermark invalid [drm:intel_crtc_atomic_check] No valid intermediate pipe watermarks are possible [drm:intel_display_resume [i915]] *ERROR* Restoring old state failed with -22 and a boatload of subsequent modeset BAT fails on my ILK. v2: - Rebase; the SKL atomic WM patches that just landed changed the WM structure fields in intel_crtc_state slightly. (Matt) Cc: Matt Roper <matthew.d.roper@intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Fixes: ed4a6a7ca853 ("drm/i915: Add two-stage ILK-style watermark programming (v11)") Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1463159442-20478-1-git-send-email-matthew.d.roper@intel.com
2016-05-13 10:10:42 -07:00
} else if (dev_priv->display.compute_intermediate_wm) {
if (HAS_PCH_SPLIT(dev_priv) && INTEL_GEN(dev_priv) < 9)
pipe_config->wm.ilk.intermediate = pipe_config->wm.ilk.optimal;
drm/i915: Calculate ILK-style watermarks during atomic check (v3) Calculate pipe watermarks during atomic calculation phase, based on the contents of the atomic transaction's state structure. We still program the watermarks at the same time we did before, but the computation now happens much earlier. While this patch isn't too exciting by itself, it paves the way for future patches. The eventual goal (which will be realized in future patches in this series) is to calculate multiple sets up watermark values up front, and then program them at different times (pre- vs post-vblank) on the platforms that need a two-step watermark update. While we're at it, s/intel_compute_pipe_wm/ilk_compute_pipe_wm/ since this function only applies to ILK-style watermarks and we have a completely different function for SKL-style watermarks. Note that the original code had a memcmp() in ilk_update_wm() to avoid calling ilk_program_watermarks() if the watermarks hadn't changed. This memcmp vanishes here, which means we may do some unnecessary result generation and merging in cases where watermarks didn't change, but the lower-level function ilk_write_wm_values already makes sure that we don't actually try to program the watermark registers again. v2: Squash a few commits from the original series together; no longer leave pre-calculated wm's in a separate temporary structure since it's easier to follow the logic if we just cut over to using the pre-calculated values directly. v3: - Pass intel_crtc instead of drm_crtc to .compute_pipe_wm() entrypoint and use intel_atomic_get_crtc_state() to avoid need for extra casting. (Ander) - Drop unused intel_check_crtc() function prototype. (Ander) Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Smoke-tested-by: Paulo Zanoni <przanoni@gmail.com> Link: http://patchwork.freedesktop.org/patch/60363/
2015-09-24 15:53:16 -07:00
}
if (INTEL_INFO(dev)->gen >= 9) {
if (mode_changed)
ret = skl_update_scaler_crtc(pipe_config);
if (!ret)
ret = intel_atomic_setup_scalers(dev, intel_crtc,
pipe_config);
}
return ret;
}
static const struct drm_crtc_helper_funcs intel_helper_funcs = {
.mode_set_base_atomic = intel_pipe_set_base_atomic,
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
.atomic_begin = intel_begin_crtc_commit,
.atomic_flush = intel_finish_crtc_commit,
.atomic_check = intel_crtc_atomic_check,
};
static void intel_modeset_update_connector_atomic_state(struct drm_device *dev)
{
struct intel_connector *connector;
for_each_intel_connector(dev, connector) {
if (connector->base.state->crtc)
drm_connector_unreference(&connector->base);
if (connector->base.encoder) {
connector->base.state->best_encoder =
connector->base.encoder;
connector->base.state->crtc =
connector->base.encoder->crtc;
drm_connector_reference(&connector->base);
} else {
connector->base.state->best_encoder = NULL;
connector->base.state->crtc = NULL;
}
}
}
static void
connected_sink_compute_bpp(struct intel_connector *connector,
struct intel_crtc_state *pipe_config)
{
int bpp = pipe_config->pipe_bpp;
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] checking for sink bpp constrains\n",
connector->base.base.id,
connector->base.name);
/* 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 default limit on screens without EDID 1.4 */
if (connector->base.display_info.bpc == 0) {
int type = connector->base.connector_type;
int clamp_bpp = 24;
/* Fall back to 18 bpp when DP sink capability is unknown. */
if (type == DRM_MODE_CONNECTOR_DisplayPort ||
type == DRM_MODE_CONNECTOR_eDP)
clamp_bpp = 18;
if (bpp > clamp_bpp) {
DRM_DEBUG_KMS("clamping display bpp (was %d) to default limit of %d\n",
bpp, clamp_bpp);
pipe_config->pipe_bpp = clamp_bpp;
}
}
}
drm/i915: precompute pipe bpp before touching the hw The procedure has now 3 steps: 1. Compute the bpp that the plane will output, this is done in pipe_config_set_bpp and stored into pipe_config->pipe_bpp. Also, this function clamps the pipe_bpp to whatever limit the EDID of any connected output specifies. 2. Adjust the pipe_bpp in the encoder and crtc functions, according to whatever constraints there are. 3. Decide whether to use dither by comparing the stored plane bpp with computed pipe_bpp. There are a few slight functional changes in this patch: - LVDS connector are now also going through the EDID clamping. But in a 2nd change we now unconditionally force the lvds bpc value - this shouldn't matter in reality when the panel setup is consistent, but better safe than sorry. - HDMI now forces the pipe_bpp to the selected value - I think that's what we actually want, since otherwise at least the pixelclock computations are wrong (I'm not sure whether the port would accept e.g. 10 bpc when in 12bpc mode). Contrary to the old code, we pick the next higher bpc value, since otherwise there's no way to make use of the 12 bpc mode (since the next patch will remove the 12bpc plane format, it doesn't exist). Both of these changes are due to the removal of the pipe_bpp = min(display_bpp, plane_bpp); statement. Another slight change is the reworking of the dp bpc code: - For the mode_valid callback it's sufficient to only check whether the mode would fit at the lowest bpc. - The bandwidth computation code is a bit restructured: It now walks all available bpp values in an outer loop and the codeblock that computes derived values (once a good configuration is found) has been moved out of the for loop maze. This is prep work to allow us to successively fall back on bpc values, and also correctly support bpc values != 8 or 6. v2: Rebased on top of Paulo Zanoni's little refactoring to use more drm dp helper functions. v3: Rebased on top of Jani's eDP bpp fix and Ville's limited color range work. v4: Remove the INTEL_MODE_DP_FORCE_6BPC #define, no longer needed. v5: Remove intel_crtc->bpp, too, and fix up the 12bpc check in the hdmi code. Also fixup the bpp check in intel_dp.c, it'll get reworked in a later patch though again. v6: Fix spelling in a comment. v7: Debug output improvements for the bpp computation. v8: Fixup 6bpc lvds check - dual-link and 8bpc mode are different things! v9: Reinstate the fix to properly ignore the firmware edp bpp ... this was lost in a rebase. v10: Both g4x and vlv lack 12bpc pipes, so don't enforce that we have that. Still unsure whether this is the way to go, but at least 6bpc for a 8bpc hdmi output seems to work. v11: And g4x/vlv also lack 12bpc hdmi support, so only support high depth on DP. Adjust the code. v12: Rebased. v13: Split out the introduction of pipe_config->dither|pipe_bpp, as requested from Jesse Barnes. v14: Split out the special 6BPC handling for DP, as requested by Jesse Barnes. Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-03-27 00:44:58 +01:00
static int
compute_baseline_pipe_bpp(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config)
drm/i915: precompute pipe bpp before touching the hw The procedure has now 3 steps: 1. Compute the bpp that the plane will output, this is done in pipe_config_set_bpp and stored into pipe_config->pipe_bpp. Also, this function clamps the pipe_bpp to whatever limit the EDID of any connected output specifies. 2. Adjust the pipe_bpp in the encoder and crtc functions, according to whatever constraints there are. 3. Decide whether to use dither by comparing the stored plane bpp with computed pipe_bpp. There are a few slight functional changes in this patch: - LVDS connector are now also going through the EDID clamping. But in a 2nd change we now unconditionally force the lvds bpc value - this shouldn't matter in reality when the panel setup is consistent, but better safe than sorry. - HDMI now forces the pipe_bpp to the selected value - I think that's what we actually want, since otherwise at least the pixelclock computations are wrong (I'm not sure whether the port would accept e.g. 10 bpc when in 12bpc mode). Contrary to the old code, we pick the next higher bpc value, since otherwise there's no way to make use of the 12 bpc mode (since the next patch will remove the 12bpc plane format, it doesn't exist). Both of these changes are due to the removal of the pipe_bpp = min(display_bpp, plane_bpp); statement. Another slight change is the reworking of the dp bpc code: - For the mode_valid callback it's sufficient to only check whether the mode would fit at the lowest bpc. - The bandwidth computation code is a bit restructured: It now walks all available bpp values in an outer loop and the codeblock that computes derived values (once a good configuration is found) has been moved out of the for loop maze. This is prep work to allow us to successively fall back on bpc values, and also correctly support bpc values != 8 or 6. v2: Rebased on top of Paulo Zanoni's little refactoring to use more drm dp helper functions. v3: Rebased on top of Jani's eDP bpp fix and Ville's limited color range work. v4: Remove the INTEL_MODE_DP_FORCE_6BPC #define, no longer needed. v5: Remove intel_crtc->bpp, too, and fix up the 12bpc check in the hdmi code. Also fixup the bpp check in intel_dp.c, it'll get reworked in a later patch though again. v6: Fix spelling in a comment. v7: Debug output improvements for the bpp computation. v8: Fixup 6bpc lvds check - dual-link and 8bpc mode are different things! v9: Reinstate the fix to properly ignore the firmware edp bpp ... this was lost in a rebase. v10: Both g4x and vlv lack 12bpc pipes, so don't enforce that we have that. Still unsure whether this is the way to go, but at least 6bpc for a 8bpc hdmi output seems to work. v11: And g4x/vlv also lack 12bpc hdmi support, so only support high depth on DP. Adjust the code. v12: Rebased. v13: Split out the introduction of pipe_config->dither|pipe_bpp, as requested from Jesse Barnes. v14: Split out the special 6BPC handling for DP, as requested by Jesse Barnes. Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-03-27 00:44:58 +01:00
{
struct drm_device *dev = crtc->base.dev;
struct drm_atomic_state *state;
struct drm_connector *connector;
struct drm_connector_state *connector_state;
int bpp, i;
drm/i915: precompute pipe bpp before touching the hw The procedure has now 3 steps: 1. Compute the bpp that the plane will output, this is done in pipe_config_set_bpp and stored into pipe_config->pipe_bpp. Also, this function clamps the pipe_bpp to whatever limit the EDID of any connected output specifies. 2. Adjust the pipe_bpp in the encoder and crtc functions, according to whatever constraints there are. 3. Decide whether to use dither by comparing the stored plane bpp with computed pipe_bpp. There are a few slight functional changes in this patch: - LVDS connector are now also going through the EDID clamping. But in a 2nd change we now unconditionally force the lvds bpc value - this shouldn't matter in reality when the panel setup is consistent, but better safe than sorry. - HDMI now forces the pipe_bpp to the selected value - I think that's what we actually want, since otherwise at least the pixelclock computations are wrong (I'm not sure whether the port would accept e.g. 10 bpc when in 12bpc mode). Contrary to the old code, we pick the next higher bpc value, since otherwise there's no way to make use of the 12 bpc mode (since the next patch will remove the 12bpc plane format, it doesn't exist). Both of these changes are due to the removal of the pipe_bpp = min(display_bpp, plane_bpp); statement. Another slight change is the reworking of the dp bpc code: - For the mode_valid callback it's sufficient to only check whether the mode would fit at the lowest bpc. - The bandwidth computation code is a bit restructured: It now walks all available bpp values in an outer loop and the codeblock that computes derived values (once a good configuration is found) has been moved out of the for loop maze. This is prep work to allow us to successively fall back on bpc values, and also correctly support bpc values != 8 or 6. v2: Rebased on top of Paulo Zanoni's little refactoring to use more drm dp helper functions. v3: Rebased on top of Jani's eDP bpp fix and Ville's limited color range work. v4: Remove the INTEL_MODE_DP_FORCE_6BPC #define, no longer needed. v5: Remove intel_crtc->bpp, too, and fix up the 12bpc check in the hdmi code. Also fixup the bpp check in intel_dp.c, it'll get reworked in a later patch though again. v6: Fix spelling in a comment. v7: Debug output improvements for the bpp computation. v8: Fixup 6bpc lvds check - dual-link and 8bpc mode are different things! v9: Reinstate the fix to properly ignore the firmware edp bpp ... this was lost in a rebase. v10: Both g4x and vlv lack 12bpc pipes, so don't enforce that we have that. Still unsure whether this is the way to go, but at least 6bpc for a 8bpc hdmi output seems to work. v11: And g4x/vlv also lack 12bpc hdmi support, so only support high depth on DP. Adjust the code. v12: Rebased. v13: Split out the introduction of pipe_config->dither|pipe_bpp, as requested from Jesse Barnes. v14: Split out the special 6BPC handling for DP, as requested by Jesse Barnes. Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-03-27 00:44:58 +01:00
if ((IS_G4X(dev) || IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)))
drm/i915: precompute pipe bpp before touching the hw The procedure has now 3 steps: 1. Compute the bpp that the plane will output, this is done in pipe_config_set_bpp and stored into pipe_config->pipe_bpp. Also, this function clamps the pipe_bpp to whatever limit the EDID of any connected output specifies. 2. Adjust the pipe_bpp in the encoder and crtc functions, according to whatever constraints there are. 3. Decide whether to use dither by comparing the stored plane bpp with computed pipe_bpp. There are a few slight functional changes in this patch: - LVDS connector are now also going through the EDID clamping. But in a 2nd change we now unconditionally force the lvds bpc value - this shouldn't matter in reality when the panel setup is consistent, but better safe than sorry. - HDMI now forces the pipe_bpp to the selected value - I think that's what we actually want, since otherwise at least the pixelclock computations are wrong (I'm not sure whether the port would accept e.g. 10 bpc when in 12bpc mode). Contrary to the old code, we pick the next higher bpc value, since otherwise there's no way to make use of the 12 bpc mode (since the next patch will remove the 12bpc plane format, it doesn't exist). Both of these changes are due to the removal of the pipe_bpp = min(display_bpp, plane_bpp); statement. Another slight change is the reworking of the dp bpc code: - For the mode_valid callback it's sufficient to only check whether the mode would fit at the lowest bpc. - The bandwidth computation code is a bit restructured: It now walks all available bpp values in an outer loop and the codeblock that computes derived values (once a good configuration is found) has been moved out of the for loop maze. This is prep work to allow us to successively fall back on bpc values, and also correctly support bpc values != 8 or 6. v2: Rebased on top of Paulo Zanoni's little refactoring to use more drm dp helper functions. v3: Rebased on top of Jani's eDP bpp fix and Ville's limited color range work. v4: Remove the INTEL_MODE_DP_FORCE_6BPC #define, no longer needed. v5: Remove intel_crtc->bpp, too, and fix up the 12bpc check in the hdmi code. Also fixup the bpp check in intel_dp.c, it'll get reworked in a later patch though again. v6: Fix spelling in a comment. v7: Debug output improvements for the bpp computation. v8: Fixup 6bpc lvds check - dual-link and 8bpc mode are different things! v9: Reinstate the fix to properly ignore the firmware edp bpp ... this was lost in a rebase. v10: Both g4x and vlv lack 12bpc pipes, so don't enforce that we have that. Still unsure whether this is the way to go, but at least 6bpc for a 8bpc hdmi output seems to work. v11: And g4x/vlv also lack 12bpc hdmi support, so only support high depth on DP. Adjust the code. v12: Rebased. v13: Split out the introduction of pipe_config->dither|pipe_bpp, as requested from Jesse Barnes. v14: Split out the special 6BPC handling for DP, as requested by Jesse Barnes. Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-03-27 00:44:58 +01:00
bpp = 10*3;
else if (INTEL_INFO(dev)->gen >= 5)
bpp = 12*3;
else
bpp = 8*3;
drm/i915: precompute pipe bpp before touching the hw The procedure has now 3 steps: 1. Compute the bpp that the plane will output, this is done in pipe_config_set_bpp and stored into pipe_config->pipe_bpp. Also, this function clamps the pipe_bpp to whatever limit the EDID of any connected output specifies. 2. Adjust the pipe_bpp in the encoder and crtc functions, according to whatever constraints there are. 3. Decide whether to use dither by comparing the stored plane bpp with computed pipe_bpp. There are a few slight functional changes in this patch: - LVDS connector are now also going through the EDID clamping. But in a 2nd change we now unconditionally force the lvds bpc value - this shouldn't matter in reality when the panel setup is consistent, but better safe than sorry. - HDMI now forces the pipe_bpp to the selected value - I think that's what we actually want, since otherwise at least the pixelclock computations are wrong (I'm not sure whether the port would accept e.g. 10 bpc when in 12bpc mode). Contrary to the old code, we pick the next higher bpc value, since otherwise there's no way to make use of the 12 bpc mode (since the next patch will remove the 12bpc plane format, it doesn't exist). Both of these changes are due to the removal of the pipe_bpp = min(display_bpp, plane_bpp); statement. Another slight change is the reworking of the dp bpc code: - For the mode_valid callback it's sufficient to only check whether the mode would fit at the lowest bpc. - The bandwidth computation code is a bit restructured: It now walks all available bpp values in an outer loop and the codeblock that computes derived values (once a good configuration is found) has been moved out of the for loop maze. This is prep work to allow us to successively fall back on bpc values, and also correctly support bpc values != 8 or 6. v2: Rebased on top of Paulo Zanoni's little refactoring to use more drm dp helper functions. v3: Rebased on top of Jani's eDP bpp fix and Ville's limited color range work. v4: Remove the INTEL_MODE_DP_FORCE_6BPC #define, no longer needed. v5: Remove intel_crtc->bpp, too, and fix up the 12bpc check in the hdmi code. Also fixup the bpp check in intel_dp.c, it'll get reworked in a later patch though again. v6: Fix spelling in a comment. v7: Debug output improvements for the bpp computation. v8: Fixup 6bpc lvds check - dual-link and 8bpc mode are different things! v9: Reinstate the fix to properly ignore the firmware edp bpp ... this was lost in a rebase. v10: Both g4x and vlv lack 12bpc pipes, so don't enforce that we have that. Still unsure whether this is the way to go, but at least 6bpc for a 8bpc hdmi output seems to work. v11: And g4x/vlv also lack 12bpc hdmi support, so only support high depth on DP. Adjust the code. v12: Rebased. v13: Split out the introduction of pipe_config->dither|pipe_bpp, as requested from Jesse Barnes. v14: Split out the special 6BPC handling for DP, as requested by Jesse Barnes. Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-03-27 00:44:58 +01:00
pipe_config->pipe_bpp = bpp;
state = pipe_config->base.state;
drm/i915: precompute pipe bpp before touching the hw The procedure has now 3 steps: 1. Compute the bpp that the plane will output, this is done in pipe_config_set_bpp and stored into pipe_config->pipe_bpp. Also, this function clamps the pipe_bpp to whatever limit the EDID of any connected output specifies. 2. Adjust the pipe_bpp in the encoder and crtc functions, according to whatever constraints there are. 3. Decide whether to use dither by comparing the stored plane bpp with computed pipe_bpp. There are a few slight functional changes in this patch: - LVDS connector are now also going through the EDID clamping. But in a 2nd change we now unconditionally force the lvds bpc value - this shouldn't matter in reality when the panel setup is consistent, but better safe than sorry. - HDMI now forces the pipe_bpp to the selected value - I think that's what we actually want, since otherwise at least the pixelclock computations are wrong (I'm not sure whether the port would accept e.g. 10 bpc when in 12bpc mode). Contrary to the old code, we pick the next higher bpc value, since otherwise there's no way to make use of the 12 bpc mode (since the next patch will remove the 12bpc plane format, it doesn't exist). Both of these changes are due to the removal of the pipe_bpp = min(display_bpp, plane_bpp); statement. Another slight change is the reworking of the dp bpc code: - For the mode_valid callback it's sufficient to only check whether the mode would fit at the lowest bpc. - The bandwidth computation code is a bit restructured: It now walks all available bpp values in an outer loop and the codeblock that computes derived values (once a good configuration is found) has been moved out of the for loop maze. This is prep work to allow us to successively fall back on bpc values, and also correctly support bpc values != 8 or 6. v2: Rebased on top of Paulo Zanoni's little refactoring to use more drm dp helper functions. v3: Rebased on top of Jani's eDP bpp fix and Ville's limited color range work. v4: Remove the INTEL_MODE_DP_FORCE_6BPC #define, no longer needed. v5: Remove intel_crtc->bpp, too, and fix up the 12bpc check in the hdmi code. Also fixup the bpp check in intel_dp.c, it'll get reworked in a later patch though again. v6: Fix spelling in a comment. v7: Debug output improvements for the bpp computation. v8: Fixup 6bpc lvds check - dual-link and 8bpc mode are different things! v9: Reinstate the fix to properly ignore the firmware edp bpp ... this was lost in a rebase. v10: Both g4x and vlv lack 12bpc pipes, so don't enforce that we have that. Still unsure whether this is the way to go, but at least 6bpc for a 8bpc hdmi output seems to work. v11: And g4x/vlv also lack 12bpc hdmi support, so only support high depth on DP. Adjust the code. v12: Rebased. v13: Split out the introduction of pipe_config->dither|pipe_bpp, as requested from Jesse Barnes. v14: Split out the special 6BPC handling for DP, as requested by Jesse Barnes. Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-03-27 00:44:58 +01:00
/* Clamp display bpp to EDID value */
for_each_connector_in_state(state, connector, connector_state, i) {
if (connector_state->crtc != &crtc->base)
drm/i915: precompute pipe bpp before touching the hw The procedure has now 3 steps: 1. Compute the bpp that the plane will output, this is done in pipe_config_set_bpp and stored into pipe_config->pipe_bpp. Also, this function clamps the pipe_bpp to whatever limit the EDID of any connected output specifies. 2. Adjust the pipe_bpp in the encoder and crtc functions, according to whatever constraints there are. 3. Decide whether to use dither by comparing the stored plane bpp with computed pipe_bpp. There are a few slight functional changes in this patch: - LVDS connector are now also going through the EDID clamping. But in a 2nd change we now unconditionally force the lvds bpc value - this shouldn't matter in reality when the panel setup is consistent, but better safe than sorry. - HDMI now forces the pipe_bpp to the selected value - I think that's what we actually want, since otherwise at least the pixelclock computations are wrong (I'm not sure whether the port would accept e.g. 10 bpc when in 12bpc mode). Contrary to the old code, we pick the next higher bpc value, since otherwise there's no way to make use of the 12 bpc mode (since the next patch will remove the 12bpc plane format, it doesn't exist). Both of these changes are due to the removal of the pipe_bpp = min(display_bpp, plane_bpp); statement. Another slight change is the reworking of the dp bpc code: - For the mode_valid callback it's sufficient to only check whether the mode would fit at the lowest bpc. - The bandwidth computation code is a bit restructured: It now walks all available bpp values in an outer loop and the codeblock that computes derived values (once a good configuration is found) has been moved out of the for loop maze. This is prep work to allow us to successively fall back on bpc values, and also correctly support bpc values != 8 or 6. v2: Rebased on top of Paulo Zanoni's little refactoring to use more drm dp helper functions. v3: Rebased on top of Jani's eDP bpp fix and Ville's limited color range work. v4: Remove the INTEL_MODE_DP_FORCE_6BPC #define, no longer needed. v5: Remove intel_crtc->bpp, too, and fix up the 12bpc check in the hdmi code. Also fixup the bpp check in intel_dp.c, it'll get reworked in a later patch though again. v6: Fix spelling in a comment. v7: Debug output improvements for the bpp computation. v8: Fixup 6bpc lvds check - dual-link and 8bpc mode are different things! v9: Reinstate the fix to properly ignore the firmware edp bpp ... this was lost in a rebase. v10: Both g4x and vlv lack 12bpc pipes, so don't enforce that we have that. Still unsure whether this is the way to go, but at least 6bpc for a 8bpc hdmi output seems to work. v11: And g4x/vlv also lack 12bpc hdmi support, so only support high depth on DP. Adjust the code. v12: Rebased. v13: Split out the introduction of pipe_config->dither|pipe_bpp, as requested from Jesse Barnes. v14: Split out the special 6BPC handling for DP, as requested by Jesse Barnes. Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-03-27 00:44:58 +01:00
continue;
connected_sink_compute_bpp(to_intel_connector(connector),
pipe_config);
drm/i915: precompute pipe bpp before touching the hw The procedure has now 3 steps: 1. Compute the bpp that the plane will output, this is done in pipe_config_set_bpp and stored into pipe_config->pipe_bpp. Also, this function clamps the pipe_bpp to whatever limit the EDID of any connected output specifies. 2. Adjust the pipe_bpp in the encoder and crtc functions, according to whatever constraints there are. 3. Decide whether to use dither by comparing the stored plane bpp with computed pipe_bpp. There are a few slight functional changes in this patch: - LVDS connector are now also going through the EDID clamping. But in a 2nd change we now unconditionally force the lvds bpc value - this shouldn't matter in reality when the panel setup is consistent, but better safe than sorry. - HDMI now forces the pipe_bpp to the selected value - I think that's what we actually want, since otherwise at least the pixelclock computations are wrong (I'm not sure whether the port would accept e.g. 10 bpc when in 12bpc mode). Contrary to the old code, we pick the next higher bpc value, since otherwise there's no way to make use of the 12 bpc mode (since the next patch will remove the 12bpc plane format, it doesn't exist). Both of these changes are due to the removal of the pipe_bpp = min(display_bpp, plane_bpp); statement. Another slight change is the reworking of the dp bpc code: - For the mode_valid callback it's sufficient to only check whether the mode would fit at the lowest bpc. - The bandwidth computation code is a bit restructured: It now walks all available bpp values in an outer loop and the codeblock that computes derived values (once a good configuration is found) has been moved out of the for loop maze. This is prep work to allow us to successively fall back on bpc values, and also correctly support bpc values != 8 or 6. v2: Rebased on top of Paulo Zanoni's little refactoring to use more drm dp helper functions. v3: Rebased on top of Jani's eDP bpp fix and Ville's limited color range work. v4: Remove the INTEL_MODE_DP_FORCE_6BPC #define, no longer needed. v5: Remove intel_crtc->bpp, too, and fix up the 12bpc check in the hdmi code. Also fixup the bpp check in intel_dp.c, it'll get reworked in a later patch though again. v6: Fix spelling in a comment. v7: Debug output improvements for the bpp computation. v8: Fixup 6bpc lvds check - dual-link and 8bpc mode are different things! v9: Reinstate the fix to properly ignore the firmware edp bpp ... this was lost in a rebase. v10: Both g4x and vlv lack 12bpc pipes, so don't enforce that we have that. Still unsure whether this is the way to go, but at least 6bpc for a 8bpc hdmi output seems to work. v11: And g4x/vlv also lack 12bpc hdmi support, so only support high depth on DP. Adjust the code. v12: Rebased. v13: Split out the introduction of pipe_config->dither|pipe_bpp, as requested from Jesse Barnes. v14: Split out the special 6BPC handling for DP, as requested by Jesse Barnes. Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-03-27 00:44:58 +01:00
}
return bpp;
}
static void intel_dump_crtc_timings(const struct drm_display_mode *mode)
{
DRM_DEBUG_KMS("crtc timings: %d %d %d %d %d %d %d %d %d, "
"type: 0x%x flags: 0x%x\n",
mode->crtc_clock,
mode->crtc_hdisplay, mode->crtc_hsync_start,
mode->crtc_hsync_end, mode->crtc_htotal,
mode->crtc_vdisplay, mode->crtc_vsync_start,
mode->crtc_vsync_end, mode->crtc_vtotal, mode->type, mode->flags);
}
static void intel_dump_pipe_config(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config,
const char *context)
{
struct drm_device *dev = crtc->base.dev;
struct drm_plane *plane;
struct intel_plane *intel_plane;
struct intel_plane_state *state;
struct drm_framebuffer *fb;
DRM_DEBUG_KMS("[CRTC:%d:%s]%s config %p for pipe %c\n",
crtc->base.base.id, crtc->base.name,
context, pipe_config, pipe_name(crtc->pipe));
DRM_DEBUG_KMS("cpu_transcoder: %s\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("dp: %i, lanes: %i, gmch_m: %u, gmch_n: %u, link_m: %u, link_n: %u, tu: %u\n",
pipe_config->has_dp_encoder,
pipe_config->lane_count,
pipe_config->dp_m_n.gmch_m, pipe_config->dp_m_n.gmch_n,
pipe_config->dp_m_n.link_m, pipe_config->dp_m_n.link_n,
pipe_config->dp_m_n.tu);
drm/i915: State readout and cross-checking for dp_m2_n2 Adding relevant read out comparison code, in check_crtc_state, for the new member of crtc_config, dp_m2_n2, which was introduced to store link_m_n values for a DP downclock mode (if available). Suggested by Daniel. v2: Changed patch title. Daniel's review comments incorporated. Added relevant state readout code for M2_N2. dp_m2_n2 comparison to be done only when high RR is not in use (This is because alternate m_n register programming will be done only when low RR is being used). v3: Modified call to get_m2_n2 which had dp_m_n as param by mistake. Compare dp_m_n and dp_m2_n2 for gen 7 and below. compare the structures based on DRRS state for gen 8 and above. Save and restore M2 N2 registers for gen 7 and below v4: For Gen>=8, check M_N registers against dp_m_n and dp_m2_n2 as there is only one set of M_N registers v5: Removed the chunk which saves and restores M2_N2 registers. Modified get_m_n() to get M2_N2 registers as well. Modified the macro which compares hw.dp_m_n against sw.dp_m2_n2/sw.dp_m_n for gen > 8. v6: Added check to compare dp_m2_n2 only when DRRS is enabled v7: Modified drrs check to use has_drrs v8: Add has_drrs check before reading M2_N2 registers Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Jani Nikula <jani.nikula@linux.intel.com> Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-08-05 07:51:23 -07:00
DRM_DEBUG_KMS("dp: %i, lanes: %i, gmch_m2: %u, gmch_n2: %u, link_m2: %u, link_n2: %u, tu2: %u\n",
drm/i915: State readout and cross-checking for dp_m2_n2 Adding relevant read out comparison code, in check_crtc_state, for the new member of crtc_config, dp_m2_n2, which was introduced to store link_m_n values for a DP downclock mode (if available). Suggested by Daniel. v2: Changed patch title. Daniel's review comments incorporated. Added relevant state readout code for M2_N2. dp_m2_n2 comparison to be done only when high RR is not in use (This is because alternate m_n register programming will be done only when low RR is being used). v3: Modified call to get_m2_n2 which had dp_m_n as param by mistake. Compare dp_m_n and dp_m2_n2 for gen 7 and below. compare the structures based on DRRS state for gen 8 and above. Save and restore M2 N2 registers for gen 7 and below v4: For Gen>=8, check M_N registers against dp_m_n and dp_m2_n2 as there is only one set of M_N registers v5: Removed the chunk which saves and restores M2_N2 registers. Modified get_m_n() to get M2_N2 registers as well. Modified the macro which compares hw.dp_m_n against sw.dp_m2_n2/sw.dp_m_n for gen > 8. v6: Added check to compare dp_m2_n2 only when DRRS is enabled v7: Modified drrs check to use has_drrs v8: Add has_drrs check before reading M2_N2 registers Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Jani Nikula <jani.nikula@linux.intel.com> Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-08-05 07:51:23 -07:00
pipe_config->has_dp_encoder,
pipe_config->lane_count,
drm/i915: State readout and cross-checking for dp_m2_n2 Adding relevant read out comparison code, in check_crtc_state, for the new member of crtc_config, dp_m2_n2, which was introduced to store link_m_n values for a DP downclock mode (if available). Suggested by Daniel. v2: Changed patch title. Daniel's review comments incorporated. Added relevant state readout code for M2_N2. dp_m2_n2 comparison to be done only when high RR is not in use (This is because alternate m_n register programming will be done only when low RR is being used). v3: Modified call to get_m2_n2 which had dp_m_n as param by mistake. Compare dp_m_n and dp_m2_n2 for gen 7 and below. compare the structures based on DRRS state for gen 8 and above. Save and restore M2 N2 registers for gen 7 and below v4: For Gen>=8, check M_N registers against dp_m_n and dp_m2_n2 as there is only one set of M_N registers v5: Removed the chunk which saves and restores M2_N2 registers. Modified get_m_n() to get M2_N2 registers as well. Modified the macro which compares hw.dp_m_n against sw.dp_m2_n2/sw.dp_m_n for gen > 8. v6: Added check to compare dp_m2_n2 only when DRRS is enabled v7: Modified drrs check to use has_drrs v8: Add has_drrs check before reading M2_N2 registers Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Jani Nikula <jani.nikula@linux.intel.com> Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-08-05 07:51:23 -07:00
pipe_config->dp_m2_n2.gmch_m,
pipe_config->dp_m2_n2.gmch_n,
pipe_config->dp_m2_n2.link_m,
pipe_config->dp_m2_n2.link_n,
pipe_config->dp_m2_n2.tu);
DRM_DEBUG_KMS("audio: %i, infoframes: %i\n",
pipe_config->has_audio,
pipe_config->has_infoframe);
DRM_DEBUG_KMS("requested mode:\n");
drm_mode_debug_printmodeline(&pipe_config->base.mode);
DRM_DEBUG_KMS("adjusted mode:\n");
drm_mode_debug_printmodeline(&pipe_config->base.adjusted_mode);
intel_dump_crtc_timings(&pipe_config->base.adjusted_mode);
DRM_DEBUG_KMS("port clock: %d\n", pipe_config->port_clock);
DRM_DEBUG_KMS("pipe src size: %dx%d\n",
pipe_config->pipe_src_w, pipe_config->pipe_src_h);
DRM_DEBUG_KMS("num_scalers: %d, scaler_users: 0x%x, scaler_id: %d\n",
crtc->num_scalers,
pipe_config->scaler_state.scaler_users,
pipe_config->scaler_state.scaler_id);
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, %s\n",
pipe_config->pch_pfit.pos,
pipe_config->pch_pfit.size,
pipe_config->pch_pfit.enabled ? "enabled" : "disabled");
DRM_DEBUG_KMS("ips: %i\n", pipe_config->ips_enabled);
DRM_DEBUG_KMS("double wide: %i\n", pipe_config->double_wide);
if (IS_BROXTON(dev)) {
DRM_DEBUG_KMS("ddi_pll_sel: %u; dpll_hw_state: ebb0: 0x%x, ebb4: 0x%x,"
"pll0: 0x%x, pll1: 0x%x, pll2: 0x%x, pll3: 0x%x, "
"pll6: 0x%x, pll8: 0x%x, pll9: 0x%x, pll10: 0x%x, pcsdw12: 0x%x\n",
pipe_config->ddi_pll_sel,
pipe_config->dpll_hw_state.ebb0,
pipe_config->dpll_hw_state.ebb4,
pipe_config->dpll_hw_state.pll0,
pipe_config->dpll_hw_state.pll1,
pipe_config->dpll_hw_state.pll2,
pipe_config->dpll_hw_state.pll3,
pipe_config->dpll_hw_state.pll6,
pipe_config->dpll_hw_state.pll8,
pipe_config->dpll_hw_state.pll9,
pipe_config->dpll_hw_state.pll10,
pipe_config->dpll_hw_state.pcsdw12);
} else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
DRM_DEBUG_KMS("ddi_pll_sel: %u; dpll_hw_state: "
"ctrl1: 0x%x, cfgcr1: 0x%x, cfgcr2: 0x%x\n",
pipe_config->ddi_pll_sel,
pipe_config->dpll_hw_state.ctrl1,
pipe_config->dpll_hw_state.cfgcr1,
pipe_config->dpll_hw_state.cfgcr2);
} else if (HAS_DDI(dev)) {
DRM_DEBUG_KMS("ddi_pll_sel: 0x%x; dpll_hw_state: wrpll: 0x%x spll: 0x%x\n",
pipe_config->ddi_pll_sel,
pipe_config->dpll_hw_state.wrpll,
pipe_config->dpll_hw_state.spll);
} else {
DRM_DEBUG_KMS("dpll_hw_state: dpll: 0x%x, dpll_md: 0x%x, "
"fp0: 0x%x, fp1: 0x%x\n",
pipe_config->dpll_hw_state.dpll,
pipe_config->dpll_hw_state.dpll_md,
pipe_config->dpll_hw_state.fp0,
pipe_config->dpll_hw_state.fp1);
}
DRM_DEBUG_KMS("planes on this crtc\n");
list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
intel_plane = to_intel_plane(plane);
if (intel_plane->pipe != crtc->pipe)
continue;
state = to_intel_plane_state(plane->state);
fb = state->base.fb;
if (!fb) {
DRM_DEBUG_KMS("[PLANE:%d:%s] disabled, scaler_id = %d\n",
plane->base.id, plane->name, state->scaler_id);
continue;
}
DRM_DEBUG_KMS("[PLANE:%d:%s] enabled",
plane->base.id, plane->name);
DRM_DEBUG_KMS("\tFB:%d, fb = %ux%u format = %s",
fb->base.id, fb->width, fb->height,
drm_get_format_name(fb->pixel_format));
DRM_DEBUG_KMS("\tscaler:%d src %dx%d+%d+%d dst %dx%d+%d+%d\n",
state->scaler_id,
state->src.x1 >> 16, state->src.y1 >> 16,
drm_rect_width(&state->src) >> 16,
drm_rect_height(&state->src) >> 16,
state->dst.x1, state->dst.y1,
drm_rect_width(&state->dst),
drm_rect_height(&state->dst));
}
}
static bool check_digital_port_conflicts(struct drm_atomic_state *state)
drm/i915: Reject modeset when the same digital port is used more than once On pre-HSW we have two encoders per digital port: one HDMI, one DP. However they are the same physical port in hardware and we can't enable both at the same time. Reject the modeset if the user attempts this. So far we've been saved by the fact that we never see both HDMI and DP connectors as connected. But if the user decides to force a mode anyway, all kinds of funny stuff might happen. Unfortunately we don't seem to have any way to inform userspace that such configurations are invalid except by returning an error from setcrtc. possible_clones only covers real cloning situations, and looking at the connector names doesn't work either since we don't always register both connectors for the same port. I suppose the only way to fix that would be to expose only a single encoder per digital port like we do on HSW+ but that would be a fairly large undertaking for little gain. kms_setmode hits this since it forces modes on non-connected VGA and HDMI connectors. Previosuly it just resulted in weirdness such as failed link training. With this patch it will now get an error back from the kernel and will die with an assert since it thinks that the configuration should be fine. v2: Deal with INTEL_OUTPUT_UNKNOWN (Paulo) Cc: Paulo Zanoni <przanoni@gmail.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-12-02 14:10:46 +02:00
{
struct drm_device *dev = state->dev;
struct drm_connector *connector;
drm/i915: Reject modeset when the same digital port is used more than once On pre-HSW we have two encoders per digital port: one HDMI, one DP. However they are the same physical port in hardware and we can't enable both at the same time. Reject the modeset if the user attempts this. So far we've been saved by the fact that we never see both HDMI and DP connectors as connected. But if the user decides to force a mode anyway, all kinds of funny stuff might happen. Unfortunately we don't seem to have any way to inform userspace that such configurations are invalid except by returning an error from setcrtc. possible_clones only covers real cloning situations, and looking at the connector names doesn't work either since we don't always register both connectors for the same port. I suppose the only way to fix that would be to expose only a single encoder per digital port like we do on HSW+ but that would be a fairly large undertaking for little gain. kms_setmode hits this since it forces modes on non-connected VGA and HDMI connectors. Previosuly it just resulted in weirdness such as failed link training. With this patch it will now get an error back from the kernel and will die with an assert since it thinks that the configuration should be fine. v2: Deal with INTEL_OUTPUT_UNKNOWN (Paulo) Cc: Paulo Zanoni <przanoni@gmail.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-12-02 14:10:46 +02:00
unsigned int used_ports = 0;
/*
* Walk the connector list instead of the encoder
* list to detect the problem on ddi platforms
* where there's just one encoder per digital port.
*/
drm_for_each_connector(connector, dev) {
struct drm_connector_state *connector_state;
struct intel_encoder *encoder;
connector_state = drm_atomic_get_existing_connector_state(state, connector);
if (!connector_state)
connector_state = connector->state;
if (!connector_state->best_encoder)
drm/i915: Reject modeset when the same digital port is used more than once On pre-HSW we have two encoders per digital port: one HDMI, one DP. However they are the same physical port in hardware and we can't enable both at the same time. Reject the modeset if the user attempts this. So far we've been saved by the fact that we never see both HDMI and DP connectors as connected. But if the user decides to force a mode anyway, all kinds of funny stuff might happen. Unfortunately we don't seem to have any way to inform userspace that such configurations are invalid except by returning an error from setcrtc. possible_clones only covers real cloning situations, and looking at the connector names doesn't work either since we don't always register both connectors for the same port. I suppose the only way to fix that would be to expose only a single encoder per digital port like we do on HSW+ but that would be a fairly large undertaking for little gain. kms_setmode hits this since it forces modes on non-connected VGA and HDMI connectors. Previosuly it just resulted in weirdness such as failed link training. With this patch it will now get an error back from the kernel and will die with an assert since it thinks that the configuration should be fine. v2: Deal with INTEL_OUTPUT_UNKNOWN (Paulo) Cc: Paulo Zanoni <przanoni@gmail.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-12-02 14:10:46 +02:00
continue;
encoder = to_intel_encoder(connector_state->best_encoder);
WARN_ON(!connector_state->crtc);
drm/i915: Reject modeset when the same digital port is used more than once On pre-HSW we have two encoders per digital port: one HDMI, one DP. However they are the same physical port in hardware and we can't enable both at the same time. Reject the modeset if the user attempts this. So far we've been saved by the fact that we never see both HDMI and DP connectors as connected. But if the user decides to force a mode anyway, all kinds of funny stuff might happen. Unfortunately we don't seem to have any way to inform userspace that such configurations are invalid except by returning an error from setcrtc. possible_clones only covers real cloning situations, and looking at the connector names doesn't work either since we don't always register both connectors for the same port. I suppose the only way to fix that would be to expose only a single encoder per digital port like we do on HSW+ but that would be a fairly large undertaking for little gain. kms_setmode hits this since it forces modes on non-connected VGA and HDMI connectors. Previosuly it just resulted in weirdness such as failed link training. With this patch it will now get an error back from the kernel and will die with an assert since it thinks that the configuration should be fine. v2: Deal with INTEL_OUTPUT_UNKNOWN (Paulo) Cc: Paulo Zanoni <przanoni@gmail.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-12-02 14:10:46 +02:00
switch (encoder->type) {
unsigned int port_mask;
case INTEL_OUTPUT_UNKNOWN:
if (WARN_ON(!HAS_DDI(dev)))
break;
case INTEL_OUTPUT_DISPLAYPORT:
case INTEL_OUTPUT_HDMI:
case INTEL_OUTPUT_EDP:
port_mask = 1 << enc_to_dig_port(&encoder->base)->port;
/* the same port mustn't appear more than once */
if (used_ports & port_mask)
return false;
used_ports |= port_mask;
default:
break;
}
}
return true;
}
static void
clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
{
struct drm_crtc_state tmp_state;
struct intel_crtc_scaler_state scaler_state;
struct intel_dpll_hw_state dpll_hw_state;
struct intel_shared_dpll *shared_dpll;
uint32_t ddi_pll_sel;
bool force_thru;
/* FIXME: before the switch to atomic started, a new pipe_config was
* kzalloc'd. Code that depends on any field being zero should be
* fixed, so that the crtc_state can be safely duplicated. For now,
* only fields that are know to not cause problems are preserved. */
tmp_state = crtc_state->base;
scaler_state = crtc_state->scaler_state;
shared_dpll = crtc_state->shared_dpll;
dpll_hw_state = crtc_state->dpll_hw_state;
ddi_pll_sel = crtc_state->ddi_pll_sel;
force_thru = crtc_state->pch_pfit.force_thru;
memset(crtc_state, 0, sizeof *crtc_state);
crtc_state->base = tmp_state;
crtc_state->scaler_state = scaler_state;
crtc_state->shared_dpll = shared_dpll;
crtc_state->dpll_hw_state = dpll_hw_state;
crtc_state->ddi_pll_sel = ddi_pll_sel;
crtc_state->pch_pfit.force_thru = force_thru;
}
static int
intel_modeset_pipe_config(struct drm_crtc *crtc,
struct intel_crtc_state *pipe_config)
{
struct drm_atomic_state *state = pipe_config->base.state;
struct intel_encoder *encoder;
struct drm_connector *connector;
struct drm_connector_state *connector_state;
int base_bpp, ret = -EINVAL;
int i;
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 <imre.deak@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-02-21 00:00:16 +01:00
bool retry = true;
clear_intel_crtc_state(pipe_config);
pipe_config->cpu_transcoder =
(enum transcoder) to_intel_crtc(crtc)->pipe;
/*
* 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->base.adjusted_mode.flags &
(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC)))
pipe_config->base.adjusted_mode.flags |= DRM_MODE_FLAG_NHSYNC;
if (!(pipe_config->base.adjusted_mode.flags &
(DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC)))
pipe_config->base.adjusted_mode.flags |= DRM_MODE_FLAG_NVSYNC;
base_bpp = compute_baseline_pipe_bpp(to_intel_crtc(crtc),
pipe_config);
if (base_bpp < 0)
drm/i915: precompute pipe bpp before touching the hw The procedure has now 3 steps: 1. Compute the bpp that the plane will output, this is done in pipe_config_set_bpp and stored into pipe_config->pipe_bpp. Also, this function clamps the pipe_bpp to whatever limit the EDID of any connected output specifies. 2. Adjust the pipe_bpp in the encoder and crtc functions, according to whatever constraints there are. 3. Decide whether to use dither by comparing the stored plane bpp with computed pipe_bpp. There are a few slight functional changes in this patch: - LVDS connector are now also going through the EDID clamping. But in a 2nd change we now unconditionally force the lvds bpc value - this shouldn't matter in reality when the panel setup is consistent, but better safe than sorry. - HDMI now forces the pipe_bpp to the selected value - I think that's what we actually want, since otherwise at least the pixelclock computations are wrong (I'm not sure whether the port would accept e.g. 10 bpc when in 12bpc mode). Contrary to the old code, we pick the next higher bpc value, since otherwise there's no way to make use of the 12 bpc mode (since the next patch will remove the 12bpc plane format, it doesn't exist). Both of these changes are due to the removal of the pipe_bpp = min(display_bpp, plane_bpp); statement. Another slight change is the reworking of the dp bpc code: - For the mode_valid callback it's sufficient to only check whether the mode would fit at the lowest bpc. - The bandwidth computation code is a bit restructured: It now walks all available bpp values in an outer loop and the codeblock that computes derived values (once a good configuration is found) has been moved out of the for loop maze. This is prep work to allow us to successively fall back on bpc values, and also correctly support bpc values != 8 or 6. v2: Rebased on top of Paulo Zanoni's little refactoring to use more drm dp helper functions. v3: Rebased on top of Jani's eDP bpp fix and Ville's limited color range work. v4: Remove the INTEL_MODE_DP_FORCE_6BPC #define, no longer needed. v5: Remove intel_crtc->bpp, too, and fix up the 12bpc check in the hdmi code. Also fixup the bpp check in intel_dp.c, it'll get reworked in a later patch though again. v6: Fix spelling in a comment. v7: Debug output improvements for the bpp computation. v8: Fixup 6bpc lvds check - dual-link and 8bpc mode are different things! v9: Reinstate the fix to properly ignore the firmware edp bpp ... this was lost in a rebase. v10: Both g4x and vlv lack 12bpc pipes, so don't enforce that we have that. Still unsure whether this is the way to go, but at least 6bpc for a 8bpc hdmi output seems to work. v11: And g4x/vlv also lack 12bpc hdmi support, so only support high depth on DP. Adjust the code. v12: Rebased. v13: Split out the introduction of pipe_config->dither|pipe_bpp, as requested from Jesse Barnes. v14: Split out the special 6BPC handling for DP, as requested by Jesse Barnes. Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-03-27 00:44:58 +01:00
goto fail;
/*
* Determine the real pipe dimensions. Note that stereo modes can
* increase the actual pipe size due to the frame doubling and
* insertion of additional space for blanks between the frame. This
* is stored in the crtc timings. We use the requested mode to do this
* computation to clearly distinguish it from the adjusted mode, which
* can be changed by the connectors in the below retry loop.
*/
drm_crtc_get_hv_timing(&pipe_config->base.mode,
&pipe_config->pipe_src_w,
&pipe_config->pipe_src_h);
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 <imre.deak@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-02-21 00:00:16 +01:00
encoder_retry:
/* Ensure the port clock defaults are reset when retrying. */
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 <jbarnes@virtuousgeek.org> (v3) Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> (v6) Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-06-01 17:16:21 +02:00
pipe_config->port_clock = 0;
pipe_config->pixel_multiplier = 1;
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 <jbarnes@virtuousgeek.org> (v3) Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> (v6) Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-06-01 17:16:21 +02:00
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 <daniel.vetter@ffwll.ch> 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 <jbarnes@virtuousgeek.org> Cc: Mika Kuoppala <mika.kuoppala@intel.com> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@gmail.com> [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 <daniel.vetter@ffwll.ch>
2013-07-21 21:37:09 +02:00
/* Fill in default crtc timings, allow encoders to overwrite them. */
drm_mode_set_crtcinfo(&pipe_config->base.adjusted_mode,
CRTC_STEREO_DOUBLE);
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 <daniel.vetter@ffwll.ch> 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 <jbarnes@virtuousgeek.org> Cc: Mika Kuoppala <mika.kuoppala@intel.com> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@gmail.com> [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 <daniel.vetter@ffwll.ch>
2013-07-21 21:37:09 +02:00
/* 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.
*/
for_each_connector_in_state(state, connector, connector_state, i) {
if (connector_state->crtc != crtc)
continue;
encoder = to_intel_encoder(connector_state->best_encoder);
if (!(encoder->compute_config(encoder, pipe_config))) {
DRM_DEBUG_KMS("Encoder config failure\n");
goto fail;
}
}
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 <jbarnes@virtuousgeek.org> (v3) Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> (v6) Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-06-01 17:16:21 +02:00
/* 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->base.adjusted_mode.crtc_clock
* pipe_config->pixel_multiplier;
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 <jbarnes@virtuousgeek.org> (v3) Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> (v6) Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-06-01 17:16:21 +02:00
ret = intel_crtc_compute_config(to_intel_crtc(crtc), pipe_config);
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 <imre.deak@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-02-21 00:00:16 +01:00
if (ret < 0) {
DRM_DEBUG_KMS("CRTC fixup failed\n");
goto fail;
}
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 <imre.deak@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-02-21 00:00:16 +01:00
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;
}
/* Dithering seems to not pass-through bits correctly when it should, so
* only enable it on 6bpc panels. */
pipe_config->dither = pipe_config->pipe_bpp == 6*3;
DRM_DEBUG_KMS("hw max bpp: %i, pipe bpp: %i, dithering: %i\n",
base_bpp, pipe_config->pipe_bpp, pipe_config->dither);
drm/i915: precompute pipe bpp before touching the hw The procedure has now 3 steps: 1. Compute the bpp that the plane will output, this is done in pipe_config_set_bpp and stored into pipe_config->pipe_bpp. Also, this function clamps the pipe_bpp to whatever limit the EDID of any connected output specifies. 2. Adjust the pipe_bpp in the encoder and crtc functions, according to whatever constraints there are. 3. Decide whether to use dither by comparing the stored plane bpp with computed pipe_bpp. There are a few slight functional changes in this patch: - LVDS connector are now also going through the EDID clamping. But in a 2nd change we now unconditionally force the lvds bpc value - this shouldn't matter in reality when the panel setup is consistent, but better safe than sorry. - HDMI now forces the pipe_bpp to the selected value - I think that's what we actually want, since otherwise at least the pixelclock computations are wrong (I'm not sure whether the port would accept e.g. 10 bpc when in 12bpc mode). Contrary to the old code, we pick the next higher bpc value, since otherwise there's no way to make use of the 12 bpc mode (since the next patch will remove the 12bpc plane format, it doesn't exist). Both of these changes are due to the removal of the pipe_bpp = min(display_bpp, plane_bpp); statement. Another slight change is the reworking of the dp bpc code: - For the mode_valid callback it's sufficient to only check whether the mode would fit at the lowest bpc. - The bandwidth computation code is a bit restructured: It now walks all available bpp values in an outer loop and the codeblock that computes derived values (once a good configuration is found) has been moved out of the for loop maze. This is prep work to allow us to successively fall back on bpc values, and also correctly support bpc values != 8 or 6. v2: Rebased on top of Paulo Zanoni's little refactoring to use more drm dp helper functions. v3: Rebased on top of Jani's eDP bpp fix and Ville's limited color range work. v4: Remove the INTEL_MODE_DP_FORCE_6BPC #define, no longer needed. v5: Remove intel_crtc->bpp, too, and fix up the 12bpc check in the hdmi code. Also fixup the bpp check in intel_dp.c, it'll get reworked in a later patch though again. v6: Fix spelling in a comment. v7: Debug output improvements for the bpp computation. v8: Fixup 6bpc lvds check - dual-link and 8bpc mode are different things! v9: Reinstate the fix to properly ignore the firmware edp bpp ... this was lost in a rebase. v10: Both g4x and vlv lack 12bpc pipes, so don't enforce that we have that. Still unsure whether this is the way to go, but at least 6bpc for a 8bpc hdmi output seems to work. v11: And g4x/vlv also lack 12bpc hdmi support, so only support high depth on DP. Adjust the code. v12: Rebased. v13: Split out the introduction of pipe_config->dither|pipe_bpp, as requested from Jesse Barnes. v14: Split out the special 6BPC handling for DP, as requested by Jesse Barnes. Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-03-27 00:44:58 +01:00
fail:
return ret;
}
drm/i915: push commit_output_state past the crtc/encoder preparing With this change we can (finally!) rip out a few of the temporary hacks and clean up a few other things: - Kill intel_crtc_prepare_encoders, now unused. - Kill the hacks in the crtc_disable/enable functions to always call the encoder callbacks, we now always call the crtc functions with the right encoder -> crtc links. - Also push down the crtc->enable, encoder and connector dpms state updates. Unfortunately we can't add a WARN in the crtc_disable callbacks to ensure that the crtc is always still enabled when disabling an output pipe - the crtc sanitizer of the hw readout path can hit this when it needs to disable an active pipe without any enabled outputs. - Only call crtc->disable if the pipe is already enabled - again avoids running afoul of the new WARN. v2: Copy&paste our own version of crtc_in_use, too. v3: We need to update the dpms an encoder->connectors_active states, too. v4: I've forgotten to kill the unconditional encoder->disable calls in the crtc_disable functions. v5: Rip out leftover debug printk. v6: Properly clear intel_encoder->connectors_active. This wasn't properly cleared when disabling an encoder because it was no longer on the new connector list, but the crtc was still enabled (i.e. switching the encoder of an active crtc). Reported by Jani Nikula. v7: Don't clobber the encoder->connectors_active state of untouched encoders. Since X likes to first disable all outputs with dpms off before setting a new framebuffer, this hit a few warnings. Reported by Paulo Zanoni. v8: Kill the now stale comment warning that intel_crtc->active is not always updated at the right times. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-10 10:42:52 +02:00
static void
intel_modeset_update_crtc_state(struct drm_atomic_state *state)
drm/i915: push commit_output_state past the crtc/encoder preparing With this change we can (finally!) rip out a few of the temporary hacks and clean up a few other things: - Kill intel_crtc_prepare_encoders, now unused. - Kill the hacks in the crtc_disable/enable functions to always call the encoder callbacks, we now always call the crtc functions with the right encoder -> crtc links. - Also push down the crtc->enable, encoder and connector dpms state updates. Unfortunately we can't add a WARN in the crtc_disable callbacks to ensure that the crtc is always still enabled when disabling an output pipe - the crtc sanitizer of the hw readout path can hit this when it needs to disable an active pipe without any enabled outputs. - Only call crtc->disable if the pipe is already enabled - again avoids running afoul of the new WARN. v2: Copy&paste our own version of crtc_in_use, too. v3: We need to update the dpms an encoder->connectors_active states, too. v4: I've forgotten to kill the unconditional encoder->disable calls in the crtc_disable functions. v5: Rip out leftover debug printk. v6: Properly clear intel_encoder->connectors_active. This wasn't properly cleared when disabling an encoder because it was no longer on the new connector list, but the crtc was still enabled (i.e. switching the encoder of an active crtc). Reported by Jani Nikula. v7: Don't clobber the encoder->connectors_active state of untouched encoders. Since X likes to first disable all outputs with dpms off before setting a new framebuffer, this hit a few warnings. Reported by Paulo Zanoni. v8: Kill the now stale comment warning that intel_crtc->active is not always updated at the right times. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-10 10:42:52 +02:00
{
struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state;
int i;
drm/i915: push commit_output_state past the crtc/encoder preparing With this change we can (finally!) rip out a few of the temporary hacks and clean up a few other things: - Kill intel_crtc_prepare_encoders, now unused. - Kill the hacks in the crtc_disable/enable functions to always call the encoder callbacks, we now always call the crtc functions with the right encoder -> crtc links. - Also push down the crtc->enable, encoder and connector dpms state updates. Unfortunately we can't add a WARN in the crtc_disable callbacks to ensure that the crtc is always still enabled when disabling an output pipe - the crtc sanitizer of the hw readout path can hit this when it needs to disable an active pipe without any enabled outputs. - Only call crtc->disable if the pipe is already enabled - again avoids running afoul of the new WARN. v2: Copy&paste our own version of crtc_in_use, too. v3: We need to update the dpms an encoder->connectors_active states, too. v4: I've forgotten to kill the unconditional encoder->disable calls in the crtc_disable functions. v5: Rip out leftover debug printk. v6: Properly clear intel_encoder->connectors_active. This wasn't properly cleared when disabling an encoder because it was no longer on the new connector list, but the crtc was still enabled (i.e. switching the encoder of an active crtc). Reported by Jani Nikula. v7: Don't clobber the encoder->connectors_active state of untouched encoders. Since X likes to first disable all outputs with dpms off before setting a new framebuffer, this hit a few warnings. Reported by Paulo Zanoni. v8: Kill the now stale comment warning that intel_crtc->active is not always updated at the right times. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-10 10:42:52 +02:00
/* Double check state. */
for_each_crtc_in_state(state, crtc, crtc_state, i) {
to_intel_crtc(crtc)->config = to_intel_crtc_state(crtc->state);
/* Update hwmode for vblank functions */
if (crtc->state->active)
crtc->hwmode = crtc->state->adjusted_mode;
else
crtc->hwmode.crtc_clock = 0;
/*
* Update legacy state to satisfy fbc code. This can
* be removed when fbc uses the atomic state.
*/
if (drm_atomic_get_existing_plane_state(state, crtc->primary)) {
struct drm_plane_state *plane_state = crtc->primary->state;
crtc->primary->fb = plane_state->fb;
crtc->x = plane_state->src_x >> 16;
crtc->y = plane_state->src_y >> 16;
}
drm/i915: push commit_output_state past the crtc/encoder preparing With this change we can (finally!) rip out a few of the temporary hacks and clean up a few other things: - Kill intel_crtc_prepare_encoders, now unused. - Kill the hacks in the crtc_disable/enable functions to always call the encoder callbacks, we now always call the crtc functions with the right encoder -> crtc links. - Also push down the crtc->enable, encoder and connector dpms state updates. Unfortunately we can't add a WARN in the crtc_disable callbacks to ensure that the crtc is always still enabled when disabling an output pipe - the crtc sanitizer of the hw readout path can hit this when it needs to disable an active pipe without any enabled outputs. - Only call crtc->disable if the pipe is already enabled - again avoids running afoul of the new WARN. v2: Copy&paste our own version of crtc_in_use, too. v3: We need to update the dpms an encoder->connectors_active states, too. v4: I've forgotten to kill the unconditional encoder->disable calls in the crtc_disable functions. v5: Rip out leftover debug printk. v6: Properly clear intel_encoder->connectors_active. This wasn't properly cleared when disabling an encoder because it was no longer on the new connector list, but the crtc was still enabled (i.e. switching the encoder of an active crtc). Reported by Jani Nikula. v7: Don't clobber the encoder->connectors_active state of untouched encoders. Since X likes to first disable all outputs with dpms off before setting a new framebuffer, this hit a few warnings. Reported by Paulo Zanoni. v8: Kill the now stale comment warning that intel_crtc->active is not always updated at the right times. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-10 10:42:52 +02:00
}
}
static bool intel_fuzzy_clock_check(int clock1, int clock2)
{
int diff;
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, \
base.head) \
for_each_if (mask & (1 <<(intel_crtc)->pipe))
static bool
intel_compare_m_n(unsigned int m, unsigned int n,
unsigned int m2, unsigned int n2,
bool exact)
{
if (m == m2 && n == n2)
return true;
if (exact || !m || !n || !m2 || !n2)
return false;
BUILD_BUG_ON(DATA_LINK_M_N_MASK > INT_MAX);
if (n > n2) {
while (n > n2) {
m2 <<= 1;
n2 <<= 1;
}
} else if (n < n2) {
while (n < n2) {
m <<= 1;
n <<= 1;
}
}
if (n != n2)
return false;
return intel_fuzzy_clock_check(m, m2);
}
static bool
intel_compare_link_m_n(const struct intel_link_m_n *m_n,
struct intel_link_m_n *m2_n2,
bool adjust)
{
if (m_n->tu == m2_n2->tu &&
intel_compare_m_n(m_n->gmch_m, m_n->gmch_n,
m2_n2->gmch_m, m2_n2->gmch_n, !adjust) &&
intel_compare_m_n(m_n->link_m, m_n->link_n,
m2_n2->link_m, m2_n2->link_n, !adjust)) {
if (adjust)
*m2_n2 = *m_n;
return true;
}
return false;
}
static bool
intel_pipe_config_compare(struct drm_device *dev,
struct intel_crtc_state *current_config,
struct intel_crtc_state *pipe_config,
bool adjust)
{
bool ret = true;
#define INTEL_ERR_OR_DBG_KMS(fmt, ...) \
do { \
if (!adjust) \
DRM_ERROR(fmt, ##__VA_ARGS__); \
else \
DRM_DEBUG_KMS(fmt, ##__VA_ARGS__); \
} while (0)
#define PIPE_CONF_CHECK_X(name) \
if (current_config->name != pipe_config->name) { \
INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
"(expected 0x%08x, found 0x%08x)\n", \
current_config->name, \
pipe_config->name); \
ret = false; \
}
#define PIPE_CONF_CHECK_I(name) \
if (current_config->name != pipe_config->name) { \
INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
"(expected %i, found %i)\n", \
current_config->name, \
pipe_config->name); \
ret = false; \
}
#define PIPE_CONF_CHECK_P(name) \
if (current_config->name != pipe_config->name) { \
INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
"(expected %p, found %p)\n", \
current_config->name, \
pipe_config->name); \
ret = false; \
}
#define PIPE_CONF_CHECK_M_N(name) \
if (!intel_compare_link_m_n(&current_config->name, \
&pipe_config->name,\
adjust)) { \
INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
"(expected tu %i gmch %i/%i link %i/%i, " \
"found tu %i, gmch %i/%i link %i/%i)\n", \
current_config->name.tu, \
current_config->name.gmch_m, \
current_config->name.gmch_n, \
current_config->name.link_m, \
current_config->name.link_n, \
pipe_config->name.tu, \
pipe_config->name.gmch_m, \
pipe_config->name.gmch_n, \
pipe_config->name.link_m, \
pipe_config->name.link_n); \
ret = false; \
}
/* This is required for BDW+ where there is only one set of registers for
* switching between high and low RR.
* This macro can be used whenever a comparison has to be made between one
* hw state and multiple sw state variables.
*/
#define PIPE_CONF_CHECK_M_N_ALT(name, alt_name) \
if (!intel_compare_link_m_n(&current_config->name, \
&pipe_config->name, adjust) && \
!intel_compare_link_m_n(&current_config->alt_name, \
&pipe_config->name, adjust)) { \
INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
"(expected tu %i gmch %i/%i link %i/%i, " \
"or tu %i gmch %i/%i link %i/%i, " \
"found tu %i, gmch %i/%i link %i/%i)\n", \
current_config->name.tu, \
current_config->name.gmch_m, \
current_config->name.gmch_n, \
current_config->name.link_m, \
current_config->name.link_n, \
current_config->alt_name.tu, \
current_config->alt_name.gmch_m, \
current_config->alt_name.gmch_n, \
current_config->alt_name.link_m, \
current_config->alt_name.link_n, \
pipe_config->name.tu, \
pipe_config->name.gmch_m, \
pipe_config->name.gmch_n, \
pipe_config->name.link_m, \
pipe_config->name.link_n); \
ret = false; \
}
#define PIPE_CONF_CHECK_FLAGS(name, mask) \
if ((current_config->name ^ pipe_config->name) & (mask)) { \
INTEL_ERR_OR_DBG_KMS("mismatch in " #name "(" #mask ") " \
"(expected %i, found %i)\n", \
current_config->name & (mask), \
pipe_config->name & (mask)); \
ret = false; \
}
#define PIPE_CONF_CHECK_CLOCK_FUZZY(name) \
if (!intel_fuzzy_clock_check(current_config->name, pipe_config->name)) { \
INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
"(expected %i, found %i)\n", \
current_config->name, \
pipe_config->name); \
ret = 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);
PIPE_CONF_CHECK_I(fdi_lanes);
PIPE_CONF_CHECK_M_N(fdi_m_n);
PIPE_CONF_CHECK_I(has_dp_encoder);
PIPE_CONF_CHECK_I(lane_count);
PIPE_CONF_CHECK_X(lane_lat_optim_mask);
drm/i915: State readout and cross-checking for dp_m2_n2 Adding relevant read out comparison code, in check_crtc_state, for the new member of crtc_config, dp_m2_n2, which was introduced to store link_m_n values for a DP downclock mode (if available). Suggested by Daniel. v2: Changed patch title. Daniel's review comments incorporated. Added relevant state readout code for M2_N2. dp_m2_n2 comparison to be done only when high RR is not in use (This is because alternate m_n register programming will be done only when low RR is being used). v3: Modified call to get_m2_n2 which had dp_m_n as param by mistake. Compare dp_m_n and dp_m2_n2 for gen 7 and below. compare the structures based on DRRS state for gen 8 and above. Save and restore M2 N2 registers for gen 7 and below v4: For Gen>=8, check M_N registers against dp_m_n and dp_m2_n2 as there is only one set of M_N registers v5: Removed the chunk which saves and restores M2_N2 registers. Modified get_m_n() to get M2_N2 registers as well. Modified the macro which compares hw.dp_m_n against sw.dp_m2_n2/sw.dp_m_n for gen > 8. v6: Added check to compare dp_m2_n2 only when DRRS is enabled v7: Modified drrs check to use has_drrs v8: Add has_drrs check before reading M2_N2 registers Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Jani Nikula <jani.nikula@linux.intel.com> Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-08-05 07:51:23 -07:00
if (INTEL_INFO(dev)->gen < 8) {
PIPE_CONF_CHECK_M_N(dp_m_n);
if (current_config->has_drrs)
PIPE_CONF_CHECK_M_N(dp_m2_n2);
} else
PIPE_CONF_CHECK_M_N_ALT(dp_m_n, dp_m2_n2);
PIPE_CONF_CHECK_I(has_dsi_encoder);
PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hdisplay);
PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_htotal);
PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hblank_start);
PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hblank_end);
PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hsync_start);
PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hsync_end);
PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vdisplay);
PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vtotal);
PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vblank_start);
PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vblank_end);
PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vsync_start);
PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vsync_end);
PIPE_CONF_CHECK_I(pixel_multiplier);
PIPE_CONF_CHECK_I(has_hdmi_sink);
if ((INTEL_INFO(dev)->gen < 8 && !IS_HASWELL(dev)) ||
IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
PIPE_CONF_CHECK_I(limited_color_range);
PIPE_CONF_CHECK_I(has_infoframe);
PIPE_CONF_CHECK_I(has_audio);
PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
DRM_MODE_FLAG_INTERLACE);
if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS)) {
PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
DRM_MODE_FLAG_PHSYNC);
PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
DRM_MODE_FLAG_NHSYNC);
PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
DRM_MODE_FLAG_PVSYNC);
PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
DRM_MODE_FLAG_NVSYNC);
}
PIPE_CONF_CHECK_X(gmch_pfit.control);
/* pfit ratios are autocomputed by the hw on gen4+ */
if (INTEL_INFO(dev)->gen < 4)
PIPE_CONF_CHECK_X(gmch_pfit.pgm_ratios);
PIPE_CONF_CHECK_X(gmch_pfit.lvds_border_bits);
if (!adjust) {
PIPE_CONF_CHECK_I(pipe_src_w);
PIPE_CONF_CHECK_I(pipe_src_h);
PIPE_CONF_CHECK_I(pch_pfit.enabled);
if (current_config->pch_pfit.enabled) {
PIPE_CONF_CHECK_X(pch_pfit.pos);
PIPE_CONF_CHECK_X(pch_pfit.size);
}
PIPE_CONF_CHECK_I(scaler_state.scaler_id);
}
/* BDW+ don't expose a synchronous way to read the state */
if (IS_HASWELL(dev))
PIPE_CONF_CHECK_I(ips_enabled);
PIPE_CONF_CHECK_I(double_wide);
PIPE_CONF_CHECK_X(ddi_pll_sel);
PIPE_CONF_CHECK_P(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);
PIPE_CONF_CHECK_X(dpll_hw_state.wrpll);
PIPE_CONF_CHECK_X(dpll_hw_state.spll);
PIPE_CONF_CHECK_X(dpll_hw_state.ctrl1);
PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr1);
PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr2);
drm/i915: hw state readout for shared pch plls 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ä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-06-07 23:11:08 +02:00
PIPE_CONF_CHECK_X(dsi_pll.ctrl);
PIPE_CONF_CHECK_X(dsi_pll.div);
if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5)
PIPE_CONF_CHECK_I(pipe_bpp);
PIPE_CONF_CHECK_CLOCK_FUZZY(base.adjusted_mode.crtc_clock);
PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);
#undef PIPE_CONF_CHECK_X
#undef PIPE_CONF_CHECK_I
#undef PIPE_CONF_CHECK_P
#undef PIPE_CONF_CHECK_FLAGS
#undef PIPE_CONF_CHECK_CLOCK_FUZZY
#undef PIPE_CONF_QUIRK
#undef INTEL_ERR_OR_DBG_KMS
return ret;
}
static void intel_pipe_config_sanity_check(struct drm_i915_private *dev_priv,
const struct intel_crtc_state *pipe_config)
{
if (pipe_config->has_pch_encoder) {
int fdi_dotclock = intel_dotclock_calculate(intel_fdi_link_freq(dev_priv, pipe_config),
&pipe_config->fdi_m_n);
int dotclock = pipe_config->base.adjusted_mode.crtc_clock;
/*
* FDI already provided one idea for the dotclock.
* Yell if the encoder disagrees.
*/
WARN(!intel_fuzzy_clock_check(fdi_dotclock, dotclock),
"FDI dotclock and encoder dotclock mismatch, fdi: %i, encoder: %i\n",
fdi_dotclock, dotclock);
}
}
static void verify_wm_state(struct drm_crtc *crtc,
struct drm_crtc_state *new_state)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct skl_ddb_allocation hw_ddb, *sw_ddb;
struct skl_ddb_entry *hw_entry, *sw_entry;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
const enum pipe pipe = intel_crtc->pipe;
int plane;
if (INTEL_INFO(dev)->gen < 9 || !new_state->active)
return;
skl_ddb_get_hw_state(dev_priv, &hw_ddb);
sw_ddb = &dev_priv->wm.skl_hw.ddb;
/* planes */
for_each_plane(dev_priv, pipe, plane) {
hw_entry = &hw_ddb.plane[pipe][plane];
sw_entry = &sw_ddb->plane[pipe][plane];
if (skl_ddb_entry_equal(hw_entry, sw_entry))
continue;
DRM_ERROR("mismatch in DDB state pipe %c plane %d "
"(expected (%u,%u), found (%u,%u))\n",
pipe_name(pipe), plane + 1,
sw_entry->start, sw_entry->end,
hw_entry->start, hw_entry->end);
}
/* cursor */
hw_entry = &hw_ddb.plane[pipe][PLANE_CURSOR];
sw_entry = &sw_ddb->plane[pipe][PLANE_CURSOR];
if (!skl_ddb_entry_equal(hw_entry, sw_entry)) {
DRM_ERROR("mismatch in DDB state pipe %c cursor "
"(expected (%u,%u), found (%u,%u))\n",
pipe_name(pipe),
sw_entry->start, sw_entry->end,
hw_entry->start, hw_entry->end);
}
}
static void
verify_connector_state(struct drm_device *dev, struct drm_crtc *crtc)
{
struct drm_connector *connector;
drm_for_each_connector(connector, dev) {
struct drm_encoder *encoder = connector->encoder;
struct drm_connector_state *state = connector->state;
if (state->crtc != crtc)
continue;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
intel_connector_verify_state(to_intel_connector(connector));
I915_STATE_WARN(state->best_encoder != encoder,
"connector's atomic encoder doesn't match legacy encoder\n");
}
}
static void
verify_encoder_state(struct drm_device *dev)
{
struct intel_encoder *encoder;
struct intel_connector *connector;
for_each_intel_encoder(dev, encoder) {
bool enabled = false;
enum pipe pipe;
DRM_DEBUG_KMS("[ENCODER:%d:%s]\n",
encoder->base.base.id,
encoder->base.name);
for_each_intel_connector(dev, connector) {
if (connector->base.state->best_encoder != &encoder->base)
continue;
enabled = true;
I915_STATE_WARN(connector->base.state->crtc !=
encoder->base.crtc,
"connector's crtc doesn't match encoder crtc\n");
}
2014-05-02 14:02:48 +10:00
I915_STATE_WARN(!!encoder->base.crtc != enabled,
"encoder's enabled state mismatch "
"(expected %i, found %i)\n",
!!encoder->base.crtc, enabled);
if (!encoder->base.crtc) {
bool active;
active = encoder->get_hw_state(encoder, &pipe);
I915_STATE_WARN(active,
"encoder detached but still enabled on pipe %c.\n",
pipe_name(pipe));
}
}
}
static void
verify_crtc_state(struct drm_crtc *crtc,
struct drm_crtc_state *old_crtc_state,
struct drm_crtc_state *new_crtc_state)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_encoder *encoder;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_crtc_state *pipe_config, *sw_config;
struct drm_atomic_state *old_state;
bool active;
old_state = old_crtc_state->state;
__drm_atomic_helper_crtc_destroy_state(old_crtc_state);
pipe_config = to_intel_crtc_state(old_crtc_state);
memset(pipe_config, 0, sizeof(*pipe_config));
pipe_config->base.crtc = crtc;
pipe_config->base.state = old_state;
DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
active = dev_priv->display.get_pipe_config(intel_crtc, pipe_config);
drm/i915: Quirk the pipe A quirk in the modeset state checker If we always force the pipe A to on we can't use the hw state to decide whether it should be on. Hence quirk the quirk. The problem is that crtc->active tracks the state of the entire display pipe, i.e. including planes, encoders and all. But our hw state readout simply looks at the pipe. But with the pipe A quirk we force-enable that (together with it's pll). To fix that mismatch we have two options: - Quirk the checked state to match what our sw tracking states if the pipe A quirk is in effect. - Improve the hw state readout to not get fooled by the pipe A quirk. Since we already have similar state clamping in e.g. assert_pipe I've opted for the first variant. Also note that we don't really loose any state checking: Individual pieces of the abstract crtc pipe are checked in the enable/disable functions with the various asssert_* checks we have, and the hw state check code doesn't check anything if the pipe is off anyway. v2: Pimp commit message after discussion with Chris and only apply the quirk for the quirk if we're checking pipe A. Otherwise we'll miss state checking for pipe B on i830M ... v3: Make the code comment consistent with the improved commit message, too (Chris). Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=64764 Cc: stable@vger.kernel.org Cc: Chris Wilson <chris@chris-wilson.co.uk> Reported-and-Tested-by: mlsemon35@gmail.com (v1) Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-05-29 10:41:29 +02:00
/* hw state is inconsistent with the pipe quirk */
if ((intel_crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
(intel_crtc->pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
active = new_crtc_state->active;
I915_STATE_WARN(new_crtc_state->active != active,
"crtc active state doesn't match with hw state "
"(expected %i, found %i)\n", new_crtc_state->active, active);
I915_STATE_WARN(intel_crtc->active != new_crtc_state->active,
"transitional active state does not match atomic hw state "
"(expected %i, found %i)\n", new_crtc_state->active, intel_crtc->active);
for_each_encoder_on_crtc(dev, crtc, encoder) {
enum pipe pipe;
active = encoder->get_hw_state(encoder, &pipe);
I915_STATE_WARN(active != new_crtc_state->active,
"[ENCODER:%i] active %i with crtc active %i\n",
encoder->base.base.id, active, new_crtc_state->active);
I915_STATE_WARN(active && intel_crtc->pipe != pipe,
"Encoder connected to wrong pipe %c\n",
pipe_name(pipe));
if (active)
encoder->get_config(encoder, pipe_config);
}
if (!new_crtc_state->active)
return;
intel_pipe_config_sanity_check(dev_priv, pipe_config);
sw_config = to_intel_crtc_state(crtc->state);
if (!intel_pipe_config_compare(dev, sw_config,
pipe_config, false)) {
I915_STATE_WARN(1, "pipe state doesn't match!\n");
intel_dump_pipe_config(intel_crtc, pipe_config,
"[hw state]");
intel_dump_pipe_config(intel_crtc, sw_config,
"[sw state]");
}
}
static void
verify_single_dpll_state(struct drm_i915_private *dev_priv,
struct intel_shared_dpll *pll,
struct drm_crtc *crtc,
struct drm_crtc_state *new_state)
{
struct intel_dpll_hw_state dpll_hw_state;
unsigned crtc_mask;
bool active;
memset(&dpll_hw_state, 0, sizeof(dpll_hw_state));
DRM_DEBUG_KMS("%s\n", pll->name);
active = pll->funcs.get_hw_state(dev_priv, pll, &dpll_hw_state);
if (!(pll->flags & INTEL_DPLL_ALWAYS_ON)) {
I915_STATE_WARN(!pll->on && pll->active_mask,
"pll in active use but not on in sw tracking\n");
I915_STATE_WARN(pll->on && !pll->active_mask,
"pll is on but not used by any active crtc\n");
I915_STATE_WARN(pll->on != active,
"pll on state mismatch (expected %i, found %i)\n",
pll->on, active);
}
if (!crtc) {
I915_STATE_WARN(pll->active_mask & ~pll->config.crtc_mask,
"more active pll users than references: %x vs %x\n",
pll->active_mask, pll->config.crtc_mask);
return;
}
crtc_mask = 1 << drm_crtc_index(crtc);
if (new_state->active)
I915_STATE_WARN(!(pll->active_mask & crtc_mask),
"pll active mismatch (expected pipe %c in active mask 0x%02x)\n",
pipe_name(drm_crtc_index(crtc)), pll->active_mask);
else
I915_STATE_WARN(pll->active_mask & crtc_mask,
"pll active mismatch (didn't expect pipe %c in active mask 0x%02x)\n",
pipe_name(drm_crtc_index(crtc)), pll->active_mask);
I915_STATE_WARN(!(pll->config.crtc_mask & crtc_mask),
"pll enabled crtcs mismatch (expected 0x%x in 0x%02x)\n",
crtc_mask, pll->config.crtc_mask);
I915_STATE_WARN(pll->on && memcmp(&pll->config.hw_state,
&dpll_hw_state,
sizeof(dpll_hw_state)),
"pll hw state mismatch\n");
}
static void
verify_shared_dpll_state(struct drm_device *dev, struct drm_crtc *crtc,
struct drm_crtc_state *old_crtc_state,
struct drm_crtc_state *new_crtc_state)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc_state *old_state = to_intel_crtc_state(old_crtc_state);
struct intel_crtc_state *new_state = to_intel_crtc_state(new_crtc_state);
if (new_state->shared_dpll)
verify_single_dpll_state(dev_priv, new_state->shared_dpll, crtc, new_crtc_state);
if (old_state->shared_dpll &&
old_state->shared_dpll != new_state->shared_dpll) {
unsigned crtc_mask = 1 << drm_crtc_index(crtc);
struct intel_shared_dpll *pll = old_state->shared_dpll;
I915_STATE_WARN(pll->active_mask & crtc_mask,
"pll active mismatch (didn't expect pipe %c in active mask)\n",
pipe_name(drm_crtc_index(crtc)));
I915_STATE_WARN(pll->config.crtc_mask & crtc_mask,
"pll enabled crtcs mismatch (found %x in enabled mask)\n",
pipe_name(drm_crtc_index(crtc)));
}
}
static void
intel_modeset_verify_crtc(struct drm_crtc *crtc,
struct drm_crtc_state *old_state,
struct drm_crtc_state *new_state)
{
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
if (!needs_modeset(new_state) &&
!to_intel_crtc_state(new_state)->update_pipe)
return;
verify_wm_state(crtc, new_state);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
verify_connector_state(crtc->dev, crtc);
verify_crtc_state(crtc, old_state, new_state);
verify_shared_dpll_state(crtc->dev, crtc, old_state, new_state);
}
static void
verify_disabled_dpll_state(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
int i;
for (i = 0; i < dev_priv->num_shared_dpll; i++)
verify_single_dpll_state(dev_priv, &dev_priv->shared_dplls[i], NULL, NULL);
}
static void
intel_modeset_verify_disabled(struct drm_device *dev)
{
verify_encoder_state(dev);
verify_connector_state(dev, NULL);
verify_disabled_dpll_state(dev);
}
static void update_scanline_offset(struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
/*
* The scanline counter increments at the leading edge of hsync.
*
* On most platforms it starts counting from vtotal-1 on the
* first active line. That means the scanline counter value is
* always one less than what we would expect. Ie. just after
* start of vblank, which also occurs at start of hsync (on the
* last active line), the scanline counter will read vblank_start-1.
*
* On gen2 the scanline counter starts counting from 1 instead
* of vtotal-1, so we have to subtract one (or rather add vtotal-1
* to keep the value positive), instead of adding one.
*
* On HSW+ the behaviour of the scanline counter depends on the output
* type. For DP ports it behaves like most other platforms, but on HDMI
* there's an extra 1 line difference. So we need to add two instead of
* one to the value.
*/
if (IS_GEN2(dev)) {
const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
int vtotal;
vtotal = adjusted_mode->crtc_vtotal;
if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
vtotal /= 2;
crtc->scanline_offset = vtotal - 1;
} else if (HAS_DDI(dev) &&
intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) {
crtc->scanline_offset = 2;
} else
crtc->scanline_offset = 1;
}
static void intel_modeset_clear_plls(struct drm_atomic_state *state)
{
struct drm_device *dev = state->dev;
struct drm_i915_private *dev_priv = to_i915(dev);
struct intel_shared_dpll_config *shared_dpll = NULL;
struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state;
int i;
if (!dev_priv->display.crtc_compute_clock)
return;
for_each_crtc_in_state(state, crtc, crtc_state, i) {
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_shared_dpll *old_dpll =
to_intel_crtc_state(crtc->state)->shared_dpll;
if (!needs_modeset(crtc_state))
continue;
to_intel_crtc_state(crtc_state)->shared_dpll = NULL;
if (!old_dpll)
continue;
if (!shared_dpll)
shared_dpll = intel_atomic_get_shared_dpll_state(state);
intel_shared_dpll_config_put(shared_dpll, old_dpll, intel_crtc);
}
}
/*
* This implements the workaround described in the "notes" section of the mode
* set sequence documentation. When going from no pipes or single pipe to
* multiple pipes, and planes are enabled after the pipe, we need to wait at
* least 2 vblanks on the first pipe before enabling planes on the second pipe.
*/
static int haswell_mode_set_planes_workaround(struct drm_atomic_state *state)
{
struct drm_crtc_state *crtc_state;
struct intel_crtc *intel_crtc;
struct drm_crtc *crtc;
struct intel_crtc_state *first_crtc_state = NULL;
struct intel_crtc_state *other_crtc_state = NULL;
enum pipe first_pipe = INVALID_PIPE, enabled_pipe = INVALID_PIPE;
int i;
/* look at all crtc's that are going to be enabled in during modeset */
for_each_crtc_in_state(state, crtc, crtc_state, i) {
intel_crtc = to_intel_crtc(crtc);
if (!crtc_state->active || !needs_modeset(crtc_state))
continue;
if (first_crtc_state) {
other_crtc_state = to_intel_crtc_state(crtc_state);
break;
} else {
first_crtc_state = to_intel_crtc_state(crtc_state);
first_pipe = intel_crtc->pipe;
}
}
/* No workaround needed? */
if (!first_crtc_state)
return 0;
/* w/a possibly needed, check how many crtc's are already enabled. */
for_each_intel_crtc(state->dev, intel_crtc) {
struct intel_crtc_state *pipe_config;
pipe_config = intel_atomic_get_crtc_state(state, intel_crtc);
if (IS_ERR(pipe_config))
return PTR_ERR(pipe_config);
pipe_config->hsw_workaround_pipe = INVALID_PIPE;
if (!pipe_config->base.active ||
needs_modeset(&pipe_config->base))
continue;
/* 2 or more enabled crtcs means no need for w/a */
if (enabled_pipe != INVALID_PIPE)
return 0;
enabled_pipe = intel_crtc->pipe;
}
if (enabled_pipe != INVALID_PIPE)
first_crtc_state->hsw_workaround_pipe = enabled_pipe;
else if (other_crtc_state)
other_crtc_state->hsw_workaround_pipe = first_pipe;
return 0;
}
static int intel_modeset_all_pipes(struct drm_atomic_state *state)
{
struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state;
int ret = 0;
/* add all active pipes to the state */
for_each_crtc(state->dev, crtc) {
crtc_state = drm_atomic_get_crtc_state(state, crtc);
if (IS_ERR(crtc_state))
return PTR_ERR(crtc_state);
if (!crtc_state->active || needs_modeset(crtc_state))
continue;
crtc_state->mode_changed = true;
ret = drm_atomic_add_affected_connectors(state, crtc);
if (ret)
break;
ret = drm_atomic_add_affected_planes(state, crtc);
if (ret)
break;
}
return ret;
}
static int intel_modeset_checks(struct drm_atomic_state *state)
{
struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
struct drm_i915_private *dev_priv = state->dev->dev_private;
struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state;
int ret = 0, i;
if (!check_digital_port_conflicts(state)) {
DRM_DEBUG_KMS("rejecting conflicting digital port configuration\n");
return -EINVAL;
}
intel_state->modeset = true;
intel_state->active_crtcs = dev_priv->active_crtcs;
for_each_crtc_in_state(state, crtc, crtc_state, i) {
if (crtc_state->active)
intel_state->active_crtcs |= 1 << i;
else
intel_state->active_crtcs &= ~(1 << i);
if (crtc_state->active != crtc->state->active)
intel_state->active_pipe_changes |= drm_crtc_mask(crtc);
}
/*
* See if the config requires any additional preparation, e.g.
* to adjust global state with pipes off. We need to do this
* here so we can get the modeset_pipe updated config for the new
* mode set on this crtc. For other crtcs we need to use the
* adjusted_mode bits in the crtc directly.
*/
if (dev_priv->display.modeset_calc_cdclk) {
drm/i915/skl: SKL CDCLK change on modeset tracking VCO WARNING: Using ChromeOS with an eDP panel and a 4K@60 DP monitor connected to DDI1 the system will hard hang during a cold boot. Occurs when DDI1 is enabled when the cdclk is less then required. DP connected to DDI2 and HPD on either port works correctly. Set cdclk based on the max required pixel clock based on VCO selected. Track boot vco instead of boot cdclk. The vco is now tracked at the atomic level and all CRTCs updated if the required vco is changed. Not tested with eDP v1.4 panels that require 8640 vco due to availability. V1: initial version V2: add vco tracking in intel_dp_compute_config(), rename skl_boot_cdclk. V3: rebase, V2 feedback not possible as encoders are not aware of atomic. V4: track target vco is atomic state. modeset all CRTCs if vco changes V5: rename atomic variable, cleaner if/else logic, use existing vco if encoder does not return a new vco value. check_patch.pl cleanup V6: simplify logic in intel_modeset_checks. V7: reorder an IF for readability and whitespace fix. V8: use dev_cdclk for tracking new cdclk during atomic V9: correctly handle vco 8640 when crtcs==0 V10: Clean up if else in crtcs==0 V11: Rebase for new intel_dpll_mgr.c Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Clint Taylor <clinton.a.taylor@intel.com> [vsyrjala: rebased due to churn] Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1463172100-24715-3-git-send-email-ville.syrjala@linux.intel.com
2016-05-13 23:41:21 +03:00
if (!intel_state->cdclk_pll_vco)
intel_state->cdclk_pll_vco = dev_priv->cdclk_pll.vco;
if (!intel_state->cdclk_pll_vco)
intel_state->cdclk_pll_vco = dev_priv->skl_preferred_vco_freq;
drm/i915/skl: SKL CDCLK change on modeset tracking VCO WARNING: Using ChromeOS with an eDP panel and a 4K@60 DP monitor connected to DDI1 the system will hard hang during a cold boot. Occurs when DDI1 is enabled when the cdclk is less then required. DP connected to DDI2 and HPD on either port works correctly. Set cdclk based on the max required pixel clock based on VCO selected. Track boot vco instead of boot cdclk. The vco is now tracked at the atomic level and all CRTCs updated if the required vco is changed. Not tested with eDP v1.4 panels that require 8640 vco due to availability. V1: initial version V2: add vco tracking in intel_dp_compute_config(), rename skl_boot_cdclk. V3: rebase, V2 feedback not possible as encoders are not aware of atomic. V4: track target vco is atomic state. modeset all CRTCs if vco changes V5: rename atomic variable, cleaner if/else logic, use existing vco if encoder does not return a new vco value. check_patch.pl cleanup V6: simplify logic in intel_modeset_checks. V7: reorder an IF for readability and whitespace fix. V8: use dev_cdclk for tracking new cdclk during atomic V9: correctly handle vco 8640 when crtcs==0 V10: Clean up if else in crtcs==0 V11: Rebase for new intel_dpll_mgr.c Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Clint Taylor <clinton.a.taylor@intel.com> [vsyrjala: rebased due to churn] Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1463172100-24715-3-git-send-email-ville.syrjala@linux.intel.com
2016-05-13 23:41:21 +03:00
ret = dev_priv->display.modeset_calc_cdclk(state);
drm/i915/skl: SKL CDCLK change on modeset tracking VCO WARNING: Using ChromeOS with an eDP panel and a 4K@60 DP monitor connected to DDI1 the system will hard hang during a cold boot. Occurs when DDI1 is enabled when the cdclk is less then required. DP connected to DDI2 and HPD on either port works correctly. Set cdclk based on the max required pixel clock based on VCO selected. Track boot vco instead of boot cdclk. The vco is now tracked at the atomic level and all CRTCs updated if the required vco is changed. Not tested with eDP v1.4 panels that require 8640 vco due to availability. V1: initial version V2: add vco tracking in intel_dp_compute_config(), rename skl_boot_cdclk. V3: rebase, V2 feedback not possible as encoders are not aware of atomic. V4: track target vco is atomic state. modeset all CRTCs if vco changes V5: rename atomic variable, cleaner if/else logic, use existing vco if encoder does not return a new vco value. check_patch.pl cleanup V6: simplify logic in intel_modeset_checks. V7: reorder an IF for readability and whitespace fix. V8: use dev_cdclk for tracking new cdclk during atomic V9: correctly handle vco 8640 when crtcs==0 V10: Clean up if else in crtcs==0 V11: Rebase for new intel_dpll_mgr.c Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Clint Taylor <clinton.a.taylor@intel.com> [vsyrjala: rebased due to churn] Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1463172100-24715-3-git-send-email-ville.syrjala@linux.intel.com
2016-05-13 23:41:21 +03:00
if (ret < 0)
return ret;
drm/i915/skl: SKL CDCLK change on modeset tracking VCO WARNING: Using ChromeOS with an eDP panel and a 4K@60 DP monitor connected to DDI1 the system will hard hang during a cold boot. Occurs when DDI1 is enabled when the cdclk is less then required. DP connected to DDI2 and HPD on either port works correctly. Set cdclk based on the max required pixel clock based on VCO selected. Track boot vco instead of boot cdclk. The vco is now tracked at the atomic level and all CRTCs updated if the required vco is changed. Not tested with eDP v1.4 panels that require 8640 vco due to availability. V1: initial version V2: add vco tracking in intel_dp_compute_config(), rename skl_boot_cdclk. V3: rebase, V2 feedback not possible as encoders are not aware of atomic. V4: track target vco is atomic state. modeset all CRTCs if vco changes V5: rename atomic variable, cleaner if/else logic, use existing vco if encoder does not return a new vco value. check_patch.pl cleanup V6: simplify logic in intel_modeset_checks. V7: reorder an IF for readability and whitespace fix. V8: use dev_cdclk for tracking new cdclk during atomic V9: correctly handle vco 8640 when crtcs==0 V10: Clean up if else in crtcs==0 V11: Rebase for new intel_dpll_mgr.c Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Clint Taylor <clinton.a.taylor@intel.com> [vsyrjala: rebased due to churn] Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1463172100-24715-3-git-send-email-ville.syrjala@linux.intel.com
2016-05-13 23:41:21 +03:00
if (intel_state->dev_cdclk != dev_priv->cdclk_freq ||
intel_state->cdclk_pll_vco != dev_priv->cdclk_pll.vco)
ret = intel_modeset_all_pipes(state);
if (ret < 0)
return ret;
DRM_DEBUG_KMS("New cdclk calculated to be atomic %u, actual %u\n",
intel_state->cdclk, intel_state->dev_cdclk);
} else
to_intel_atomic_state(state)->cdclk = dev_priv->atomic_cdclk_freq;
intel_modeset_clear_plls(state);
if (IS_HASWELL(dev_priv))
return haswell_mode_set_planes_workaround(state);
return 0;
}
/*
* Handle calculation of various watermark data at the end of the atomic check
* phase. The code here should be run after the per-crtc and per-plane 'check'
* handlers to ensure that all derived state has been updated.
*/
static int calc_watermark_data(struct drm_atomic_state *state)
{
struct drm_device *dev = state->dev;
drm/i915/gen9: Compute DDB allocation at atomic check time (v4) Calculate the DDB blocks needed to satisfy the current atomic transaction at atomic check time. This is a prerequisite to calculating SKL watermarks during the 'check' phase and rejecting any configurations that we can't find valid watermarks for. Due to the nature of DDB allocation, it's possible for the addition of a new CRTC to make the watermark configuration already in use on another, unchanged CRTC become invalid. A change in which CRTC's are active triggers a recompute of the entire DDB, which unfortunately means we need to disallow any other atomic commits from racing with such an update. If the active CRTC's change, we need to grab the lock on all CRTC's and run all CRTC's through their 'check' handler to recompute and re-check their per-CRTC DDB allocations. Note that with this patch we only compute the DDB allocation but we don't actually use the computed values during watermark programming yet. For ease of review/testing/bisecting, we still recompute the DDB at watermark programming time and just WARN() if it doesn't match the precomputed values. A future patch will switch over to using the precomputed values once we're sure they're being properly computed. Another clarifying note: DDB allocation itself shouldn't ever fail with the algorithm we use today (i.e., we have enough DDB blocks on BXT to support the minimum needs of the worst-case scenario of every pipe/plane enabled at full size). However the watermarks calculations based on the DDB may fail and we'll be moving those to the atomic check as well in future patches. v2: - Skip DDB calculations in the rare case where our transaction doesn't actually touch any CRTC's at all. Assuming at least one CRTC state is present in our transaction, then it means we can't race with any transactions that would update dev_priv->active_crtcs (which requires _all_ CRTC locks). v3: - Also calculate DDB during initial hw readout, to prevent using incorrect bios values. (Maarten) v4: - Use new distrust_bios_wm flag instead of skip_initial_wm (which was never actually set). - Set intel_state->active_pipe_changes instead of just realloc_pipes Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Lyude Paul <cpaul@redhat.com> Cc: Radhakrishna Sripada <radhakrishna.sripada@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1463061971-19638-10-git-send-email-matthew.d.roper@intel.com
2016-05-12 07:06:03 -07:00
struct drm_i915_private *dev_priv = to_i915(dev);
/* Is there platform-specific watermark information to calculate? */
if (dev_priv->display.compute_global_watermarks)
return dev_priv->display.compute_global_watermarks(state);
return 0;
}
/**
* intel_atomic_check - validate state object
* @dev: drm device
* @state: state to validate
*/
static int intel_atomic_check(struct drm_device *dev,
struct drm_atomic_state *state)
{
struct drm_i915_private *dev_priv = to_i915(dev);
struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state;
int ret, i;
bool any_ms = false;
ret = drm_atomic_helper_check_modeset(dev, state);
if (ret)
return ret;
for_each_crtc_in_state(state, crtc, crtc_state, i) {
struct intel_crtc_state *pipe_config =
to_intel_crtc_state(crtc_state);
/* Catch I915_MODE_FLAG_INHERITED */
if (crtc_state->mode.private_flags != crtc->state->mode.private_flags)
crtc_state->mode_changed = true;
if (!needs_modeset(crtc_state))
continue;
if (!crtc_state->enable) {
any_ms = true;
continue;
}
/* FIXME: For only active_changed we shouldn't need to do any
* state recomputation at all. */
ret = drm_atomic_add_affected_connectors(state, crtc);
if (ret)
return ret;
ret = intel_modeset_pipe_config(crtc, pipe_config);
if (ret) {
intel_dump_pipe_config(to_intel_crtc(crtc),
pipe_config, "[failed]");
return ret;
}
if (i915.fastboot &&
intel_pipe_config_compare(dev,
to_intel_crtc_state(crtc->state),
pipe_config, true)) {
crtc_state->mode_changed = false;
to_intel_crtc_state(crtc_state)->update_pipe = true;
}
if (needs_modeset(crtc_state))
any_ms = true;
ret = drm_atomic_add_affected_planes(state, crtc);
if (ret)
return ret;
intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config,
needs_modeset(crtc_state) ?
"[modeset]" : "[fastset]");
}
if (any_ms) {
ret = intel_modeset_checks(state);
if (ret)
return ret;
} else
intel_state->cdclk = dev_priv->cdclk_freq;
ret = drm_atomic_helper_check_planes(dev, state);
if (ret)
return ret;
intel_fbc_choose_crtc(dev_priv, state);
return calc_watermark_data(state);
}
static int intel_atomic_prepare_commit(struct drm_device *dev,
struct drm_atomic_state *state,
bool nonblock)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_plane_state *plane_state;
struct drm_crtc_state *crtc_state;
struct drm_plane *plane;
struct drm_crtc *crtc;
int i, ret;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
for_each_crtc_in_state(state, crtc, crtc_state, i) {
if (state->legacy_cursor_update)
continue;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
ret = intel_crtc_wait_for_pending_flips(crtc);
if (ret)
return ret;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
if (atomic_read(&to_intel_crtc(crtc)->unpin_work_count) >= 2)
flush_workqueue(dev_priv->wq);
}
ret = mutex_lock_interruptible(&dev->struct_mutex);
if (ret)
return ret;
ret = drm_atomic_helper_prepare_planes(dev, state);
mutex_unlock(&dev->struct_mutex);
Merge tag 'topic/drm-misc-2016-05-04' of git://anongit.freedesktop.org/drm-intel into drm-next Ofc I promise just a few leftovers for drm-misc and somehow it's the biggest pull. But really mostly trivial stuff: - MAINTAINERS updates from Emil - rename async to nonblock in atomic_commit to avoid the confusion between nonblocking ioctl and async flip (= not vblank synced), from Maarten. Needs to be regened with newer drivers, but probably only after -rc1 to catch them all. - actually lockless gem_object_free, plus acked driver conversion patches. All the trickier prep stuff already is in drm-next. - Noralf's nice work for generic defio support in our fbdev emulation. Keeps the udl hack, and qxl is tested by Gerd. * tag 'topic/drm-misc-2016-05-04' of git://anongit.freedesktop.org/drm-intel: (47 commits) drm: Fixup locking WARN_ON mistake around gem_object_free_unlocked drm/etnaviv: Use lockless gem BO free callback drm/imx: Use lockless gem BO free callback drm/radeon: Use lockless gem BO free callback drm/amdgpu: Use lockless gem BO free callback drm/gem: support BO freeing without dev->struct_mutex MAINTAINERS: Add myself for the new VC4 (RPi GPU) graphics driver. MAINTAINERS: Add a bunch of legacy (UMS) DRM drivers MAINTAINERS: Add a few DRM drivers by Dave Airlie MAINTAINERS: List the correct git repo for the Renesas DRM drivers MAINTAINERS: Update the files list for the Renesas DRM drivers MAINTAINERS: Update the files list for the Armada DRM driver MAINTAINERS: Update the files list for the Rockchip DRM driver MAINTAINERS: Update the files list for the Exynos DRM driver MAINTAINERS: Add maintainer entry for the VMWGFX DRM driver MAINTAINERS: Add maintainer entry for the MSM DRM driver MAINTAINERS: Add maintainer entry for the Nouveau DRM driver MAINTAINERS: Update the files list for the Etnaviv DRM driver MAINTAINERS: Remove unneded wildcard for the i915 DRM driver drm/atomic: Add WARN_ON when state->acquire_ctx is not set. ...
2016-05-05 09:56:30 +10:00
if (!ret && !nonblock) {
for_each_plane_in_state(state, plane, plane_state, i) {
struct intel_plane_state *intel_plane_state =
to_intel_plane_state(plane_state);
if (!intel_plane_state->wait_req)
continue;
ret = __i915_wait_request(intel_plane_state->wait_req,
true, NULL, NULL);
if (ret) {
drm/i915: Prevent leaking of -EIO from i915_wait_request() Reporting -EIO from i915_wait_request() has proven very troublematic over the years, with numerous hard-to-reproduce bugs cropping up in the corner case of where a reset occurs and the code wasn't expecting such an error. If the we reset the GPU or have detected a hang and wish to reset the GPU, the request is forcibly complete and the wait broken. Currently, we report either -EAGAIN or -EIO in order for the caller to retreat and restart the wait (if appropriate) after dropping and then reacquiring the struct_mutex (essential to allow the GPU reset to proceed). However, if we take the view that the request is complete (no further work will be done on it by the GPU because it is dead and soon to be reset), then we can proceed with the task at hand and then drop the struct_mutex allowing the reset to occur. This transfers the burden of checking whether it is safe to proceed to the caller, which in all but one instance it is safe - completely eliminating the source of all spurious -EIO. Of note, we only have two API entry points where we expect that userspace can observe an EIO. First is when submitting an execbuf, if the GPU is terminally wedged, then the operation cannot succeed and an -EIO is reported. Secondly, existing userspace uses the throttle ioctl to detect an already wedged GPU before starting using HW acceleration (or to confirm that the GPU is wedged after an error condition). So if the GPU is wedged when the user calls throttle, also report -EIO. v2: Split more carefully the change to i915_wait_request() and assorted ABI from the reset handling. v3: Add a couple of WARN_ON(EIO) to the interruptible modesetting code so that we don't start to leak EIO there in future (and break our hang resistant modesetting). Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/1460565315-7748-9-git-send-email-chris@chris-wilson.co.uk Link: http://patchwork.freedesktop.org/patch/msgid/1460565315-7748-1-git-send-email-chris@chris-wilson.co.uk
2016-04-13 17:35:08 +01:00
/* Any hang should be swallowed by the wait */
WARN_ON(ret == -EIO);
mutex_lock(&dev->struct_mutex);
drm_atomic_helper_cleanup_planes(dev, state);
mutex_unlock(&dev->struct_mutex);
break;
}
}
}
return ret;
}
u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
if (!dev->max_vblank_count)
return drm_accurate_vblank_count(&crtc->base);
return dev->driver->get_vblank_counter(dev, crtc->pipe);
}
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
static void intel_atomic_wait_for_vblanks(struct drm_device *dev,
struct drm_i915_private *dev_priv,
unsigned crtc_mask)
{
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
unsigned last_vblank_count[I915_MAX_PIPES];
enum pipe pipe;
int ret;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
if (!crtc_mask)
return;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
for_each_pipe(dev_priv, pipe) {
struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
if (!((1 << pipe) & crtc_mask))
continue;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
ret = drm_crtc_vblank_get(crtc);
if (WARN_ON(ret != 0)) {
crtc_mask &= ~(1 << pipe);
continue;
}
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
last_vblank_count[pipe] = drm_crtc_vblank_count(crtc);
}
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
for_each_pipe(dev_priv, pipe) {
struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
long lret;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
if (!((1 << pipe) & crtc_mask))
continue;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
lret = wait_event_timeout(dev->vblank[pipe].queue,
last_vblank_count[pipe] !=
drm_crtc_vblank_count(crtc),
msecs_to_jiffies(50));
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
WARN(!lret, "pipe %c vblank wait timed out\n", pipe_name(pipe));
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
drm_crtc_vblank_put(crtc);
}
}
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
static bool needs_vblank_wait(struct intel_crtc_state *crtc_state)
{
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
/* fb updated, need to unpin old fb */
if (crtc_state->fb_changed)
return true;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
/* wm changes, need vblank before final wm's */
if (crtc_state->update_wm_post)
return true;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
/*
* cxsr is re-enabled after vblank.
* This is already handled by crtc_state->update_wm_post,
* but added for clarity.
*/
if (crtc_state->disable_cxsr)
return true;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
return false;
}
static void intel_atomic_commit_tail(struct drm_atomic_state *state)
{
struct drm_device *dev = state->dev;
struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc_state *old_crtc_state;
struct drm_crtc *crtc;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
struct intel_crtc_state *intel_cstate;
struct drm_plane *plane;
struct drm_plane_state *plane_state;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
bool hw_check = intel_state->modeset;
unsigned long put_domains[I915_MAX_PIPES] = {};
unsigned crtc_vblank_mask = 0;
int i, ret;
for_each_plane_in_state(state, plane, plane_state, i) {
struct intel_plane_state *intel_plane_state =
to_intel_plane_state(plane_state);
if (!intel_plane_state->wait_req)
continue;
ret = __i915_wait_request(intel_plane_state->wait_req,
true, NULL, NULL);
/* EIO should be eaten, and we can't get interrupted in the
* worker, and blocking commits have waited already. */
WARN_ON(ret);
}
drm_atomic_helper_wait_for_dependencies(state);
if (intel_state->modeset) {
memcpy(dev_priv->min_pixclk, intel_state->min_pixclk,
sizeof(intel_state->min_pixclk));
dev_priv->active_crtcs = intel_state->active_crtcs;
dev_priv->atomic_cdclk_freq = intel_state->cdclk;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
intel_display_power_get(dev_priv, POWER_DOMAIN_MODESET);
}
for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
if (needs_modeset(crtc->state) ||
to_intel_crtc_state(crtc->state)->update_pipe) {
hw_check = true;
put_domains[to_intel_crtc(crtc)->pipe] =
modeset_get_crtc_power_domains(crtc,
to_intel_crtc_state(crtc->state));
}
if (!needs_modeset(crtc->state))
continue;
intel_pre_plane_update(to_intel_crtc_state(old_crtc_state));
if (old_crtc_state->active) {
intel_crtc_disable_planes(crtc, old_crtc_state->plane_mask);
dev_priv->display.crtc_disable(crtc);
intel_crtc->active = false;
intel_fbc_disable(intel_crtc);
intel_disable_shared_dpll(intel_crtc);
/*
* Underruns don't always raise
* interrupts, so check manually.
*/
intel_check_cpu_fifo_underruns(dev_priv);
intel_check_pch_fifo_underruns(dev_priv);
if (!crtc->state->active)
intel_update_watermarks(crtc);
}
}
drm/i915: push commit_output_state past the crtc/encoder preparing With this change we can (finally!) rip out a few of the temporary hacks and clean up a few other things: - Kill intel_crtc_prepare_encoders, now unused. - Kill the hacks in the crtc_disable/enable functions to always call the encoder callbacks, we now always call the crtc functions with the right encoder -> crtc links. - Also push down the crtc->enable, encoder and connector dpms state updates. Unfortunately we can't add a WARN in the crtc_disable callbacks to ensure that the crtc is always still enabled when disabling an output pipe - the crtc sanitizer of the hw readout path can hit this when it needs to disable an active pipe without any enabled outputs. - Only call crtc->disable if the pipe is already enabled - again avoids running afoul of the new WARN. v2: Copy&paste our own version of crtc_in_use, too. v3: We need to update the dpms an encoder->connectors_active states, too. v4: I've forgotten to kill the unconditional encoder->disable calls in the crtc_disable functions. v5: Rip out leftover debug printk. v6: Properly clear intel_encoder->connectors_active. This wasn't properly cleared when disabling an encoder because it was no longer on the new connector list, but the crtc was still enabled (i.e. switching the encoder of an active crtc). Reported by Jani Nikula. v7: Don't clobber the encoder->connectors_active state of untouched encoders. Since X likes to first disable all outputs with dpms off before setting a new framebuffer, this hit a few warnings. Reported by Paulo Zanoni. v8: Kill the now stale comment warning that intel_crtc->active is not always updated at the right times. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-10 10:42:52 +02:00
/* Only after disabling all output pipelines that will be changed can we
* update the the output configuration. */
intel_modeset_update_crtc_state(state);
if (intel_state->modeset) {
drm_atomic_helper_update_legacy_modeset_state(state->dev, state);
if (dev_priv->display.modeset_commit_cdclk &&
drm/i915/skl: SKL CDCLK change on modeset tracking VCO WARNING: Using ChromeOS with an eDP panel and a 4K@60 DP monitor connected to DDI1 the system will hard hang during a cold boot. Occurs when DDI1 is enabled when the cdclk is less then required. DP connected to DDI2 and HPD on either port works correctly. Set cdclk based on the max required pixel clock based on VCO selected. Track boot vco instead of boot cdclk. The vco is now tracked at the atomic level and all CRTCs updated if the required vco is changed. Not tested with eDP v1.4 panels that require 8640 vco due to availability. V1: initial version V2: add vco tracking in intel_dp_compute_config(), rename skl_boot_cdclk. V3: rebase, V2 feedback not possible as encoders are not aware of atomic. V4: track target vco is atomic state. modeset all CRTCs if vco changes V5: rename atomic variable, cleaner if/else logic, use existing vco if encoder does not return a new vco value. check_patch.pl cleanup V6: simplify logic in intel_modeset_checks. V7: reorder an IF for readability and whitespace fix. V8: use dev_cdclk for tracking new cdclk during atomic V9: correctly handle vco 8640 when crtcs==0 V10: Clean up if else in crtcs==0 V11: Rebase for new intel_dpll_mgr.c Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Clint Taylor <clinton.a.taylor@intel.com> [vsyrjala: rebased due to churn] Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1463172100-24715-3-git-send-email-ville.syrjala@linux.intel.com
2016-05-13 23:41:21 +03:00
(intel_state->dev_cdclk != dev_priv->cdclk_freq ||
intel_state->cdclk_pll_vco != dev_priv->cdclk_pll.vco))
dev_priv->display.modeset_commit_cdclk(state);
intel_modeset_verify_disabled(dev);
}
drm/i915: add ->display.modeset_global_resources callback After all relevant pipes are disabled and after we've updated all the state with the staged state, but before we call the per-crtc ->mode_set functions there's a very natural point to set up any shared/global resources like - shared plls (obviously only the setup, the enabling needs to be separately handling with a separate refcount) - global watermark state like the DSPARB on gmch platforms - workaround bits that depend upon the exact global output configuration - enabling the right set of refclocks - enabling/disabling manual power wells. Now for a lot of these things we can't move them into this function yet, most often because we only compute the required information in the per-crtc ->mode_set callback. Which is too late. But due to a bunch of reasons (check-only atomic modeset, fastboot&hw state checks, ...) we need to separate the computation of that state from the actual hw frobbery anyway. So we can move things into this new callback step- by-step. Others can't be moved here (or implemented at all) because our code lacks the smarts to properly update them. E.g. the DSPARB can only be updated when all pipes are disabled, so if we decide to change it's value, we need to disable _all_ pipes. The infrastructure for that is already in place (with the various pipe masks that driver the modeset logic). But again we need to move a few things out of ->mode_set first before we can even implement the correct decision making. In any case, we need to start somewhere, so let's start with the callback: Some small follow-up patches will make immediate good use of it. Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-10-26 10:58:18 +02:00
/* Now enable the clocks, plane, pipe, and connectors that we set up. */
for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
bool modeset = needs_modeset(crtc->state);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
struct intel_crtc_state *pipe_config =
to_intel_crtc_state(crtc->state);
if (modeset && crtc->state->active) {
update_scanline_offset(to_intel_crtc(crtc));
dev_priv->display.crtc_enable(crtc);
}
/* Complete events for now disable pipes here. */
if (modeset && !crtc->state->active && crtc->state->event) {
spin_lock_irq(&dev->event_lock);
drm_crtc_send_vblank_event(crtc, crtc->state->event);
spin_unlock_irq(&dev->event_lock);
crtc->state->event = NULL;
}
if (!modeset)
intel_pre_plane_update(to_intel_crtc_state(old_crtc_state));
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
if (crtc->state->active &&
drm_atomic_get_existing_plane_state(state, crtc->primary))
intel_fbc_enable(intel_crtc, pipe_config, to_intel_plane_state(crtc->primary->state));
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
if (crtc->state->active)
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
drm_atomic_helper_commit_planes_on_crtc(old_crtc_state);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
if (pipe_config->base.active && needs_vblank_wait(pipe_config))
crtc_vblank_mask |= 1 << i;
}
/* FIXME: We should call drm_atomic_helper_commit_hw_done() here
* already, but still need the state for the delayed optimization. To
* fix this:
* - wrap the optimization/post_plane_update stuff into a per-crtc work.
* - schedule that vblank worker _before_ calling hw_done
* - at the start of commit_tail, cancel it _synchrously
* - switch over to the vblank wait helper in the core after that since
* we don't need out special handling any more.
*/
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
if (!state->legacy_cursor_update)
intel_atomic_wait_for_vblanks(dev, dev_priv, crtc_vblank_mask);
/*
* Now that the vblank has passed, we can go ahead and program the
* optimal watermarks on platforms that need two-step watermark
* programming.
*
* TODO: Move this (and other cleanup) to an async worker eventually.
*/
for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
intel_cstate = to_intel_crtc_state(crtc->state);
if (dev_priv->display.optimize_watermarks)
dev_priv->display.optimize_watermarks(intel_cstate);
}
for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
intel_post_plane_update(to_intel_crtc_state(old_crtc_state));
if (put_domains[i])
modeset_put_power_domains(dev_priv, put_domains[i]);
intel_modeset_verify_crtc(crtc, old_crtc_state, crtc->state);
}
drm_atomic_helper_commit_hw_done(state);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
if (intel_state->modeset)
intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET);
mutex_lock(&dev->struct_mutex);
drm_atomic_helper_cleanup_planes(dev, state);
mutex_unlock(&dev->struct_mutex);
drm_atomic_helper_commit_cleanup_done(state);
drm_atomic_state_free(state);
/* As one of the primary mmio accessors, KMS has a high likelihood
* of triggering bugs in unclaimed access. After we finish
* modesetting, see if an error has been flagged, and if so
* enable debugging for the next modeset - and hope we catch
* the culprit.
*
* XXX note that we assume display power is on at this point.
* This might hold true now but we need to add pm helper to check
* unclaimed only when the hardware is on, as atomic commits
* can happen also when the device is completely off.
*/
intel_uncore_arm_unclaimed_mmio_detection(dev_priv);
}
static void intel_atomic_commit_work(struct work_struct *work)
{
struct drm_atomic_state *state = container_of(work,
struct drm_atomic_state,
commit_work);
intel_atomic_commit_tail(state);
}
static void intel_atomic_track_fbs(struct drm_atomic_state *state)
{
struct drm_plane_state *old_plane_state;
struct drm_plane *plane;
struct drm_i915_gem_object *obj, *old_obj;
struct intel_plane *intel_plane;
int i;
mutex_lock(&state->dev->struct_mutex);
for_each_plane_in_state(state, plane, old_plane_state, i) {
obj = intel_fb_obj(plane->state->fb);
old_obj = intel_fb_obj(old_plane_state->fb);
intel_plane = to_intel_plane(plane);
i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit);
}
mutex_unlock(&state->dev->struct_mutex);
}
/**
* intel_atomic_commit - commit validated state object
* @dev: DRM device
* @state: the top-level driver state object
* @nonblock: nonblocking commit
*
* This function commits a top-level state object that has been validated
* with drm_atomic_helper_check().
*
* FIXME: Atomic modeset support for i915 is not yet complete. At the moment
* nonblocking commits are only safe for pure plane updates. Everything else
* should work though.
*
* RETURNS
* Zero for success or -errno.
*/
static int intel_atomic_commit(struct drm_device *dev,
struct drm_atomic_state *state,
bool nonblock)
{
struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
struct drm_i915_private *dev_priv = dev->dev_private;
int ret = 0;
if (intel_state->modeset && nonblock) {
DRM_DEBUG_KMS("nonblocking commit for modeset not yet implemented.\n");
return -EINVAL;
}
ret = drm_atomic_helper_setup_commit(state, nonblock);
if (ret)
return ret;
INIT_WORK(&state->commit_work, intel_atomic_commit_work);
ret = intel_atomic_prepare_commit(dev, state, nonblock);
if (ret) {
DRM_DEBUG_ATOMIC("Preparing state failed with %i\n", ret);
return ret;
}
drm_atomic_helper_swap_state(state, true);
dev_priv->wm.distrust_bios_wm = false;
dev_priv->wm.skl_results = intel_state->wm_results;
intel_shared_dpll_commit(state);
intel_atomic_track_fbs(state);
if (nonblock)
queue_work(system_unbound_wq, &state->commit_work);
else
intel_atomic_commit_tail(state);
return 0;
}
void intel_crtc_restore_mode(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
struct drm_atomic_state *state;
struct drm_crtc_state *crtc_state;
int ret;
state = drm_atomic_state_alloc(dev);
if (!state) {
DRM_DEBUG_KMS("[CRTC:%d:%s] crtc restore failed, out of memory",
crtc->base.id, crtc->name);
return;
}
state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
retry:
crtc_state = drm_atomic_get_crtc_state(state, crtc);
ret = PTR_ERR_OR_ZERO(crtc_state);
if (!ret) {
if (!crtc_state->active)
goto out;
crtc_state->mode_changed = true;
ret = drm_atomic_commit(state);
}
if (ret == -EDEADLK) {
drm_atomic_state_clear(state);
drm_modeset_backoff(state->acquire_ctx);
goto retry;
}
if (ret)
out:
drm_atomic_state_free(state);
}
#undef for_each_intel_crtc_masked
static const struct drm_crtc_funcs intel_crtc_funcs = {
.gamma_set = drm_atomic_helper_legacy_gamma_set,
.set_config = drm_atomic_helper_set_config,
.set_property = drm_atomic_helper_crtc_set_property,
.destroy = intel_crtc_destroy,
Revert "drm/i915: Use atomic commits for legacy page_flips" This reverts commit ee042aa40b66d18d465206845b0752c6a617ba3f. Something appears to be off in the timing, but as far as I can tell it is not along the event delivery path. The net effect appears to be rendering flicker (the current render buffer appears on the scanout, with what appears to be active rendering for a fraction of a frame) and is causing me a headache. The cursor is also being stalled by page flips, causing a "heavy mouse" and jitter. Daniel Stone did find what appears to the cause of the tearing, in https://lists.freedesktop.org/archives/intel-gfx/2016-June/099466.html That is the parameter passed to intel_atomic_commit_tail is the old_state but we need the new_state to wait upon. That leaves the question of how the CRC based tests didn't spot the error (how can we improve our tests?), the issue of legacy cursor stalling flips, and the issue of flips stalling the cursor. For the moment, step back until the condundrum of new/old state is reviewed along with more tests! Reported-and-tested-by: Steven Newbury <steve@snewbury.org.uk> Reported-by: Rafael Ristovski <rafael.ristovski@gmail.com> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96593 Testcase: igt/kms_cursor_legacy/basic-cursor-vs-flip Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1466772243-21879-1-git-send-email-chris@chris-wilson.co.uk Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
2016-06-24 13:44:03 +01:00
.page_flip = intel_crtc_page_flip,
.atomic_duplicate_state = intel_crtc_duplicate_state,
.atomic_destroy_state = intel_crtc_destroy_state,
};
/**
* intel_prepare_plane_fb - Prepare fb for usage on plane
* @plane: drm plane to prepare for
* @fb: framebuffer to prepare for presentation
*
* Prepares a framebuffer for usage on a display plane. Generally this
* involves pinning the underlying object and updating the frontbuffer tracking
* bits. Some older platforms need special physical address handling for
* cursor planes.
*
* Must be called with struct_mutex held.
*
* Returns 0 on success, negative error code on failure.
*/
int
intel_prepare_plane_fb(struct drm_plane *plane,
const struct drm_plane_state *new_state)
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
{
struct drm_device *dev = plane->dev;
struct drm_framebuffer *fb = new_state->fb;
struct drm_i915_gem_object *obj = intel_fb_obj(fb);
struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->state->fb);
struct reservation_object *resv;
int ret = 0;
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
if (!obj && !old_obj)
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
return 0;
if (old_obj) {
struct drm_crtc_state *crtc_state =
drm_atomic_get_existing_crtc_state(new_state->state, plane->state->crtc);
/* Big Hammer, we also need to ensure that any pending
* MI_WAIT_FOR_EVENT inside a user batch buffer on the
* current scanout is retired before unpinning the old
* framebuffer. Note that we rely on userspace rendering
* into the buffer attached to the pipe they are waiting
* on. If not, userspace generates a GPU hang with IPEHR
* point to the MI_WAIT_FOR_EVENT.
*
* This should only fail upon a hung GPU, in which case we
* can safely continue.
*/
if (needs_modeset(crtc_state))
ret = i915_gem_object_wait_rendering(old_obj, true);
drm/i915: Prevent leaking of -EIO from i915_wait_request() Reporting -EIO from i915_wait_request() has proven very troublematic over the years, with numerous hard-to-reproduce bugs cropping up in the corner case of where a reset occurs and the code wasn't expecting such an error. If the we reset the GPU or have detected a hang and wish to reset the GPU, the request is forcibly complete and the wait broken. Currently, we report either -EAGAIN or -EIO in order for the caller to retreat and restart the wait (if appropriate) after dropping and then reacquiring the struct_mutex (essential to allow the GPU reset to proceed). However, if we take the view that the request is complete (no further work will be done on it by the GPU because it is dead and soon to be reset), then we can proceed with the task at hand and then drop the struct_mutex allowing the reset to occur. This transfers the burden of checking whether it is safe to proceed to the caller, which in all but one instance it is safe - completely eliminating the source of all spurious -EIO. Of note, we only have two API entry points where we expect that userspace can observe an EIO. First is when submitting an execbuf, if the GPU is terminally wedged, then the operation cannot succeed and an -EIO is reported. Secondly, existing userspace uses the throttle ioctl to detect an already wedged GPU before starting using HW acceleration (or to confirm that the GPU is wedged after an error condition). So if the GPU is wedged when the user calls throttle, also report -EIO. v2: Split more carefully the change to i915_wait_request() and assorted ABI from the reset handling. v3: Add a couple of WARN_ON(EIO) to the interruptible modesetting code so that we don't start to leak EIO there in future (and break our hang resistant modesetting). Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/1460565315-7748-9-git-send-email-chris@chris-wilson.co.uk Link: http://patchwork.freedesktop.org/patch/msgid/1460565315-7748-1-git-send-email-chris@chris-wilson.co.uk
2016-04-13 17:35:08 +01:00
if (ret) {
/* GPU hangs should have been swallowed by the wait */
WARN_ON(ret == -EIO);
return ret;
drm/i915: Prevent leaking of -EIO from i915_wait_request() Reporting -EIO from i915_wait_request() has proven very troublematic over the years, with numerous hard-to-reproduce bugs cropping up in the corner case of where a reset occurs and the code wasn't expecting such an error. If the we reset the GPU or have detected a hang and wish to reset the GPU, the request is forcibly complete and the wait broken. Currently, we report either -EAGAIN or -EIO in order for the caller to retreat and restart the wait (if appropriate) after dropping and then reacquiring the struct_mutex (essential to allow the GPU reset to proceed). However, if we take the view that the request is complete (no further work will be done on it by the GPU because it is dead and soon to be reset), then we can proceed with the task at hand and then drop the struct_mutex allowing the reset to occur. This transfers the burden of checking whether it is safe to proceed to the caller, which in all but one instance it is safe - completely eliminating the source of all spurious -EIO. Of note, we only have two API entry points where we expect that userspace can observe an EIO. First is when submitting an execbuf, if the GPU is terminally wedged, then the operation cannot succeed and an -EIO is reported. Secondly, existing userspace uses the throttle ioctl to detect an already wedged GPU before starting using HW acceleration (or to confirm that the GPU is wedged after an error condition). So if the GPU is wedged when the user calls throttle, also report -EIO. v2: Split more carefully the change to i915_wait_request() and assorted ABI from the reset handling. v3: Add a couple of WARN_ON(EIO) to the interruptible modesetting code so that we don't start to leak EIO there in future (and break our hang resistant modesetting). Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/1460565315-7748-9-git-send-email-chris@chris-wilson.co.uk Link: http://patchwork.freedesktop.org/patch/msgid/1460565315-7748-1-git-send-email-chris@chris-wilson.co.uk
2016-04-13 17:35:08 +01:00
}
}
if (!obj)
return 0;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
/* For framebuffer backed by dmabuf, wait for fence */
resv = i915_gem_object_get_dmabuf_resv(obj);
if (resv) {
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
long lret;
lret = reservation_object_wait_timeout_rcu(resv, false, true,
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
MAX_SCHEDULE_TIMEOUT);
if (lret == -ERESTARTSYS)
return lret;
WARN(lret < 0, "waiting returns %li\n", lret);
}
if (plane->type == DRM_PLANE_TYPE_CURSOR &&
INTEL_INFO(dev)->cursor_needs_physical) {
int align = IS_I830(dev) ? 16 * 1024 : 256;
ret = i915_gem_object_attach_phys(obj, align);
if (ret)
DRM_DEBUG_KMS("failed to attach phys object\n");
} else {
ret = intel_pin_and_fence_fb_obj(fb, new_state->rotation);
}
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
if (ret == 0) {
struct intel_plane_state *plane_state =
to_intel_plane_state(new_state);
i915_gem_request_assign(&plane_state->wait_req,
obj->last_write_req);
}
return ret;
}
/**
* intel_cleanup_plane_fb - Cleans up an fb after plane use
* @plane: drm plane to clean up for
* @fb: old framebuffer that was on plane
*
* Cleans up a framebuffer that has just been removed from a plane.
*
* Must be called with struct_mutex held.
*/
void
intel_cleanup_plane_fb(struct drm_plane *plane,
const struct drm_plane_state *old_state)
{
struct drm_device *dev = plane->dev;
struct intel_plane_state *old_intel_state;
struct drm_i915_gem_object *old_obj = intel_fb_obj(old_state->fb);
struct drm_i915_gem_object *obj = intel_fb_obj(plane->state->fb);
old_intel_state = to_intel_plane_state(old_state);
if (!obj && !old_obj)
return;
if (old_obj && (plane->type != DRM_PLANE_TYPE_CURSOR ||
!INTEL_INFO(dev)->cursor_needs_physical))
intel_unpin_fb_obj(old_state->fb, old_state->rotation);
i915_gem_request_assign(&old_intel_state->wait_req, NULL);
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
}
int
skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state)
{
int max_scale;
struct drm_device *dev;
struct drm_i915_private *dev_priv;
int crtc_clock, cdclk;
if (!intel_crtc || !crtc_state->base.enable)
return DRM_PLANE_HELPER_NO_SCALING;
dev = intel_crtc->base.dev;
dev_priv = dev->dev_private;
crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
cdclk = to_intel_atomic_state(crtc_state->base.state)->cdclk;
if (WARN_ON_ONCE(!crtc_clock || cdclk < crtc_clock))
return DRM_PLANE_HELPER_NO_SCALING;
/*
* skl max scale is lower of:
* close to 3 but not 3, -1 is for that purpose
* or
* cdclk/crtc_clock
*/
max_scale = min((1 << 16) * 3 - 1, (1 << 8) * ((cdclk << 8) / crtc_clock));
return max_scale;
}
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
static int
intel_check_primary_plane(struct drm_plane *plane,
struct intel_crtc_state *crtc_state,
struct intel_plane_state *state)
{
struct drm_crtc *crtc = state->base.crtc;
struct drm_framebuffer *fb = state->base.fb;
int min_scale = DRM_PLANE_HELPER_NO_SCALING;
int max_scale = DRM_PLANE_HELPER_NO_SCALING;
bool can_position = false;
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
if (INTEL_INFO(plane->dev)->gen >= 9) {
/* use scaler when colorkey is not required */
if (state->ckey.flags == I915_SET_COLORKEY_NONE) {
min_scale = 1;
max_scale = skl_max_scale(to_intel_crtc(crtc), crtc_state);
}
can_position = true;
}
return drm_plane_helper_check_update(plane, crtc, fb, &state->src,
&state->dst, &state->clip,
state->base.rotation,
min_scale, max_scale,
can_position, true,
&state->visible);
}
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
static void intel_begin_crtc_commit(struct drm_crtc *crtc,
struct drm_crtc_state *old_crtc_state)
{
struct drm_device *dev = crtc->dev;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_crtc_state *old_intel_state =
to_intel_crtc_state(old_crtc_state);
bool modeset = needs_modeset(crtc->state);
/* Perform vblank evasion around commit operation */
intel_pipe_update_start(intel_crtc);
if (modeset)
return;
if (crtc->state->color_mgmt_changed || to_intel_crtc_state(crtc->state)->update_pipe) {
intel_color_set_csc(crtc->state);
intel_color_load_luts(crtc->state);
}
if (to_intel_crtc_state(crtc->state)->update_pipe)
intel_update_pipe_config(intel_crtc, old_intel_state);
else if (INTEL_INFO(dev)->gen >= 9)
skl_detach_scalers(intel_crtc);
}
static void intel_finish_crtc_commit(struct drm_crtc *crtc,
struct drm_crtc_state *old_crtc_state)
{
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
intel_pipe_update_end(intel_crtc, NULL);
}
drm/i915: Make all plane disables use 'update_plane' (v5) If we extend the commit_plane handlers for each plane type to be able to handle fb=0, then we can easily implement plane disable via the update_plane handler. The cursor plane already works this way, and this is the direction we need to go to integrate with the atomic plane handler. We can now kill off the type-specific disable functions, as well as the redundant intel_plane_disable() (not to be confused with intel_disable_plane()). Note that prepare_plane_fb() only gets called as part of update_plane when fb!=NULL (by design, to match the semantics of the atomic plane helpers); this means that our commit_plane handlers need to handle the frontbuffer tracking for the disable case, even though they don't handle it for normal updates. v2: - Change BUG_ON to WARN_ON (Ander/Daniel) v3: - Drop unnecessary plane->crtc check since a previous patch to plane update ensures that plane->crtc will always be non-NULL, even for disable calls that might pass NULL from userspace. (Ander) - Drop a s/crtc/plane->crtc/ hunk that was unnecessary. (Ander) v4: - Fix missing whitespace (Ander) v5: - Use state's crtc rather than plane's crtc in intel_check_primary_plane(). plane->crtc could be NULL, but we've already fixed up state->crtc to ensure it's non-NULL (even if userspace passed it as NULL during a disable call). (Ander) Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-12-04 10:27:42 -08:00
/**
* intel_plane_destroy - destroy a plane
* @plane: plane to destroy
drm/i915: Make all plane disables use 'update_plane' (v5) If we extend the commit_plane handlers for each plane type to be able to handle fb=0, then we can easily implement plane disable via the update_plane handler. The cursor plane already works this way, and this is the direction we need to go to integrate with the atomic plane handler. We can now kill off the type-specific disable functions, as well as the redundant intel_plane_disable() (not to be confused with intel_disable_plane()). Note that prepare_plane_fb() only gets called as part of update_plane when fb!=NULL (by design, to match the semantics of the atomic plane helpers); this means that our commit_plane handlers need to handle the frontbuffer tracking for the disable case, even though they don't handle it for normal updates. v2: - Change BUG_ON to WARN_ON (Ander/Daniel) v3: - Drop unnecessary plane->crtc check since a previous patch to plane update ensures that plane->crtc will always be non-NULL, even for disable calls that might pass NULL from userspace. (Ander) - Drop a s/crtc/plane->crtc/ hunk that was unnecessary. (Ander) v4: - Fix missing whitespace (Ander) v5: - Use state's crtc rather than plane's crtc in intel_check_primary_plane(). plane->crtc could be NULL, but we've already fixed up state->crtc to ensure it's non-NULL (even if userspace passed it as NULL during a disable call). (Ander) Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-12-04 10:27:42 -08:00
*
* Common destruction function for all types of planes (primary, cursor,
* sprite).
drm/i915: Make all plane disables use 'update_plane' (v5) If we extend the commit_plane handlers for each plane type to be able to handle fb=0, then we can easily implement plane disable via the update_plane handler. The cursor plane already works this way, and this is the direction we need to go to integrate with the atomic plane handler. We can now kill off the type-specific disable functions, as well as the redundant intel_plane_disable() (not to be confused with intel_disable_plane()). Note that prepare_plane_fb() only gets called as part of update_plane when fb!=NULL (by design, to match the semantics of the atomic plane helpers); this means that our commit_plane handlers need to handle the frontbuffer tracking for the disable case, even though they don't handle it for normal updates. v2: - Change BUG_ON to WARN_ON (Ander/Daniel) v3: - Drop unnecessary plane->crtc check since a previous patch to plane update ensures that plane->crtc will always be non-NULL, even for disable calls that might pass NULL from userspace. (Ander) - Drop a s/crtc/plane->crtc/ hunk that was unnecessary. (Ander) v4: - Fix missing whitespace (Ander) v5: - Use state's crtc rather than plane's crtc in intel_check_primary_plane(). plane->crtc could be NULL, but we've already fixed up state->crtc to ensure it's non-NULL (even if userspace passed it as NULL during a disable call). (Ander) Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-12-04 10:27:42 -08:00
*/
void intel_plane_destroy(struct drm_plane *plane)
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
{
if (!plane)
return;
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
drm_plane_cleanup(plane);
kfree(to_intel_plane(plane));
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
}
const struct drm_plane_funcs intel_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
drm/i915: Switch to unified plane cursor handling (v4) The DRM core will translate calls to legacy cursor ioctls into universal cursor calls automatically, so there's no need to maintain the legacy cursor support. This greatly simplifies the transition since we don't have to handle reference counting differently depending on which cursor interface was called. The aim here is to transition to the universal plane interface with minimal code change. There's a lot of cleanup that can be done (e.g., using state stored in crtc->cursor->fb rather than intel_crtc) that is left to future patches. v4: - Drop drm_gem_object_unreference() that is no longer needed now that we receive the GEM obj directly rather than looking up the ID. v3: - Pass cursor obj to intel_crtc_cursor_set_obj() if cursor fb changes, even if 'visible' is false. intel_crtc_cursor_set_obj() will notice that the cursor isn't visible and disable it properly, but we still need to get intel_crtc->cursor_addr set properly so that we behave properly if the cursor becomes visible again in the future without changing the cursor buffer (noted by Chris Wilson and verified via i-g-t kms_cursor_crc). - s/drm_plane_init/drm_universal_plane_init/. Due to type compatibility between enum and bool, everything actually works correctly with the wrong init call, except for the type of plane that gets exposed to userspace (it shows up as type 'primary' rather than type 'cursor'). v2: - Remove duplicate dimension checks on cursor - Drop explicit cursor disable from crtc destroy (fb & plane destruction will take care of that now) - Use DRM plane helper to check update parameters Cc: intel-gfx@lists.freedesktop.org Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Pallavi G<pallavi.g@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-10 08:28:13 -07:00
.destroy = intel_plane_destroy,
.set_property = drm_atomic_helper_plane_set_property,
.atomic_get_property = intel_plane_atomic_get_property,
.atomic_set_property = intel_plane_atomic_set_property,
drm/i915: Move to atomic plane helpers (v9) Switch plane handling to use the atomic plane helpers. This means that rather than provide our own implementations of .update_plane() and .disable_plane(), we expose the lower-level check/prepare/commit/cleanup entrypoints and let the DRM core implement update/disable for us using those entrypoints. The other main change that falls out of this patch is that our drm_plane's will now always have a valid plane->state that contains the relevant plane state (initial state is allocated at plane creation). The base drm_plane_state pointed to holds the requested source/dest coordinates, and the subclassed intel_plane_state holds the adjusted values that our driver actually uses. v2: - Renamed file from intel_atomic.c to intel_atomic_plane.c (Daniel) - Fix a copy/paste comment mistake (Bob) v3: - Use prepare/cleanup functions that we've already factored out - Use newly refactored pre_commit/commit/post_commit to avoid sleeping during vblank evasion v4: - Rebase to latest di-nightly requires adding an 'old_state' parameter to atomic_update; v5: - Must have botched a rebase somewhere and lost some work. Restore state 'dirty' flag to let begin/end code know which planes to run the pre_commit/post_commit hooks for. This would have actually shown up as broken in the next commit rather than this one. v6: - Squash kerneldoc patch into this one. - Previous patches have now already taken care of most of the infrastructure that used to be in this patch. All we're adding here now is some thin wrappers. v7: - Check return of intel_plane_duplicate_state() for allocation failures. v8: - Drop unused drm_plane_state -> intel_plane_state cast. (Ander) - Squash in actual transition to plane helpers. Significant refactoring earlier in the patchset has made the combined prep+transition much easier to swallow than it was in earlier iterations. (Ander) v9: - s/track_fbs/disabled_planes/ in the atomic crtc flags. The only fb's we need to update frontbuffer tracking for are those on a plane about to be disabled (since the atomic helpers never call prepare_fb() when disabling a plane), so the new name more accurately describes what we're actually tracking. Testcase: igt/kms_plane Testcase: igt/kms_universal_plane Testcase: igt/kms_cursor_crc Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-12-23 10:41:52 -08:00
.atomic_duplicate_state = intel_plane_duplicate_state,
.atomic_destroy_state = intel_plane_destroy_state,
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
};
static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
int pipe)
{
struct intel_plane *primary = NULL;
struct intel_plane_state *state = NULL;
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
const uint32_t *intel_primary_formats;
unsigned int num_formats;
int ret;
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
primary = kzalloc(sizeof(*primary), GFP_KERNEL);
if (!primary)
goto fail;
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
state = intel_create_plane_state(&primary->base);
if (!state)
goto fail;
primary->base.state = &state->base;
drm/i915: Move to atomic plane helpers (v9) Switch plane handling to use the atomic plane helpers. This means that rather than provide our own implementations of .update_plane() and .disable_plane(), we expose the lower-level check/prepare/commit/cleanup entrypoints and let the DRM core implement update/disable for us using those entrypoints. The other main change that falls out of this patch is that our drm_plane's will now always have a valid plane->state that contains the relevant plane state (initial state is allocated at plane creation). The base drm_plane_state pointed to holds the requested source/dest coordinates, and the subclassed intel_plane_state holds the adjusted values that our driver actually uses. v2: - Renamed file from intel_atomic.c to intel_atomic_plane.c (Daniel) - Fix a copy/paste comment mistake (Bob) v3: - Use prepare/cleanup functions that we've already factored out - Use newly refactored pre_commit/commit/post_commit to avoid sleeping during vblank evasion v4: - Rebase to latest di-nightly requires adding an 'old_state' parameter to atomic_update; v5: - Must have botched a rebase somewhere and lost some work. Restore state 'dirty' flag to let begin/end code know which planes to run the pre_commit/post_commit hooks for. This would have actually shown up as broken in the next commit rather than this one. v6: - Squash kerneldoc patch into this one. - Previous patches have now already taken care of most of the infrastructure that used to be in this patch. All we're adding here now is some thin wrappers. v7: - Check return of intel_plane_duplicate_state() for allocation failures. v8: - Drop unused drm_plane_state -> intel_plane_state cast. (Ander) - Squash in actual transition to plane helpers. Significant refactoring earlier in the patchset has made the combined prep+transition much easier to swallow than it was in earlier iterations. (Ander) v9: - s/track_fbs/disabled_planes/ in the atomic crtc flags. The only fb's we need to update frontbuffer tracking for are those on a plane about to be disabled (since the atomic helpers never call prepare_fb() when disabling a plane), so the new name more accurately describes what we're actually tracking. Testcase: igt/kms_plane Testcase: igt/kms_universal_plane Testcase: igt/kms_cursor_crc Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-12-23 10:41:52 -08:00
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
primary->can_scale = false;
primary->max_downscale = 1;
if (INTEL_INFO(dev)->gen >= 9) {
primary->can_scale = true;
state->scaler_id = -1;
}
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
primary->pipe = pipe;
primary->plane = pipe;
primary->frontbuffer_bit = INTEL_FRONTBUFFER_PRIMARY(pipe);
primary->check_plane = intel_check_primary_plane;
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
if (HAS_FBC(dev) && INTEL_INFO(dev)->gen < 4)
primary->plane = !pipe;
if (INTEL_INFO(dev)->gen >= 9) {
intel_primary_formats = skl_primary_formats;
num_formats = ARRAY_SIZE(skl_primary_formats);
primary->update_plane = skylake_update_primary_plane;
primary->disable_plane = skylake_disable_primary_plane;
} else if (HAS_PCH_SPLIT(dev)) {
intel_primary_formats = i965_primary_formats;
num_formats = ARRAY_SIZE(i965_primary_formats);
primary->update_plane = ironlake_update_primary_plane;
primary->disable_plane = i9xx_disable_primary_plane;
} else if (INTEL_INFO(dev)->gen >= 4) {
intel_primary_formats = i965_primary_formats;
num_formats = ARRAY_SIZE(i965_primary_formats);
primary->update_plane = i9xx_update_primary_plane;
primary->disable_plane = i9xx_disable_primary_plane;
} else {
intel_primary_formats = i8xx_primary_formats;
num_formats = ARRAY_SIZE(i8xx_primary_formats);
primary->update_plane = i9xx_update_primary_plane;
primary->disable_plane = i9xx_disable_primary_plane;
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
}
if (INTEL_INFO(dev)->gen >= 9)
ret = drm_universal_plane_init(dev, &primary->base, 0,
&intel_plane_funcs,
intel_primary_formats, num_formats,
DRM_PLANE_TYPE_PRIMARY,
"plane 1%c", pipe_name(pipe));
else if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev))
ret = drm_universal_plane_init(dev, &primary->base, 0,
&intel_plane_funcs,
intel_primary_formats, num_formats,
DRM_PLANE_TYPE_PRIMARY,
"primary %c", pipe_name(pipe));
else
ret = drm_universal_plane_init(dev, &primary->base, 0,
&intel_plane_funcs,
intel_primary_formats, num_formats,
DRM_PLANE_TYPE_PRIMARY,
"plane %c", plane_name(primary->plane));
if (ret)
goto fail;
drm/i915: Add 180 degree primary plane rotation support Primary planes support 180 degree rotation. Expose the feature through rotation drm property. v2: Calculating linear/tiled offsets based on pipe source width and height. Added 180 degree rotation support in ironlake_update_plane. v3: Checking if CRTC is active before issueing update_plane. Added wait for vblank to make sure we dont overtake page flips. Disabling FBC since it does not work with rotated planes. v4: Updated rotation checks for pending flips, fbc disable. Creating rotation property only for Gen4 onwards. Property resetting as part of lastclose. v5: Resetting property in i915_driver_lastclose properly for planes and crtcs. Fixed linear offset calculation that was off by 1 w.r.t width in i9xx_update_plane and ironlake_update_plane. Removed tab based indentation and unnecessary braces in intel_crtc_set_property and intel_update_fbc. FBC and flip related checks should be done only for valid crtcs. v6: Minor nits in FBC disable checks for comments in intel_crtc_set_property and positioning the disable code in intel_update_fbc. v7: In case rotation property on inactive crtc is updated, we return successfully printing debug log as crtc is inactive and only property change is preserved. v8: update_plane is changed to update_primary_plane, crtc->fb is changed to crtc->primary->fb and return value of update_primary_plane is ignored. v9: added rotation property to primary plane instead of crtc. Removing reset of rotation property from lastclose. rotation_property is moved to drm_mode_config, so drm layer will take care of resetting. Adding updation of fbc when rotation is set to 0. Allowing rotation only if value is different than old one. v10: Calling intel_primary_plane_setplane instead of update_primary_plane in set_property(Daniel). v11: Using same set_property function for both primary and sprite, Adding primary plane specific code in the same function (Matt). v12: Removing disabling/ enabling of fbc from set_property because it is done from intel_pipe_set_base. Other formatting v13: we need to call disable_fbc before changing the rotation to 180, disable_fbc from intel_pipe_set_base gets called very late, that will be used to re-enable fbc if rotation is set to 0 (Ville). Testcase: igt/kms_rotation_crc Signed-off-by: Uma Shankar <uma.shankar@intel.com> Signed-off-by: Sagar Kamble <sagar.a.kamble@intel.com> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com> [danvet: Add FIXME to explain why we need the open-coded update_fbc hunk to disable fbc when rotated 180 degree. And make checkpatch happier.] Acked-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-08-22 14:06:04 +05:30
if (INTEL_INFO(dev)->gen >= 4)
intel_create_rotation_property(dev, primary);
drm/i915: Add 180 degree primary plane rotation support Primary planes support 180 degree rotation. Expose the feature through rotation drm property. v2: Calculating linear/tiled offsets based on pipe source width and height. Added 180 degree rotation support in ironlake_update_plane. v3: Checking if CRTC is active before issueing update_plane. Added wait for vblank to make sure we dont overtake page flips. Disabling FBC since it does not work with rotated planes. v4: Updated rotation checks for pending flips, fbc disable. Creating rotation property only for Gen4 onwards. Property resetting as part of lastclose. v5: Resetting property in i915_driver_lastclose properly for planes and crtcs. Fixed linear offset calculation that was off by 1 w.r.t width in i9xx_update_plane and ironlake_update_plane. Removed tab based indentation and unnecessary braces in intel_crtc_set_property and intel_update_fbc. FBC and flip related checks should be done only for valid crtcs. v6: Minor nits in FBC disable checks for comments in intel_crtc_set_property and positioning the disable code in intel_update_fbc. v7: In case rotation property on inactive crtc is updated, we return successfully printing debug log as crtc is inactive and only property change is preserved. v8: update_plane is changed to update_primary_plane, crtc->fb is changed to crtc->primary->fb and return value of update_primary_plane is ignored. v9: added rotation property to primary plane instead of crtc. Removing reset of rotation property from lastclose. rotation_property is moved to drm_mode_config, so drm layer will take care of resetting. Adding updation of fbc when rotation is set to 0. Allowing rotation only if value is different than old one. v10: Calling intel_primary_plane_setplane instead of update_primary_plane in set_property(Daniel). v11: Using same set_property function for both primary and sprite, Adding primary plane specific code in the same function (Matt). v12: Removing disabling/ enabling of fbc from set_property because it is done from intel_pipe_set_base. Other formatting v13: we need to call disable_fbc before changing the rotation to 180, disable_fbc from intel_pipe_set_base gets called very late, that will be used to re-enable fbc if rotation is set to 0 (Ville). Testcase: igt/kms_rotation_crc Signed-off-by: Uma Shankar <uma.shankar@intel.com> Signed-off-by: Sagar Kamble <sagar.a.kamble@intel.com> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com> [danvet: Add FIXME to explain why we need the open-coded update_fbc hunk to disable fbc when rotated 180 degree. And make checkpatch happier.] Acked-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-08-22 14:06:04 +05:30
drm/i915: Move to atomic plane helpers (v9) Switch plane handling to use the atomic plane helpers. This means that rather than provide our own implementations of .update_plane() and .disable_plane(), we expose the lower-level check/prepare/commit/cleanup entrypoints and let the DRM core implement update/disable for us using those entrypoints. The other main change that falls out of this patch is that our drm_plane's will now always have a valid plane->state that contains the relevant plane state (initial state is allocated at plane creation). The base drm_plane_state pointed to holds the requested source/dest coordinates, and the subclassed intel_plane_state holds the adjusted values that our driver actually uses. v2: - Renamed file from intel_atomic.c to intel_atomic_plane.c (Daniel) - Fix a copy/paste comment mistake (Bob) v3: - Use prepare/cleanup functions that we've already factored out - Use newly refactored pre_commit/commit/post_commit to avoid sleeping during vblank evasion v4: - Rebase to latest di-nightly requires adding an 'old_state' parameter to atomic_update; v5: - Must have botched a rebase somewhere and lost some work. Restore state 'dirty' flag to let begin/end code know which planes to run the pre_commit/post_commit hooks for. This would have actually shown up as broken in the next commit rather than this one. v6: - Squash kerneldoc patch into this one. - Previous patches have now already taken care of most of the infrastructure that used to be in this patch. All we're adding here now is some thin wrappers. v7: - Check return of intel_plane_duplicate_state() for allocation failures. v8: - Drop unused drm_plane_state -> intel_plane_state cast. (Ander) - Squash in actual transition to plane helpers. Significant refactoring earlier in the patchset has made the combined prep+transition much easier to swallow than it was in earlier iterations. (Ander) v9: - s/track_fbs/disabled_planes/ in the atomic crtc flags. The only fb's we need to update frontbuffer tracking for are those on a plane about to be disabled (since the atomic helpers never call prepare_fb() when disabling a plane), so the new name more accurately describes what we're actually tracking. Testcase: igt/kms_plane Testcase: igt/kms_universal_plane Testcase: igt/kms_cursor_crc Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-12-23 10:41:52 -08:00
drm_plane_helper_add(&primary->base, &intel_plane_helper_funcs);
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
return &primary->base;
fail:
kfree(state);
kfree(primary);
return NULL;
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
}
void intel_create_rotation_property(struct drm_device *dev, struct intel_plane *plane)
{
if (!dev->mode_config.rotation_property) {
unsigned long flags = BIT(DRM_ROTATE_0) |
BIT(DRM_ROTATE_180);
if (INTEL_INFO(dev)->gen >= 9)
flags |= BIT(DRM_ROTATE_90) | BIT(DRM_ROTATE_270);
dev->mode_config.rotation_property =
drm_mode_create_rotation_property(dev, flags);
}
if (dev->mode_config.rotation_property)
drm_object_attach_property(&plane->base.base,
dev->mode_config.rotation_property,
plane->base.state->rotation);
}
drm/i915: Switch to unified plane cursor handling (v4) The DRM core will translate calls to legacy cursor ioctls into universal cursor calls automatically, so there's no need to maintain the legacy cursor support. This greatly simplifies the transition since we don't have to handle reference counting differently depending on which cursor interface was called. The aim here is to transition to the universal plane interface with minimal code change. There's a lot of cleanup that can be done (e.g., using state stored in crtc->cursor->fb rather than intel_crtc) that is left to future patches. v4: - Drop drm_gem_object_unreference() that is no longer needed now that we receive the GEM obj directly rather than looking up the ID. v3: - Pass cursor obj to intel_crtc_cursor_set_obj() if cursor fb changes, even if 'visible' is false. intel_crtc_cursor_set_obj() will notice that the cursor isn't visible and disable it properly, but we still need to get intel_crtc->cursor_addr set properly so that we behave properly if the cursor becomes visible again in the future without changing the cursor buffer (noted by Chris Wilson and verified via i-g-t kms_cursor_crc). - s/drm_plane_init/drm_universal_plane_init/. Due to type compatibility between enum and bool, everything actually works correctly with the wrong init call, except for the type of plane that gets exposed to userspace (it shows up as type 'primary' rather than type 'cursor'). v2: - Remove duplicate dimension checks on cursor - Drop explicit cursor disable from crtc destroy (fb & plane destruction will take care of that now) - Use DRM plane helper to check update parameters Cc: intel-gfx@lists.freedesktop.org Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Pallavi G<pallavi.g@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-10 08:28:13 -07:00
static int
intel_check_cursor_plane(struct drm_plane *plane,
struct intel_crtc_state *crtc_state,
struct intel_plane_state *state)
drm/i915: Switch to unified plane cursor handling (v4) The DRM core will translate calls to legacy cursor ioctls into universal cursor calls automatically, so there's no need to maintain the legacy cursor support. This greatly simplifies the transition since we don't have to handle reference counting differently depending on which cursor interface was called. The aim here is to transition to the universal plane interface with minimal code change. There's a lot of cleanup that can be done (e.g., using state stored in crtc->cursor->fb rather than intel_crtc) that is left to future patches. v4: - Drop drm_gem_object_unreference() that is no longer needed now that we receive the GEM obj directly rather than looking up the ID. v3: - Pass cursor obj to intel_crtc_cursor_set_obj() if cursor fb changes, even if 'visible' is false. intel_crtc_cursor_set_obj() will notice that the cursor isn't visible and disable it properly, but we still need to get intel_crtc->cursor_addr set properly so that we behave properly if the cursor becomes visible again in the future without changing the cursor buffer (noted by Chris Wilson and verified via i-g-t kms_cursor_crc). - s/drm_plane_init/drm_universal_plane_init/. Due to type compatibility between enum and bool, everything actually works correctly with the wrong init call, except for the type of plane that gets exposed to userspace (it shows up as type 'primary' rather than type 'cursor'). v2: - Remove duplicate dimension checks on cursor - Drop explicit cursor disable from crtc destroy (fb & plane destruction will take care of that now) - Use DRM plane helper to check update parameters Cc: intel-gfx@lists.freedesktop.org Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Pallavi G<pallavi.g@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-10 08:28:13 -07:00
{
struct drm_crtc *crtc = crtc_state->base.crtc;
struct drm_framebuffer *fb = state->base.fb;
struct drm_i915_gem_object *obj = intel_fb_obj(fb);
drm/i915: Workaround CHV pipe C cursor fail Turns out CHV pipe C was glued on somewhat poorly, and there's something wrong with the cursor. If the cursor straddles the left screen edge, and is then moved away from the edge or disabled, the pipe will often underrun. If enough underruns are triggered quickly enough the pipe will fall over and die (it just scans out a solid color and reports a constant underrun). We need to turn the disp2d power well off and on again to recover the pipe. None of that is very nice for the user, so let's just refuse to place the cursor in the compromised position. The ddx appears to fall back to swcursor when the ioctl returns an error, so theoretically there's no loss of functionality for the user (discounting swcursor bugs). I suppose most cursors images actually have the hotspot not exactly at 0,0 so under typical conditions the fallback will in fact kick in as soon as the cursor touches the left edge of the screen. Any atomic compositor should anyway be prepared to fall back to GPU composition when things don't work out, so there should be no problem with those. Other things that I tried to solve this include flipping all display related clock gating knobs I could find, increasing the minimum gtt alignment all the way up to 512k. I also tried to see if there are more specific screen coordinates that hit the bug, but the findings were somewhat inconclusive. Sometimes the failures happen almost across the whole left edge, sometimes more at the very top and around the bottom half. I wasn't able to find any real pattern to these variations, so it seems our only choice is to just refuse to straddle the left screen edge at all. Cc: stable@vger.kernel.org Cc: Jason Plum <max@warheads.net> Testcase: igt/kms_chv_cursor_fail Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92826 Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1450459479-16286-1-git-send-email-ville.syrjala@linux.intel.com Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-12-18 19:24:39 +02:00
enum pipe pipe = to_intel_plane(plane)->pipe;
unsigned stride;
int ret;
drm/i915: Switch to unified plane cursor handling (v4) The DRM core will translate calls to legacy cursor ioctls into universal cursor calls automatically, so there's no need to maintain the legacy cursor support. This greatly simplifies the transition since we don't have to handle reference counting differently depending on which cursor interface was called. The aim here is to transition to the universal plane interface with minimal code change. There's a lot of cleanup that can be done (e.g., using state stored in crtc->cursor->fb rather than intel_crtc) that is left to future patches. v4: - Drop drm_gem_object_unreference() that is no longer needed now that we receive the GEM obj directly rather than looking up the ID. v3: - Pass cursor obj to intel_crtc_cursor_set_obj() if cursor fb changes, even if 'visible' is false. intel_crtc_cursor_set_obj() will notice that the cursor isn't visible and disable it properly, but we still need to get intel_crtc->cursor_addr set properly so that we behave properly if the cursor becomes visible again in the future without changing the cursor buffer (noted by Chris Wilson and verified via i-g-t kms_cursor_crc). - s/drm_plane_init/drm_universal_plane_init/. Due to type compatibility between enum and bool, everything actually works correctly with the wrong init call, except for the type of plane that gets exposed to userspace (it shows up as type 'primary' rather than type 'cursor'). v2: - Remove duplicate dimension checks on cursor - Drop explicit cursor disable from crtc destroy (fb & plane destruction will take care of that now) - Use DRM plane helper to check update parameters Cc: intel-gfx@lists.freedesktop.org Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Pallavi G<pallavi.g@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-10 08:28:13 -07:00
ret = drm_plane_helper_check_update(plane, crtc, fb, &state->src,
&state->dst, &state->clip,
state->base.rotation,
drm/i915: Switch to unified plane cursor handling (v4) The DRM core will translate calls to legacy cursor ioctls into universal cursor calls automatically, so there's no need to maintain the legacy cursor support. This greatly simplifies the transition since we don't have to handle reference counting differently depending on which cursor interface was called. The aim here is to transition to the universal plane interface with minimal code change. There's a lot of cleanup that can be done (e.g., using state stored in crtc->cursor->fb rather than intel_crtc) that is left to future patches. v4: - Drop drm_gem_object_unreference() that is no longer needed now that we receive the GEM obj directly rather than looking up the ID. v3: - Pass cursor obj to intel_crtc_cursor_set_obj() if cursor fb changes, even if 'visible' is false. intel_crtc_cursor_set_obj() will notice that the cursor isn't visible and disable it properly, but we still need to get intel_crtc->cursor_addr set properly so that we behave properly if the cursor becomes visible again in the future without changing the cursor buffer (noted by Chris Wilson and verified via i-g-t kms_cursor_crc). - s/drm_plane_init/drm_universal_plane_init/. Due to type compatibility between enum and bool, everything actually works correctly with the wrong init call, except for the type of plane that gets exposed to userspace (it shows up as type 'primary' rather than type 'cursor'). v2: - Remove duplicate dimension checks on cursor - Drop explicit cursor disable from crtc destroy (fb & plane destruction will take care of that now) - Use DRM plane helper to check update parameters Cc: intel-gfx@lists.freedesktop.org Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Pallavi G<pallavi.g@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-10 08:28:13 -07:00
DRM_PLANE_HELPER_NO_SCALING,
DRM_PLANE_HELPER_NO_SCALING,
true, true, &state->visible);
if (ret)
return ret;
/* if we want to turn off the cursor ignore width and height */
if (!obj)
return 0;
/* Check for which cursor types we support */
if (!cursor_size_ok(plane->dev, state->base.crtc_w, state->base.crtc_h)) {
drm/i915: Move to atomic plane helpers (v9) Switch plane handling to use the atomic plane helpers. This means that rather than provide our own implementations of .update_plane() and .disable_plane(), we expose the lower-level check/prepare/commit/cleanup entrypoints and let the DRM core implement update/disable for us using those entrypoints. The other main change that falls out of this patch is that our drm_plane's will now always have a valid plane->state that contains the relevant plane state (initial state is allocated at plane creation). The base drm_plane_state pointed to holds the requested source/dest coordinates, and the subclassed intel_plane_state holds the adjusted values that our driver actually uses. v2: - Renamed file from intel_atomic.c to intel_atomic_plane.c (Daniel) - Fix a copy/paste comment mistake (Bob) v3: - Use prepare/cleanup functions that we've already factored out - Use newly refactored pre_commit/commit/post_commit to avoid sleeping during vblank evasion v4: - Rebase to latest di-nightly requires adding an 'old_state' parameter to atomic_update; v5: - Must have botched a rebase somewhere and lost some work. Restore state 'dirty' flag to let begin/end code know which planes to run the pre_commit/post_commit hooks for. This would have actually shown up as broken in the next commit rather than this one. v6: - Squash kerneldoc patch into this one. - Previous patches have now already taken care of most of the infrastructure that used to be in this patch. All we're adding here now is some thin wrappers. v7: - Check return of intel_plane_duplicate_state() for allocation failures. v8: - Drop unused drm_plane_state -> intel_plane_state cast. (Ander) - Squash in actual transition to plane helpers. Significant refactoring earlier in the patchset has made the combined prep+transition much easier to swallow than it was in earlier iterations. (Ander) v9: - s/track_fbs/disabled_planes/ in the atomic crtc flags. The only fb's we need to update frontbuffer tracking for are those on a plane about to be disabled (since the atomic helpers never call prepare_fb() when disabling a plane), so the new name more accurately describes what we're actually tracking. Testcase: igt/kms_plane Testcase: igt/kms_universal_plane Testcase: igt/kms_cursor_crc Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-12-23 10:41:52 -08:00
DRM_DEBUG("Cursor dimension %dx%d not supported\n",
state->base.crtc_w, state->base.crtc_h);
return -EINVAL;
}
drm/i915: Move to atomic plane helpers (v9) Switch plane handling to use the atomic plane helpers. This means that rather than provide our own implementations of .update_plane() and .disable_plane(), we expose the lower-level check/prepare/commit/cleanup entrypoints and let the DRM core implement update/disable for us using those entrypoints. The other main change that falls out of this patch is that our drm_plane's will now always have a valid plane->state that contains the relevant plane state (initial state is allocated at plane creation). The base drm_plane_state pointed to holds the requested source/dest coordinates, and the subclassed intel_plane_state holds the adjusted values that our driver actually uses. v2: - Renamed file from intel_atomic.c to intel_atomic_plane.c (Daniel) - Fix a copy/paste comment mistake (Bob) v3: - Use prepare/cleanup functions that we've already factored out - Use newly refactored pre_commit/commit/post_commit to avoid sleeping during vblank evasion v4: - Rebase to latest di-nightly requires adding an 'old_state' parameter to atomic_update; v5: - Must have botched a rebase somewhere and lost some work. Restore state 'dirty' flag to let begin/end code know which planes to run the pre_commit/post_commit hooks for. This would have actually shown up as broken in the next commit rather than this one. v6: - Squash kerneldoc patch into this one. - Previous patches have now already taken care of most of the infrastructure that used to be in this patch. All we're adding here now is some thin wrappers. v7: - Check return of intel_plane_duplicate_state() for allocation failures. v8: - Drop unused drm_plane_state -> intel_plane_state cast. (Ander) - Squash in actual transition to plane helpers. Significant refactoring earlier in the patchset has made the combined prep+transition much easier to swallow than it was in earlier iterations. (Ander) v9: - s/track_fbs/disabled_planes/ in the atomic crtc flags. The only fb's we need to update frontbuffer tracking for are those on a plane about to be disabled (since the atomic helpers never call prepare_fb() when disabling a plane), so the new name more accurately describes what we're actually tracking. Testcase: igt/kms_plane Testcase: igt/kms_universal_plane Testcase: igt/kms_cursor_crc Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-12-23 10:41:52 -08:00
stride = roundup_pow_of_two(state->base.crtc_w) * 4;
if (obj->base.size < stride * state->base.crtc_h) {
DRM_DEBUG_KMS("buffer is too small\n");
return -ENOMEM;
}
if (fb->modifier[0] != DRM_FORMAT_MOD_NONE) {
DRM_DEBUG_KMS("cursor cannot be tiled\n");
return -EINVAL;
drm/i915: Refactor work that can sleep out of commit (v7) Once we integrate our work into the atomic pipeline, plane commit operations will need to happen with interrupts disabled, due to vblank evasion. Our commit functions today include sleepable work, so those operations need to be split out and run either before or after the atomic register programming. The solution here calculates which of those operations will need to be performed during the 'check' phase and sets flags in an intel_crtc sub-struct. New intel_begin_crtc_commit() and intel_finish_crtc_commit() functions are added before and after the actual register programming; these will eventually be called from the atomic plane helper's .atomic_begin() and .atomic_end() entrypoints. v2: Fix broken sprite code split v3: Make the pre/post commit work crtc-based to match how we eventually want this to be called from the atomic plane helpers. v4: Some platforms that haven't had their watermark code reworked were waiting for vblank, then calling update_sprite_watermarks in their platform-specific disable code. These also need to be flagged out of the critical section. v5: Sprite plane test for primary show/hide should just set the flag to wait for pending flips, not actually perform the wait. (Ander) v6: - Rebase onto latest di-nightly; picks up an important runtime PM fix. - Handle 'wait_for_flips' flag in intel_begin_crtc_commit(). (Ander) - Use wait_for_flips flag for primary plane update rather than performing the wait in the check routine. - Added kerneldoc to pre_disable/post_enable functions that are no longer static. (Ander) - Replace assert_pipe_enabled() in intel_disable_primary_hw_plane() with an intel_crtc->active test; it turns out assert_pipe_enabled() grabs some mutexes and can sleep, which we can't do with interrupts disabled. v7: - Check for fb != NULL when deciding whether the sprite plane hides the primary plane during a sprite update. (PRTS) Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-12-24 07:59:06 -08:00
}
drm/i915: Workaround CHV pipe C cursor fail Turns out CHV pipe C was glued on somewhat poorly, and there's something wrong with the cursor. If the cursor straddles the left screen edge, and is then moved away from the edge or disabled, the pipe will often underrun. If enough underruns are triggered quickly enough the pipe will fall over and die (it just scans out a solid color and reports a constant underrun). We need to turn the disp2d power well off and on again to recover the pipe. None of that is very nice for the user, so let's just refuse to place the cursor in the compromised position. The ddx appears to fall back to swcursor when the ioctl returns an error, so theoretically there's no loss of functionality for the user (discounting swcursor bugs). I suppose most cursors images actually have the hotspot not exactly at 0,0 so under typical conditions the fallback will in fact kick in as soon as the cursor touches the left edge of the screen. Any atomic compositor should anyway be prepared to fall back to GPU composition when things don't work out, so there should be no problem with those. Other things that I tried to solve this include flipping all display related clock gating knobs I could find, increasing the minimum gtt alignment all the way up to 512k. I also tried to see if there are more specific screen coordinates that hit the bug, but the findings were somewhat inconclusive. Sometimes the failures happen almost across the whole left edge, sometimes more at the very top and around the bottom half. I wasn't able to find any real pattern to these variations, so it seems our only choice is to just refuse to straddle the left screen edge at all. Cc: stable@vger.kernel.org Cc: Jason Plum <max@warheads.net> Testcase: igt/kms_chv_cursor_fail Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92826 Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1450459479-16286-1-git-send-email-ville.syrjala@linux.intel.com Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-12-18 19:24:39 +02:00
/*
* There's something wrong with the cursor on CHV pipe C.
* If it straddles the left edge of the screen then
* moving it away from the edge or disabling it often
* results in a pipe underrun, and often that can lead to
* dead pipe (constant underrun reported, and it scans
* out just a solid color). To recover from that, the
* display power well must be turned off and on again.
* Refuse the put the cursor into that compromised position.
*/
if (IS_CHERRYVIEW(plane->dev) && pipe == PIPE_C &&
state->visible && state->base.crtc_x < 0) {
DRM_DEBUG_KMS("CHV cursor C not allowed to straddle the left screen edge\n");
return -EINVAL;
}
return 0;
}
drm/i915: Switch to unified plane cursor handling (v4) The DRM core will translate calls to legacy cursor ioctls into universal cursor calls automatically, so there's no need to maintain the legacy cursor support. This greatly simplifies the transition since we don't have to handle reference counting differently depending on which cursor interface was called. The aim here is to transition to the universal plane interface with minimal code change. There's a lot of cleanup that can be done (e.g., using state stored in crtc->cursor->fb rather than intel_crtc) that is left to future patches. v4: - Drop drm_gem_object_unreference() that is no longer needed now that we receive the GEM obj directly rather than looking up the ID. v3: - Pass cursor obj to intel_crtc_cursor_set_obj() if cursor fb changes, even if 'visible' is false. intel_crtc_cursor_set_obj() will notice that the cursor isn't visible and disable it properly, but we still need to get intel_crtc->cursor_addr set properly so that we behave properly if the cursor becomes visible again in the future without changing the cursor buffer (noted by Chris Wilson and verified via i-g-t kms_cursor_crc). - s/drm_plane_init/drm_universal_plane_init/. Due to type compatibility between enum and bool, everything actually works correctly with the wrong init call, except for the type of plane that gets exposed to userspace (it shows up as type 'primary' rather than type 'cursor'). v2: - Remove duplicate dimension checks on cursor - Drop explicit cursor disable from crtc destroy (fb & plane destruction will take care of that now) - Use DRM plane helper to check update parameters Cc: intel-gfx@lists.freedesktop.org Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Pallavi G<pallavi.g@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-10 08:28:13 -07:00
static void
intel_disable_cursor_plane(struct drm_plane *plane,
struct drm_crtc *crtc)
{
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
intel_crtc->cursor_addr = 0;
intel_crtc_update_cursor(crtc, NULL);
}
static void
intel_update_cursor_plane(struct drm_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *state)
{
struct drm_crtc *crtc = crtc_state->base.crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
drm/i915: Move to atomic plane helpers (v9) Switch plane handling to use the atomic plane helpers. This means that rather than provide our own implementations of .update_plane() and .disable_plane(), we expose the lower-level check/prepare/commit/cleanup entrypoints and let the DRM core implement update/disable for us using those entrypoints. The other main change that falls out of this patch is that our drm_plane's will now always have a valid plane->state that contains the relevant plane state (initial state is allocated at plane creation). The base drm_plane_state pointed to holds the requested source/dest coordinates, and the subclassed intel_plane_state holds the adjusted values that our driver actually uses. v2: - Renamed file from intel_atomic.c to intel_atomic_plane.c (Daniel) - Fix a copy/paste comment mistake (Bob) v3: - Use prepare/cleanup functions that we've already factored out - Use newly refactored pre_commit/commit/post_commit to avoid sleeping during vblank evasion v4: - Rebase to latest di-nightly requires adding an 'old_state' parameter to atomic_update; v5: - Must have botched a rebase somewhere and lost some work. Restore state 'dirty' flag to let begin/end code know which planes to run the pre_commit/post_commit hooks for. This would have actually shown up as broken in the next commit rather than this one. v6: - Squash kerneldoc patch into this one. - Previous patches have now already taken care of most of the infrastructure that used to be in this patch. All we're adding here now is some thin wrappers. v7: - Check return of intel_plane_duplicate_state() for allocation failures. v8: - Drop unused drm_plane_state -> intel_plane_state cast. (Ander) - Squash in actual transition to plane helpers. Significant refactoring earlier in the patchset has made the combined prep+transition much easier to swallow than it was in earlier iterations. (Ander) v9: - s/track_fbs/disabled_planes/ in the atomic crtc flags. The only fb's we need to update frontbuffer tracking for are those on a plane about to be disabled (since the atomic helpers never call prepare_fb() when disabling a plane), so the new name more accurately describes what we're actually tracking. Testcase: igt/kms_plane Testcase: igt/kms_universal_plane Testcase: igt/kms_cursor_crc Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-12-23 10:41:52 -08:00
struct drm_device *dev = plane->dev;
struct drm_i915_gem_object *obj = intel_fb_obj(state->base.fb);
uint32_t addr;
if (!obj)
addr = 0;
else if (!INTEL_INFO(dev)->cursor_needs_physical)
addr = i915_gem_obj_ggtt_offset(obj);
else
addr = obj->phys_handle->busaddr;
intel_crtc->cursor_addr = addr;
intel_crtc_update_cursor(crtc, state);
}
drm/i915: Switch to unified plane cursor handling (v4) The DRM core will translate calls to legacy cursor ioctls into universal cursor calls automatically, so there's no need to maintain the legacy cursor support. This greatly simplifies the transition since we don't have to handle reference counting differently depending on which cursor interface was called. The aim here is to transition to the universal plane interface with minimal code change. There's a lot of cleanup that can be done (e.g., using state stored in crtc->cursor->fb rather than intel_crtc) that is left to future patches. v4: - Drop drm_gem_object_unreference() that is no longer needed now that we receive the GEM obj directly rather than looking up the ID. v3: - Pass cursor obj to intel_crtc_cursor_set_obj() if cursor fb changes, even if 'visible' is false. intel_crtc_cursor_set_obj() will notice that the cursor isn't visible and disable it properly, but we still need to get intel_crtc->cursor_addr set properly so that we behave properly if the cursor becomes visible again in the future without changing the cursor buffer (noted by Chris Wilson and verified via i-g-t kms_cursor_crc). - s/drm_plane_init/drm_universal_plane_init/. Due to type compatibility between enum and bool, everything actually works correctly with the wrong init call, except for the type of plane that gets exposed to userspace (it shows up as type 'primary' rather than type 'cursor'). v2: - Remove duplicate dimension checks on cursor - Drop explicit cursor disable from crtc destroy (fb & plane destruction will take care of that now) - Use DRM plane helper to check update parameters Cc: intel-gfx@lists.freedesktop.org Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Pallavi G<pallavi.g@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-10 08:28:13 -07:00
static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev,
int pipe)
{
struct intel_plane *cursor = NULL;
struct intel_plane_state *state = NULL;
int ret;
drm/i915: Switch to unified plane cursor handling (v4) The DRM core will translate calls to legacy cursor ioctls into universal cursor calls automatically, so there's no need to maintain the legacy cursor support. This greatly simplifies the transition since we don't have to handle reference counting differently depending on which cursor interface was called. The aim here is to transition to the universal plane interface with minimal code change. There's a lot of cleanup that can be done (e.g., using state stored in crtc->cursor->fb rather than intel_crtc) that is left to future patches. v4: - Drop drm_gem_object_unreference() that is no longer needed now that we receive the GEM obj directly rather than looking up the ID. v3: - Pass cursor obj to intel_crtc_cursor_set_obj() if cursor fb changes, even if 'visible' is false. intel_crtc_cursor_set_obj() will notice that the cursor isn't visible and disable it properly, but we still need to get intel_crtc->cursor_addr set properly so that we behave properly if the cursor becomes visible again in the future without changing the cursor buffer (noted by Chris Wilson and verified via i-g-t kms_cursor_crc). - s/drm_plane_init/drm_universal_plane_init/. Due to type compatibility between enum and bool, everything actually works correctly with the wrong init call, except for the type of plane that gets exposed to userspace (it shows up as type 'primary' rather than type 'cursor'). v2: - Remove duplicate dimension checks on cursor - Drop explicit cursor disable from crtc destroy (fb & plane destruction will take care of that now) - Use DRM plane helper to check update parameters Cc: intel-gfx@lists.freedesktop.org Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Pallavi G<pallavi.g@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-10 08:28:13 -07:00
cursor = kzalloc(sizeof(*cursor), GFP_KERNEL);
if (!cursor)
goto fail;
drm/i915: Switch to unified plane cursor handling (v4) The DRM core will translate calls to legacy cursor ioctls into universal cursor calls automatically, so there's no need to maintain the legacy cursor support. This greatly simplifies the transition since we don't have to handle reference counting differently depending on which cursor interface was called. The aim here is to transition to the universal plane interface with minimal code change. There's a lot of cleanup that can be done (e.g., using state stored in crtc->cursor->fb rather than intel_crtc) that is left to future patches. v4: - Drop drm_gem_object_unreference() that is no longer needed now that we receive the GEM obj directly rather than looking up the ID. v3: - Pass cursor obj to intel_crtc_cursor_set_obj() if cursor fb changes, even if 'visible' is false. intel_crtc_cursor_set_obj() will notice that the cursor isn't visible and disable it properly, but we still need to get intel_crtc->cursor_addr set properly so that we behave properly if the cursor becomes visible again in the future without changing the cursor buffer (noted by Chris Wilson and verified via i-g-t kms_cursor_crc). - s/drm_plane_init/drm_universal_plane_init/. Due to type compatibility between enum and bool, everything actually works correctly with the wrong init call, except for the type of plane that gets exposed to userspace (it shows up as type 'primary' rather than type 'cursor'). v2: - Remove duplicate dimension checks on cursor - Drop explicit cursor disable from crtc destroy (fb & plane destruction will take care of that now) - Use DRM plane helper to check update parameters Cc: intel-gfx@lists.freedesktop.org Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Pallavi G<pallavi.g@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-10 08:28:13 -07:00
state = intel_create_plane_state(&cursor->base);
if (!state)
goto fail;
cursor->base.state = &state->base;
drm/i915: Move to atomic plane helpers (v9) Switch plane handling to use the atomic plane helpers. This means that rather than provide our own implementations of .update_plane() and .disable_plane(), we expose the lower-level check/prepare/commit/cleanup entrypoints and let the DRM core implement update/disable for us using those entrypoints. The other main change that falls out of this patch is that our drm_plane's will now always have a valid plane->state that contains the relevant plane state (initial state is allocated at plane creation). The base drm_plane_state pointed to holds the requested source/dest coordinates, and the subclassed intel_plane_state holds the adjusted values that our driver actually uses. v2: - Renamed file from intel_atomic.c to intel_atomic_plane.c (Daniel) - Fix a copy/paste comment mistake (Bob) v3: - Use prepare/cleanup functions that we've already factored out - Use newly refactored pre_commit/commit/post_commit to avoid sleeping during vblank evasion v4: - Rebase to latest di-nightly requires adding an 'old_state' parameter to atomic_update; v5: - Must have botched a rebase somewhere and lost some work. Restore state 'dirty' flag to let begin/end code know which planes to run the pre_commit/post_commit hooks for. This would have actually shown up as broken in the next commit rather than this one. v6: - Squash kerneldoc patch into this one. - Previous patches have now already taken care of most of the infrastructure that used to be in this patch. All we're adding here now is some thin wrappers. v7: - Check return of intel_plane_duplicate_state() for allocation failures. v8: - Drop unused drm_plane_state -> intel_plane_state cast. (Ander) - Squash in actual transition to plane helpers. Significant refactoring earlier in the patchset has made the combined prep+transition much easier to swallow than it was in earlier iterations. (Ander) v9: - s/track_fbs/disabled_planes/ in the atomic crtc flags. The only fb's we need to update frontbuffer tracking for are those on a plane about to be disabled (since the atomic helpers never call prepare_fb() when disabling a plane), so the new name more accurately describes what we're actually tracking. Testcase: igt/kms_plane Testcase: igt/kms_universal_plane Testcase: igt/kms_cursor_crc Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-12-23 10:41:52 -08:00
drm/i915: Switch to unified plane cursor handling (v4) The DRM core will translate calls to legacy cursor ioctls into universal cursor calls automatically, so there's no need to maintain the legacy cursor support. This greatly simplifies the transition since we don't have to handle reference counting differently depending on which cursor interface was called. The aim here is to transition to the universal plane interface with minimal code change. There's a lot of cleanup that can be done (e.g., using state stored in crtc->cursor->fb rather than intel_crtc) that is left to future patches. v4: - Drop drm_gem_object_unreference() that is no longer needed now that we receive the GEM obj directly rather than looking up the ID. v3: - Pass cursor obj to intel_crtc_cursor_set_obj() if cursor fb changes, even if 'visible' is false. intel_crtc_cursor_set_obj() will notice that the cursor isn't visible and disable it properly, but we still need to get intel_crtc->cursor_addr set properly so that we behave properly if the cursor becomes visible again in the future without changing the cursor buffer (noted by Chris Wilson and verified via i-g-t kms_cursor_crc). - s/drm_plane_init/drm_universal_plane_init/. Due to type compatibility between enum and bool, everything actually works correctly with the wrong init call, except for the type of plane that gets exposed to userspace (it shows up as type 'primary' rather than type 'cursor'). v2: - Remove duplicate dimension checks on cursor - Drop explicit cursor disable from crtc destroy (fb & plane destruction will take care of that now) - Use DRM plane helper to check update parameters Cc: intel-gfx@lists.freedesktop.org Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Pallavi G<pallavi.g@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-10 08:28:13 -07:00
cursor->can_scale = false;
cursor->max_downscale = 1;
cursor->pipe = pipe;
cursor->plane = pipe;
cursor->frontbuffer_bit = INTEL_FRONTBUFFER_CURSOR(pipe);
cursor->check_plane = intel_check_cursor_plane;
cursor->update_plane = intel_update_cursor_plane;
cursor->disable_plane = intel_disable_cursor_plane;
drm/i915: Switch to unified plane cursor handling (v4) The DRM core will translate calls to legacy cursor ioctls into universal cursor calls automatically, so there's no need to maintain the legacy cursor support. This greatly simplifies the transition since we don't have to handle reference counting differently depending on which cursor interface was called. The aim here is to transition to the universal plane interface with minimal code change. There's a lot of cleanup that can be done (e.g., using state stored in crtc->cursor->fb rather than intel_crtc) that is left to future patches. v4: - Drop drm_gem_object_unreference() that is no longer needed now that we receive the GEM obj directly rather than looking up the ID. v3: - Pass cursor obj to intel_crtc_cursor_set_obj() if cursor fb changes, even if 'visible' is false. intel_crtc_cursor_set_obj() will notice that the cursor isn't visible and disable it properly, but we still need to get intel_crtc->cursor_addr set properly so that we behave properly if the cursor becomes visible again in the future without changing the cursor buffer (noted by Chris Wilson and verified via i-g-t kms_cursor_crc). - s/drm_plane_init/drm_universal_plane_init/. Due to type compatibility between enum and bool, everything actually works correctly with the wrong init call, except for the type of plane that gets exposed to userspace (it shows up as type 'primary' rather than type 'cursor'). v2: - Remove duplicate dimension checks on cursor - Drop explicit cursor disable from crtc destroy (fb & plane destruction will take care of that now) - Use DRM plane helper to check update parameters Cc: intel-gfx@lists.freedesktop.org Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Pallavi G<pallavi.g@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-10 08:28:13 -07:00
ret = drm_universal_plane_init(dev, &cursor->base, 0,
&intel_plane_funcs,
intel_cursor_formats,
ARRAY_SIZE(intel_cursor_formats),
DRM_PLANE_TYPE_CURSOR,
"cursor %c", pipe_name(pipe));
if (ret)
goto fail;
if (INTEL_INFO(dev)->gen >= 4) {
if (!dev->mode_config.rotation_property)
dev->mode_config.rotation_property =
drm_mode_create_rotation_property(dev,
BIT(DRM_ROTATE_0) |
BIT(DRM_ROTATE_180));
if (dev->mode_config.rotation_property)
drm_object_attach_property(&cursor->base.base,
dev->mode_config.rotation_property,
state->base.rotation);
}
if (INTEL_INFO(dev)->gen >=9)
state->scaler_id = -1;
drm/i915: Move to atomic plane helpers (v9) Switch plane handling to use the atomic plane helpers. This means that rather than provide our own implementations of .update_plane() and .disable_plane(), we expose the lower-level check/prepare/commit/cleanup entrypoints and let the DRM core implement update/disable for us using those entrypoints. The other main change that falls out of this patch is that our drm_plane's will now always have a valid plane->state that contains the relevant plane state (initial state is allocated at plane creation). The base drm_plane_state pointed to holds the requested source/dest coordinates, and the subclassed intel_plane_state holds the adjusted values that our driver actually uses. v2: - Renamed file from intel_atomic.c to intel_atomic_plane.c (Daniel) - Fix a copy/paste comment mistake (Bob) v3: - Use prepare/cleanup functions that we've already factored out - Use newly refactored pre_commit/commit/post_commit to avoid sleeping during vblank evasion v4: - Rebase to latest di-nightly requires adding an 'old_state' parameter to atomic_update; v5: - Must have botched a rebase somewhere and lost some work. Restore state 'dirty' flag to let begin/end code know which planes to run the pre_commit/post_commit hooks for. This would have actually shown up as broken in the next commit rather than this one. v6: - Squash kerneldoc patch into this one. - Previous patches have now already taken care of most of the infrastructure that used to be in this patch. All we're adding here now is some thin wrappers. v7: - Check return of intel_plane_duplicate_state() for allocation failures. v8: - Drop unused drm_plane_state -> intel_plane_state cast. (Ander) - Squash in actual transition to plane helpers. Significant refactoring earlier in the patchset has made the combined prep+transition much easier to swallow than it was in earlier iterations. (Ander) v9: - s/track_fbs/disabled_planes/ in the atomic crtc flags. The only fb's we need to update frontbuffer tracking for are those on a plane about to be disabled (since the atomic helpers never call prepare_fb() when disabling a plane), so the new name more accurately describes what we're actually tracking. Testcase: igt/kms_plane Testcase: igt/kms_universal_plane Testcase: igt/kms_cursor_crc Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-12-23 10:41:52 -08:00
drm_plane_helper_add(&cursor->base, &intel_plane_helper_funcs);
drm/i915: Switch to unified plane cursor handling (v4) The DRM core will translate calls to legacy cursor ioctls into universal cursor calls automatically, so there's no need to maintain the legacy cursor support. This greatly simplifies the transition since we don't have to handle reference counting differently depending on which cursor interface was called. The aim here is to transition to the universal plane interface with minimal code change. There's a lot of cleanup that can be done (e.g., using state stored in crtc->cursor->fb rather than intel_crtc) that is left to future patches. v4: - Drop drm_gem_object_unreference() that is no longer needed now that we receive the GEM obj directly rather than looking up the ID. v3: - Pass cursor obj to intel_crtc_cursor_set_obj() if cursor fb changes, even if 'visible' is false. intel_crtc_cursor_set_obj() will notice that the cursor isn't visible and disable it properly, but we still need to get intel_crtc->cursor_addr set properly so that we behave properly if the cursor becomes visible again in the future without changing the cursor buffer (noted by Chris Wilson and verified via i-g-t kms_cursor_crc). - s/drm_plane_init/drm_universal_plane_init/. Due to type compatibility between enum and bool, everything actually works correctly with the wrong init call, except for the type of plane that gets exposed to userspace (it shows up as type 'primary' rather than type 'cursor'). v2: - Remove duplicate dimension checks on cursor - Drop explicit cursor disable from crtc destroy (fb & plane destruction will take care of that now) - Use DRM plane helper to check update parameters Cc: intel-gfx@lists.freedesktop.org Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Pallavi G<pallavi.g@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-10 08:28:13 -07:00
return &cursor->base;
fail:
kfree(state);
kfree(cursor);
return NULL;
drm/i915: Switch to unified plane cursor handling (v4) The DRM core will translate calls to legacy cursor ioctls into universal cursor calls automatically, so there's no need to maintain the legacy cursor support. This greatly simplifies the transition since we don't have to handle reference counting differently depending on which cursor interface was called. The aim here is to transition to the universal plane interface with minimal code change. There's a lot of cleanup that can be done (e.g., using state stored in crtc->cursor->fb rather than intel_crtc) that is left to future patches. v4: - Drop drm_gem_object_unreference() that is no longer needed now that we receive the GEM obj directly rather than looking up the ID. v3: - Pass cursor obj to intel_crtc_cursor_set_obj() if cursor fb changes, even if 'visible' is false. intel_crtc_cursor_set_obj() will notice that the cursor isn't visible and disable it properly, but we still need to get intel_crtc->cursor_addr set properly so that we behave properly if the cursor becomes visible again in the future without changing the cursor buffer (noted by Chris Wilson and verified via i-g-t kms_cursor_crc). - s/drm_plane_init/drm_universal_plane_init/. Due to type compatibility between enum and bool, everything actually works correctly with the wrong init call, except for the type of plane that gets exposed to userspace (it shows up as type 'primary' rather than type 'cursor'). v2: - Remove duplicate dimension checks on cursor - Drop explicit cursor disable from crtc destroy (fb & plane destruction will take care of that now) - Use DRM plane helper to check update parameters Cc: intel-gfx@lists.freedesktop.org Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Pallavi G<pallavi.g@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-10 08:28:13 -07:00
}
static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_crtc,
struct intel_crtc_state *crtc_state)
{
int i;
struct intel_scaler *intel_scaler;
struct intel_crtc_scaler_state *scaler_state = &crtc_state->scaler_state;
for (i = 0; i < intel_crtc->num_scalers; i++) {
intel_scaler = &scaler_state->scalers[i];
intel_scaler->in_use = 0;
intel_scaler->mode = PS_SCALER_MODE_DYN;
}
scaler_state->scaler_id = -1;
}
static void intel_crtc_init(struct drm_device *dev, int pipe)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc;
struct intel_crtc_state *crtc_state = NULL;
drm/i915: Switch to unified plane cursor handling (v4) The DRM core will translate calls to legacy cursor ioctls into universal cursor calls automatically, so there's no need to maintain the legacy cursor support. This greatly simplifies the transition since we don't have to handle reference counting differently depending on which cursor interface was called. The aim here is to transition to the universal plane interface with minimal code change. There's a lot of cleanup that can be done (e.g., using state stored in crtc->cursor->fb rather than intel_crtc) that is left to future patches. v4: - Drop drm_gem_object_unreference() that is no longer needed now that we receive the GEM obj directly rather than looking up the ID. v3: - Pass cursor obj to intel_crtc_cursor_set_obj() if cursor fb changes, even if 'visible' is false. intel_crtc_cursor_set_obj() will notice that the cursor isn't visible and disable it properly, but we still need to get intel_crtc->cursor_addr set properly so that we behave properly if the cursor becomes visible again in the future without changing the cursor buffer (noted by Chris Wilson and verified via i-g-t kms_cursor_crc). - s/drm_plane_init/drm_universal_plane_init/. Due to type compatibility between enum and bool, everything actually works correctly with the wrong init call, except for the type of plane that gets exposed to userspace (it shows up as type 'primary' rather than type 'cursor'). v2: - Remove duplicate dimension checks on cursor - Drop explicit cursor disable from crtc destroy (fb & plane destruction will take care of that now) - Use DRM plane helper to check update parameters Cc: intel-gfx@lists.freedesktop.org Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Pallavi G<pallavi.g@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-10 08:28:13 -07:00
struct drm_plane *primary = NULL;
struct drm_plane *cursor = NULL;
int ret;
intel_crtc = kzalloc(sizeof(*intel_crtc), GFP_KERNEL);
if (intel_crtc == NULL)
return;
crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL);
if (!crtc_state)
goto fail;
intel_crtc->config = crtc_state;
intel_crtc->base.state = &crtc_state->base;
crtc_state->base.crtc = &intel_crtc->base;
/* initialize shared scalers */
if (INTEL_INFO(dev)->gen >= 9) {
if (pipe == PIPE_C)
intel_crtc->num_scalers = 1;
else
intel_crtc->num_scalers = SKL_NUM_SCALERS;
skl_init_scalers(dev, intel_crtc, crtc_state);
}
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
primary = intel_primary_plane_create(dev, pipe);
drm/i915: Switch to unified plane cursor handling (v4) The DRM core will translate calls to legacy cursor ioctls into universal cursor calls automatically, so there's no need to maintain the legacy cursor support. This greatly simplifies the transition since we don't have to handle reference counting differently depending on which cursor interface was called. The aim here is to transition to the universal plane interface with minimal code change. There's a lot of cleanup that can be done (e.g., using state stored in crtc->cursor->fb rather than intel_crtc) that is left to future patches. v4: - Drop drm_gem_object_unreference() that is no longer needed now that we receive the GEM obj directly rather than looking up the ID. v3: - Pass cursor obj to intel_crtc_cursor_set_obj() if cursor fb changes, even if 'visible' is false. intel_crtc_cursor_set_obj() will notice that the cursor isn't visible and disable it properly, but we still need to get intel_crtc->cursor_addr set properly so that we behave properly if the cursor becomes visible again in the future without changing the cursor buffer (noted by Chris Wilson and verified via i-g-t kms_cursor_crc). - s/drm_plane_init/drm_universal_plane_init/. Due to type compatibility between enum and bool, everything actually works correctly with the wrong init call, except for the type of plane that gets exposed to userspace (it shows up as type 'primary' rather than type 'cursor'). v2: - Remove duplicate dimension checks on cursor - Drop explicit cursor disable from crtc destroy (fb & plane destruction will take care of that now) - Use DRM plane helper to check update parameters Cc: intel-gfx@lists.freedesktop.org Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Pallavi G<pallavi.g@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-10 08:28:13 -07:00
if (!primary)
goto fail;
cursor = intel_cursor_plane_create(dev, pipe);
if (!cursor)
goto fail;
drm/i915: Intel-specific primary plane handling (v8) Intel hardware allows the primary plane to be disabled independently of the CRTC. Provide custom primary plane handling to allow this. v8: - Pin/unpin properly when clipping causes the primary plane to be disabled when it has previously been enabled. - s/drm_primary_helper_check_update/drm_plane_helper_check_update/ v7: - Clip primary plane to invisible when crtc is disabled since intel_crtc->config.pipe_src_{w,h} may be garbage otherwise. - Unpin old fb before pinning new one in the "just pin and return" case that is used when the crtc is disabled. - Don't treat implicit disabling of the primary plane (caused by clipping) the same way as explicit disabling (caused by fb=0). For implicit disables, we should leave the fb set and pinned, whereas for explicit disables we need to unpin the fb before primary->fb is cleared. v6: - Pass rectangles to primary helper check function and get plane visibility back. - Wait for pending pageflips on primary plane update/disable. - Allow primary plane to be updated while the crtc is disabled (changes will take effect when the crtc is re-enabled if modeset passes -1 for the fb id). - Drop WARN() if we try to disable the primary plane when it's already been disabled. This will happen if the crtc gets disabled after the primary plane has already been disabled independently. v5: - Use new drm_primary_helper_check_update() helper function to check setplane parameter validity. - Swap primary plane's pipe for pre-gen4 FBC (caught by Ville Syrjälä) - Cleanup primary plane properly on crtc init failure v4: - Don't add a primary_plane field to intel_crtc; that was left over from a much earlier iteration of this patch series, but is no longer needed/used now that the DRM core primary plane support has been merged. v3: - Provide gen-specific primary plane format lists (suggested by Daniel Vetter). - If the primary plane is already enabled, go ahead and just call the primary plane helper to do the update (suggested by Daniel Vetter). - Don't try to disable the primary plane on destruction; the DRM layer should have already taken care of this for us. v2: - Unpin fb properly on primary plane disable - Provide an Intel-specific set of primary plane formats - Additional sanity checks on setplane (in line with the checks currently being done by the DRM core primary plane helper) Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-29 08:06:54 -07:00
ret = drm_crtc_init_with_planes(dev, &intel_crtc->base, primary,
cursor, &intel_crtc_funcs,
"pipe %c", pipe_name(pipe));
drm/i915: Switch to unified plane cursor handling (v4) The DRM core will translate calls to legacy cursor ioctls into universal cursor calls automatically, so there's no need to maintain the legacy cursor support. This greatly simplifies the transition since we don't have to handle reference counting differently depending on which cursor interface was called. The aim here is to transition to the universal plane interface with minimal code change. There's a lot of cleanup that can be done (e.g., using state stored in crtc->cursor->fb rather than intel_crtc) that is left to future patches. v4: - Drop drm_gem_object_unreference() that is no longer needed now that we receive the GEM obj directly rather than looking up the ID. v3: - Pass cursor obj to intel_crtc_cursor_set_obj() if cursor fb changes, even if 'visible' is false. intel_crtc_cursor_set_obj() will notice that the cursor isn't visible and disable it properly, but we still need to get intel_crtc->cursor_addr set properly so that we behave properly if the cursor becomes visible again in the future without changing the cursor buffer (noted by Chris Wilson and verified via i-g-t kms_cursor_crc). - s/drm_plane_init/drm_universal_plane_init/. Due to type compatibility between enum and bool, everything actually works correctly with the wrong init call, except for the type of plane that gets exposed to userspace (it shows up as type 'primary' rather than type 'cursor'). v2: - Remove duplicate dimension checks on cursor - Drop explicit cursor disable from crtc destroy (fb & plane destruction will take care of that now) - Use DRM plane helper to check update parameters Cc: intel-gfx@lists.freedesktop.org Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Pallavi G<pallavi.g@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-10 08:28:13 -07:00
if (ret)
goto fail;
/*
* On gen2/3 only plane A can do fbc, but the panel fitter and lvds port
* is hooked to pipe B. Hence we want plane A feeding pipe B.
*/
intel_crtc->pipe = pipe;
intel_crtc->plane = pipe;
if (HAS_FBC(dev) && INTEL_INFO(dev)->gen < 4) {
DRM_DEBUG_KMS("swapping pipes & planes for FBC\n");
intel_crtc->plane = !pipe;
}
intel_crtc->cursor_base = ~0;
intel_crtc->cursor_cntl = ~0;
intel_crtc->cursor_size = ~0;
drm/i915: Make sprite updates atomic Add a mechanism by which we can evade the leading edge of vblank. This guarantees that no two sprite register writes will straddle on either side of the vblank start, and that means all the writes will be latched together in one atomic operation. We do the vblank evade by checking the scanline counter, and if it's too close to the start of vblank (too close has been hardcoded to 100usec for now), we will wait for the vblank start to pass. In order to eliminate random delayes from the rest of the system, we operate with interrupts disabled, except when waiting for the vblank obviously. Note that we now go digging through pipe_to_crtc_mapping[] in the vblank interrupt handler, which is a bit dangerous since we set up interrupts before the crtcs. However in this case since it's the vblank interrupt, we don't actually unmask it until some piece of code requests it. v2: preempt_check_resched() calls after local_irq_enable() (Jesse) Hook up the vblank irq stuff on BDW as well v3: Pass intel_crtc instead of drm_crtc (Daniel) Warn if crtc.mutex isn't locked (Daniel) Add an explicit compiler barrier and document the barriers (Daniel) Note the irq vs. modeset setup madness in the commit message (Daniel) v4: Use prepare_to_wait() & co. directly and eliminate vbl_received v5: Refactor intel_pipe_handle_vblank() vs. drm_handle_vblank() (Chris) Check for min/max scanline <= 0 (Chris) Don't call intel_pipe_update_end() if start failed totally (Chris) Check that the vblank counters match on both sides of the critical section (Chris) v6: Fix atomic update for interlaced modes v7: Reorder code for better readability (Chris) v8: Drop preempt_check_resched(). It's not available to modules anymore and isn't even needed unless we ourselves cause a wakeup needing reschedule while interrupts are off Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Reviewed-by: Sourab Gupta <sourabgupta@gmail.com> Reviewed-by: Akash Goel <akash.goels@gmail.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-04-29 13:35:46 +03:00
intel_crtc->wm.cxsr_allowed = true;
BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) ||
dev_priv->plane_to_crtc_mapping[intel_crtc->plane] != NULL);
dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base;
dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base;
drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
intel_color_init(&intel_crtc->base);
WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe);
drm/i915: Switch to unified plane cursor handling (v4) The DRM core will translate calls to legacy cursor ioctls into universal cursor calls automatically, so there's no need to maintain the legacy cursor support. This greatly simplifies the transition since we don't have to handle reference counting differently depending on which cursor interface was called. The aim here is to transition to the universal plane interface with minimal code change. There's a lot of cleanup that can be done (e.g., using state stored in crtc->cursor->fb rather than intel_crtc) that is left to future patches. v4: - Drop drm_gem_object_unreference() that is no longer needed now that we receive the GEM obj directly rather than looking up the ID. v3: - Pass cursor obj to intel_crtc_cursor_set_obj() if cursor fb changes, even if 'visible' is false. intel_crtc_cursor_set_obj() will notice that the cursor isn't visible and disable it properly, but we still need to get intel_crtc->cursor_addr set properly so that we behave properly if the cursor becomes visible again in the future without changing the cursor buffer (noted by Chris Wilson and verified via i-g-t kms_cursor_crc). - s/drm_plane_init/drm_universal_plane_init/. Due to type compatibility between enum and bool, everything actually works correctly with the wrong init call, except for the type of plane that gets exposed to userspace (it shows up as type 'primary' rather than type 'cursor'). v2: - Remove duplicate dimension checks on cursor - Drop explicit cursor disable from crtc destroy (fb & plane destruction will take care of that now) - Use DRM plane helper to check update parameters Cc: intel-gfx@lists.freedesktop.org Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Pallavi G<pallavi.g@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-10 08:28:13 -07:00
return;
fail:
intel_plane_destroy(primary);
intel_plane_destroy(cursor);
kfree(crtc_state);
drm/i915: Switch to unified plane cursor handling (v4) The DRM core will translate calls to legacy cursor ioctls into universal cursor calls automatically, so there's no need to maintain the legacy cursor support. This greatly simplifies the transition since we don't have to handle reference counting differently depending on which cursor interface was called. The aim here is to transition to the universal plane interface with minimal code change. There's a lot of cleanup that can be done (e.g., using state stored in crtc->cursor->fb rather than intel_crtc) that is left to future patches. v4: - Drop drm_gem_object_unreference() that is no longer needed now that we receive the GEM obj directly rather than looking up the ID. v3: - Pass cursor obj to intel_crtc_cursor_set_obj() if cursor fb changes, even if 'visible' is false. intel_crtc_cursor_set_obj() will notice that the cursor isn't visible and disable it properly, but we still need to get intel_crtc->cursor_addr set properly so that we behave properly if the cursor becomes visible again in the future without changing the cursor buffer (noted by Chris Wilson and verified via i-g-t kms_cursor_crc). - s/drm_plane_init/drm_universal_plane_init/. Due to type compatibility between enum and bool, everything actually works correctly with the wrong init call, except for the type of plane that gets exposed to userspace (it shows up as type 'primary' rather than type 'cursor'). v2: - Remove duplicate dimension checks on cursor - Drop explicit cursor disable from crtc destroy (fb & plane destruction will take care of that now) - Use DRM plane helper to check update parameters Cc: intel-gfx@lists.freedesktop.org Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Pallavi G<pallavi.g@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-06-10 08:28:13 -07:00
kfree(intel_crtc);
}
enum pipe intel_get_pipe_from_connector(struct intel_connector *connector)
{
struct drm_encoder *encoder = connector->base.encoder;
drm: Split connection_mutex out of mode_config.mutex (v3) After the split-out of crtc locks from the big mode_config.mutex there's still two major areas it protects: - Various connector probe states, like connector->status, EDID properties, probed mode lists and similar information. - The links from connector->encoder and encoder->crtc and other modeset-relevant connector state (e.g. properties which control the panel fitter). The later is used by modeset operations. But they don't really care about the former since it's allowed to e.g. enable a disconnected VGA output or with a mode not in the probed list. Thus far this hasn't been a problem, but for the atomic modeset conversion Rob Clark needs to convert all modeset relevant locks into w/w locks. This is required because the order of acquisition is determined by how userspace supplies the atomic modeset data. This has run into troubles in the detect path since the i915 load detect code needs _both_ protections offered by the mode_config.mutex: It updates probe state and it needs to change the modeset configuration to enable the temporary load detect pipe. The big deal here is that for the probe/detect users of this lock a plain mutex fits best, but for atomic modesets we really want a w/w mutex. To fix this lets split out a new connection_mutex lock for the modeset relevant parts. For simplicity I've decided to only add one additional lock for all connector/encoder links and modeset configuration states. We have piles of different modeset objects in addition to those (like bridges or panels), so adding per-object locks would be much more effort. Also, we're guaranteed (at least for now) to do a full modeset if we need to acquire this lock. Which means that fine-grained locking is fairly irrelevant compared to the amount of time the full modeset will take. I've done a full audit, and there's just a few things that justify special focus: - Locking in drm_sysfs.c is almost completely absent. We should sprinkle mode_config.connection_mutex over this file a bit, but since it already lacks mode_config.mutex this patch wont make the situation any worse. This is material for a follow-up patch. - omap has a omap_framebuffer_flush function which walks the connector->encoder->crtc links and is called from many contexts. Some look like they don't acquire mode_config.mutex, so this is already racy. Again fixing this is material for a separate patch. - The radeon hot_plug function to retrain DP links looks at connector->dpms. Currently this happens without any locking, so is already racy. I think radeon_hotplug_work_func should gain mutex_lock/unlock calls for the mode_config.connection_mutex. - Same applies to i915's intel_dp_hot_plug. But again, this is already racy. - i915 load_detect code needs to acquire this lock. Which means the w/w dance due to Rob's work will be nicely contained to _just_ this function. I've added fixme comments everywhere where it looks suspicious but in the sysfs code. After a quick irc discussion with Dave Airlie it sounds like the lack of locking in there is due to sysfs cleanup fun at module unload. v1: original (only compile tested) v2: missing mutex_init(), etc (from Rob Clark) v3: i915 needs more care in the conversion: - Protect the edp pp logic with the connection_mutex. - Use connection_mutex in the backlight code due to get_pipe_from_connector. - Use drm_modeset_lock_all in suspend/resume paths. - Update lock checks in the overlay code. Cc: Alex Deucher <alexdeucher@gmail.com> Cc: Rob Clark <robdclark@gmail.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Rob Clark <robdclark@gmail.com>
2014-05-29 23:54:47 +02:00
struct drm_device *dev = connector->base.dev;
WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
if (!encoder || WARN_ON(!encoder->crtc))
return INVALID_PIPE;
return to_intel_crtc(encoder->crtc)->pipe;
}
int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
struct drm_file *file)
{
struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data;
struct drm_crtc *drmmode_crtc;
struct intel_crtc *crtc;
drmmode_crtc = drm_crtc_find(dev, pipe_from_crtc_id->crtc_id);
if (!drmmode_crtc)
return -ENOENT;
crtc = to_intel_crtc(drmmode_crtc);
pipe_from_crtc_id->pipe = crtc->pipe;
return 0;
}
drm/i915: simplify possible_clones computation Intel hw only has one MUX for encoders, so outputs are either not cloneable or all in the same group of cloneable outputs. This neatly simplifies the code and allows us to ditch some ugly if cascades in the dp and hdmi init code (well, we need these if cascades for other stuff still, but that can be taken care of in follow-up patches). Note that this changes two things: - dvo can now be cloned with sdvo, but dvo is gen2 whereas sdvo is gen3+, so no problem. Note that the old code had a bug and didn't allow cloning crt with dvo (but only the other way round). - sdvo-lvds can now be cloned with sdvo-non-tv. Spec says this won't work, but the only reason I've found is that you can't use the panel-fitter (used for lvds upscaling) with anything else. But we don't use the panel fitter for sdvo-lvds. Imo this part of Bspec is a) rather confusing b) mostly as a guideline to implementors (i.e. explicitly stating what is already implicit from the spec, without always going into the details of why). So I think we can ignore this - worst case we'll get a bug report from a user with with sdvo-lvds and sdvo-tmds and have to add that special case back in. Because sdvo lvds is a bit special explain in comments why sdvo LVDS outputs can be cloned, but native LVDS and eDP can't be cloned - we use the panel fitter for the later, but not for sdvo. Note that this also uncoditionally initializes the panel_vdd work used by eDP. Trying to be clever doesn't buy us anything (but strange bugs) and this way we can kill the is_edp check. v2: Incorporate review from Paulo - Add in a missing space. - Pimp comment message to address his concerns. Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-12 20:08:18 +02:00
static int intel_encoder_clones(struct intel_encoder *encoder)
{
drm/i915: simplify possible_clones computation Intel hw only has one MUX for encoders, so outputs are either not cloneable or all in the same group of cloneable outputs. This neatly simplifies the code and allows us to ditch some ugly if cascades in the dp and hdmi init code (well, we need these if cascades for other stuff still, but that can be taken care of in follow-up patches). Note that this changes two things: - dvo can now be cloned with sdvo, but dvo is gen2 whereas sdvo is gen3+, so no problem. Note that the old code had a bug and didn't allow cloning crt with dvo (but only the other way round). - sdvo-lvds can now be cloned with sdvo-non-tv. Spec says this won't work, but the only reason I've found is that you can't use the panel-fitter (used for lvds upscaling) with anything else. But we don't use the panel fitter for sdvo-lvds. Imo this part of Bspec is a) rather confusing b) mostly as a guideline to implementors (i.e. explicitly stating what is already implicit from the spec, without always going into the details of why). So I think we can ignore this - worst case we'll get a bug report from a user with with sdvo-lvds and sdvo-tmds and have to add that special case back in. Because sdvo lvds is a bit special explain in comments why sdvo LVDS outputs can be cloned, but native LVDS and eDP can't be cloned - we use the panel fitter for the later, but not for sdvo. Note that this also uncoditionally initializes the panel_vdd work used by eDP. Trying to be clever doesn't buy us anything (but strange bugs) and this way we can kill the is_edp check. v2: Incorporate review from Paulo - Add in a missing space. - Pimp comment message to address his concerns. Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-12 20:08:18 +02:00
struct drm_device *dev = encoder->base.dev;
struct intel_encoder *source_encoder;
int index_mask = 0;
int entry = 0;
for_each_intel_encoder(dev, source_encoder) {
if (encoders_cloneable(encoder, source_encoder))
drm/i915: simplify possible_clones computation Intel hw only has one MUX for encoders, so outputs are either not cloneable or all in the same group of cloneable outputs. This neatly simplifies the code and allows us to ditch some ugly if cascades in the dp and hdmi init code (well, we need these if cascades for other stuff still, but that can be taken care of in follow-up patches). Note that this changes two things: - dvo can now be cloned with sdvo, but dvo is gen2 whereas sdvo is gen3+, so no problem. Note that the old code had a bug and didn't allow cloning crt with dvo (but only the other way round). - sdvo-lvds can now be cloned with sdvo-non-tv. Spec says this won't work, but the only reason I've found is that you can't use the panel-fitter (used for lvds upscaling) with anything else. But we don't use the panel fitter for sdvo-lvds. Imo this part of Bspec is a) rather confusing b) mostly as a guideline to implementors (i.e. explicitly stating what is already implicit from the spec, without always going into the details of why). So I think we can ignore this - worst case we'll get a bug report from a user with with sdvo-lvds and sdvo-tmds and have to add that special case back in. Because sdvo lvds is a bit special explain in comments why sdvo LVDS outputs can be cloned, but native LVDS and eDP can't be cloned - we use the panel fitter for the later, but not for sdvo. Note that this also uncoditionally initializes the panel_vdd work used by eDP. Trying to be clever doesn't buy us anything (but strange bugs) and this way we can kill the is_edp check. v2: Incorporate review from Paulo - Add in a missing space. - Pimp comment message to address his concerns. Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-12 20:08:18 +02:00
index_mask |= (1 << entry);
entry++;
}
return index_mask;
}
static bool has_edp_a(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
if (!IS_MOBILE(dev))
return false;
if ((I915_READ(DP_A) & DP_DETECTED) == 0)
return false;
if (IS_GEN5(dev) && (I915_READ(FUSE_STRAP) & ILK_eDP_A_DISABLE))
return false;
return true;
}
static bool intel_crt_present(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
if (INTEL_INFO(dev)->gen >= 9)
return false;
if (IS_HSW_ULT(dev) || IS_BDW_ULT(dev))
return false;
if (IS_CHERRYVIEW(dev))
return false;
if (HAS_PCH_LPT_H(dev) && I915_READ(SFUSE_STRAP) & SFUSE_STRAP_CRT_DISABLED)
return false;
/* DDI E can't be used if DDI A requires 4 lanes */
if (HAS_DDI(dev) && I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES)
return false;
drm/i915: Check VBT for CRT port presence on HSW/BDW Unfortunatey there appear to quite a few HSW/BDW machines (eg. NUCs, Brix Pro) in the wild with LPT/WPT-H that have no physical CRT connector and non-working FDI. FDI training fails every single time on these machines. Dunno, maybe they just didn't bother wiring it up or something? Unfortunately all the fuse bits and whatnot are telling us that the CRT connector is present. And so what we get from this is tons of false positives from the CI systems due to VGA connector forcing. I've not found any way to detect this purely from hardware, so we have to resort to looking at the VBT int_crt_support bit. We used to check this bit on all platforms, but that broke all the old machines, so the check was then restricted to VLV only in commit 84b4e042c470 ("drm/i915: only apply crt_present check on VLV") Considering HSW and VLV VBT probably got defined around the same time, it should be reasonably safe to assume that the bits is sane for HSW/BDW as well. At least I have one copy of some VBT spec here that says it's meant for both VLV and HSW, and it knows about the bit (lists it being valid from version 155 onwards). Also I have two desktop machines with actual CRT ports and both have int_crt_support==1 in their VBTs. Also we already trust VBT >= 155 to tell us various details about the DDI ports, so trusting it a bit more seems reasonable. As far as VLV goes, the added VBT version check should be fine. Even if someone has some weird VLV machine with a very old VBT version, it just means they'll end up with a shadow CRT connector. IIRC the reason for eliminating the shadow CRT connector on VLV was to speed up display probing rather than fixing something more serious. v2: Move the platform checks into the VBT parsing code Also check that the VBT version is at least 155 v3: Improve commit message (Paulo) Cc: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1449005493-15487-1-git-send-email-ville.syrjala@linux.intel.com
2015-12-01 23:31:33 +02:00
if (!dev_priv->vbt.int_crt_support)
return false;
return true;
}
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;
/*
* intel_edp_init_connector() depends on this completing first, to
* prevent the registeration of both eDP and LVDS and the incorrect
* sharing of the PPS.
*/
intel_lvds_init(dev);
if (intel_crt_present(dev))
intel_crt_init(dev);
if (IS_BROXTON(dev)) {
/*
* FIXME: Broxton doesn't support port detection via the
* DDI_BUF_CTL_A or SFUSE_STRAP registers, find another way to
* detect the ports.
*/
intel_ddi_init(dev, PORT_A);
intel_ddi_init(dev, PORT_B);
intel_ddi_init(dev, PORT_C);
intel_dsi_init(dev);
} else if (HAS_DDI(dev)) {
int found;
/*
* Haswell uses DDI functions to detect digital outputs.
* On SKL pre-D0 the strap isn't connected, so we assume
* it's there.
*/
found = I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_INIT_DISPLAY_DETECTED;
/* WaIgnoreDDIAStrap: skl */
if (found || IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
intel_ddi_init(dev, PORT_A);
/* DDI B, C and D detection is indicated by the SFUSE_STRAP
* register */
found = I915_READ(SFUSE_STRAP);
if (found & SFUSE_STRAP_DDIB_DETECTED)
intel_ddi_init(dev, PORT_B);
if (found & SFUSE_STRAP_DDIC_DETECTED)
intel_ddi_init(dev, PORT_C);
if (found & SFUSE_STRAP_DDID_DETECTED)
intel_ddi_init(dev, PORT_D);
/*
* On SKL we don't have a way to detect DDI-E so we rely on VBT.
*/
if ((IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) &&
(dev_priv->vbt.ddi_port_info[PORT_E].supports_dp ||
dev_priv->vbt.ddi_port_info[PORT_E].supports_dvi ||
dev_priv->vbt.ddi_port_info[PORT_E].supports_hdmi))
intel_ddi_init(dev, PORT_E);
} else if (HAS_PCH_SPLIT(dev)) {
int found;
dpd_is_edp = intel_dp_is_edp(dev, PORT_D);
if (has_edp_a(dev))
intel_dp_init(dev, DP_A, PORT_A);
if (I915_READ(PCH_HDMIB) & SDVO_DETECTED) {
/* PCH SDVOB multiplex with HDMIB */
found = intel_sdvo_init(dev, PCH_SDVOB, PORT_B);
if (!found)
intel_hdmi_init(dev, PCH_HDMIB, PORT_B);
if (!found && (I915_READ(PCH_DP_B) & DP_DETECTED))
intel_dp_init(dev, PCH_DP_B, PORT_B);
}
if (I915_READ(PCH_HDMIC) & SDVO_DETECTED)
intel_hdmi_init(dev, PCH_HDMIC, PORT_C);
if (!dpd_is_edp && I915_READ(PCH_HDMID) & SDVO_DETECTED)
intel_hdmi_init(dev, PCH_HDMID, PORT_D);
if (I915_READ(PCH_DP_C) & DP_DETECTED)
intel_dp_init(dev, PCH_DP_C, PORT_C);
if (I915_READ(PCH_DP_D) & DP_DETECTED)
intel_dp_init(dev, PCH_DP_D, PORT_D);
} else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
bool has_edp, has_port;
/*
* The DP_DETECTED bit is the latched state of the DDC
* SDA pin at boot. However since eDP doesn't require DDC
* (no way to plug in a DP->HDMI dongle) the DDC pins for
* eDP ports may have been muxed to an alternate function.
* Thus we can't rely on the DP_DETECTED bit alone to detect
* eDP ports. Consult the VBT as well as DP_DETECTED to
* detect eDP ports.
*
* Sadly the straps seem to be missing sometimes even for HDMI
* ports (eg. on Voyo V3 - CHT x7-Z8700), so check both strap
* and VBT for the presence of the port. Additionally we can't
* trust the port type the VBT declares as we've seen at least
* HDMI ports that the VBT claim are DP or eDP.
*/
has_edp = intel_dp_is_edp(dev, PORT_B);
has_port = intel_bios_is_port_present(dev_priv, PORT_B);
if (I915_READ(VLV_DP_B) & DP_DETECTED || has_port)
has_edp &= intel_dp_init(dev, VLV_DP_B, PORT_B);
if ((I915_READ(VLV_HDMIB) & SDVO_DETECTED || has_port) && !has_edp)
intel_hdmi_init(dev, VLV_HDMIB, PORT_B);
drm/i915: preserve dispaly init order on ByT This patch changes HDMI port registration order for the BayTrail platform. The story is that in kernel version 3.11 i915 supported only one HDMI port - the HDMIB port. So this port ended up being HDMI-1 in user-space. But commit '6f6005a drm/i915: expose HDMI connectors on port C on BYT' introduced HDMIC port support. And added HDMIC registration prior to HDMIB, so HDMIB became HDMI-2 and HDMIC became HDMI-1. Well, this is fine as far as the kernel is concerned. i915 does not give any guarantees to the numbering, and has never given them. However, this breaks wayland setup in Tizen IVI. We have only one single HDMI port on our hardware, and it is connected to HDMIB. Our configuration relies on the fact that it is HDMI-1. Well, certainly this is user-space problem which was exposed with Jesse's patch. However, there is a reason why we have to do this assumption - we use touchscreen monitors and we have to associate event devices with the monitors, and this is not easy to do dynamically, so we just have a static setup. Anyway, while the user-space setup will have to be fixed regardless, let's chane the HDMI port registration order so that HDMIB stays HDMI-1, just like it was in 3.11. Simply because there is no strong reason for changing the order in the kernel, and it'll help setups like ours in sense that we'll have more time for fixing the issue properly. Also amend the commentary which looks a bit out-of-date. Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> [danvet: Drop the commment, SDVOC is gone and we have a proper HDMIC define now.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-10-16 18:10:41 +03:00
has_edp = intel_dp_is_edp(dev, PORT_C);
has_port = intel_bios_is_port_present(dev_priv, PORT_C);
if (I915_READ(VLV_DP_C) & DP_DETECTED || has_port)
has_edp &= intel_dp_init(dev, VLV_DP_C, PORT_C);
if ((I915_READ(VLV_HDMIC) & SDVO_DETECTED || has_port) && !has_edp)
intel_hdmi_init(dev, VLV_HDMIC, PORT_C);
if (IS_CHERRYVIEW(dev)) {
/*
* eDP not supported on port D,
* so no need to worry about it
*/
has_port = intel_bios_is_port_present(dev_priv, PORT_D);
if (I915_READ(CHV_DP_D) & DP_DETECTED || has_port)
intel_dp_init(dev, CHV_DP_D, PORT_D);
if (I915_READ(CHV_HDMID) & SDVO_DETECTED || has_port)
intel_hdmi_init(dev, CHV_HDMID, PORT_D);
}
intel_dsi_init(dev);
} else if (!IS_GEN2(dev) && !IS_PINEVIEW(dev)) {
bool found = false;
if (I915_READ(GEN3_SDVOB) & SDVO_DETECTED) {
DRM_DEBUG_KMS("probing SDVOB\n");
found = intel_sdvo_init(dev, GEN3_SDVOB, PORT_B);
if (!found && IS_G4X(dev)) {
DRM_DEBUG_KMS("probing HDMI on SDVOB\n");
intel_hdmi_init(dev, GEN4_HDMIB, PORT_B);
}
if (!found && IS_G4X(dev))
intel_dp_init(dev, DP_B, PORT_B);
}
/* Before G4X SDVOC doesn't have its own detect register */
if (I915_READ(GEN3_SDVOB) & SDVO_DETECTED) {
DRM_DEBUG_KMS("probing SDVOC\n");
found = intel_sdvo_init(dev, GEN3_SDVOC, PORT_C);
}
if (!found && (I915_READ(GEN3_SDVOC) & SDVO_DETECTED)) {
if (IS_G4X(dev)) {
DRM_DEBUG_KMS("probing HDMI on SDVOC\n");
intel_hdmi_init(dev, GEN4_HDMIC, PORT_C);
}
if (IS_G4X(dev))
intel_dp_init(dev, DP_C, PORT_C);
}
if (IS_G4X(dev) &&
(I915_READ(DP_D) & DP_DETECTED))
intel_dp_init(dev, DP_D, PORT_D);
} else if (IS_GEN2(dev))
intel_dvo_init(dev);
if (SUPPORTS_TV(dev))
intel_tv_init(dev);
intel_psr_init(dev);
for_each_intel_encoder(dev, encoder) {
encoder->base.possible_crtcs = encoder->crtc_mask;
encoder->base.possible_clones =
drm/i915: simplify possible_clones computation Intel hw only has one MUX for encoders, so outputs are either not cloneable or all in the same group of cloneable outputs. This neatly simplifies the code and allows us to ditch some ugly if cascades in the dp and hdmi init code (well, we need these if cascades for other stuff still, but that can be taken care of in follow-up patches). Note that this changes two things: - dvo can now be cloned with sdvo, but dvo is gen2 whereas sdvo is gen3+, so no problem. Note that the old code had a bug and didn't allow cloning crt with dvo (but only the other way round). - sdvo-lvds can now be cloned with sdvo-non-tv. Spec says this won't work, but the only reason I've found is that you can't use the panel-fitter (used for lvds upscaling) with anything else. But we don't use the panel fitter for sdvo-lvds. Imo this part of Bspec is a) rather confusing b) mostly as a guideline to implementors (i.e. explicitly stating what is already implicit from the spec, without always going into the details of why). So I think we can ignore this - worst case we'll get a bug report from a user with with sdvo-lvds and sdvo-tmds and have to add that special case back in. Because sdvo lvds is a bit special explain in comments why sdvo LVDS outputs can be cloned, but native LVDS and eDP can't be cloned - we use the panel fitter for the later, but not for sdvo. Note that this also uncoditionally initializes the panel_vdd work used by eDP. Trying to be clever doesn't buy us anything (but strange bugs) and this way we can kill the is_edp check. v2: Incorporate review from Paulo - Add in a missing space. - Pimp comment message to address his concerns. Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-12 20:08:18 +02:00
intel_encoder_clones(encoder);
}
intel_init_pch_refclk(dev);
drm_helper_move_panel_connectors_to_head(dev);
}
static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
{
struct drm_device *dev = fb->dev;
struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
drm_framebuffer_cleanup(fb);
mutex_lock(&dev->struct_mutex);
WARN_ON(!intel_fb->obj->framebuffer_references--);
drm_gem_object_unreference(&intel_fb->obj->base);
mutex_unlock(&dev->struct_mutex);
kfree(intel_fb);
}
static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb,
struct drm_file *file,
unsigned int *handle)
{
struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
struct drm_i915_gem_object *obj = intel_fb->obj;
if (obj->userptr.mm) {
DRM_DEBUG("attempting to use a userptr for a framebuffer, denied\n");
return -EINVAL;
}
return drm_gem_handle_create(file, &obj->base, handle);
}
drm/i915: dirty fb operation flushsing frontbuffer Let's do a frontbuffer flush on dirty fb. To be used for DIRTYFB drm ioctl. This patch solves the biggest PSR known issue, that is missed screen updates during boot, mainly when there is a splash screen involved like Plymouth. Previously PSR was being invalidated by fbdev and Plymounth was taking control with PSR yet invalidated and could get screen updates normally. However with some atomic modeset changes Pymouth modeset over ioctl was now causing frontbuffer flushes making PSR gets back to work while it cannot track the screen updates and exit properly. By adding this flush on dirtyfb we properly track frontbuffer writes and properly exit PSR. Actually all mmap_wc users should call this dirty callback in order to have a proper frontbuffer tracking. In the future it can be extended to return 0 if the whole screen has being flushed or the number of rects flushed as Chris suggested. v2: Remove ORIGIN_FB_DIRTY and use ORIGIN_GTT instead since dirty callback is just called after few screen updates and not on everyone as pointed by Daniel. v3: Use flush instead of invalidate since flush means invalidate + flush and dirty means drawn had finished and it can be flushed. v4: Remove PSR from subject since it is purely frontbuffer tracking change and that can be useful for FBC as well. Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: Paulo Zanoni <paulo.r.zanoni@intel.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> [danvet: Fix alignment as spotted by Paulo.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-07-08 16:22:45 -07:00
static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb,
struct drm_file *file,
unsigned flags, unsigned color,
struct drm_clip_rect *clips,
unsigned num_clips)
{
struct drm_device *dev = fb->dev;
struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
struct drm_i915_gem_object *obj = intel_fb->obj;
mutex_lock(&dev->struct_mutex);
intel_fb_obj_flush(obj, false, ORIGIN_DIRTYFB);
drm/i915: dirty fb operation flushsing frontbuffer Let's do a frontbuffer flush on dirty fb. To be used for DIRTYFB drm ioctl. This patch solves the biggest PSR known issue, that is missed screen updates during boot, mainly when there is a splash screen involved like Plymouth. Previously PSR was being invalidated by fbdev and Plymounth was taking control with PSR yet invalidated and could get screen updates normally. However with some atomic modeset changes Pymouth modeset over ioctl was now causing frontbuffer flushes making PSR gets back to work while it cannot track the screen updates and exit properly. By adding this flush on dirtyfb we properly track frontbuffer writes and properly exit PSR. Actually all mmap_wc users should call this dirty callback in order to have a proper frontbuffer tracking. In the future it can be extended to return 0 if the whole screen has being flushed or the number of rects flushed as Chris suggested. v2: Remove ORIGIN_FB_DIRTY and use ORIGIN_GTT instead since dirty callback is just called after few screen updates and not on everyone as pointed by Daniel. v3: Use flush instead of invalidate since flush means invalidate + flush and dirty means drawn had finished and it can be flushed. v4: Remove PSR from subject since it is purely frontbuffer tracking change and that can be useful for FBC as well. Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: Paulo Zanoni <paulo.r.zanoni@intel.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> [danvet: Fix alignment as spotted by Paulo.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-07-08 16:22:45 -07:00
mutex_unlock(&dev->struct_mutex);
return 0;
}
static const struct drm_framebuffer_funcs intel_fb_funcs = {
.destroy = intel_user_framebuffer_destroy,
.create_handle = intel_user_framebuffer_create_handle,
drm/i915: dirty fb operation flushsing frontbuffer Let's do a frontbuffer flush on dirty fb. To be used for DIRTYFB drm ioctl. This patch solves the biggest PSR known issue, that is missed screen updates during boot, mainly when there is a splash screen involved like Plymouth. Previously PSR was being invalidated by fbdev and Plymounth was taking control with PSR yet invalidated and could get screen updates normally. However with some atomic modeset changes Pymouth modeset over ioctl was now causing frontbuffer flushes making PSR gets back to work while it cannot track the screen updates and exit properly. By adding this flush on dirtyfb we properly track frontbuffer writes and properly exit PSR. Actually all mmap_wc users should call this dirty callback in order to have a proper frontbuffer tracking. In the future it can be extended to return 0 if the whole screen has being flushed or the number of rects flushed as Chris suggested. v2: Remove ORIGIN_FB_DIRTY and use ORIGIN_GTT instead since dirty callback is just called after few screen updates and not on everyone as pointed by Daniel. v3: Use flush instead of invalidate since flush means invalidate + flush and dirty means drawn had finished and it can be flushed. v4: Remove PSR from subject since it is purely frontbuffer tracking change and that can be useful for FBC as well. Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: Paulo Zanoni <paulo.r.zanoni@intel.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> [danvet: Fix alignment as spotted by Paulo.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-07-08 16:22:45 -07:00
.dirty = intel_user_framebuffer_dirty,
};
static
u32 intel_fb_pitch_limit(struct drm_device *dev, uint64_t fb_modifier,
uint32_t pixel_format)
{
u32 gen = INTEL_INFO(dev)->gen;
if (gen >= 9) {
int cpp = drm_format_plane_cpp(pixel_format, 0);
/* "The stride in bytes must not exceed the of the size of 8K
* pixels and 32K bytes."
*/
return min(8192 * cpp, 32768);
} else if (gen >= 5 && !IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev)) {
return 32*1024;
} else if (gen >= 4) {
if (fb_modifier == I915_FORMAT_MOD_X_TILED)
return 16*1024;
else
return 32*1024;
} else if (gen >= 3) {
if (fb_modifier == I915_FORMAT_MOD_X_TILED)
return 8*1024;
else
return 16*1024;
} else {
/* XXX DSPC is limited to 4k tiled */
return 8*1024;
}
}
static int intel_framebuffer_init(struct drm_device *dev,
struct intel_framebuffer *intel_fb,
struct drm_mode_fb_cmd2 *mode_cmd,
struct drm_i915_gem_object *obj)
{
struct drm_i915_private *dev_priv = to_i915(dev);
unsigned int aligned_height;
int ret;
u32 pitch_limit, stride_alignment;
WARN_ON(!mutex_is_locked(&dev->struct_mutex));
if (mode_cmd->flags & DRM_MODE_FB_MODIFIERS) {
/* Enforce that fb modifier and tiling mode match, but only for
* X-tiled. This is needed for FBC. */
if (!!(obj->tiling_mode == I915_TILING_X) !=
!!(mode_cmd->modifier[0] == I915_FORMAT_MOD_X_TILED)) {
DRM_DEBUG("tiling_mode doesn't match fb modifier\n");
return -EINVAL;
}
} else {
if (obj->tiling_mode == I915_TILING_X)
mode_cmd->modifier[0] = I915_FORMAT_MOD_X_TILED;
else if (obj->tiling_mode == I915_TILING_Y) {
DRM_DEBUG("No Y tiling for legacy addfb\n");
return -EINVAL;
}
}
/* Passed in modifier sanity checking. */
switch (mode_cmd->modifier[0]) {
case I915_FORMAT_MOD_Y_TILED:
case I915_FORMAT_MOD_Yf_TILED:
if (INTEL_INFO(dev)->gen < 9) {
DRM_DEBUG("Unsupported tiling 0x%llx!\n",
mode_cmd->modifier[0]);
return -EINVAL;
}
case DRM_FORMAT_MOD_NONE:
case I915_FORMAT_MOD_X_TILED:
break;
default:
DRM_DEBUG("Unsupported fb modifier 0x%llx!\n",
mode_cmd->modifier[0]);
return -EINVAL;
}
stride_alignment = intel_fb_stride_alignment(dev_priv,
mode_cmd->modifier[0],
mode_cmd->pixel_format);
if (mode_cmd->pitches[0] & (stride_alignment - 1)) {
DRM_DEBUG("pitch (%d) must be at least %u byte aligned\n",
mode_cmd->pitches[0], stride_alignment);
return -EINVAL;
}
pitch_limit = intel_fb_pitch_limit(dev, mode_cmd->modifier[0],
mode_cmd->pixel_format);
if (mode_cmd->pitches[0] > pitch_limit) {
DRM_DEBUG("%s pitch (%u) must be at less than %d\n",
mode_cmd->modifier[0] != DRM_FORMAT_MOD_NONE ?
"tiled" : "linear",
mode_cmd->pitches[0], pitch_limit);
return -EINVAL;
}
if (mode_cmd->modifier[0] == I915_FORMAT_MOD_X_TILED &&
mode_cmd->pitches[0] != obj->stride) {
DRM_DEBUG("pitch (%d) must match tiling stride (%d)\n",
mode_cmd->pitches[0], obj->stride);
return -EINVAL;
}
/* Reject formats not supported by any plane early. */
switch (mode_cmd->pixel_format) {
case DRM_FORMAT_C8:
case DRM_FORMAT_RGB565:
case DRM_FORMAT_XRGB8888:
case DRM_FORMAT_ARGB8888:
break;
case DRM_FORMAT_XRGB1555:
if (INTEL_INFO(dev)->gen > 3) {
DRM_DEBUG("unsupported pixel format: %s\n",
drm_get_format_name(mode_cmd->pixel_format));
return -EINVAL;
}
break;
case DRM_FORMAT_ABGR8888:
if (!IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev) &&
INTEL_INFO(dev)->gen < 9) {
DRM_DEBUG("unsupported pixel format: %s\n",
drm_get_format_name(mode_cmd->pixel_format));
return -EINVAL;
}
break;
case DRM_FORMAT_XBGR8888:
case DRM_FORMAT_XRGB2101010:
case DRM_FORMAT_XBGR2101010:
if (INTEL_INFO(dev)->gen < 4) {
DRM_DEBUG("unsupported pixel format: %s\n",
drm_get_format_name(mode_cmd->pixel_format));
return -EINVAL;
}
break;
case DRM_FORMAT_ABGR2101010:
if (!IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev)) {
DRM_DEBUG("unsupported pixel format: %s\n",
drm_get_format_name(mode_cmd->pixel_format));
return -EINVAL;
}
break;
case DRM_FORMAT_YUYV:
case DRM_FORMAT_UYVY:
case DRM_FORMAT_YVYU:
case DRM_FORMAT_VYUY:
if (INTEL_INFO(dev)->gen < 5) {
DRM_DEBUG("unsupported pixel format: %s\n",
drm_get_format_name(mode_cmd->pixel_format));
return -EINVAL;
}
break;
default:
DRM_DEBUG("unsupported pixel format: %s\n",
drm_get_format_name(mode_cmd->pixel_format));
return -EINVAL;
}
/* FIXME need to adjust LINOFF/TILEOFF accordingly. */
if (mode_cmd->offsets[0] != 0)
return -EINVAL;
aligned_height = intel_fb_align_height(dev, mode_cmd->height,
mode_cmd->pixel_format,
mode_cmd->modifier[0]);
/* FIXME drm helper for size checks (especially planar formats)? */
if (obj->base.size < aligned_height * mode_cmd->pitches[0])
return -EINVAL;
drm_helper_mode_fill_fb_struct(&intel_fb->base, mode_cmd);
intel_fb->obj = obj;
intel_fill_fb_info(dev_priv, &intel_fb->base);
ret = drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_funcs);
if (ret) {
DRM_ERROR("framebuffer init failed %d\n", ret);
return ret;
}
intel_fb->obj->framebuffer_references++;
return 0;
}
static struct drm_framebuffer *
intel_user_framebuffer_create(struct drm_device *dev,
struct drm_file *filp,
const struct drm_mode_fb_cmd2 *user_mode_cmd)
{
drm/i915: On fb alloc failure, unref gem object where it gets refed Currently when allocating a framebuffer fails, the gem object gets unrefed at the bottom of the call stack in __intel_framebuffer_create, not where it gets refed, which is in intel_framebuffer_create_for_mode (via i915_gem_alloc_object) and in intel_user_framebuffer_create (via drm_gem_object_lookup). This invites mistakes: __intel_framebuffer_create is also called from intelfb_alloc, and as discovered by Tvrtko Ursulin, a double unref was introduced there with a8bb6818270c ("drm/i915: Fix error path leak in fbdev fb allocation"). As suggested by Ville Syrjälä, fix the double unref and improve code clarity by moving the unref away from __intel_framebuffer_create to where the gem object gets refed. Based on Tvrtko Ursulin's original v2. v3: On fb alloc failure, unref gem object where it gets refed, fix double unref in separate commit (Ville Syrjälä) v4: Lock struct_mutex on unref (Chris Wilson) v5: Rebase on drm-intel-nightly 2015y-09m-01d-09h-06m-08s UTC, rephrase commit message (Jani Nicula) Tested-by: Pierre Moreau <pierre.morrow@free.fr> [MBP 5,3 2009 nvidia MCP79 + G96 pre-retina] Tested-by: Paul Hordiienko <pvt.gord@gmail.com> [MBP 6,2 2010 intel ILK + nvidia GT216 pre-retina] Tested-by: William Brown <william@blackhats.net.au> [MBP 8,2 2011 intel SNB + amd turks pre-retina] Tested-by: Lukas Wunner <lukas@wunner.de> [MBP 9,1 2012 intel IVB + nvidia GK107 pre-retina] Tested-by: Bruno Bierbaumer <bruno@bierbaumer.net> [MBP 11,3 2013 intel HSW + nvidia GK107 retina] Fixes: a8bb6818270c ("drm/i915: Fix error path leak in fbdev fb allocation") Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Lukas Wunner <lukas@wunner.de> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/2161c5062ef5d6458f8ae14d924a26d4d1dba317.1446892879.git.lukas@wunner.de Signed-off-by: Jani Nikula <jani.nikula@intel.com>
2015-07-04 11:50:58 +02:00
struct drm_framebuffer *fb;
struct drm_i915_gem_object *obj;
drm/i915: Don't clobber the addfb2 ioctl params We try to convert the old way of of specifying fb tiling (obj->tiling) into the new fb modifiers. We store the result in the passed in mode_cmd structure. But that structure comes directly from the addfb2 ioctl, and gets copied back out to userspace, which means we're clobbering the modifiers that the user provided (all 0 since the DRM_MODE_FB_MODIFIERS flag wasn't even set by the user). Hence if the user reuses the struct for another addfb2, the ioctl will be rejected since it's now asking for some modifiers w/o the flag set. Fix the problem by making a copy of the user provided structure. We can play any games we want with the copy. IGT-Version: 1.12-git (x86_64) (Linux: 4.4.0-rc1-stereo+ x86_64) ... Subtest basic-X-tiled: SUCCESS (0.001s) Test assertion failure function pitch_tests, file kms_addfb_basic.c:167: Failed assertion: drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &f) == 0 Last errno: 22, Invalid argument Stack trace: #0 [__igt_fail_assert+0x101] #1 [pitch_tests+0x619] #2 [__real_main426+0x2f] #3 [main+0x23] #4 [__libc_start_main+0xf0] #5 [_start+0x29] #6 [<unknown>+0x29] Subtest framebuffer-vs-set-tiling failed. **** DEBUG **** Test assertion failure function pitch_tests, file kms_addfb_basic.c:167: Failed assertion: drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &f) == 0 Last errno: 22, Invalid argument **** END **** Subtest framebuffer-vs-set-tiling: FAIL (0.003s) ... IGT-Version: 1.12-git (x86_64) (Linux: 4.4.0-rc1-stereo+ x86_64) Subtest framebuffer-vs-set-tiling: SUCCESS (0.000s) Cc: stable@vger.kernel.org # v4.1+ Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Fixes: 2a80eada326f ("drm/i915: Add fb format modifier support") Testcase: igt/kms_addfb_basic/clobbered-modifier Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Jani Nikula <jani.nikula@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1447261890-3960-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-11 19:11:28 +02:00
struct drm_mode_fb_cmd2 mode_cmd = *user_mode_cmd;
obj = to_intel_bo(drm_gem_object_lookup(filp, mode_cmd.handles[0]));
if (&obj->base == NULL)
return ERR_PTR(-ENOENT);
fb = intel_framebuffer_create(dev, &mode_cmd, obj);
drm/i915: On fb alloc failure, unref gem object where it gets refed Currently when allocating a framebuffer fails, the gem object gets unrefed at the bottom of the call stack in __intel_framebuffer_create, not where it gets refed, which is in intel_framebuffer_create_for_mode (via i915_gem_alloc_object) and in intel_user_framebuffer_create (via drm_gem_object_lookup). This invites mistakes: __intel_framebuffer_create is also called from intelfb_alloc, and as discovered by Tvrtko Ursulin, a double unref was introduced there with a8bb6818270c ("drm/i915: Fix error path leak in fbdev fb allocation"). As suggested by Ville Syrjälä, fix the double unref and improve code clarity by moving the unref away from __intel_framebuffer_create to where the gem object gets refed. Based on Tvrtko Ursulin's original v2. v3: On fb alloc failure, unref gem object where it gets refed, fix double unref in separate commit (Ville Syrjälä) v4: Lock struct_mutex on unref (Chris Wilson) v5: Rebase on drm-intel-nightly 2015y-09m-01d-09h-06m-08s UTC, rephrase commit message (Jani Nicula) Tested-by: Pierre Moreau <pierre.morrow@free.fr> [MBP 5,3 2009 nvidia MCP79 + G96 pre-retina] Tested-by: Paul Hordiienko <pvt.gord@gmail.com> [MBP 6,2 2010 intel ILK + nvidia GT216 pre-retina] Tested-by: William Brown <william@blackhats.net.au> [MBP 8,2 2011 intel SNB + amd turks pre-retina] Tested-by: Lukas Wunner <lukas@wunner.de> [MBP 9,1 2012 intel IVB + nvidia GK107 pre-retina] Tested-by: Bruno Bierbaumer <bruno@bierbaumer.net> [MBP 11,3 2013 intel HSW + nvidia GK107 retina] Fixes: a8bb6818270c ("drm/i915: Fix error path leak in fbdev fb allocation") Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Lukas Wunner <lukas@wunner.de> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/2161c5062ef5d6458f8ae14d924a26d4d1dba317.1446892879.git.lukas@wunner.de Signed-off-by: Jani Nikula <jani.nikula@intel.com>
2015-07-04 11:50:58 +02:00
if (IS_ERR(fb))
drm_gem_object_unreference_unlocked(&obj->base);
return fb;
}
#ifndef CONFIG_DRM_FBDEV_EMULATION
static inline void intel_fbdev_output_poll_changed(struct drm_device *dev)
{
}
#endif
static const struct drm_mode_config_funcs intel_mode_funcs = {
.fb_create = intel_user_framebuffer_create,
.output_poll_changed = intel_fbdev_output_poll_changed,
.atomic_check = intel_atomic_check,
.atomic_commit = intel_atomic_commit,
.atomic_state_alloc = intel_atomic_state_alloc,
.atomic_state_clear = intel_atomic_state_clear,
};
/**
* intel_init_display_hooks - initialize the display modesetting hooks
* @dev_priv: device private
*/
void intel_init_display_hooks(struct drm_i915_private *dev_priv)
{
if (INTEL_INFO(dev_priv)->gen >= 9) {
dev_priv->display.get_pipe_config = haswell_get_pipe_config;
dev_priv->display.get_initial_plane_config =
skylake_get_initial_plane_config;
dev_priv->display.crtc_compute_clock =
haswell_crtc_compute_clock;
dev_priv->display.crtc_enable = haswell_crtc_enable;
dev_priv->display.crtc_disable = haswell_crtc_disable;
} else if (HAS_DDI(dev_priv)) {
dev_priv->display.get_pipe_config = haswell_get_pipe_config;
dev_priv->display.get_initial_plane_config =
ironlake_get_initial_plane_config;
dev_priv->display.crtc_compute_clock =
haswell_crtc_compute_clock;
dev_priv->display.crtc_enable = haswell_crtc_enable;
dev_priv->display.crtc_disable = haswell_crtc_disable;
} else if (HAS_PCH_SPLIT(dev_priv)) {
dev_priv->display.get_pipe_config = ironlake_get_pipe_config;
dev_priv->display.get_initial_plane_config =
ironlake_get_initial_plane_config;
dev_priv->display.crtc_compute_clock =
ironlake_crtc_compute_clock;
dev_priv->display.crtc_enable = ironlake_crtc_enable;
dev_priv->display.crtc_disable = ironlake_crtc_disable;
} else if (IS_CHERRYVIEW(dev_priv)) {
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
dev_priv->display.get_initial_plane_config =
i9xx_get_initial_plane_config;
dev_priv->display.crtc_compute_clock = chv_crtc_compute_clock;
dev_priv->display.crtc_enable = valleyview_crtc_enable;
dev_priv->display.crtc_disable = i9xx_crtc_disable;
} else if (IS_VALLEYVIEW(dev_priv)) {
dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
dev_priv->display.get_initial_plane_config =
i9xx_get_initial_plane_config;
dev_priv->display.crtc_compute_clock = vlv_crtc_compute_clock;
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 <pallavi.g@intel.com> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [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 <daniel.vetter@ffwll.ch>
2013-04-18 14:51:36 -07:00
dev_priv->display.crtc_enable = valleyview_crtc_enable;
dev_priv->display.crtc_disable = i9xx_crtc_disable;
} else if (IS_G4X(dev_priv)) {
dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
dev_priv->display.get_initial_plane_config =
i9xx_get_initial_plane_config;
dev_priv->display.crtc_compute_clock = g4x_crtc_compute_clock;
dev_priv->display.crtc_enable = i9xx_crtc_enable;
dev_priv->display.crtc_disable = i9xx_crtc_disable;
} else if (IS_PINEVIEW(dev_priv)) {
dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
dev_priv->display.get_initial_plane_config =
i9xx_get_initial_plane_config;
dev_priv->display.crtc_compute_clock = pnv_crtc_compute_clock;
dev_priv->display.crtc_enable = i9xx_crtc_enable;
dev_priv->display.crtc_disable = i9xx_crtc_disable;
} else if (!IS_GEN2(dev_priv)) {
dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
dev_priv->display.get_initial_plane_config =
i9xx_get_initial_plane_config;
dev_priv->display.crtc_compute_clock = i9xx_crtc_compute_clock;
dev_priv->display.crtc_enable = i9xx_crtc_enable;
dev_priv->display.crtc_disable = i9xx_crtc_disable;
} else {
dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
dev_priv->display.get_initial_plane_config =
i9xx_get_initial_plane_config;
dev_priv->display.crtc_compute_clock = i8xx_crtc_compute_clock;
dev_priv->display.crtc_enable = i9xx_crtc_enable;
dev_priv->display.crtc_disable = i9xx_crtc_disable;
}
/* Returns the core display clock speed */
if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
dev_priv->display.get_display_clock_speed =
skylake_get_display_clock_speed;
else if (IS_BROXTON(dev_priv))
dev_priv->display.get_display_clock_speed =
broxton_get_display_clock_speed;
else if (IS_BROADWELL(dev_priv))
dev_priv->display.get_display_clock_speed =
broadwell_get_display_clock_speed;
else if (IS_HASWELL(dev_priv))
dev_priv->display.get_display_clock_speed =
haswell_get_display_clock_speed;
else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
dev_priv->display.get_display_clock_speed =
valleyview_get_display_clock_speed;
else if (IS_GEN5(dev_priv))
dev_priv->display.get_display_clock_speed =
ilk_get_display_clock_speed;
else if (IS_I945G(dev_priv) || IS_BROADWATER(dev_priv) ||
IS_GEN6(dev_priv) || IS_IVYBRIDGE(dev_priv))
dev_priv->display.get_display_clock_speed =
i945_get_display_clock_speed;
else if (IS_GM45(dev_priv))
dev_priv->display.get_display_clock_speed =
gm45_get_display_clock_speed;
else if (IS_CRESTLINE(dev_priv))
dev_priv->display.get_display_clock_speed =
i965gm_get_display_clock_speed;
else if (IS_PINEVIEW(dev_priv))
dev_priv->display.get_display_clock_speed =
pnv_get_display_clock_speed;
else if (IS_G33(dev_priv) || IS_G4X(dev_priv))
dev_priv->display.get_display_clock_speed =
g33_get_display_clock_speed;
else if (IS_I915G(dev_priv))
dev_priv->display.get_display_clock_speed =
i915_get_display_clock_speed;
else if (IS_I945GM(dev_priv) || IS_845G(dev_priv))
dev_priv->display.get_display_clock_speed =
i9xx_misc_get_display_clock_speed;
else if (IS_I915GM(dev_priv))
dev_priv->display.get_display_clock_speed =
i915gm_get_display_clock_speed;
else if (IS_I865G(dev_priv))
dev_priv->display.get_display_clock_speed =
i865_get_display_clock_speed;
else if (IS_I85X(dev_priv))
dev_priv->display.get_display_clock_speed =
i85x_get_display_clock_speed;
else { /* 830 */
WARN(!IS_I830(dev_priv), "Unknown platform. Assuming 133 MHz CDCLK\n");
dev_priv->display.get_display_clock_speed =
i830_get_display_clock_speed;
}
if (IS_GEN5(dev_priv)) {
dev_priv->display.fdi_link_train = ironlake_fdi_link_train;
} else if (IS_GEN6(dev_priv)) {
dev_priv->display.fdi_link_train = gen6_fdi_link_train;
} else if (IS_IVYBRIDGE(dev_priv)) {
/* FIXME: detect B0+ stepping and use auto training */
dev_priv->display.fdi_link_train = ivb_manual_fdi_link_train;
} else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
dev_priv->display.fdi_link_train = hsw_fdi_link_train;
}
if (IS_BROADWELL(dev_priv)) {
dev_priv->display.modeset_commit_cdclk =
broadwell_modeset_commit_cdclk;
dev_priv->display.modeset_calc_cdclk =
broadwell_modeset_calc_cdclk;
} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
dev_priv->display.modeset_commit_cdclk =
valleyview_modeset_commit_cdclk;
dev_priv->display.modeset_calc_cdclk =
valleyview_modeset_calc_cdclk;
} else if (IS_BROXTON(dev_priv)) {
dev_priv->display.modeset_commit_cdclk =
bxt_modeset_commit_cdclk;
dev_priv->display.modeset_calc_cdclk =
bxt_modeset_calc_cdclk;
drm/i915/skl: SKL CDCLK change on modeset tracking VCO WARNING: Using ChromeOS with an eDP panel and a 4K@60 DP monitor connected to DDI1 the system will hard hang during a cold boot. Occurs when DDI1 is enabled when the cdclk is less then required. DP connected to DDI2 and HPD on either port works correctly. Set cdclk based on the max required pixel clock based on VCO selected. Track boot vco instead of boot cdclk. The vco is now tracked at the atomic level and all CRTCs updated if the required vco is changed. Not tested with eDP v1.4 panels that require 8640 vco due to availability. V1: initial version V2: add vco tracking in intel_dp_compute_config(), rename skl_boot_cdclk. V3: rebase, V2 feedback not possible as encoders are not aware of atomic. V4: track target vco is atomic state. modeset all CRTCs if vco changes V5: rename atomic variable, cleaner if/else logic, use existing vco if encoder does not return a new vco value. check_patch.pl cleanup V6: simplify logic in intel_modeset_checks. V7: reorder an IF for readability and whitespace fix. V8: use dev_cdclk for tracking new cdclk during atomic V9: correctly handle vco 8640 when crtcs==0 V10: Clean up if else in crtcs==0 V11: Rebase for new intel_dpll_mgr.c Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Clint Taylor <clinton.a.taylor@intel.com> [vsyrjala: rebased due to churn] Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1463172100-24715-3-git-send-email-ville.syrjala@linux.intel.com
2016-05-13 23:41:21 +03:00
} else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
dev_priv->display.modeset_commit_cdclk =
skl_modeset_commit_cdclk;
dev_priv->display.modeset_calc_cdclk =
skl_modeset_calc_cdclk;
}
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
switch (INTEL_INFO(dev_priv)->gen) {
case 2:
dev_priv->display.queue_flip = intel_gen2_queue_flip;
break;
case 3:
dev_priv->display.queue_flip = intel_gen3_queue_flip;
break;
case 4:
case 5:
dev_priv->display.queue_flip = intel_gen4_queue_flip;
break;
case 6:
dev_priv->display.queue_flip = intel_gen6_queue_flip;
break;
case 7:
case 8: /* FIXME(BDW): Check that the gen8 RCS flip works. */
dev_priv->display.queue_flip = intel_gen7_queue_flip;
break;
case 9:
/* Drop through - unsupported since execlist only. */
default:
/* Default just returns -ENODEV to indicate unsupported */
dev_priv->display.queue_flip = intel_default_queue_flip;
}
}
/*
* Some BIOSes insist on assuming the GPU's pipe A is enabled at suspend,
* resume, or other times. This quirk makes sure that's the case for
* affected systems.
*/
static void quirk_pipea_force(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
dev_priv->quirks |= QUIRK_PIPEA_FORCE;
DRM_INFO("applying pipe a force quirk\n");
}
static void quirk_pipeb_force(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
dev_priv->quirks |= QUIRK_PIPEB_FORCE;
DRM_INFO("applying pipe b force quirk\n");
}
/*
* Some machines (Lenovo U160) do not work with SSC on LVDS for some reason
*/
static void quirk_ssc_force_disable(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
dev_priv->quirks |= QUIRK_LVDS_SSC_DISABLE;
DRM_INFO("applying lvds SSC disable quirk\n");
}
/*
* A machine (e.g. Acer Aspire 5734Z) may need to invert the panel backlight
* brightness value
*/
static void quirk_invert_brightness(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
dev_priv->quirks |= QUIRK_INVERT_BRIGHTNESS;
DRM_INFO("applying inverted panel brightness quirk\n");
}
/* Some VBT's incorrectly indicate no backlight is present */
static void quirk_backlight_present(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
dev_priv->quirks |= QUIRK_BACKLIGHT_PRESENT;
DRM_INFO("applying backlight present quirk\n");
}
struct intel_quirk {
int device;
int subsystem_vendor;
int subsystem_device;
void (*hook)(struct drm_device *dev);
};
/* For systems that don't have a meaningful PCI subdevice/subvendor ID */
struct intel_dmi_quirk {
void (*hook)(struct drm_device *dev);
const struct dmi_system_id (*dmi_id_list)[];
};
static int intel_dmi_reverse_brightness(const struct dmi_system_id *id)
{
DRM_INFO("Backlight polarity reversed on %s\n", id->ident);
return 1;
}
static const struct intel_dmi_quirk intel_dmi_quirks[] = {
{
.dmi_id_list = &(const struct dmi_system_id[]) {
{
.callback = intel_dmi_reverse_brightness,
.ident = "NCR Corporation",
.matches = {DMI_MATCH(DMI_SYS_VENDOR, "NCR Corporation"),
DMI_MATCH(DMI_PRODUCT_NAME, ""),
},
},
{ } /* terminating entry */
},
.hook = quirk_invert_brightness,
},
};
static struct intel_quirk intel_quirks[] = {
/* Toshiba Protege R-205, S-209 needs pipe A force quirk */
{ 0x2592, 0x1179, 0x0001, quirk_pipea_force },
/* ThinkPad T60 needs pipe A force quirk (bug #16494) */
{ 0x2782, 0x17aa, 0x201a, quirk_pipea_force },
/* 830 needs to leave pipe A & dpll A up */
{ 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force },
/* 830 needs to leave pipe B & dpll B up */
{ 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipeb_force },
/* Lenovo U160 cannot use SSC on LVDS */
{ 0x0046, 0x17aa, 0x3920, quirk_ssc_force_disable },
/* Sony Vaio Y cannot use SSC on LVDS */
{ 0x0046, 0x104d, 0x9076, quirk_ssc_force_disable },
/* Acer Aspire 5734Z must invert backlight brightness */
{ 0x2a42, 0x1025, 0x0459, quirk_invert_brightness },
/* Acer/eMachines G725 */
{ 0x2a42, 0x1025, 0x0210, quirk_invert_brightness },
/* Acer/eMachines e725 */
{ 0x2a42, 0x1025, 0x0212, quirk_invert_brightness },
/* Acer/Packard Bell NCL20 */
{ 0x2a42, 0x1025, 0x034b, quirk_invert_brightness },
/* Acer Aspire 4736Z */
{ 0x2a42, 0x1025, 0x0260, quirk_invert_brightness },
/* Acer Aspire 5336 */
{ 0x2a42, 0x1025, 0x048a, quirk_invert_brightness },
/* Acer C720 and C720P Chromebooks (Celeron 2955U) have backlights */
{ 0x0a06, 0x1025, 0x0a11, quirk_backlight_present },
/* Acer C720 Chromebook (Core i3 4005U) */
{ 0x0a16, 0x1025, 0x0a11, quirk_backlight_present },
/* Apple Macbook 2,1 (Core 2 T7400) */
{ 0x27a2, 0x8086, 0x7270, quirk_backlight_present },
/* Apple Macbook 4,1 */
{ 0x2a02, 0x106b, 0x00a1, quirk_backlight_present },
/* Toshiba CB35 Chromebook (Celeron 2955U) */
{ 0x0a06, 0x1179, 0x0a88, quirk_backlight_present },
/* HP Chromebook 14 (Celeron 2955U) */
{ 0x0a06, 0x103c, 0x21ed, quirk_backlight_present },
/* Dell Chromebook 11 */
{ 0x0a06, 0x1028, 0x0a35, quirk_backlight_present },
/* Dell Chromebook 11 (2015 version) */
{ 0x0a16, 0x1028, 0x0a35, quirk_backlight_present },
};
static void intel_init_quirks(struct drm_device *dev)
{
struct pci_dev *d = dev->pdev;
int i;
for (i = 0; i < ARRAY_SIZE(intel_quirks); i++) {
struct intel_quirk *q = &intel_quirks[i];
if (d->device == q->device &&
(d->subsystem_vendor == q->subsystem_vendor ||
q->subsystem_vendor == PCI_ANY_ID) &&
(d->subsystem_device == q->subsystem_device ||
q->subsystem_device == PCI_ANY_ID))
q->hook(dev);
}
for (i = 0; i < ARRAY_SIZE(intel_dmi_quirks); i++) {
if (dmi_check_system(*intel_dmi_quirks[i].dmi_id_list) != 0)
intel_dmi_quirks[i].hook(dev);
}
}
/* Disable the VGA plane that we never use */
static void i915_disable_vga(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u8 sr1;
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
i915_reg_t vga_reg = i915_vgacntrl_reg(dev);
/* WaEnableVGAAccessThroughIOPort:ctg,elk,ilk,snb,ivb,vlv,hsw */
vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO);
outb(SR01, VGA_SR_INDEX);
sr1 = inb(VGA_SR_DATA);
outb(sr1 | 1<<5, VGA_SR_DATA);
vga_put(dev->pdev, VGA_RSRC_LEGACY_IO);
udelay(300);
I915_WRITE(vga_reg, VGA_DISP_DISABLE);
POSTING_READ(vga_reg);
}
void intel_modeset_init_hw(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
intel_update_cdclk(dev);
dev_priv->atomic_cdclk_freq = dev_priv->cdclk_freq;
intel_init_clock_gating(dev);
intel_enable_gt_powersave(dev_priv);
}
drm/i915: Sanitize watermarks after hardware state readout (v4) Although we can do a good job of reading out hardware state, the graphics firmware may have programmed the watermarks in a creative way that doesn't match how i915 would have chosen to program them. We shouldn't trust the firmware's watermark programming, but should rather re-calculate how we think WM's should be programmed and then shove those values into the hardware. We can do this pretty easily by creating a dummy top-level state, running it through the check process to calculate all the values, and then just programming the watermarks for each CRTC. v2: Move watermark sanitization after our BIOS fb reconstruction; the watermark calculations that we do here need to look at pstate->fb, which isn't setup yet in intel_modeset_setup_hw_state(), even though we have an enabled & visible plane. v3: - Don't move 'active = optimal' watermark assignment; we just undo that change in the next patch anyway. (Ville) - Move atomic helper locking fix to separate patch. (Maarten) v4: - Grab connection_mutex before calling atomic helper to duplicate state. The connector loop inside the helper will throw a WARN if we don't hold something to protect the connector list (and the helper itself doesn't try to lock the list). - Make failure to calculate watermarks for inherited state a WARN() since it probably indicates a serious problem in either our state readout code or our watermark code for this platform. Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
2015-12-03 11:37:41 -08:00
/*
* Calculate what we think the watermarks should be for the state we've read
* out of the hardware and then immediately program those watermarks so that
* we ensure the hardware settings match our internal state.
*
* We can calculate what we think WM's should be by creating a duplicate of the
* current state (which was constructed during hardware readout) and running it
* through the atomic check code to calculate new watermark values in the
* state object.
*/
static void sanitize_watermarks(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_atomic_state *state;
struct drm_crtc *crtc;
struct drm_crtc_state *cstate;
struct drm_modeset_acquire_ctx ctx;
int ret;
int i;
/* Only supported on platforms that use atomic watermark design */
drm/i915: Add two-stage ILK-style watermark programming (v11) In addition to calculating final watermarks, let's also pre-calculate a set of intermediate watermark values at atomic check time. These intermediate watermarks are a combination of the watermarks for the old state and the new state; they should satisfy the requirements of both states which means they can be programmed immediately when we commit the atomic state (without waiting for a vblank). Once the vblank does happen, we can then re-program watermarks to the more optimal final value. v2: Significant rebasing/rewriting. v3: - Move 'need_postvbl_update' flag to CRTC state (Daniel) - Don't forget to check intermediate watermark values for validity (Maarten) - Don't due async watermark optimization; just do it at the end of the atomic transaction, after waiting for vblanks. We do want it to be async eventually, but adding that now will cause more trouble for Maarten's in-progress work. (Maarten) - Don't allocate space in crtc_state for intermediate watermarks on platforms that don't need it (gen9+). - Move WaCxSRDisabledForSpriteScaling:ivb into intel_begin_crtc_commit now that ilk_update_wm is gone. v4: - Add a wm_mutex to cover updates to intel_crtc->active and the need_postvbl_update flag. Since we don't have async yet it isn't terribly important yet, but might as well add it now. - Change interface to program watermarks. Platforms will now expose .initial_watermarks() and .optimize_watermarks() functions to do watermark programming. These should lock wm_mutex, copy the appropriate state values into intel_crtc->active, and then call the internal program watermarks function. v5: - Skip intermediate watermark calculation/check during initial hardware readout since we don't trust the existing HW values (and don't have valid values of our own yet). - Don't try to call .optimize_watermarks() on platforms that don't have atomic watermarks yet. (Maarten) v6: - Rebase v7: - Further rebase v8: - A few minor indentation and line length fixes v9: - Yet another rebase since Maarten's patches reworked a bunch of the code (wm_pre, wm_post, etc.) that this was previously based on. v10: - Move wm_mutex to dev_priv to protect against racing commits against disjoint CRTC sets. (Maarten) - Drop unnecessary clearing of cstate->wm.need_postvbl_update (Maarten) v11: - Now that we've moved to atomic watermark updates, make sure we call the proper function to program watermarks in {ironlake,haswell}_crtc_enable(); the failure to do so on the previous patch iteration led to us not actually programming the watermarks before turning on the CRTC, which was the cause of the underruns that the CI system was seeing. - Fix inverted logic for determining when to optimize watermarks. We were needlessly optimizing when the intermediate/optimal values were the same (harmless), but not actually optimizing when they differed (also harmless, but wasteful from a power/bandwidth perspective). Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1456276813-5689-1-git-send-email-matthew.d.roper@intel.com
2016-02-23 17:20:13 -08:00
if (!dev_priv->display.optimize_watermarks)
drm/i915: Sanitize watermarks after hardware state readout (v4) Although we can do a good job of reading out hardware state, the graphics firmware may have programmed the watermarks in a creative way that doesn't match how i915 would have chosen to program them. We shouldn't trust the firmware's watermark programming, but should rather re-calculate how we think WM's should be programmed and then shove those values into the hardware. We can do this pretty easily by creating a dummy top-level state, running it through the check process to calculate all the values, and then just programming the watermarks for each CRTC. v2: Move watermark sanitization after our BIOS fb reconstruction; the watermark calculations that we do here need to look at pstate->fb, which isn't setup yet in intel_modeset_setup_hw_state(), even though we have an enabled & visible plane. v3: - Don't move 'active = optimal' watermark assignment; we just undo that change in the next patch anyway. (Ville) - Move atomic helper locking fix to separate patch. (Maarten) v4: - Grab connection_mutex before calling atomic helper to duplicate state. The connector loop inside the helper will throw a WARN if we don't hold something to protect the connector list (and the helper itself doesn't try to lock the list). - Make failure to calculate watermarks for inherited state a WARN() since it probably indicates a serious problem in either our state readout code or our watermark code for this platform. Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
2015-12-03 11:37:41 -08:00
return;
/*
* We need to hold connection_mutex before calling duplicate_state so
* that the connector loop is protected.
*/
drm_modeset_acquire_init(&ctx, 0);
retry:
ret = drm_modeset_lock_all_ctx(dev, &ctx);
drm/i915: Sanitize watermarks after hardware state readout (v4) Although we can do a good job of reading out hardware state, the graphics firmware may have programmed the watermarks in a creative way that doesn't match how i915 would have chosen to program them. We shouldn't trust the firmware's watermark programming, but should rather re-calculate how we think WM's should be programmed and then shove those values into the hardware. We can do this pretty easily by creating a dummy top-level state, running it through the check process to calculate all the values, and then just programming the watermarks for each CRTC. v2: Move watermark sanitization after our BIOS fb reconstruction; the watermark calculations that we do here need to look at pstate->fb, which isn't setup yet in intel_modeset_setup_hw_state(), even though we have an enabled & visible plane. v3: - Don't move 'active = optimal' watermark assignment; we just undo that change in the next patch anyway. (Ville) - Move atomic helper locking fix to separate patch. (Maarten) v4: - Grab connection_mutex before calling atomic helper to duplicate state. The connector loop inside the helper will throw a WARN if we don't hold something to protect the connector list (and the helper itself doesn't try to lock the list). - Make failure to calculate watermarks for inherited state a WARN() since it probably indicates a serious problem in either our state readout code or our watermark code for this platform. Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
2015-12-03 11:37:41 -08:00
if (ret == -EDEADLK) {
drm_modeset_backoff(&ctx);
goto retry;
} else if (WARN_ON(ret)) {
goto fail;
drm/i915: Sanitize watermarks after hardware state readout (v4) Although we can do a good job of reading out hardware state, the graphics firmware may have programmed the watermarks in a creative way that doesn't match how i915 would have chosen to program them. We shouldn't trust the firmware's watermark programming, but should rather re-calculate how we think WM's should be programmed and then shove those values into the hardware. We can do this pretty easily by creating a dummy top-level state, running it through the check process to calculate all the values, and then just programming the watermarks for each CRTC. v2: Move watermark sanitization after our BIOS fb reconstruction; the watermark calculations that we do here need to look at pstate->fb, which isn't setup yet in intel_modeset_setup_hw_state(), even though we have an enabled & visible plane. v3: - Don't move 'active = optimal' watermark assignment; we just undo that change in the next patch anyway. (Ville) - Move atomic helper locking fix to separate patch. (Maarten) v4: - Grab connection_mutex before calling atomic helper to duplicate state. The connector loop inside the helper will throw a WARN if we don't hold something to protect the connector list (and the helper itself doesn't try to lock the list). - Make failure to calculate watermarks for inherited state a WARN() since it probably indicates a serious problem in either our state readout code or our watermark code for this platform. Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
2015-12-03 11:37:41 -08:00
}
state = drm_atomic_helper_duplicate_state(dev, &ctx);
if (WARN_ON(IS_ERR(state)))
goto fail;
drm/i915: Sanitize watermarks after hardware state readout (v4) Although we can do a good job of reading out hardware state, the graphics firmware may have programmed the watermarks in a creative way that doesn't match how i915 would have chosen to program them. We shouldn't trust the firmware's watermark programming, but should rather re-calculate how we think WM's should be programmed and then shove those values into the hardware. We can do this pretty easily by creating a dummy top-level state, running it through the check process to calculate all the values, and then just programming the watermarks for each CRTC. v2: Move watermark sanitization after our BIOS fb reconstruction; the watermark calculations that we do here need to look at pstate->fb, which isn't setup yet in intel_modeset_setup_hw_state(), even though we have an enabled & visible plane. v3: - Don't move 'active = optimal' watermark assignment; we just undo that change in the next patch anyway. (Ville) - Move atomic helper locking fix to separate patch. (Maarten) v4: - Grab connection_mutex before calling atomic helper to duplicate state. The connector loop inside the helper will throw a WARN if we don't hold something to protect the connector list (and the helper itself doesn't try to lock the list). - Make failure to calculate watermarks for inherited state a WARN() since it probably indicates a serious problem in either our state readout code or our watermark code for this platform. Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
2015-12-03 11:37:41 -08:00
drm/i915: Add two-stage ILK-style watermark programming (v11) In addition to calculating final watermarks, let's also pre-calculate a set of intermediate watermark values at atomic check time. These intermediate watermarks are a combination of the watermarks for the old state and the new state; they should satisfy the requirements of both states which means they can be programmed immediately when we commit the atomic state (without waiting for a vblank). Once the vblank does happen, we can then re-program watermarks to the more optimal final value. v2: Significant rebasing/rewriting. v3: - Move 'need_postvbl_update' flag to CRTC state (Daniel) - Don't forget to check intermediate watermark values for validity (Maarten) - Don't due async watermark optimization; just do it at the end of the atomic transaction, after waiting for vblanks. We do want it to be async eventually, but adding that now will cause more trouble for Maarten's in-progress work. (Maarten) - Don't allocate space in crtc_state for intermediate watermarks on platforms that don't need it (gen9+). - Move WaCxSRDisabledForSpriteScaling:ivb into intel_begin_crtc_commit now that ilk_update_wm is gone. v4: - Add a wm_mutex to cover updates to intel_crtc->active and the need_postvbl_update flag. Since we don't have async yet it isn't terribly important yet, but might as well add it now. - Change interface to program watermarks. Platforms will now expose .initial_watermarks() and .optimize_watermarks() functions to do watermark programming. These should lock wm_mutex, copy the appropriate state values into intel_crtc->active, and then call the internal program watermarks function. v5: - Skip intermediate watermark calculation/check during initial hardware readout since we don't trust the existing HW values (and don't have valid values of our own yet). - Don't try to call .optimize_watermarks() on platforms that don't have atomic watermarks yet. (Maarten) v6: - Rebase v7: - Further rebase v8: - A few minor indentation and line length fixes v9: - Yet another rebase since Maarten's patches reworked a bunch of the code (wm_pre, wm_post, etc.) that this was previously based on. v10: - Move wm_mutex to dev_priv to protect against racing commits against disjoint CRTC sets. (Maarten) - Drop unnecessary clearing of cstate->wm.need_postvbl_update (Maarten) v11: - Now that we've moved to atomic watermark updates, make sure we call the proper function to program watermarks in {ironlake,haswell}_crtc_enable(); the failure to do so on the previous patch iteration led to us not actually programming the watermarks before turning on the CRTC, which was the cause of the underruns that the CI system was seeing. - Fix inverted logic for determining when to optimize watermarks. We were needlessly optimizing when the intermediate/optimal values were the same (harmless), but not actually optimizing when they differed (also harmless, but wasteful from a power/bandwidth perspective). Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1456276813-5689-1-git-send-email-matthew.d.roper@intel.com
2016-02-23 17:20:13 -08:00
/*
* Hardware readout is the only time we don't want to calculate
* intermediate watermarks (since we don't trust the current
* watermarks).
*/
to_intel_atomic_state(state)->skip_intermediate_wm = true;
drm/i915: Sanitize watermarks after hardware state readout (v4) Although we can do a good job of reading out hardware state, the graphics firmware may have programmed the watermarks in a creative way that doesn't match how i915 would have chosen to program them. We shouldn't trust the firmware's watermark programming, but should rather re-calculate how we think WM's should be programmed and then shove those values into the hardware. We can do this pretty easily by creating a dummy top-level state, running it through the check process to calculate all the values, and then just programming the watermarks for each CRTC. v2: Move watermark sanitization after our BIOS fb reconstruction; the watermark calculations that we do here need to look at pstate->fb, which isn't setup yet in intel_modeset_setup_hw_state(), even though we have an enabled & visible plane. v3: - Don't move 'active = optimal' watermark assignment; we just undo that change in the next patch anyway. (Ville) - Move atomic helper locking fix to separate patch. (Maarten) v4: - Grab connection_mutex before calling atomic helper to duplicate state. The connector loop inside the helper will throw a WARN if we don't hold something to protect the connector list (and the helper itself doesn't try to lock the list). - Make failure to calculate watermarks for inherited state a WARN() since it probably indicates a serious problem in either our state readout code or our watermark code for this platform. Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
2015-12-03 11:37:41 -08:00
ret = intel_atomic_check(dev, state);
if (ret) {
/*
* If we fail here, it means that the hardware appears to be
* programmed in a way that shouldn't be possible, given our
* understanding of watermark requirements. This might mean a
* mistake in the hardware readout code or a mistake in the
* watermark calculations for a given platform. Raise a WARN
* so that this is noticeable.
*
* If this actually happens, we'll have to just leave the
* BIOS-programmed watermarks untouched and hope for the best.
*/
WARN(true, "Could not determine valid watermarks for inherited state\n");
goto fail;
drm/i915: Sanitize watermarks after hardware state readout (v4) Although we can do a good job of reading out hardware state, the graphics firmware may have programmed the watermarks in a creative way that doesn't match how i915 would have chosen to program them. We shouldn't trust the firmware's watermark programming, but should rather re-calculate how we think WM's should be programmed and then shove those values into the hardware. We can do this pretty easily by creating a dummy top-level state, running it through the check process to calculate all the values, and then just programming the watermarks for each CRTC. v2: Move watermark sanitization after our BIOS fb reconstruction; the watermark calculations that we do here need to look at pstate->fb, which isn't setup yet in intel_modeset_setup_hw_state(), even though we have an enabled & visible plane. v3: - Don't move 'active = optimal' watermark assignment; we just undo that change in the next patch anyway. (Ville) - Move atomic helper locking fix to separate patch. (Maarten) v4: - Grab connection_mutex before calling atomic helper to duplicate state. The connector loop inside the helper will throw a WARN if we don't hold something to protect the connector list (and the helper itself doesn't try to lock the list). - Make failure to calculate watermarks for inherited state a WARN() since it probably indicates a serious problem in either our state readout code or our watermark code for this platform. Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
2015-12-03 11:37:41 -08:00
}
/* Write calculated watermark values back */
for_each_crtc_in_state(state, crtc, cstate, i) {
struct intel_crtc_state *cs = to_intel_crtc_state(cstate);
drm/i915: Add two-stage ILK-style watermark programming (v11) In addition to calculating final watermarks, let's also pre-calculate a set of intermediate watermark values at atomic check time. These intermediate watermarks are a combination of the watermarks for the old state and the new state; they should satisfy the requirements of both states which means they can be programmed immediately when we commit the atomic state (without waiting for a vblank). Once the vblank does happen, we can then re-program watermarks to the more optimal final value. v2: Significant rebasing/rewriting. v3: - Move 'need_postvbl_update' flag to CRTC state (Daniel) - Don't forget to check intermediate watermark values for validity (Maarten) - Don't due async watermark optimization; just do it at the end of the atomic transaction, after waiting for vblanks. We do want it to be async eventually, but adding that now will cause more trouble for Maarten's in-progress work. (Maarten) - Don't allocate space in crtc_state for intermediate watermarks on platforms that don't need it (gen9+). - Move WaCxSRDisabledForSpriteScaling:ivb into intel_begin_crtc_commit now that ilk_update_wm is gone. v4: - Add a wm_mutex to cover updates to intel_crtc->active and the need_postvbl_update flag. Since we don't have async yet it isn't terribly important yet, but might as well add it now. - Change interface to program watermarks. Platforms will now expose .initial_watermarks() and .optimize_watermarks() functions to do watermark programming. These should lock wm_mutex, copy the appropriate state values into intel_crtc->active, and then call the internal program watermarks function. v5: - Skip intermediate watermark calculation/check during initial hardware readout since we don't trust the existing HW values (and don't have valid values of our own yet). - Don't try to call .optimize_watermarks() on platforms that don't have atomic watermarks yet. (Maarten) v6: - Rebase v7: - Further rebase v8: - A few minor indentation and line length fixes v9: - Yet another rebase since Maarten's patches reworked a bunch of the code (wm_pre, wm_post, etc.) that this was previously based on. v10: - Move wm_mutex to dev_priv to protect against racing commits against disjoint CRTC sets. (Maarten) - Drop unnecessary clearing of cstate->wm.need_postvbl_update (Maarten) v11: - Now that we've moved to atomic watermark updates, make sure we call the proper function to program watermarks in {ironlake,haswell}_crtc_enable(); the failure to do so on the previous patch iteration led to us not actually programming the watermarks before turning on the CRTC, which was the cause of the underruns that the CI system was seeing. - Fix inverted logic for determining when to optimize watermarks. We were needlessly optimizing when the intermediate/optimal values were the same (harmless), but not actually optimizing when they differed (also harmless, but wasteful from a power/bandwidth perspective). Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1456276813-5689-1-git-send-email-matthew.d.roper@intel.com
2016-02-23 17:20:13 -08:00
cs->wm.need_postvbl_update = true;
dev_priv->display.optimize_watermarks(cs);
drm/i915: Sanitize watermarks after hardware state readout (v4) Although we can do a good job of reading out hardware state, the graphics firmware may have programmed the watermarks in a creative way that doesn't match how i915 would have chosen to program them. We shouldn't trust the firmware's watermark programming, but should rather re-calculate how we think WM's should be programmed and then shove those values into the hardware. We can do this pretty easily by creating a dummy top-level state, running it through the check process to calculate all the values, and then just programming the watermarks for each CRTC. v2: Move watermark sanitization after our BIOS fb reconstruction; the watermark calculations that we do here need to look at pstate->fb, which isn't setup yet in intel_modeset_setup_hw_state(), even though we have an enabled & visible plane. v3: - Don't move 'active = optimal' watermark assignment; we just undo that change in the next patch anyway. (Ville) - Move atomic helper locking fix to separate patch. (Maarten) v4: - Grab connection_mutex before calling atomic helper to duplicate state. The connector loop inside the helper will throw a WARN if we don't hold something to protect the connector list (and the helper itself doesn't try to lock the list). - Make failure to calculate watermarks for inherited state a WARN() since it probably indicates a serious problem in either our state readout code or our watermark code for this platform. Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
2015-12-03 11:37:41 -08:00
}
drm_atomic_state_free(state);
fail:
drm/i915: Sanitize watermarks after hardware state readout (v4) Although we can do a good job of reading out hardware state, the graphics firmware may have programmed the watermarks in a creative way that doesn't match how i915 would have chosen to program them. We shouldn't trust the firmware's watermark programming, but should rather re-calculate how we think WM's should be programmed and then shove those values into the hardware. We can do this pretty easily by creating a dummy top-level state, running it through the check process to calculate all the values, and then just programming the watermarks for each CRTC. v2: Move watermark sanitization after our BIOS fb reconstruction; the watermark calculations that we do here need to look at pstate->fb, which isn't setup yet in intel_modeset_setup_hw_state(), even though we have an enabled & visible plane. v3: - Don't move 'active = optimal' watermark assignment; we just undo that change in the next patch anyway. (Ville) - Move atomic helper locking fix to separate patch. (Maarten) v4: - Grab connection_mutex before calling atomic helper to duplicate state. The connector loop inside the helper will throw a WARN if we don't hold something to protect the connector list (and the helper itself doesn't try to lock the list). - Make failure to calculate watermarks for inherited state a WARN() since it probably indicates a serious problem in either our state readout code or our watermark code for this platform. Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
2015-12-03 11:37:41 -08:00
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
}
void intel_modeset_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = to_i915(dev);
struct i915_ggtt *ggtt = &dev_priv->ggtt;
int sprite, ret;
enum pipe pipe;
struct intel_crtc *crtc;
drm_mode_config_init(dev);
dev->mode_config.min_width = 0;
dev->mode_config.min_height = 0;
dev->mode_config.preferred_depth = 24;
dev->mode_config.prefer_shadow = 1;
dev->mode_config.allow_fb_modifiers = true;
dev->mode_config.funcs = &intel_mode_funcs;
intel_init_quirks(dev);
intel_init_pm(dev);
if (INTEL_INFO(dev)->num_pipes == 0)
return;
drm/i915: Preserve SSC earlier Commit 92122789b2d6 ("drm/i915: preserve SSC if previously set v3") added code to intel_modeset_gem_init to override the SSC status read from VBT with the SSC status set by BIOS. However, intel_modeset_gem_init is invoked *after* intel_modeset_init, which calls intel_setup_outputs, which *modifies* SSC status by way of intel_init_pch_refclk. So unlike advertised, intel_modeset_gem_init doesn't preserve the SSC status set by BIOS but whatever intel_init_pch_refclk decided on. This is a problem on dual gpu laptops such as the MacBook Pro which require either a handler to switch DDC lines, or the discrete gpu to proxy DDC/AUX communication: Both the handler and the discrete gpu may initialize after the i915 driver, and consequently, an LVDS connector may initially seem disconnected and the SSC therefore is disabled by intel_init_pch_refclk, but on reprobe the connector may turn out to be connected and the SSC must then be enabled. Due to 92122789b2d6 however, the SSC is not enabled on reprobe since it is assumed BIOS disabled it while in fact it was disabled by intel_init_pch_refclk. Also, because the SSC status is preserved so late, the preserved value only ever gets used on resume but not on panel initialization: intel_modeset_init calls intel_init_display which indirectly calls intel_panel_use_ssc via multiple subroutines, *before* the BIOS value overrides the VBT value in intel_modeset_gem_init (intel_panel_use_ssc is the sole user of dev_priv->vbt.lvds_use_ssc). Fix this by moving the code introduced by 92122789b2d6 from intel_modeset_gem_init to intel_modeset_init before the invocation of intel_setup_outputs and intel_init_display. Add a DRM_DEBUG_KMS as suggested way back by Jani: http://lists.freedesktop.org/archives/intel-gfx/2014-June/046666.html Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=88861 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61115 Tested-by: Paul Hordiienko <pvt.gord@gmail.com> [MBP 6,2 2010 intel ILK + nvidia GT216 pre-retina] Tested-by: William Brown <william@blackhats.net.au> [MBP 8,2 2011 intel SNB + amd turks pre-retina] Tested-by: Lukas Wunner <lukas@wunner.de> [MBP 9,1 2012 intel IVB + nvidia GK107 pre-retina] Tested-by: Bruno Bierbaumer <bruno@bierbaumer.net> [MBP 11,3 2013 intel HSW + nvidia GK107 retina -- work in progress] Fixes: 92122789b2d6 ("drm/i915: preserve SSC if previously set v3") Signed-off-by: Lukas Wunner <lukas@wunner.de> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
2015-07-15 13:57:35 +02:00
/*
* There may be no VBT; and if the BIOS enabled SSC we can
* just keep using it to avoid unnecessary flicker. Whereas if the
* BIOS isn't using it, don't assume it will work even if the VBT
* indicates as much.
*/
if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) {
bool bios_lvds_use_ssc = !!(I915_READ(PCH_DREF_CONTROL) &
DREF_SSC1_ENABLE);
if (dev_priv->vbt.lvds_use_ssc != bios_lvds_use_ssc) {
DRM_DEBUG_KMS("SSC %sabled by BIOS, overriding VBT which says %sabled\n",
bios_lvds_use_ssc ? "en" : "dis",
dev_priv->vbt.lvds_use_ssc ? "en" : "dis");
dev_priv->vbt.lvds_use_ssc = bios_lvds_use_ssc;
}
}
if (IS_GEN2(dev)) {
dev->mode_config.max_width = 2048;
dev->mode_config.max_height = 2048;
} else if (IS_GEN3(dev)) {
dev->mode_config.max_width = 4096;
dev->mode_config.max_height = 4096;
} else {
dev->mode_config.max_width = 8192;
dev->mode_config.max_height = 8192;
}
if (IS_845G(dev) || IS_I865G(dev)) {
dev->mode_config.cursor_width = IS_845G(dev) ? 64 : 512;
dev->mode_config.cursor_height = 1023;
} else if (IS_GEN2(dev)) {
dev->mode_config.cursor_width = GEN2_CURSOR_WIDTH;
dev->mode_config.cursor_height = GEN2_CURSOR_HEIGHT;
} else {
dev->mode_config.cursor_width = MAX_CURSOR_WIDTH;
dev->mode_config.cursor_height = MAX_CURSOR_HEIGHT;
}
dev->mode_config.fb_base = ggtt->mappable_base;
DRM_DEBUG_KMS("%d display pipe%s available.\n",
INTEL_INFO(dev)->num_pipes,
INTEL_INFO(dev)->num_pipes > 1 ? "s" : "");
for_each_pipe(dev_priv, pipe) {
intel_crtc_init(dev, pipe);
for_each_sprite(dev_priv, pipe, sprite) {
ret = intel_plane_init(dev, pipe, sprite);
if (ret)
DRM_DEBUG_KMS("pipe %c sprite %c init failed: %d\n",
pipe_name(pipe), sprite_name(pipe, sprite), ret);
}
}
intel_update_czclk(dev_priv);
intel_update_cdclk(dev);
intel_shared_dpll_init(dev);
if (dev_priv->max_cdclk_freq == 0)
intel_update_max_cdclk(dev);
/* Just disable it once at startup */
i915_disable_vga(dev);
intel_setup_outputs(dev);
drm: Split connection_mutex out of mode_config.mutex (v3) After the split-out of crtc locks from the big mode_config.mutex there's still two major areas it protects: - Various connector probe states, like connector->status, EDID properties, probed mode lists and similar information. - The links from connector->encoder and encoder->crtc and other modeset-relevant connector state (e.g. properties which control the panel fitter). The later is used by modeset operations. But they don't really care about the former since it's allowed to e.g. enable a disconnected VGA output or with a mode not in the probed list. Thus far this hasn't been a problem, but for the atomic modeset conversion Rob Clark needs to convert all modeset relevant locks into w/w locks. This is required because the order of acquisition is determined by how userspace supplies the atomic modeset data. This has run into troubles in the detect path since the i915 load detect code needs _both_ protections offered by the mode_config.mutex: It updates probe state and it needs to change the modeset configuration to enable the temporary load detect pipe. The big deal here is that for the probe/detect users of this lock a plain mutex fits best, but for atomic modesets we really want a w/w mutex. To fix this lets split out a new connection_mutex lock for the modeset relevant parts. For simplicity I've decided to only add one additional lock for all connector/encoder links and modeset configuration states. We have piles of different modeset objects in addition to those (like bridges or panels), so adding per-object locks would be much more effort. Also, we're guaranteed (at least for now) to do a full modeset if we need to acquire this lock. Which means that fine-grained locking is fairly irrelevant compared to the amount of time the full modeset will take. I've done a full audit, and there's just a few things that justify special focus: - Locking in drm_sysfs.c is almost completely absent. We should sprinkle mode_config.connection_mutex over this file a bit, but since it already lacks mode_config.mutex this patch wont make the situation any worse. This is material for a follow-up patch. - omap has a omap_framebuffer_flush function which walks the connector->encoder->crtc links and is called from many contexts. Some look like they don't acquire mode_config.mutex, so this is already racy. Again fixing this is material for a separate patch. - The radeon hot_plug function to retrain DP links looks at connector->dpms. Currently this happens without any locking, so is already racy. I think radeon_hotplug_work_func should gain mutex_lock/unlock calls for the mode_config.connection_mutex. - Same applies to i915's intel_dp_hot_plug. But again, this is already racy. - i915 load_detect code needs to acquire this lock. Which means the w/w dance due to Rob's work will be nicely contained to _just_ this function. I've added fixme comments everywhere where it looks suspicious but in the sysfs code. After a quick irc discussion with Dave Airlie it sounds like the lack of locking in there is due to sysfs cleanup fun at module unload. v1: original (only compile tested) v2: missing mutex_init(), etc (from Rob Clark) v3: i915 needs more care in the conversion: - Protect the edp pp logic with the connection_mutex. - Use connection_mutex in the backlight code due to get_pipe_from_connector. - Use drm_modeset_lock_all in suspend/resume paths. - Update lock checks in the overlay code. Cc: Alex Deucher <alexdeucher@gmail.com> Cc: Rob Clark <robdclark@gmail.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Rob Clark <robdclark@gmail.com>
2014-05-29 23:54:47 +02:00
drm_modeset_lock_all(dev);
intel_modeset_setup_hw_state(dev);
drm: Split connection_mutex out of mode_config.mutex (v3) After the split-out of crtc locks from the big mode_config.mutex there's still two major areas it protects: - Various connector probe states, like connector->status, EDID properties, probed mode lists and similar information. - The links from connector->encoder and encoder->crtc and other modeset-relevant connector state (e.g. properties which control the panel fitter). The later is used by modeset operations. But they don't really care about the former since it's allowed to e.g. enable a disconnected VGA output or with a mode not in the probed list. Thus far this hasn't been a problem, but for the atomic modeset conversion Rob Clark needs to convert all modeset relevant locks into w/w locks. This is required because the order of acquisition is determined by how userspace supplies the atomic modeset data. This has run into troubles in the detect path since the i915 load detect code needs _both_ protections offered by the mode_config.mutex: It updates probe state and it needs to change the modeset configuration to enable the temporary load detect pipe. The big deal here is that for the probe/detect users of this lock a plain mutex fits best, but for atomic modesets we really want a w/w mutex. To fix this lets split out a new connection_mutex lock for the modeset relevant parts. For simplicity I've decided to only add one additional lock for all connector/encoder links and modeset configuration states. We have piles of different modeset objects in addition to those (like bridges or panels), so adding per-object locks would be much more effort. Also, we're guaranteed (at least for now) to do a full modeset if we need to acquire this lock. Which means that fine-grained locking is fairly irrelevant compared to the amount of time the full modeset will take. I've done a full audit, and there's just a few things that justify special focus: - Locking in drm_sysfs.c is almost completely absent. We should sprinkle mode_config.connection_mutex over this file a bit, but since it already lacks mode_config.mutex this patch wont make the situation any worse. This is material for a follow-up patch. - omap has a omap_framebuffer_flush function which walks the connector->encoder->crtc links and is called from many contexts. Some look like they don't acquire mode_config.mutex, so this is already racy. Again fixing this is material for a separate patch. - The radeon hot_plug function to retrain DP links looks at connector->dpms. Currently this happens without any locking, so is already racy. I think radeon_hotplug_work_func should gain mutex_lock/unlock calls for the mode_config.connection_mutex. - Same applies to i915's intel_dp_hot_plug. But again, this is already racy. - i915 load_detect code needs to acquire this lock. Which means the w/w dance due to Rob's work will be nicely contained to _just_ this function. I've added fixme comments everywhere where it looks suspicious but in the sysfs code. After a quick irc discussion with Dave Airlie it sounds like the lack of locking in there is due to sysfs cleanup fun at module unload. v1: original (only compile tested) v2: missing mutex_init(), etc (from Rob Clark) v3: i915 needs more care in the conversion: - Protect the edp pp logic with the connection_mutex. - Use connection_mutex in the backlight code due to get_pipe_from_connector. - Use drm_modeset_lock_all in suspend/resume paths. - Update lock checks in the overlay code. Cc: Alex Deucher <alexdeucher@gmail.com> Cc: Rob Clark <robdclark@gmail.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Rob Clark <robdclark@gmail.com>
2014-05-29 23:54:47 +02:00
drm_modeset_unlock_all(dev);
for_each_intel_crtc(dev, crtc) {
struct intel_initial_plane_config plane_config = {};
if (!crtc->active)
continue;
/*
* Note that reserving the BIOS fb up front prevents us
* from stuffing other stolen allocations like the ring
* on top. This prevents some ugliness at boot time, and
* can even allow for smooth boot transitions if the BIOS
* fb is large enough for the active pipe configuration.
*/
dev_priv->display.get_initial_plane_config(crtc,
&plane_config);
/*
* If the fb is shared between multiple heads, we'll
* just get the first one.
*/
intel_find_initial_plane_obj(crtc, &plane_config);
}
drm/i915: Sanitize watermarks after hardware state readout (v4) Although we can do a good job of reading out hardware state, the graphics firmware may have programmed the watermarks in a creative way that doesn't match how i915 would have chosen to program them. We shouldn't trust the firmware's watermark programming, but should rather re-calculate how we think WM's should be programmed and then shove those values into the hardware. We can do this pretty easily by creating a dummy top-level state, running it through the check process to calculate all the values, and then just programming the watermarks for each CRTC. v2: Move watermark sanitization after our BIOS fb reconstruction; the watermark calculations that we do here need to look at pstate->fb, which isn't setup yet in intel_modeset_setup_hw_state(), even though we have an enabled & visible plane. v3: - Don't move 'active = optimal' watermark assignment; we just undo that change in the next patch anyway. (Ville) - Move atomic helper locking fix to separate patch. (Maarten) v4: - Grab connection_mutex before calling atomic helper to duplicate state. The connector loop inside the helper will throw a WARN if we don't hold something to protect the connector list (and the helper itself doesn't try to lock the list). - Make failure to calculate watermarks for inherited state a WARN() since it probably indicates a serious problem in either our state readout code or our watermark code for this platform. Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
2015-12-03 11:37:41 -08:00
/*
* Make sure hardware watermarks really match the state we read out.
* Note that we need to do this after reconstructing the BIOS fb's
* since the watermark calculation done here will use pstate->fb.
*/
sanitize_watermarks(dev);
}
static void intel_enable_pipe_a(struct drm_device *dev)
{
struct intel_connector *connector;
struct drm_connector *crt = NULL;
struct intel_load_detect_pipe load_detect_temp;
struct drm_modeset_acquire_ctx *ctx = dev->mode_config.acquire_ctx;
/* We can't just switch on the pipe A, we need to set things up with a
* proper mode and output configuration. As a gross hack, enable pipe A
* by enabling the load detect pipe once. */
for_each_intel_connector(dev, connector) {
if (connector->encoder->type == INTEL_OUTPUT_ANALOG) {
crt = &connector->base;
break;
}
}
if (!crt)
return;
if (intel_get_load_detect_pipe(crt, NULL, &load_detect_temp, ctx))
intel_release_load_detect_pipe(crt, &load_detect_temp, ctx);
}
static bool
intel_check_plane_mapping(struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 val;
if (INTEL_INFO(dev)->num_pipes == 1)
return true;
val = I915_READ(DSPCNTR(!crtc->plane));
if ((val & DISPLAY_PLANE_ENABLE) &&
(!!(val & DISPPLANE_SEL_PIPE_MASK) == crtc->pipe))
return false;
return true;
}
static bool intel_crtc_has_encoders(struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
struct intel_encoder *encoder;
for_each_encoder_on_crtc(dev, &crtc->base, encoder)
return true;
return false;
}
static bool intel_encoder_has_connectors(struct intel_encoder *encoder)
{
struct drm_device *dev = encoder->base.dev;
struct intel_connector *connector;
for_each_connector_on_encoder(dev, &encoder->base, connector)
return true;
return false;
}
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
static void intel_sanitize_crtc(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;
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
/* Clear any frame start delays used for debugging left by the BIOS */
if (!transcoder_is_dsi(cpu_transcoder)) {
i915_reg_t reg = PIPECONF(cpu_transcoder);
I915_WRITE(reg,
I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
}
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
/* restore vblank interrupts to correct state */
drm/irq: Add drm_crtc_vblank_reset At driver load we need to tell the vblank code about the state of the pipes, so that the logic around reject vblank_get when the pipe is off works correctly. Thus far i915 used drm_vblank_off, but one of the side-effects of it is that it also saves the vblank counter. And for that it calls down into the ->get_vblank_counter hook. Which isn't really a good idea when the pipe is off for a few reasons: - With runtime pm the register might not respond. - If the pipe is off some datastructures might not be around or unitialized. The later is what blew up on gen3: We look at intel_crtc->config to compute the vblank counter, and for a disabled pipe at boot-up that's just not there. Thus far this was papered over by a check for intel_crtc->active, but I want to get rid of that (since it's fairly race, vblank hooks are called from all kinds of places). So prep for that by adding a _reset functions which only does what we really need to be done at driver load: Mark the vblank pipe as off, but don't do any vblank counter saving or event flushing - neither of that is required. v2: Clarify the code flow slightly as suggested by Ville. v3: Fix kerneldoc spelling, spotted by Laurent. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Cc: Imre Deak <imre.deak@intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> (v2) Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2015-02-13 21:03:42 +01:00
drm_crtc_vblank_reset(&crtc->base);
if (crtc->active) {
struct intel_plane *plane;
drm/irq: Add drm_crtc_vblank_reset At driver load we need to tell the vblank code about the state of the pipes, so that the logic around reject vblank_get when the pipe is off works correctly. Thus far i915 used drm_vblank_off, but one of the side-effects of it is that it also saves the vblank counter. And for that it calls down into the ->get_vblank_counter hook. Which isn't really a good idea when the pipe is off for a few reasons: - With runtime pm the register might not respond. - If the pipe is off some datastructures might not be around or unitialized. The later is what blew up on gen3: We look at intel_crtc->config to compute the vblank counter, and for a disabled pipe at boot-up that's just not there. Thus far this was papered over by a check for intel_crtc->active, but I want to get rid of that (since it's fairly race, vblank hooks are called from all kinds of places). So prep for that by adding a _reset functions which only does what we really need to be done at driver load: Mark the vblank pipe as off, but don't do any vblank counter saving or event flushing - neither of that is required. v2: Clarify the code flow slightly as suggested by Ville. v3: Fix kerneldoc spelling, spotted by Laurent. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Cc: Imre Deak <imre.deak@intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> (v2) Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2015-02-13 21:03:42 +01:00
drm_crtc_vblank_on(&crtc->base);
/* Disable everything but the primary plane */
for_each_intel_plane_on_crtc(dev, crtc, plane) {
if (plane->base.type == DRM_PLANE_TYPE_PRIMARY)
continue;
plane->disable_plane(&plane->base, &crtc->base);
}
drm/irq: Add drm_crtc_vblank_reset At driver load we need to tell the vblank code about the state of the pipes, so that the logic around reject vblank_get when the pipe is off works correctly. Thus far i915 used drm_vblank_off, but one of the side-effects of it is that it also saves the vblank counter. And for that it calls down into the ->get_vblank_counter hook. Which isn't really a good idea when the pipe is off for a few reasons: - With runtime pm the register might not respond. - If the pipe is off some datastructures might not be around or unitialized. The later is what blew up on gen3: We look at intel_crtc->config to compute the vblank counter, and for a disabled pipe at boot-up that's just not there. Thus far this was papered over by a check for intel_crtc->active, but I want to get rid of that (since it's fairly race, vblank hooks are called from all kinds of places). So prep for that by adding a _reset functions which only does what we really need to be done at driver load: Mark the vblank pipe as off, but don't do any vblank counter saving or event flushing - neither of that is required. v2: Clarify the code flow slightly as suggested by Ville. v3: Fix kerneldoc spelling, spotted by Laurent. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Cc: Imre Deak <imre.deak@intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> (v2) Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2015-02-13 21:03:42 +01:00
}
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
/* We need to sanitize the plane -> pipe mapping first because this will
* disable the crtc (and hence change the state) if it is wrong. Note
* that gen4+ has a fixed plane -> pipe mapping. */
if (INTEL_INFO(dev)->gen < 4 && !intel_check_plane_mapping(crtc)) {
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
bool plane;
DRM_DEBUG_KMS("[CRTC:%d:%s] wrong plane connection detected!\n",
crtc->base.base.id, crtc->base.name);
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
/* Pipe has the wrong plane attached and the plane is active.
* Temporarily change the plane mapping and disable everything
* ... */
plane = crtc->plane;
to_intel_plane_state(crtc->base.primary->state)->visible = true;
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
crtc->plane = !plane;
intel_crtc_disable_noatomic(&crtc->base);
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
crtc->plane = plane;
}
if (dev_priv->quirks & QUIRK_PIPEA_FORCE &&
crtc->pipe == PIPE_A && !crtc->active) {
/* BIOS forgot to enable pipe A, this mostly happens after
* resume. Force-enable the pipe to fix this, the update_dpms
* call below we restore the pipe to the right state, but leave
* the required bits on. */
intel_enable_pipe_a(dev);
}
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
/* Adjust the state of the output pipe according to whether we
* have active connectors/encoders. */
drm/i915: Update state before setting watermarks, v2. When intel_update_watermarks is called on skylake from the hw state readout disable function it calls intel_update_watermarks. intel_update_watermarks inspects crtc->state, which should be set to disabled. This wasn't the case, and this resulted in a divide-by-zero in skl_update_wm when intel_update_watermarks got called. ------------[ cut here ]------------ WARNING: CPU: 1 PID: 295 at drivers/gpu/drm/i915/intel_pm.c:2834 skl_update_pipe_wm+0x102/0x8c0 [i915]() WARN_ON(!config->num_pipes_active) Modules linked in: coretemp i915(+) xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx CPU: 1 PID: 295 Comm: systemd-udevd Tainted: G U W 4.5.0-rc4 -xxxxxx #25 Hardware name: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 0000000000000000 ffff88003777f5a8 ffffffff813485c2 ffff88003777f5f0 ffffffffa0236240 ffff88003777f5e0 ffffffff81050fce ffff8800aa420000 ffff8800aba18000 ffff8800aba18000 ffff880037304c00 ffff8800aa420000 Call Trace: [<ffffffff813485c2>] dump_stack+0x67/0x95 [<ffffffff81050fce>] warn_slowpath_common+0x9e/0xc0 [<ffffffff8105103c>] warn_slowpath_fmt+0x4c/0x50 [<ffffffff8106945e>] ? flush_work+0x8e/0x280 [<ffffffff810693d5>] ? flush_work+0x5/0x280 [<ffffffffa016add2>] skl_update_pipe_wm+0x102/0x8c0 [i915] [<ffffffffa016b96f>] skl_update_wm+0xff/0x5f0 [i915] [<ffffffff810928ee>] ? trace_hardirqs_on_caller+0x15e/0x1d0 [<ffffffff8109296d>] ? trace_hardirqs_on+0xd/0x10 [<ffffffffa016ce6e>] intel_update_watermarks+0x1e/0x30 [i915] [<ffffffffa01d3ee2>] intel_crtc_disable_noatomic+0xd2/0x150 [i915] [<ffffffffa01dd3d2>] intel_modeset_setup_hw_state+0xdd2/0xde0 [i915] [<ffffffffa01dfd83>] intel_modeset_init+0x15a3/0x1950 [i915] [<ffffffffa02160b6>] i915_driver_load+0x13c6/0x1720 [i915] [<ffffffff81522160>] ? add_sysfs_fw_map_entry+0x9b/0x9b [<ffffffffa00b15ef>] drm_dev_register+0x6f/0xb0 [drm] [<ffffffffa00b3b3a>] drm_get_pci_dev+0x10a/0x1d0 [drm] [<ffffffffa01582d9>] i915_pci_probe+0x49/0x50 [i915] [<ffffffff8138ae30>] pci_device_probe+0x80/0xf0 [<ffffffff8143e2ac>] driver_probe_device+0x1bc/0x3d0 [<ffffffff8143e526>] __driver_attach+0x66/0x90 [<ffffffff8143e4c0>] ? driver_probe_device+0x3d0/0x3d0 [<ffffffff8143be3b>] bus_for_each_dev+0x5b/0xa0 [<ffffffff8143db3e>] driver_attach+0x1e/0x20 [<ffffffff8143d461>] bus_add_driver+0x151/0x270 [<ffffffff8143eabc>] driver_register+0x8c/0xd0 [<ffffffff8138a2ed>] __pci_register_driver+0x5d/0x60 [<ffffffffa00b3c58>] drm_pci_init+0x58/0xf0 [drm] [<ffffffff8109296d>] ? trace_hardirqs_on+0xd/0x10 [<ffffffffa02aa000>] ? 0xffffffffa02aa000 [<ffffffffa02aa094>] i915_init+0x94/0x9b [i915] [<ffffffff81000423>] do_one_initcall+0x113/0x1f0 [<ffffffff810a4b21>] ? rcu_read_lock_sched_held+0x61/0x90 [<ffffffff811601dc>] ? kmem_cache_alloc_trace+0x1cc/0x280 [<ffffffff8111110a>] do_init_module+0x60/0x1c8 [<ffffffff810c731b>] load_module+0x1ceb/0x2410 [<ffffffff810c3a60>] ? store_uevent+0x40/0x40 [<ffffffff811763d1>] ? kernel_read+0x41/0x60 [<ffffffff810c7c1d>] SYSC_finit_module+0x8d/0xa0 [<ffffffff810c7c4e>] SyS_finit_module+0xe/0x10 [<ffffffff815f1e97>] entry_SYSCALL_64_fastpath+0x12/0x6f ---[ end trace 1149e9ab3695a423 ]--- ------------[ cut here ]------------ Changes since v1: - Clear state before calling any function after .crtc_disable. Reported-by: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/56D6FD21.7020907@linux.intel.com Tested-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com>
2016-03-02 15:48:01 +01:00
if (crtc->active && !intel_crtc_has_encoders(crtc))
intel_crtc_disable_noatomic(&crtc->base);
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
if (crtc->active || HAS_GMCH_DISPLAY(dev)) {
/*
* We start out with underrun reporting disabled to avoid races.
* For correct bookkeeping mark this on active crtcs.
*
* Also on gmch platforms we dont have any hardware bits to
* disable the underrun reporting. Which means we need to start
* out with underrun reporting disabled also on inactive pipes,
* since otherwise we'll complain about the garbage we read when
* e.g. coming up after runtime pm.
*
* No protection against concurrent access is required - at
* worst a fifo underrun happens which also sets this to false.
*/
crtc->cpu_fifo_underrun_disabled = true;
crtc->pch_fifo_underrun_disabled = true;
}
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
}
static void intel_sanitize_encoder(struct intel_encoder *encoder)
{
struct intel_connector *connector;
struct drm_device *dev = encoder->base.dev;
/* We need to check both for a crtc link (meaning that the
* encoder is active and trying to read from a pipe) and the
* pipe itself being active. */
bool has_active_crtc = encoder->base.crtc &&
to_intel_crtc(encoder->base.crtc)->active;
if (intel_encoder_has_connectors(encoder) && !has_active_crtc) {
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
DRM_DEBUG_KMS("[ENCODER:%d:%s] has active connectors but no active pipe!\n",
encoder->base.base.id,
encoder->base.name);
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
/* Connector is active, but has no active pipe. This is
* fallout from our resume register restoring. Disable
* the encoder manually again. */
if (encoder->base.crtc) {
DRM_DEBUG_KMS("[ENCODER:%d:%s] manually disabled\n",
encoder->base.base.id,
encoder->base.name);
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
encoder->disable(encoder);
if (encoder->post_disable)
encoder->post_disable(encoder);
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
}
drm/i915: Break encoder->crtc link separately in intel_sanitize_crtc() Depending on the SDVO output_flags SDVO may have multiple connectors linking to the same encoder (in intel_connector->encoder->base). Only one of those connectors should be active (ie link to the encoder thru drm_connector->encoder). If intel_connector_break_all_links() is called from intel_sanitize_crtc() we may break the crtc connection of an encoder thru an inactive connector in which case intel_connector_break_all_links() will not be called again for the active connector if this happens to come later in the list due to: if (connector->encoder->base.crtc != &crtc->base) continue; in intel_sanitize_crtc(). This will however leave the drm_connector->encoder linkage for this active connector in place. Subsequently this will cause multiple warnings in intel_connector_check_state() to trigger and the driver will eventually die in drm_encoder_crtc_ok() (because of crtc == NULL). To avoid this remove intel_connector_break_all_links() and move its code to its two calling functions: intel_sanitize_crtc() and intel_sanitize_encoder(). This allows to implement the link breaking more flexibly matching the surrounding code: ie. in intel_sanitize_crtc() we can break the crtc link separatly after the links to the encoders have been broken which avoids above problem. This regression has been introduced in: commit 24929352481f085c5f85d4d4cbc919ddf106d381 Author: Daniel Vetter <daniel.vetter@ffwll.ch> Date: Mon Jul 2 20:28:59 2012 +0200 drm/i915: read out the modeset hw state at load and resume time so goes back to the very beginning of the modeset rework. v2: This patch takes care of the concernes voiced by Chris Wilson and Daniel Vetter that only breaking links if the drm_connector is linked to an encoder may miss some links. v3: move all encoder handling to encoder loop as suggested by Daniel Vetter. Signed-off-by: Egbert Eich <eich@suse.de> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: stable@vger.kernel.org Cc: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
2014-04-25 10:56:22 +02:00
encoder->base.crtc = NULL;
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
/* Inconsistent output/port/pipe state happens presumably due to
* a bug in one of the get_hw_state functions. Or someplace else
* in our code, like the register restore mess on resume. Clamp
* things to off as a safer default. */
for_each_intel_connector(dev, connector) {
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
if (connector->encoder != encoder)
continue;
drm/i915: Break encoder->crtc link separately in intel_sanitize_crtc() Depending on the SDVO output_flags SDVO may have multiple connectors linking to the same encoder (in intel_connector->encoder->base). Only one of those connectors should be active (ie link to the encoder thru drm_connector->encoder). If intel_connector_break_all_links() is called from intel_sanitize_crtc() we may break the crtc connection of an encoder thru an inactive connector in which case intel_connector_break_all_links() will not be called again for the active connector if this happens to come later in the list due to: if (connector->encoder->base.crtc != &crtc->base) continue; in intel_sanitize_crtc(). This will however leave the drm_connector->encoder linkage for this active connector in place. Subsequently this will cause multiple warnings in intel_connector_check_state() to trigger and the driver will eventually die in drm_encoder_crtc_ok() (because of crtc == NULL). To avoid this remove intel_connector_break_all_links() and move its code to its two calling functions: intel_sanitize_crtc() and intel_sanitize_encoder(). This allows to implement the link breaking more flexibly matching the surrounding code: ie. in intel_sanitize_crtc() we can break the crtc link separatly after the links to the encoders have been broken which avoids above problem. This regression has been introduced in: commit 24929352481f085c5f85d4d4cbc919ddf106d381 Author: Daniel Vetter <daniel.vetter@ffwll.ch> Date: Mon Jul 2 20:28:59 2012 +0200 drm/i915: read out the modeset hw state at load and resume time so goes back to the very beginning of the modeset rework. v2: This patch takes care of the concernes voiced by Chris Wilson and Daniel Vetter that only breaking links if the drm_connector is linked to an encoder may miss some links. v3: move all encoder handling to encoder loop as suggested by Daniel Vetter. Signed-off-by: Egbert Eich <eich@suse.de> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: stable@vger.kernel.org Cc: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
2014-04-25 10:56:22 +02:00
connector->base.dpms = DRM_MODE_DPMS_OFF;
connector->base.encoder = NULL;
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
}
}
/* Enabled encoders without active connectors will be fixed in
* the crtc fixup. */
}
void i915_redisable_vga_power_on(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
drm/i915: Type safe register read/write Make I915_READ and I915_WRITE more type safe by wrapping the register offset in a struct. This should eliminate most of the fumbles we've had with misplaced parens. This only takes care of normal mmio registers. We could extend the idea to other register types and define each with its own struct. That way you wouldn't be able to accidentally pass the wrong thing to a specific register access function. The gpio_reg setup is probably the ugliest thing left. But I figure I'd just leave it for now, and wait for some divine inspiration to strike before making it nice. As for the generated code, it's actually a bit better sometimes. Eg. looking at i915_irq_handler(), we can see the following change: lea 0x70024(%rdx,%rax,1),%r9d mov $0x1,%edx - movslq %r9d,%r9 - mov %r9,%rsi - mov %r9,-0x58(%rbp) - callq *0xd8(%rbx) + mov %r9d,%esi + mov %r9d,-0x48(%rbp) callq *0xd8(%rbx) So previously gcc thought the register offset might be signed and decided to sign extend it, just in case. The rest appears to be mostly just minor shuffling of instructions. v2: i915_mmio_reg_{offset,equal,valid}() helpers added s/_REG/_MMIO/ in the register defines mo more switch statements left to worry about ring_emit stuff got sorted in a prep patch cmd parser, lrc context and w/a batch buildup also in prep patch vgpu stuff cleaned up and moved to a prep patch all other unrelated changes split out v3: Rebased due to BXT DSI/BLC, MOCS, etc. v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
i915_reg_t vga_reg = i915_vgacntrl_reg(dev);
if (!(I915_READ(vga_reg) & VGA_DISP_DISABLE)) {
DRM_DEBUG_KMS("Something enabled VGA plane, disabling it\n");
i915_disable_vga(dev);
}
}
void i915_redisable_vga(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
/* 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 (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_VGA))
return;
i915_redisable_vga_power_on(dev);
intel_display_power_put(dev_priv, POWER_DOMAIN_VGA);
}
static bool primary_get_hw_state(struct intel_plane *plane)
{
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
return I915_READ(DSPCNTR(plane->plane)) & DISPLAY_PLANE_ENABLE;
}
/* FIXME read out full plane state for all planes */
static void readout_plane_state(struct intel_crtc *crtc)
{
struct drm_plane *primary = crtc->base.primary;
struct intel_plane_state *plane_state =
to_intel_plane_state(primary->state);
plane_state->visible = crtc->active &&
primary_get_hw_state(to_intel_plane(primary));
if (plane_state->visible)
crtc->base.state->plane_mask |= 1 << drm_plane_index(primary);
}
static void intel_modeset_readout_hw_state(struct drm_device *dev)
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
{
struct drm_i915_private *dev_priv = dev->dev_private;
enum pipe pipe;
struct intel_crtc *crtc;
struct intel_encoder *encoder;
struct intel_connector *connector;
int i;
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
dev_priv->active_crtcs = 0;
for_each_intel_crtc(dev, crtc) {
struct intel_crtc_state *crtc_state = crtc->config;
int pixclk = 0;
__drm_atomic_helper_crtc_destroy_state(&crtc_state->base);
memset(crtc_state, 0, sizeof(*crtc_state));
crtc_state->base.crtc = &crtc->base;
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
crtc_state->base.active = crtc_state->base.enable =
dev_priv->display.get_pipe_config(crtc, crtc_state);
crtc->base.enabled = crtc_state->base.enable;
crtc->active = crtc_state->base.active;
if (crtc_state->base.active) {
dev_priv->active_crtcs |= 1 << crtc->pipe;
drm/i915/skl: SKL CDCLK change on modeset tracking VCO WARNING: Using ChromeOS with an eDP panel and a 4K@60 DP monitor connected to DDI1 the system will hard hang during a cold boot. Occurs when DDI1 is enabled when the cdclk is less then required. DP connected to DDI2 and HPD on either port works correctly. Set cdclk based on the max required pixel clock based on VCO selected. Track boot vco instead of boot cdclk. The vco is now tracked at the atomic level and all CRTCs updated if the required vco is changed. Not tested with eDP v1.4 panels that require 8640 vco due to availability. V1: initial version V2: add vco tracking in intel_dp_compute_config(), rename skl_boot_cdclk. V3: rebase, V2 feedback not possible as encoders are not aware of atomic. V4: track target vco is atomic state. modeset all CRTCs if vco changes V5: rename atomic variable, cleaner if/else logic, use existing vco if encoder does not return a new vco value. check_patch.pl cleanup V6: simplify logic in intel_modeset_checks. V7: reorder an IF for readability and whitespace fix. V8: use dev_cdclk for tracking new cdclk during atomic V9: correctly handle vco 8640 when crtcs==0 V10: Clean up if else in crtcs==0 V11: Rebase for new intel_dpll_mgr.c Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Clint Taylor <clinton.a.taylor@intel.com> [vsyrjala: rebased due to churn] Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1463172100-24715-3-git-send-email-ville.syrjala@linux.intel.com
2016-05-13 23:41:21 +03:00
if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
pixclk = ilk_pipe_pixel_rate(crtc_state);
else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
pixclk = crtc_state->base.adjusted_mode.crtc_clock;
else
WARN_ON(dev_priv->display.modeset_calc_cdclk);
/* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */
if (IS_BROADWELL(dev_priv) && crtc_state->ips_enabled)
pixclk = DIV_ROUND_UP(pixclk * 100, 95);
}
dev_priv->min_pixclk[crtc->pipe] = pixclk;
readout_plane_state(crtc);
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
DRM_DEBUG_KMS("[CRTC:%d:%s] hw state readout: %s\n",
crtc->base.base.id, crtc->base.name,
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
crtc->active ? "enabled" : "disabled");
}
for (i = 0; i < dev_priv->num_shared_dpll; i++) {
struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
pll->on = pll->funcs.get_hw_state(dev_priv, pll,
&pll->config.hw_state);
pll->config.crtc_mask = 0;
for_each_intel_crtc(dev, crtc) {
if (crtc->active && crtc->config->shared_dpll == pll)
pll->config.crtc_mask |= 1 << crtc->pipe;
}
pll->active_mask = pll->config.crtc_mask;
DRM_DEBUG_KMS("%s hw state readout: crtc_mask 0x%08x, on %i\n",
pll->name, pll->config.crtc_mask, pll->on);
}
for_each_intel_encoder(dev, encoder) {
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
pipe = 0;
if (encoder->get_hw_state(encoder, &pipe)) {
crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
encoder->base.crtc = &crtc->base;
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
encoder->get_config(encoder, crtc->config);
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
} else {
encoder->base.crtc = NULL;
}
DRM_DEBUG_KMS("[ENCODER:%d:%s] hw state readout: %s, pipe %c\n",
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
encoder->base.base.id,
encoder->base.name,
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
encoder->base.crtc ? "enabled" : "disabled",
pipe_name(pipe));
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
}
for_each_intel_connector(dev, connector) {
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
if (connector->get_hw_state(connector)) {
connector->base.dpms = DRM_MODE_DPMS_ON;
encoder = connector->encoder;
connector->base.encoder = &encoder->base;
if (encoder->base.crtc &&
encoder->base.crtc->state->active) {
/*
* This has to be done during hardware readout
* because anything calling .crtc_disable may
* rely on the connector_mask being accurate.
*/
encoder->base.crtc->state->connector_mask |=
1 << drm_connector_index(&connector->base);
encoder->base.crtc->state->encoder_mask |=
1 << drm_encoder_index(&encoder->base);
}
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
} else {
connector->base.dpms = DRM_MODE_DPMS_OFF;
connector->base.encoder = NULL;
}
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] hw state readout: %s\n",
connector->base.base.id,
connector->base.name,
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
connector->base.encoder ? "enabled" : "disabled");
}
for_each_intel_crtc(dev, crtc) {
crtc->base.hwmode = crtc->config->base.adjusted_mode;
memset(&crtc->base.mode, 0, sizeof(crtc->base.mode));
if (crtc->base.state->active) {
intel_mode_from_pipe_config(&crtc->base.mode, crtc->config);
intel_mode_from_pipe_config(&crtc->base.state->adjusted_mode, crtc->config);
WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));
/*
* The initial mode needs to be set in order to keep
* the atomic core happy. It wants a valid mode if the
* crtc's enabled, so we do the above call.
*
* At this point some state updated by the connectors
* in their ->detect() callback has not run yet, so
* no recalculation can be done yet.
*
* Even if we could do a recalculation and modeset
* right now it would cause a double modeset if
* fbdev or userspace chooses a different initial mode.
*
* If that happens, someone indicated they wanted a
* mode change, which means it's safe to do a full
* recalculation.
*/
crtc->base.state->mode.private_flags = I915_MODE_FLAG_INHERITED;
drm_calc_timestamping_constants(&crtc->base, &crtc->base.hwmode);
update_scanline_offset(crtc);
}
intel_pipe_config_sanity_check(dev_priv, crtc->config);
}
}
/* Scan out the current hw modeset state,
* and sanitizes it to the current state
*/
static void
intel_modeset_setup_hw_state(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
enum pipe pipe;
struct intel_crtc *crtc;
struct intel_encoder *encoder;
int i;
intel_modeset_readout_hw_state(dev);
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
/* HW state is read out, now we need to sanitize this mess. */
for_each_intel_encoder(dev, encoder) {
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
intel_sanitize_encoder(encoder);
}
for_each_pipe(dev_priv, pipe) {
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
intel_sanitize_crtc(crtc);
drm/i915: Make intel_crtc->config a pointer To match the semantics of drm_crtc->state, which this will eventually become. The allocation of the memory for config will be fixed in a followup patch. By adding the extra _config field to intel_crtc it was possible to generate this entire patch with the cocci script below. @@ @@ struct intel_crtc { ... -struct intel_crtc_state config; +struct intel_crtc_state _config; +struct intel_crtc_state *config; ... } @@ struct intel_crtc *crtc; @@ -memset(&crtc->config, 0, sizeof(crtc->config)); +memset(crtc->config, 0, sizeof(*crtc->config)); @@ @@ __intel_set_mode(...) { <... -to_intel_crtc(crtc)->config = *pipe_config; +(*(to_intel_crtc(crtc)->config)) = *pipe_config; ...> } @@ @@ intel_crtc_init(...) { ... WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); +intel_crtc->config = &intel_crtc->_config; return; ... } @@ struct intel_crtc *crtc; @@ -&crtc->config +crtc->config @@ struct intel_crtc *crtc; identifier member; @@ -crtc->config.member +crtc->config->member @@ expression E; @@ -&(to_intel_crtc(E)->config) +to_intel_crtc(E)->config @@ expression E; identifier member; @@ -to_intel_crtc(E)->config.member +to_intel_crtc(E)->config->member v2: Clarify manual changes by splitting them into another patch. (Matt) Improve cocci script to generate even more of the changes. (Ander) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-01-15 14:55:25 +02:00
intel_dump_pipe_config(crtc, crtc->config,
"[setup_hw_state]");
drm/i915: read out the modeset hw state at load and resume time ... instead of resetting a few things and hoping that this will work out. To properly disable the output pipelines at the initial modeset after resume or boot up we need to have an accurate picture of which outputs are enabled and connected to which crtcs. Otherwise we risk disabling things at the wrong time, which can lead to hangs (or at least royally confused panels), both requiring a walk to the reset button to fix. Hence read out the hw state with the freshly introduce get_hw_state functions and then sanitize it afterwards. For a full modeset readout (which would allow us to avoid the initial modeset at boot up) a few things are still missing: - Reading out the mode from the pipe, especially the dotclock computation is quite some fun. - Reading out the parameters for the stolen memory framebuffer and wrapping it up. - Reading out the pch pll connections - luckily the disable code simply bails out if the crtc doesn't have a pch pll attached (even for configurations that would need one). This patch here turned up tons of smelly stuff around resume: We restore tons of register in seemingly random way (well, not quite, but we're not too careful either), which leaves the hw in a rather ill-defined state: E.g. the port registers are sometimes unconditionally restore (lvds, crt), leaving us with an active encoder/connector but no active pipe connected to it. Luckily the hw state sanitizer detects this madness and fixes things up a bit. v2: When checking whether an encoder with active connectors has a crtc wire up to it, check for both the crtc _and_ it's active state. v3: - Extract intel_sanitize_encoder. - Manually disable active encoders without an active pipe. v4: Correclty fix up the pipe<->plane mapping on machines where we switch pipes/planes. Noticed by Chris Wilson, who also provided the fixup. v5: Spelling fix in a comment, noticed by Paulo Zanoni Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-02 20:28:59 +02:00
}
drm/i915: stage modeset output changes This is the core of the new modeset logic. The current code which is based upon the crtc helper code first updates all the link of the new display pipeline and then calls the lower-level set_mode function to execute the required callbacks to get there. The issue with this approach is that for disabling we need to know the _current_ display pipe state, not the new one. Hence we need to stage the new state of the display pipe and only update it once we have disabled the current configuration and before we start to update the hw registers with the new configuration. This patch here just prepares the ground by switching the new output state computation to these staging pointers. To make it clearer, rename the old update_output_state function to stage_output_state. A few peculiarities: - We're also calling the set_mode function at various places to update properties. Hence after a successfule modeset we need to stage the current configuration (for otherwise we might fall back again). This happens automatically because as part of the (successful) modeset we need to copy the staged state to the real one. But for the hw readout code we need to make sure that this happens, too. - Teach the new staged output state computation code the required smarts to handle the disabling of outputs. The current code handles this in a special case, but to better handle global modeset changes covering more than one crtc, we want to do this all in the same low-level modeset code. - The actual modeset code is still a bit ugly and wants to know the new crtc->enabled state a bit early. Follow-on patches will clean that up, for now we have to apply the staged output configuration early, outside of the set_mode functions. - Improve/add comments in stage_output_state. Essentially all that is left to do now is move the disabling code into set_mode and then move the staged state update code also into set_mode, at the right place between disabling things and calling the mode_set callbacks for the new configuration. v2: Disabling a crtc works by passing in a NULL mode or fb, userspace doesn't hand in the list of connectors. We therefore need to detect this case manually and tear down all the output links. v3: Properly update the output staging pointers after having read out the hw state. v4: Simplify the code, add more DRM_DEBUG_KMS output and check a few assumptions with WARN_ON. Essentially all things that I've noticed while debugging issues in other places of the code. v4: Correctly disable the old set of connectors when enabling an already enabled crtc on a new set of crtc. Reported by Paulo Zanoni. Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-05 22:34:27 +02:00
intel_modeset_update_connector_atomic_state(dev);
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_mask)
continue;
DRM_DEBUG_KMS("%s enabled but not in use, disabling\n", pll->name);
pll->funcs.disable(dev_priv, pll);
pll->on = false;
}
if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
vlv_wm_get_hw_state(dev);
else if (IS_GEN9(dev))
skl_wm_get_hw_state(dev);
else if (HAS_PCH_SPLIT(dev))
ilk_wm_get_hw_state(dev);
for_each_intel_crtc(dev, crtc) {
unsigned long put_domains;
put_domains = modeset_get_crtc_power_domains(&crtc->base, crtc->config);
if (WARN_ON(put_domains))
modeset_put_power_domains(dev_priv, put_domains);
}
intel_display_set_init_power(dev_priv, false);
intel_fbc_init_pipe_state(dev_priv);
}
void intel_display_resume(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_atomic_state *state = dev_priv->modeset_restore_state;
struct drm_modeset_acquire_ctx ctx;
int ret;
bool setup = false;
dev_priv->modeset_restore_state = NULL;
drm/i915: Lock mode_config.mutex in intel_display_resume. Unfortunately i915 is still not fully atomic, and expects mode_config.mutex to be held during modeset until we finally fix it. This fixes the following WARN when resuming: [ 425.208983] ------------[ cut here ]------------ [ 425.208990] WARNING: CPU: 0 PID: 6828 at drivers/gpu/drm/drm_edid.c:3555 drm_select_eld+0xa5/0xd0() [ 425.209015] Modules linked in: pl2303 usbserial snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_codec_generic intel_powerclamp coretemp i915 crct10dif_pclmul crc32_pclmul ghash_clmulni_intel snd_hda_intel snd_hda_codec snd_hwdep lpc_ich snd_hda_core snd_pcm i2c_hid i2c_designware_platform i2c_designware_core r8169 mii sdhci_acpi sdhci mmc_core [ 425.209018] CPU: 0 PID: 6828 Comm: kworker/u4:5 Tainted: G U W 4.5.0-rc4-gfxbench+ #1 [ 425.209020] Hardware name: \xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff \xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff/DN2820FYK, BIOS FYBYT10H.86A.0038.2014.0717.1455 07/17/2014 [ 425.209027] Workqueue: events_unbound async_run_entry_fn [ 425.209032] 0000000000000000 ffff880072433958 ffffffff813f6b05 0000000000000000 [ 425.209036] ffffffff81aaef2d ffff880072433990 ffffffff81078291 ffff880036b933d8 [ 425.209039] ffff88006d528000 ffff88006d52b3d8 ffff88006d52b3d8 ffff88007315b6f8 [ 425.209040] Call Trace: [ 425.209045] [<ffffffff813f6b05>] dump_stack+0x67/0x92 [ 425.209049] [<ffffffff81078291>] warn_slowpath_common+0x81/0xc0 [ 425.209052] [<ffffffff81078385>] warn_slowpath_null+0x15/0x20 [ 425.209054] [<ffffffff8151e195>] drm_select_eld+0xa5/0xd0 [ 425.209101] [<ffffffffa01f34f4>] intel_audio_codec_enable+0x44/0x160 [i915] [ 425.209135] [<ffffffffa023eac7>] intel_enable_hdmi_audio+0x87/0x90 [i915] [ 425.209169] [<ffffffffa023eb5a>] g4x_enable_hdmi+0x8a/0xa0 [i915] [ 425.209202] [<ffffffffa023f41b>] vlv_hdmi_pre_enable+0x1cb/0x240 [i915] [ 425.209236] [<ffffffffa020edcf>] valleyview_crtc_enable+0x10f/0x290 [i915] [ 425.209270] [<ffffffffa020ba49>] intel_atomic_commit+0x769/0x17a0 [i915] [ 425.209274] [<ffffffff81526ad5>] ? drm_atomic_check_only+0x145/0x660 [ 425.209276] [<ffffffff81527022>] drm_atomic_commit+0x32/0x50 [ 425.209310] [<ffffffffa0215fa0>] intel_display_resume+0xa0/0x130 [i915] [ 425.209338] [<ffffffffa018c1bb>] i915_drm_resume+0xcb/0x160 [i915] [ 425.209366] [<ffffffffa018c272>] i915_pm_resume+0x22/0x30 [i915] [ 425.209370] [<ffffffff8143d91e>] pci_pm_resume+0x6e/0xe0 [ 425.209373] [<ffffffff8143d8b0>] ? pci_pm_resume_noirq+0xa0/0xa0 [ 425.209375] [<ffffffff815409ae>] dpm_run_callback+0x6e/0x280 [ 425.209378] [<ffffffff815410b2>] device_resume+0x92/0x250 [ 425.209380] [<ffffffff81541288>] async_resume+0x18/0x40 [ 425.209382] [<ffffffff8109c7a5>] async_run_entry_fn+0x45/0x140 [ 425.209386] [<ffffffff81093293>] process_one_work+0x1e3/0x620 [ 425.209388] [<ffffffff810931f7>] ? process_one_work+0x147/0x620 [ 425.209391] [<ffffffff81093719>] worker_thread+0x49/0x490 [ 425.209393] [<ffffffff810936d0>] ? process_one_work+0x620/0x620 [ 425.209396] [<ffffffff81099e0a>] kthread+0xea/0x100 [ 425.209400] [<ffffffff81099d20>] ? kthread_create_on_node+0x1f0/0x1f0 [ 425.209404] [<ffffffff817ba03f>] ret_from_fork+0x3f/0x70 [ 425.209407] [<ffffffff81099d20>] ? kthread_create_on_node+0x1f0/0x1f0 [ 425.209409] ---[ end trace d1b247107f34a8b2 ]--- Fixes: e2c8b8701e2d ("drm/i915: Use atomic helpers for suspend, v2.") Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1455632862-18557-1-git-send-email-maarten.lankhorst@linux.intel.com Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2016-02-16 15:27:42 +01:00
/*
* This is a cludge because with real atomic modeset mode_config.mutex
* won't be taken. Unfortunately some probed state like
* audio_codec_enable is still protected by mode_config.mutex, so lock
* it here for now.
*/
mutex_lock(&dev->mode_config.mutex);
drm_modeset_acquire_init(&ctx, 0);
retry:
ret = drm_modeset_lock_all_ctx(dev, &ctx);
if (ret == 0 && !setup) {
setup = true;
intel_modeset_setup_hw_state(dev);
i915_redisable_vga(dev);
}
if (ret == 0 && state) {
struct drm_crtc_state *crtc_state;
struct drm_crtc *crtc;
int i;
state->acquire_ctx = &ctx;
drm/i915: Ignore stale wm register values on resume on ilk-bdw (v2) When we resume the watermark register may contain some BIOS leftovers, or just the hardware reset values. We should ignore those as the pipes will be off anyway, and so frobbing around with intermediate watermarks doesn't make much sense. In fact I think we should just throw the skip_intermediate_wm flag out, and instead properly sanitize the "active" watermarks to match the current plane and pipe states. The actual wm state readout might also need a bit of work. But for now, let's continue with the skip_intermediate_wm to keep the fix more minimal. Fixes this sort of errors on resume [drm:ilk_validate_pipe_wm] LP0 watermark invalid [drm:intel_crtc_atomic_check] No valid intermediate pipe watermarks are possible [drm:intel_display_resume [i915]] *ERROR* Restoring old state failed with -22 and a boatload of subsequent modeset BAT fails on my ILK. v2: - Rebase; the SKL atomic WM patches that just landed changed the WM structure fields in intel_crtc_state slightly. (Matt) Cc: Matt Roper <matthew.d.roper@intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Fixes: ed4a6a7ca853 ("drm/i915: Add two-stage ILK-style watermark programming (v11)") Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1463159442-20478-1-git-send-email-matthew.d.roper@intel.com
2016-05-13 10:10:42 -07:00
/* ignore any reset values/BIOS leftovers in the WM registers */
to_intel_atomic_state(state)->skip_intermediate_wm = true;
for_each_crtc_in_state(state, crtc, crtc_state, i) {
/*
* Force recalculation even if we restore
* current state. With fast modeset this may not result
* in a modeset when the state is compatible.
*/
crtc_state->mode_changed = true;
}
ret = drm_atomic_commit(state);
}
if (ret == -EDEADLK) {
drm_modeset_backoff(&ctx);
goto retry;
}
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
drm/i915: Lock mode_config.mutex in intel_display_resume. Unfortunately i915 is still not fully atomic, and expects mode_config.mutex to be held during modeset until we finally fix it. This fixes the following WARN when resuming: [ 425.208983] ------------[ cut here ]------------ [ 425.208990] WARNING: CPU: 0 PID: 6828 at drivers/gpu/drm/drm_edid.c:3555 drm_select_eld+0xa5/0xd0() [ 425.209015] Modules linked in: pl2303 usbserial snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_codec_generic intel_powerclamp coretemp i915 crct10dif_pclmul crc32_pclmul ghash_clmulni_intel snd_hda_intel snd_hda_codec snd_hwdep lpc_ich snd_hda_core snd_pcm i2c_hid i2c_designware_platform i2c_designware_core r8169 mii sdhci_acpi sdhci mmc_core [ 425.209018] CPU: 0 PID: 6828 Comm: kworker/u4:5 Tainted: G U W 4.5.0-rc4-gfxbench+ #1 [ 425.209020] Hardware name: \xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff \xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff/DN2820FYK, BIOS FYBYT10H.86A.0038.2014.0717.1455 07/17/2014 [ 425.209027] Workqueue: events_unbound async_run_entry_fn [ 425.209032] 0000000000000000 ffff880072433958 ffffffff813f6b05 0000000000000000 [ 425.209036] ffffffff81aaef2d ffff880072433990 ffffffff81078291 ffff880036b933d8 [ 425.209039] ffff88006d528000 ffff88006d52b3d8 ffff88006d52b3d8 ffff88007315b6f8 [ 425.209040] Call Trace: [ 425.209045] [<ffffffff813f6b05>] dump_stack+0x67/0x92 [ 425.209049] [<ffffffff81078291>] warn_slowpath_common+0x81/0xc0 [ 425.209052] [<ffffffff81078385>] warn_slowpath_null+0x15/0x20 [ 425.209054] [<ffffffff8151e195>] drm_select_eld+0xa5/0xd0 [ 425.209101] [<ffffffffa01f34f4>] intel_audio_codec_enable+0x44/0x160 [i915] [ 425.209135] [<ffffffffa023eac7>] intel_enable_hdmi_audio+0x87/0x90 [i915] [ 425.209169] [<ffffffffa023eb5a>] g4x_enable_hdmi+0x8a/0xa0 [i915] [ 425.209202] [<ffffffffa023f41b>] vlv_hdmi_pre_enable+0x1cb/0x240 [i915] [ 425.209236] [<ffffffffa020edcf>] valleyview_crtc_enable+0x10f/0x290 [i915] [ 425.209270] [<ffffffffa020ba49>] intel_atomic_commit+0x769/0x17a0 [i915] [ 425.209274] [<ffffffff81526ad5>] ? drm_atomic_check_only+0x145/0x660 [ 425.209276] [<ffffffff81527022>] drm_atomic_commit+0x32/0x50 [ 425.209310] [<ffffffffa0215fa0>] intel_display_resume+0xa0/0x130 [i915] [ 425.209338] [<ffffffffa018c1bb>] i915_drm_resume+0xcb/0x160 [i915] [ 425.209366] [<ffffffffa018c272>] i915_pm_resume+0x22/0x30 [i915] [ 425.209370] [<ffffffff8143d91e>] pci_pm_resume+0x6e/0xe0 [ 425.209373] [<ffffffff8143d8b0>] ? pci_pm_resume_noirq+0xa0/0xa0 [ 425.209375] [<ffffffff815409ae>] dpm_run_callback+0x6e/0x280 [ 425.209378] [<ffffffff815410b2>] device_resume+0x92/0x250 [ 425.209380] [<ffffffff81541288>] async_resume+0x18/0x40 [ 425.209382] [<ffffffff8109c7a5>] async_run_entry_fn+0x45/0x140 [ 425.209386] [<ffffffff81093293>] process_one_work+0x1e3/0x620 [ 425.209388] [<ffffffff810931f7>] ? process_one_work+0x147/0x620 [ 425.209391] [<ffffffff81093719>] worker_thread+0x49/0x490 [ 425.209393] [<ffffffff810936d0>] ? process_one_work+0x620/0x620 [ 425.209396] [<ffffffff81099e0a>] kthread+0xea/0x100 [ 425.209400] [<ffffffff81099d20>] ? kthread_create_on_node+0x1f0/0x1f0 [ 425.209404] [<ffffffff817ba03f>] ret_from_fork+0x3f/0x70 [ 425.209407] [<ffffffff81099d20>] ? kthread_create_on_node+0x1f0/0x1f0 [ 425.209409] ---[ end trace d1b247107f34a8b2 ]--- Fixes: e2c8b8701e2d ("drm/i915: Use atomic helpers for suspend, v2.") Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1455632862-18557-1-git-send-email-maarten.lankhorst@linux.intel.com Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2016-02-16 15:27:42 +01:00
mutex_unlock(&dev->mode_config.mutex);
if (ret) {
DRM_ERROR("Restoring old state failed with %i\n", ret);
drm_atomic_state_free(state);
}
}
void intel_modeset_gem_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_crtc *c;
struct drm_i915_gem_object *obj;
int ret;
intel_init_gt_powersave(dev_priv);
intel_modeset_init_hw(dev);
intel_setup_overlay(dev_priv);
/*
* Make sure any fbs we allocated at startup are properly
* pinned & fenced. When we do the allocation it's too early
* for this.
*/
for_each_crtc(dev, c) {
obj = intel_fb_obj(c->primary->fb);
if (obj == NULL)
continue;
mutex_lock(&dev->struct_mutex);
ret = intel_pin_and_fence_fb_obj(c->primary->fb,
c->primary->state->rotation);
mutex_unlock(&dev->struct_mutex);
if (ret) {
DRM_ERROR("failed to pin boot fb on pipe %d\n",
to_intel_crtc(c)->pipe);
Merge tag 'drm-intel-next-2014-03-21' of git://anongit.freedesktop.org/drm-intel into drm-next - Inherit/reuse firmwar framebuffers (for real this time) from Jesse, less flicker for fastbooting. - More flexible cloning for hdmi (Ville). - Some PPGTT fixes from Ben. - Ring init fixes from Naresh Kumar. - set_cache_level regression fixes for the vma conversion from Ville&Chris. - Conversion to the new dp aux helpers (Jani). - Unification of runtime pm with pc8 support from Paulo, prep work for runtime pm on other platforms than HSW. - Larger cursor sizes (Sagar Kamble). - Piles of improvements and fixes all over, as usual. * tag 'drm-intel-next-2014-03-21' of git://anongit.freedesktop.org/drm-intel: (75 commits) drm/i915: Include a note about the dangers of I915_READ64/I915_WRITE64 drm/i915/sdvo: fix questionable return value check drm/i915: Fix unsafe loop iteration over vma whilst unbinding them drm/i915: Enabling 128x128 and 256x256 ARGB Cursor Support drm/i915: Print how many objects are shared in per-process stats drm/i915: Per-process stats work better when evaluated per-process drm/i915: remove rps local variables drm/i915: Remove extraneous MMIO for RPS drm/i915: Rename and comment all the RPS *stuff* drm/i915: Store the HW min frequency as min_freq drm/i915: Fix coding style for RPS drm/i915: Reorganize the overclock code drm/i915: init pm.suspended earlier drm/i915: update the PC8 and runtime PM documentation drm/i915: rename __hsw_do_{en, dis}able_pc8 drm/i915: kill struct i915_package_c8 drm/i915: move pc8.irqs_disabled to pm.irqs_disabled drm/i915: remove dev_priv->pc8.enabled drm/i915: don't get/put PC8 when getting/putting power wells drm/i915: make intel_aux_display_runtime_get get runtime PM, not PC8 ... Conflicts: drivers/gpu/drm/i915/intel_display.c drivers/gpu/drm/i915/intel_dp.c
2014-04-03 07:51:54 +10:00
drm_framebuffer_unreference(c->primary->fb);
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
c->primary->fb = NULL;
c->primary->crtc = c->primary->state->crtc = NULL;
drm/i915: Revert async unpin and nonblocking atomic commit This reverts the following patches: d55dbd06bb5e1399aba9ab5227465339d1bbefff drm/i915: Allow nonblocking update of pageflips. 15c86bdb760185e871c7a0f559978328aa500971 drm/i915: Check for unpin correctness. 95c2ccdc82d520f59ae3b6fdc097b63c9b7082bb Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" a6747b7304a9d66758a196d885dab8bbfa5e7d1f drm/i915: Make unpin async. 03f476e1fcb42fca88fc50b94b0d3adbdbe887f0 drm/i915: Prepare connectors for nonblocking checks. 2099deffef4404f949ba1b68d2b17e0608190bc2 drm/i915: Pass atomic states to fbc update functions. ee7171af72c39c18b7d7571419a4ac6ca30aea66 drm/i915: Remove reset_counter from intel_crtc. 2ee004f7c59b2e642f0bb2834f847d756f2dd7b7 drm/i915: Remove queue_flip pointer. b8d2afae557dbb9b9c7bc6f6ec4f5278f3c4c34e drm/i915: Remove use_mmio_flip kernel parameter. 8dd634d922615ec3a9af7976029110ec037f8b50 drm/i915: Remove cs based page flip support. 143f73b3bf48c089b40f58462dd7f7c199fd4f0f drm/i915: Rework intel_crtc_page_flip to be almost atomic, v3. 84fc494b64e8c591be446a966b7447a9db519c88 drm/i915: Add the exclusive fence to plane_state. 6885843ae164e11f6c802209d06921e678a3f3f3 drm/i915: Convert flip_work to a list. aa420ddd8eeaa5df579894a412289e4d07c2fee9 drm/i915: Allow mmio updates on all platforms, v2. afee4d8707ab1f21b7668de995be3a5961e83582 Revert "drm/i915: Avoid stalling on pending flips for legacy cursor updates" "drm/i915: Allow nonblocking update of pageflips" should have been split up, misses a proper commit message and seems to cause issues in the legacy page_flip path as demonstrated by kms_flip. "drm/i915: Make unpin async" doesn't handle the unthrottled cursor updates correctly, leading to an apparent pin count leak. This is caught by the WARN_ON in i915_gem_object_do_pin which screams if we have more than DRM_I915_GEM_OBJECT_MAX_PIN_COUNT pins. Unfortuantely we can't just revert these two because this patch series came with a built-in bisect breakage in the form of temporarily removing the unthrottled cursor update hack for legacy cursor ioctl. Therefore there's no other option than to revert the entire pile :( There's one tiny conflict in intel_drv.h due to other patches, nothing serious. Normally I'd wait a bit longer with doing a maintainer revert, but since the minimal set of patches we need to revert (due to the bisect breakage) is so big, time is running out fast. And very soon (especially after a few attempts at fixing issues) it'll be really hard to revert things cleanly. Lessons learned: - Not a good idea to rush the review (done by someone fairly new to the area) and not make sure domain experts had a chance to read it. - Patches should be properly split up. I only looked at the two patches that should be reverted in detail, but both look like the mix up different things in one patch. - Patches really should have proper commit messages. Especially when doing more than one thing, and especially when touching critical and tricky core code. - Building a patch series and r-b stamping it when it has a built-in bisect breakage is not a good idea. - I also think we need to stop building up technical debt by postponing atomic igt testcases even longer. I think it's clear that there's enough corner cases in this beast that we really need to have the testcases _before_ the next step lands. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Dave Airlie <airlied@redhat.com> Acked-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
2016-05-24 17:13:53 +02:00
update_state_fb(c->primary);
c->state->plane_mask &= ~(1 << drm_plane_index(c->primary));
}
}
}
int intel_connector_register(struct drm_connector *connector)
{
struct intel_connector *intel_connector = to_intel_connector(connector);
int ret;
ret = intel_backlight_device_register(intel_connector);
if (ret)
goto err;
return 0;
drm/i915: Register the backlight device after the modeset init Currently we register the backlight device as soon as we register the connector. That means we can get backlight requests from userspace already before reading out the current modeset hardware state. That means we don't yet know the current crtc->encoder->connector mapping, which causes problems for VLV/CHV which need to know the current pipe in order to figure out which BLC registers to poke. Currently we just ignore such requests fairly deep in the backlight code which means the backlight device brightness property will get out of sync with our backlight.level and the actual hardware state. Fix the problem by delaying the backlight device registration until the entire modeset init has been performed. And we also move the backlight unregisteration to happen as the first thing during the modeset cleanup so that we also won't be bothered with userspace backlight requested during teardown. This is a real world problem on machines using systemd, because systemd, for some reason, wants to restore the backlight to the level it used last time. And that happens as soon as it sees the backlight device appearing in the system. Sometimes the userspace access makes it through before the modeset init, sometimes not. v2: Do not lie to the user in the debug prints (Jani) Include connector name in the prints (Jani) Fix a typo in the commit message (Jani) Reviewed-by: Jani Nikula <jani.nikula@intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-11-07 15:19:46 +02:00
err:
return ret;
}
void intel_connector_unregister(struct drm_connector *connector)
{
struct intel_connector *intel_connector = to_intel_connector(connector);
intel_backlight_device_unregister(intel_connector);
intel_panel_destroy_backlight(connector);
}
void intel_modeset_cleanup(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
intel_disable_gt_powersave(dev_priv);
/*
* Interrupts and polling as the first thing to avoid creating havoc.
* Too much stuff here (turning of connectors, ...) would
* experience fancy races otherwise.
*/
intel_irq_uninstall(dev_priv);
/*
* 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);
intel_unregister_dsm_handler();
intel_fbc_global_disable(dev_priv);
/* flush any delayed tasks or pending work */
flush_scheduled_work();
drm_mode_config_cleanup(dev);
intel_cleanup_overlay(dev_priv);
intel_cleanup_gt_powersave(dev_priv);
intel_teardown_gmbus(dev);
}
void intel_connector_attach_encoder(struct intel_connector *connector,
struct intel_encoder *encoder)
{
connector->encoder = encoder;
drm_mode_connector_attach_encoder(&connector->base,
&encoder->base);
}
/*
* set vga decode state - true == enable VGA decode
*/
int intel_modeset_vga_set_state(struct drm_device *dev, bool state)
{
struct drm_i915_private *dev_priv = dev->dev_private;
unsigned reg = INTEL_INFO(dev)->gen >= 6 ? SNB_GMCH_CTRL : INTEL_GMCH_CTRL;
u16 gmch_ctrl;
if (pci_read_config_word(dev_priv->bridge_dev, reg, &gmch_ctrl)) {
DRM_ERROR("failed to read control word\n");
return -EIO;
}
if (!!(gmch_ctrl & INTEL_GMCH_VGA_DISABLE) == !state)
return 0;
if (state)
gmch_ctrl &= ~INTEL_GMCH_VGA_DISABLE;
else
gmch_ctrl |= INTEL_GMCH_VGA_DISABLE;
if (pci_write_config_word(dev_priv->bridge_dev, reg, gmch_ctrl)) {
DRM_ERROR("failed to write control word\n");
return -EIO;
}
return 0;
}
struct intel_display_error_state {
u32 power_well_driver;
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 <paulo.r.zanoni@intel.com> 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 <paulo.r.zanoni@intel.com> Cc: Damien Lespiau <damien.lespiau@intel.com> Cc: Jani Nikula <jani.nikula@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=60021 Cc: stable@vger.kernel.org Tested-by: Dustin King <daking@rescomp.stanford.edu> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-08-08 15:12:06 +02:00
int num_transcoders;
struct intel_cursor_error_state {
u32 control;
u32 position;
u32 base;
u32 size;
} cursor[I915_MAX_PIPES];
struct intel_pipe_error_state {
2013-11-27 22:02:02 +02:00
bool power_domain_on;
u32 source;
u32 stat;
} pipe[I915_MAX_PIPES];
struct intel_plane_error_state {
u32 control;
u32 stride;
u32 size;
u32 pos;
u32 addr;
u32 surface;
u32 tile_offset;
} plane[I915_MAX_PIPES];
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 <paulo.r.zanoni@intel.com> 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 <paulo.r.zanoni@intel.com> Cc: Damien Lespiau <damien.lespiau@intel.com> Cc: Jani Nikula <jani.nikula@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=60021 Cc: stable@vger.kernel.org Tested-by: Dustin King <daking@rescomp.stanford.edu> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-08-08 15:12:06 +02:00
struct intel_transcoder_error_state {
2013-11-27 22:02:02 +02:00
bool power_domain_on;
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 <paulo.r.zanoni@intel.com> 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 <paulo.r.zanoni@intel.com> Cc: Damien Lespiau <damien.lespiau@intel.com> Cc: Jani Nikula <jani.nikula@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=60021 Cc: stable@vger.kernel.org Tested-by: Dustin King <daking@rescomp.stanford.edu> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-08-08 15:12:06 +02:00
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 *
intel_display_capture_error_state(struct drm_i915_private *dev_priv)
{
struct intel_display_error_state *error;
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 <paulo.r.zanoni@intel.com> 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 <paulo.r.zanoni@intel.com> Cc: Damien Lespiau <damien.lespiau@intel.com> Cc: Jani Nikula <jani.nikula@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=60021 Cc: stable@vger.kernel.org Tested-by: Dustin King <daking@rescomp.stanford.edu> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-08-08 15:12:06 +02:00
int transcoders[] = {
TRANSCODER_A,
TRANSCODER_B,
TRANSCODER_C,
TRANSCODER_EDP,
};
int i;
if (INTEL_INFO(dev_priv)->num_pipes == 0)
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 <paulo.r.zanoni@intel.com> 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 <paulo.r.zanoni@intel.com> Cc: Damien Lespiau <damien.lespiau@intel.com> Cc: Jani Nikula <jani.nikula@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=60021 Cc: stable@vger.kernel.org Tested-by: Dustin King <daking@rescomp.stanford.edu> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-08-08 15:12:06 +02:00
return NULL;
error = kzalloc(sizeof(*error), GFP_ATOMIC);
if (error == NULL)
return NULL;
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
error->power_well_driver = I915_READ(HSW_PWR_WELL_DRIVER);
for_each_pipe(dev_priv, i) {
2013-11-27 22:02:02 +02:00
error->pipe[i].power_domain_on =
__intel_display_power_is_enabled(dev_priv,
POWER_DOMAIN_PIPE(i));
2013-11-27 22:02:02 +02:00
if (!error->pipe[i].power_domain_on)
continue;
error->cursor[i].control = I915_READ(CURCNTR(i));
error->cursor[i].position = I915_READ(CURPOS(i));
error->cursor[i].base = I915_READ(CURBASE(i));
error->plane[i].control = I915_READ(DSPCNTR(i));
error->plane[i].stride = I915_READ(DSPSTRIDE(i));
if (INTEL_GEN(dev_priv) <= 3) {
error->plane[i].size = I915_READ(DSPSIZE(i));
error->plane[i].pos = I915_READ(DSPPOS(i));
}
if (INTEL_GEN(dev_priv) <= 7 && !IS_HASWELL(dev_priv))
error->plane[i].addr = I915_READ(DSPADDR(i));
if (INTEL_GEN(dev_priv) >= 4) {
error->plane[i].surface = I915_READ(DSPSURF(i));
error->plane[i].tile_offset = I915_READ(DSPTILEOFF(i));
}
error->pipe[i].source = I915_READ(PIPESRC(i));
if (HAS_GMCH_DISPLAY(dev_priv))
error->pipe[i].stat = I915_READ(PIPESTAT(i));
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 <paulo.r.zanoni@intel.com> 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 <paulo.r.zanoni@intel.com> Cc: Damien Lespiau <damien.lespiau@intel.com> Cc: Jani Nikula <jani.nikula@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=60021 Cc: stable@vger.kernel.org Tested-by: Dustin King <daking@rescomp.stanford.edu> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-08-08 15:12:06 +02:00
}
/* Note: this does not include DSI transcoders. */
error->num_transcoders = INTEL_INFO(dev_priv)->num_pipes;
if (HAS_DDI(dev_priv))
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 <paulo.r.zanoni@intel.com> 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 <paulo.r.zanoni@intel.com> Cc: Damien Lespiau <damien.lespiau@intel.com> Cc: Jani Nikula <jani.nikula@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=60021 Cc: stable@vger.kernel.org Tested-by: Dustin King <daking@rescomp.stanford.edu> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-08-08 15:12:06 +02:00
error->num_transcoders++; /* Account for eDP. */
for (i = 0; i < error->num_transcoders; i++) {
enum transcoder cpu_transcoder = transcoders[i];
2013-11-27 22:02:02 +02:00
error->transcoder[i].power_domain_on =
__intel_display_power_is_enabled(dev_priv,
POWER_DOMAIN_TRANSCODER(cpu_transcoder));
2013-11-27 22:02:02 +02:00
if (!error->transcoder[i].power_domain_on)
continue;
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 <paulo.r.zanoni@intel.com> 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 <paulo.r.zanoni@intel.com> Cc: Damien Lespiau <damien.lespiau@intel.com> Cc: Jani Nikula <jani.nikula@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=60021 Cc: stable@vger.kernel.org Tested-by: Dustin King <daking@rescomp.stanford.edu> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-08-08 15:12:06 +02:00
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));
}
return error;
}
#define err_printf(e, ...) i915_error_printf(e, __VA_ARGS__)
void
intel_display_print_error_state(struct drm_i915_error_state_buf *m,
struct drm_device *dev,
struct intel_display_error_state *error)
{
struct drm_i915_private *dev_priv = dev->dev_private;
int i;
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 <paulo.r.zanoni@intel.com> 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 <paulo.r.zanoni@intel.com> Cc: Damien Lespiau <damien.lespiau@intel.com> Cc: Jani Nikula <jani.nikula@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=60021 Cc: stable@vger.kernel.org Tested-by: Dustin King <daking@rescomp.stanford.edu> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-08-08 15:12:06 +02:00
if (!error)
return;
err_printf(m, "Num Pipes: %d\n", INTEL_INFO(dev)->num_pipes);
if (IS_HASWELL(dev) || IS_BROADWELL(dev))
err_printf(m, "PWR_WELL_CTL2: %08x\n",
error->power_well_driver);
for_each_pipe(dev_priv, i) {
err_printf(m, "Pipe [%d]:\n", i);
2013-11-27 22:02:02 +02:00
err_printf(m, " Power: %s\n",
onoff(error->pipe[i].power_domain_on));
err_printf(m, " SRC: %08x\n", error->pipe[i].source);
err_printf(m, " STAT: %08x\n", error->pipe[i].stat);
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) {
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))
err_printf(m, " ADDR: %08x\n", error->plane[i].addr);
if (INTEL_INFO(dev)->gen >= 4) {
err_printf(m, " SURF: %08x\n", error->plane[i].surface);
err_printf(m, " TILEOFF: %08x\n", error->plane[i].tile_offset);
}
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);
}
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 <paulo.r.zanoni@intel.com> 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 <paulo.r.zanoni@intel.com> Cc: Damien Lespiau <damien.lespiau@intel.com> Cc: Jani Nikula <jani.nikula@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=60021 Cc: stable@vger.kernel.org Tested-by: Dustin King <daking@rescomp.stanford.edu> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-08-08 15:12:06 +02:00
for (i = 0; i < error->num_transcoders; i++) {
err_printf(m, "CPU transcoder: %s\n",
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 <paulo.r.zanoni@intel.com> 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 <paulo.r.zanoni@intel.com> Cc: Damien Lespiau <damien.lespiau@intel.com> Cc: Jani Nikula <jani.nikula@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=60021 Cc: stable@vger.kernel.org Tested-by: Dustin King <daking@rescomp.stanford.edu> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-08-08 15:12:06 +02:00
transcoder_name(error->transcoder[i].cpu_transcoder));
2013-11-27 22:02:02 +02:00
err_printf(m, " Power: %s\n",
onoff(error->transcoder[i].power_domain_on));
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 <paulo.r.zanoni@intel.com> 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 <paulo.r.zanoni@intel.com> Cc: Damien Lespiau <damien.lespiau@intel.com> Cc: Jani Nikula <jani.nikula@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=60021 Cc: stable@vger.kernel.org Tested-by: Dustin King <daking@rescomp.stanford.edu> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-08-08 15:12:06 +02:00
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);
}
}