DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
/*
|
|
|
|
* 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>
|
|
|
|
*/
|
|
|
|
|
2012-04-01 11:38:50 +00:00
|
|
|
#include <linux/dmi.h>
|
2009-09-10 22:28:03 +00:00
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/input.h>
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
#include <linux/i2c.h>
|
2009-06-26 03:23:55 +00:00
|
|
|
#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 08:04:11 +00:00
|
|
|
#include <linux/slab.h>
|
2010-08-13 22:11:26 +00:00
|
|
|
#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 06:25:34 +00:00
|
|
|
#include <drm/drm_edid.h>
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
#include "drmP.h"
|
|
|
|
#include "intel_drv.h"
|
|
|
|
#include "i915_drm.h"
|
|
|
|
#include "i915_drv.h"
|
2010-07-01 23:48:37 +00:00
|
|
|
#include "i915_trace.h"
|
2009-12-04 00:55:24 +00:00
|
|
|
#include "drm_dp_helper.h"
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
#include "drm_crtc_helper.h"
|
2011-11-17 06:24:52 +00:00
|
|
|
#include <linux/dma_remapping.h>
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2009-07-23 17:00:32 +00:00
|
|
|
#define HAS_eDP (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))
|
|
|
|
|
2011-08-16 19:34:10 +00:00
|
|
|
bool intel_pipe_has_type(struct drm_crtc *crtc, int type);
|
2010-08-20 19:40:52 +00:00
|
|
|
static void intel_increase_pllclock(struct drm_crtc *crtc);
|
2010-09-13 12:54:26 +00:00
|
|
|
static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
|
|
|
typedef struct {
|
2011-08-16 19:34:10 +00:00
|
|
|
/* given values */
|
|
|
|
int n;
|
|
|
|
int m1, m2;
|
|
|
|
int p1, p2;
|
|
|
|
/* derived values */
|
|
|
|
int dot;
|
|
|
|
int vco;
|
|
|
|
int m;
|
|
|
|
int p;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
} intel_clock_t;
|
|
|
|
|
|
|
|
typedef struct {
|
2011-08-16 19:34:10 +00:00
|
|
|
int min, max;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
} intel_range_t;
|
|
|
|
|
|
|
|
typedef struct {
|
2011-08-16 19:34:10 +00:00
|
|
|
int dot_limit;
|
|
|
|
int p2_slow, p2_fast;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
} intel_p2_t;
|
|
|
|
|
|
|
|
#define INTEL_P2_NUM 2
|
2009-03-18 12:13:27 +00:00
|
|
|
typedef struct intel_limit intel_limit_t;
|
|
|
|
struct intel_limit {
|
2011-08-16 19:34:10 +00:00
|
|
|
intel_range_t dot, vco, n, m, m1, m2, p, p1;
|
|
|
|
intel_p2_t p2;
|
|
|
|
bool (* find_pll)(const intel_limit_t *, struct drm_crtc *,
|
2012-01-10 23:09:36 +00:00
|
|
|
int, int, intel_clock_t *, intel_clock_t *);
|
2009-03-18 12:13:27 +00:00
|
|
|
};
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2010-07-07 21:06:43 +00:00
|
|
|
/* FDI */
|
|
|
|
#define IRONLAKE_FDI_FREQ 2700000 /* in kHz for mode->clock */
|
|
|
|
|
2009-03-18 12:13:27 +00:00
|
|
|
static bool
|
|
|
|
intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
|
2012-01-10 23:09:36 +00:00
|
|
|
int target, int refclk, intel_clock_t *match_clock,
|
|
|
|
intel_clock_t *best_clock);
|
2009-03-18 12:13:27 +00:00
|
|
|
static bool
|
|
|
|
intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
|
2012-01-10 23:09:36 +00:00
|
|
|
int target, int refclk, intel_clock_t *match_clock,
|
|
|
|
intel_clock_t *best_clock);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2009-04-07 23:16:42 +00:00
|
|
|
static bool
|
|
|
|
intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc,
|
2012-01-10 23:09:36 +00:00
|
|
|
int target, int refclk, intel_clock_t *match_clock,
|
|
|
|
intel_clock_t *best_clock);
|
2009-07-23 17:00:31 +00:00
|
|
|
static bool
|
2009-12-03 22:14:42 +00:00
|
|
|
intel_find_pll_ironlake_dp(const intel_limit_t *, struct drm_crtc *crtc,
|
2012-01-10 23:09:36 +00:00
|
|
|
int target, int refclk, intel_clock_t *match_clock,
|
|
|
|
intel_clock_t *best_clock);
|
2009-04-07 23:16:42 +00:00
|
|
|
|
2012-06-15 18:55:13 +00:00
|
|
|
static bool
|
|
|
|
intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc,
|
|
|
|
int target, int refclk, intel_clock_t *match_clock,
|
|
|
|
intel_clock_t *best_clock);
|
|
|
|
|
2010-09-07 19:54:59 +00:00
|
|
|
static inline u32 /* units of 100MHz */
|
|
|
|
intel_fdi_link_freq(struct drm_device *dev)
|
|
|
|
{
|
2010-10-13 08:59:17 +00:00
|
|
|
if (IS_GEN5(dev)) {
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
return (I915_READ(FDI_PLL_BIOS_0) & FDI_PLL_FB_CLOCK_MASK) + 2;
|
|
|
|
} else
|
|
|
|
return 27;
|
2010-09-07 19:54:59 +00:00
|
|
|
}
|
|
|
|
|
2009-06-06 02:22:17 +00:00
|
|
|
static const intel_limit_t intel_limits_i8xx_dvo = {
|
2011-08-16 19:34:10 +00:00
|
|
|
.dot = { .min = 25000, .max = 350000 },
|
|
|
|
.vco = { .min = 930000, .max = 1400000 },
|
|
|
|
.n = { .min = 3, .max = 16 },
|
|
|
|
.m = { .min = 96, .max = 140 },
|
|
|
|
.m1 = { .min = 18, .max = 26 },
|
|
|
|
.m2 = { .min = 6, .max = 16 },
|
|
|
|
.p = { .min = 4, .max = 128 },
|
|
|
|
.p1 = { .min = 2, .max = 33 },
|
2011-03-30 20:01:10 +00:00
|
|
|
.p2 = { .dot_limit = 165000,
|
|
|
|
.p2_slow = 4, .p2_fast = 2 },
|
2009-03-18 12:13:27 +00:00
|
|
|
.find_pll = intel_find_best_PLL,
|
2009-06-06 02:22:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const intel_limit_t intel_limits_i8xx_lvds = {
|
2011-08-16 19:34:10 +00:00
|
|
|
.dot = { .min = 25000, .max = 350000 },
|
|
|
|
.vco = { .min = 930000, .max = 1400000 },
|
|
|
|
.n = { .min = 3, .max = 16 },
|
|
|
|
.m = { .min = 96, .max = 140 },
|
|
|
|
.m1 = { .min = 18, .max = 26 },
|
|
|
|
.m2 = { .min = 6, .max = 16 },
|
|
|
|
.p = { .min = 4, .max = 128 },
|
|
|
|
.p1 = { .min = 1, .max = 6 },
|
2011-03-30 20:01:10 +00:00
|
|
|
.p2 = { .dot_limit = 165000,
|
|
|
|
.p2_slow = 14, .p2_fast = 7 },
|
2009-03-18 12:13:27 +00:00
|
|
|
.find_pll = intel_find_best_PLL,
|
2009-06-06 02:22:17 +00:00
|
|
|
};
|
2011-03-30 20:01:10 +00:00
|
|
|
|
2009-06-06 02:22:17 +00:00
|
|
|
static const intel_limit_t intel_limits_i9xx_sdvo = {
|
2011-08-16 19:34:10 +00:00
|
|
|
.dot = { .min = 20000, .max = 400000 },
|
|
|
|
.vco = { .min = 1400000, .max = 2800000 },
|
|
|
|
.n = { .min = 1, .max = 6 },
|
|
|
|
.m = { .min = 70, .max = 120 },
|
|
|
|
.m1 = { .min = 10, .max = 22 },
|
|
|
|
.m2 = { .min = 5, .max = 9 },
|
|
|
|
.p = { .min = 5, .max = 80 },
|
|
|
|
.p1 = { .min = 1, .max = 8 },
|
2011-03-30 20:01:10 +00:00
|
|
|
.p2 = { .dot_limit = 200000,
|
|
|
|
.p2_slow = 10, .p2_fast = 5 },
|
2009-03-18 12:13:27 +00:00
|
|
|
.find_pll = intel_find_best_PLL,
|
2009-06-06 02:22:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const intel_limit_t intel_limits_i9xx_lvds = {
|
2011-08-16 19:34:10 +00:00
|
|
|
.dot = { .min = 20000, .max = 400000 },
|
|
|
|
.vco = { .min = 1400000, .max = 2800000 },
|
|
|
|
.n = { .min = 1, .max = 6 },
|
|
|
|
.m = { .min = 70, .max = 120 },
|
|
|
|
.m1 = { .min = 10, .max = 22 },
|
|
|
|
.m2 = { .min = 5, .max = 9 },
|
|
|
|
.p = { .min = 7, .max = 98 },
|
|
|
|
.p1 = { .min = 1, .max = 8 },
|
2011-03-30 20:01:10 +00:00
|
|
|
.p2 = { .dot_limit = 112000,
|
|
|
|
.p2_slow = 14, .p2_fast = 7 },
|
2009-03-18 12:13:27 +00:00
|
|
|
.find_pll = intel_find_best_PLL,
|
2009-06-06 02:22:17 +00:00
|
|
|
};
|
|
|
|
|
2011-03-30 20:01:10 +00:00
|
|
|
|
2009-06-06 02:22:17 +00:00
|
|
|
static const intel_limit_t intel_limits_g4x_sdvo = {
|
2011-03-30 20:01:10 +00:00
|
|
|
.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
|
2009-03-18 12:13:23 +00:00
|
|
|
},
|
2009-03-18 12:13:27 +00:00
|
|
|
.find_pll = intel_g4x_find_best_PLL,
|
2009-06-06 02:22:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const intel_limit_t intel_limits_g4x_hdmi = {
|
2011-03-30 20:01:10 +00:00
|
|
|
.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 },
|
2009-03-18 12:13:27 +00:00
|
|
|
.find_pll = intel_g4x_find_best_PLL,
|
2009-06-06 02:22:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const intel_limit_t intel_limits_g4x_single_channel_lvds = {
|
2011-03-30 20:01:10 +00:00
|
|
|
.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
|
2009-03-18 12:13:23 +00:00
|
|
|
},
|
2009-03-18 12:13:27 +00:00
|
|
|
.find_pll = intel_g4x_find_best_PLL,
|
2009-06-06 02:22:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const intel_limit_t intel_limits_g4x_dual_channel_lvds = {
|
2011-03-30 20:01:10 +00:00
|
|
|
.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
|
2009-03-18 12:13:23 +00:00
|
|
|
},
|
2009-03-18 12:13:27 +00:00
|
|
|
.find_pll = intel_g4x_find_best_PLL,
|
2009-06-06 02:22:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const intel_limit_t intel_limits_g4x_display_port = {
|
2011-08-16 19:34:10 +00:00
|
|
|
.dot = { .min = 161670, .max = 227000 },
|
|
|
|
.vco = { .min = 1750000, .max = 3500000},
|
|
|
|
.n = { .min = 1, .max = 2 },
|
|
|
|
.m = { .min = 97, .max = 108 },
|
|
|
|
.m1 = { .min = 0x10, .max = 0x12 },
|
|
|
|
.m2 = { .min = 0x05, .max = 0x06 },
|
|
|
|
.p = { .min = 10, .max = 20 },
|
|
|
|
.p1 = { .min = 1, .max = 2},
|
|
|
|
.p2 = { .dot_limit = 0,
|
2011-03-30 20:01:10 +00:00
|
|
|
.p2_slow = 10, .p2_fast = 10 },
|
2011-08-16 19:34:10 +00:00
|
|
|
.find_pll = intel_find_pll_g4x_dp,
|
2009-06-06 02:22:17 +00:00
|
|
|
};
|
|
|
|
|
2009-12-03 22:14:42 +00:00
|
|
|
static const intel_limit_t intel_limits_pineview_sdvo = {
|
2011-08-16 19:34:10 +00:00
|
|
|
.dot = { .min = 20000, .max = 400000},
|
|
|
|
.vco = { .min = 1700000, .max = 3500000 },
|
2011-03-30 20:01:10 +00:00
|
|
|
/* Pineview's Ncounter is a ring counter */
|
2011-08-16 19:34:10 +00:00
|
|
|
.n = { .min = 3, .max = 6 },
|
|
|
|
.m = { .min = 2, .max = 256 },
|
2011-03-30 20:01:10 +00:00
|
|
|
/* Pineview only has one combined m divider, which we treat as m2. */
|
2011-08-16 19:34:10 +00:00
|
|
|
.m1 = { .min = 0, .max = 0 },
|
|
|
|
.m2 = { .min = 0, .max = 254 },
|
|
|
|
.p = { .min = 5, .max = 80 },
|
|
|
|
.p1 = { .min = 1, .max = 8 },
|
2011-03-30 20:01:10 +00:00
|
|
|
.p2 = { .dot_limit = 200000,
|
|
|
|
.p2_slow = 10, .p2_fast = 5 },
|
2009-04-03 07:24:43 +00:00
|
|
|
.find_pll = intel_find_best_PLL,
|
2009-06-06 02:22:17 +00:00
|
|
|
};
|
|
|
|
|
2009-12-03 22:14:42 +00:00
|
|
|
static const intel_limit_t intel_limits_pineview_lvds = {
|
2011-08-16 19:34:10 +00:00
|
|
|
.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 },
|
2011-03-30 20:01:10 +00:00
|
|
|
.p2 = { .dot_limit = 112000,
|
|
|
|
.p2_slow = 14, .p2_fast = 14 },
|
2009-04-03 07:24:43 +00:00
|
|
|
.find_pll = intel_find_best_PLL,
|
2009-06-06 02:22:17 +00:00
|
|
|
};
|
|
|
|
|
2011-03-30 20:01:10 +00:00
|
|
|
/* Ironlake / Sandybridge
|
|
|
|
*
|
|
|
|
* We calculate clock using (register_value + 2) for N/M1/M2, so here
|
|
|
|
* the range value for them is (actual_value - 2).
|
|
|
|
*/
|
2010-02-05 01:14:17 +00:00
|
|
|
static const intel_limit_t intel_limits_ironlake_dac = {
|
2011-03-30 20:01:10 +00:00
|
|
|
.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 },
|
2009-12-31 08:06:04 +00:00
|
|
|
.find_pll = intel_g4x_find_best_PLL,
|
2009-06-06 02:22:17 +00:00
|
|
|
};
|
|
|
|
|
2010-02-05 01:14:17 +00:00
|
|
|
static const intel_limit_t intel_limits_ironlake_single_lvds = {
|
2011-03-30 20:01:10 +00:00
|
|
|
.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 },
|
2010-02-05 01:14:17 +00:00
|
|
|
.find_pll = intel_g4x_find_best_PLL,
|
|
|
|
};
|
|
|
|
|
|
|
|
static const intel_limit_t intel_limits_ironlake_dual_lvds = {
|
2011-03-30 20:01:10 +00:00
|
|
|
.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 },
|
2010-02-05 01:14:17 +00:00
|
|
|
.find_pll = intel_g4x_find_best_PLL,
|
|
|
|
};
|
|
|
|
|
2011-03-30 20:01:10 +00:00
|
|
|
/* LVDS 100mhz refclk limits. */
|
2010-02-05 01:14:17 +00:00
|
|
|
static const intel_limit_t intel_limits_ironlake_single_lvds_100m = {
|
2011-03-30 20:01:10 +00:00
|
|
|
.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 },
|
2011-08-16 19:34:10 +00:00
|
|
|
.p1 = { .min = 2, .max = 8 },
|
2011-03-30 20:01:10 +00:00
|
|
|
.p2 = { .dot_limit = 225000,
|
|
|
|
.p2_slow = 14, .p2_fast = 14 },
|
2010-02-05 01:14:17 +00:00
|
|
|
.find_pll = intel_g4x_find_best_PLL,
|
|
|
|
};
|
|
|
|
|
|
|
|
static const intel_limit_t intel_limits_ironlake_dual_lvds_100m = {
|
2011-03-30 20:01:10 +00:00
|
|
|
.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 },
|
2011-08-16 19:34:10 +00:00
|
|
|
.p1 = { .min = 2, .max = 6 },
|
2011-03-30 20:01:10 +00:00
|
|
|
.p2 = { .dot_limit = 225000,
|
|
|
|
.p2_slow = 7, .p2_fast = 7 },
|
2009-12-31 08:06:04 +00:00
|
|
|
.find_pll = intel_g4x_find_best_PLL,
|
|
|
|
};
|
|
|
|
|
|
|
|
static const intel_limit_t intel_limits_ironlake_display_port = {
|
2011-08-16 19:34:10 +00:00
|
|
|
.dot = { .min = 25000, .max = 350000 },
|
|
|
|
.vco = { .min = 1760000, .max = 3510000},
|
|
|
|
.n = { .min = 1, .max = 2 },
|
|
|
|
.m = { .min = 81, .max = 90 },
|
|
|
|
.m1 = { .min = 12, .max = 22 },
|
|
|
|
.m2 = { .min = 5, .max = 9 },
|
|
|
|
.p = { .min = 10, .max = 20 },
|
|
|
|
.p1 = { .min = 1, .max = 2},
|
|
|
|
.p2 = { .dot_limit = 0,
|
2011-03-30 20:01:10 +00:00
|
|
|
.p2_slow = 10, .p2_fast = 10 },
|
2011-08-16 19:34:10 +00:00
|
|
|
.find_pll = intel_find_pll_ironlake_dp,
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
};
|
|
|
|
|
2012-06-15 18:55:13 +00:00
|
|
|
static const intel_limit_t intel_limits_vlv_dac = {
|
|
|
|
.dot = { .min = 25000, .max = 270000 },
|
|
|
|
.vco = { .min = 4000000, .max = 6000000 },
|
|
|
|
.n = { .min = 1, .max = 7 },
|
|
|
|
.m = { .min = 22, .max = 450 }, /* guess */
|
|
|
|
.m1 = { .min = 2, .max = 3 },
|
|
|
|
.m2 = { .min = 11, .max = 156 },
|
|
|
|
.p = { .min = 10, .max = 30 },
|
|
|
|
.p1 = { .min = 2, .max = 3 },
|
|
|
|
.p2 = { .dot_limit = 270000,
|
|
|
|
.p2_slow = 2, .p2_fast = 20 },
|
|
|
|
.find_pll = intel_vlv_find_best_pll,
|
|
|
|
};
|
|
|
|
|
|
|
|
static const intel_limit_t intel_limits_vlv_hdmi = {
|
|
|
|
.dot = { .min = 20000, .max = 165000 },
|
|
|
|
.vco = { .min = 5994000, .max = 4000000 },
|
|
|
|
.n = { .min = 1, .max = 7 },
|
|
|
|
.m = { .min = 60, .max = 300 }, /* guess */
|
|
|
|
.m1 = { .min = 2, .max = 3 },
|
|
|
|
.m2 = { .min = 11, .max = 156 },
|
|
|
|
.p = { .min = 10, .max = 30 },
|
|
|
|
.p1 = { .min = 2, .max = 3 },
|
|
|
|
.p2 = { .dot_limit = 270000,
|
|
|
|
.p2_slow = 2, .p2_fast = 20 },
|
|
|
|
.find_pll = intel_vlv_find_best_pll,
|
|
|
|
};
|
|
|
|
|
|
|
|
static const intel_limit_t intel_limits_vlv_dp = {
|
|
|
|
.dot = { .min = 162000, .max = 270000 },
|
|
|
|
.vco = { .min = 5994000, .max = 4000000 },
|
|
|
|
.n = { .min = 1, .max = 7 },
|
|
|
|
.m = { .min = 60, .max = 300 }, /* guess */
|
|
|
|
.m1 = { .min = 2, .max = 3 },
|
|
|
|
.m2 = { .min = 11, .max = 156 },
|
|
|
|
.p = { .min = 10, .max = 30 },
|
|
|
|
.p1 = { .min = 2, .max = 3 },
|
|
|
|
.p2 = { .dot_limit = 270000,
|
|
|
|
.p2_slow = 2, .p2_fast = 20 },
|
|
|
|
.find_pll = intel_vlv_find_best_pll,
|
|
|
|
};
|
|
|
|
|
2012-03-28 20:39:25 +00:00
|
|
|
u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg)
|
|
|
|
{
|
|
|
|
unsigned long flags;
|
|
|
|
u32 val = 0;
|
|
|
|
|
|
|
|
spin_lock_irqsave(&dev_priv->dpio_lock, flags);
|
|
|
|
if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) {
|
|
|
|
DRM_ERROR("DPIO idle wait timed out\n");
|
|
|
|
goto out_unlock;
|
|
|
|
}
|
|
|
|
|
|
|
|
I915_WRITE(DPIO_REG, reg);
|
|
|
|
I915_WRITE(DPIO_PKT, DPIO_RID | DPIO_OP_READ | DPIO_PORTID |
|
|
|
|
DPIO_BYTE);
|
|
|
|
if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) {
|
|
|
|
DRM_ERROR("DPIO read wait timed out\n");
|
|
|
|
goto out_unlock;
|
|
|
|
}
|
|
|
|
val = I915_READ(DPIO_DATA);
|
|
|
|
|
|
|
|
out_unlock:
|
|
|
|
spin_unlock_irqrestore(&dev_priv->dpio_lock, flags);
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
2012-06-15 18:55:13 +00:00
|
|
|
static void intel_dpio_write(struct drm_i915_private *dev_priv, int reg,
|
|
|
|
u32 val)
|
|
|
|
{
|
|
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
spin_lock_irqsave(&dev_priv->dpio_lock, flags);
|
|
|
|
if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) {
|
|
|
|
DRM_ERROR("DPIO idle wait timed out\n");
|
|
|
|
goto out_unlock;
|
|
|
|
}
|
|
|
|
|
|
|
|
I915_WRITE(DPIO_DATA, val);
|
|
|
|
I915_WRITE(DPIO_REG, reg);
|
|
|
|
I915_WRITE(DPIO_PKT, DPIO_RID | DPIO_OP_WRITE | DPIO_PORTID |
|
|
|
|
DPIO_BYTE);
|
|
|
|
if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100))
|
|
|
|
DRM_ERROR("DPIO write wait timed out\n");
|
|
|
|
|
|
|
|
out_unlock:
|
|
|
|
spin_unlock_irqrestore(&dev_priv->dpio_lock, flags);
|
|
|
|
}
|
|
|
|
|
2012-03-28 20:39:25 +00:00
|
|
|
static void vlv_init_dpio(struct drm_device *dev)
|
|
|
|
{
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
|
|
|
|
/* Reset the DPIO config */
|
|
|
|
I915_WRITE(DPIO_CTL, 0);
|
|
|
|
POSTING_READ(DPIO_CTL);
|
|
|
|
I915_WRITE(DPIO_CTL, 1);
|
|
|
|
POSTING_READ(DPIO_CTL);
|
|
|
|
}
|
|
|
|
|
2012-04-01 11:38:50 +00:00
|
|
|
static int intel_dual_link_lvds_callback(const struct dmi_system_id *id)
|
|
|
|
{
|
|
|
|
DRM_INFO("Forcing lvds to dual link mode on %s\n", id->ident);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct dmi_system_id intel_dual_link_lvds[] = {
|
|
|
|
{
|
|
|
|
.callback = intel_dual_link_lvds_callback,
|
|
|
|
.ident = "Apple MacBook Pro (Core i5/i7 Series)",
|
|
|
|
.matches = {
|
|
|
|
DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
|
|
|
|
DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro8,2"),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{ } /* terminating entry */
|
|
|
|
};
|
|
|
|
|
2012-03-20 12:07:05 +00:00
|
|
|
static bool is_dual_link_lvds(struct drm_i915_private *dev_priv,
|
|
|
|
unsigned int reg)
|
|
|
|
{
|
|
|
|
unsigned int val;
|
|
|
|
|
2012-03-20 12:07:06 +00:00
|
|
|
/* use the module option value if specified */
|
|
|
|
if (i915_lvds_channel_mode > 0)
|
|
|
|
return i915_lvds_channel_mode == 2;
|
|
|
|
|
2012-04-01 11:38:50 +00:00
|
|
|
if (dmi_check_system(intel_dual_link_lvds))
|
|
|
|
return true;
|
|
|
|
|
2012-03-20 12:07:05 +00:00
|
|
|
if (dev_priv->lvds_val)
|
|
|
|
val = dev_priv->lvds_val;
|
|
|
|
else {
|
|
|
|
/* BIOS should set the proper LVDS register value at boot, but
|
|
|
|
* in reality, it doesn't set the value when the lid is closed;
|
|
|
|
* we need to check "the value to be set" in VBT when LVDS
|
|
|
|
* register is uninitialized.
|
|
|
|
*/
|
|
|
|
val = I915_READ(reg);
|
2012-06-13 18:46:58 +00:00
|
|
|
if (!(val & ~(LVDS_PIPE_MASK | LVDS_DETECTED)))
|
2012-03-20 12:07:05 +00:00
|
|
|
val = dev_priv->bios_lvds_val;
|
|
|
|
dev_priv->lvds_val = val;
|
|
|
|
}
|
|
|
|
return (val & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP;
|
|
|
|
}
|
|
|
|
|
2010-12-14 20:04:54 +00:00
|
|
|
static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc,
|
|
|
|
int refclk)
|
2009-06-05 07:38:42 +00:00
|
|
|
{
|
2010-02-05 01:14:17 +00:00
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
2009-06-05 07:38:42 +00:00
|
|
|
const intel_limit_t *limit;
|
2010-02-05 01:14:17 +00:00
|
|
|
|
|
|
|
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
|
2012-03-20 12:07:05 +00:00
|
|
|
if (is_dual_link_lvds(dev_priv, PCH_LVDS)) {
|
2010-02-05 01:14:17 +00:00
|
|
|
/* LVDS dual channel */
|
2010-12-14 20:04:54 +00:00
|
|
|
if (refclk == 100000)
|
2010-02-05 01:14:17 +00:00
|
|
|
limit = &intel_limits_ironlake_dual_lvds_100m;
|
|
|
|
else
|
|
|
|
limit = &intel_limits_ironlake_dual_lvds;
|
|
|
|
} else {
|
2010-12-14 20:04:54 +00:00
|
|
|
if (refclk == 100000)
|
2010-02-05 01:14:17 +00:00
|
|
|
limit = &intel_limits_ironlake_single_lvds_100m;
|
|
|
|
else
|
|
|
|
limit = &intel_limits_ironlake_single_lvds;
|
|
|
|
}
|
|
|
|
} else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) ||
|
2009-12-31 08:06:04 +00:00
|
|
|
HAS_eDP)
|
|
|
|
limit = &intel_limits_ironlake_display_port;
|
2009-06-05 07:38:42 +00:00
|
|
|
else
|
2010-02-05 01:14:17 +00:00
|
|
|
limit = &intel_limits_ironlake_dac;
|
2009-06-05 07:38:42 +00:00
|
|
|
|
|
|
|
return limit;
|
|
|
|
}
|
|
|
|
|
2009-03-18 12:13:23 +00:00
|
|
|
static const intel_limit_t *intel_g4x_limit(struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
const intel_limit_t *limit;
|
|
|
|
|
|
|
|
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
|
2012-03-20 12:07:05 +00:00
|
|
|
if (is_dual_link_lvds(dev_priv, LVDS))
|
2009-03-18 12:13:23 +00:00
|
|
|
/* LVDS with dual channel */
|
2009-06-06 02:22:17 +00:00
|
|
|
limit = &intel_limits_g4x_dual_channel_lvds;
|
2009-03-18 12:13:23 +00:00
|
|
|
else
|
|
|
|
/* LVDS with dual channel */
|
2009-06-06 02:22:17 +00:00
|
|
|
limit = &intel_limits_g4x_single_channel_lvds;
|
2009-03-18 12:13:23 +00:00
|
|
|
} else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI) ||
|
|
|
|
intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) {
|
2009-06-06 02:22:17 +00:00
|
|
|
limit = &intel_limits_g4x_hdmi;
|
2009-03-18 12:13:23 +00:00
|
|
|
} else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) {
|
2009-06-06 02:22:17 +00:00
|
|
|
limit = &intel_limits_g4x_sdvo;
|
2011-08-16 19:34:10 +00:00
|
|
|
} else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) {
|
2009-06-06 02:22:17 +00:00
|
|
|
limit = &intel_limits_g4x_display_port;
|
2009-03-18 12:13:23 +00:00
|
|
|
} else /* The option is for other outputs */
|
2009-06-06 02:22:17 +00:00
|
|
|
limit = &intel_limits_i9xx_sdvo;
|
2009-03-18 12:13:23 +00:00
|
|
|
|
|
|
|
return limit;
|
|
|
|
}
|
|
|
|
|
2010-12-14 20:04:54 +00:00
|
|
|
static const intel_limit_t *intel_limit(struct drm_crtc *crtc, int refclk)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
const intel_limit_t *limit;
|
|
|
|
|
2009-10-22 23:11:14 +00:00
|
|
|
if (HAS_PCH_SPLIT(dev))
|
2010-12-14 20:04:54 +00:00
|
|
|
limit = intel_ironlake_limit(crtc, refclk);
|
2009-06-05 07:38:42 +00:00
|
|
|
else if (IS_G4X(dev)) {
|
2009-03-18 12:13:23 +00:00
|
|
|
limit = intel_g4x_limit(crtc);
|
2009-12-03 22:14:42 +00:00
|
|
|
} else if (IS_PINEVIEW(dev)) {
|
2009-02-23 07:19:16 +00:00
|
|
|
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
|
2009-12-03 22:14:42 +00:00
|
|
|
limit = &intel_limits_pineview_lvds;
|
2009-02-23 07:19:16 +00:00
|
|
|
else
|
2009-12-03 22:14:42 +00:00
|
|
|
limit = &intel_limits_pineview_sdvo;
|
2012-06-15 18:55:13 +00:00
|
|
|
} else if (IS_VALLEYVIEW(dev)) {
|
|
|
|
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG))
|
|
|
|
limit = &intel_limits_vlv_dac;
|
|
|
|
else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI))
|
|
|
|
limit = &intel_limits_vlv_hdmi;
|
|
|
|
else
|
|
|
|
limit = &intel_limits_vlv_dp;
|
2010-09-16 23:32:17 +00:00
|
|
|
} else if (!IS_GEN2(dev)) {
|
|
|
|
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
|
|
|
|
limit = &intel_limits_i9xx_lvds;
|
|
|
|
else
|
|
|
|
limit = &intel_limits_i9xx_sdvo;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
} else {
|
|
|
|
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
|
2009-06-06 02:22:17 +00:00
|
|
|
limit = &intel_limits_i8xx_lvds;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
else
|
2009-06-06 02:22:17 +00:00
|
|
|
limit = &intel_limits_i8xx_dvo;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
return limit;
|
|
|
|
}
|
|
|
|
|
2009-12-03 22:14:42 +00:00
|
|
|
/* m1 is reserved as 0 in Pineview, n is a ring counter */
|
|
|
|
static void pineview_clock(int refclk, intel_clock_t *clock)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
{
|
2009-02-23 07:19:16 +00:00
|
|
|
clock->m = clock->m2 + 2;
|
|
|
|
clock->p = clock->p1 * clock->p2;
|
|
|
|
clock->vco = refclk * clock->m / clock->n;
|
|
|
|
clock->dot = clock->vco / clock->p;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void intel_clock(struct drm_device *dev, int refclk, intel_clock_t *clock)
|
|
|
|
{
|
2009-12-03 22:14:42 +00:00
|
|
|
if (IS_PINEVIEW(dev)) {
|
|
|
|
pineview_clock(refclk, clock);
|
2009-02-23 07:19:16 +00:00
|
|
|
return;
|
|
|
|
}
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
|
|
|
|
clock->p = clock->p1 * clock->p2;
|
|
|
|
clock->vco = refclk * clock->m / (clock->n + 2);
|
|
|
|
clock->dot = clock->vco / clock->p;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns whether any output on the specified pipe is of the specified type
|
|
|
|
*/
|
2010-09-09 14:14:28 +00:00
|
|
|
bool intel_pipe_has_type(struct drm_crtc *crtc, int type)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
{
|
2010-09-09 14:14:28 +00:00
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct intel_encoder *encoder;
|
|
|
|
|
2012-07-05 07:50:24 +00:00
|
|
|
for_each_encoder_on_crtc(dev, crtc, encoder)
|
|
|
|
if (encoder->type == type)
|
2010-09-09 14:14:28 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
2009-02-23 23:36:40 +00:00
|
|
|
#define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
/**
|
|
|
|
* Returns whether the given set of divisors are valid for a given refclk with
|
|
|
|
* the given connectors.
|
|
|
|
*/
|
|
|
|
|
2010-12-14 20:04:54 +00:00
|
|
|
static bool intel_PLL_is_valid(struct drm_device *dev,
|
|
|
|
const intel_limit_t *limit,
|
|
|
|
const intel_clock_t *clock)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
{
|
|
|
|
if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1)
|
2011-08-16 19:34:10 +00:00
|
|
|
INTELPllInvalid("p1 out of range\n");
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
if (clock->p < limit->p.min || limit->p.max < clock->p)
|
2011-08-16 19:34:10 +00:00
|
|
|
INTELPllInvalid("p out of range\n");
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
if (clock->m2 < limit->m2.min || limit->m2.max < clock->m2)
|
2011-08-16 19:34:10 +00:00
|
|
|
INTELPllInvalid("m2 out of range\n");
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1)
|
2011-08-16 19:34:10 +00:00
|
|
|
INTELPllInvalid("m1 out of range\n");
|
2009-12-03 22:14:42 +00:00
|
|
|
if (clock->m1 <= clock->m2 && !IS_PINEVIEW(dev))
|
2011-08-16 19:34:10 +00:00
|
|
|
INTELPllInvalid("m1 <= m2\n");
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
if (clock->m < limit->m.min || limit->m.max < clock->m)
|
2011-08-16 19:34:10 +00:00
|
|
|
INTELPllInvalid("m out of range\n");
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
if (clock->n < limit->n.min || limit->n.max < clock->n)
|
2011-08-16 19:34:10 +00:00
|
|
|
INTELPllInvalid("n out of range\n");
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
if (clock->vco < limit->vco.min || limit->vco.max < clock->vco)
|
2011-08-16 19:34:10 +00:00
|
|
|
INTELPllInvalid("vco out of range\n");
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
/* 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)
|
2011-08-16 19:34:10 +00:00
|
|
|
INTELPllInvalid("dot out of range\n");
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-03-18 12:13:27 +00:00
|
|
|
static bool
|
|
|
|
intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
|
2012-01-10 23:09:36 +00:00
|
|
|
int target, int refclk, intel_clock_t *match_clock,
|
|
|
|
intel_clock_t *best_clock)
|
2009-03-18 12:13:27 +00:00
|
|
|
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
intel_clock_t clock;
|
|
|
|
int err = target;
|
|
|
|
|
2009-08-08 11:01:17 +00:00
|
|
|
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
|
2009-07-13 10:40:32 +00:00
|
|
|
(I915_READ(LVDS)) != 0) {
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
/*
|
|
|
|
* For LVDS, if the panel is on, 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.
|
|
|
|
*/
|
2012-03-20 12:07:05 +00:00
|
|
|
if (is_dual_link_lvds(dev_priv, LVDS))
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
clock.p2 = limit->p2.p2_fast;
|
|
|
|
else
|
|
|
|
clock.p2 = limit->p2.p2_slow;
|
|
|
|
} else {
|
|
|
|
if (target < limit->p2.dot_limit)
|
|
|
|
clock.p2 = limit->p2.p2_slow;
|
|
|
|
else
|
|
|
|
clock.p2 = limit->p2.p2_fast;
|
|
|
|
}
|
|
|
|
|
2011-08-16 19:34:10 +00:00
|
|
|
memset(best_clock, 0, sizeof(*best_clock));
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2009-11-20 03:24:18 +00:00
|
|
|
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++) {
|
2009-12-03 22:14:42 +00:00
|
|
|
/* m1 is always 0 in Pineview */
|
|
|
|
if (clock.m2 >= clock.m1 && !IS_PINEVIEW(dev))
|
2009-11-20 03:24:18 +00:00
|
|
|
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++) {
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
int this_err;
|
|
|
|
|
2009-02-23 07:19:16 +00:00
|
|
|
intel_clock(dev, refclk, &clock);
|
2010-12-14 20:04:54 +00:00
|
|
|
if (!intel_PLL_is_valid(dev, limit,
|
|
|
|
&clock))
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
continue;
|
2012-01-10 23:09:36 +00:00
|
|
|
if (match_clock &&
|
|
|
|
clock.p != match_clock->p)
|
|
|
|
continue;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
|
|
|
this_err = abs(clock.dot - target);
|
|
|
|
if (this_err < err) {
|
|
|
|
*best_clock = clock;
|
|
|
|
err = this_err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return (err != target);
|
|
|
|
}
|
|
|
|
|
2009-03-18 12:13:27 +00:00
|
|
|
static bool
|
|
|
|
intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
|
2012-01-10 23:09:36 +00:00
|
|
|
int target, int refclk, intel_clock_t *match_clock,
|
|
|
|
intel_clock_t *best_clock)
|
2009-03-18 12:13:27 +00:00
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
intel_clock_t clock;
|
|
|
|
int max_n;
|
|
|
|
bool found;
|
2010-07-02 20:43:30 +00:00
|
|
|
/* approximately equals target * 0.00585 */
|
|
|
|
int err_most = (target >> 8) + (target >> 9);
|
2009-03-18 12:13:27 +00:00
|
|
|
found = false;
|
|
|
|
|
|
|
|
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
|
2009-12-31 08:06:04 +00:00
|
|
|
int lvds_reg;
|
|
|
|
|
2010-01-29 00:45:52 +00:00
|
|
|
if (HAS_PCH_SPLIT(dev))
|
2009-12-31 08:06:04 +00:00
|
|
|
lvds_reg = PCH_LVDS;
|
|
|
|
else
|
|
|
|
lvds_reg = LVDS;
|
|
|
|
if ((I915_READ(lvds_reg) & LVDS_CLKB_POWER_MASK) ==
|
2009-03-18 12:13:27 +00:00
|
|
|
LVDS_CLKB_POWER_UP)
|
|
|
|
clock.p2 = limit->p2.p2_fast;
|
|
|
|
else
|
|
|
|
clock.p2 = limit->p2.p2_slow;
|
|
|
|
} else {
|
|
|
|
if (target < limit->p2.dot_limit)
|
|
|
|
clock.p2 = limit->p2.p2_slow;
|
|
|
|
else
|
|
|
|
clock.p2 = limit->p2.p2_fast;
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(best_clock, 0, sizeof(*best_clock));
|
|
|
|
max_n = limit->n.max;
|
2010-03-29 13:41:47 +00:00
|
|
|
/* based on hardware requirement, prefer smaller n to precision */
|
2009-03-18 12:13:27 +00:00
|
|
|
for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
|
2010-03-29 13:41:47 +00:00
|
|
|
/* based on hardware requirement, prefere larger m1,m2 */
|
2009-03-18 12:13:27 +00:00
|
|
|
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;
|
|
|
|
|
2009-02-23 07:19:16 +00:00
|
|
|
intel_clock(dev, refclk, &clock);
|
2010-12-14 20:04:54 +00:00
|
|
|
if (!intel_PLL_is_valid(dev, limit,
|
|
|
|
&clock))
|
2009-03-18 12:13:27 +00:00
|
|
|
continue;
|
2012-01-10 23:09:36 +00:00
|
|
|
if (match_clock &&
|
|
|
|
clock.p != match_clock->p)
|
|
|
|
continue;
|
2010-12-14 20:04:54 +00:00
|
|
|
|
|
|
|
this_err = abs(clock.dot - target);
|
2009-03-18 12:13:27 +00:00
|
|
|
if (this_err < err_most) {
|
|
|
|
*best_clock = clock;
|
|
|
|
err_most = this_err;
|
|
|
|
max_n = clock.n;
|
|
|
|
found = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-06-05 07:38:42 +00:00
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
2009-07-23 17:00:31 +00:00
|
|
|
static bool
|
2009-12-03 22:14:42 +00:00
|
|
|
intel_find_pll_ironlake_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
|
2012-01-10 23:09:36 +00:00
|
|
|
int target, int refclk, intel_clock_t *match_clock,
|
|
|
|
intel_clock_t *best_clock)
|
2009-07-23 17:00:31 +00:00
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
intel_clock_t clock;
|
2009-12-31 08:06:04 +00:00
|
|
|
|
2009-07-23 17:00:31 +00:00
|
|
|
if (target < 200000) {
|
|
|
|
clock.n = 1;
|
|
|
|
clock.p1 = 2;
|
|
|
|
clock.p2 = 10;
|
|
|
|
clock.m1 = 12;
|
|
|
|
clock.m2 = 9;
|
|
|
|
} else {
|
|
|
|
clock.n = 2;
|
|
|
|
clock.p1 = 1;
|
|
|
|
clock.p2 = 10;
|
|
|
|
clock.m1 = 14;
|
|
|
|
clock.m2 = 8;
|
|
|
|
}
|
|
|
|
intel_clock(dev, refclk, &clock);
|
|
|
|
memcpy(best_clock, &clock, sizeof(intel_clock_t));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-04-07 23:16:42 +00:00
|
|
|
/* DisplayPort has only two frequencies, 162MHz and 270MHz */
|
|
|
|
static bool
|
|
|
|
intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
|
2012-01-10 23:09:36 +00:00
|
|
|
int target, int refclk, intel_clock_t *match_clock,
|
|
|
|
intel_clock_t *best_clock)
|
2009-04-07 23:16:42 +00:00
|
|
|
{
|
2010-09-11 12:48:45 +00:00
|
|
|
intel_clock_t clock;
|
|
|
|
if (target < 200000) {
|
|
|
|
clock.p1 = 2;
|
|
|
|
clock.p2 = 10;
|
|
|
|
clock.n = 2;
|
|
|
|
clock.m1 = 23;
|
|
|
|
clock.m2 = 8;
|
|
|
|
} else {
|
|
|
|
clock.p1 = 1;
|
|
|
|
clock.p2 = 10;
|
|
|
|
clock.n = 1;
|
|
|
|
clock.m1 = 14;
|
|
|
|
clock.m2 = 2;
|
|
|
|
}
|
|
|
|
clock.m = 5 * (clock.m1 + 2) + (clock.m2 + 2);
|
|
|
|
clock.p = (clock.p1 * clock.p2);
|
|
|
|
clock.dot = 96000 * clock.m / (clock.n + 2) / clock.p;
|
|
|
|
clock.vco = 0;
|
|
|
|
memcpy(best_clock, &clock, sizeof(intel_clock_t));
|
|
|
|
return true;
|
2009-04-07 23:16:42 +00:00
|
|
|
}
|
2012-06-15 18:55:13 +00:00
|
|
|
static bool
|
|
|
|
intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc,
|
|
|
|
int target, int refclk, intel_clock_t *match_clock,
|
|
|
|
intel_clock_t *best_clock)
|
|
|
|
{
|
|
|
|
u32 p1, p2, m1, m2, vco, bestn, bestm1, bestm2, bestp1, bestp2;
|
|
|
|
u32 m, n, fastclk;
|
|
|
|
u32 updrate, minupdate, fracbits, p;
|
|
|
|
unsigned long bestppm, ppm, absppm;
|
|
|
|
int dotclk, flag;
|
|
|
|
|
2012-07-25 12:49:18 +00:00
|
|
|
flag = 0;
|
2012-06-15 18:55:13 +00:00
|
|
|
dotclk = target * 1000;
|
|
|
|
bestppm = 1000000;
|
|
|
|
ppm = absppm = 0;
|
|
|
|
fastclk = dotclk / (2*100);
|
|
|
|
updrate = 0;
|
|
|
|
minupdate = 19200;
|
|
|
|
fracbits = 1;
|
|
|
|
n = p = p1 = p2 = m = m1 = m2 = vco = bestn = 0;
|
|
|
|
bestm1 = bestm2 = bestp1 = bestp2 = 0;
|
|
|
|
|
|
|
|
/* based on hardware requirement, prefer smaller n to precision */
|
|
|
|
for (n = limit->n.min; n <= ((refclk) / minupdate); n++) {
|
|
|
|
updrate = refclk / n;
|
|
|
|
for (p1 = limit->p1.max; p1 > limit->p1.min; p1--) {
|
|
|
|
for (p2 = limit->p2.p2_fast+1; p2 > 0; p2--) {
|
|
|
|
if (p2 > 10)
|
|
|
|
p2 = p2 - 1;
|
|
|
|
p = p1 * p2;
|
|
|
|
/* based on hardware requirement, prefer bigger m1,m2 values */
|
|
|
|
for (m1 = limit->m1.min; m1 <= limit->m1.max; m1++) {
|
|
|
|
m2 = (((2*(fastclk * p * n / m1 )) +
|
|
|
|
refclk) / (2*refclk));
|
|
|
|
m = m1 * m2;
|
|
|
|
vco = updrate * m;
|
|
|
|
if (vco >= limit->vco.min && vco < limit->vco.max) {
|
|
|
|
ppm = 1000000 * ((vco / p) - fastclk) / fastclk;
|
|
|
|
absppm = (ppm > 0) ? ppm : (-ppm);
|
|
|
|
if (absppm < 100 && ((p1 * p2) > (bestp1 * bestp2))) {
|
|
|
|
bestppm = 0;
|
|
|
|
flag = 1;
|
|
|
|
}
|
|
|
|
if (absppm < bestppm - 10) {
|
|
|
|
bestppm = absppm;
|
|
|
|
flag = 1;
|
|
|
|
}
|
|
|
|
if (flag) {
|
|
|
|
bestn = n;
|
|
|
|
bestm1 = m1;
|
|
|
|
bestm2 = m2;
|
|
|
|
bestp1 = p1;
|
|
|
|
bestp2 = p2;
|
|
|
|
flag = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
best_clock->n = bestn;
|
|
|
|
best_clock->m1 = bestm1;
|
|
|
|
best_clock->m2 = bestm2;
|
|
|
|
best_clock->p1 = bestp1;
|
|
|
|
best_clock->p2 = bestp2;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2009-04-07 23:16:42 +00:00
|
|
|
|
2012-05-04 20:18:15 +00:00
|
|
|
static void ironlake_wait_for_vblank(struct drm_device *dev, int pipe)
|
|
|
|
{
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
u32 frame, frame_reg = PIPEFRAME(pipe);
|
|
|
|
|
|
|
|
frame = I915_READ(frame_reg);
|
|
|
|
|
|
|
|
if (wait_for(I915_READ_NOTRACE(frame_reg) != frame, 50))
|
|
|
|
DRM_DEBUG_KMS("vblank wait timed out\n");
|
|
|
|
}
|
|
|
|
|
2010-08-18 20:20:54 +00:00
|
|
|
/**
|
|
|
|
* intel_wait_for_vblank - wait for vblank on a given pipe
|
|
|
|
* @dev: drm device
|
|
|
|
* @pipe: pipe to wait for
|
|
|
|
*
|
|
|
|
* Wait for vblank to occur on a given pipe. Needed for various bits of
|
|
|
|
* mode setting code.
|
|
|
|
*/
|
|
|
|
void intel_wait_for_vblank(struct drm_device *dev, int pipe)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
{
|
2010-08-18 20:20:54 +00:00
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
2011-02-07 20:26:52 +00:00
|
|
|
int pipestat_reg = PIPESTAT(pipe);
|
2010-08-18 20:20:54 +00:00
|
|
|
|
2012-05-04 20:18:15 +00:00
|
|
|
if (INTEL_INFO(dev)->gen >= 5) {
|
|
|
|
ironlake_wait_for_vblank(dev, pipe);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-09-05 19:25:43 +00:00
|
|
|
/* Clear existing vblank status. Note this will clear any other
|
|
|
|
* sticky status fields as well.
|
|
|
|
*
|
|
|
|
* This races with i915_driver_irq_handler() with the result
|
|
|
|
* that either function could miss a vblank event. Here it is not
|
|
|
|
* fatal, as we will either wait upon the next vblank interrupt or
|
|
|
|
* timeout. Generally speaking intel_wait_for_vblank() is only
|
|
|
|
* called during modeset at which time the GPU should be idle and
|
|
|
|
* should *not* be performing page flips and thus not waiting on
|
|
|
|
* vblanks...
|
|
|
|
* Currently, the result of us stealing a vblank from the irq
|
|
|
|
* handler is that a single frame will be skipped during swapbuffers.
|
|
|
|
*/
|
|
|
|
I915_WRITE(pipestat_reg,
|
|
|
|
I915_READ(pipestat_reg) | PIPE_VBLANK_INTERRUPT_STATUS);
|
|
|
|
|
2010-08-18 20:20:54 +00:00
|
|
|
/* Wait for vblank interrupt bit to set */
|
2010-08-23 16:43:35 +00:00
|
|
|
if (wait_for(I915_READ(pipestat_reg) &
|
|
|
|
PIPE_VBLANK_INTERRUPT_STATUS,
|
|
|
|
50))
|
2010-08-18 20:20:54 +00:00
|
|
|
DRM_DEBUG_KMS("vblank wait timed out\n");
|
|
|
|
}
|
|
|
|
|
2010-10-03 07:33:06 +00:00
|
|
|
/*
|
|
|
|
* intel_wait_for_pipe_off - wait for pipe to turn off
|
2010-08-18 20:20:54 +00:00
|
|
|
* @dev: drm device
|
|
|
|
* @pipe: 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.
|
|
|
|
*
|
2010-10-03 07:33:06 +00:00
|
|
|
* 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).
|
2010-10-03 09:56:11 +00:00
|
|
|
*
|
2010-08-18 20:20:54 +00:00
|
|
|
*/
|
2010-10-03 09:56:11 +00:00
|
|
|
void intel_wait_for_pipe_off(struct drm_device *dev, int pipe)
|
2010-08-18 20:20:54 +00:00
|
|
|
{
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
2010-10-03 07:33:06 +00:00
|
|
|
|
|
|
|
if (INTEL_INFO(dev)->gen >= 4) {
|
2010-10-03 09:56:11 +00:00
|
|
|
int reg = PIPECONF(pipe);
|
2010-10-03 07:33:06 +00:00
|
|
|
|
|
|
|
/* Wait for the Pipe State to go off */
|
2010-10-03 09:56:11 +00:00
|
|
|
if (wait_for((I915_READ(reg) & I965_PIPECONF_ACTIVE) == 0,
|
|
|
|
100))
|
2012-07-09 07:51:57 +00:00
|
|
|
WARN(1, "pipe_off wait timed out\n");
|
2010-10-03 07:33:06 +00:00
|
|
|
} else {
|
2012-05-04 20:18:14 +00:00
|
|
|
u32 last_line, line_mask;
|
2010-10-03 09:56:11 +00:00
|
|
|
int reg = PIPEDSL(pipe);
|
2010-10-03 07:33:06 +00:00
|
|
|
unsigned long timeout = jiffies + msecs_to_jiffies(100);
|
|
|
|
|
2012-05-04 20:18:14 +00:00
|
|
|
if (IS_GEN2(dev))
|
|
|
|
line_mask = DSL_LINEMASK_GEN2;
|
|
|
|
else
|
|
|
|
line_mask = DSL_LINEMASK_GEN3;
|
|
|
|
|
2010-10-03 07:33:06 +00:00
|
|
|
/* Wait for the display line to settle */
|
|
|
|
do {
|
2012-05-04 20:18:14 +00:00
|
|
|
last_line = I915_READ(reg) & line_mask;
|
2010-10-03 07:33:06 +00:00
|
|
|
mdelay(5);
|
2012-05-04 20:18:14 +00:00
|
|
|
} while (((I915_READ(reg) & line_mask) != last_line) &&
|
2010-10-03 07:33:06 +00:00
|
|
|
time_after(timeout, jiffies));
|
|
|
|
if (time_after(jiffies, timeout))
|
2012-07-09 07:51:57 +00:00
|
|
|
WARN(1, "pipe_off wait timed out\n");
|
2010-10-03 07:33:06 +00:00
|
|
|
}
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
2011-01-04 23:09:30 +00:00
|
|
|
static const char *state_string(bool enabled)
|
|
|
|
{
|
|
|
|
return enabled ? "on" : "off";
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Only for pre-ILK configs */
|
|
|
|
static void assert_pll(struct drm_i915_private *dev_priv,
|
|
|
|
enum pipe pipe, bool state)
|
|
|
|
{
|
|
|
|
int reg;
|
|
|
|
u32 val;
|
|
|
|
bool cur_state;
|
|
|
|
|
|
|
|
reg = DPLL(pipe);
|
|
|
|
val = I915_READ(reg);
|
|
|
|
cur_state = !!(val & DPLL_VCO_ENABLE);
|
|
|
|
WARN(cur_state != state,
|
|
|
|
"PLL state assertion failure (expected %s, current %s)\n",
|
|
|
|
state_string(state), state_string(cur_state));
|
|
|
|
}
|
|
|
|
#define assert_pll_enabled(d, p) assert_pll(d, p, true)
|
|
|
|
#define assert_pll_disabled(d, p) assert_pll(d, p, false)
|
|
|
|
|
2011-01-03 20:14:26 +00:00
|
|
|
/* For ILK+ */
|
|
|
|
static void assert_pch_pll(struct drm_i915_private *dev_priv,
|
2012-05-20 17:10:50 +00:00
|
|
|
struct intel_pch_pll *pll,
|
|
|
|
struct intel_crtc *crtc,
|
|
|
|
bool state)
|
2011-01-03 20:14:26 +00:00
|
|
|
{
|
|
|
|
u32 val;
|
|
|
|
bool cur_state;
|
|
|
|
|
2012-05-09 18:37:17 +00:00
|
|
|
if (HAS_PCH_LPT(dev_priv->dev)) {
|
|
|
|
DRM_DEBUG_DRIVER("LPT detected: skipping PCH PLL test\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-05-20 17:10:50 +00:00
|
|
|
if (WARN (!pll,
|
|
|
|
"asserting PCH PLL %s with no PLL\n", state_string(state)))
|
2012-04-20 16:11:53 +00:00
|
|
|
return;
|
|
|
|
|
2012-05-20 17:10:50 +00:00
|
|
|
val = I915_READ(pll->pll_reg);
|
|
|
|
cur_state = !!(val & DPLL_VCO_ENABLE);
|
|
|
|
WARN(cur_state != state,
|
|
|
|
"PCH PLL state for reg %x assertion failure (expected %s, current %s), val=%08x\n",
|
|
|
|
pll->pll_reg, state_string(state), state_string(cur_state), val);
|
|
|
|
|
|
|
|
/* Make sure the selected PLL is correctly attached to the transcoder */
|
|
|
|
if (crtc && HAS_PCH_CPT(dev_priv->dev)) {
|
2011-10-12 16:27:42 +00:00
|
|
|
u32 pch_dpll;
|
|
|
|
|
|
|
|
pch_dpll = I915_READ(PCH_DPLL_SEL);
|
2012-05-20 17:10:50 +00:00
|
|
|
cur_state = pll->pll_reg == _PCH_DPLL_B;
|
|
|
|
if (!WARN(((pch_dpll >> (4 * crtc->pipe)) & 1) != cur_state,
|
|
|
|
"PLL[%d] not attached to this transcoder %d: %08x\n",
|
|
|
|
cur_state, crtc->pipe, pch_dpll)) {
|
|
|
|
cur_state = !!(val >> (4*crtc->pipe + 3));
|
|
|
|
WARN(cur_state != state,
|
|
|
|
"PLL[%d] not %s on this transcoder %d: %08x\n",
|
|
|
|
pll->pll_reg == _PCH_DPLL_B,
|
|
|
|
state_string(state),
|
|
|
|
crtc->pipe,
|
|
|
|
val);
|
|
|
|
}
|
2011-10-12 16:27:42 +00:00
|
|
|
}
|
2011-01-03 20:14:26 +00:00
|
|
|
}
|
2012-05-20 17:10:50 +00:00
|
|
|
#define assert_pch_pll_enabled(d, p, c) assert_pch_pll(d, p, c, true)
|
|
|
|
#define assert_pch_pll_disabled(d, p, c) assert_pch_pll(d, p, c, false)
|
2011-01-03 20:14:26 +00:00
|
|
|
|
|
|
|
static void assert_fdi_tx(struct drm_i915_private *dev_priv,
|
|
|
|
enum pipe pipe, bool state)
|
|
|
|
{
|
|
|
|
int reg;
|
|
|
|
u32 val;
|
|
|
|
bool cur_state;
|
|
|
|
|
2012-05-09 18:37:18 +00:00
|
|
|
if (IS_HASWELL(dev_priv->dev)) {
|
|
|
|
/* On Haswell, DDI is used instead of FDI_TX_CTL */
|
|
|
|
reg = DDI_FUNC_CTL(pipe);
|
|
|
|
val = I915_READ(reg);
|
|
|
|
cur_state = !!(val & PIPE_DDI_FUNC_ENABLE);
|
|
|
|
} else {
|
|
|
|
reg = FDI_TX_CTL(pipe);
|
|
|
|
val = I915_READ(reg);
|
|
|
|
cur_state = !!(val & FDI_TX_ENABLE);
|
|
|
|
}
|
2011-01-03 20:14:26 +00:00
|
|
|
WARN(cur_state != state,
|
|
|
|
"FDI TX state assertion failure (expected %s, current %s)\n",
|
|
|
|
state_string(state), state_string(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)
|
|
|
|
{
|
|
|
|
int reg;
|
|
|
|
u32 val;
|
|
|
|
bool cur_state;
|
|
|
|
|
2012-05-09 18:37:19 +00:00
|
|
|
if (IS_HASWELL(dev_priv->dev) && pipe > 0) {
|
|
|
|
DRM_ERROR("Attempting to enable FDI_RX on Haswell pipe > 0\n");
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
reg = FDI_RX_CTL(pipe);
|
|
|
|
val = I915_READ(reg);
|
|
|
|
cur_state = !!(val & FDI_RX_ENABLE);
|
|
|
|
}
|
2011-01-03 20:14:26 +00:00
|
|
|
WARN(cur_state != state,
|
|
|
|
"FDI RX state assertion failure (expected %s, current %s)\n",
|
|
|
|
state_string(state), state_string(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)
|
|
|
|
{
|
|
|
|
int reg;
|
|
|
|
u32 val;
|
|
|
|
|
|
|
|
/* ILK FDI PLL is always enabled */
|
|
|
|
if (dev_priv->info->gen == 5)
|
|
|
|
return;
|
|
|
|
|
2012-05-09 18:37:18 +00:00
|
|
|
/* On Haswell, DDI ports are responsible for the FDI PLL setup */
|
|
|
|
if (IS_HASWELL(dev_priv->dev))
|
|
|
|
return;
|
|
|
|
|
2011-01-03 20:14:26 +00:00
|
|
|
reg = FDI_TX_CTL(pipe);
|
|
|
|
val = I915_READ(reg);
|
|
|
|
WARN(!(val & FDI_TX_PLL_ENABLE), "FDI TX PLL assertion failure, should be active but is disabled\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void assert_fdi_rx_pll_enabled(struct drm_i915_private *dev_priv,
|
|
|
|
enum pipe pipe)
|
|
|
|
{
|
|
|
|
int reg;
|
|
|
|
u32 val;
|
|
|
|
|
2012-05-09 18:37:19 +00:00
|
|
|
if (IS_HASWELL(dev_priv->dev) && pipe > 0) {
|
|
|
|
DRM_ERROR("Attempting to enable FDI on Haswell with pipe > 0\n");
|
|
|
|
return;
|
|
|
|
}
|
2011-01-03 20:14:26 +00:00
|
|
|
reg = FDI_RX_CTL(pipe);
|
|
|
|
val = I915_READ(reg);
|
|
|
|
WARN(!(val & FDI_RX_PLL_ENABLE), "FDI RX PLL assertion failure, should be active but is disabled\n");
|
|
|
|
}
|
|
|
|
|
2011-01-04 23:09:32 +00:00
|
|
|
static void assert_panel_unlocked(struct drm_i915_private *dev_priv,
|
|
|
|
enum pipe pipe)
|
|
|
|
{
|
|
|
|
int pp_reg, lvds_reg;
|
|
|
|
u32 val;
|
|
|
|
enum pipe panel_pipe = PIPE_A;
|
2011-08-25 13:37:45 +00:00
|
|
|
bool locked = true;
|
2011-01-04 23:09:32 +00:00
|
|
|
|
|
|
|
if (HAS_PCH_SPLIT(dev_priv->dev)) {
|
|
|
|
pp_reg = PCH_PP_CONTROL;
|
|
|
|
lvds_reg = PCH_LVDS;
|
|
|
|
} else {
|
|
|
|
pp_reg = PP_CONTROL;
|
|
|
|
lvds_reg = LVDS;
|
|
|
|
}
|
|
|
|
|
|
|
|
val = I915_READ(pp_reg);
|
|
|
|
if (!(val & PANEL_POWER_ON) ||
|
|
|
|
((val & PANEL_UNLOCK_REGS) == PANEL_UNLOCK_REGS))
|
|
|
|
locked = false;
|
|
|
|
|
|
|
|
if (I915_READ(lvds_reg) & LVDS_PIPEB_SELECT)
|
|
|
|
panel_pipe = PIPE_B;
|
|
|
|
|
|
|
|
WARN(panel_pipe == pipe && locked,
|
|
|
|
"panel assertion failure, pipe %c regs locked\n",
|
2011-02-07 20:26:52 +00:00
|
|
|
pipe_name(pipe));
|
2011-01-04 23:09:32 +00:00
|
|
|
}
|
|
|
|
|
2011-12-13 21:19:38 +00:00
|
|
|
void assert_pipe(struct drm_i915_private *dev_priv,
|
|
|
|
enum pipe pipe, bool state)
|
2011-01-04 23:09:30 +00:00
|
|
|
{
|
|
|
|
int reg;
|
|
|
|
u32 val;
|
2011-01-04 23:09:33 +00:00
|
|
|
bool cur_state;
|
2011-01-04 23:09:30 +00:00
|
|
|
|
2012-01-22 00:36:48 +00:00
|
|
|
/* if we need the pipe A quirk it must be always on */
|
|
|
|
if (pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE)
|
|
|
|
state = true;
|
|
|
|
|
2011-01-04 23:09:30 +00:00
|
|
|
reg = PIPECONF(pipe);
|
|
|
|
val = I915_READ(reg);
|
2011-01-04 23:09:33 +00:00
|
|
|
cur_state = !!(val & PIPECONF_ENABLE);
|
|
|
|
WARN(cur_state != state,
|
|
|
|
"pipe %c assertion failure (expected %s, current %s)\n",
|
2011-02-07 20:26:52 +00:00
|
|
|
pipe_name(pipe), state_string(state), state_string(cur_state));
|
2011-01-04 23:09:30 +00:00
|
|
|
}
|
|
|
|
|
2012-01-16 23:01:13 +00:00
|
|
|
static void assert_plane(struct drm_i915_private *dev_priv,
|
|
|
|
enum plane plane, bool state)
|
2011-01-04 23:09:30 +00:00
|
|
|
{
|
|
|
|
int reg;
|
|
|
|
u32 val;
|
2012-01-16 23:01:13 +00:00
|
|
|
bool cur_state;
|
2011-01-04 23:09:30 +00:00
|
|
|
|
|
|
|
reg = DSPCNTR(plane);
|
|
|
|
val = I915_READ(reg);
|
2012-01-16 23:01:13 +00:00
|
|
|
cur_state = !!(val & DISPLAY_PLANE_ENABLE);
|
|
|
|
WARN(cur_state != state,
|
|
|
|
"plane %c assertion failure (expected %s, current %s)\n",
|
|
|
|
plane_name(plane), state_string(state), state_string(cur_state));
|
2011-01-04 23:09:30 +00:00
|
|
|
}
|
|
|
|
|
2012-01-16 23:01:13 +00:00
|
|
|
#define assert_plane_enabled(d, p) assert_plane(d, p, true)
|
|
|
|
#define assert_plane_disabled(d, p) assert_plane(d, p, false)
|
|
|
|
|
2011-01-04 23:09:30 +00:00
|
|
|
static void assert_planes_disabled(struct drm_i915_private *dev_priv,
|
|
|
|
enum pipe pipe)
|
|
|
|
{
|
|
|
|
int reg, i;
|
|
|
|
u32 val;
|
|
|
|
int cur_pipe;
|
|
|
|
|
2011-02-02 20:28:02 +00:00
|
|
|
/* Planes are fixed to pipes on ILK+ */
|
2011-10-07 18:38:42 +00:00
|
|
|
if (HAS_PCH_SPLIT(dev_priv->dev)) {
|
|
|
|
reg = DSPCNTR(pipe);
|
|
|
|
val = I915_READ(reg);
|
|
|
|
WARN((val & DISPLAY_PLANE_ENABLE),
|
|
|
|
"plane %c assertion failure, should be disabled but not\n",
|
|
|
|
plane_name(pipe));
|
2011-02-02 20:28:02 +00:00
|
|
|
return;
|
2011-10-07 18:38:42 +00:00
|
|
|
}
|
2011-02-02 20:28:02 +00:00
|
|
|
|
2011-01-04 23:09:30 +00:00
|
|
|
/* Need to check both planes against the pipe */
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
reg = DSPCNTR(i);
|
|
|
|
val = I915_READ(reg);
|
|
|
|
cur_pipe = (val & DISPPLANE_SEL_PIPE_MASK) >>
|
|
|
|
DISPPLANE_SEL_PIPE_SHIFT;
|
|
|
|
WARN((val & DISPLAY_PLANE_ENABLE) && pipe == cur_pipe,
|
2011-02-07 20:26:52 +00:00
|
|
|
"plane %c assertion failure, should be off on pipe %c but is still active\n",
|
|
|
|
plane_name(i), pipe_name(pipe));
|
2011-01-04 23:09:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-04 23:09:34 +00:00
|
|
|
static void assert_pch_refclk_enabled(struct drm_i915_private *dev_priv)
|
|
|
|
{
|
|
|
|
u32 val;
|
|
|
|
bool enabled;
|
|
|
|
|
2012-05-09 18:37:17 +00:00
|
|
|
if (HAS_PCH_LPT(dev_priv->dev)) {
|
|
|
|
DRM_DEBUG_DRIVER("LPT does not has PCH refclk, skipping check\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-01-04 23:09:34 +00:00
|
|
|
val = I915_READ(PCH_DREF_CONTROL);
|
|
|
|
enabled = !!(val & (DREF_SSC_SOURCE_MASK | DREF_NONSPREAD_SOURCE_MASK |
|
|
|
|
DREF_SUPERSPREAD_SOURCE_MASK));
|
|
|
|
WARN(!enabled, "PCH refclk assertion failure, should be active but is disabled\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void assert_transcoder_disabled(struct drm_i915_private *dev_priv,
|
|
|
|
enum pipe pipe)
|
|
|
|
{
|
|
|
|
int reg;
|
|
|
|
u32 val;
|
|
|
|
bool enabled;
|
|
|
|
|
|
|
|
reg = TRANSCONF(pipe);
|
|
|
|
val = I915_READ(reg);
|
|
|
|
enabled = !!(val & TRANS_ENABLE);
|
2011-02-07 20:26:52 +00:00
|
|
|
WARN(enabled,
|
|
|
|
"transcoder assertion failed, should be off on pipe %c but is still active\n",
|
|
|
|
pipe_name(pipe));
|
2011-01-04 23:09:34 +00:00
|
|
|
}
|
|
|
|
|
2011-08-06 17:39:45 +00:00
|
|
|
static bool dp_pipe_enabled(struct drm_i915_private *dev_priv,
|
|
|
|
enum pipe pipe, u32 port_sel, u32 val)
|
2011-07-26 05:12:43 +00:00
|
|
|
{
|
|
|
|
if ((val & DP_PORT_EN) == 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (HAS_PCH_CPT(dev_priv->dev)) {
|
|
|
|
u32 trans_dp_ctl_reg = TRANS_DP_CTL(pipe);
|
|
|
|
u32 trans_dp_ctl = I915_READ(trans_dp_ctl_reg);
|
|
|
|
if ((trans_dp_ctl & TRANS_DP_PORT_SEL_MASK) != port_sel)
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
if ((val & DP_PIPE_MASK) != (pipe << 30))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2011-08-06 17:35:34 +00:00
|
|
|
static bool hdmi_pipe_enabled(struct drm_i915_private *dev_priv,
|
|
|
|
enum pipe pipe, u32 val)
|
|
|
|
{
|
|
|
|
if ((val & PORT_ENABLE) == 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (HAS_PCH_CPT(dev_priv->dev)) {
|
|
|
|
if ((val & PORT_TRANS_SEL_MASK) != PORT_TRANS_SEL_CPT(pipe))
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
if ((val & TRANSCODER_MASK) != TRANSCODER(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->dev)) {
|
|
|
|
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->dev)) {
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2011-02-02 20:28:03 +00:00
|
|
|
static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv,
|
2011-07-26 05:12:43 +00:00
|
|
|
enum pipe pipe, int reg, u32 port_sel)
|
2011-02-02 20:28:03 +00:00
|
|
|
{
|
2011-02-07 21:46:40 +00:00
|
|
|
u32 val = I915_READ(reg);
|
2011-08-06 17:39:45 +00:00
|
|
|
WARN(dp_pipe_enabled(dev_priv, pipe, port_sel, val),
|
2011-02-02 20:28:03 +00:00
|
|
|
"PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n",
|
2011-02-07 20:26:52 +00:00
|
|
|
reg, pipe_name(pipe));
|
2012-06-05 09:03:40 +00:00
|
|
|
|
2012-09-10 19:58:29 +00:00
|
|
|
WARN(HAS_PCH_IBX(dev_priv->dev) && (val & DP_PORT_EN) == 0
|
|
|
|
&& (val & DP_PIPEB_SELECT),
|
2012-06-05 09:03:40 +00:00
|
|
|
"IBX PCH dp port still using transcoder B\n");
|
2011-02-02 20:28:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv,
|
|
|
|
enum pipe pipe, int reg)
|
|
|
|
{
|
2011-02-07 21:46:40 +00:00
|
|
|
u32 val = I915_READ(reg);
|
2012-08-13 03:08:33 +00:00
|
|
|
WARN(hdmi_pipe_enabled(dev_priv, pipe, val),
|
2011-10-07 18:38:43 +00:00
|
|
|
"PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n",
|
2011-02-07 20:26:52 +00:00
|
|
|
reg, pipe_name(pipe));
|
2012-06-05 09:03:40 +00:00
|
|
|
|
2012-09-10 19:58:29 +00:00
|
|
|
WARN(HAS_PCH_IBX(dev_priv->dev) && (val & PORT_ENABLE) == 0
|
|
|
|
&& (val & SDVO_PIPE_B_SELECT),
|
2012-06-05 09:03:40 +00:00
|
|
|
"IBX PCH hdmi port still using transcoder B\n");
|
2011-02-02 20:28:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
|
|
|
|
enum pipe pipe)
|
|
|
|
{
|
|
|
|
int reg;
|
|
|
|
u32 val;
|
|
|
|
|
2011-07-26 05:12:43 +00:00
|
|
|
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);
|
2011-02-02 20:28:03 +00:00
|
|
|
|
|
|
|
reg = PCH_ADPA;
|
|
|
|
val = I915_READ(reg);
|
2012-08-13 03:08:33 +00:00
|
|
|
WARN(adpa_pipe_enabled(dev_priv, pipe, val),
|
2011-02-02 20:28:03 +00:00
|
|
|
"PCH VGA enabled on transcoder %c, should be disabled\n",
|
2011-02-07 20:26:52 +00:00
|
|
|
pipe_name(pipe));
|
2011-02-02 20:28:03 +00:00
|
|
|
|
|
|
|
reg = PCH_LVDS;
|
|
|
|
val = I915_READ(reg);
|
2012-08-13 03:08:33 +00:00
|
|
|
WARN(lvds_pipe_enabled(dev_priv, pipe, val),
|
2011-02-02 20:28:03 +00:00
|
|
|
"PCH LVDS enabled on transcoder %c, should be disabled\n",
|
2011-02-07 20:26:52 +00:00
|
|
|
pipe_name(pipe));
|
2011-02-02 20:28:03 +00:00
|
|
|
|
|
|
|
assert_pch_hdmi_disabled(dev_priv, pipe, HDMIB);
|
|
|
|
assert_pch_hdmi_disabled(dev_priv, pipe, HDMIC);
|
|
|
|
assert_pch_hdmi_disabled(dev_priv, pipe, HDMID);
|
|
|
|
}
|
|
|
|
|
2011-01-04 23:09:33 +00:00
|
|
|
/**
|
|
|
|
* intel_enable_pll - enable a PLL
|
|
|
|
* @dev_priv: i915 private structure
|
|
|
|
* @pipe: pipe PLL to enable
|
|
|
|
*
|
|
|
|
* Enable @pipe's PLL so we can start pumping pixels from a plane. Check to
|
|
|
|
* make sure the PLL reg is writable first though, since the panel write
|
|
|
|
* protect mechanism may be enabled.
|
|
|
|
*
|
|
|
|
* Note! This is for pre-ILK only.
|
2012-07-18 17:22:30 +00:00
|
|
|
*
|
|
|
|
* Unfortunately needed by dvo_ns2501 since the dvo depends on it running.
|
2011-01-04 23:09:33 +00:00
|
|
|
*/
|
2012-08-12 17:27:09 +00:00
|
|
|
static void intel_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
|
2011-01-04 23:09:33 +00:00
|
|
|
{
|
|
|
|
int reg;
|
|
|
|
u32 val;
|
|
|
|
|
|
|
|
/* No really, not for ILK+ */
|
2012-06-15 18:55:13 +00:00
|
|
|
BUG_ON(!IS_VALLEYVIEW(dev_priv->dev) && dev_priv->info->gen >= 5);
|
2011-01-04 23:09:33 +00:00
|
|
|
|
|
|
|
/* PLL is protected by panel, make sure we can write it */
|
|
|
|
if (IS_MOBILE(dev_priv->dev) && !IS_I830(dev_priv->dev))
|
|
|
|
assert_panel_unlocked(dev_priv, pipe);
|
|
|
|
|
|
|
|
reg = DPLL(pipe);
|
|
|
|
val = I915_READ(reg);
|
|
|
|
val |= DPLL_VCO_ENABLE;
|
|
|
|
|
|
|
|
/* We do this three times for luck */
|
|
|
|
I915_WRITE(reg, val);
|
|
|
|
POSTING_READ(reg);
|
|
|
|
udelay(150); /* wait for warmup */
|
|
|
|
I915_WRITE(reg, val);
|
|
|
|
POSTING_READ(reg);
|
|
|
|
udelay(150); /* wait for warmup */
|
|
|
|
I915_WRITE(reg, val);
|
|
|
|
POSTING_READ(reg);
|
|
|
|
udelay(150); /* wait for warmup */
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* intel_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 intel_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
|
|
|
|
{
|
|
|
|
int reg;
|
|
|
|
u32 val;
|
|
|
|
|
|
|
|
/* Don't disable pipe A or pipe A PLLs if needed */
|
|
|
|
if (pipe == PIPE_A && (dev_priv->quirks & QUIRK_PIPEA_FORCE))
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Make sure the pipe isn't still relying on us */
|
|
|
|
assert_pipe_disabled(dev_priv, pipe);
|
|
|
|
|
|
|
|
reg = DPLL(pipe);
|
|
|
|
val = I915_READ(reg);
|
|
|
|
val &= ~DPLL_VCO_ENABLE;
|
|
|
|
I915_WRITE(reg, val);
|
|
|
|
POSTING_READ(reg);
|
|
|
|
}
|
|
|
|
|
2012-05-09 18:37:10 +00:00
|
|
|
/* SBI access */
|
|
|
|
static void
|
|
|
|
intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value)
|
|
|
|
{
|
|
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
spin_lock_irqsave(&dev_priv->dpio_lock, flags);
|
2012-06-08 19:43:19 +00:00
|
|
|
if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0,
|
2012-05-09 18:37:10 +00:00
|
|
|
100)) {
|
|
|
|
DRM_ERROR("timeout waiting for SBI to become ready\n");
|
|
|
|
goto out_unlock;
|
|
|
|
}
|
|
|
|
|
|
|
|
I915_WRITE(SBI_ADDR,
|
|
|
|
(reg << 16));
|
|
|
|
I915_WRITE(SBI_DATA,
|
|
|
|
value);
|
|
|
|
I915_WRITE(SBI_CTL_STAT,
|
|
|
|
SBI_BUSY |
|
|
|
|
SBI_CTL_OP_CRWR);
|
|
|
|
|
2012-06-08 19:43:19 +00:00
|
|
|
if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
|
2012-05-09 18:37:10 +00:00
|
|
|
100)) {
|
|
|
|
DRM_ERROR("timeout waiting for SBI to complete write transaction\n");
|
|
|
|
goto out_unlock;
|
|
|
|
}
|
|
|
|
|
|
|
|
out_unlock:
|
|
|
|
spin_unlock_irqrestore(&dev_priv->dpio_lock, flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
static u32
|
|
|
|
intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg)
|
|
|
|
{
|
|
|
|
unsigned long flags;
|
2012-06-08 19:43:19 +00:00
|
|
|
u32 value = 0;
|
2012-05-09 18:37:10 +00:00
|
|
|
|
|
|
|
spin_lock_irqsave(&dev_priv->dpio_lock, flags);
|
2012-06-08 19:43:19 +00:00
|
|
|
if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0,
|
2012-05-09 18:37:10 +00:00
|
|
|
100)) {
|
|
|
|
DRM_ERROR("timeout waiting for SBI to become ready\n");
|
|
|
|
goto out_unlock;
|
|
|
|
}
|
|
|
|
|
|
|
|
I915_WRITE(SBI_ADDR,
|
|
|
|
(reg << 16));
|
|
|
|
I915_WRITE(SBI_CTL_STAT,
|
|
|
|
SBI_BUSY |
|
|
|
|
SBI_CTL_OP_CRRD);
|
|
|
|
|
2012-06-08 19:43:19 +00:00
|
|
|
if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
|
2012-05-09 18:37:10 +00:00
|
|
|
100)) {
|
|
|
|
DRM_ERROR("timeout waiting for SBI to complete read transaction\n");
|
|
|
|
goto out_unlock;
|
|
|
|
}
|
|
|
|
|
|
|
|
value = I915_READ(SBI_DATA);
|
|
|
|
|
|
|
|
out_unlock:
|
|
|
|
spin_unlock_irqrestore(&dev_priv->dpio_lock, flags);
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2011-01-04 23:09:34 +00:00
|
|
|
/**
|
|
|
|
* intel_enable_pch_pll - enable PCH PLL
|
|
|
|
* @dev_priv: i915 private structure
|
|
|
|
* @pipe: pipe PLL to enable
|
|
|
|
*
|
|
|
|
* The PCH PLL needs to be enabled before the PCH transcoder, since it
|
|
|
|
* drives the transcoder clock.
|
|
|
|
*/
|
2012-04-20 16:11:53 +00:00
|
|
|
static void intel_enable_pch_pll(struct intel_crtc *intel_crtc)
|
2011-01-04 23:09:34 +00:00
|
|
|
{
|
2012-04-20 16:11:53 +00:00
|
|
|
struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
|
2012-05-13 19:16:12 +00:00
|
|
|
struct intel_pch_pll *pll;
|
2011-01-04 23:09:34 +00:00
|
|
|
int reg;
|
|
|
|
u32 val;
|
|
|
|
|
2012-05-13 19:16:12 +00:00
|
|
|
/* PCH PLLs only available on ILK, SNB and IVB */
|
2011-01-04 23:09:34 +00:00
|
|
|
BUG_ON(dev_priv->info->gen < 5);
|
2012-05-13 19:16:12 +00:00
|
|
|
pll = intel_crtc->pch_pll;
|
|
|
|
if (pll == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (WARN_ON(pll->refcount == 0))
|
|
|
|
return;
|
2012-04-20 16:11:53 +00:00
|
|
|
|
|
|
|
DRM_DEBUG_KMS("enable PCH PLL %x (active %d, on? %d)for crtc %d\n",
|
|
|
|
pll->pll_reg, pll->active, pll->on,
|
|
|
|
intel_crtc->base.base.id);
|
2011-01-04 23:09:34 +00:00
|
|
|
|
|
|
|
/* PCH refclock must be enabled first */
|
|
|
|
assert_pch_refclk_enabled(dev_priv);
|
|
|
|
|
2012-04-20 16:11:53 +00:00
|
|
|
if (pll->active++ && pll->on) {
|
2012-05-20 17:10:50 +00:00
|
|
|
assert_pch_pll_enabled(dev_priv, pll, NULL);
|
2012-04-20 16:11:53 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
DRM_DEBUG_KMS("enabling PCH PLL %x\n", pll->pll_reg);
|
|
|
|
|
|
|
|
reg = pll->pll_reg;
|
2011-01-04 23:09:34 +00:00
|
|
|
val = I915_READ(reg);
|
|
|
|
val |= DPLL_VCO_ENABLE;
|
|
|
|
I915_WRITE(reg, val);
|
|
|
|
POSTING_READ(reg);
|
|
|
|
udelay(200);
|
2012-04-20 16:11:53 +00:00
|
|
|
|
|
|
|
pll->on = true;
|
2011-01-04 23:09:34 +00:00
|
|
|
}
|
|
|
|
|
2012-04-20 16:11:53 +00:00
|
|
|
static void intel_disable_pch_pll(struct intel_crtc *intel_crtc)
|
2011-01-04 23:09:34 +00:00
|
|
|
{
|
2012-04-20 16:11:53 +00:00
|
|
|
struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
|
|
|
|
struct intel_pch_pll *pll = intel_crtc->pch_pll;
|
2011-01-04 23:09:34 +00:00
|
|
|
int reg;
|
2012-04-20 16:11:53 +00:00
|
|
|
u32 val;
|
2011-09-02 19:52:11 +00:00
|
|
|
|
2011-01-04 23:09:34 +00:00
|
|
|
/* PCH only available on ILK+ */
|
|
|
|
BUG_ON(dev_priv->info->gen < 5);
|
2012-04-20 16:11:53 +00:00
|
|
|
if (pll == NULL)
|
|
|
|
return;
|
2011-01-04 23:09:34 +00:00
|
|
|
|
2012-05-13 19:16:12 +00:00
|
|
|
if (WARN_ON(pll->refcount == 0))
|
|
|
|
return;
|
2011-11-15 18:28:53 +00:00
|
|
|
|
2012-04-20 16:11:53 +00:00
|
|
|
DRM_DEBUG_KMS("disable PCH PLL %x (active %d, on? %d) for crtc %d\n",
|
|
|
|
pll->pll_reg, pll->active, pll->on,
|
|
|
|
intel_crtc->base.base.id);
|
2011-11-15 18:28:53 +00:00
|
|
|
|
2012-05-13 19:16:12 +00:00
|
|
|
if (WARN_ON(pll->active == 0)) {
|
2012-05-20 17:10:50 +00:00
|
|
|
assert_pch_pll_disabled(dev_priv, pll, NULL);
|
2012-05-13 19:16:12 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-04-20 16:11:53 +00:00
|
|
|
if (--pll->active) {
|
2012-05-20 17:10:50 +00:00
|
|
|
assert_pch_pll_enabled(dev_priv, pll, NULL);
|
2011-11-15 18:28:53 +00:00
|
|
|
return;
|
2012-04-20 16:11:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DRM_DEBUG_KMS("disabling PCH PLL %x\n", pll->pll_reg);
|
|
|
|
|
|
|
|
/* Make sure transcoder isn't still depending on us */
|
|
|
|
assert_transcoder_disabled(dev_priv, intel_crtc->pipe);
|
2011-11-15 18:28:53 +00:00
|
|
|
|
2012-04-20 16:11:53 +00:00
|
|
|
reg = pll->pll_reg;
|
2011-01-04 23:09:34 +00:00
|
|
|
val = I915_READ(reg);
|
|
|
|
val &= ~DPLL_VCO_ENABLE;
|
|
|
|
I915_WRITE(reg, val);
|
|
|
|
POSTING_READ(reg);
|
|
|
|
udelay(200);
|
2012-04-20 16:11:53 +00:00
|
|
|
|
|
|
|
pll->on = false;
|
2011-01-04 23:09:34 +00:00
|
|
|
}
|
|
|
|
|
2011-01-03 20:14:26 +00:00
|
|
|
static void intel_enable_transcoder(struct drm_i915_private *dev_priv,
|
|
|
|
enum pipe pipe)
|
|
|
|
{
|
|
|
|
int reg;
|
2012-02-03 19:47:15 +00:00
|
|
|
u32 val, pipeconf_val;
|
2012-02-14 19:07:09 +00:00
|
|
|
struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
|
2011-01-03 20:14:26 +00:00
|
|
|
|
|
|
|
/* PCH only available on ILK+ */
|
|
|
|
BUG_ON(dev_priv->info->gen < 5);
|
|
|
|
|
|
|
|
/* Make sure PCH DPLL is enabled */
|
2012-05-20 17:10:50 +00:00
|
|
|
assert_pch_pll_enabled(dev_priv,
|
|
|
|
to_intel_crtc(crtc)->pch_pll,
|
|
|
|
to_intel_crtc(crtc));
|
2011-01-03 20:14:26 +00:00
|
|
|
|
|
|
|
/* FDI must be feeding us bits for PCH ports */
|
|
|
|
assert_fdi_tx_enabled(dev_priv, pipe);
|
|
|
|
assert_fdi_rx_enabled(dev_priv, pipe);
|
|
|
|
|
2012-05-09 18:37:19 +00:00
|
|
|
if (IS_HASWELL(dev_priv->dev) && pipe > 0) {
|
|
|
|
DRM_ERROR("Attempting to enable transcoder on Haswell with pipe > 0\n");
|
|
|
|
return;
|
|
|
|
}
|
2011-01-03 20:14:26 +00:00
|
|
|
reg = TRANSCONF(pipe);
|
|
|
|
val = I915_READ(reg);
|
2012-02-03 19:47:15 +00:00
|
|
|
pipeconf_val = I915_READ(PIPECONF(pipe));
|
2011-06-24 19:19:20 +00:00
|
|
|
|
|
|
|
if (HAS_PCH_IBX(dev_priv->dev)) {
|
|
|
|
/*
|
|
|
|
* make the BPC in transcoder be consistent with
|
|
|
|
* that in pipeconf reg.
|
|
|
|
*/
|
|
|
|
val &= ~PIPE_BPC_MASK;
|
2012-02-03 19:47:15 +00:00
|
|
|
val |= pipeconf_val & PIPE_BPC_MASK;
|
2011-06-24 19:19:20 +00:00
|
|
|
}
|
2012-02-03 19:47:15 +00:00
|
|
|
|
|
|
|
val &= ~TRANS_INTERLACE_MASK;
|
|
|
|
if ((pipeconf_val & PIPECONF_INTERLACE_MASK) == PIPECONF_INTERLACED_ILK)
|
2012-02-14 19:07:09 +00:00
|
|
|
if (HAS_PCH_IBX(dev_priv->dev) &&
|
|
|
|
intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO))
|
|
|
|
val |= TRANS_LEGACY_INTERLACED_ILK;
|
|
|
|
else
|
|
|
|
val |= TRANS_INTERLACED;
|
2012-02-03 19:47:15 +00:00
|
|
|
else
|
|
|
|
val |= TRANS_PROGRESSIVE;
|
|
|
|
|
2011-01-03 20:14:26 +00:00
|
|
|
I915_WRITE(reg, val | TRANS_ENABLE);
|
|
|
|
if (wait_for(I915_READ(reg) & TRANS_STATE_ENABLE, 100))
|
|
|
|
DRM_ERROR("failed to enable transcoder %d\n", pipe);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void intel_disable_transcoder(struct drm_i915_private *dev_priv,
|
|
|
|
enum pipe pipe)
|
|
|
|
{
|
|
|
|
int reg;
|
|
|
|
u32 val;
|
|
|
|
|
|
|
|
/* FDI relies on the transcoder */
|
|
|
|
assert_fdi_tx_disabled(dev_priv, pipe);
|
|
|
|
assert_fdi_rx_disabled(dev_priv, pipe);
|
|
|
|
|
2011-02-02 20:28:03 +00:00
|
|
|
/* Ports must be off as well */
|
|
|
|
assert_pch_ports_disabled(dev_priv, pipe);
|
|
|
|
|
2011-01-03 20:14:26 +00:00
|
|
|
reg = TRANSCONF(pipe);
|
|
|
|
val = I915_READ(reg);
|
|
|
|
val &= ~TRANS_ENABLE;
|
|
|
|
I915_WRITE(reg, val);
|
|
|
|
/* wait for PCH transcoder off, transcoder state */
|
|
|
|
if (wait_for((I915_READ(reg) & TRANS_STATE_ENABLE) == 0, 50))
|
2011-10-13 16:46:32 +00:00
|
|
|
DRM_ERROR("failed to disable transcoder %d\n", pipe);
|
2011-01-03 20:14:26 +00:00
|
|
|
}
|
|
|
|
|
2011-01-04 23:09:30 +00:00
|
|
|
/**
|
2011-01-28 13:54:53 +00:00
|
|
|
* intel_enable_pipe - enable a pipe, asserting requirements
|
2011-01-04 23:09:30 +00:00
|
|
|
* @dev_priv: i915 private structure
|
|
|
|
* @pipe: pipe to enable
|
2011-01-03 20:14:26 +00:00
|
|
|
* @pch_port: on ILK+, is this pipe driving a PCH port or not
|
2011-01-04 23:09:30 +00:00
|
|
|
*
|
|
|
|
* Enable @pipe, making sure that various hardware specific requirements
|
|
|
|
* are met, if applicable, e.g. PLL enabled, LVDS pairs enabled, etc.
|
|
|
|
*
|
|
|
|
* @pipe should be %PIPE_A or %PIPE_B.
|
|
|
|
*
|
|
|
|
* Will wait until the pipe is actually running (i.e. first vblank) before
|
|
|
|
* returning.
|
|
|
|
*/
|
2011-01-03 20:14:26 +00:00
|
|
|
static void intel_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe,
|
|
|
|
bool pch_port)
|
2011-01-04 23:09:30 +00:00
|
|
|
{
|
|
|
|
int reg;
|
|
|
|
u32 val;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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_PCH_SPLIT(dev_priv->dev))
|
|
|
|
assert_pll_enabled(dev_priv, pipe);
|
2011-01-03 20:14:26 +00:00
|
|
|
else {
|
|
|
|
if (pch_port) {
|
|
|
|
/* if driving the PCH, we need FDI enabled */
|
|
|
|
assert_fdi_rx_pll_enabled(dev_priv, pipe);
|
|
|
|
assert_fdi_tx_pll_enabled(dev_priv, pipe);
|
|
|
|
}
|
|
|
|
/* FIXME: assert CPU port conditions for SNB+ */
|
|
|
|
}
|
2011-01-04 23:09:30 +00:00
|
|
|
|
|
|
|
reg = PIPECONF(pipe);
|
|
|
|
val = I915_READ(reg);
|
2011-03-17 07:18:29 +00:00
|
|
|
if (val & PIPECONF_ENABLE)
|
|
|
|
return;
|
|
|
|
|
|
|
|
I915_WRITE(reg, val | PIPECONF_ENABLE);
|
2011-01-04 23:09:30 +00:00
|
|
|
intel_wait_for_vblank(dev_priv->dev, pipe);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2011-01-28 13:54:53 +00:00
|
|
|
* intel_disable_pipe - disable a pipe, asserting requirements
|
2011-01-04 23:09:30 +00:00
|
|
|
* @dev_priv: i915 private structure
|
|
|
|
* @pipe: pipe to disable
|
|
|
|
*
|
|
|
|
* Disable @pipe, making sure that various hardware specific requirements
|
|
|
|
* are met, if applicable, e.g. plane disabled, panel fitter off, etc.
|
|
|
|
*
|
|
|
|
* @pipe should be %PIPE_A or %PIPE_B.
|
|
|
|
*
|
|
|
|
* Will wait until the pipe has shut down before returning.
|
|
|
|
*/
|
|
|
|
static void intel_disable_pipe(struct drm_i915_private *dev_priv,
|
|
|
|
enum pipe pipe)
|
|
|
|
{
|
|
|
|
int reg;
|
|
|
|
u32 val;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Make sure planes won't keep trying to pump pixels to us,
|
|
|
|
* or we might hang the display.
|
|
|
|
*/
|
|
|
|
assert_planes_disabled(dev_priv, pipe);
|
|
|
|
|
|
|
|
/* Don't disable pipe A or pipe A PLLs if needed */
|
|
|
|
if (pipe == PIPE_A && (dev_priv->quirks & QUIRK_PIPEA_FORCE))
|
|
|
|
return;
|
|
|
|
|
|
|
|
reg = PIPECONF(pipe);
|
|
|
|
val = I915_READ(reg);
|
2011-03-17 07:18:29 +00:00
|
|
|
if ((val & PIPECONF_ENABLE) == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
I915_WRITE(reg, val & ~PIPECONF_ENABLE);
|
2011-01-04 23:09:30 +00:00
|
|
|
intel_wait_for_pipe_off(dev_priv->dev, pipe);
|
|
|
|
}
|
|
|
|
|
2011-07-28 21:47:14 +00:00
|
|
|
/*
|
|
|
|
* Plane regs are double buffered, going from enabled->disabled needs a
|
|
|
|
* trigger in order to latch. The display address reg provides this.
|
|
|
|
*/
|
2012-04-18 18:29:25 +00:00
|
|
|
void intel_flush_display_plane(struct drm_i915_private *dev_priv,
|
2011-07-28 21:47:14 +00:00
|
|
|
enum plane plane)
|
|
|
|
{
|
|
|
|
I915_WRITE(DSPADDR(plane), I915_READ(DSPADDR(plane)));
|
|
|
|
I915_WRITE(DSPSURF(plane), I915_READ(DSPSURF(plane)));
|
|
|
|
}
|
|
|
|
|
2011-01-04 23:09:30 +00:00
|
|
|
/**
|
|
|
|
* intel_enable_plane - enable a display plane on a given pipe
|
|
|
|
* @dev_priv: i915 private structure
|
|
|
|
* @plane: plane to enable
|
|
|
|
* @pipe: pipe being fed
|
|
|
|
*
|
|
|
|
* Enable @plane on @pipe, making sure that @pipe is running first.
|
|
|
|
*/
|
|
|
|
static void intel_enable_plane(struct drm_i915_private *dev_priv,
|
|
|
|
enum plane plane, enum pipe pipe)
|
|
|
|
{
|
|
|
|
int reg;
|
|
|
|
u32 val;
|
|
|
|
|
|
|
|
/* If the pipe isn't enabled, we can't pump pixels and may hang */
|
|
|
|
assert_pipe_enabled(dev_priv, pipe);
|
|
|
|
|
|
|
|
reg = DSPCNTR(plane);
|
|
|
|
val = I915_READ(reg);
|
2011-03-17 07:18:29 +00:00
|
|
|
if (val & DISPLAY_PLANE_ENABLE)
|
|
|
|
return;
|
|
|
|
|
|
|
|
I915_WRITE(reg, val | DISPLAY_PLANE_ENABLE);
|
2011-07-28 21:47:14 +00:00
|
|
|
intel_flush_display_plane(dev_priv, plane);
|
2011-01-04 23:09:30 +00:00
|
|
|
intel_wait_for_vblank(dev_priv->dev, pipe);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* intel_disable_plane - disable a display plane
|
|
|
|
* @dev_priv: i915 private structure
|
|
|
|
* @plane: plane to disable
|
|
|
|
* @pipe: pipe consuming the data
|
|
|
|
*
|
|
|
|
* Disable @plane; should be an independent operation.
|
|
|
|
*/
|
|
|
|
static void intel_disable_plane(struct drm_i915_private *dev_priv,
|
|
|
|
enum plane plane, enum pipe pipe)
|
|
|
|
{
|
|
|
|
int reg;
|
|
|
|
u32 val;
|
|
|
|
|
|
|
|
reg = DSPCNTR(plane);
|
|
|
|
val = I915_READ(reg);
|
2011-03-17 07:18:29 +00:00
|
|
|
if ((val & DISPLAY_PLANE_ENABLE) == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
I915_WRITE(reg, val & ~DISPLAY_PLANE_ENABLE);
|
2011-01-04 23:09:30 +00:00
|
|
|
intel_flush_display_plane(dev_priv, plane);
|
|
|
|
intel_wait_for_vblank(dev_priv->dev, pipe);
|
|
|
|
}
|
|
|
|
|
2010-07-23 22:32:05 +00:00
|
|
|
int
|
2010-09-14 11:50:34 +00:00
|
|
|
intel_pin_and_fence_fb_obj(struct drm_device *dev,
|
2010-11-08 19:18:58 +00:00
|
|
|
struct drm_i915_gem_object *obj,
|
2010-11-12 13:42:53 +00:00
|
|
|
struct intel_ring_buffer *pipelined)
|
2009-11-18 16:25:18 +00:00
|
|
|
{
|
2011-02-21 14:43:56 +00:00
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
2009-11-18 16:25:18 +00:00
|
|
|
u32 alignment;
|
|
|
|
int ret;
|
|
|
|
|
2010-11-08 19:18:58 +00:00
|
|
|
switch (obj->tiling_mode) {
|
2009-11-18 16:25:18 +00:00
|
|
|
case I915_TILING_NONE:
|
2010-07-05 17:01:46 +00:00
|
|
|
if (IS_BROADWATER(dev) || IS_CRESTLINE(dev))
|
|
|
|
alignment = 128 * 1024;
|
2010-09-16 23:32:17 +00:00
|
|
|
else if (INTEL_INFO(dev)->gen >= 4)
|
2010-07-05 17:01:46 +00:00
|
|
|
alignment = 4 * 1024;
|
|
|
|
else
|
|
|
|
alignment = 64 * 1024;
|
2009-11-18 16:25:18 +00:00
|
|
|
break;
|
|
|
|
case I915_TILING_X:
|
|
|
|
/* pin() will align the object as required by fence */
|
|
|
|
alignment = 0;
|
|
|
|
break;
|
|
|
|
case I915_TILING_Y:
|
|
|
|
/* FIXME: Is this true? */
|
|
|
|
DRM_ERROR("Y tiled not allowed for scan out buffers\n");
|
|
|
|
return -EINVAL;
|
|
|
|
default:
|
|
|
|
BUG();
|
|
|
|
}
|
|
|
|
|
2011-02-21 14:43:56 +00:00
|
|
|
dev_priv->mm.interruptible = false;
|
2011-04-14 08:41:17 +00:00
|
|
|
ret = i915_gem_object_pin_to_display_plane(obj, alignment, pipelined);
|
2010-09-14 11:50:34 +00:00
|
|
|
if (ret)
|
2011-02-21 14:43:56 +00:00
|
|
|
goto err_interruptible;
|
2009-11-18 16:25:18 +00:00
|
|
|
|
|
|
|
/* 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.
|
|
|
|
*/
|
2012-04-17 14:31:24 +00:00
|
|
|
ret = i915_gem_object_get_fence(obj);
|
2012-03-22 15:10:00 +00:00
|
|
|
if (ret)
|
|
|
|
goto err_unpin;
|
2011-12-14 12:57:08 +00:00
|
|
|
|
2012-03-22 15:10:00 +00:00
|
|
|
i915_gem_object_pin_fence(obj);
|
2009-11-18 16:25:18 +00:00
|
|
|
|
2011-02-21 14:43:56 +00:00
|
|
|
dev_priv->mm.interruptible = true;
|
2009-11-18 16:25:18 +00:00
|
|
|
return 0;
|
2010-09-14 11:50:34 +00:00
|
|
|
|
|
|
|
err_unpin:
|
|
|
|
i915_gem_object_unpin(obj);
|
2011-02-21 14:43:56 +00:00
|
|
|
err_interruptible:
|
|
|
|
dev_priv->mm.interruptible = true;
|
2010-09-14 11:50:34 +00:00
|
|
|
return ret;
|
2009-11-18 16:25:18 +00:00
|
|
|
}
|
|
|
|
|
2011-12-14 12:57:08 +00:00
|
|
|
void intel_unpin_fb_obj(struct drm_i915_gem_object *obj)
|
|
|
|
{
|
|
|
|
i915_gem_object_unpin_fence(obj);
|
|
|
|
i915_gem_object_unpin(obj);
|
|
|
|
}
|
|
|
|
|
2012-07-05 10:17:30 +00:00
|
|
|
/* Computes the linear offset to the base tile and adjusts x, y. bytes per pixel
|
|
|
|
* is assumed to be a power-of-two. */
|
|
|
|
static unsigned long gen4_compute_dspaddr_offset_xtiled(int *x, int *y,
|
|
|
|
unsigned int bpp,
|
|
|
|
unsigned int pitch)
|
|
|
|
{
|
|
|
|
int tile_rows, tiles;
|
|
|
|
|
|
|
|
tile_rows = *y / 8;
|
|
|
|
*y %= 8;
|
|
|
|
tiles = *x / (512/bpp);
|
|
|
|
*x %= 512/bpp;
|
|
|
|
|
|
|
|
return tile_rows * pitch * 8 + tiles * 4096;
|
|
|
|
}
|
|
|
|
|
2011-06-24 19:19:23 +00:00
|
|
|
static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
|
|
|
|
int x, int y)
|
2010-08-02 19:07:50 +00:00
|
|
|
{
|
|
|
|
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_framebuffer *intel_fb;
|
2010-11-08 19:18:58 +00:00
|
|
|
struct drm_i915_gem_object *obj;
|
2010-08-02 19:07:50 +00:00
|
|
|
int plane = intel_crtc->plane;
|
2012-07-05 10:17:29 +00:00
|
|
|
unsigned long linear_offset;
|
2010-08-02 19:07:50 +00:00
|
|
|
u32 dspcntr;
|
2010-09-11 12:48:45 +00:00
|
|
|
u32 reg;
|
2010-08-02 19:07:50 +00:00
|
|
|
|
|
|
|
switch (plane) {
|
|
|
|
case 0:
|
|
|
|
case 1:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
DRM_ERROR("Can't update plane %d in SAREA\n", plane);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
intel_fb = to_intel_framebuffer(fb);
|
|
|
|
obj = intel_fb->obj;
|
|
|
|
|
2010-09-11 12:48:45 +00:00
|
|
|
reg = DSPCNTR(plane);
|
|
|
|
dspcntr = I915_READ(reg);
|
2010-08-02 19:07:50 +00:00
|
|
|
/* Mask out pixel format bits in case we change it */
|
|
|
|
dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
|
|
|
|
switch (fb->bits_per_pixel) {
|
|
|
|
case 8:
|
|
|
|
dspcntr |= DISPPLANE_8BPP;
|
|
|
|
break;
|
|
|
|
case 16:
|
|
|
|
if (fb->depth == 15)
|
|
|
|
dspcntr |= DISPPLANE_15_16BPP;
|
|
|
|
else
|
|
|
|
dspcntr |= DISPPLANE_16BPP;
|
|
|
|
break;
|
|
|
|
case 24:
|
|
|
|
case 32:
|
|
|
|
dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
|
|
|
|
break;
|
|
|
|
default:
|
2011-06-24 19:19:23 +00:00
|
|
|
DRM_ERROR("Unknown color depth %d\n", fb->bits_per_pixel);
|
2010-08-02 19:07:50 +00:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
2010-09-16 23:32:17 +00:00
|
|
|
if (INTEL_INFO(dev)->gen >= 4) {
|
2010-11-08 19:18:58 +00:00
|
|
|
if (obj->tiling_mode != I915_TILING_NONE)
|
2010-08-02 19:07:50 +00:00
|
|
|
dspcntr |= DISPPLANE_TILED;
|
|
|
|
else
|
|
|
|
dspcntr &= ~DISPPLANE_TILED;
|
|
|
|
}
|
|
|
|
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(reg, dspcntr);
|
2010-08-02 19:07:50 +00:00
|
|
|
|
2012-07-05 10:17:29 +00:00
|
|
|
linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
|
2010-08-02 19:07:50 +00:00
|
|
|
|
2012-07-05 10:17:30 +00:00
|
|
|
if (INTEL_INFO(dev)->gen >= 4) {
|
|
|
|
intel_crtc->dspaddr_offset =
|
|
|
|
gen4_compute_dspaddr_offset_xtiled(&x, &y,
|
|
|
|
fb->bits_per_pixel / 8,
|
|
|
|
fb->pitches[0]);
|
|
|
|
linear_offset -= intel_crtc->dspaddr_offset;
|
|
|
|
} else {
|
2012-07-05 10:17:29 +00:00
|
|
|
intel_crtc->dspaddr_offset = linear_offset;
|
2012-07-05 10:17:30 +00:00
|
|
|
}
|
2012-07-05 10:17:29 +00:00
|
|
|
|
|
|
|
DRM_DEBUG_KMS("Writing base %08X %08lX %d %d %d\n",
|
|
|
|
obj->gtt_offset, linear_offset, x, y, fb->pitches[0]);
|
2011-12-19 22:06:49 +00:00
|
|
|
I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
|
2010-09-16 23:32:17 +00:00
|
|
|
if (INTEL_INFO(dev)->gen >= 4) {
|
2012-07-05 10:17:30 +00:00
|
|
|
I915_MODIFY_DISPBASE(DSPSURF(plane),
|
|
|
|
obj->gtt_offset + intel_crtc->dspaddr_offset);
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(DSPTILEOFF(plane), (y << 16) | x);
|
2012-07-05 10:17:29 +00:00
|
|
|
I915_WRITE(DSPLINOFF(plane), linear_offset);
|
2010-09-11 12:48:45 +00:00
|
|
|
} else
|
2012-07-05 10:17:29 +00:00
|
|
|
I915_WRITE(DSPADDR(plane), obj->gtt_offset + linear_offset);
|
2010-09-11 12:48:45 +00:00
|
|
|
POSTING_READ(reg);
|
2010-08-02 19:07:50 +00:00
|
|
|
|
2011-06-24 19:19:23 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ironlake_update_plane(struct drm_crtc *crtc,
|
|
|
|
struct drm_framebuffer *fb, int x, int y)
|
|
|
|
{
|
|
|
|
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_framebuffer *intel_fb;
|
|
|
|
struct drm_i915_gem_object *obj;
|
|
|
|
int plane = intel_crtc->plane;
|
2012-07-05 10:17:29 +00:00
|
|
|
unsigned long linear_offset;
|
2011-06-24 19:19:23 +00:00
|
|
|
u32 dspcntr;
|
|
|
|
u32 reg;
|
|
|
|
|
|
|
|
switch (plane) {
|
|
|
|
case 0:
|
|
|
|
case 1:
|
2011-09-02 19:54:37 +00:00
|
|
|
case 2:
|
2011-06-24 19:19:23 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
DRM_ERROR("Can't update plane %d in SAREA\n", plane);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
intel_fb = to_intel_framebuffer(fb);
|
|
|
|
obj = intel_fb->obj;
|
|
|
|
|
|
|
|
reg = DSPCNTR(plane);
|
|
|
|
dspcntr = I915_READ(reg);
|
|
|
|
/* Mask out pixel format bits in case we change it */
|
|
|
|
dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
|
|
|
|
switch (fb->bits_per_pixel) {
|
|
|
|
case 8:
|
|
|
|
dspcntr |= DISPPLANE_8BPP;
|
|
|
|
break;
|
|
|
|
case 16:
|
|
|
|
if (fb->depth != 16)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
dspcntr |= DISPPLANE_16BPP;
|
|
|
|
break;
|
|
|
|
case 24:
|
|
|
|
case 32:
|
|
|
|
if (fb->depth == 24)
|
|
|
|
dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
|
|
|
|
else if (fb->depth == 30)
|
|
|
|
dspcntr |= DISPPLANE_32BPP_30BIT_NO_ALPHA;
|
|
|
|
else
|
|
|
|
return -EINVAL;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
DRM_ERROR("Unknown color depth %d\n", fb->bits_per_pixel);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (obj->tiling_mode != I915_TILING_NONE)
|
|
|
|
dspcntr |= DISPPLANE_TILED;
|
|
|
|
else
|
|
|
|
dspcntr &= ~DISPPLANE_TILED;
|
|
|
|
|
|
|
|
/* must disable */
|
|
|
|
dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
|
|
|
|
|
|
|
|
I915_WRITE(reg, dspcntr);
|
|
|
|
|
2012-07-05 10:17:29 +00:00
|
|
|
linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
|
2012-07-05 10:17:30 +00:00
|
|
|
intel_crtc->dspaddr_offset =
|
|
|
|
gen4_compute_dspaddr_offset_xtiled(&x, &y,
|
|
|
|
fb->bits_per_pixel / 8,
|
|
|
|
fb->pitches[0]);
|
|
|
|
linear_offset -= intel_crtc->dspaddr_offset;
|
2011-06-24 19:19:23 +00:00
|
|
|
|
2012-07-05 10:17:29 +00:00
|
|
|
DRM_DEBUG_KMS("Writing base %08X %08lX %d %d %d\n",
|
|
|
|
obj->gtt_offset, linear_offset, x, y, fb->pitches[0]);
|
2011-12-19 22:06:49 +00:00
|
|
|
I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
|
2012-07-05 10:17:30 +00:00
|
|
|
I915_MODIFY_DISPBASE(DSPSURF(plane),
|
|
|
|
obj->gtt_offset + intel_crtc->dspaddr_offset);
|
2011-06-24 19:19:23 +00:00
|
|
|
I915_WRITE(DSPTILEOFF(plane), (y << 16) | x);
|
2012-07-05 10:17:29 +00:00
|
|
|
I915_WRITE(DSPLINOFF(plane), linear_offset);
|
2011-06-24 19:19:23 +00:00
|
|
|
POSTING_READ(reg);
|
|
|
|
|
|
|
|
return 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)
|
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
|
2012-04-17 14:08:19 +00:00
|
|
|
if (dev_priv->display.disable_fbc)
|
|
|
|
dev_priv->display.disable_fbc(dev);
|
2010-08-20 19:40:52 +00:00
|
|
|
intel_increase_pllclock(crtc);
|
2010-08-02 19:07:50 +00:00
|
|
|
|
2012-04-17 14:08:19 +00:00
|
|
|
return dev_priv->display.update_plane(crtc, fb, x, y);
|
2010-08-02 19:07:50 +00:00
|
|
|
}
|
|
|
|
|
2012-04-03 16:58:35 +00:00
|
|
|
static int
|
|
|
|
intel_finish_fb(struct drm_framebuffer *old_fb)
|
|
|
|
{
|
|
|
|
struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj;
|
|
|
|
struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
|
|
|
|
bool was_interruptible = dev_priv->mm.interruptible;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
wait_event(dev_priv->pending_flip_queue,
|
|
|
|
atomic_read(&dev_priv->mm.wedged) ||
|
|
|
|
atomic_read(&obj->pending_flip) == 0);
|
|
|
|
|
|
|
|
/* 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.
|
|
|
|
*
|
|
|
|
* This should only fail upon a hung GPU, in which case we
|
|
|
|
* can safely continue.
|
|
|
|
*/
|
|
|
|
dev_priv->mm.interruptible = false;
|
|
|
|
ret = i915_gem_object_finish_gpu(obj);
|
|
|
|
dev_priv->mm.interruptible = was_interruptible;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-02-11 13:25:09 +00:00
|
|
|
static int
|
2008-12-18 03:14:46 +00:00
|
|
|
intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
|
drm/i915: push crtc->fb update into pipe_set_base
Passing in the old fb, having overwritten the current fb, leads to
some neatly convoluted code. It's much simpler if we defer the
crtc->fb update to the place that updates the hw, in pipe_set_base.
This way we also don't need to restore anything in case something
fails - we only update crtc->fb once things have succeeded.
The real reason for this change is that now we keep the old fb
assigned to crtc->fb, which allows us to finally move the crtc disable
case into the common low-level set_mode function in the next patch.
Also don't clobber crtc->x and crtc->y, we neatly pass these down the
callchain already. Unfortunately we can't do the same with crtc->mode,
because that one is being used in the mode_set callbacks.
v2: Don't restore the drm_crtc object any more on failed modesets,
since we've lose an fb reference otherwise. Also (and this is the
reason this has been found), this totally confused the modeset state
tracking, since it clobbers crtc->enabled. Issue reported by Paulo
Zanoni.
v3: Rip out the entire crtc saving into struct intel_set_config, not
just the restoring part.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-05 20:51:56 +00:00
|
|
|
struct drm_framebuffer *fb)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
2012-04-17 14:08:19 +00:00
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
struct drm_i915_master_private *master_priv;
|
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
drm/i915: push crtc->fb update into pipe_set_base
Passing in the old fb, having overwritten the current fb, leads to
some neatly convoluted code. It's much simpler if we defer the
crtc->fb update to the place that updates the hw, in pipe_set_base.
This way we also don't need to restore anything in case something
fails - we only update crtc->fb once things have succeeded.
The real reason for this change is that now we keep the old fb
assigned to crtc->fb, which allows us to finally move the crtc disable
case into the common low-level set_mode function in the next patch.
Also don't clobber crtc->x and crtc->y, we neatly pass these down the
callchain already. Unfortunately we can't do the same with crtc->mode,
because that one is being used in the mode_set callbacks.
v2: Don't restore the drm_crtc object any more on failed modesets,
since we've lose an fb reference otherwise. Also (and this is the
reason this has been found), this totally confused the modeset state
tracking, since it clobbers crtc->enabled. Issue reported by Paulo
Zanoni.
v3: Rip out the entire crtc saving into struct intel_set_config, not
just the restoring part.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-05 20:51:56 +00:00
|
|
|
struct drm_framebuffer *old_fb;
|
2009-02-11 13:25:09 +00:00
|
|
|
int ret;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
|
|
|
/* no fb bound */
|
drm/i915: push crtc->fb update into pipe_set_base
Passing in the old fb, having overwritten the current fb, leads to
some neatly convoluted code. It's much simpler if we defer the
crtc->fb update to the place that updates the hw, in pipe_set_base.
This way we also don't need to restore anything in case something
fails - we only update crtc->fb once things have succeeded.
The real reason for this change is that now we keep the old fb
assigned to crtc->fb, which allows us to finally move the crtc disable
case into the common low-level set_mode function in the next patch.
Also don't clobber crtc->x and crtc->y, we neatly pass these down the
callchain already. Unfortunately we can't do the same with crtc->mode,
because that one is being used in the mode_set callbacks.
v2: Don't restore the drm_crtc object any more on failed modesets,
since we've lose an fb reference otherwise. Also (and this is the
reason this has been found), this totally confused the modeset state
tracking, since it clobbers crtc->enabled. Issue reported by Paulo
Zanoni.
v3: Rip out the entire crtc saving into struct intel_set_config, not
just the restoring part.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-05 20:51:56 +00:00
|
|
|
if (!fb) {
|
2011-07-19 22:38:56 +00:00
|
|
|
DRM_ERROR("No FB bound\n");
|
2009-02-11 13:25:09 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-05-09 18:37:12 +00:00
|
|
|
if(intel_crtc->plane > dev_priv->num_pipe) {
|
|
|
|
DRM_ERROR("no plane for crtc: plane %d, num_pipes %d\n",
|
|
|
|
intel_crtc->plane,
|
|
|
|
dev_priv->num_pipe);
|
2009-02-11 13:25:09 +00:00
|
|
|
return -EINVAL;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
2009-02-11 13:25:09 +00:00
|
|
|
mutex_lock(&dev->struct_mutex);
|
2010-09-20 14:41:01 +00:00
|
|
|
ret = intel_pin_and_fence_fb_obj(dev,
|
drm/i915: push crtc->fb update into pipe_set_base
Passing in the old fb, having overwritten the current fb, leads to
some neatly convoluted code. It's much simpler if we defer the
crtc->fb update to the place that updates the hw, in pipe_set_base.
This way we also don't need to restore anything in case something
fails - we only update crtc->fb once things have succeeded.
The real reason for this change is that now we keep the old fb
assigned to crtc->fb, which allows us to finally move the crtc disable
case into the common low-level set_mode function in the next patch.
Also don't clobber crtc->x and crtc->y, we neatly pass these down the
callchain already. Unfortunately we can't do the same with crtc->mode,
because that one is being used in the mode_set callbacks.
v2: Don't restore the drm_crtc object any more on failed modesets,
since we've lose an fb reference otherwise. Also (and this is the
reason this has been found), this totally confused the modeset state
tracking, since it clobbers crtc->enabled. Issue reported by Paulo
Zanoni.
v3: Rip out the entire crtc saving into struct intel_set_config, not
just the restoring part.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-05 20:51:56 +00:00
|
|
|
to_intel_framebuffer(fb)->obj,
|
2010-11-12 13:42:53 +00:00
|
|
|
NULL);
|
2009-02-11 13:25:09 +00:00
|
|
|
if (ret != 0) {
|
|
|
|
mutex_unlock(&dev->struct_mutex);
|
2011-07-19 22:38:56 +00:00
|
|
|
DRM_ERROR("pin & fence failed\n");
|
2009-02-11 13:25:09 +00:00
|
|
|
return ret;
|
|
|
|
}
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
drm/i915: push crtc->fb update into pipe_set_base
Passing in the old fb, having overwritten the current fb, leads to
some neatly convoluted code. It's much simpler if we defer the
crtc->fb update to the place that updates the hw, in pipe_set_base.
This way we also don't need to restore anything in case something
fails - we only update crtc->fb once things have succeeded.
The real reason for this change is that now we keep the old fb
assigned to crtc->fb, which allows us to finally move the crtc disable
case into the common low-level set_mode function in the next patch.
Also don't clobber crtc->x and crtc->y, we neatly pass these down the
callchain already. Unfortunately we can't do the same with crtc->mode,
because that one is being used in the mode_set callbacks.
v2: Don't restore the drm_crtc object any more on failed modesets,
since we've lose an fb reference otherwise. Also (and this is the
reason this has been found), this totally confused the modeset state
tracking, since it clobbers crtc->enabled. Issue reported by Paulo
Zanoni.
v3: Rip out the entire crtc saving into struct intel_set_config, not
just the restoring part.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-05 20:51:56 +00:00
|
|
|
if (crtc->fb)
|
|
|
|
intel_finish_fb(crtc->fb);
|
2010-09-20 14:41:01 +00:00
|
|
|
|
drm/i915: push crtc->fb update into pipe_set_base
Passing in the old fb, having overwritten the current fb, leads to
some neatly convoluted code. It's much simpler if we defer the
crtc->fb update to the place that updates the hw, in pipe_set_base.
This way we also don't need to restore anything in case something
fails - we only update crtc->fb once things have succeeded.
The real reason for this change is that now we keep the old fb
assigned to crtc->fb, which allows us to finally move the crtc disable
case into the common low-level set_mode function in the next patch.
Also don't clobber crtc->x and crtc->y, we neatly pass these down the
callchain already. Unfortunately we can't do the same with crtc->mode,
because that one is being used in the mode_set callbacks.
v2: Don't restore the drm_crtc object any more on failed modesets,
since we've lose an fb reference otherwise. Also (and this is the
reason this has been found), this totally confused the modeset state
tracking, since it clobbers crtc->enabled. Issue reported by Paulo
Zanoni.
v3: Rip out the entire crtc saving into struct intel_set_config, not
just the restoring part.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-05 20:51:56 +00:00
|
|
|
ret = dev_priv->display.update_plane(crtc, fb, x, y);
|
2010-08-08 12:20:19 +00:00
|
|
|
if (ret) {
|
drm/i915: push crtc->fb update into pipe_set_base
Passing in the old fb, having overwritten the current fb, leads to
some neatly convoluted code. It's much simpler if we defer the
crtc->fb update to the place that updates the hw, in pipe_set_base.
This way we also don't need to restore anything in case something
fails - we only update crtc->fb once things have succeeded.
The real reason for this change is that now we keep the old fb
assigned to crtc->fb, which allows us to finally move the crtc disable
case into the common low-level set_mode function in the next patch.
Also don't clobber crtc->x and crtc->y, we neatly pass these down the
callchain already. Unfortunately we can't do the same with crtc->mode,
because that one is being used in the mode_set callbacks.
v2: Don't restore the drm_crtc object any more on failed modesets,
since we've lose an fb reference otherwise. Also (and this is the
reason this has been found), this totally confused the modeset state
tracking, since it clobbers crtc->enabled. Issue reported by Paulo
Zanoni.
v3: Rip out the entire crtc saving into struct intel_set_config, not
just the restoring part.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-05 20:51:56 +00:00
|
|
|
intel_unpin_fb_obj(to_intel_framebuffer(fb)->obj);
|
2009-02-11 13:25:09 +00:00
|
|
|
mutex_unlock(&dev->struct_mutex);
|
2011-07-19 22:38:56 +00:00
|
|
|
DRM_ERROR("failed to update base address\n");
|
2010-08-08 12:20:19 +00:00
|
|
|
return ret;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
2008-12-18 03:14:46 +00:00
|
|
|
|
drm/i915: push crtc->fb update into pipe_set_base
Passing in the old fb, having overwritten the current fb, leads to
some neatly convoluted code. It's much simpler if we defer the
crtc->fb update to the place that updates the hw, in pipe_set_base.
This way we also don't need to restore anything in case something
fails - we only update crtc->fb once things have succeeded.
The real reason for this change is that now we keep the old fb
assigned to crtc->fb, which allows us to finally move the crtc disable
case into the common low-level set_mode function in the next patch.
Also don't clobber crtc->x and crtc->y, we neatly pass these down the
callchain already. Unfortunately we can't do the same with crtc->mode,
because that one is being used in the mode_set callbacks.
v2: Don't restore the drm_crtc object any more on failed modesets,
since we've lose an fb reference otherwise. Also (and this is the
reason this has been found), this totally confused the modeset state
tracking, since it clobbers crtc->enabled. Issue reported by Paulo
Zanoni.
v3: Rip out the entire crtc saving into struct intel_set_config, not
just the restoring part.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-05 20:51:56 +00:00
|
|
|
old_fb = crtc->fb;
|
|
|
|
crtc->fb = fb;
|
2012-09-10 19:58:30 +00:00
|
|
|
crtc->x = x;
|
|
|
|
crtc->y = y;
|
drm/i915: push crtc->fb update into pipe_set_base
Passing in the old fb, having overwritten the current fb, leads to
some neatly convoluted code. It's much simpler if we defer the
crtc->fb update to the place that updates the hw, in pipe_set_base.
This way we also don't need to restore anything in case something
fails - we only update crtc->fb once things have succeeded.
The real reason for this change is that now we keep the old fb
assigned to crtc->fb, which allows us to finally move the crtc disable
case into the common low-level set_mode function in the next patch.
Also don't clobber crtc->x and crtc->y, we neatly pass these down the
callchain already. Unfortunately we can't do the same with crtc->mode,
because that one is being used in the mode_set callbacks.
v2: Don't restore the drm_crtc object any more on failed modesets,
since we've lose an fb reference otherwise. Also (and this is the
reason this has been found), this totally confused the modeset state
tracking, since it clobbers crtc->enabled. Issue reported by Paulo
Zanoni.
v3: Rip out the entire crtc saving into struct intel_set_config, not
just the restoring part.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-05 20:51:56 +00:00
|
|
|
|
2010-12-14 16:09:31 +00:00
|
|
|
if (old_fb) {
|
|
|
|
intel_wait_for_vblank(dev, intel_crtc->pipe);
|
2011-12-14 12:57:08 +00:00
|
|
|
intel_unpin_fb_obj(to_intel_framebuffer(old_fb)->obj);
|
2010-12-14 16:09:31 +00:00
|
|
|
}
|
2009-08-17 20:31:43 +00:00
|
|
|
|
2012-04-17 14:08:19 +00:00
|
|
|
intel_update_fbc(dev);
|
2009-02-11 13:25:09 +00:00
|
|
|
mutex_unlock(&dev->struct_mutex);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
|
|
|
if (!dev->primary->master)
|
2009-02-11 13:25:09 +00:00
|
|
|
return 0;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
|
|
|
master_priv = dev->primary->master->driver_priv;
|
|
|
|
if (!master_priv->sarea_priv)
|
2009-02-11 13:25:09 +00:00
|
|
|
return 0;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2010-09-20 14:41:01 +00:00
|
|
|
if (intel_crtc->pipe) {
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
master_priv->sarea_priv->pipeB_x = x;
|
|
|
|
master_priv->sarea_priv->pipeB_y = y;
|
2009-02-11 13:25:09 +00:00
|
|
|
} else {
|
|
|
|
master_priv->sarea_priv->pipeA_x = x;
|
|
|
|
master_priv->sarea_priv->pipeA_y = y;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
2009-02-11 13:25:09 +00:00
|
|
|
|
|
|
|
return 0;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
2010-09-11 12:48:45 +00:00
|
|
|
static void ironlake_set_pll_edp(struct drm_crtc *crtc, int clock)
|
2009-07-23 17:00:32 +00:00
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
u32 dpa_ctl;
|
|
|
|
|
2009-10-09 03:39:41 +00:00
|
|
|
DRM_DEBUG_KMS("eDP PLL enable for clock %d\n", clock);
|
2009-07-23 17:00:32 +00:00
|
|
|
dpa_ctl = I915_READ(DP_A);
|
|
|
|
dpa_ctl &= ~DP_PLL_FREQ_MASK;
|
|
|
|
|
|
|
|
if (clock < 200000) {
|
|
|
|
u32 temp;
|
|
|
|
dpa_ctl |= DP_PLL_FREQ_160MHZ;
|
|
|
|
/* workaround for 160Mhz:
|
|
|
|
1) program 0x4600c bits 15:0 = 0x8124
|
|
|
|
2) program 0x46010 bit 0 = 1
|
|
|
|
3) program 0x46034 bit 24 = 1
|
|
|
|
4) program 0x64000 bit 14 = 1
|
|
|
|
*/
|
|
|
|
temp = I915_READ(0x4600c);
|
|
|
|
temp &= 0xffff0000;
|
|
|
|
I915_WRITE(0x4600c, temp | 0x8124);
|
|
|
|
|
|
|
|
temp = I915_READ(0x46010);
|
|
|
|
I915_WRITE(0x46010, temp | 1);
|
|
|
|
|
|
|
|
temp = I915_READ(0x46034);
|
|
|
|
I915_WRITE(0x46034, temp | (1 << 24));
|
|
|
|
} else {
|
|
|
|
dpa_ctl |= DP_PLL_FREQ_270MHZ;
|
|
|
|
}
|
|
|
|
I915_WRITE(DP_A, dpa_ctl);
|
|
|
|
|
2010-09-11 12:48:45 +00:00
|
|
|
POSTING_READ(DP_A);
|
2009-07-23 17:00:32 +00:00
|
|
|
udelay(500);
|
|
|
|
}
|
|
|
|
|
2010-10-28 08:38:08 +00:00
|
|
|
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;
|
|
|
|
u32 reg, temp;
|
|
|
|
|
|
|
|
/* enable normal train */
|
|
|
|
reg = FDI_TX_CTL(pipe);
|
|
|
|
temp = I915_READ(reg);
|
2011-05-17 23:13:52 +00:00
|
|
|
if (IS_IVYBRIDGE(dev)) {
|
2011-04-28 22:09:55 +00:00
|
|
|
temp &= ~FDI_LINK_TRAIN_NONE_IVB;
|
|
|
|
temp |= FDI_LINK_TRAIN_NONE_IVB | FDI_TX_ENHANCE_FRAME_ENABLE;
|
2011-05-17 23:13:52 +00:00
|
|
|
} else {
|
|
|
|
temp &= ~FDI_LINK_TRAIN_NONE;
|
|
|
|
temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE;
|
2011-04-28 22:09:55 +00:00
|
|
|
}
|
2010-10-28 08:38:08 +00:00
|
|
|
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);
|
2011-04-28 22:09:55 +00:00
|
|
|
|
|
|
|
/* IVB wants error correction enabled */
|
|
|
|
if (IS_IVYBRIDGE(dev))
|
|
|
|
I915_WRITE(reg, I915_READ(reg) | FDI_FS_ERRC_ENABLE |
|
|
|
|
FDI_FE_ERRC_ENABLE);
|
2010-10-28 08:38:08 +00:00
|
|
|
}
|
|
|
|
|
2011-07-29 19:42:37 +00:00
|
|
|
static void cpt_phase_pointer_enable(struct drm_device *dev, int pipe)
|
|
|
|
{
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
u32 flags = I915_READ(SOUTH_CHICKEN1);
|
|
|
|
|
|
|
|
flags |= FDI_PHASE_SYNC_OVR(pipe);
|
|
|
|
I915_WRITE(SOUTH_CHICKEN1, flags); /* once to unlock... */
|
|
|
|
flags |= FDI_PHASE_SYNC_EN(pipe);
|
|
|
|
I915_WRITE(SOUTH_CHICKEN1, flags); /* then again to enable */
|
|
|
|
POSTING_READ(SOUTH_CHICKEN1);
|
|
|
|
}
|
|
|
|
|
2010-04-07 08:15:54 +00:00
|
|
|
/* 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;
|
2011-01-04 23:09:37 +00:00
|
|
|
int plane = intel_crtc->plane;
|
2010-09-11 12:48:45 +00:00
|
|
|
u32 reg, temp, tries;
|
2010-04-07 08:15:54 +00:00
|
|
|
|
2011-01-04 23:09:37 +00:00
|
|
|
/* FDI needs bits from pipe & plane first */
|
|
|
|
assert_pipe_enabled(dev_priv, pipe);
|
|
|
|
assert_plane_enabled(dev_priv, plane);
|
|
|
|
|
2010-06-25 19:32:14 +00:00
|
|
|
/* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
|
|
|
|
for train result */
|
2010-09-11 12:48:45 +00:00
|
|
|
reg = FDI_RX_IMR(pipe);
|
|
|
|
temp = I915_READ(reg);
|
2010-06-25 19:32:14 +00:00
|
|
|
temp &= ~FDI_RX_SYMBOL_LOCK;
|
|
|
|
temp &= ~FDI_RX_BIT_LOCK;
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(reg, temp);
|
|
|
|
I915_READ(reg);
|
2010-06-25 19:32:14 +00:00
|
|
|
udelay(150);
|
|
|
|
|
2010-04-07 08:15:54 +00:00
|
|
|
/* enable CPU FDI TX and PCH FDI RX */
|
2010-09-11 12:48:45 +00:00
|
|
|
reg = FDI_TX_CTL(pipe);
|
|
|
|
temp = I915_READ(reg);
|
2010-04-12 15:38:44 +00:00
|
|
|
temp &= ~(7 << 19);
|
|
|
|
temp |= (intel_crtc->fdi_lanes - 1) << 19;
|
2010-04-07 08:15:54 +00:00
|
|
|
temp &= ~FDI_LINK_TRAIN_NONE;
|
|
|
|
temp |= FDI_LINK_TRAIN_PATTERN_1;
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(reg, temp | FDI_TX_ENABLE);
|
2010-04-07 08:15:54 +00:00
|
|
|
|
2010-09-11 12:48:45 +00:00
|
|
|
reg = FDI_RX_CTL(pipe);
|
|
|
|
temp = I915_READ(reg);
|
2010-04-07 08:15:54 +00:00
|
|
|
temp &= ~FDI_LINK_TRAIN_NONE;
|
|
|
|
temp |= FDI_LINK_TRAIN_PATTERN_1;
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(reg, temp | FDI_RX_ENABLE);
|
|
|
|
|
|
|
|
POSTING_READ(reg);
|
2010-04-07 08:15:54 +00:00
|
|
|
udelay(150);
|
|
|
|
|
2010-10-07 23:01:15 +00:00
|
|
|
/* Ironlake workaround, enable clock pointer after FDI enable*/
|
2011-01-04 23:09:38 +00:00
|
|
|
if (HAS_PCH_IBX(dev)) {
|
|
|
|
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);
|
|
|
|
}
|
2010-10-07 23:01:15 +00:00
|
|
|
|
2010-09-11 12:48:45 +00:00
|
|
|
reg = FDI_RX_IIR(pipe);
|
2010-06-25 19:32:14 +00:00
|
|
|
for (tries = 0; tries < 5; tries++) {
|
2010-09-11 12:48:45 +00:00
|
|
|
temp = I915_READ(reg);
|
2010-04-07 08:15:54 +00:00
|
|
|
DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp);
|
|
|
|
|
|
|
|
if ((temp & FDI_RX_BIT_LOCK)) {
|
|
|
|
DRM_DEBUG_KMS("FDI train 1 done.\n");
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(reg, temp | FDI_RX_BIT_LOCK);
|
2010-04-07 08:15:54 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2010-06-25 19:32:14 +00:00
|
|
|
if (tries == 5)
|
2010-09-11 12:48:45 +00:00
|
|
|
DRM_ERROR("FDI train 1 fail!\n");
|
2010-04-07 08:15:54 +00:00
|
|
|
|
|
|
|
/* Train 2 */
|
2010-09-11 12:48:45 +00:00
|
|
|
reg = FDI_TX_CTL(pipe);
|
|
|
|
temp = I915_READ(reg);
|
2010-04-07 08:15:54 +00:00
|
|
|
temp &= ~FDI_LINK_TRAIN_NONE;
|
|
|
|
temp |= FDI_LINK_TRAIN_PATTERN_2;
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(reg, temp);
|
2010-04-07 08:15:54 +00:00
|
|
|
|
2010-09-11 12:48:45 +00:00
|
|
|
reg = FDI_RX_CTL(pipe);
|
|
|
|
temp = I915_READ(reg);
|
2010-04-07 08:15:54 +00:00
|
|
|
temp &= ~FDI_LINK_TRAIN_NONE;
|
|
|
|
temp |= FDI_LINK_TRAIN_PATTERN_2;
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(reg, temp);
|
2010-04-07 08:15:54 +00:00
|
|
|
|
2010-09-11 12:48:45 +00:00
|
|
|
POSTING_READ(reg);
|
|
|
|
udelay(150);
|
2010-04-07 08:15:54 +00:00
|
|
|
|
2010-09-11 12:48:45 +00:00
|
|
|
reg = FDI_RX_IIR(pipe);
|
2010-06-25 19:32:14 +00:00
|
|
|
for (tries = 0; tries < 5; tries++) {
|
2010-09-11 12:48:45 +00:00
|
|
|
temp = I915_READ(reg);
|
2010-04-07 08:15:54 +00:00
|
|
|
DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp);
|
|
|
|
|
|
|
|
if (temp & FDI_RX_SYMBOL_LOCK) {
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(reg, temp | FDI_RX_SYMBOL_LOCK);
|
2010-04-07 08:15:54 +00:00
|
|
|
DRM_DEBUG_KMS("FDI train 2 done.\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2010-06-25 19:32:14 +00:00
|
|
|
if (tries == 5)
|
2010-09-11 12:48:45 +00:00
|
|
|
DRM_ERROR("FDI train 2 fail!\n");
|
2010-04-07 08:15:54 +00:00
|
|
|
|
|
|
|
DRM_DEBUG_KMS("FDI train done\n");
|
2010-10-07 23:01:11 +00:00
|
|
|
|
2010-04-07 08:15:54 +00:00
|
|
|
}
|
|
|
|
|
2011-08-16 19:34:10 +00:00
|
|
|
static const int snb_b_fdi_train_param[] = {
|
2010-04-07 08:15:54 +00:00
|
|
|
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;
|
2012-03-02 17:53:39 +00:00
|
|
|
u32 reg, temp, i, retry;
|
2010-04-07 08:15:54 +00:00
|
|
|
|
2010-06-25 19:32:14 +00:00
|
|
|
/* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
|
|
|
|
for train result */
|
2010-09-11 12:48:45 +00:00
|
|
|
reg = FDI_RX_IMR(pipe);
|
|
|
|
temp = I915_READ(reg);
|
2010-06-25 19:32:14 +00:00
|
|
|
temp &= ~FDI_RX_SYMBOL_LOCK;
|
|
|
|
temp &= ~FDI_RX_BIT_LOCK;
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(reg, temp);
|
|
|
|
|
|
|
|
POSTING_READ(reg);
|
2010-06-25 19:32:14 +00:00
|
|
|
udelay(150);
|
|
|
|
|
2010-04-07 08:15:54 +00:00
|
|
|
/* enable CPU FDI TX and PCH FDI RX */
|
2010-09-11 12:48:45 +00:00
|
|
|
reg = FDI_TX_CTL(pipe);
|
|
|
|
temp = I915_READ(reg);
|
2010-04-12 15:38:44 +00:00
|
|
|
temp &= ~(7 << 19);
|
|
|
|
temp |= (intel_crtc->fdi_lanes - 1) << 19;
|
2010-04-07 08:15:54 +00:00
|
|
|
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;
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(reg, temp | FDI_TX_ENABLE);
|
2010-04-07 08:15:54 +00:00
|
|
|
|
2010-09-11 12:48:45 +00:00
|
|
|
reg = FDI_RX_CTL(pipe);
|
|
|
|
temp = I915_READ(reg);
|
2010-04-07 08:15:54 +00:00
|
|
|
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;
|
|
|
|
}
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(reg, temp | FDI_RX_ENABLE);
|
|
|
|
|
|
|
|
POSTING_READ(reg);
|
2010-04-07 08:15:54 +00:00
|
|
|
udelay(150);
|
|
|
|
|
2011-07-29 19:42:37 +00:00
|
|
|
if (HAS_PCH_CPT(dev))
|
|
|
|
cpt_phase_pointer_enable(dev, pipe);
|
|
|
|
|
2011-08-16 19:34:10 +00:00
|
|
|
for (i = 0; i < 4; i++) {
|
2010-09-11 12:48:45 +00:00
|
|
|
reg = FDI_TX_CTL(pipe);
|
|
|
|
temp = I915_READ(reg);
|
2010-04-07 08:15:54 +00:00
|
|
|
temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
|
|
|
|
temp |= snb_b_fdi_train_param[i];
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(reg, temp);
|
|
|
|
|
|
|
|
POSTING_READ(reg);
|
2010-04-07 08:15:54 +00:00
|
|
|
udelay(500);
|
|
|
|
|
2012-03-02 17:53:39 +00:00
|
|
|
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);
|
2010-04-07 08:15:54 +00:00
|
|
|
}
|
2012-03-02 17:53:39 +00:00
|
|
|
if (retry < 5)
|
|
|
|
break;
|
2010-04-07 08:15:54 +00:00
|
|
|
}
|
|
|
|
if (i == 4)
|
2010-09-11 12:48:45 +00:00
|
|
|
DRM_ERROR("FDI train 1 fail!\n");
|
2010-04-07 08:15:54 +00:00
|
|
|
|
|
|
|
/* Train 2 */
|
2010-09-11 12:48:45 +00:00
|
|
|
reg = FDI_TX_CTL(pipe);
|
|
|
|
temp = I915_READ(reg);
|
2010-04-07 08:15:54 +00:00
|
|
|
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;
|
|
|
|
}
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(reg, temp);
|
2010-04-07 08:15:54 +00:00
|
|
|
|
2010-09-11 12:48:45 +00:00
|
|
|
reg = FDI_RX_CTL(pipe);
|
|
|
|
temp = I915_READ(reg);
|
2010-04-07 08:15:54 +00:00
|
|
|
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;
|
|
|
|
}
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(reg, temp);
|
|
|
|
|
|
|
|
POSTING_READ(reg);
|
2010-04-07 08:15:54 +00:00
|
|
|
udelay(150);
|
|
|
|
|
2011-08-16 19:34:10 +00:00
|
|
|
for (i = 0; i < 4; i++) {
|
2010-09-11 12:48:45 +00:00
|
|
|
reg = FDI_TX_CTL(pipe);
|
|
|
|
temp = I915_READ(reg);
|
2010-04-07 08:15:54 +00:00
|
|
|
temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
|
|
|
|
temp |= snb_b_fdi_train_param[i];
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(reg, temp);
|
|
|
|
|
|
|
|
POSTING_READ(reg);
|
2010-04-07 08:15:54 +00:00
|
|
|
udelay(500);
|
|
|
|
|
2012-03-02 17:53:39 +00:00
|
|
|
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);
|
2010-04-07 08:15:54 +00:00
|
|
|
}
|
2012-03-02 17:53:39 +00:00
|
|
|
if (retry < 5)
|
|
|
|
break;
|
2010-04-07 08:15:54 +00:00
|
|
|
}
|
|
|
|
if (i == 4)
|
2010-09-11 12:48:45 +00:00
|
|
|
DRM_ERROR("FDI train 2 fail!\n");
|
2010-04-07 08:15:54 +00:00
|
|
|
|
|
|
|
DRM_DEBUG_KMS("FDI train done.\n");
|
|
|
|
}
|
|
|
|
|
2011-04-28 22:09:55 +00:00
|
|
|
/* 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;
|
|
|
|
u32 reg, temp, i;
|
|
|
|
|
|
|
|
/* 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 &= ~(7 << 19);
|
|
|
|
temp |= (intel_crtc->fdi_lanes - 1) << 19;
|
|
|
|
temp &= ~(FDI_LINK_TRAIN_AUTO | FDI_LINK_TRAIN_NONE_IVB);
|
|
|
|
temp |= FDI_LINK_TRAIN_PATTERN_1_IVB;
|
|
|
|
temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
|
|
|
|
temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B;
|
2011-10-10 21:28:52 +00:00
|
|
|
temp |= FDI_COMPOSITE_SYNC;
|
2011-04-28 22:09:55 +00:00
|
|
|
I915_WRITE(reg, temp | FDI_TX_ENABLE);
|
|
|
|
|
|
|
|
reg = FDI_RX_CTL(pipe);
|
|
|
|
temp = I915_READ(reg);
|
|
|
|
temp &= ~FDI_LINK_TRAIN_AUTO;
|
|
|
|
temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
|
|
|
|
temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
|
2011-10-10 21:28:52 +00:00
|
|
|
temp |= FDI_COMPOSITE_SYNC;
|
2011-04-28 22:09:55 +00:00
|
|
|
I915_WRITE(reg, temp | FDI_RX_ENABLE);
|
|
|
|
|
|
|
|
POSTING_READ(reg);
|
|
|
|
udelay(150);
|
|
|
|
|
2011-07-29 19:42:37 +00:00
|
|
|
if (HAS_PCH_CPT(dev))
|
|
|
|
cpt_phase_pointer_enable(dev, pipe);
|
|
|
|
|
2011-08-16 19:34:10 +00:00
|
|
|
for (i = 0; i < 4; i++) {
|
2011-04-28 22:09:55 +00:00
|
|
|
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);
|
|
|
|
|
|
|
|
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.\n");
|
|
|
|
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_IVB;
|
|
|
|
temp |= FDI_LINK_TRAIN_PATTERN_2_IVB;
|
|
|
|
temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
|
|
|
|
temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B;
|
|
|
|
I915_WRITE(reg, temp);
|
|
|
|
|
|
|
|
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(150);
|
|
|
|
|
2011-08-16 19:34:10 +00:00
|
|
|
for (i = 0; i < 4; i++) {
|
2011-04-28 22:09:55 +00:00
|
|
|
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);
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (i == 4)
|
|
|
|
DRM_ERROR("FDI train 2 fail!\n");
|
|
|
|
|
|
|
|
DRM_DEBUG_KMS("FDI train done.\n");
|
|
|
|
}
|
|
|
|
|
2012-08-12 17:27:14 +00:00
|
|
|
static void ironlake_fdi_pll_enable(struct intel_crtc *intel_crtc)
|
2009-06-05 07:38:42 +00:00
|
|
|
{
|
2012-08-12 17:27:14 +00:00
|
|
|
struct drm_device *dev = intel_crtc->base.dev;
|
2009-06-05 07:38:42 +00:00
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
int pipe = intel_crtc->pipe;
|
2010-09-11 12:48:45 +00:00
|
|
|
u32 reg, temp;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2010-09-10 18:27:03 +00:00
|
|
|
/* Write the TU size bits so error detection works */
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(FDI_RX_TUSIZE1(pipe),
|
|
|
|
I915_READ(PIPE_DATA_M1(pipe)) & TU_SIZE_MASK);
|
2010-09-10 18:27:03 +00:00
|
|
|
|
2010-09-10 17:57:18 +00:00
|
|
|
/* enable PCH FDI RX PLL, wait warmup plus DMI latency */
|
2010-09-11 12:48:45 +00:00
|
|
|
reg = FDI_RX_CTL(pipe);
|
|
|
|
temp = I915_READ(reg);
|
|
|
|
temp &= ~((0x7 << 19) | (0x7 << 16));
|
2010-09-10 17:57:18 +00:00
|
|
|
temp |= (intel_crtc->fdi_lanes - 1) << 19;
|
2010-09-11 12:48:45 +00:00
|
|
|
temp |= (I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK) << 11;
|
|
|
|
I915_WRITE(reg, temp | FDI_RX_PLL_ENABLE);
|
|
|
|
|
|
|
|
POSTING_READ(reg);
|
2010-09-10 17:57:18 +00:00
|
|
|
udelay(200);
|
|
|
|
|
|
|
|
/* Switch from Rawclk to PCDclk */
|
2010-09-11 12:48:45 +00:00
|
|
|
temp = I915_READ(reg);
|
|
|
|
I915_WRITE(reg, temp | FDI_PCDCLK);
|
|
|
|
|
|
|
|
POSTING_READ(reg);
|
2010-09-10 17:57:18 +00:00
|
|
|
udelay(200);
|
|
|
|
|
2012-05-09 18:37:18 +00:00
|
|
|
/* On Haswell, the PLL configuration for ports and pipes is handled
|
|
|
|
* separately, as part of DDI setup */
|
|
|
|
if (!IS_HASWELL(dev)) {
|
|
|
|
/* 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);
|
2010-09-11 12:48:45 +00:00
|
|
|
|
2012-05-09 18:37:18 +00:00
|
|
|
POSTING_READ(reg);
|
|
|
|
udelay(100);
|
|
|
|
}
|
2010-09-10 17:26:01 +00:00
|
|
|
}
|
2010-09-10 18:10:00 +00:00
|
|
|
}
|
|
|
|
|
2012-08-12 17:27:14 +00:00
|
|
|
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;
|
|
|
|
u32 reg, 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);
|
|
|
|
}
|
|
|
|
|
2011-07-29 19:42:37 +00:00
|
|
|
static void cpt_phase_pointer_disable(struct drm_device *dev, int pipe)
|
|
|
|
{
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
u32 flags = I915_READ(SOUTH_CHICKEN1);
|
|
|
|
|
|
|
|
flags &= ~(FDI_PHASE_SYNC_EN(pipe));
|
|
|
|
I915_WRITE(SOUTH_CHICKEN1, flags); /* once to disable... */
|
|
|
|
flags &= ~(FDI_PHASE_SYNC_OVR(pipe));
|
|
|
|
I915_WRITE(SOUTH_CHICKEN1, flags); /* then again to lock */
|
|
|
|
POSTING_READ(SOUTH_CHICKEN1);
|
|
|
|
}
|
2011-01-04 23:09:37 +00:00
|
|
|
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;
|
|
|
|
u32 reg, 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)) & PIPE_BPC_MASK) << 11;
|
|
|
|
I915_WRITE(reg, temp & ~FDI_RX_ENABLE);
|
|
|
|
|
|
|
|
POSTING_READ(reg);
|
|
|
|
udelay(100);
|
|
|
|
|
|
|
|
/* Ironlake workaround, disable clock pointer after downing FDI */
|
2011-01-04 23:09:38 +00:00
|
|
|
if (HAS_PCH_IBX(dev)) {
|
|
|
|
I915_WRITE(FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_OVR);
|
2011-01-04 23:09:37 +00:00
|
|
|
I915_WRITE(FDI_RX_CHICKEN(pipe),
|
|
|
|
I915_READ(FDI_RX_CHICKEN(pipe) &
|
2011-01-04 23:09:38 +00:00
|
|
|
~FDI_RX_PHASE_SYNC_POINTER_EN));
|
2011-07-29 19:42:37 +00:00
|
|
|
} else if (HAS_PCH_CPT(dev)) {
|
|
|
|
cpt_phase_pointer_disable(dev, pipe);
|
2011-01-04 23:09:38 +00:00
|
|
|
}
|
2011-01-04 23:09:37 +00:00
|
|
|
|
|
|
|
/* 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)) & PIPE_BPC_MASK) << 11;
|
|
|
|
I915_WRITE(reg, temp);
|
|
|
|
|
|
|
|
POSTING_READ(reg);
|
|
|
|
udelay(100);
|
|
|
|
}
|
|
|
|
|
2012-09-27 20:25:58 +00:00
|
|
|
static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
unsigned long flags;
|
|
|
|
bool pending;
|
|
|
|
|
|
|
|
if (atomic_read(&dev_priv->mm.wedged))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
spin_lock_irqsave(&dev->event_lock, flags);
|
|
|
|
pending = to_intel_crtc(crtc)->unpin_work != NULL;
|
|
|
|
spin_unlock_irqrestore(&dev->event_lock, flags);
|
|
|
|
|
|
|
|
return pending;
|
|
|
|
}
|
|
|
|
|
2010-09-23 22:04:43 +00:00
|
|
|
static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
|
|
|
|
{
|
2012-04-17 09:05:38 +00:00
|
|
|
struct drm_device *dev = crtc->dev;
|
2012-09-27 20:25:58 +00:00
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
2010-09-23 22:04:43 +00:00
|
|
|
|
|
|
|
if (crtc->fb == NULL)
|
|
|
|
return;
|
|
|
|
|
2012-09-27 20:25:58 +00:00
|
|
|
wait_event(dev_priv->pending_flip_queue,
|
|
|
|
!intel_crtc_has_pending_flip(crtc));
|
|
|
|
|
2012-04-17 09:05:38 +00:00
|
|
|
mutex_lock(&dev->struct_mutex);
|
|
|
|
intel_finish_fb(crtc->fb);
|
|
|
|
mutex_unlock(&dev->struct_mutex);
|
2010-09-23 22:04:43 +00:00
|
|
|
}
|
|
|
|
|
2011-01-03 20:14:26 +00:00
|
|
|
static bool intel_crtc_driving_pch(struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
2012-08-10 13:05:10 +00:00
|
|
|
struct intel_encoder *intel_encoder;
|
2011-01-03 20:14:26 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If there's a non-PCH eDP on this crtc, it must be DP_A, and that
|
|
|
|
* must be driven by its own crtc; no sharing is possible.
|
|
|
|
*/
|
2012-08-10 13:05:10 +00:00
|
|
|
for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
|
2011-01-03 20:14:26 +00:00
|
|
|
|
2012-05-09 23:30:31 +00:00
|
|
|
/* On Haswell, LPT PCH handles the VGA connection via FDI, and Haswell
|
|
|
|
* CPU handles all others */
|
|
|
|
if (IS_HASWELL(dev)) {
|
|
|
|
/* It is still unclear how this will work on PPT, so throw up a warning */
|
|
|
|
WARN_ON(!HAS_PCH_LPT(dev));
|
|
|
|
|
2012-08-10 13:05:10 +00:00
|
|
|
if (intel_encoder->type == INTEL_OUTPUT_ANALOG) {
|
2012-05-09 23:30:31 +00:00
|
|
|
DRM_DEBUG_KMS("Haswell detected DAC encoder, assuming is PCH\n");
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
DRM_DEBUG_KMS("Haswell detected encoder %d, assuming is CPU\n",
|
2012-08-10 13:05:10 +00:00
|
|
|
intel_encoder->type);
|
2012-05-09 23:30:31 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-10 13:05:10 +00:00
|
|
|
switch (intel_encoder->type) {
|
2011-01-03 20:14:26 +00:00
|
|
|
case INTEL_OUTPUT_EDP:
|
2012-08-10 13:05:10 +00:00
|
|
|
if (!intel_encoder_is_pch_edp(&intel_encoder->base))
|
2011-01-03 20:14:26 +00:00
|
|
|
return false;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-05-09 18:37:26 +00:00
|
|
|
/* Program iCLKIP clock to the desired frequency */
|
|
|
|
static void lpt_program_iclkip(struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
u32 divsel, phaseinc, auxdiv, phasedir = 0;
|
|
|
|
u32 temp;
|
|
|
|
|
|
|
|
/* It is necessary to ungate the pixclk gate prior to programming
|
|
|
|
* the divisors, and gate it back when it is done.
|
|
|
|
*/
|
|
|
|
I915_WRITE(PIXCLK_GATE, PIXCLK_GATE_GATE);
|
|
|
|
|
|
|
|
/* Disable SSCCTL */
|
|
|
|
intel_sbi_write(dev_priv, SBI_SSCCTL6,
|
|
|
|
intel_sbi_read(dev_priv, SBI_SSCCTL6) |
|
|
|
|
SBI_SSCCTL_DISABLE);
|
|
|
|
|
|
|
|
/* 20MHz is a corner case which is out of range for the 7-bit divisor */
|
|
|
|
if (crtc->mode.clock == 20000) {
|
|
|
|
auxdiv = 1;
|
|
|
|
divsel = 0x41;
|
|
|
|
phaseinc = 0x20;
|
|
|
|
} else {
|
|
|
|
/* The iCLK virtual clock root frequency is in MHz,
|
|
|
|
* but the crtc->mode.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.
|
|
|
|
*/
|
|
|
|
u32 iclk_virtual_root_freq = 172800 * 1000;
|
|
|
|
u32 iclk_pi_range = 64;
|
|
|
|
u32 desired_divisor, msb_divisor_value, pi_value;
|
|
|
|
|
|
|
|
desired_divisor = (iclk_virtual_root_freq / crtc->mode.clock);
|
|
|
|
msb_divisor_value = desired_divisor / iclk_pi_range;
|
|
|
|
pi_value = desired_divisor % iclk_pi_range;
|
|
|
|
|
|
|
|
auxdiv = 0;
|
|
|
|
divsel = msb_divisor_value - 2;
|
|
|
|
phaseinc = pi_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 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",
|
|
|
|
crtc->mode.clock,
|
|
|
|
auxdiv,
|
|
|
|
divsel,
|
|
|
|
phasedir,
|
|
|
|
phaseinc);
|
|
|
|
|
|
|
|
/* Program SSCDIVINTPHASE6 */
|
|
|
|
temp = intel_sbi_read(dev_priv, SBI_SSCDIVINTPHASE6);
|
|
|
|
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);
|
|
|
|
|
|
|
|
/* Program SSCAUXDIV */
|
|
|
|
temp = intel_sbi_read(dev_priv, SBI_SSCAUXDIV6);
|
|
|
|
temp &= ~SBI_SSCAUXDIV_FINALDIV2SEL(1);
|
|
|
|
temp |= SBI_SSCAUXDIV_FINALDIV2SEL(auxdiv);
|
|
|
|
intel_sbi_write(dev_priv,
|
|
|
|
SBI_SSCAUXDIV6,
|
|
|
|
temp);
|
|
|
|
|
|
|
|
|
|
|
|
/* Enable modulator and associated divider */
|
|
|
|
temp = intel_sbi_read(dev_priv, SBI_SSCCTL6);
|
|
|
|
temp &= ~SBI_SSCCTL_DISABLE;
|
|
|
|
intel_sbi_write(dev_priv,
|
|
|
|
SBI_SSCCTL6,
|
|
|
|
temp);
|
|
|
|
|
|
|
|
/* Wait for initialization time */
|
|
|
|
udelay(24);
|
|
|
|
|
|
|
|
I915_WRITE(PIXCLK_GATE, PIXCLK_GATE_UNGATE);
|
|
|
|
}
|
|
|
|
|
2011-01-05 18:31:48 +00:00
|
|
|
/*
|
|
|
|
* 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)
|
2010-09-10 18:10:00 +00:00
|
|
|
{
|
|
|
|
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;
|
2012-04-20 16:11:53 +00:00
|
|
|
u32 reg, temp;
|
2009-06-05 07:38:42 +00:00
|
|
|
|
2012-05-11 08:21:25 +00:00
|
|
|
assert_transcoder_disabled(dev_priv, pipe);
|
|
|
|
|
2010-09-10 17:57:18 +00:00
|
|
|
/* For PCH output, training FDI link */
|
2011-04-28 21:27:04 +00:00
|
|
|
dev_priv->display.fdi_link_train(crtc);
|
2009-06-05 07:38:42 +00:00
|
|
|
|
2012-05-13 08:54:09 +00:00
|
|
|
intel_enable_pch_pll(intel_crtc);
|
|
|
|
|
2012-05-09 18:37:26 +00:00
|
|
|
if (HAS_PCH_LPT(dev)) {
|
|
|
|
DRM_DEBUG_KMS("LPT detected: programming iCLKIP\n");
|
|
|
|
lpt_program_iclkip(crtc);
|
|
|
|
} else if (HAS_PCH_CPT(dev)) {
|
2012-04-20 16:11:53 +00:00
|
|
|
u32 sel;
|
2011-10-12 16:51:31 +00:00
|
|
|
|
2010-09-10 17:57:18 +00:00
|
|
|
temp = I915_READ(PCH_DPLL_SEL);
|
2012-04-20 16:11:53 +00:00
|
|
|
switch (pipe) {
|
|
|
|
default:
|
|
|
|
case 0:
|
|
|
|
temp |= TRANSA_DPLL_ENABLE;
|
|
|
|
sel = TRANSA_DPLLB_SEL;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
temp |= TRANSB_DPLL_ENABLE;
|
|
|
|
sel = TRANSB_DPLLB_SEL;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
temp |= TRANSC_DPLL_ENABLE;
|
|
|
|
sel = TRANSC_DPLLB_SEL;
|
|
|
|
break;
|
2011-10-12 22:01:33 +00:00
|
|
|
}
|
2012-04-20 16:11:53 +00:00
|
|
|
if (intel_crtc->pch_pll->pll_reg == _PCH_DPLL_B)
|
|
|
|
temp |= sel;
|
|
|
|
else
|
|
|
|
temp &= ~sel;
|
2010-09-10 17:57:18 +00:00
|
|
|
I915_WRITE(PCH_DPLL_SEL, temp);
|
|
|
|
}
|
2010-09-11 12:48:45 +00:00
|
|
|
|
2011-01-04 23:09:35 +00:00
|
|
|
/* set transcoder timing, panel must allow it */
|
|
|
|
assert_panel_unlocked(dev_priv, pipe);
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(TRANS_HTOTAL(pipe), I915_READ(HTOTAL(pipe)));
|
|
|
|
I915_WRITE(TRANS_HBLANK(pipe), I915_READ(HBLANK(pipe)));
|
|
|
|
I915_WRITE(TRANS_HSYNC(pipe), I915_READ(HSYNC(pipe)));
|
2010-04-07 08:15:54 +00:00
|
|
|
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(TRANS_VTOTAL(pipe), I915_READ(VTOTAL(pipe)));
|
|
|
|
I915_WRITE(TRANS_VBLANK(pipe), I915_READ(VBLANK(pipe)));
|
|
|
|
I915_WRITE(TRANS_VSYNC(pipe), I915_READ(VSYNC(pipe)));
|
2012-01-28 13:49:24 +00:00
|
|
|
I915_WRITE(TRANS_VSYNCSHIFT(pipe), I915_READ(VSYNCSHIFT(pipe)));
|
2010-04-07 08:15:54 +00:00
|
|
|
|
2012-05-09 18:37:14 +00:00
|
|
|
if (!IS_HASWELL(dev))
|
|
|
|
intel_fdi_normal_train(crtc);
|
2010-10-28 08:38:08 +00:00
|
|
|
|
2010-09-10 17:57:18 +00:00
|
|
|
/* For PCH DP, enable TRANS_DP_CTL */
|
|
|
|
if (HAS_PCH_CPT(dev) &&
|
2011-11-02 02:54:11 +00:00
|
|
|
(intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) ||
|
|
|
|
intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) {
|
2011-06-24 19:19:21 +00:00
|
|
|
u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK) >> 5;
|
2010-09-11 12:48:45 +00:00
|
|
|
reg = TRANS_DP_CTL(pipe);
|
|
|
|
temp = I915_READ(reg);
|
|
|
|
temp &= ~(TRANS_DP_PORT_SEL_MASK |
|
2010-11-18 01:32:58 +00:00
|
|
|
TRANS_DP_SYNC_MASK |
|
|
|
|
TRANS_DP_BPC_MASK);
|
2010-09-11 12:48:45 +00:00
|
|
|
temp |= (TRANS_DP_OUTPUT_ENABLE |
|
|
|
|
TRANS_DP_ENH_FRAMING);
|
2011-06-24 19:19:21 +00:00
|
|
|
temp |= bpc << 9; /* same format but at 11:9 */
|
2010-09-10 17:57:18 +00:00
|
|
|
|
|
|
|
if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC)
|
2010-09-11 12:48:45 +00:00
|
|
|
temp |= TRANS_DP_HSYNC_ACTIVE_HIGH;
|
2010-09-10 17:57:18 +00:00
|
|
|
if (crtc->mode.flags & DRM_MODE_FLAG_PVSYNC)
|
2010-09-11 12:48:45 +00:00
|
|
|
temp |= TRANS_DP_VSYNC_ACTIVE_HIGH;
|
2010-09-10 17:57:18 +00:00
|
|
|
|
|
|
|
switch (intel_trans_dp_port_sel(crtc)) {
|
|
|
|
case PCH_DP_B:
|
2010-09-11 12:48:45 +00:00
|
|
|
temp |= TRANS_DP_PORT_SEL_B;
|
2010-09-10 17:57:18 +00:00
|
|
|
break;
|
|
|
|
case PCH_DP_C:
|
2010-09-11 12:48:45 +00:00
|
|
|
temp |= TRANS_DP_PORT_SEL_C;
|
2010-09-10 17:57:18 +00:00
|
|
|
break;
|
|
|
|
case PCH_DP_D:
|
2010-09-11 12:48:45 +00:00
|
|
|
temp |= TRANS_DP_PORT_SEL_D;
|
2010-09-10 17:57:18 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
DRM_DEBUG_KMS("Wrong PCH DP port return. Guess port B\n");
|
2010-09-11 12:48:45 +00:00
|
|
|
temp |= TRANS_DP_PORT_SEL_B;
|
2010-09-10 17:57:18 +00:00
|
|
|
break;
|
2009-07-23 17:00:32 +00:00
|
|
|
}
|
2009-06-05 07:38:42 +00:00
|
|
|
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(reg, temp);
|
2010-09-10 17:26:01 +00:00
|
|
|
}
|
2010-06-12 06:32:27 +00:00
|
|
|
|
2011-01-03 20:14:26 +00:00
|
|
|
intel_enable_transcoder(dev_priv, pipe);
|
2011-01-05 18:31:48 +00:00
|
|
|
}
|
|
|
|
|
2012-04-20 16:11:53 +00:00
|
|
|
static void intel_put_pch_pll(struct intel_crtc *intel_crtc)
|
|
|
|
{
|
|
|
|
struct intel_pch_pll *pll = intel_crtc->pch_pll;
|
|
|
|
|
|
|
|
if (pll == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (pll->refcount == 0) {
|
|
|
|
WARN(1, "bad PCH PLL refcount\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
--pll->refcount;
|
|
|
|
intel_crtc->pch_pll = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct intel_pch_pll *intel_get_pch_pll(struct intel_crtc *intel_crtc, u32 dpll, u32 fp)
|
|
|
|
{
|
|
|
|
struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
|
|
|
|
struct intel_pch_pll *pll;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
pll = intel_crtc->pch_pll;
|
|
|
|
if (pll) {
|
|
|
|
DRM_DEBUG_KMS("CRTC:%d reusing existing PCH PLL %x\n",
|
|
|
|
intel_crtc->base.base.id, pll->pll_reg);
|
|
|
|
goto prepare;
|
|
|
|
}
|
|
|
|
|
2012-05-20 18:00:25 +00:00
|
|
|
if (HAS_PCH_IBX(dev_priv->dev)) {
|
|
|
|
/* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
|
|
|
|
i = intel_crtc->pipe;
|
|
|
|
pll = &dev_priv->pch_plls[i];
|
|
|
|
|
|
|
|
DRM_DEBUG_KMS("CRTC:%d using pre-allocated PCH PLL %x\n",
|
|
|
|
intel_crtc->base.base.id, pll->pll_reg);
|
|
|
|
|
|
|
|
goto found;
|
|
|
|
}
|
|
|
|
|
2012-04-20 16:11:53 +00:00
|
|
|
for (i = 0; i < dev_priv->num_pch_pll; i++) {
|
|
|
|
pll = &dev_priv->pch_plls[i];
|
|
|
|
|
|
|
|
/* Only want to check enabled timings first */
|
|
|
|
if (pll->refcount == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (dpll == (I915_READ(pll->pll_reg) & 0x7fffffff) &&
|
|
|
|
fp == I915_READ(pll->fp0_reg)) {
|
|
|
|
DRM_DEBUG_KMS("CRTC:%d sharing existing PCH PLL %x (refcount %d, ative %d)\n",
|
|
|
|
intel_crtc->base.base.id,
|
|
|
|
pll->pll_reg, pll->refcount, pll->active);
|
|
|
|
|
|
|
|
goto found;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Ok no matching timings, maybe there's a free one? */
|
|
|
|
for (i = 0; i < dev_priv->num_pch_pll; i++) {
|
|
|
|
pll = &dev_priv->pch_plls[i];
|
|
|
|
if (pll->refcount == 0) {
|
|
|
|
DRM_DEBUG_KMS("CRTC:%d allocated PCH PLL %x\n",
|
|
|
|
intel_crtc->base.base.id, pll->pll_reg);
|
|
|
|
goto found;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
found:
|
|
|
|
intel_crtc->pch_pll = pll;
|
|
|
|
pll->refcount++;
|
|
|
|
DRM_DEBUG_DRIVER("using pll %d for pipe %d\n", i, intel_crtc->pipe);
|
|
|
|
prepare: /* separate function? */
|
|
|
|
DRM_DEBUG_DRIVER("switching PLL %x off\n", pll->pll_reg);
|
|
|
|
|
2012-05-02 19:43:56 +00:00
|
|
|
/* Wait for the clocks to stabilize before rewriting the regs */
|
|
|
|
I915_WRITE(pll->pll_reg, dpll & ~DPLL_VCO_ENABLE);
|
2012-04-20 16:11:53 +00:00
|
|
|
POSTING_READ(pll->pll_reg);
|
|
|
|
udelay(150);
|
2012-05-02 19:43:56 +00:00
|
|
|
|
|
|
|
I915_WRITE(pll->fp0_reg, fp);
|
|
|
|
I915_WRITE(pll->pll_reg, dpll & ~DPLL_VCO_ENABLE);
|
2012-04-20 16:11:53 +00:00
|
|
|
pll->on = false;
|
|
|
|
return pll;
|
|
|
|
}
|
|
|
|
|
2011-10-11 17:43:02 +00:00
|
|
|
void intel_cpt_verify_modeset(struct drm_device *dev, int pipe)
|
|
|
|
{
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
int dslreg = PIPEDSL(pipe), tc2reg = TRANS_CHICKEN2(pipe);
|
|
|
|
u32 temp;
|
|
|
|
|
|
|
|
temp = I915_READ(dslreg);
|
|
|
|
udelay(500);
|
|
|
|
if (wait_for(I915_READ(dslreg) != temp, 5)) {
|
|
|
|
/* Without this, mode sets may fail silently on FDI */
|
|
|
|
I915_WRITE(tc2reg, TRANS_AUTOTRAIN_GEN_STALL_DIS);
|
|
|
|
udelay(250);
|
|
|
|
I915_WRITE(tc2reg, 0);
|
|
|
|
if (wait_for(I915_READ(dslreg) != temp, 5))
|
|
|
|
DRM_ERROR("mode set failed: pipe %d stuck\n", pipe);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-05 18:31:48 +00:00
|
|
|
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);
|
2012-06-29 20:40:09 +00:00
|
|
|
struct intel_encoder *encoder;
|
2011-01-05 18:31:48 +00:00
|
|
|
int pipe = intel_crtc->pipe;
|
|
|
|
int plane = intel_crtc->plane;
|
|
|
|
u32 temp;
|
|
|
|
bool is_pch_port;
|
|
|
|
|
2012-07-02 09:43:47 +00:00
|
|
|
WARN_ON(!crtc->enabled);
|
|
|
|
|
2011-01-05 18:31:48 +00:00
|
|
|
if (intel_crtc->active)
|
|
|
|
return;
|
|
|
|
|
|
|
|
intel_crtc->active = true;
|
|
|
|
intel_update_watermarks(dev);
|
|
|
|
|
|
|
|
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
|
|
|
|
temp = I915_READ(PCH_LVDS);
|
|
|
|
if ((temp & LVDS_PORT_EN) == 0)
|
|
|
|
I915_WRITE(PCH_LVDS, temp | LVDS_PORT_EN);
|
|
|
|
}
|
|
|
|
|
|
|
|
is_pch_port = intel_crtc_driving_pch(crtc);
|
|
|
|
|
2012-09-06 20:08:33 +00:00
|
|
|
if (is_pch_port) {
|
2012-08-12 17:27:14 +00:00
|
|
|
ironlake_fdi_pll_enable(intel_crtc);
|
2012-09-06 20:08:33 +00:00
|
|
|
} else {
|
|
|
|
assert_fdi_tx_disabled(dev_priv, pipe);
|
|
|
|
assert_fdi_rx_disabled(dev_priv, pipe);
|
|
|
|
}
|
2011-01-05 18:31:48 +00:00
|
|
|
|
2012-09-06 20:15:40 +00:00
|
|
|
for_each_encoder_on_crtc(dev, crtc, encoder)
|
|
|
|
if (encoder->pre_enable)
|
|
|
|
encoder->pre_enable(encoder);
|
|
|
|
|
2011-01-05 18:31:48 +00:00
|
|
|
/* Enable panel fitting for LVDS */
|
|
|
|
if (dev_priv->pch_pf_size &&
|
|
|
|
(intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) || HAS_eDP)) {
|
|
|
|
/* Force use of hard-coded filter coefficients
|
|
|
|
* as some pre-programmed values are broken,
|
|
|
|
* e.g. x201.
|
|
|
|
*/
|
2011-02-07 20:26:52 +00:00
|
|
|
I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3);
|
|
|
|
I915_WRITE(PF_WIN_POS(pipe), dev_priv->pch_pf_pos);
|
|
|
|
I915_WRITE(PF_WIN_SZ(pipe), dev_priv->pch_pf_size);
|
2011-01-05 18:31:48 +00:00
|
|
|
}
|
|
|
|
|
2011-06-15 21:32:33 +00:00
|
|
|
/*
|
|
|
|
* On ILK+ LUT must be loaded before the pipe is running but with
|
|
|
|
* clocks enabled
|
|
|
|
*/
|
|
|
|
intel_crtc_load_lut(crtc);
|
|
|
|
|
2011-01-05 18:31:48 +00:00
|
|
|
intel_enable_pipe(dev_priv, pipe, is_pch_port);
|
|
|
|
intel_enable_plane(dev_priv, plane, pipe);
|
|
|
|
|
|
|
|
if (is_pch_port)
|
|
|
|
ironlake_pch_enable(crtc);
|
2010-09-10 17:57:18 +00:00
|
|
|
|
2011-04-25 19:11:50 +00:00
|
|
|
mutex_lock(&dev->struct_mutex);
|
2010-09-11 09:47:47 +00:00
|
|
|
intel_update_fbc(dev);
|
2011-04-25 19:11:50 +00:00
|
|
|
mutex_unlock(&dev->struct_mutex);
|
|
|
|
|
2010-09-13 12:54:26 +00:00
|
|
|
intel_crtc_update_cursor(crtc, true);
|
2012-06-29 20:40:09 +00:00
|
|
|
|
2012-07-01 21:24:36 +00:00
|
|
|
for_each_encoder_on_crtc(dev, crtc, encoder)
|
|
|
|
encoder->enable(encoder);
|
2012-07-01 22:16:19 +00:00
|
|
|
|
|
|
|
if (HAS_PCH_CPT(dev))
|
|
|
|
intel_cpt_verify_modeset(dev, intel_crtc->pipe);
|
2010-09-10 17:26:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2012-06-29 20:40:09 +00:00
|
|
|
struct intel_encoder *encoder;
|
2010-09-10 17:26:01 +00:00
|
|
|
int pipe = intel_crtc->pipe;
|
|
|
|
int plane = intel_crtc->plane;
|
2010-09-11 12:48:45 +00:00
|
|
|
u32 reg, temp;
|
2010-06-12 06:32:27 +00:00
|
|
|
|
2012-06-29 20:40:09 +00:00
|
|
|
|
2010-09-13 13:19:16 +00:00
|
|
|
if (!intel_crtc->active)
|
|
|
|
return;
|
|
|
|
|
2012-07-10 08:42:52 +00:00
|
|
|
for_each_encoder_on_crtc(dev, crtc, encoder)
|
|
|
|
encoder->disable(encoder);
|
|
|
|
|
2010-09-23 22:04:43 +00:00
|
|
|
intel_crtc_wait_for_pending_flips(crtc);
|
2010-09-10 17:26:01 +00:00
|
|
|
drm_vblank_off(dev, pipe);
|
2010-09-13 12:54:26 +00:00
|
|
|
intel_crtc_update_cursor(crtc, false);
|
2010-09-11 12:48:45 +00:00
|
|
|
|
2011-01-04 23:09:30 +00:00
|
|
|
intel_disable_plane(dev_priv, plane, pipe);
|
2010-08-07 10:01:35 +00:00
|
|
|
|
2011-07-08 11:22:37 +00:00
|
|
|
if (dev_priv->cfb_plane == plane)
|
|
|
|
intel_disable_fbc(dev);
|
2009-06-05 07:38:42 +00:00
|
|
|
|
2011-01-04 23:09:30 +00:00
|
|
|
intel_disable_pipe(dev_priv, pipe);
|
2009-07-23 17:00:32 +00:00
|
|
|
|
2010-09-10 17:26:01 +00:00
|
|
|
/* Disable PF */
|
2011-02-07 20:26:52 +00:00
|
|
|
I915_WRITE(PF_CTL(pipe), 0);
|
|
|
|
I915_WRITE(PF_WIN_SZ(pipe), 0);
|
2009-06-05 07:38:42 +00:00
|
|
|
|
2012-09-06 20:15:40 +00:00
|
|
|
for_each_encoder_on_crtc(dev, crtc, encoder)
|
|
|
|
if (encoder->post_disable)
|
|
|
|
encoder->post_disable(encoder);
|
|
|
|
|
2011-01-04 23:09:37 +00:00
|
|
|
ironlake_fdi_disable(crtc);
|
2009-06-05 07:38:42 +00:00
|
|
|
|
2011-01-03 20:14:26 +00:00
|
|
|
intel_disable_transcoder(dev_priv, pipe);
|
2010-08-07 10:01:35 +00:00
|
|
|
|
2010-09-10 17:26:01 +00:00
|
|
|
if (HAS_PCH_CPT(dev)) {
|
|
|
|
/* disable TRANS_DP_CTL */
|
2010-09-11 12:48:45 +00:00
|
|
|
reg = TRANS_DP_CTL(pipe);
|
|
|
|
temp = I915_READ(reg);
|
|
|
|
temp &= ~(TRANS_DP_OUTPUT_ENABLE | TRANS_DP_PORT_SEL_MASK);
|
2011-02-02 20:08:07 +00:00
|
|
|
temp |= TRANS_DP_PORT_SEL_NONE;
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(reg, temp);
|
2010-09-10 17:26:01 +00:00
|
|
|
|
|
|
|
/* disable DPLL_SEL */
|
|
|
|
temp = I915_READ(PCH_DPLL_SEL);
|
2011-02-07 20:26:52 +00:00
|
|
|
switch (pipe) {
|
|
|
|
case 0:
|
2011-10-12 22:01:33 +00:00
|
|
|
temp &= ~(TRANSA_DPLL_ENABLE | TRANSA_DPLLB_SEL);
|
2011-02-07 20:26:52 +00:00
|
|
|
break;
|
|
|
|
case 1:
|
2010-09-10 17:26:01 +00:00
|
|
|
temp &= ~(TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL);
|
2011-02-07 20:26:52 +00:00
|
|
|
break;
|
|
|
|
case 2:
|
2011-10-12 16:51:31 +00:00
|
|
|
/* C shares PLL A or B */
|
2011-10-12 22:01:33 +00:00
|
|
|
temp &= ~(TRANSC_DPLL_ENABLE | TRANSC_DPLLB_SEL);
|
2011-02-07 20:26:52 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
BUG(); /* wtf */
|
|
|
|
}
|
2010-09-10 17:26:01 +00:00
|
|
|
I915_WRITE(PCH_DPLL_SEL, temp);
|
|
|
|
}
|
2010-04-08 01:43:27 +00:00
|
|
|
|
2010-09-10 17:26:01 +00:00
|
|
|
/* disable PCH DPLL */
|
2012-04-20 16:11:53 +00:00
|
|
|
intel_disable_pch_pll(intel_crtc);
|
2010-04-07 08:15:54 +00:00
|
|
|
|
2012-08-12 17:27:14 +00:00
|
|
|
ironlake_fdi_pll_disable(intel_crtc);
|
2010-09-13 12:54:26 +00:00
|
|
|
|
2010-09-13 13:19:16 +00:00
|
|
|
intel_crtc->active = false;
|
2010-09-13 12:54:26 +00:00
|
|
|
intel_update_watermarks(dev);
|
2011-04-25 19:11:50 +00:00
|
|
|
|
|
|
|
mutex_lock(&dev->struct_mutex);
|
2010-09-13 12:54:26 +00:00
|
|
|
intel_update_fbc(dev);
|
2011-04-25 19:11:50 +00:00
|
|
|
mutex_unlock(&dev->struct_mutex);
|
2010-09-10 17:26:01 +00:00
|
|
|
}
|
2009-11-25 05:09:38 +00:00
|
|
|
|
2012-04-20 16:11:53 +00:00
|
|
|
static void ironlake_crtc_off(struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
|
intel_put_pch_pll(intel_crtc);
|
|
|
|
}
|
|
|
|
|
2009-09-15 20:57:34 +00:00
|
|
|
static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable)
|
|
|
|
{
|
|
|
|
if (!enable && intel_crtc->overlay) {
|
2010-08-12 12:53:37 +00:00
|
|
|
struct drm_device *dev = intel_crtc->base.dev;
|
2011-02-21 14:43:56 +00:00
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
2009-09-15 20:57:37 +00:00
|
|
|
|
2010-08-12 12:53:37 +00:00
|
|
|
mutex_lock(&dev->struct_mutex);
|
2011-02-21 14:43:56 +00:00
|
|
|
dev_priv->mm.interruptible = false;
|
|
|
|
(void) intel_overlay_switch_off(intel_crtc->overlay);
|
|
|
|
dev_priv->mm.interruptible = true;
|
2010-08-12 12:53:37 +00:00
|
|
|
mutex_unlock(&dev->struct_mutex);
|
2009-09-15 20:57:34 +00:00
|
|
|
}
|
|
|
|
|
2010-08-12 12:50:28 +00:00
|
|
|
/* Let userspace switch the overlay on again. In most cases userspace
|
|
|
|
* has to recompute where to put it anyway.
|
|
|
|
*/
|
2009-09-15 20:57:34 +00:00
|
|
|
}
|
|
|
|
|
2010-09-10 17:31:34 +00:00
|
|
|
static void i9xx_crtc_enable(struct drm_crtc *crtc)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
2012-06-29 20:40:09 +00:00
|
|
|
struct intel_encoder *encoder;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
int pipe = intel_crtc->pipe;
|
2009-09-10 22:28:06 +00:00
|
|
|
int plane = intel_crtc->plane;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2012-07-02 09:43:47 +00:00
|
|
|
WARN_ON(!crtc->enabled);
|
|
|
|
|
2010-09-13 13:19:16 +00:00
|
|
|
if (intel_crtc->active)
|
|
|
|
return;
|
|
|
|
|
|
|
|
intel_crtc->active = true;
|
2010-09-13 12:54:26 +00:00
|
|
|
intel_update_watermarks(dev);
|
|
|
|
|
2011-01-04 23:09:33 +00:00
|
|
|
intel_enable_pll(dev_priv, pipe);
|
2011-01-03 20:14:26 +00:00
|
|
|
intel_enable_pipe(dev_priv, pipe, false);
|
2011-01-04 23:09:30 +00:00
|
|
|
intel_enable_plane(dev_priv, plane, pipe);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2010-09-10 17:31:34 +00:00
|
|
|
intel_crtc_load_lut(crtc);
|
2010-09-11 09:47:47 +00:00
|
|
|
intel_update_fbc(dev);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2010-09-10 17:31:34 +00:00
|
|
|
/* Give the overlay scaler a chance to enable if it's on this pipe */
|
|
|
|
intel_crtc_dpms_overlay(intel_crtc, true);
|
2010-09-13 12:54:26 +00:00
|
|
|
intel_crtc_update_cursor(crtc, true);
|
2012-06-29 20:40:09 +00:00
|
|
|
|
2012-07-01 21:24:36 +00:00
|
|
|
for_each_encoder_on_crtc(dev, crtc, encoder)
|
|
|
|
encoder->enable(encoder);
|
2010-09-10 17:31:34 +00:00
|
|
|
}
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2010-09-10 17:31:34 +00:00
|
|
|
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);
|
2012-06-29 20:40:09 +00:00
|
|
|
struct intel_encoder *encoder;
|
2010-09-10 17:31:34 +00:00
|
|
|
int pipe = intel_crtc->pipe;
|
|
|
|
int plane = intel_crtc->plane;
|
2010-07-19 20:53:12 +00:00
|
|
|
|
2012-06-29 20:40:09 +00:00
|
|
|
|
2010-09-13 13:19:16 +00:00
|
|
|
if (!intel_crtc->active)
|
|
|
|
return;
|
|
|
|
|
2012-07-10 08:42:52 +00:00
|
|
|
for_each_encoder_on_crtc(dev, crtc, encoder)
|
|
|
|
encoder->disable(encoder);
|
|
|
|
|
2010-09-10 17:31:34 +00:00
|
|
|
/* Give the overlay scaler a chance to disable if it's on this pipe */
|
2010-09-23 22:04:43 +00:00
|
|
|
intel_crtc_wait_for_pending_flips(crtc);
|
|
|
|
drm_vblank_off(dev, pipe);
|
2010-09-10 17:31:34 +00:00
|
|
|
intel_crtc_dpms_overlay(intel_crtc, false);
|
2010-09-13 12:54:26 +00:00
|
|
|
intel_crtc_update_cursor(crtc, false);
|
2010-09-10 17:31:34 +00:00
|
|
|
|
2011-07-08 11:22:37 +00:00
|
|
|
if (dev_priv->cfb_plane == plane)
|
|
|
|
intel_disable_fbc(dev);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2011-01-04 23:09:30 +00:00
|
|
|
intel_disable_plane(dev_priv, plane, pipe);
|
|
|
|
intel_disable_pipe(dev_priv, pipe);
|
2011-01-04 23:09:33 +00:00
|
|
|
intel_disable_pll(dev_priv, pipe);
|
2010-09-10 17:31:34 +00:00
|
|
|
|
2010-09-13 13:19:16 +00:00
|
|
|
intel_crtc->active = false;
|
2010-09-13 12:54:26 +00:00
|
|
|
intel_update_fbc(dev);
|
|
|
|
intel_update_watermarks(dev);
|
2010-09-10 17:31:34 +00:00
|
|
|
}
|
|
|
|
|
2012-04-20 16:11:53 +00:00
|
|
|
static void i9xx_crtc_off(struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2012-07-08 20:34:21 +00:00
|
|
|
static void intel_crtc_update_sarea(struct drm_crtc *crtc,
|
|
|
|
bool enabled)
|
2009-06-05 07:38:42 +00:00
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct drm_i915_master_private *master_priv;
|
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
|
int pipe = intel_crtc->pipe;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
|
|
|
if (!dev->primary->master)
|
|
|
|
return;
|
|
|
|
|
|
|
|
master_priv = dev->primary->master->driver_priv;
|
|
|
|
if (!master_priv->sarea_priv)
|
|
|
|
return;
|
|
|
|
|
|
|
|
switch (pipe) {
|
|
|
|
case 0:
|
|
|
|
master_priv->sarea_priv->pipeA_w = enabled ? crtc->mode.hdisplay : 0;
|
|
|
|
master_priv->sarea_priv->pipeA_h = enabled ? crtc->mode.vdisplay : 0;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
master_priv->sarea_priv->pipeB_w = enabled ? crtc->mode.hdisplay : 0;
|
|
|
|
master_priv->sarea_priv->pipeB_h = enabled ? crtc->mode.vdisplay : 0;
|
|
|
|
break;
|
|
|
|
default:
|
2011-02-07 20:26:52 +00:00
|
|
|
DRM_ERROR("Can't update pipe %c in SAREA\n", pipe_name(pipe));
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-08 20:34:21 +00:00
|
|
|
/**
|
|
|
|
* Sets the power management mode of the pipe and plane.
|
|
|
|
*/
|
|
|
|
void intel_crtc_update_dpms(struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
struct intel_encoder *intel_encoder;
|
|
|
|
bool enable = false;
|
|
|
|
|
|
|
|
for_each_encoder_on_crtc(dev, crtc, intel_encoder)
|
|
|
|
enable |= intel_encoder->connectors_active;
|
|
|
|
|
|
|
|
if (enable)
|
|
|
|
dev_priv->display.crtc_enable(crtc);
|
|
|
|
else
|
|
|
|
dev_priv->display.crtc_disable(crtc);
|
|
|
|
|
|
|
|
intel_crtc_update_sarea(crtc, enable);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void intel_crtc_noop(struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2010-09-08 15:30:16 +00:00
|
|
|
static void intel_crtc_disable(struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
2012-07-08 20:34:21 +00:00
|
|
|
struct drm_connector *connector;
|
2012-04-20 16:11:53 +00:00
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
2010-09-08 15:30:16 +00:00
|
|
|
|
2012-07-08 20:34:21 +00:00
|
|
|
/* crtc should still be enabled when we disable it. */
|
|
|
|
WARN_ON(!crtc->enabled);
|
|
|
|
|
|
|
|
dev_priv->display.crtc_disable(crtc);
|
|
|
|
intel_crtc_update_sarea(crtc, false);
|
2012-04-20 16:11:53 +00:00
|
|
|
dev_priv->display.off(crtc);
|
|
|
|
|
2012-01-16 23:01:13 +00:00
|
|
|
assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane);
|
|
|
|
assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe);
|
2010-09-08 15:30:16 +00:00
|
|
|
|
|
|
|
if (crtc->fb) {
|
|
|
|
mutex_lock(&dev->struct_mutex);
|
2011-12-14 12:57:08 +00:00
|
|
|
intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj);
|
2010-09-08 15:30:16 +00:00
|
|
|
mutex_unlock(&dev->struct_mutex);
|
2012-07-08 20:34:21 +00:00
|
|
|
crtc->fb = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Update computed state. */
|
|
|
|
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
|
|
|
if (!connector->encoder || !connector->encoder->crtc)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (connector->encoder->crtc != crtc)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
connector->dpms = DRM_MODE_DPMS_OFF;
|
|
|
|
to_intel_encoder(connector->encoder)->connectors_active = false;
|
2010-09-08 15:30:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-26 17:21:47 +00:00
|
|
|
void intel_modeset_disable(struct drm_device *dev)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
{
|
2012-07-26 17:21:47 +00:00
|
|
|
struct drm_crtc *crtc;
|
|
|
|
|
|
|
|
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
|
|
|
if (crtc->enabled)
|
|
|
|
intel_crtc_disable(crtc);
|
|
|
|
}
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
2012-07-11 14:51:39 +00:00
|
|
|
void intel_encoder_noop(struct drm_encoder *encoder)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
{
|
2010-09-10 17:47:20 +00:00
|
|
|
}
|
|
|
|
|
2010-08-04 12:50:23 +00:00
|
|
|
void intel_encoder_destroy(struct drm_encoder *encoder)
|
2010-09-10 17:47:20 +00:00
|
|
|
{
|
2010-09-09 14:14:28 +00:00
|
|
|
struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
|
2010-08-04 12:50:23 +00:00
|
|
|
|
|
|
|
drm_encoder_cleanup(encoder);
|
|
|
|
kfree(intel_encoder);
|
2010-09-10 17:47:20 +00:00
|
|
|
}
|
|
|
|
|
2012-06-30 06:59:56 +00:00
|
|
|
/* Simple dpms helper for encodres with just one connector, no cloning and only
|
|
|
|
* one kind of off state. It clamps all !ON modes to fully OFF and changes the
|
|
|
|
* state of the entire output pipe. */
|
|
|
|
void intel_encoder_dpms(struct intel_encoder *encoder, int mode)
|
2010-09-10 17:47:20 +00:00
|
|
|
{
|
2012-06-30 06:59:56 +00:00
|
|
|
if (mode == DRM_MODE_DPMS_ON) {
|
|
|
|
encoder->connectors_active = true;
|
|
|
|
|
drm/i915: convert dpms functions of dvo/sdvo/crt
Yeah, big patch but I couldn't come up with a neat idea of how to
split it up further, that wouldn't break dpms on cloned configs
somehow. But the changes in dvo/sdvo/crt are all pretty much
orthonogal, so it's not too bad a patch.
These are the only encoders that support cloning, which requires a few
special changes compared to the previous patches.
- Compute the desired state of the display pipe by walking all
connected encoders and checking whether any has active connectors.
To make this clearer, drop the old mode parameter to the crtc dpms
function and rename it to intel_crtc_update_dpms.
- There's the curious case of intel_crtc->dpms_mode. With the previous
patches to remove the overlay pipe A code and to rework the load
detect pipe code, the big users are gone. We still keep it to avoid
enabling the pipe twice, but we duplicate this logic with
crtc->active, too. Still, leave this for now and just push a fake
dpms mode into it that reflects the state of the display pipe.
Changes in the encoder dpms functions:
- We clamp the dpms state to the supported range right away. This is
escpecially important for the VGA outputs, where only older hw
supports the intermediate states. This (and the crt->adpa_reg patch)
allows us to unify the crt dpms code again between all variants
(gmch, vlv and pch).
- We only enable/disable the output for dvo/sdvo and leave the encoder
running. The encoder will be disabled/enabled when we switch the
state of the entire output pipeline (which will happen right away
for non-cloned setups). This way the duplication is reduced and
strange interaction when disabling output ports at the wrong time
avoided.
The dpms code for all three types of connectors contains a bit of
duplicated logic, but I think keeping these special cases separate is
simpler: CRT is the only one that hanldes intermediate dpms state
(which requires extra logic to enable/disable things in the right
order), and introducing some abstraction just to share the code
between dvo and sdvo smells like overkill. We can do that once someone
bothers to implement cloning for the more modern outputs. But I doubt
that this will ever happen.
v2: s/crtc/crt/_set_dpms, noticed by Paulo Zanoni.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-01 20:42:24 +00:00
|
|
|
intel_crtc_update_dpms(encoder->base.crtc);
|
2012-06-30 06:59:56 +00:00
|
|
|
} else {
|
|
|
|
encoder->connectors_active = false;
|
|
|
|
|
drm/i915: convert dpms functions of dvo/sdvo/crt
Yeah, big patch but I couldn't come up with a neat idea of how to
split it up further, that wouldn't break dpms on cloned configs
somehow. But the changes in dvo/sdvo/crt are all pretty much
orthonogal, so it's not too bad a patch.
These are the only encoders that support cloning, which requires a few
special changes compared to the previous patches.
- Compute the desired state of the display pipe by walking all
connected encoders and checking whether any has active connectors.
To make this clearer, drop the old mode parameter to the crtc dpms
function and rename it to intel_crtc_update_dpms.
- There's the curious case of intel_crtc->dpms_mode. With the previous
patches to remove the overlay pipe A code and to rework the load
detect pipe code, the big users are gone. We still keep it to avoid
enabling the pipe twice, but we duplicate this logic with
crtc->active, too. Still, leave this for now and just push a fake
dpms mode into it that reflects the state of the display pipe.
Changes in the encoder dpms functions:
- We clamp the dpms state to the supported range right away. This is
escpecially important for the VGA outputs, where only older hw
supports the intermediate states. This (and the crt->adpa_reg patch)
allows us to unify the crt dpms code again between all variants
(gmch, vlv and pch).
- We only enable/disable the output for dvo/sdvo and leave the encoder
running. The encoder will be disabled/enabled when we switch the
state of the entire output pipeline (which will happen right away
for non-cloned setups). This way the duplication is reduced and
strange interaction when disabling output ports at the wrong time
avoided.
The dpms code for all three types of connectors contains a bit of
duplicated logic, but I think keeping these special cases separate is
simpler: CRT is the only one that hanldes intermediate dpms state
(which requires extra logic to enable/disable things in the right
order), and introducing some abstraction just to share the code
between dvo and sdvo smells like overkill. We can do that once someone
bothers to implement cloning for the more modern outputs. But I doubt
that this will ever happen.
v2: s/crtc/crt/_set_dpms, noticed by Paulo Zanoni.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-01 20:42:24 +00:00
|
|
|
intel_crtc_update_dpms(encoder->base.crtc);
|
2012-06-30 06:59:56 +00:00
|
|
|
}
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
2012-07-02 19:54:27 +00:00
|
|
|
/* Cross check the actual hw state with our own modeset state tracking (and it's
|
|
|
|
* internal consistency). */
|
2012-08-31 15:37:33 +00:00
|
|
|
static void intel_connector_check_state(struct intel_connector *connector)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
{
|
2012-07-02 19:54:27 +00:00
|
|
|
if (connector->get_hw_state(connector)) {
|
|
|
|
struct intel_encoder *encoder = connector->encoder;
|
|
|
|
struct drm_crtc *crtc;
|
|
|
|
bool encoder_enabled;
|
|
|
|
enum pipe pipe;
|
|
|
|
|
|
|
|
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
|
|
|
|
connector->base.base.id,
|
|
|
|
drm_get_connector_name(&connector->base));
|
|
|
|
|
|
|
|
WARN(connector->base.dpms == DRM_MODE_DPMS_OFF,
|
|
|
|
"wrong connector dpms state\n");
|
|
|
|
WARN(connector->base.encoder != &encoder->base,
|
|
|
|
"active connector not linked to encoder\n");
|
|
|
|
WARN(!encoder->connectors_active,
|
|
|
|
"encoder->connectors_active not set\n");
|
|
|
|
|
|
|
|
encoder_enabled = encoder->get_hw_state(encoder, &pipe);
|
|
|
|
WARN(!encoder_enabled, "encoder not enabled\n");
|
|
|
|
if (WARN_ON(!encoder->base.crtc))
|
|
|
|
return;
|
|
|
|
|
|
|
|
crtc = encoder->base.crtc;
|
|
|
|
|
|
|
|
WARN(!crtc->enabled, "crtc not enabled\n");
|
|
|
|
WARN(!to_intel_crtc(crtc)->active, "crtc not active\n");
|
|
|
|
WARN(pipe != to_intel_crtc(crtc)->pipe,
|
|
|
|
"encoder active on the wrong pipe\n");
|
|
|
|
}
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
2012-06-30 06:59:56 +00:00
|
|
|
/* Even simpler default implementation, if there's really no special case to
|
|
|
|
* consider. */
|
|
|
|
void intel_connector_dpms(struct drm_connector *connector, int mode)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
{
|
2012-06-30 06:59:56 +00:00
|
|
|
struct intel_encoder *encoder = intel_attached_encoder(connector);
|
2011-10-11 17:43:02 +00:00
|
|
|
|
2012-06-30 06:59:56 +00:00
|
|
|
/* All the simple cases only support two dpms states. */
|
|
|
|
if (mode != DRM_MODE_DPMS_ON)
|
|
|
|
mode = DRM_MODE_DPMS_OFF;
|
2011-10-11 17:43:02 +00:00
|
|
|
|
2012-06-30 06:59:56 +00:00
|
|
|
if (mode == connector->dpms)
|
|
|
|
return;
|
|
|
|
|
|
|
|
connector->dpms = mode;
|
|
|
|
|
|
|
|
/* Only need to change hw state when actually enabled */
|
|
|
|
if (encoder->base.crtc)
|
|
|
|
intel_encoder_dpms(encoder, mode);
|
|
|
|
else
|
2012-07-10 07:50:11 +00:00
|
|
|
WARN_ON(encoder->connectors_active != false);
|
2012-07-02 19:54:27 +00:00
|
|
|
|
2012-08-31 15:37:33 +00:00
|
|
|
intel_modeset_check_state(connector->dev);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
2012-07-02 11:10:34 +00:00
|
|
|
/* 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)
|
2010-08-04 12:50:23 +00: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 18:28:59 +00:00
|
|
|
enum pipe pipe = 0;
|
2012-07-02 11:10:34 +00:00
|
|
|
struct intel_encoder *encoder = connector->encoder;
|
2010-08-04 12:50:23 +00:00
|
|
|
|
2012-07-02 11:10:34 +00:00
|
|
|
return encoder->get_hw_state(encoder, &pipe);
|
2010-08-04 12:50:23 +00:00
|
|
|
}
|
|
|
|
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
|
2012-07-20 08:30:45 +00:00
|
|
|
const struct drm_display_mode *mode,
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
struct drm_display_mode *adjusted_mode)
|
|
|
|
{
|
2009-06-05 07:38:42 +00:00
|
|
|
struct drm_device *dev = crtc->dev;
|
2010-09-12 17:25:19 +00:00
|
|
|
|
2009-10-22 23:11:14 +00:00
|
|
|
if (HAS_PCH_SPLIT(dev)) {
|
2009-06-05 07:38:42 +00:00
|
|
|
/* FDI link clock is fixed at 2.7G */
|
2010-07-07 21:06:43 +00:00
|
|
|
if (mode->clock * 3 > IRONLAKE_FDI_FREQ * 4)
|
|
|
|
return false;
|
2009-06-05 07:38:42 +00:00
|
|
|
}
|
2010-09-12 17:25:19 +00:00
|
|
|
|
2012-04-15 17:53:19 +00:00
|
|
|
/* All interlaced capable intel hw wants timings in frames. Note though
|
|
|
|
* that intel_lvds_mode_fixup does some funny tricks with the crtc
|
|
|
|
* timings, so we need to be careful not to clobber these.*/
|
|
|
|
if (!(adjusted_mode->private_flags & INTEL_MODE_CRTC_TIMINGS_SET))
|
|
|
|
drm_mode_set_crtcinfo(adjusted_mode, 0);
|
2010-09-12 17:25:19 +00:00
|
|
|
|
2012-06-21 10:19:59 +00:00
|
|
|
/* WaPruneModeWithIncorrectHsyncOffset: Cantiga+ cannot handle modes
|
|
|
|
* with a hsync front porch of 0.
|
|
|
|
*/
|
|
|
|
if ((INTEL_INFO(dev)->gen > 4 || IS_G4X(dev)) &&
|
|
|
|
adjusted_mode->hsync_start == adjusted_mode->hdisplay)
|
|
|
|
return false;
|
|
|
|
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-03-28 20:39:23 +00:00
|
|
|
static int valleyview_get_display_clock_speed(struct drm_device *dev)
|
|
|
|
{
|
|
|
|
return 400000; /* FIXME */
|
|
|
|
}
|
|
|
|
|
2009-09-21 17:42:27 +00:00
|
|
|
static int i945_get_display_clock_speed(struct drm_device *dev)
|
|
|
|
{
|
|
|
|
return 400000;
|
|
|
|
}
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2009-09-21 17:42:27 +00:00
|
|
|
static int i915_get_display_clock_speed(struct drm_device *dev)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
{
|
2009-09-21 17:42:27 +00:00
|
|
|
return 333000;
|
|
|
|
}
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2009-09-21 17:42:27 +00:00
|
|
|
static int i9xx_misc_get_display_clock_speed(struct drm_device *dev)
|
|
|
|
{
|
|
|
|
return 200000;
|
|
|
|
}
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2009-09-21 17:42:27 +00:00
|
|
|
static int i915gm_get_display_clock_speed(struct drm_device *dev)
|
|
|
|
{
|
|
|
|
u16 gcfgc = 0;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2009-09-21 17:42:27 +00:00
|
|
|
pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
|
|
|
|
|
|
|
|
if (gcfgc & GC_LOW_FREQUENCY_ENABLE)
|
|
|
|
return 133000;
|
|
|
|
else {
|
|
|
|
switch (gcfgc & GC_DISPLAY_CLOCK_MASK) {
|
|
|
|
case GC_DISPLAY_CLOCK_333_MHZ:
|
|
|
|
return 333000;
|
|
|
|
default:
|
|
|
|
case GC_DISPLAY_CLOCK_190_200_MHZ:
|
|
|
|
return 190000;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
2009-09-21 17:42:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int i865_get_display_clock_speed(struct drm_device *dev)
|
|
|
|
{
|
|
|
|
return 266000;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int i855_get_display_clock_speed(struct drm_device *dev)
|
|
|
|
{
|
|
|
|
u16 hpllcc = 0;
|
|
|
|
/* 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_100_200:
|
|
|
|
return 200000;
|
|
|
|
case GC_CLOCK_166_250:
|
|
|
|
return 250000;
|
|
|
|
case GC_CLOCK_100_133:
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
return 133000;
|
2009-09-21 17:42:27 +00:00
|
|
|
}
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2009-09-21 17:42:27 +00:00
|
|
|
/* Shouldn't happen */
|
|
|
|
return 0;
|
|
|
|
}
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2009-09-21 17:42:27 +00:00
|
|
|
static int i830_get_display_clock_speed(struct drm_device *dev)
|
|
|
|
{
|
|
|
|
return 133000;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
2009-06-05 07:38:42 +00:00
|
|
|
struct fdi_m_n {
|
|
|
|
u32 tu;
|
|
|
|
u32 gmch_m;
|
|
|
|
u32 gmch_n;
|
|
|
|
u32 link_m;
|
|
|
|
u32 link_n;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
fdi_reduce_ratio(u32 *num, u32 *den)
|
|
|
|
{
|
|
|
|
while (*num > 0xffffff || *den > 0xffffff) {
|
|
|
|
*num >>= 1;
|
|
|
|
*den >>= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2009-12-03 22:14:42 +00:00
|
|
|
ironlake_compute_m_n(int bits_per_pixel, int nlanes, int pixel_clock,
|
|
|
|
int link_clock, struct fdi_m_n *m_n)
|
2009-06-05 07:38:42 +00:00
|
|
|
{
|
|
|
|
m_n->tu = 64; /* default size */
|
|
|
|
|
2010-12-04 01:01:29 +00:00
|
|
|
/* BUG_ON(pixel_clock > INT_MAX / 36); */
|
|
|
|
m_n->gmch_m = bits_per_pixel * pixel_clock;
|
|
|
|
m_n->gmch_n = link_clock * nlanes * 8;
|
2009-06-05 07:38:42 +00:00
|
|
|
fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n);
|
|
|
|
|
2010-12-04 01:01:29 +00:00
|
|
|
m_n->link_m = pixel_clock;
|
|
|
|
m_n->link_n = link_clock;
|
2009-06-05 07:38:42 +00:00
|
|
|
fdi_reduce_ratio(&m_n->link_m, &m_n->link_n);
|
|
|
|
}
|
|
|
|
|
2011-01-12 17:04:08 +00:00
|
|
|
static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv)
|
|
|
|
{
|
2011-09-26 23:09:45 +00:00
|
|
|
if (i915_panel_use_ssc >= 0)
|
|
|
|
return i915_panel_use_ssc != 0;
|
|
|
|
return dev_priv->lvds_use_ssc
|
2011-07-12 21:56:22 +00:00
|
|
|
&& !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE);
|
2011-01-12 17:04:08 +00:00
|
|
|
}
|
|
|
|
|
2011-06-24 19:19:22 +00:00
|
|
|
/**
|
|
|
|
* intel_choose_pipe_bpp_dither - figure out what color depth the pipe should send
|
|
|
|
* @crtc: CRTC structure
|
2011-12-13 23:41:00 +00:00
|
|
|
* @mode: requested mode
|
2011-06-24 19:19:22 +00:00
|
|
|
*
|
|
|
|
* A pipe may be connected to one or more outputs. Based on the depth of the
|
|
|
|
* attached framebuffer, choose a good color depth to use on the pipe.
|
|
|
|
*
|
|
|
|
* If possible, match the pipe depth to the fb depth. In some cases, this
|
|
|
|
* isn't ideal, because the connected output supports a lesser or restricted
|
|
|
|
* set of depths. Resolve that here:
|
|
|
|
* LVDS typically supports only 6bpc, so clamp down in that case
|
|
|
|
* HDMI supports only 8bpc or 12bpc, so clamp to 8bpc with dither for 10bpc
|
|
|
|
* Displays may support a restricted set as well, check EDID and clamp as
|
|
|
|
* appropriate.
|
2011-12-13 23:41:00 +00:00
|
|
|
* DP may want to dither down to 6bpc to fit larger modes
|
2011-06-24 19:19:22 +00:00
|
|
|
*
|
|
|
|
* RETURNS:
|
|
|
|
* Dithering requirement (i.e. false if display bpc and pipe bpc match,
|
|
|
|
* true if they don't match).
|
|
|
|
*/
|
|
|
|
static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
|
drm/i915: push crtc->fb update into pipe_set_base
Passing in the old fb, having overwritten the current fb, leads to
some neatly convoluted code. It's much simpler if we defer the
crtc->fb update to the place that updates the hw, in pipe_set_base.
This way we also don't need to restore anything in case something
fails - we only update crtc->fb once things have succeeded.
The real reason for this change is that now we keep the old fb
assigned to crtc->fb, which allows us to finally move the crtc disable
case into the common low-level set_mode function in the next patch.
Also don't clobber crtc->x and crtc->y, we neatly pass these down the
callchain already. Unfortunately we can't do the same with crtc->mode,
because that one is being used in the mode_set callbacks.
v2: Don't restore the drm_crtc object any more on failed modesets,
since we've lose an fb reference otherwise. Also (and this is the
reason this has been found), this totally confused the modeset state
tracking, since it clobbers crtc->enabled. Issue reported by Paulo
Zanoni.
v3: Rip out the entire crtc saving into struct intel_set_config, not
just the restoring part.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-05 20:51:56 +00:00
|
|
|
struct drm_framebuffer *fb,
|
2011-12-13 23:41:00 +00:00
|
|
|
unsigned int *pipe_bpp,
|
|
|
|
struct drm_display_mode *mode)
|
2011-06-24 19:19:22 +00:00
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
struct drm_connector *connector;
|
2012-07-05 07:50:24 +00:00
|
|
|
struct intel_encoder *intel_encoder;
|
2011-06-24 19:19:22 +00:00
|
|
|
unsigned int display_bpc = UINT_MAX, bpc;
|
|
|
|
|
|
|
|
/* Walk the encoders & connectors on this crtc, get min bpc */
|
2012-07-05 07:50:24 +00:00
|
|
|
for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
|
2011-06-24 19:19:22 +00:00
|
|
|
|
|
|
|
if (intel_encoder->type == INTEL_OUTPUT_LVDS) {
|
|
|
|
unsigned int lvds_bpc;
|
|
|
|
|
|
|
|
if ((I915_READ(PCH_LVDS) & LVDS_A3_POWER_MASK) ==
|
|
|
|
LVDS_A3_POWER_UP)
|
|
|
|
lvds_bpc = 8;
|
|
|
|
else
|
|
|
|
lvds_bpc = 6;
|
|
|
|
|
|
|
|
if (lvds_bpc < display_bpc) {
|
2011-10-10 20:33:34 +00:00
|
|
|
DRM_DEBUG_KMS("clamping display bpc (was %d) to LVDS (%d)\n", display_bpc, lvds_bpc);
|
2011-06-24 19:19:22 +00:00
|
|
|
display_bpc = lvds_bpc;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Not one of the known troublemakers, check the EDID */
|
|
|
|
list_for_each_entry(connector, &dev->mode_config.connector_list,
|
|
|
|
head) {
|
2012-07-05 07:50:24 +00:00
|
|
|
if (connector->encoder != &intel_encoder->base)
|
2011-06-24 19:19:22 +00:00
|
|
|
continue;
|
|
|
|
|
2011-07-28 19:55:14 +00:00
|
|
|
/* Don't use an invalid EDID bpc value */
|
|
|
|
if (connector->display_info.bpc &&
|
|
|
|
connector->display_info.bpc < display_bpc) {
|
2011-10-10 20:33:34 +00:00
|
|
|
DRM_DEBUG_KMS("clamping display bpc (was %d) to EDID reported max of %d\n", display_bpc, connector->display_info.bpc);
|
2011-06-24 19:19:22 +00:00
|
|
|
display_bpc = connector->display_info.bpc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* HDMI is either 12 or 8, so if the display lets 10bpc sneak
|
|
|
|
* through, clamp it down. (Note: >12bpc will be caught below.)
|
|
|
|
*/
|
|
|
|
if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
|
|
|
|
if (display_bpc > 8 && display_bpc < 12) {
|
2011-10-10 20:33:34 +00:00
|
|
|
DRM_DEBUG_KMS("forcing bpc to 12 for HDMI\n");
|
2011-06-24 19:19:22 +00:00
|
|
|
display_bpc = 12;
|
|
|
|
} else {
|
2011-10-10 20:33:34 +00:00
|
|
|
DRM_DEBUG_KMS("forcing bpc to 8 for HDMI\n");
|
2011-06-24 19:19:22 +00:00
|
|
|
display_bpc = 8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-13 23:41:00 +00:00
|
|
|
if (mode->private_flags & INTEL_MODE_DP_FORCE_6BPC) {
|
|
|
|
DRM_DEBUG_KMS("Dithering DP to 6bpc\n");
|
|
|
|
display_bpc = 6;
|
|
|
|
}
|
|
|
|
|
2011-06-24 19:19:22 +00:00
|
|
|
/*
|
|
|
|
* We could just drive the pipe at the highest bpc all the time and
|
|
|
|
* enable dithering as needed, but that costs bandwidth. So choose
|
|
|
|
* the minimum value that expresses the full color range of the fb but
|
|
|
|
* also stays within the max display bpc discovered above.
|
|
|
|
*/
|
|
|
|
|
drm/i915: push crtc->fb update into pipe_set_base
Passing in the old fb, having overwritten the current fb, leads to
some neatly convoluted code. It's much simpler if we defer the
crtc->fb update to the place that updates the hw, in pipe_set_base.
This way we also don't need to restore anything in case something
fails - we only update crtc->fb once things have succeeded.
The real reason for this change is that now we keep the old fb
assigned to crtc->fb, which allows us to finally move the crtc disable
case into the common low-level set_mode function in the next patch.
Also don't clobber crtc->x and crtc->y, we neatly pass these down the
callchain already. Unfortunately we can't do the same with crtc->mode,
because that one is being used in the mode_set callbacks.
v2: Don't restore the drm_crtc object any more on failed modesets,
since we've lose an fb reference otherwise. Also (and this is the
reason this has been found), this totally confused the modeset state
tracking, since it clobbers crtc->enabled. Issue reported by Paulo
Zanoni.
v3: Rip out the entire crtc saving into struct intel_set_config, not
just the restoring part.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-05 20:51:56 +00:00
|
|
|
switch (fb->depth) {
|
2011-06-24 19:19:22 +00:00
|
|
|
case 8:
|
|
|
|
bpc = 8; /* since we go through a colormap */
|
|
|
|
break;
|
|
|
|
case 15:
|
|
|
|
case 16:
|
|
|
|
bpc = 6; /* min is 18bpp */
|
|
|
|
break;
|
|
|
|
case 24:
|
2011-09-05 18:53:21 +00:00
|
|
|
bpc = 8;
|
2011-06-24 19:19:22 +00:00
|
|
|
break;
|
|
|
|
case 30:
|
2011-09-05 18:53:21 +00:00
|
|
|
bpc = 10;
|
2011-06-24 19:19:22 +00:00
|
|
|
break;
|
|
|
|
case 48:
|
2011-09-05 18:53:21 +00:00
|
|
|
bpc = 12;
|
2011-06-24 19:19:22 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
DRM_DEBUG("unsupported depth, assuming 24 bits\n");
|
|
|
|
bpc = min((unsigned int)8, display_bpc);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2011-09-05 18:53:21 +00:00
|
|
|
display_bpc = min(display_bpc, bpc);
|
|
|
|
|
2011-10-10 20:33:34 +00:00
|
|
|
DRM_DEBUG_KMS("setting pipe bpc to %d (max display bpc %d)\n",
|
|
|
|
bpc, display_bpc);
|
2011-06-24 19:19:22 +00:00
|
|
|
|
2011-09-05 18:53:21 +00:00
|
|
|
*pipe_bpp = display_bpc * 3;
|
2011-06-24 19:19:22 +00:00
|
|
|
|
|
|
|
return display_bpc != bpc;
|
|
|
|
}
|
|
|
|
|
2012-06-15 18:55:13 +00:00
|
|
|
static int vlv_get_refclk(struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
int refclk = 27000; /* for DP & HDMI */
|
|
|
|
|
|
|
|
return 100000; /* only one validated so far */
|
|
|
|
|
|
|
|
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) {
|
|
|
|
refclk = 96000;
|
|
|
|
} else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
|
|
|
|
if (intel_panel_use_ssc(dev_priv))
|
|
|
|
refclk = 100000;
|
|
|
|
else
|
|
|
|
refclk = 96000;
|
|
|
|
} else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) {
|
|
|
|
refclk = 100000;
|
|
|
|
}
|
|
|
|
|
|
|
|
return refclk;
|
|
|
|
}
|
|
|
|
|
2011-12-15 20:30:36 +00:00
|
|
|
static int i9xx_get_refclk(struct drm_crtc *crtc, int num_connectors)
|
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
int refclk;
|
|
|
|
|
2012-06-15 18:55:13 +00:00
|
|
|
if (IS_VALLEYVIEW(dev)) {
|
|
|
|
refclk = vlv_get_refclk(crtc);
|
|
|
|
} else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
|
2011-12-15 20:30:36 +00:00
|
|
|
intel_panel_use_ssc(dev_priv) && num_connectors < 2) {
|
|
|
|
refclk = dev_priv->lvds_ssc_freq * 1000;
|
|
|
|
DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n",
|
|
|
|
refclk / 1000);
|
|
|
|
} else if (!IS_GEN2(dev)) {
|
|
|
|
refclk = 96000;
|
|
|
|
} else {
|
|
|
|
refclk = 48000;
|
|
|
|
}
|
|
|
|
|
|
|
|
return refclk;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void i9xx_adjust_sdvo_tv_clock(struct drm_display_mode *adjusted_mode,
|
|
|
|
intel_clock_t *clock)
|
|
|
|
{
|
|
|
|
/* SDVO TV has fixed PLL values depend on its clock range,
|
|
|
|
this mirrors vbios setting. */
|
|
|
|
if (adjusted_mode->clock >= 100000
|
|
|
|
&& adjusted_mode->clock < 140500) {
|
|
|
|
clock->p1 = 2;
|
|
|
|
clock->p2 = 10;
|
|
|
|
clock->n = 3;
|
|
|
|
clock->m1 = 16;
|
|
|
|
clock->m2 = 8;
|
|
|
|
} else if (adjusted_mode->clock >= 140500
|
|
|
|
&& adjusted_mode->clock <= 200000) {
|
|
|
|
clock->p1 = 1;
|
|
|
|
clock->p2 = 10;
|
|
|
|
clock->n = 6;
|
|
|
|
clock->m1 = 12;
|
|
|
|
clock->m2 = 8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-15 20:30:37 +00:00
|
|
|
static void i9xx_update_pll_dividers(struct drm_crtc *crtc,
|
|
|
|
intel_clock_t *clock,
|
|
|
|
intel_clock_t *reduced_clock)
|
|
|
|
{
|
|
|
|
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 fp, fp2 = 0;
|
|
|
|
|
|
|
|
if (IS_PINEVIEW(dev)) {
|
|
|
|
fp = (1 << clock->n) << 16 | clock->m1 << 8 | clock->m2;
|
|
|
|
if (reduced_clock)
|
|
|
|
fp2 = (1 << reduced_clock->n) << 16 |
|
|
|
|
reduced_clock->m1 << 8 | reduced_clock->m2;
|
|
|
|
} else {
|
|
|
|
fp = clock->n << 16 | clock->m1 << 8 | clock->m2;
|
|
|
|
if (reduced_clock)
|
|
|
|
fp2 = reduced_clock->n << 16 | reduced_clock->m1 << 8 |
|
|
|
|
reduced_clock->m2;
|
|
|
|
}
|
|
|
|
|
|
|
|
I915_WRITE(FP0(pipe), fp);
|
|
|
|
|
|
|
|
intel_crtc->lowfreq_avail = false;
|
|
|
|
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
|
|
|
|
reduced_clock && i915_powersave) {
|
|
|
|
I915_WRITE(FP1(pipe), fp2);
|
|
|
|
intel_crtc->lowfreq_avail = true;
|
|
|
|
} else {
|
|
|
|
I915_WRITE(FP1(pipe), fp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-28 21:11:26 +00:00
|
|
|
static void intel_update_lvds(struct drm_crtc *crtc, intel_clock_t *clock,
|
|
|
|
struct drm_display_mode *adjusted_mode)
|
|
|
|
{
|
|
|
|
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;
|
2012-04-14 16:41:59 +00:00
|
|
|
u32 temp;
|
2012-03-28 21:11:26 +00:00
|
|
|
|
|
|
|
temp = I915_READ(LVDS);
|
|
|
|
temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
|
|
|
|
if (pipe == 1) {
|
|
|
|
temp |= LVDS_PIPEB_SELECT;
|
|
|
|
} else {
|
|
|
|
temp &= ~LVDS_PIPEB_SELECT;
|
|
|
|
}
|
|
|
|
/* set the corresponsding LVDS_BORDER bit */
|
|
|
|
temp |= dev_priv->lvds_border_bits;
|
|
|
|
/* Set the B0-B3 data pairs corresponding to whether we're going to
|
|
|
|
* set the DPLLs for dual-channel mode or not.
|
|
|
|
*/
|
|
|
|
if (clock->p2 == 7)
|
|
|
|
temp |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
|
|
|
|
else
|
|
|
|
temp &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
|
|
|
|
|
|
|
|
/* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
|
|
|
|
* appropriately here, but we need to look more thoroughly into how
|
|
|
|
* panels behave in the two modes.
|
|
|
|
*/
|
|
|
|
/* set the dithering flag on LVDS as needed */
|
|
|
|
if (INTEL_INFO(dev)->gen >= 4) {
|
|
|
|
if (dev_priv->lvds_dither)
|
|
|
|
temp |= LVDS_ENABLE_DITHER;
|
|
|
|
else
|
|
|
|
temp &= ~LVDS_ENABLE_DITHER;
|
|
|
|
}
|
2012-04-14 16:41:59 +00:00
|
|
|
temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY);
|
2012-03-28 21:11:26 +00:00
|
|
|
if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
|
2012-04-14 16:41:59 +00:00
|
|
|
temp |= LVDS_HSYNC_POLARITY;
|
2012-03-28 21:11:26 +00:00
|
|
|
if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
|
2012-04-14 16:41:59 +00:00
|
|
|
temp |= LVDS_VSYNC_POLARITY;
|
2012-03-28 21:11:26 +00:00
|
|
|
I915_WRITE(LVDS, temp);
|
|
|
|
}
|
|
|
|
|
2012-06-15 18:55:13 +00:00
|
|
|
static void vlv_update_pll(struct drm_crtc *crtc,
|
|
|
|
struct drm_display_mode *mode,
|
|
|
|
struct drm_display_mode *adjusted_mode,
|
|
|
|
intel_clock_t *clock, intel_clock_t *reduced_clock,
|
|
|
|
int refclk, int num_connectors)
|
|
|
|
{
|
|
|
|
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 dpll, mdiv, pdiv;
|
|
|
|
u32 bestn, bestm1, bestm2, bestp1, bestp2;
|
|
|
|
bool is_hdmi;
|
|
|
|
|
|
|
|
is_hdmi = intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI);
|
|
|
|
|
|
|
|
bestn = clock->n;
|
|
|
|
bestm1 = clock->m1;
|
|
|
|
bestm2 = clock->m2;
|
|
|
|
bestp1 = clock->p1;
|
|
|
|
bestp2 = clock->p2;
|
|
|
|
|
|
|
|
/* Enable DPIO clock input */
|
|
|
|
dpll = DPLL_EXT_BUFFER_ENABLE_VLV | DPLL_REFA_CLK_ENABLE_VLV |
|
|
|
|
DPLL_VGA_MODE_DIS | DPLL_INTEGRATED_CLOCK_VLV;
|
|
|
|
I915_WRITE(DPLL(pipe), dpll);
|
|
|
|
POSTING_READ(DPLL(pipe));
|
|
|
|
|
|
|
|
mdiv = ((bestm1 << DPIO_M1DIV_SHIFT) | (bestm2 & DPIO_M2DIV_MASK));
|
|
|
|
mdiv |= ((bestp1 << DPIO_P1_SHIFT) | (bestp2 << DPIO_P2_SHIFT));
|
|
|
|
mdiv |= ((bestn << DPIO_N_SHIFT));
|
|
|
|
mdiv |= (1 << DPIO_POST_DIV_SHIFT);
|
|
|
|
mdiv |= (1 << DPIO_K_SHIFT);
|
|
|
|
mdiv |= DPIO_ENABLE_CALIBRATION;
|
|
|
|
intel_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv);
|
|
|
|
|
|
|
|
intel_dpio_write(dev_priv, DPIO_CORE_CLK(pipe), 0x01000000);
|
|
|
|
|
|
|
|
pdiv = DPIO_REFSEL_OVERRIDE | (5 << DPIO_PLL_MODESEL_SHIFT) |
|
|
|
|
(3 << DPIO_BIAS_CURRENT_CTL_SHIFT) | (1<<20) |
|
|
|
|
(8 << DPIO_DRIVER_CTL_SHIFT) | (5 << DPIO_CLK_BIAS_CTL_SHIFT);
|
|
|
|
intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), pdiv);
|
|
|
|
|
|
|
|
intel_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), 0x009f0051);
|
|
|
|
|
|
|
|
dpll |= DPLL_VCO_ENABLE;
|
|
|
|
I915_WRITE(DPLL(pipe), dpll);
|
|
|
|
POSTING_READ(DPLL(pipe));
|
|
|
|
if (wait_for(((I915_READ(DPLL(pipe)) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1))
|
|
|
|
DRM_ERROR("DPLL %d failed to lock\n", pipe);
|
|
|
|
|
|
|
|
if (is_hdmi) {
|
|
|
|
u32 temp = intel_mode_get_pixel_multiplier(adjusted_mode);
|
|
|
|
|
|
|
|
if (temp > 1)
|
|
|
|
temp = (temp - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT;
|
|
|
|
else
|
|
|
|
temp = 0;
|
|
|
|
|
|
|
|
I915_WRITE(DPLL_MD(pipe), temp);
|
|
|
|
POSTING_READ(DPLL_MD(pipe));
|
|
|
|
}
|
|
|
|
|
|
|
|
intel_dpio_write(dev_priv, DPIO_FASTCLK_DISABLE, 0x641); /* ??? */
|
|
|
|
}
|
|
|
|
|
2012-03-28 21:12:16 +00:00
|
|
|
static void i9xx_update_pll(struct drm_crtc *crtc,
|
|
|
|
struct drm_display_mode *mode,
|
|
|
|
struct drm_display_mode *adjusted_mode,
|
|
|
|
intel_clock_t *clock, intel_clock_t *reduced_clock,
|
|
|
|
int num_connectors)
|
|
|
|
{
|
|
|
|
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 dpll;
|
|
|
|
bool is_sdvo;
|
|
|
|
|
|
|
|
is_sdvo = intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO) ||
|
|
|
|
intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI);
|
|
|
|
|
|
|
|
dpll = DPLL_VGA_MODE_DIS;
|
|
|
|
|
|
|
|
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
|
|
|
|
dpll |= DPLLB_MODE_LVDS;
|
|
|
|
else
|
|
|
|
dpll |= DPLLB_MODE_DAC_SERIAL;
|
|
|
|
if (is_sdvo) {
|
|
|
|
int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
|
|
|
|
if (pixel_multiplier > 1) {
|
|
|
|
if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
|
|
|
|
dpll |= (pixel_multiplier - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
|
|
|
|
}
|
|
|
|
dpll |= DPLL_DVO_HIGH_SPEED;
|
|
|
|
}
|
|
|
|
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT))
|
|
|
|
dpll |= DPLL_DVO_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 (is_sdvo && intel_pipe_has_type(crtc, INTEL_OUTPUT_TVOUT))
|
|
|
|
dpll |= PLL_REF_INPUT_TVCLKINBC;
|
|
|
|
else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_TVOUT))
|
|
|
|
/* XXX: just matching BIOS for now */
|
|
|
|
/* dpll |= PLL_REF_INPUT_TVCLKINBC; */
|
|
|
|
dpll |= 3;
|
|
|
|
else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
|
|
|
|
intel_panel_use_ssc(dev_priv) && num_connectors < 2)
|
|
|
|
dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
|
|
|
|
else
|
|
|
|
dpll |= PLL_REF_INPUT_DREFCLK;
|
|
|
|
|
|
|
|
dpll |= DPLL_VCO_ENABLE;
|
|
|
|
I915_WRITE(DPLL(pipe), dpll & ~DPLL_VCO_ENABLE);
|
|
|
|
POSTING_READ(DPLL(pipe));
|
|
|
|
udelay(150);
|
|
|
|
|
|
|
|
/* The LVDS pin pair needs to be on before the DPLLs are enabled.
|
|
|
|
* This is an exception to the general rule that mode_set doesn't turn
|
|
|
|
* things on.
|
|
|
|
*/
|
|
|
|
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
|
|
|
|
intel_update_lvds(crtc, clock, adjusted_mode);
|
|
|
|
|
|
|
|
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT))
|
|
|
|
intel_dp_set_m_n(crtc, mode, adjusted_mode);
|
|
|
|
|
|
|
|
I915_WRITE(DPLL(pipe), dpll);
|
|
|
|
|
|
|
|
/* Wait for the clocks to stabilize. */
|
|
|
|
POSTING_READ(DPLL(pipe));
|
|
|
|
udelay(150);
|
|
|
|
|
|
|
|
if (INTEL_INFO(dev)->gen >= 4) {
|
|
|
|
u32 temp = 0;
|
|
|
|
if (is_sdvo) {
|
|
|
|
temp = intel_mode_get_pixel_multiplier(adjusted_mode);
|
|
|
|
if (temp > 1)
|
|
|
|
temp = (temp - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT;
|
|
|
|
else
|
|
|
|
temp = 0;
|
|
|
|
}
|
|
|
|
I915_WRITE(DPLL_MD(pipe), temp);
|
|
|
|
} else {
|
|
|
|
/* The pixel multiplier can only be updated once the
|
|
|
|
* DPLL is enabled and the clocks are stable.
|
|
|
|
*
|
|
|
|
* So write it again.
|
|
|
|
*/
|
|
|
|
I915_WRITE(DPLL(pipe), dpll);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void i8xx_update_pll(struct drm_crtc *crtc,
|
|
|
|
struct drm_display_mode *adjusted_mode,
|
|
|
|
intel_clock_t *clock,
|
|
|
|
int num_connectors)
|
|
|
|
{
|
|
|
|
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 dpll;
|
|
|
|
|
|
|
|
dpll = DPLL_VGA_MODE_DIS;
|
|
|
|
|
|
|
|
if (intel_pipe_has_type(crtc, 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 (intel_pipe_has_type(crtc, INTEL_OUTPUT_TVOUT))
|
|
|
|
/* XXX: just matching BIOS for now */
|
|
|
|
/* dpll |= PLL_REF_INPUT_TVCLKINBC; */
|
|
|
|
dpll |= 3;
|
|
|
|
else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
|
|
|
|
intel_panel_use_ssc(dev_priv) && num_connectors < 2)
|
|
|
|
dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
|
|
|
|
else
|
|
|
|
dpll |= PLL_REF_INPUT_DREFCLK;
|
|
|
|
|
|
|
|
dpll |= DPLL_VCO_ENABLE;
|
|
|
|
I915_WRITE(DPLL(pipe), dpll & ~DPLL_VCO_ENABLE);
|
|
|
|
POSTING_READ(DPLL(pipe));
|
|
|
|
udelay(150);
|
|
|
|
|
|
|
|
/* The LVDS pin pair needs to be on before the DPLLs are enabled.
|
|
|
|
* This is an exception to the general rule that mode_set doesn't turn
|
|
|
|
* things on.
|
|
|
|
*/
|
|
|
|
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
|
|
|
|
intel_update_lvds(crtc, clock, adjusted_mode);
|
|
|
|
|
2012-09-11 10:37:55 +00:00
|
|
|
I915_WRITE(DPLL(pipe), dpll);
|
|
|
|
|
|
|
|
/* Wait for the clocks to stabilize. */
|
|
|
|
POSTING_READ(DPLL(pipe));
|
|
|
|
udelay(150);
|
|
|
|
|
2012-03-28 21:12:16 +00:00
|
|
|
/* The pixel multiplier can only be updated once the
|
|
|
|
* DPLL is enabled and the clocks are stable.
|
|
|
|
*
|
|
|
|
* So write it again.
|
|
|
|
*/
|
|
|
|
I915_WRITE(DPLL(pipe), dpll);
|
|
|
|
}
|
|
|
|
|
2011-03-30 20:01:02 +00:00
|
|
|
static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
|
|
|
|
struct drm_display_mode *mode,
|
|
|
|
struct drm_display_mode *adjusted_mode,
|
|
|
|
int x, int y,
|
drm/i915: push crtc->fb update into pipe_set_base
Passing in the old fb, having overwritten the current fb, leads to
some neatly convoluted code. It's much simpler if we defer the
crtc->fb update to the place that updates the hw, in pipe_set_base.
This way we also don't need to restore anything in case something
fails - we only update crtc->fb once things have succeeded.
The real reason for this change is that now we keep the old fb
assigned to crtc->fb, which allows us to finally move the crtc disable
case into the common low-level set_mode function in the next patch.
Also don't clobber crtc->x and crtc->y, we neatly pass these down the
callchain already. Unfortunately we can't do the same with crtc->mode,
because that one is being used in the mode_set callbacks.
v2: Don't restore the drm_crtc object any more on failed modesets,
since we've lose an fb reference otherwise. Also (and this is the
reason this has been found), this totally confused the modeset state
tracking, since it clobbers crtc->enabled. Issue reported by Paulo
Zanoni.
v3: Rip out the entire crtc saving into struct intel_set_config, not
just the restoring part.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-05 20:51:56 +00:00
|
|
|
struct drm_framebuffer *fb)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
{
|
|
|
|
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;
|
2009-09-10 22:28:06 +00:00
|
|
|
int plane = intel_crtc->plane;
|
2010-03-25 18:48:48 +00:00
|
|
|
int refclk, num_connectors = 0;
|
2009-08-17 20:31:43 +00:00
|
|
|
intel_clock_t clock, reduced_clock;
|
2012-03-28 21:12:16 +00:00
|
|
|
u32 dspcntr, pipeconf, vsyncshift;
|
|
|
|
bool ok, has_reduced_clock = false, is_sdvo = false;
|
|
|
|
bool is_lvds = false, is_tv = false, is_dp = false;
|
2010-09-11 12:48:45 +00:00
|
|
|
struct intel_encoder *encoder;
|
2009-03-18 12:13:27 +00:00
|
|
|
const intel_limit_t *limit;
|
2009-02-11 13:25:09 +00:00
|
|
|
int ret;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2012-07-05 07:50:24 +00:00
|
|
|
for_each_encoder_on_crtc(dev, crtc, encoder) {
|
2010-09-11 12:48:45 +00:00
|
|
|
switch (encoder->type) {
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
case INTEL_OUTPUT_LVDS:
|
|
|
|
is_lvds = true;
|
|
|
|
break;
|
|
|
|
case INTEL_OUTPUT_SDVO:
|
2009-01-02 21:33:00 +00:00
|
|
|
case INTEL_OUTPUT_HDMI:
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
is_sdvo = true;
|
2010-09-11 12:48:45 +00:00
|
|
|
if (encoder->needs_tv_clock)
|
2009-02-02 23:11:52 +00:00
|
|
|
is_tv = true;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
break;
|
|
|
|
case INTEL_OUTPUT_TVOUT:
|
|
|
|
is_tv = true;
|
|
|
|
break;
|
2009-04-07 23:16:42 +00:00
|
|
|
case INTEL_OUTPUT_DISPLAYPORT:
|
|
|
|
is_dp = true;
|
|
|
|
break;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
2009-02-14 01:56:52 +00:00
|
|
|
|
2010-03-25 18:48:48 +00:00
|
|
|
num_connectors++;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
2011-12-15 20:30:36 +00:00
|
|
|
refclk = i9xx_get_refclk(crtc, num_connectors);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2009-03-18 12:13:27 +00:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
2010-12-14 20:04:54 +00:00
|
|
|
limit = intel_limit(crtc, refclk);
|
2012-01-10 23:09:36 +00:00
|
|
|
ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, NULL,
|
|
|
|
&clock);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
if (!ok) {
|
|
|
|
DRM_ERROR("Couldn't find PLL settings for mode!\n");
|
2009-02-11 13:25:09 +00:00
|
|
|
return -EINVAL;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
2010-07-09 07:45:04 +00:00
|
|
|
/* Ensure that the cursor is valid for the new mode before changing... */
|
2010-09-13 12:54:26 +00:00
|
|
|
intel_crtc_update_cursor(crtc, true);
|
2010-07-09 07:45:04 +00:00
|
|
|
|
2010-01-06 14:05:56 +00:00
|
|
|
if (is_lvds && dev_priv->lvds_downclock_avail) {
|
2012-01-10 23:09:36 +00:00
|
|
|
/*
|
|
|
|
* Ensure we match the reduced clock's P to the target clock.
|
|
|
|
* If the clocks don't match, we can't switch the display clock
|
|
|
|
* by using the FP0/FP1. In such case we will disable the LVDS
|
|
|
|
* downclock feature.
|
|
|
|
*/
|
2010-01-06 14:05:56 +00:00
|
|
|
has_reduced_clock = limit->find_pll(limit, crtc,
|
2010-09-11 12:48:45 +00:00
|
|
|
dev_priv->lvds_downclock,
|
|
|
|
refclk,
|
2012-01-10 23:09:36 +00:00
|
|
|
&clock,
|
2010-09-11 12:48:45 +00:00
|
|
|
&reduced_clock);
|
2009-03-24 06:02:43 +00:00
|
|
|
}
|
|
|
|
|
2011-12-15 20:30:36 +00:00
|
|
|
if (is_sdvo && is_tv)
|
|
|
|
i9xx_adjust_sdvo_tv_clock(adjusted_mode, &clock);
|
2009-03-24 06:02:43 +00:00
|
|
|
|
2011-12-15 20:30:37 +00:00
|
|
|
i9xx_update_pll_dividers(crtc, &clock, has_reduced_clock ?
|
|
|
|
&reduced_clock : NULL);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2012-03-28 21:12:16 +00:00
|
|
|
if (IS_GEN2(dev))
|
|
|
|
i8xx_update_pll(crtc, adjusted_mode, &clock, num_connectors);
|
2012-06-15 18:55:13 +00:00
|
|
|
else if (IS_VALLEYVIEW(dev))
|
|
|
|
vlv_update_pll(crtc, mode,adjusted_mode, &clock, NULL,
|
|
|
|
refclk, num_connectors);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
else
|
2012-03-28 21:12:16 +00:00
|
|
|
i9xx_update_pll(crtc, mode, adjusted_mode, &clock,
|
|
|
|
has_reduced_clock ? &reduced_clock : NULL,
|
|
|
|
num_connectors);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
|
|
|
/* setup pipeconf */
|
2010-09-11 12:48:45 +00:00
|
|
|
pipeconf = I915_READ(PIPECONF(pipe));
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
|
|
|
/* Set up the display plane register */
|
|
|
|
dspcntr = DISPPLANE_GAMMA_ENABLE;
|
|
|
|
|
2011-03-30 20:01:04 +00:00
|
|
|
if (pipe == 0)
|
|
|
|
dspcntr &= ~DISPPLANE_SEL_PIPE_MASK;
|
|
|
|
else
|
|
|
|
dspcntr |= DISPPLANE_SEL_PIPE_B;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2010-09-16 23:32:17 +00:00
|
|
|
if (pipe == 0 && INTEL_INFO(dev)->gen < 4) {
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
/* Enable pixel doubling when the dot clock is > 90% of the (display)
|
|
|
|
* core speed.
|
|
|
|
*
|
|
|
|
* XXX: No double-wide on 915GM pipe B. Is that the only reason for the
|
|
|
|
* pipe == 0 check?
|
|
|
|
*/
|
2009-09-21 17:42:27 +00:00
|
|
|
if (mode->clock >
|
|
|
|
dev_priv->display.get_display_clock_speed(dev) * 9 / 10)
|
2010-09-11 12:48:45 +00:00
|
|
|
pipeconf |= PIPECONF_DOUBLE_WIDE;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
else
|
2010-09-11 12:48:45 +00:00
|
|
|
pipeconf &= ~PIPECONF_DOUBLE_WIDE;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
2011-12-13 23:41:00 +00:00
|
|
|
/* default to 8bpc */
|
|
|
|
pipeconf &= ~(PIPECONF_BPP_MASK | PIPECONF_DITHER_EN);
|
|
|
|
if (is_dp) {
|
2012-09-26 15:43:10 +00:00
|
|
|
if (adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC) {
|
2011-12-13 23:41:00 +00:00
|
|
|
pipeconf |= PIPECONF_BPP_6 |
|
|
|
|
PIPECONF_DITHER_EN |
|
|
|
|
PIPECONF_DITHER_TYPE_SP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-10-09 03:39:41 +00:00
|
|
|
DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
drm_mode_debug_printmodeline(mode);
|
|
|
|
|
2011-12-15 20:30:37 +00:00
|
|
|
if (HAS_PIPE_CXSR(dev)) {
|
|
|
|
if (intel_crtc->lowfreq_avail) {
|
2009-10-09 03:39:41 +00:00
|
|
|
DRM_DEBUG_KMS("enabling CxSR downclocking\n");
|
2009-08-17 20:31:43 +00:00
|
|
|
pipeconf |= PIPECONF_CXSR_DOWNCLOCK;
|
2011-12-15 20:30:37 +00:00
|
|
|
} else {
|
2009-10-09 03:39:41 +00:00
|
|
|
DRM_DEBUG_KMS("disabling CxSR downclocking\n");
|
2009-08-17 20:31:43 +00:00
|
|
|
pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-08 21:53:38 +00:00
|
|
|
pipeconf &= ~PIPECONF_INTERLACE_MASK;
|
2012-01-28 13:49:23 +00:00
|
|
|
if (!IS_GEN2(dev) &&
|
|
|
|
adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
|
2010-05-25 16:41:46 +00:00
|
|
|
pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
|
|
|
|
/* the chip adds 2 halflines automatically */
|
|
|
|
adjusted_mode->crtc_vtotal -= 1;
|
|
|
|
adjusted_mode->crtc_vblank_end -= 1;
|
2012-01-28 13:49:24 +00:00
|
|
|
vsyncshift = adjusted_mode->crtc_hsync_start
|
|
|
|
- adjusted_mode->crtc_htotal/2;
|
|
|
|
} else {
|
2012-02-08 21:53:38 +00:00
|
|
|
pipeconf |= PIPECONF_PROGRESSIVE;
|
2012-01-28 13:49:24 +00:00
|
|
|
vsyncshift = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!IS_GEN3(dev))
|
|
|
|
I915_WRITE(VSYNCSHIFT(pipe), vsyncshift);
|
2010-05-25 16:41:46 +00:00
|
|
|
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(HTOTAL(pipe),
|
|
|
|
(adjusted_mode->crtc_hdisplay - 1) |
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
((adjusted_mode->crtc_htotal - 1) << 16));
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(HBLANK(pipe),
|
|
|
|
(adjusted_mode->crtc_hblank_start - 1) |
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
((adjusted_mode->crtc_hblank_end - 1) << 16));
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(HSYNC(pipe),
|
|
|
|
(adjusted_mode->crtc_hsync_start - 1) |
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
((adjusted_mode->crtc_hsync_end - 1) << 16));
|
2010-09-11 12:48:45 +00:00
|
|
|
|
|
|
|
I915_WRITE(VTOTAL(pipe),
|
|
|
|
(adjusted_mode->crtc_vdisplay - 1) |
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
((adjusted_mode->crtc_vtotal - 1) << 16));
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(VBLANK(pipe),
|
|
|
|
(adjusted_mode->crtc_vblank_start - 1) |
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
((adjusted_mode->crtc_vblank_end - 1) << 16));
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(VSYNC(pipe),
|
|
|
|
(adjusted_mode->crtc_vsync_start - 1) |
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
((adjusted_mode->crtc_vsync_end - 1) << 16));
|
2010-09-11 12:48:45 +00:00
|
|
|
|
|
|
|
/* pipesrc and dspsize control the size that is scaled from,
|
|
|
|
* which should always be the user's requested size.
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
*/
|
2011-03-30 20:01:04 +00:00
|
|
|
I915_WRITE(DSPSIZE(plane),
|
|
|
|
((mode->vdisplay - 1) << 16) |
|
|
|
|
(mode->hdisplay - 1));
|
|
|
|
I915_WRITE(DSPPOS(plane), 0);
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(PIPESRC(pipe),
|
|
|
|
((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
|
2009-06-05 07:38:42 +00:00
|
|
|
|
2011-03-30 20:01:02 +00:00
|
|
|
I915_WRITE(PIPECONF(pipe), pipeconf);
|
|
|
|
POSTING_READ(PIPECONF(pipe));
|
2011-03-30 20:01:04 +00:00
|
|
|
intel_enable_pipe(dev_priv, pipe, false);
|
2011-03-30 20:01:02 +00:00
|
|
|
|
|
|
|
intel_wait_for_vblank(dev, pipe);
|
|
|
|
|
|
|
|
I915_WRITE(DSPCNTR(plane), dspcntr);
|
|
|
|
POSTING_READ(DSPCNTR(plane));
|
|
|
|
|
drm/i915: push crtc->fb update into pipe_set_base
Passing in the old fb, having overwritten the current fb, leads to
some neatly convoluted code. It's much simpler if we defer the
crtc->fb update to the place that updates the hw, in pipe_set_base.
This way we also don't need to restore anything in case something
fails - we only update crtc->fb once things have succeeded.
The real reason for this change is that now we keep the old fb
assigned to crtc->fb, which allows us to finally move the crtc disable
case into the common low-level set_mode function in the next patch.
Also don't clobber crtc->x and crtc->y, we neatly pass these down the
callchain already. Unfortunately we can't do the same with crtc->mode,
because that one is being used in the mode_set callbacks.
v2: Don't restore the drm_crtc object any more on failed modesets,
since we've lose an fb reference otherwise. Also (and this is the
reason this has been found), this totally confused the modeset state
tracking, since it clobbers crtc->enabled. Issue reported by Paulo
Zanoni.
v3: Rip out the entire crtc saving into struct intel_set_config, not
just the restoring part.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-05 20:51:56 +00:00
|
|
|
ret = intel_pipe_set_base(crtc, x, y, fb);
|
2011-03-30 20:01:02 +00:00
|
|
|
|
|
|
|
intel_update_watermarks(dev);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-09-27 05:24:57 +00:00
|
|
|
/*
|
|
|
|
* Initialize reference clocks when the driver loads
|
|
|
|
*/
|
|
|
|
void ironlake_init_pch_refclk(struct drm_device *dev)
|
2011-08-03 19:59:20 +00:00
|
|
|
{
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
struct drm_mode_config *mode_config = &dev->mode_config;
|
|
|
|
struct intel_encoder *encoder;
|
|
|
|
u32 temp;
|
|
|
|
bool has_lvds = false;
|
2011-09-22 19:01:57 +00:00
|
|
|
bool has_cpu_edp = false;
|
|
|
|
bool has_pch_edp = false;
|
|
|
|
bool has_panel = false;
|
2011-09-26 21:29:12 +00:00
|
|
|
bool has_ck505 = false;
|
|
|
|
bool can_ssc = false;
|
2011-08-03 19:59:20 +00:00
|
|
|
|
|
|
|
/* We need to take the global config into account */
|
2011-09-22 19:01:57 +00:00
|
|
|
list_for_each_entry(encoder, &mode_config->encoder_list,
|
|
|
|
base.head) {
|
|
|
|
switch (encoder->type) {
|
|
|
|
case INTEL_OUTPUT_LVDS:
|
|
|
|
has_panel = true;
|
|
|
|
has_lvds = true;
|
|
|
|
break;
|
|
|
|
case INTEL_OUTPUT_EDP:
|
|
|
|
has_panel = true;
|
|
|
|
if (intel_encoder_is_pch_edp(&encoder->base))
|
|
|
|
has_pch_edp = true;
|
|
|
|
else
|
|
|
|
has_cpu_edp = true;
|
|
|
|
break;
|
2011-08-03 19:59:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-26 21:29:12 +00:00
|
|
|
if (HAS_PCH_IBX(dev)) {
|
|
|
|
has_ck505 = dev_priv->display_clock_mode;
|
|
|
|
can_ssc = has_ck505;
|
|
|
|
} else {
|
|
|
|
has_ck505 = false;
|
|
|
|
can_ssc = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
DRM_DEBUG_KMS("has_panel %d has_lvds %d has_pch_edp %d has_cpu_edp %d has_ck505 %d\n",
|
|
|
|
has_panel, has_lvds, has_pch_edp, has_cpu_edp,
|
|
|
|
has_ck505);
|
2011-08-03 19:59:20 +00:00
|
|
|
|
|
|
|
/* 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.
|
|
|
|
*/
|
|
|
|
temp = I915_READ(PCH_DREF_CONTROL);
|
|
|
|
/* Always enable nonspread source */
|
|
|
|
temp &= ~DREF_NONSPREAD_SOURCE_MASK;
|
|
|
|
|
2011-09-26 21:29:12 +00:00
|
|
|
if (has_ck505)
|
|
|
|
temp |= DREF_NONSPREAD_CK505_ENABLE;
|
|
|
|
else
|
|
|
|
temp |= DREF_NONSPREAD_SOURCE_ENABLE;
|
2011-08-03 19:59:20 +00:00
|
|
|
|
2011-09-22 19:01:57 +00:00
|
|
|
if (has_panel) {
|
|
|
|
temp &= ~DREF_SSC_SOURCE_MASK;
|
|
|
|
temp |= DREF_SSC_SOURCE_ENABLE;
|
2011-08-03 19:59:20 +00:00
|
|
|
|
2011-09-22 19:01:57 +00:00
|
|
|
/* SSC must be turned on before enabling the CPU output */
|
2011-09-26 21:29:12 +00:00
|
|
|
if (intel_panel_use_ssc(dev_priv) && can_ssc) {
|
2011-09-22 19:01:57 +00:00
|
|
|
DRM_DEBUG_KMS("Using SSC on panel\n");
|
2011-08-03 19:59:20 +00:00
|
|
|
temp |= DREF_SSC1_ENABLE;
|
2012-03-30 20:14:05 +00:00
|
|
|
} else
|
|
|
|
temp &= ~DREF_SSC1_ENABLE;
|
2011-09-22 19:01:57 +00:00
|
|
|
|
|
|
|
/* Get SSC going before enabling the outputs */
|
|
|
|
I915_WRITE(PCH_DREF_CONTROL, temp);
|
|
|
|
POSTING_READ(PCH_DREF_CONTROL);
|
|
|
|
udelay(200);
|
|
|
|
|
2011-08-03 19:59:20 +00:00
|
|
|
temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
|
|
|
|
|
|
|
|
/* Enable CPU source on CPU attached eDP */
|
2011-09-22 19:01:57 +00:00
|
|
|
if (has_cpu_edp) {
|
2011-09-26 21:29:12 +00:00
|
|
|
if (intel_panel_use_ssc(dev_priv) && can_ssc) {
|
2011-09-22 19:01:57 +00:00
|
|
|
DRM_DEBUG_KMS("Using SSC on eDP\n");
|
2011-08-03 19:59:20 +00:00
|
|
|
temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD;
|
2011-09-22 19:01:57 +00:00
|
|
|
}
|
2011-08-03 19:59:20 +00:00
|
|
|
else
|
|
|
|
temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
|
2011-09-22 19:01:57 +00:00
|
|
|
} else
|
|
|
|
temp |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
|
|
|
|
|
|
|
|
I915_WRITE(PCH_DREF_CONTROL, temp);
|
|
|
|
POSTING_READ(PCH_DREF_CONTROL);
|
|
|
|
udelay(200);
|
|
|
|
} else {
|
|
|
|
DRM_DEBUG_KMS("Disabling SSC entirely\n");
|
|
|
|
|
|
|
|
temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
|
|
|
|
|
|
|
|
/* Turn off CPU output */
|
|
|
|
temp |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
|
|
|
|
|
|
|
|
I915_WRITE(PCH_DREF_CONTROL, temp);
|
|
|
|
POSTING_READ(PCH_DREF_CONTROL);
|
|
|
|
udelay(200);
|
|
|
|
|
|
|
|
/* Turn off the SSC source */
|
|
|
|
temp &= ~DREF_SSC_SOURCE_MASK;
|
|
|
|
temp |= DREF_SSC_SOURCE_DISABLE;
|
|
|
|
|
|
|
|
/* Turn off SSC1 */
|
|
|
|
temp &= ~ DREF_SSC1_ENABLE;
|
|
|
|
|
2011-08-03 19:59:20 +00:00
|
|
|
I915_WRITE(PCH_DREF_CONTROL, temp);
|
|
|
|
POSTING_READ(PCH_DREF_CONTROL);
|
|
|
|
udelay(200);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-02 20:03:05 +00:00
|
|
|
static int ironlake_get_refclk(struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
struct intel_encoder *encoder;
|
|
|
|
struct intel_encoder *edp_encoder = NULL;
|
|
|
|
int num_connectors = 0;
|
|
|
|
bool is_lvds = false;
|
|
|
|
|
2012-07-05 07:50:24 +00:00
|
|
|
for_each_encoder_on_crtc(dev, crtc, encoder) {
|
2011-09-02 20:03:05 +00:00
|
|
|
switch (encoder->type) {
|
|
|
|
case INTEL_OUTPUT_LVDS:
|
|
|
|
is_lvds = true;
|
|
|
|
break;
|
|
|
|
case INTEL_OUTPUT_EDP:
|
|
|
|
edp_encoder = encoder;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
num_connectors++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) {
|
|
|
|
DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n",
|
|
|
|
dev_priv->lvds_ssc_freq);
|
|
|
|
return dev_priv->lvds_ssc_freq * 1000;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 120000;
|
|
|
|
}
|
|
|
|
|
2012-09-12 13:06:29 +00:00
|
|
|
static void ironlake_set_pipeconf(struct drm_crtc *crtc,
|
|
|
|
struct drm_display_mode *adjusted_mode,
|
|
|
|
bool dither)
|
|
|
|
{
|
|
|
|
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 = I915_READ(PIPECONF(pipe));
|
|
|
|
|
|
|
|
val &= ~PIPE_BPC_MASK;
|
|
|
|
switch (intel_crtc->bpp) {
|
|
|
|
case 18:
|
|
|
|
val |= PIPE_6BPC;
|
|
|
|
break;
|
|
|
|
case 24:
|
|
|
|
val |= PIPE_8BPC;
|
|
|
|
break;
|
|
|
|
case 30:
|
|
|
|
val |= PIPE_10BPC;
|
|
|
|
break;
|
|
|
|
case 36:
|
|
|
|
val |= PIPE_12BPC;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
val |= PIPE_8BPC;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
val &= ~(PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_MASK);
|
|
|
|
if (dither)
|
|
|
|
val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
|
|
|
|
|
|
|
|
val &= ~PIPECONF_INTERLACE_MASK;
|
|
|
|
if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
|
|
|
|
val |= PIPECONF_INTERLACED_ILK;
|
|
|
|
else
|
|
|
|
val |= PIPECONF_PROGRESSIVE;
|
|
|
|
|
|
|
|
I915_WRITE(PIPECONF(pipe), val);
|
|
|
|
POSTING_READ(PIPECONF(pipe));
|
|
|
|
}
|
|
|
|
|
2012-09-12 13:06:34 +00:00
|
|
|
static bool ironlake_compute_clocks(struct drm_crtc *crtc,
|
|
|
|
struct drm_display_mode *adjusted_mode,
|
|
|
|
intel_clock_t *clock,
|
|
|
|
bool *has_reduced_clock,
|
|
|
|
intel_clock_t *reduced_clock)
|
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
struct intel_encoder *intel_encoder;
|
|
|
|
int refclk;
|
|
|
|
const intel_limit_t *limit;
|
|
|
|
bool ret, is_sdvo = false, is_tv = false, is_lvds = false;
|
|
|
|
|
|
|
|
for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
|
|
|
|
switch (intel_encoder->type) {
|
|
|
|
case INTEL_OUTPUT_LVDS:
|
|
|
|
is_lvds = true;
|
|
|
|
break;
|
|
|
|
case INTEL_OUTPUT_SDVO:
|
|
|
|
case INTEL_OUTPUT_HDMI:
|
|
|
|
is_sdvo = true;
|
|
|
|
if (intel_encoder->needs_tv_clock)
|
|
|
|
is_tv = true;
|
|
|
|
break;
|
|
|
|
case INTEL_OUTPUT_TVOUT:
|
|
|
|
is_tv = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
refclk = ironlake_get_refclk(crtc);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
limit = intel_limit(crtc, refclk);
|
|
|
|
ret = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, NULL,
|
|
|
|
clock);
|
|
|
|
if (!ret)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (is_lvds && dev_priv->lvds_downclock_avail) {
|
|
|
|
/*
|
|
|
|
* Ensure we match the reduced clock's P to the target clock.
|
|
|
|
* If the clocks don't match, we can't switch the display clock
|
|
|
|
* by using the FP0/FP1. In such case we will disable the LVDS
|
|
|
|
* downclock feature.
|
|
|
|
*/
|
|
|
|
*has_reduced_clock = limit->find_pll(limit, crtc,
|
|
|
|
dev_priv->lvds_downclock,
|
|
|
|
refclk,
|
|
|
|
clock,
|
|
|
|
reduced_clock);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_sdvo && is_tv)
|
|
|
|
i9xx_adjust_sdvo_tv_clock(adjusted_mode, clock);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2011-03-30 20:01:02 +00:00
|
|
|
static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
|
|
|
|
struct drm_display_mode *mode,
|
|
|
|
struct drm_display_mode *adjusted_mode,
|
|
|
|
int x, int y,
|
drm/i915: push crtc->fb update into pipe_set_base
Passing in the old fb, having overwritten the current fb, leads to
some neatly convoluted code. It's much simpler if we defer the
crtc->fb update to the place that updates the hw, in pipe_set_base.
This way we also don't need to restore anything in case something
fails - we only update crtc->fb once things have succeeded.
The real reason for this change is that now we keep the old fb
assigned to crtc->fb, which allows us to finally move the crtc disable
case into the common low-level set_mode function in the next patch.
Also don't clobber crtc->x and crtc->y, we neatly pass these down the
callchain already. Unfortunately we can't do the same with crtc->mode,
because that one is being used in the mode_set callbacks.
v2: Don't restore the drm_crtc object any more on failed modesets,
since we've lose an fb reference otherwise. Also (and this is the
reason this has been found), this totally confused the modeset state
tracking, since it clobbers crtc->enabled. Issue reported by Paulo
Zanoni.
v3: Rip out the entire crtc saving into struct intel_set_config, not
just the restoring part.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-05 20:51:56 +00:00
|
|
|
struct drm_framebuffer *fb)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
{
|
|
|
|
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;
|
2009-09-10 22:28:06 +00:00
|
|
|
int plane = intel_crtc->plane;
|
2012-09-12 13:06:34 +00:00
|
|
|
int num_connectors = 0;
|
2009-08-17 20:31:43 +00:00
|
|
|
intel_clock_t clock, reduced_clock;
|
2012-09-12 13:06:32 +00:00
|
|
|
u32 dpll, fp = 0, fp2 = 0;
|
2011-03-30 20:01:08 +00:00
|
|
|
bool ok, has_reduced_clock = false, is_sdvo = false;
|
2009-04-07 23:16:42 +00:00
|
|
|
bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
|
2012-04-10 18:58:03 +00:00
|
|
|
struct intel_encoder *encoder, *edp_encoder = NULL;
|
2009-02-11 13:25:09 +00:00
|
|
|
int ret;
|
2009-06-05 07:38:42 +00:00
|
|
|
struct fdi_m_n m_n = {0};
|
2011-03-30 20:01:09 +00:00
|
|
|
u32 temp;
|
2011-06-24 19:19:22 +00:00
|
|
|
int target_clock, pixel_multiplier, lane, link_bw, factor;
|
|
|
|
unsigned int pipe_bpp;
|
|
|
|
bool dither;
|
2012-04-10 18:58:03 +00:00
|
|
|
bool is_cpu_edp = false, is_pch_edp = false;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2012-07-05 07:50:24 +00:00
|
|
|
for_each_encoder_on_crtc(dev, crtc, encoder) {
|
2010-09-11 12:48:45 +00:00
|
|
|
switch (encoder->type) {
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
case INTEL_OUTPUT_LVDS:
|
|
|
|
is_lvds = true;
|
|
|
|
break;
|
|
|
|
case INTEL_OUTPUT_SDVO:
|
2009-01-02 21:33:00 +00:00
|
|
|
case INTEL_OUTPUT_HDMI:
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
is_sdvo = true;
|
2010-09-11 12:48:45 +00:00
|
|
|
if (encoder->needs_tv_clock)
|
2009-02-02 23:11:52 +00:00
|
|
|
is_tv = true;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
break;
|
|
|
|
case INTEL_OUTPUT_TVOUT:
|
|
|
|
is_tv = true;
|
|
|
|
break;
|
|
|
|
case INTEL_OUTPUT_ANALOG:
|
|
|
|
is_crt = true;
|
|
|
|
break;
|
2009-04-07 23:16:42 +00:00
|
|
|
case INTEL_OUTPUT_DISPLAYPORT:
|
|
|
|
is_dp = true;
|
|
|
|
break;
|
2009-07-23 17:00:32 +00:00
|
|
|
case INTEL_OUTPUT_EDP:
|
2012-04-10 18:58:03 +00:00
|
|
|
is_dp = true;
|
|
|
|
if (intel_encoder_is_pch_edp(&encoder->base))
|
|
|
|
is_pch_edp = true;
|
|
|
|
else
|
|
|
|
is_cpu_edp = true;
|
|
|
|
edp_encoder = encoder;
|
2009-07-23 17:00:32 +00:00
|
|
|
break;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
2009-02-14 01:56:52 +00:00
|
|
|
|
2010-03-25 18:48:48 +00:00
|
|
|
num_connectors++;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
2012-09-12 13:06:34 +00:00
|
|
|
ok = ironlake_compute_clocks(crtc, adjusted_mode, &clock,
|
|
|
|
&has_reduced_clock, &reduced_clock);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
if (!ok) {
|
|
|
|
DRM_ERROR("Couldn't find PLL settings for mode!\n");
|
2009-02-11 13:25:09 +00:00
|
|
|
return -EINVAL;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
2010-07-09 07:45:04 +00:00
|
|
|
/* Ensure that the cursor is valid for the new mode before changing... */
|
2010-09-13 12:54:26 +00:00
|
|
|
intel_crtc_update_cursor(crtc, true);
|
2010-07-09 07:45:04 +00:00
|
|
|
|
2009-06-05 07:38:42 +00:00
|
|
|
/* FDI link */
|
2011-03-30 20:01:07 +00:00
|
|
|
pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
|
|
|
|
lane = 0;
|
|
|
|
/* CPU eDP doesn't require FDI link, so just set DP M/N
|
|
|
|
according to current link config */
|
2012-04-10 18:58:03 +00:00
|
|
|
if (is_cpu_edp) {
|
|
|
|
intel_edp_link_config(edp_encoder, &lane, &link_bw);
|
2011-03-30 20:01:07 +00:00
|
|
|
} else {
|
|
|
|
/* FDI is a binary signal running at ~2.7GHz, encoding
|
|
|
|
* each output octet as 10 bits. The actual frequency
|
|
|
|
* is stored as a divider into a 100MHz clock, and the
|
|
|
|
* mode pixel clock is stored in units of 1KHz.
|
|
|
|
* Hence the bw of each lane in terms of the mode signal
|
|
|
|
* is:
|
|
|
|
*/
|
|
|
|
link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10;
|
|
|
|
}
|
2009-09-25 08:01:28 +00:00
|
|
|
|
2012-06-04 16:39:19 +00:00
|
|
|
/* [e]DP over FDI requires target mode clock instead of link clock. */
|
|
|
|
if (edp_encoder)
|
|
|
|
target_clock = intel_edp_target_clock(edp_encoder, mode);
|
|
|
|
else if (is_dp)
|
|
|
|
target_clock = mode->clock;
|
|
|
|
else
|
|
|
|
target_clock = adjusted_mode->clock;
|
|
|
|
|
2011-03-30 20:01:07 +00:00
|
|
|
/* determine panel color depth */
|
2012-09-26 15:43:10 +00:00
|
|
|
dither = intel_choose_pipe_bpp_dither(crtc, fb, &pipe_bpp,
|
|
|
|
adjusted_mode);
|
2012-09-12 13:06:29 +00:00
|
|
|
if (is_lvds && dev_priv->lvds_dither)
|
|
|
|
dither = true;
|
|
|
|
|
|
|
|
if (pipe_bpp != 18 && pipe_bpp != 24 && pipe_bpp != 30 &&
|
|
|
|
pipe_bpp != 36) {
|
2011-07-28 19:55:14 +00:00
|
|
|
WARN(1, "intel_choose_pipe_bpp returned invalid value %d\n",
|
2012-09-12 13:06:29 +00:00
|
|
|
pipe_bpp);
|
2011-06-24 19:19:22 +00:00
|
|
|
pipe_bpp = 24;
|
2011-03-30 20:01:07 +00:00
|
|
|
}
|
2011-06-24 19:19:22 +00:00
|
|
|
intel_crtc->bpp = pipe_bpp;
|
|
|
|
|
2011-03-30 20:01:07 +00:00
|
|
|
if (!lane) {
|
|
|
|
/*
|
|
|
|
* Account for spread spectrum to avoid
|
|
|
|
* oversubscribing the link. Max center spread
|
|
|
|
* is 2.5%; use 5% for safety's sake.
|
|
|
|
*/
|
2011-06-24 19:19:22 +00:00
|
|
|
u32 bps = target_clock * intel_crtc->bpp * 21 / 20;
|
2011-03-30 20:01:07 +00:00
|
|
|
lane = bps / (link_bw * 8) + 1;
|
2009-07-23 17:00:31 +00:00
|
|
|
}
|
2009-06-05 07:38:42 +00:00
|
|
|
|
2011-03-30 20:01:07 +00:00
|
|
|
intel_crtc->fdi_lanes = lane;
|
|
|
|
|
|
|
|
if (pixel_multiplier > 1)
|
|
|
|
link_bw *= pixel_multiplier;
|
2011-06-24 19:19:22 +00:00
|
|
|
ironlake_compute_m_n(intel_crtc->bpp, lane, target_clock, link_bw,
|
|
|
|
&m_n);
|
2011-03-30 20:01:07 +00:00
|
|
|
|
2011-03-30 20:01:08 +00:00
|
|
|
fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
|
|
|
|
if (has_reduced_clock)
|
|
|
|
fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 |
|
|
|
|
reduced_clock.m2;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2010-12-03 21:35:48 +00:00
|
|
|
/* Enable autotuning of the PLL clock (if permissible) */
|
2011-03-30 20:01:07 +00:00
|
|
|
factor = 21;
|
|
|
|
if (is_lvds) {
|
|
|
|
if ((intel_panel_use_ssc(dev_priv) &&
|
|
|
|
dev_priv->lvds_ssc_freq == 100) ||
|
|
|
|
(I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP)
|
|
|
|
factor = 25;
|
|
|
|
} else if (is_sdvo && is_tv)
|
|
|
|
factor = 20;
|
2010-12-03 21:35:48 +00:00
|
|
|
|
2011-07-28 21:50:30 +00:00
|
|
|
if (clock.m < factor * clock.n)
|
2011-03-30 20:01:07 +00:00
|
|
|
fp |= FP_CB_TUNE;
|
2009-06-05 07:38:42 +00:00
|
|
|
|
2010-09-11 12:48:45 +00:00
|
|
|
dpll = 0;
|
2009-06-05 07:38:42 +00:00
|
|
|
|
2011-03-30 20:01:08 +00:00
|
|
|
if (is_lvds)
|
|
|
|
dpll |= DPLLB_MODE_LVDS;
|
|
|
|
else
|
|
|
|
dpll |= DPLLB_MODE_DAC_SERIAL;
|
|
|
|
if (is_sdvo) {
|
|
|
|
int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
|
|
|
|
if (pixel_multiplier > 1) {
|
|
|
|
dpll |= (pixel_multiplier - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
2011-03-30 20:01:08 +00:00
|
|
|
dpll |= DPLL_DVO_HIGH_SPEED;
|
|
|
|
}
|
2012-04-10 18:58:03 +00:00
|
|
|
if (is_dp && !is_cpu_edp)
|
2011-03-30 20:01:08 +00:00
|
|
|
dpll |= DPLL_DVO_HIGH_SPEED;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2011-03-30 20:01:08 +00:00
|
|
|
/* compute bitmask from p1 value */
|
|
|
|
dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
|
|
|
|
/* also FPA1 */
|
|
|
|
dpll |= (1 << (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;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
2009-02-14 01:56:52 +00:00
|
|
|
if (is_sdvo && is_tv)
|
|
|
|
dpll |= PLL_REF_INPUT_TVCLKINBC;
|
|
|
|
else if (is_tv)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
/* XXX: just matching BIOS for now */
|
2009-02-14 01:56:52 +00:00
|
|
|
/* dpll |= PLL_REF_INPUT_TVCLKINBC; */
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
dpll |= 3;
|
2011-01-12 17:04:08 +00:00
|
|
|
else if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2)
|
2009-02-14 01:56:52 +00:00
|
|
|
dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
else
|
|
|
|
dpll |= PLL_REF_INPUT_DREFCLK;
|
|
|
|
|
2011-10-12 17:49:14 +00:00
|
|
|
DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
drm_mode_debug_printmodeline(mode);
|
|
|
|
|
2012-05-09 18:37:17 +00:00
|
|
|
/* CPU eDP is the only output that doesn't need a PCH PLL of its own on
|
|
|
|
* pre-Haswell/LPT generation */
|
|
|
|
if (HAS_PCH_LPT(dev)) {
|
|
|
|
DRM_DEBUG_KMS("LPT detected: no PLL for pipe %d necessary\n",
|
|
|
|
pipe);
|
|
|
|
} else if (!is_cpu_edp) {
|
2012-04-20 16:11:53 +00:00
|
|
|
struct intel_pch_pll *pll;
|
2011-10-12 16:51:31 +00:00
|
|
|
|
2012-04-20 16:11:53 +00:00
|
|
|
pll = intel_get_pch_pll(intel_crtc, dpll, fp);
|
|
|
|
if (pll == NULL) {
|
|
|
|
DRM_DEBUG_DRIVER("failed to find PLL for pipe %d\n",
|
|
|
|
pipe);
|
2011-10-12 16:51:31 +00:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
2012-04-20 16:11:53 +00:00
|
|
|
} else
|
|
|
|
intel_put_pch_pll(intel_crtc);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
|
|
|
/* The LVDS pin pair needs to be on before the DPLLs are enabled.
|
|
|
|
* This is an exception to the general rule that mode_set doesn't turn
|
|
|
|
* things on.
|
|
|
|
*/
|
|
|
|
if (is_lvds) {
|
2011-03-30 20:01:09 +00:00
|
|
|
temp = I915_READ(PCH_LVDS);
|
2010-09-11 12:48:45 +00:00
|
|
|
temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
|
2012-01-12 22:51:17 +00:00
|
|
|
if (HAS_PCH_CPT(dev)) {
|
|
|
|
temp &= ~PORT_TRANS_SEL_MASK;
|
2011-10-12 16:51:31 +00:00
|
|
|
temp |= PORT_TRANS_SEL_CPT(pipe);
|
2012-01-12 22:51:17 +00:00
|
|
|
} else {
|
|
|
|
if (pipe == 1)
|
|
|
|
temp |= LVDS_PIPEB_SELECT;
|
|
|
|
else
|
|
|
|
temp &= ~LVDS_PIPEB_SELECT;
|
|
|
|
}
|
2011-10-12 16:51:31 +00:00
|
|
|
|
2009-10-10 02:42:37 +00:00
|
|
|
/* set the corresponsding LVDS_BORDER bit */
|
2010-09-11 12:48:45 +00:00
|
|
|
temp |= dev_priv->lvds_border_bits;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
/* Set the B0-B3 data pairs corresponding to whether we're going to
|
|
|
|
* set the DPLLs for dual-channel mode or not.
|
|
|
|
*/
|
|
|
|
if (clock.p2 == 7)
|
2010-09-11 12:48:45 +00:00
|
|
|
temp |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
else
|
2010-09-11 12:48:45 +00:00
|
|
|
temp &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
|
|
|
/* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
|
|
|
|
* appropriately here, but we need to look more thoroughly into how
|
|
|
|
* panels behave in the two modes.
|
|
|
|
*/
|
2012-04-14 16:41:59 +00:00
|
|
|
temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY);
|
2011-01-12 21:43:19 +00:00
|
|
|
if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
|
2012-04-14 16:41:59 +00:00
|
|
|
temp |= LVDS_HSYNC_POLARITY;
|
2011-01-12 21:43:19 +00:00
|
|
|
if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
|
2012-04-14 16:41:59 +00:00
|
|
|
temp |= LVDS_VSYNC_POLARITY;
|
2011-03-30 20:01:09 +00:00
|
|
|
I915_WRITE(PCH_LVDS, temp);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
2010-09-07 21:48:06 +00:00
|
|
|
|
2012-04-10 18:58:03 +00:00
|
|
|
if (is_dp && !is_cpu_edp) {
|
2009-04-07 23:16:42 +00:00
|
|
|
intel_dp_set_m_n(crtc, mode, adjusted_mode);
|
2011-03-30 20:01:07 +00:00
|
|
|
} else {
|
2010-04-07 08:15:54 +00:00
|
|
|
/* For non-DP output, clear any trans DP clock recovery setting.*/
|
2011-02-07 20:26:52 +00:00
|
|
|
I915_WRITE(TRANSDATA_M1(pipe), 0);
|
|
|
|
I915_WRITE(TRANSDATA_N1(pipe), 0);
|
|
|
|
I915_WRITE(TRANSDPLINK_M1(pipe), 0);
|
|
|
|
I915_WRITE(TRANSDPLINK_N1(pipe), 0);
|
2010-04-07 08:15:54 +00:00
|
|
|
}
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2012-04-20 16:11:53 +00:00
|
|
|
if (intel_crtc->pch_pll) {
|
|
|
|
I915_WRITE(intel_crtc->pch_pll->pll_reg, dpll);
|
2010-09-11 12:48:45 +00:00
|
|
|
|
2009-07-23 17:00:32 +00:00
|
|
|
/* Wait for the clocks to stabilize. */
|
2012-04-20 16:11:53 +00:00
|
|
|
POSTING_READ(intel_crtc->pch_pll->pll_reg);
|
2009-07-23 17:00:32 +00:00
|
|
|
udelay(150);
|
|
|
|
|
2011-03-30 20:01:07 +00:00
|
|
|
/* The pixel multiplier can only be updated once the
|
|
|
|
* DPLL is enabled and the clocks are stable.
|
|
|
|
*
|
|
|
|
* So write it again.
|
|
|
|
*/
|
2012-04-20 16:11:53 +00:00
|
|
|
I915_WRITE(intel_crtc->pch_pll->pll_reg, dpll);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
2010-09-11 12:48:45 +00:00
|
|
|
intel_crtc->lowfreq_avail = false;
|
2012-04-20 16:11:53 +00:00
|
|
|
if (intel_crtc->pch_pll) {
|
2011-10-12 16:51:31 +00:00
|
|
|
if (is_lvds && has_reduced_clock && i915_powersave) {
|
2012-04-20 16:11:53 +00:00
|
|
|
I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp2);
|
2011-10-12 16:51:31 +00:00
|
|
|
intel_crtc->lowfreq_avail = true;
|
|
|
|
} else {
|
2012-04-20 16:11:53 +00:00
|
|
|
I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp);
|
2009-08-17 20:31:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-05-25 16:41:46 +00:00
|
|
|
if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
|
|
|
|
/* the chip adds 2 halflines automatically */
|
|
|
|
adjusted_mode->crtc_vtotal -= 1;
|
|
|
|
adjusted_mode->crtc_vblank_end -= 1;
|
2012-01-28 13:49:24 +00:00
|
|
|
I915_WRITE(VSYNCSHIFT(pipe),
|
|
|
|
adjusted_mode->crtc_hsync_start
|
|
|
|
- adjusted_mode->crtc_htotal/2);
|
|
|
|
} else {
|
|
|
|
I915_WRITE(VSYNCSHIFT(pipe), 0);
|
|
|
|
}
|
2010-05-25 16:41:46 +00:00
|
|
|
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(HTOTAL(pipe),
|
|
|
|
(adjusted_mode->crtc_hdisplay - 1) |
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
((adjusted_mode->crtc_htotal - 1) << 16));
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(HBLANK(pipe),
|
|
|
|
(adjusted_mode->crtc_hblank_start - 1) |
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
((adjusted_mode->crtc_hblank_end - 1) << 16));
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(HSYNC(pipe),
|
|
|
|
(adjusted_mode->crtc_hsync_start - 1) |
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
((adjusted_mode->crtc_hsync_end - 1) << 16));
|
2010-09-11 12:48:45 +00:00
|
|
|
|
|
|
|
I915_WRITE(VTOTAL(pipe),
|
|
|
|
(adjusted_mode->crtc_vdisplay - 1) |
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
((adjusted_mode->crtc_vtotal - 1) << 16));
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(VBLANK(pipe),
|
|
|
|
(adjusted_mode->crtc_vblank_start - 1) |
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
((adjusted_mode->crtc_vblank_end - 1) << 16));
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(VSYNC(pipe),
|
|
|
|
(adjusted_mode->crtc_vsync_start - 1) |
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
((adjusted_mode->crtc_vsync_end - 1) << 16));
|
2010-09-11 12:48:45 +00:00
|
|
|
|
2011-03-30 20:01:07 +00:00
|
|
|
/* pipesrc controls the size that is scaled from, which should
|
|
|
|
* always be the user's requested size.
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
*/
|
2010-09-11 12:48:45 +00:00
|
|
|
I915_WRITE(PIPESRC(pipe),
|
|
|
|
((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
|
2009-06-05 07:38:42 +00:00
|
|
|
|
2011-03-30 20:01:07 +00:00
|
|
|
I915_WRITE(PIPE_DATA_M1(pipe), TU_SIZE(m_n.tu) | m_n.gmch_m);
|
|
|
|
I915_WRITE(PIPE_DATA_N1(pipe), m_n.gmch_n);
|
|
|
|
I915_WRITE(PIPE_LINK_M1(pipe), m_n.link_m);
|
|
|
|
I915_WRITE(PIPE_LINK_N1(pipe), m_n.link_n);
|
2009-06-05 07:38:42 +00:00
|
|
|
|
2012-04-10 18:58:03 +00:00
|
|
|
if (is_cpu_edp)
|
2011-03-30 20:01:07 +00:00
|
|
|
ironlake_set_pll_edp(crtc, adjusted_mode->clock);
|
2009-06-05 07:38:42 +00:00
|
|
|
|
2012-09-12 13:06:29 +00:00
|
|
|
ironlake_set_pipeconf(crtc, adjusted_mode, dither);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2010-08-18 20:20:54 +00:00
|
|
|
intel_wait_for_vblank(dev, pipe);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2012-09-12 13:06:32 +00:00
|
|
|
/* Set up the display plane register */
|
|
|
|
I915_WRITE(DSPCNTR(plane), DISPPLANE_GAMMA_ENABLE);
|
2011-01-04 23:09:30 +00:00
|
|
|
POSTING_READ(DSPCNTR(plane));
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
drm/i915: push crtc->fb update into pipe_set_base
Passing in the old fb, having overwritten the current fb, leads to
some neatly convoluted code. It's much simpler if we defer the
crtc->fb update to the place that updates the hw, in pipe_set_base.
This way we also don't need to restore anything in case something
fails - we only update crtc->fb once things have succeeded.
The real reason for this change is that now we keep the old fb
assigned to crtc->fb, which allows us to finally move the crtc disable
case into the common low-level set_mode function in the next patch.
Also don't clobber crtc->x and crtc->y, we neatly pass these down the
callchain already. Unfortunately we can't do the same with crtc->mode,
because that one is being used in the mode_set callbacks.
v2: Don't restore the drm_crtc object any more on failed modesets,
since we've lose an fb reference otherwise. Also (and this is the
reason this has been found), this totally confused the modeset state
tracking, since it clobbers crtc->enabled. Issue reported by Paulo
Zanoni.
v3: Rip out the entire crtc saving into struct intel_set_config, not
just the restoring part.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-05 20:51:56 +00:00
|
|
|
ret = intel_pipe_set_base(crtc, x, y, fb);
|
2009-06-26 03:23:55 +00:00
|
|
|
|
|
|
|
intel_update_watermarks(dev);
|
|
|
|
|
2012-05-09 18:37:24 +00:00
|
|
|
intel_update_linetime_watermarks(dev, pipe, adjusted_mode);
|
|
|
|
|
2009-06-06 08:45:59 +00:00
|
|
|
return ret;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
2011-03-30 20:01:02 +00:00
|
|
|
static int intel_crtc_mode_set(struct drm_crtc *crtc,
|
|
|
|
struct drm_display_mode *mode,
|
|
|
|
struct drm_display_mode *adjusted_mode,
|
|
|
|
int x, int y,
|
drm/i915: push crtc->fb update into pipe_set_base
Passing in the old fb, having overwritten the current fb, leads to
some neatly convoluted code. It's much simpler if we defer the
crtc->fb update to the place that updates the hw, in pipe_set_base.
This way we also don't need to restore anything in case something
fails - we only update crtc->fb once things have succeeded.
The real reason for this change is that now we keep the old fb
assigned to crtc->fb, which allows us to finally move the crtc disable
case into the common low-level set_mode function in the next patch.
Also don't clobber crtc->x and crtc->y, we neatly pass these down the
callchain already. Unfortunately we can't do the same with crtc->mode,
because that one is being used in the mode_set callbacks.
v2: Don't restore the drm_crtc object any more on failed modesets,
since we've lose an fb reference otherwise. Also (and this is the
reason this has been found), this totally confused the modeset state
tracking, since it clobbers crtc->enabled. Issue reported by Paulo
Zanoni.
v3: Rip out the entire crtc saving into struct intel_set_config, not
just the restoring part.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-05 20:51:56 +00:00
|
|
|
struct drm_framebuffer *fb)
|
2011-03-30 20:01:02 +00:00
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
2011-03-30 20:01:03 +00:00
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
|
int pipe = intel_crtc->pipe;
|
2011-03-30 20:01:02 +00:00
|
|
|
int ret;
|
|
|
|
|
2011-03-30 20:01:03 +00:00
|
|
|
drm_vblank_pre_modeset(dev, pipe);
|
2009-06-26 03:23:55 +00:00
|
|
|
|
2011-03-30 20:01:02 +00:00
|
|
|
ret = dev_priv->display.crtc_mode_set(crtc, mode, adjusted_mode,
|
drm/i915: push crtc->fb update into pipe_set_base
Passing in the old fb, having overwritten the current fb, leads to
some neatly convoluted code. It's much simpler if we defer the
crtc->fb update to the place that updates the hw, in pipe_set_base.
This way we also don't need to restore anything in case something
fails - we only update crtc->fb once things have succeeded.
The real reason for this change is that now we keep the old fb
assigned to crtc->fb, which allows us to finally move the crtc disable
case into the common low-level set_mode function in the next patch.
Also don't clobber crtc->x and crtc->y, we neatly pass these down the
callchain already. Unfortunately we can't do the same with crtc->mode,
because that one is being used in the mode_set callbacks.
v2: Don't restore the drm_crtc object any more on failed modesets,
since we've lose an fb reference otherwise. Also (and this is the
reason this has been found), this totally confused the modeset state
tracking, since it clobbers crtc->enabled. Issue reported by Paulo
Zanoni.
v3: Rip out the entire crtc saving into struct intel_set_config, not
just the restoring part.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-05 20:51:56 +00:00
|
|
|
x, y, fb);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
drm_vblank_post_modeset(dev, pipe);
|
2009-02-11 13:25:09 +00:00
|
|
|
|
2009-06-06 08:45:59 +00:00
|
|
|
return ret;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
2011-12-09 12:42:19 +00:00
|
|
|
static bool intel_eld_uptodate(struct drm_connector *connector,
|
|
|
|
int reg_eldv, uint32_t bits_eldv,
|
|
|
|
int reg_elda, uint32_t bits_elda,
|
|
|
|
int reg_edid)
|
|
|
|
{
|
|
|
|
struct drm_i915_private *dev_priv = connector->dev->dev_private;
|
|
|
|
uint8_t *eld = connector->eld;
|
|
|
|
uint32_t i;
|
|
|
|
|
|
|
|
i = I915_READ(reg_eldv);
|
|
|
|
i &= bits_eldv;
|
|
|
|
|
|
|
|
if (!eld[0])
|
|
|
|
return !i;
|
|
|
|
|
|
|
|
if (!i)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
i = I915_READ(reg_elda);
|
|
|
|
i &= ~bits_elda;
|
|
|
|
I915_WRITE(reg_elda, i);
|
|
|
|
|
|
|
|
for (i = 0; i < eld[2]; i++)
|
|
|
|
if (I915_READ(reg_edid) != *((uint32_t *)eld + i))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
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 06:25:34 +00:00
|
|
|
static void g4x_write_eld(struct drm_connector *connector,
|
|
|
|
struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
struct drm_i915_private *dev_priv = connector->dev->dev_private;
|
|
|
|
uint8_t *eld = connector->eld;
|
|
|
|
uint32_t eldv;
|
|
|
|
uint32_t len;
|
|
|
|
uint32_t i;
|
|
|
|
|
|
|
|
i = I915_READ(G4X_AUD_VID_DID);
|
|
|
|
|
|
|
|
if (i == INTEL_AUDIO_DEVBLC || i == INTEL_AUDIO_DEVCL)
|
|
|
|
eldv = G4X_ELDV_DEVCL_DEVBLC;
|
|
|
|
else
|
|
|
|
eldv = G4X_ELDV_DEVCTG;
|
|
|
|
|
2011-12-09 12:42:19 +00:00
|
|
|
if (intel_eld_uptodate(connector,
|
|
|
|
G4X_AUD_CNTL_ST, eldv,
|
|
|
|
G4X_AUD_CNTL_ST, G4X_ELD_ADDR,
|
|
|
|
G4X_HDMIW_HDMIEDID))
|
|
|
|
return;
|
|
|
|
|
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 06:25:34 +00:00
|
|
|
i = I915_READ(G4X_AUD_CNTL_ST);
|
|
|
|
i &= ~(eldv | G4X_ELD_ADDR);
|
|
|
|
len = (i >> 9) & 0x1f; /* ELD buffer size */
|
|
|
|
I915_WRITE(G4X_AUD_CNTL_ST, i);
|
|
|
|
|
|
|
|
if (!eld[0])
|
|
|
|
return;
|
|
|
|
|
|
|
|
len = min_t(uint8_t, eld[2], len);
|
|
|
|
DRM_DEBUG_DRIVER("ELD size %d\n", len);
|
|
|
|
for (i = 0; i < len; i++)
|
|
|
|
I915_WRITE(G4X_HDMIW_HDMIEDID, *((uint32_t *)eld + i));
|
|
|
|
|
|
|
|
i = I915_READ(G4X_AUD_CNTL_ST);
|
|
|
|
i |= eldv;
|
|
|
|
I915_WRITE(G4X_AUD_CNTL_ST, i);
|
|
|
|
}
|
|
|
|
|
2012-08-16 14:43:37 +00:00
|
|
|
static void haswell_write_eld(struct drm_connector *connector,
|
|
|
|
struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
struct drm_i915_private *dev_priv = connector->dev->dev_private;
|
|
|
|
uint8_t *eld = connector->eld;
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
uint32_t eldv;
|
|
|
|
uint32_t i;
|
|
|
|
int len;
|
|
|
|
int pipe = to_intel_crtc(crtc)->pipe;
|
|
|
|
int tmp;
|
|
|
|
|
|
|
|
int hdmiw_hdmiedid = HSW_AUD_EDID_DATA(pipe);
|
|
|
|
int aud_cntl_st = HSW_AUD_DIP_ELD_CTRL(pipe);
|
|
|
|
int aud_config = HSW_AUD_CFG(pipe);
|
|
|
|
int aud_cntrl_st2 = HSW_AUD_PIN_ELD_CP_VLD;
|
|
|
|
|
|
|
|
|
|
|
|
DRM_DEBUG_DRIVER("HDMI: Haswell Audio initialize....\n");
|
|
|
|
|
|
|
|
/* Audio output enable */
|
|
|
|
DRM_DEBUG_DRIVER("HDMI audio: enable codec\n");
|
|
|
|
tmp = I915_READ(aud_cntrl_st2);
|
|
|
|
tmp |= (AUDIO_OUTPUT_ENABLE_A << (pipe * 4));
|
|
|
|
I915_WRITE(aud_cntrl_st2, tmp);
|
|
|
|
|
|
|
|
/* Wait for 1 vertical blank */
|
|
|
|
intel_wait_for_vblank(dev, pipe);
|
|
|
|
|
|
|
|
/* Set ELD valid state */
|
|
|
|
tmp = I915_READ(aud_cntrl_st2);
|
|
|
|
DRM_DEBUG_DRIVER("HDMI audio: pin eld vld status=0x%8x\n", tmp);
|
|
|
|
tmp |= (AUDIO_ELD_VALID_A << (pipe * 4));
|
|
|
|
I915_WRITE(aud_cntrl_st2, tmp);
|
|
|
|
tmp = I915_READ(aud_cntrl_st2);
|
|
|
|
DRM_DEBUG_DRIVER("HDMI audio: eld vld status=0x%8x\n", tmp);
|
|
|
|
|
|
|
|
/* Enable HDMI mode */
|
|
|
|
tmp = I915_READ(aud_config);
|
|
|
|
DRM_DEBUG_DRIVER("HDMI audio: audio conf: 0x%8x\n", tmp);
|
|
|
|
/* clear N_programing_enable and N_value_index */
|
|
|
|
tmp &= ~(AUD_CONFIG_N_VALUE_INDEX | AUD_CONFIG_N_PROG_ENABLE);
|
|
|
|
I915_WRITE(aud_config, tmp);
|
|
|
|
|
|
|
|
DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(pipe));
|
|
|
|
|
|
|
|
eldv = AUDIO_ELD_VALID_A << (pipe * 4);
|
|
|
|
|
|
|
|
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) {
|
|
|
|
DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n");
|
|
|
|
eld[5] |= (1 << 2); /* Conn_Type, 0x1 = DisplayPort */
|
|
|
|
I915_WRITE(aud_config, AUD_CONFIG_N_VALUE_INDEX); /* 0x1 = DP */
|
|
|
|
} else
|
|
|
|
I915_WRITE(aud_config, 0);
|
|
|
|
|
|
|
|
if (intel_eld_uptodate(connector,
|
|
|
|
aud_cntrl_st2, eldv,
|
|
|
|
aud_cntl_st, IBX_ELD_ADDRESS,
|
|
|
|
hdmiw_hdmiedid))
|
|
|
|
return;
|
|
|
|
|
|
|
|
i = I915_READ(aud_cntrl_st2);
|
|
|
|
i &= ~eldv;
|
|
|
|
I915_WRITE(aud_cntrl_st2, i);
|
|
|
|
|
|
|
|
if (!eld[0])
|
|
|
|
return;
|
|
|
|
|
|
|
|
i = I915_READ(aud_cntl_st);
|
|
|
|
i &= ~IBX_ELD_ADDRESS;
|
|
|
|
I915_WRITE(aud_cntl_st, i);
|
|
|
|
i = (i >> 29) & DIP_PORT_SEL_MASK; /* DIP_Port_Select, 0x1 = PortB */
|
|
|
|
DRM_DEBUG_DRIVER("port num:%d\n", i);
|
|
|
|
|
|
|
|
len = min_t(uint8_t, eld[2], 21); /* 84 bytes of hw ELD buffer */
|
|
|
|
DRM_DEBUG_DRIVER("ELD size %d\n", len);
|
|
|
|
for (i = 0; i < len; i++)
|
|
|
|
I915_WRITE(hdmiw_hdmiedid, *((uint32_t *)eld + i));
|
|
|
|
|
|
|
|
i = I915_READ(aud_cntrl_st2);
|
|
|
|
i |= eldv;
|
|
|
|
I915_WRITE(aud_cntrl_st2, i);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
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 06:25:34 +00:00
|
|
|
static void ironlake_write_eld(struct drm_connector *connector,
|
|
|
|
struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
struct drm_i915_private *dev_priv = connector->dev->dev_private;
|
|
|
|
uint8_t *eld = connector->eld;
|
|
|
|
uint32_t eldv;
|
|
|
|
uint32_t i;
|
|
|
|
int len;
|
|
|
|
int hdmiw_hdmiedid;
|
2012-01-06 20:41:31 +00:00
|
|
|
int aud_config;
|
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 06:25:34 +00:00
|
|
|
int aud_cntl_st;
|
|
|
|
int aud_cntrl_st2;
|
2012-08-09 08:52:18 +00:00
|
|
|
int pipe = to_intel_crtc(crtc)->pipe;
|
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 06:25:34 +00:00
|
|
|
|
2011-12-09 12:42:17 +00:00
|
|
|
if (HAS_PCH_IBX(connector->dev)) {
|
2012-08-09 08:52:18 +00:00
|
|
|
hdmiw_hdmiedid = IBX_HDMIW_HDMIEDID(pipe);
|
|
|
|
aud_config = IBX_AUD_CFG(pipe);
|
|
|
|
aud_cntl_st = IBX_AUD_CNTL_ST(pipe);
|
2011-12-09 12:42:18 +00:00
|
|
|
aud_cntrl_st2 = IBX_AUD_CNTL_ST2;
|
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 06:25:34 +00:00
|
|
|
} else {
|
2012-08-09 08:52:18 +00:00
|
|
|
hdmiw_hdmiedid = CPT_HDMIW_HDMIEDID(pipe);
|
|
|
|
aud_config = CPT_AUD_CFG(pipe);
|
|
|
|
aud_cntl_st = CPT_AUD_CNTL_ST(pipe);
|
2011-12-09 12:42:18 +00:00
|
|
|
aud_cntrl_st2 = CPT_AUD_CNTRL_ST2;
|
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 06:25:34 +00:00
|
|
|
}
|
|
|
|
|
2012-08-09 08:52:18 +00:00
|
|
|
DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(pipe));
|
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 06:25:34 +00:00
|
|
|
|
|
|
|
i = I915_READ(aud_cntl_st);
|
2012-08-09 08:52:18 +00:00
|
|
|
i = (i >> 29) & DIP_PORT_SEL_MASK; /* DIP_Port_Select, 0x1 = PortB */
|
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 06:25:34 +00:00
|
|
|
if (!i) {
|
|
|
|
DRM_DEBUG_DRIVER("Audio directed to unknown port\n");
|
|
|
|
/* operate blindly on all ports */
|
2011-12-09 12:42:18 +00:00
|
|
|
eldv = IBX_ELD_VALIDB;
|
|
|
|
eldv |= IBX_ELD_VALIDB << 4;
|
|
|
|
eldv |= IBX_ELD_VALIDB << 8;
|
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 06:25:34 +00:00
|
|
|
} else {
|
|
|
|
DRM_DEBUG_DRIVER("ELD on port %c\n", 'A' + i);
|
2011-12-09 12:42:18 +00:00
|
|
|
eldv = IBX_ELD_VALIDB << ((i - 1) * 4);
|
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 06:25:34 +00:00
|
|
|
}
|
|
|
|
|
2011-12-09 12:42:19 +00:00
|
|
|
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) {
|
|
|
|
DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n");
|
|
|
|
eld[5] |= (1 << 2); /* Conn_Type, 0x1 = DisplayPort */
|
2012-01-06 20:41:31 +00:00
|
|
|
I915_WRITE(aud_config, AUD_CONFIG_N_VALUE_INDEX); /* 0x1 = DP */
|
|
|
|
} else
|
|
|
|
I915_WRITE(aud_config, 0);
|
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 06:25:34 +00:00
|
|
|
|
2011-12-09 12:42:19 +00:00
|
|
|
if (intel_eld_uptodate(connector,
|
|
|
|
aud_cntrl_st2, eldv,
|
|
|
|
aud_cntl_st, IBX_ELD_ADDRESS,
|
|
|
|
hdmiw_hdmiedid))
|
|
|
|
return;
|
|
|
|
|
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 06:25:34 +00:00
|
|
|
i = I915_READ(aud_cntrl_st2);
|
|
|
|
i &= ~eldv;
|
|
|
|
I915_WRITE(aud_cntrl_st2, i);
|
|
|
|
|
|
|
|
if (!eld[0])
|
|
|
|
return;
|
|
|
|
|
|
|
|
i = I915_READ(aud_cntl_st);
|
2011-12-09 12:42:18 +00:00
|
|
|
i &= ~IBX_ELD_ADDRESS;
|
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 06:25:34 +00:00
|
|
|
I915_WRITE(aud_cntl_st, i);
|
|
|
|
|
|
|
|
len = min_t(uint8_t, eld[2], 21); /* 84 bytes of hw ELD buffer */
|
|
|
|
DRM_DEBUG_DRIVER("ELD size %d\n", len);
|
|
|
|
for (i = 0; i < len; i++)
|
|
|
|
I915_WRITE(hdmiw_hdmiedid, *((uint32_t *)eld + i));
|
|
|
|
|
|
|
|
i = I915_READ(aud_cntrl_st2);
|
|
|
|
i |= eldv;
|
|
|
|
I915_WRITE(aud_cntrl_st2, i);
|
|
|
|
}
|
|
|
|
|
|
|
|
void intel_write_eld(struct drm_encoder *encoder,
|
|
|
|
struct drm_display_mode *mode)
|
|
|
|
{
|
|
|
|
struct drm_crtc *crtc = encoder->crtc;
|
|
|
|
struct drm_connector *connector;
|
|
|
|
struct drm_device *dev = encoder->dev;
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
|
|
|
|
connector = drm_select_eld(encoder, mode);
|
|
|
|
if (!connector)
|
|
|
|
return;
|
|
|
|
|
|
|
|
DRM_DEBUG_DRIVER("ELD on [CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
|
|
|
|
connector->base.id,
|
|
|
|
drm_get_connector_name(connector),
|
|
|
|
connector->encoder->base.id,
|
|
|
|
drm_get_encoder_name(connector->encoder));
|
|
|
|
|
|
|
|
connector->eld[6] = drm_av_sync_delay(connector, mode) / 2;
|
|
|
|
|
|
|
|
if (dev_priv->display.write_eld)
|
|
|
|
dev_priv->display.write_eld(connector, crtc);
|
|
|
|
}
|
|
|
|
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
/** Loads the palette/gamma unit for the CRTC with the prepared values */
|
|
|
|
void intel_crtc_load_lut(struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
2011-02-07 20:26:52 +00:00
|
|
|
int palreg = PALETTE(intel_crtc->pipe);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
/* The clocks have to be on to load the palette. */
|
2012-02-24 17:12:45 +00:00
|
|
|
if (!crtc->enabled || !intel_crtc->active)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
return;
|
|
|
|
|
2009-12-03 22:14:42 +00:00
|
|
|
/* use legacy palette for Ironlake */
|
2009-10-22 23:11:14 +00:00
|
|
|
if (HAS_PCH_SPLIT(dev))
|
2011-02-07 20:26:52 +00:00
|
|
|
palreg = LGC_PALETTE(intel_crtc->pipe);
|
2009-06-05 07:38:42 +00:00
|
|
|
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
for (i = 0; i < 256; i++) {
|
|
|
|
I915_WRITE(palreg + 4 * i,
|
|
|
|
(intel_crtc->lut_r[i] << 16) |
|
|
|
|
(intel_crtc->lut_g[i] << 8) |
|
|
|
|
intel_crtc->lut_b[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-07 10:01:38 +00:00
|
|
|
static void i845_update_cursor(struct drm_crtc *crtc, u32 base)
|
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
|
bool visible = base != 0;
|
|
|
|
u32 cntl;
|
|
|
|
|
|
|
|
if (intel_crtc->cursor_visible == visible)
|
|
|
|
return;
|
|
|
|
|
2011-02-07 20:26:52 +00:00
|
|
|
cntl = I915_READ(_CURACNTR);
|
2010-08-07 10:01:38 +00:00
|
|
|
if (visible) {
|
|
|
|
/* On these chipsets we can only modify the base whilst
|
|
|
|
* the cursor is disabled.
|
|
|
|
*/
|
2011-02-07 20:26:52 +00:00
|
|
|
I915_WRITE(_CURABASE, base);
|
2010-08-07 10:01:38 +00:00
|
|
|
|
|
|
|
cntl &= ~(CURSOR_FORMAT_MASK);
|
|
|
|
/* XXX width must be 64, stride 256 => 0x00 << 28 */
|
|
|
|
cntl |= CURSOR_ENABLE |
|
|
|
|
CURSOR_GAMMA_ENABLE |
|
|
|
|
CURSOR_FORMAT_ARGB;
|
|
|
|
} else
|
|
|
|
cntl &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE);
|
2011-02-07 20:26:52 +00:00
|
|
|
I915_WRITE(_CURACNTR, cntl);
|
2010-08-07 10:01:38 +00:00
|
|
|
|
|
|
|
intel_crtc->cursor_visible = visible;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
bool visible = base != 0;
|
|
|
|
|
|
|
|
if (intel_crtc->cursor_visible != visible) {
|
2011-02-17 18:40:53 +00:00
|
|
|
uint32_t cntl = I915_READ(CURCNTR(pipe));
|
2010-08-07 10:01:38 +00:00
|
|
|
if (base) {
|
|
|
|
cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
|
|
|
|
cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
|
|
|
|
cntl |= pipe << 28; /* Connect to correct pipe */
|
|
|
|
} else {
|
|
|
|
cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
|
|
|
|
cntl |= CURSOR_MODE_DISABLE;
|
|
|
|
}
|
2011-02-07 20:26:52 +00:00
|
|
|
I915_WRITE(CURCNTR(pipe), cntl);
|
2010-08-07 10:01:38 +00:00
|
|
|
|
|
|
|
intel_crtc->cursor_visible = visible;
|
|
|
|
}
|
|
|
|
/* and commit changes on next vblank */
|
2011-02-07 20:26:52 +00:00
|
|
|
I915_WRITE(CURBASE(pipe), base);
|
2010-08-07 10:01:38 +00:00
|
|
|
}
|
|
|
|
|
2011-10-12 18:10:21 +00:00
|
|
|
static void ivb_update_cursor(struct drm_crtc *crtc, u32 base)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
bool visible = base != 0;
|
|
|
|
|
|
|
|
if (intel_crtc->cursor_visible != visible) {
|
|
|
|
uint32_t cntl = I915_READ(CURCNTR_IVB(pipe));
|
|
|
|
if (base) {
|
|
|
|
cntl &= ~CURSOR_MODE;
|
|
|
|
cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
|
|
|
|
} else {
|
|
|
|
cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
|
|
|
|
cntl |= CURSOR_MODE_DISABLE;
|
|
|
|
}
|
|
|
|
I915_WRITE(CURCNTR_IVB(pipe), cntl);
|
|
|
|
|
|
|
|
intel_crtc->cursor_visible = visible;
|
|
|
|
}
|
|
|
|
/* and commit changes on next vblank */
|
|
|
|
I915_WRITE(CURBASE_IVB(pipe), base);
|
|
|
|
}
|
|
|
|
|
2010-07-09 07:45:04 +00:00
|
|
|
/* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */
|
2010-09-13 12:54:26 +00:00
|
|
|
static void intel_crtc_update_cursor(struct drm_crtc *crtc,
|
|
|
|
bool on)
|
2010-07-09 07:45:04 +00:00
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
|
int pipe = intel_crtc->pipe;
|
|
|
|
int x = intel_crtc->cursor_x;
|
|
|
|
int y = intel_crtc->cursor_y;
|
2010-08-07 10:01:38 +00:00
|
|
|
u32 base, pos;
|
2010-07-09 07:45:04 +00:00
|
|
|
bool visible;
|
|
|
|
|
|
|
|
pos = 0;
|
|
|
|
|
2010-09-13 12:54:26 +00:00
|
|
|
if (on && crtc->enabled && crtc->fb) {
|
2010-07-09 07:45:04 +00:00
|
|
|
base = intel_crtc->cursor_addr;
|
|
|
|
if (x > (int) crtc->fb->width)
|
|
|
|
base = 0;
|
|
|
|
|
|
|
|
if (y > (int) crtc->fb->height)
|
|
|
|
base = 0;
|
|
|
|
} else
|
|
|
|
base = 0;
|
|
|
|
|
|
|
|
if (x < 0) {
|
|
|
|
if (x + intel_crtc->cursor_width < 0)
|
|
|
|
base = 0;
|
|
|
|
|
|
|
|
pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
|
|
|
|
x = -x;
|
|
|
|
}
|
|
|
|
pos |= x << CURSOR_X_SHIFT;
|
|
|
|
|
|
|
|
if (y < 0) {
|
|
|
|
if (y + intel_crtc->cursor_height < 0)
|
|
|
|
base = 0;
|
|
|
|
|
|
|
|
pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT;
|
|
|
|
y = -y;
|
|
|
|
}
|
|
|
|
pos |= y << CURSOR_Y_SHIFT;
|
|
|
|
|
|
|
|
visible = base != 0;
|
2010-08-07 10:01:38 +00:00
|
|
|
if (!visible && !intel_crtc->cursor_visible)
|
2010-07-09 07:45:04 +00:00
|
|
|
return;
|
|
|
|
|
2012-04-13 20:08:48 +00:00
|
|
|
if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) {
|
2011-10-12 18:10:21 +00:00
|
|
|
I915_WRITE(CURPOS_IVB(pipe), pos);
|
|
|
|
ivb_update_cursor(crtc, base);
|
|
|
|
} else {
|
|
|
|
I915_WRITE(CURPOS(pipe), pos);
|
|
|
|
if (IS_845G(dev) || IS_I865G(dev))
|
|
|
|
i845_update_cursor(crtc, base);
|
|
|
|
else
|
|
|
|
i9xx_update_cursor(crtc, base);
|
|
|
|
}
|
2010-07-09 07:45:04 +00:00
|
|
|
}
|
|
|
|
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
static int intel_crtc_cursor_set(struct drm_crtc *crtc,
|
2010-11-08 19:18:58 +00:00
|
|
|
struct drm_file *file,
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
uint32_t handle,
|
|
|
|
uint32_t width, uint32_t height)
|
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
2010-11-08 19:18:58 +00:00
|
|
|
struct drm_i915_gem_object *obj;
|
2010-07-09 07:45:04 +00:00
|
|
|
uint32_t addr;
|
2008-12-18 03:14:59 +00:00
|
|
|
int ret;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
|
|
|
/* if we want to turn off the cursor ignore width and height */
|
|
|
|
if (!handle) {
|
2009-10-09 03:39:41 +00:00
|
|
|
DRM_DEBUG_KMS("cursor off\n");
|
2008-12-18 03:14:59 +00:00
|
|
|
addr = 0;
|
2010-11-08 19:18:58 +00:00
|
|
|
obj = NULL;
|
2009-02-23 00:12:15 +00:00
|
|
|
mutex_lock(&dev->struct_mutex);
|
2008-12-18 03:14:59 +00:00
|
|
|
goto finish;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Currently we only support 64x64 cursors */
|
|
|
|
if (width != 64 || height != 64) {
|
|
|
|
DRM_ERROR("we currently only support 64x64 cursors\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2010-11-08 19:18:58 +00:00
|
|
|
obj = to_intel_bo(drm_gem_object_lookup(dev, file, handle));
|
2011-02-19 11:31:06 +00:00
|
|
|
if (&obj->base == NULL)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
return -ENOENT;
|
|
|
|
|
2010-11-08 19:18:58 +00:00
|
|
|
if (obj->base.size < width * height * 4) {
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
DRM_ERROR("buffer is to small\n");
|
2009-01-15 04:03:07 +00:00
|
|
|
ret = -ENOMEM;
|
|
|
|
goto fail;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
2008-12-30 10:31:46 +00:00
|
|
|
/* we only need to pin inside GTT if cursor is non-phy */
|
2009-02-14 01:56:49 +00:00
|
|
|
mutex_lock(&dev->struct_mutex);
|
2009-12-16 20:16:17 +00:00
|
|
|
if (!dev_priv->info->cursor_needs_physical) {
|
2010-11-10 16:40:20 +00:00
|
|
|
if (obj->tiling_mode) {
|
|
|
|
DRM_ERROR("cursor cannot be tiled\n");
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto fail_locked;
|
|
|
|
}
|
|
|
|
|
2011-04-14 08:41:17 +00:00
|
|
|
ret = i915_gem_object_pin_to_display_plane(obj, 0, NULL);
|
2010-06-02 07:30:48 +00:00
|
|
|
if (ret) {
|
|
|
|
DRM_ERROR("failed to move cursor bo into the GTT\n");
|
2011-04-14 08:41:17 +00:00
|
|
|
goto fail_locked;
|
2010-06-02 07:30:48 +00:00
|
|
|
}
|
|
|
|
|
2010-11-10 16:40:20 +00:00
|
|
|
ret = i915_gem_object_put_fence(obj);
|
|
|
|
if (ret) {
|
2011-04-14 08:41:17 +00:00
|
|
|
DRM_ERROR("failed to release fence for cursor");
|
2010-11-10 16:40:20 +00:00
|
|
|
goto fail_unpin;
|
|
|
|
}
|
|
|
|
|
2010-11-08 19:18:58 +00:00
|
|
|
addr = obj->gtt_offset;
|
2008-12-30 10:31:46 +00:00
|
|
|
} else {
|
2010-08-07 10:01:39 +00:00
|
|
|
int align = IS_I830(dev) ? 16 * 1024 : 256;
|
2010-11-08 19:18:58 +00:00
|
|
|
ret = i915_gem_attach_phys_object(dev, obj,
|
2010-08-07 10:01:39 +00:00
|
|
|
(intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1,
|
|
|
|
align);
|
2008-12-30 10:31:46 +00:00
|
|
|
if (ret) {
|
|
|
|
DRM_ERROR("failed to attach phys object\n");
|
2009-02-14 01:56:49 +00:00
|
|
|
goto fail_locked;
|
2008-12-30 10:31:46 +00:00
|
|
|
}
|
2010-11-08 19:18:58 +00:00
|
|
|
addr = obj->phys_obj->handle->busaddr;
|
2008-12-18 03:14:59 +00:00
|
|
|
}
|
|
|
|
|
2010-09-16 23:32:17 +00:00
|
|
|
if (IS_GEN2(dev))
|
2009-05-20 20:47:08 +00:00
|
|
|
I915_WRITE(CURSIZE, (height << 12) | width);
|
|
|
|
|
2008-12-18 03:14:59 +00:00
|
|
|
finish:
|
|
|
|
if (intel_crtc->cursor_bo) {
|
2009-12-16 20:16:17 +00:00
|
|
|
if (dev_priv->info->cursor_needs_physical) {
|
2010-11-08 19:18:58 +00:00
|
|
|
if (intel_crtc->cursor_bo != obj)
|
2008-12-30 10:31:46 +00:00
|
|
|
i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo);
|
|
|
|
} else
|
|
|
|
i915_gem_object_unpin(intel_crtc->cursor_bo);
|
2010-11-08 19:18:58 +00:00
|
|
|
drm_gem_object_unreference(&intel_crtc->cursor_bo->base);
|
2008-12-18 03:14:59 +00:00
|
|
|
}
|
2009-09-10 22:28:06 +00:00
|
|
|
|
2009-02-14 01:56:49 +00:00
|
|
|
mutex_unlock(&dev->struct_mutex);
|
2008-12-18 03:14:59 +00:00
|
|
|
|
|
|
|
intel_crtc->cursor_addr = addr;
|
2010-11-08 19:18:58 +00:00
|
|
|
intel_crtc->cursor_bo = obj;
|
2010-07-09 07:45:04 +00:00
|
|
|
intel_crtc->cursor_width = width;
|
|
|
|
intel_crtc->cursor_height = height;
|
|
|
|
|
2010-09-13 12:54:26 +00:00
|
|
|
intel_crtc_update_cursor(crtc, true);
|
2008-12-18 03:14:59 +00:00
|
|
|
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
return 0;
|
2010-06-02 07:30:48 +00:00
|
|
|
fail_unpin:
|
2010-11-08 19:18:58 +00:00
|
|
|
i915_gem_object_unpin(obj);
|
2009-02-14 01:56:49 +00:00
|
|
|
fail_locked:
|
2009-01-15 04:03:07 +00:00
|
|
|
mutex_unlock(&dev->struct_mutex);
|
2010-02-09 05:49:12 +00:00
|
|
|
fail:
|
2010-11-08 19:18:58 +00:00
|
|
|
drm_gem_object_unreference_unlocked(&obj->base);
|
2009-01-15 04:03:07 +00:00
|
|
|
return ret;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
|
|
|
|
{
|
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
|
|
2010-07-09 07:45:04 +00:00
|
|
|
intel_crtc->cursor_x = x;
|
|
|
|
intel_crtc->cursor_y = y;
|
2009-08-17 20:31:43 +00:00
|
|
|
|
2010-09-13 12:54:26 +00:00
|
|
|
intel_crtc_update_cursor(crtc, true);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Sets the color ramps on behalf of RandR */
|
|
|
|
void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
|
|
|
|
u16 blue, int regno)
|
|
|
|
{
|
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
|
|
|
|
|
intel_crtc->lut_r[regno] = red >> 8;
|
|
|
|
intel_crtc->lut_g[regno] = green >> 8;
|
|
|
|
intel_crtc->lut_b[regno] = blue >> 8;
|
|
|
|
}
|
|
|
|
|
2009-10-06 03:54:01 +00:00
|
|
|
void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
|
|
|
|
u16 *blue, int regno)
|
|
|
|
{
|
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
|
|
|
|
|
*red = intel_crtc->lut_r[regno] << 8;
|
|
|
|
*green = intel_crtc->lut_g[regno] << 8;
|
|
|
|
*blue = intel_crtc->lut_b[regno] << 8;
|
|
|
|
}
|
|
|
|
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
|
2010-08-03 00:33:19 +00:00
|
|
|
u16 *blue, uint32_t start, uint32_t size)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
{
|
2010-08-03 00:33:19 +00:00
|
|
|
int end = (start + size > 256) ? 256 : start + size, i;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
|
|
2010-08-03 00:33:19 +00:00
|
|
|
for (i = start; i < end; i++) {
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
intel_crtc->lut_r[i] = red[i] >> 8;
|
|
|
|
intel_crtc->lut_g[i] = green[i] >> 8;
|
|
|
|
intel_crtc->lut_b[i] = blue[i] >> 8;
|
|
|
|
}
|
|
|
|
|
|
|
|
intel_crtc_load_lut(crtc);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a pipe with a simple mode set on it for doing load-based monitor
|
|
|
|
* detection.
|
|
|
|
*
|
|
|
|
* It will be up to the load-detect code to adjust the pipe as appropriate for
|
2010-03-25 18:48:48 +00:00
|
|
|
* its requirements. The pipe will be connected to no other encoders.
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
*
|
2010-03-25 18:48:48 +00:00
|
|
|
* Currently this code will only succeed if there is a pipe with no encoders
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
* configured for it. In the future, it could choose to temporarily disable
|
|
|
|
* some outputs to free up a pipe for its use.
|
|
|
|
*
|
|
|
|
* \return crtc, or NULL if no pipes are available.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* 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),
|
|
|
|
};
|
|
|
|
|
2011-04-19 07:36:26 +00:00
|
|
|
static struct drm_framebuffer *
|
|
|
|
intel_framebuffer_create(struct drm_device *dev,
|
2011-11-14 22:51:28 +00:00
|
|
|
struct drm_mode_fb_cmd2 *mode_cmd,
|
2011-04-19 07:36:26 +00:00
|
|
|
struct drm_i915_gem_object *obj)
|
|
|
|
{
|
|
|
|
struct intel_framebuffer *intel_fb;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
|
|
|
|
if (!intel_fb) {
|
|
|
|
drm_gem_object_unreference_unlocked(&obj->base);
|
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj);
|
|
|
|
if (ret) {
|
|
|
|
drm_gem_object_unreference_unlocked(&obj->base);
|
|
|
|
kfree(intel_fb);
|
|
|
|
return ERR_PTR(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
return &intel_fb->base;
|
|
|
|
}
|
|
|
|
|
|
|
|
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 ALIGN(pitch * mode->vdisplay, PAGE_SIZE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct drm_framebuffer *
|
|
|
|
intel_framebuffer_create_for_mode(struct drm_device *dev,
|
|
|
|
struct drm_display_mode *mode,
|
|
|
|
int depth, int bpp)
|
|
|
|
{
|
|
|
|
struct drm_i915_gem_object *obj;
|
2011-11-14 22:51:28 +00:00
|
|
|
struct drm_mode_fb_cmd2 mode_cmd;
|
2011-04-19 07:36:26 +00:00
|
|
|
|
|
|
|
obj = i915_gem_alloc_object(dev,
|
|
|
|
intel_framebuffer_size_for_mode(mode, bpp));
|
|
|
|
if (obj == NULL)
|
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
|
|
|
|
mode_cmd.width = mode->hdisplay;
|
|
|
|
mode_cmd.height = mode->vdisplay;
|
2011-11-14 22:51:28 +00:00
|
|
|
mode_cmd.pitches[0] = intel_framebuffer_pitch_for_width(mode_cmd.width,
|
|
|
|
bpp);
|
2012-02-23 15:33:40 +00:00
|
|
|
mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth);
|
2011-04-19 07:36:26 +00:00
|
|
|
|
|
|
|
return intel_framebuffer_create(dev, &mode_cmd, obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct drm_framebuffer *
|
|
|
|
mode_fits_in_fbdev(struct drm_device *dev,
|
|
|
|
struct drm_display_mode *mode)
|
|
|
|
{
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
struct drm_i915_gem_object *obj;
|
|
|
|
struct drm_framebuffer *fb;
|
|
|
|
|
|
|
|
if (dev_priv->fbdev == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
obj = dev_priv->fbdev->ifb.obj;
|
|
|
|
if (obj == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
fb = &dev_priv->fbdev->ifb.base;
|
2011-12-19 22:06:49 +00:00
|
|
|
if (fb->pitches[0] < intel_framebuffer_pitch_for_width(mode->hdisplay,
|
|
|
|
fb->bits_per_pixel))
|
2011-04-19 07:36:26 +00:00
|
|
|
return NULL;
|
|
|
|
|
2011-12-19 22:06:49 +00:00
|
|
|
if (obj->base.size < mode->vdisplay * fb->pitches[0])
|
2011-04-19 07:36:26 +00:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return fb;
|
|
|
|
}
|
|
|
|
|
2012-08-12 19:20:10 +00:00
|
|
|
bool intel_get_load_detect_pipe(struct drm_connector *connector,
|
2011-04-19 22:10:58 +00:00
|
|
|
struct drm_display_mode *mode,
|
2011-04-19 22:18:09 +00:00
|
|
|
struct intel_load_detect_pipe *old)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
{
|
|
|
|
struct intel_crtc *intel_crtc;
|
2012-08-12 19:20:10 +00:00
|
|
|
struct intel_encoder *intel_encoder =
|
|
|
|
intel_attached_encoder(connector);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
struct drm_crtc *possible_crtc;
|
2010-09-09 14:14:28 +00:00
|
|
|
struct drm_encoder *encoder = &intel_encoder->base;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
struct drm_crtc *crtc = NULL;
|
|
|
|
struct drm_device *dev = encoder->dev;
|
drm/i915: push crtc->fb update into pipe_set_base
Passing in the old fb, having overwritten the current fb, leads to
some neatly convoluted code. It's much simpler if we defer the
crtc->fb update to the place that updates the hw, in pipe_set_base.
This way we also don't need to restore anything in case something
fails - we only update crtc->fb once things have succeeded.
The real reason for this change is that now we keep the old fb
assigned to crtc->fb, which allows us to finally move the crtc disable
case into the common low-level set_mode function in the next patch.
Also don't clobber crtc->x and crtc->y, we neatly pass these down the
callchain already. Unfortunately we can't do the same with crtc->mode,
because that one is being used in the mode_set callbacks.
v2: Don't restore the drm_crtc object any more on failed modesets,
since we've lose an fb reference otherwise. Also (and this is the
reason this has been found), this totally confused the modeset state
tracking, since it clobbers crtc->enabled. Issue reported by Paulo
Zanoni.
v3: Rip out the entire crtc saving into struct intel_set_config, not
just the restoring part.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-05 20:51:56 +00:00
|
|
|
struct drm_framebuffer *fb;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
int i = -1;
|
|
|
|
|
2011-04-19 07:36:26 +00:00
|
|
|
DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
|
|
|
|
connector->base.id, drm_get_connector_name(connector),
|
|
|
|
encoder->base.id, drm_get_encoder_name(encoder));
|
|
|
|
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
/*
|
|
|
|
* Algorithm gets a little messy:
|
2011-04-19 22:21:12 +00:00
|
|
|
*
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
* - if the connector already has an assigned crtc, use it (but make
|
|
|
|
* sure it's on first)
|
2011-04-19 22:21:12 +00:00
|
|
|
*
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
* - 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 (encoder->crtc) {
|
|
|
|
crtc = encoder->crtc;
|
2011-04-19 22:18:09 +00:00
|
|
|
|
2012-08-12 17:27:11 +00:00
|
|
|
old->dpms_mode = connector->dpms;
|
2011-04-19 22:18:09 +00:00
|
|
|
old->load_detect_temp = false;
|
|
|
|
|
|
|
|
/* Make sure the crtc and connector are running */
|
2012-08-12 17:27:11 +00:00
|
|
|
if (connector->dpms != DRM_MODE_DPMS_ON)
|
|
|
|
connector->funcs->dpms(connector, DRM_MODE_DPMS_ON);
|
2011-04-19 22:18:09 +00:00
|
|
|
|
2011-04-19 22:10:58 +00:00
|
|
|
return true;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Find an unused one (if possible) */
|
|
|
|
list_for_each_entry(possible_crtc, &dev->mode_config.crtc_list, head) {
|
|
|
|
i++;
|
|
|
|
if (!(encoder->possible_crtcs & (1 << i)))
|
|
|
|
continue;
|
|
|
|
if (!possible_crtc->enabled) {
|
|
|
|
crtc = possible_crtc;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If we didn't find an unused CRTC, don't use any.
|
|
|
|
*/
|
|
|
|
if (!crtc) {
|
2011-04-19 22:10:58 +00:00
|
|
|
DRM_DEBUG_KMS("no pipe available for load-detect\n");
|
|
|
|
return false;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
2012-07-09 08:40:58 +00:00
|
|
|
intel_encoder->new_crtc = to_intel_crtc(crtc);
|
|
|
|
to_intel_connector(connector)->new_encoder = intel_encoder;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
|
|
|
intel_crtc = to_intel_crtc(crtc);
|
2012-08-12 17:27:11 +00:00
|
|
|
old->dpms_mode = connector->dpms;
|
2011-04-19 22:18:09 +00:00
|
|
|
old->load_detect_temp = true;
|
2011-04-19 07:36:26 +00:00
|
|
|
old->release_fb = NULL;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2011-04-20 06:25:26 +00:00
|
|
|
if (!mode)
|
|
|
|
mode = &load_detect_mode;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2011-04-19 07:36:26 +00:00
|
|
|
/* 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.
|
|
|
|
*/
|
drm/i915: push crtc->fb update into pipe_set_base
Passing in the old fb, having overwritten the current fb, leads to
some neatly convoluted code. It's much simpler if we defer the
crtc->fb update to the place that updates the hw, in pipe_set_base.
This way we also don't need to restore anything in case something
fails - we only update crtc->fb once things have succeeded.
The real reason for this change is that now we keep the old fb
assigned to crtc->fb, which allows us to finally move the crtc disable
case into the common low-level set_mode function in the next patch.
Also don't clobber crtc->x and crtc->y, we neatly pass these down the
callchain already. Unfortunately we can't do the same with crtc->mode,
because that one is being used in the mode_set callbacks.
v2: Don't restore the drm_crtc object any more on failed modesets,
since we've lose an fb reference otherwise. Also (and this is the
reason this has been found), this totally confused the modeset state
tracking, since it clobbers crtc->enabled. Issue reported by Paulo
Zanoni.
v3: Rip out the entire crtc saving into struct intel_set_config, not
just the restoring part.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-05 20:51:56 +00:00
|
|
|
fb = mode_fits_in_fbdev(dev, mode);
|
|
|
|
if (fb == NULL) {
|
2011-04-19 07:36:26 +00:00
|
|
|
DRM_DEBUG_KMS("creating tmp fb for load-detection\n");
|
drm/i915: push crtc->fb update into pipe_set_base
Passing in the old fb, having overwritten the current fb, leads to
some neatly convoluted code. It's much simpler if we defer the
crtc->fb update to the place that updates the hw, in pipe_set_base.
This way we also don't need to restore anything in case something
fails - we only update crtc->fb once things have succeeded.
The real reason for this change is that now we keep the old fb
assigned to crtc->fb, which allows us to finally move the crtc disable
case into the common low-level set_mode function in the next patch.
Also don't clobber crtc->x and crtc->y, we neatly pass these down the
callchain already. Unfortunately we can't do the same with crtc->mode,
because that one is being used in the mode_set callbacks.
v2: Don't restore the drm_crtc object any more on failed modesets,
since we've lose an fb reference otherwise. Also (and this is the
reason this has been found), this totally confused the modeset state
tracking, since it clobbers crtc->enabled. Issue reported by Paulo
Zanoni.
v3: Rip out the entire crtc saving into struct intel_set_config, not
just the restoring part.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-05 20:51:56 +00:00
|
|
|
fb = intel_framebuffer_create_for_mode(dev, mode, 24, 32);
|
|
|
|
old->release_fb = fb;
|
2011-04-19 07:36:26 +00:00
|
|
|
} else
|
|
|
|
DRM_DEBUG_KMS("reusing fbdev for load-detection framebuffer\n");
|
drm/i915: push crtc->fb update into pipe_set_base
Passing in the old fb, having overwritten the current fb, leads to
some neatly convoluted code. It's much simpler if we defer the
crtc->fb update to the place that updates the hw, in pipe_set_base.
This way we also don't need to restore anything in case something
fails - we only update crtc->fb once things have succeeded.
The real reason for this change is that now we keep the old fb
assigned to crtc->fb, which allows us to finally move the crtc disable
case into the common low-level set_mode function in the next patch.
Also don't clobber crtc->x and crtc->y, we neatly pass these down the
callchain already. Unfortunately we can't do the same with crtc->mode,
because that one is being used in the mode_set callbacks.
v2: Don't restore the drm_crtc object any more on failed modesets,
since we've lose an fb reference otherwise. Also (and this is the
reason this has been found), this totally confused the modeset state
tracking, since it clobbers crtc->enabled. Issue reported by Paulo
Zanoni.
v3: Rip out the entire crtc saving into struct intel_set_config, not
just the restoring part.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-05 20:51:56 +00:00
|
|
|
if (IS_ERR(fb)) {
|
2011-04-19 07:36:26 +00:00
|
|
|
DRM_DEBUG_KMS("failed to allocate framebuffer for load-detection\n");
|
2012-08-12 17:27:11 +00:00
|
|
|
goto fail;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
drm/i915: push crtc->fb update into pipe_set_base
Passing in the old fb, having overwritten the current fb, leads to
some neatly convoluted code. It's much simpler if we defer the
crtc->fb update to the place that updates the hw, in pipe_set_base.
This way we also don't need to restore anything in case something
fails - we only update crtc->fb once things have succeeded.
The real reason for this change is that now we keep the old fb
assigned to crtc->fb, which allows us to finally move the crtc disable
case into the common low-level set_mode function in the next patch.
Also don't clobber crtc->x and crtc->y, we neatly pass these down the
callchain already. Unfortunately we can't do the same with crtc->mode,
because that one is being used in the mode_set callbacks.
v2: Don't restore the drm_crtc object any more on failed modesets,
since we've lose an fb reference otherwise. Also (and this is the
reason this has been found), this totally confused the modeset state
tracking, since it clobbers crtc->enabled. Issue reported by Paulo
Zanoni.
v3: Rip out the entire crtc saving into struct intel_set_config, not
just the restoring part.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-05 20:51:56 +00:00
|
|
|
if (!intel_set_mode(crtc, mode, 0, 0, fb)) {
|
2011-04-20 06:25:26 +00:00
|
|
|
DRM_DEBUG_KMS("failed to set mode on load-detect pipe\n");
|
2011-04-19 07:36:26 +00:00
|
|
|
if (old->release_fb)
|
|
|
|
old->release_fb->funcs->destroy(old->release_fb);
|
2012-08-12 17:27:11 +00:00
|
|
|
goto fail;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
2011-04-19 22:10:58 +00:00
|
|
|
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
/* let the connector get through one full cycle before testing */
|
2010-08-18 20:20:54 +00:00
|
|
|
intel_wait_for_vblank(dev, intel_crtc->pipe);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2011-04-19 22:10:58 +00:00
|
|
|
return true;
|
2012-08-12 17:27:11 +00:00
|
|
|
fail:
|
|
|
|
connector->encoder = NULL;
|
|
|
|
encoder->crtc = NULL;
|
|
|
|
return false;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
2012-08-12 19:20:10 +00:00
|
|
|
void intel_release_load_detect_pipe(struct drm_connector *connector,
|
2011-04-19 22:18:09 +00:00
|
|
|
struct intel_load_detect_pipe *old)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
{
|
2012-08-12 19:20:10 +00:00
|
|
|
struct intel_encoder *intel_encoder =
|
|
|
|
intel_attached_encoder(connector);
|
2010-09-09 14:14:28 +00:00
|
|
|
struct drm_encoder *encoder = &intel_encoder->base;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2011-04-19 07:36:26 +00:00
|
|
|
DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
|
|
|
|
connector->base.id, drm_get_connector_name(connector),
|
|
|
|
encoder->base.id, drm_get_encoder_name(encoder));
|
|
|
|
|
2011-04-19 22:18:09 +00:00
|
|
|
if (old->load_detect_temp) {
|
2012-07-09 08:40:58 +00:00
|
|
|
struct drm_crtc *crtc = encoder->crtc;
|
|
|
|
|
|
|
|
to_intel_connector(connector)->new_encoder = NULL;
|
|
|
|
intel_encoder->new_crtc = NULL;
|
|
|
|
intel_set_mode(crtc, NULL, 0, 0, NULL);
|
2011-04-19 07:36:26 +00:00
|
|
|
|
|
|
|
if (old->release_fb)
|
|
|
|
old->release_fb->funcs->destroy(old->release_fb);
|
|
|
|
|
2011-04-21 08:32:11 +00:00
|
|
|
return;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
2010-03-25 18:48:48 +00:00
|
|
|
/* Switch crtc and encoder back off if necessary */
|
2012-08-12 17:27:11 +00:00
|
|
|
if (old->dpms_mode != DRM_MODE_DPMS_ON)
|
|
|
|
connector->funcs->dpms(connector, old->dpms_mode);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Returns the clock of the currently programmed mode of the given pipe. */
|
|
|
|
static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
|
int pipe = intel_crtc->pipe;
|
2011-02-17 18:40:53 +00:00
|
|
|
u32 dpll = I915_READ(DPLL(pipe));
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
u32 fp;
|
|
|
|
intel_clock_t clock;
|
|
|
|
|
|
|
|
if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
|
2011-04-22 21:17:21 +00:00
|
|
|
fp = I915_READ(FP0(pipe));
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
else
|
2011-04-22 21:17:21 +00:00
|
|
|
fp = I915_READ(FP1(pipe));
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
|
|
|
clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
|
2009-12-03 22:14:42 +00:00
|
|
|
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;
|
2009-02-23 07:19:16 +00:00
|
|
|
} else {
|
|
|
|
clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
|
|
|
|
clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
|
|
|
|
}
|
|
|
|
|
2010-09-16 23:32:17 +00:00
|
|
|
if (!IS_GEN2(dev)) {
|
2009-12-03 22:14:42 +00:00
|
|
|
if (IS_PINEVIEW(dev))
|
|
|
|
clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW) >>
|
|
|
|
DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW);
|
2009-02-23 07:19:16 +00:00
|
|
|
else
|
|
|
|
clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >>
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
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:
|
2009-10-09 03:39:41 +00:00
|
|
|
DRM_DEBUG_KMS("Unknown DPLL mode %08x in programmed "
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
"mode\n", (int)(dpll & DPLL_MODE_MASK));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* XXX: Handle the 100Mhz refclk */
|
2009-02-23 07:19:16 +00:00
|
|
|
intel_clock(dev, 96000, &clock);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
} else {
|
|
|
|
bool is_lvds = (pipe == 1) && (I915_READ(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);
|
|
|
|
clock.p2 = 14;
|
|
|
|
|
|
|
|
if ((dpll & PLL_REF_INPUT_MASK) ==
|
|
|
|
PLLB_REF_INPUT_SPREADSPECTRUMIN) {
|
|
|
|
/* XXX: might not be 66MHz */
|
2009-02-23 07:19:16 +00:00
|
|
|
intel_clock(dev, 66000, &clock);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
} else
|
2009-02-23 07:19:16 +00:00
|
|
|
intel_clock(dev, 48000, &clock);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
} 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;
|
|
|
|
|
2009-02-23 07:19:16 +00:00
|
|
|
intel_clock(dev, 48000, &clock);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* XXX: It would be nice to validate the clocks, but we can't reuse
|
|
|
|
* i830PllIsValid() because it relies on the xf86_config connector
|
|
|
|
* configuration being accurate, which it isn't necessarily.
|
|
|
|
*/
|
|
|
|
|
|
|
|
return clock.dot;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** 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)
|
|
|
|
{
|
2011-02-17 18:40:53 +00:00
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
|
int pipe = intel_crtc->pipe;
|
|
|
|
struct drm_display_mode *mode;
|
2011-02-17 18:40:53 +00:00
|
|
|
int htot = I915_READ(HTOTAL(pipe));
|
|
|
|
int hsync = I915_READ(HSYNC(pipe));
|
|
|
|
int vtot = I915_READ(VTOTAL(pipe));
|
|
|
|
int vsync = I915_READ(VSYNC(pipe));
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
|
|
|
mode = kzalloc(sizeof(*mode), GFP_KERNEL);
|
|
|
|
if (!mode)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
mode->clock = intel_crtc_clock_get(dev, crtc);
|
|
|
|
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);
|
|
|
|
|
|
|
|
return mode;
|
|
|
|
}
|
|
|
|
|
2010-08-20 19:40:52 +00:00
|
|
|
static void intel_increase_pllclock(struct drm_crtc *crtc)
|
2009-08-17 20:31:43 +00:00
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
drm_i915_private_t *dev_priv = dev->dev_private;
|
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
|
int pipe = intel_crtc->pipe;
|
2010-12-30 17:36:39 +00:00
|
|
|
int dpll_reg = DPLL(pipe);
|
|
|
|
int dpll;
|
2009-08-17 20:31:43 +00:00
|
|
|
|
2009-10-22 23:11:14 +00:00
|
|
|
if (HAS_PCH_SPLIT(dev))
|
2009-08-17 20:31:43 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (!dev_priv->lvds_downclock_avail)
|
|
|
|
return;
|
|
|
|
|
2010-12-30 17:36:39 +00:00
|
|
|
dpll = I915_READ(dpll_reg);
|
2009-08-17 20:31:43 +00:00
|
|
|
if (!HAS_PIPE_CXSR(dev) && (dpll & DISPLAY_RATE_SELECT_FPA1)) {
|
2009-10-09 03:39:40 +00:00
|
|
|
DRM_DEBUG_DRIVER("upclocking LVDS\n");
|
2009-08-17 20:31:43 +00:00
|
|
|
|
2012-02-13 18:14:51 +00:00
|
|
|
assert_panel_unlocked(dev_priv, pipe);
|
2009-08-17 20:31:43 +00:00
|
|
|
|
|
|
|
dpll &= ~DISPLAY_RATE_SELECT_FPA1;
|
|
|
|
I915_WRITE(dpll_reg, dpll);
|
2010-08-18 20:20:54 +00:00
|
|
|
intel_wait_for_vblank(dev, pipe);
|
2010-12-30 17:36:39 +00:00
|
|
|
|
2009-08-17 20:31:43 +00:00
|
|
|
dpll = I915_READ(dpll_reg);
|
|
|
|
if (dpll & DISPLAY_RATE_SELECT_FPA1)
|
2009-10-09 03:39:40 +00:00
|
|
|
DRM_DEBUG_DRIVER("failed to upclock LVDS!\n");
|
2009-08-17 20:31:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void intel_decrease_pllclock(struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
drm_i915_private_t *dev_priv = dev->dev_private;
|
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
|
|
2009-10-22 23:11:14 +00:00
|
|
|
if (HAS_PCH_SPLIT(dev))
|
2009-08-17 20:31:43 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (!dev_priv->lvds_downclock_avail)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Since this is called by a timer, we should never get here in
|
|
|
|
* the manual case.
|
|
|
|
*/
|
|
|
|
if (!HAS_PIPE_CXSR(dev) && intel_crtc->lowfreq_avail) {
|
2012-05-07 09:30:46 +00:00
|
|
|
int pipe = intel_crtc->pipe;
|
|
|
|
int dpll_reg = DPLL(pipe);
|
|
|
|
int dpll;
|
2011-04-12 17:06:51 +00:00
|
|
|
|
2009-10-09 03:39:40 +00:00
|
|
|
DRM_DEBUG_DRIVER("downclocking LVDS\n");
|
2009-08-17 20:31:43 +00:00
|
|
|
|
2012-02-13 18:14:51 +00:00
|
|
|
assert_panel_unlocked(dev_priv, pipe);
|
2009-08-17 20:31:43 +00:00
|
|
|
|
2012-05-07 09:30:46 +00:00
|
|
|
dpll = I915_READ(dpll_reg);
|
2009-08-17 20:31:43 +00:00
|
|
|
dpll |= DISPLAY_RATE_SELECT_FPA1;
|
|
|
|
I915_WRITE(dpll_reg, dpll);
|
2010-08-18 20:20:54 +00:00
|
|
|
intel_wait_for_vblank(dev, pipe);
|
2009-08-17 20:31:43 +00:00
|
|
|
dpll = I915_READ(dpll_reg);
|
|
|
|
if (!(dpll & DISPLAY_RATE_SELECT_FPA1))
|
2009-10-09 03:39:40 +00:00
|
|
|
DRM_DEBUG_DRIVER("failed to downclock LVDS!\n");
|
2009-08-17 20:31:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2012-07-21 11:31:41 +00:00
|
|
|
void intel_mark_busy(struct drm_device *dev)
|
|
|
|
{
|
|
|
|
i915_update_gfx_val(dev->dev_private);
|
|
|
|
}
|
|
|
|
|
|
|
|
void intel_mark_idle(struct drm_device *dev)
|
2009-08-17 20:31:43 +00:00
|
|
|
{
|
2012-07-21 11:31:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void intel_mark_fb_busy(struct drm_i915_gem_object *obj)
|
|
|
|
{
|
|
|
|
struct drm_device *dev = obj->base.dev;
|
2009-08-17 20:31:43 +00:00
|
|
|
struct drm_crtc *crtc;
|
|
|
|
|
|
|
|
if (!i915_powersave)
|
|
|
|
return;
|
|
|
|
|
|
|
|
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
|
|
|
if (!crtc->fb)
|
|
|
|
continue;
|
|
|
|
|
2012-07-21 11:31:41 +00:00
|
|
|
if (to_intel_framebuffer(crtc->fb)->obj == obj)
|
|
|
|
intel_increase_pllclock(crtc);
|
2009-08-17 20:31:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-21 11:31:41 +00:00
|
|
|
void intel_mark_fb_idle(struct drm_i915_gem_object *obj)
|
2009-08-17 20:31:43 +00:00
|
|
|
{
|
2012-07-21 11:31:41 +00:00
|
|
|
struct drm_device *dev = obj->base.dev;
|
|
|
|
struct drm_crtc *crtc;
|
2009-08-17 20:31:43 +00:00
|
|
|
|
2012-07-21 11:31:41 +00:00
|
|
|
if (!i915_powersave)
|
2012-05-03 14:47:57 +00:00
|
|
|
return;
|
|
|
|
|
2009-08-17 20:31:43 +00:00
|
|
|
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
|
|
|
if (!crtc->fb)
|
|
|
|
continue;
|
|
|
|
|
2012-07-21 11:31:41 +00:00
|
|
|
if (to_intel_framebuffer(crtc->fb)->obj == obj)
|
|
|
|
intel_decrease_pllclock(crtc);
|
2009-08-17 20:31:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
static void intel_crtc_destroy(struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
2010-08-20 20:26:30 +00:00
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct intel_unpin_work *work;
|
|
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
spin_lock_irqsave(&dev->event_lock, flags);
|
|
|
|
work = intel_crtc->unpin_work;
|
|
|
|
intel_crtc->unpin_work = NULL;
|
|
|
|
spin_unlock_irqrestore(&dev->event_lock, flags);
|
|
|
|
|
|
|
|
if (work) {
|
|
|
|
cancel_work_sync(&work->work);
|
|
|
|
kfree(work);
|
|
|
|
}
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
|
|
|
drm_crtc_cleanup(crtc);
|
2010-08-20 20:26:30 +00:00
|
|
|
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
kfree(intel_crtc);
|
|
|
|
}
|
|
|
|
|
2009-11-18 16:25:18 +00:00
|
|
|
static void intel_unpin_work_fn(struct work_struct *__work)
|
|
|
|
{
|
|
|
|
struct intel_unpin_work *work =
|
|
|
|
container_of(__work, struct intel_unpin_work, work);
|
|
|
|
|
|
|
|
mutex_lock(&work->dev->struct_mutex);
|
2011-12-14 12:57:08 +00:00
|
|
|
intel_unpin_fb_obj(work->old_fb_obj);
|
2010-11-08 19:18:58 +00:00
|
|
|
drm_gem_object_unreference(&work->pending_flip_obj->base);
|
|
|
|
drm_gem_object_unreference(&work->old_fb_obj->base);
|
2010-11-10 16:40:20 +00:00
|
|
|
|
2011-07-08 11:22:41 +00:00
|
|
|
intel_update_fbc(work->dev);
|
2009-11-18 16:25:18 +00:00
|
|
|
mutex_unlock(&work->dev->struct_mutex);
|
|
|
|
kfree(work);
|
|
|
|
}
|
|
|
|
|
2010-03-26 17:35:20 +00:00
|
|
|
static void do_intel_finish_page_flip(struct drm_device *dev,
|
2010-12-09 06:00:07 +00:00
|
|
|
struct drm_crtc *crtc)
|
2009-11-18 16:25:18 +00:00
|
|
|
{
|
|
|
|
drm_i915_private_t *dev_priv = dev->dev_private;
|
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
|
struct intel_unpin_work *work;
|
2010-11-08 19:18:58 +00:00
|
|
|
struct drm_i915_gem_object *obj;
|
2009-11-18 16:25:18 +00:00
|
|
|
struct drm_pending_vblank_event *e;
|
2010-12-09 06:00:07 +00:00
|
|
|
struct timeval tnow, tvbl;
|
2009-11-18 16:25:18 +00:00
|
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
/* Ignore early vblank irqs */
|
|
|
|
if (intel_crtc == NULL)
|
|
|
|
return;
|
|
|
|
|
2010-12-09 06:00:07 +00:00
|
|
|
do_gettimeofday(&tnow);
|
|
|
|
|
2009-11-18 16:25:18 +00:00
|
|
|
spin_lock_irqsave(&dev->event_lock, flags);
|
|
|
|
work = intel_crtc->unpin_work;
|
|
|
|
if (work == NULL || !work->pending) {
|
|
|
|
spin_unlock_irqrestore(&dev->event_lock, flags);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
intel_crtc->unpin_work = NULL;
|
|
|
|
|
|
|
|
if (work->event) {
|
|
|
|
e = work->event;
|
2010-12-09 06:00:07 +00:00
|
|
|
e->event.sequence = drm_vblank_count_and_time(dev, intel_crtc->pipe, &tvbl);
|
2010-12-08 03:07:19 +00:00
|
|
|
|
|
|
|
/* Called before vblank count and timestamps have
|
|
|
|
* been updated for the vblank interval of flip
|
|
|
|
* completion? Need to increment vblank count and
|
|
|
|
* add one videorefresh duration to returned timestamp
|
2010-12-09 06:00:07 +00:00
|
|
|
* to account for this. We assume this happened if we
|
|
|
|
* get called over 0.9 frame durations after the last
|
|
|
|
* timestamped vblank.
|
|
|
|
*
|
|
|
|
* This calculation can not be used with vrefresh rates
|
|
|
|
* below 5Hz (10Hz to be on the safe side) without
|
|
|
|
* promoting to 64 integers.
|
2010-12-08 03:07:19 +00:00
|
|
|
*/
|
2010-12-09 06:00:07 +00:00
|
|
|
if (10 * (timeval_to_ns(&tnow) - timeval_to_ns(&tvbl)) >
|
|
|
|
9 * crtc->framedur_ns) {
|
2010-12-08 03:07:19 +00:00
|
|
|
e->event.sequence++;
|
2010-12-09 06:00:07 +00:00
|
|
|
tvbl = ns_to_timeval(timeval_to_ns(&tvbl) +
|
|
|
|
crtc->framedur_ns);
|
2010-12-08 03:07:19 +00:00
|
|
|
}
|
|
|
|
|
2010-12-09 06:00:07 +00:00
|
|
|
e->event.tv_sec = tvbl.tv_sec;
|
|
|
|
e->event.tv_usec = tvbl.tv_usec;
|
2010-12-08 03:07:19 +00:00
|
|
|
|
2009-11-18 16:25:18 +00:00
|
|
|
list_add_tail(&e->base.link,
|
|
|
|
&e->base.file_priv->event_list);
|
|
|
|
wake_up_interruptible(&e->base.file_priv->event_wait);
|
|
|
|
}
|
|
|
|
|
2010-12-08 03:07:19 +00:00
|
|
|
drm_vblank_put(dev, intel_crtc->pipe);
|
|
|
|
|
2009-11-18 16:25:18 +00:00
|
|
|
spin_unlock_irqrestore(&dev->event_lock, flags);
|
|
|
|
|
2010-11-08 19:18:58 +00:00
|
|
|
obj = work->old_fb_obj;
|
2010-11-10 16:40:20 +00:00
|
|
|
|
2010-10-07 16:28:15 +00:00
|
|
|
atomic_clear_mask(1 << intel_crtc->plane,
|
2010-11-08 19:18:58 +00:00
|
|
|
&obj->pending_flip.counter);
|
2010-11-10 16:40:20 +00:00
|
|
|
|
2012-09-27 20:25:58 +00:00
|
|
|
wake_up(&dev_priv->pending_flip_queue);
|
2009-11-18 16:25:18 +00:00
|
|
|
schedule_work(&work->work);
|
2010-07-01 23:48:37 +00:00
|
|
|
|
|
|
|
trace_i915_flip_complete(intel_crtc->plane, work->pending_flip_obj);
|
2009-11-18 16:25:18 +00:00
|
|
|
}
|
|
|
|
|
2010-03-26 17:35:20 +00:00
|
|
|
void intel_finish_page_flip(struct drm_device *dev, int pipe)
|
|
|
|
{
|
|
|
|
drm_i915_private_t *dev_priv = dev->dev_private;
|
|
|
|
struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
|
|
|
|
|
2010-12-09 06:00:07 +00:00
|
|
|
do_intel_finish_page_flip(dev, crtc);
|
2010-03-26 17:35:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void intel_finish_page_flip_plane(struct drm_device *dev, int plane)
|
|
|
|
{
|
|
|
|
drm_i915_private_t *dev_priv = dev->dev_private;
|
|
|
|
struct drm_crtc *crtc = dev_priv->plane_to_crtc_mapping[plane];
|
|
|
|
|
2010-12-09 06:00:07 +00:00
|
|
|
do_intel_finish_page_flip(dev, crtc);
|
2010-03-26 17:35:20 +00:00
|
|
|
}
|
|
|
|
|
2009-11-18 16:25:18 +00:00
|
|
|
void intel_prepare_page_flip(struct drm_device *dev, int plane)
|
|
|
|
{
|
|
|
|
drm_i915_private_t *dev_priv = dev->dev_private;
|
|
|
|
struct intel_crtc *intel_crtc =
|
|
|
|
to_intel_crtc(dev_priv->plane_to_crtc_mapping[plane]);
|
|
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
spin_lock_irqsave(&dev->event_lock, flags);
|
2010-01-14 21:18:02 +00:00
|
|
|
if (intel_crtc->unpin_work) {
|
2010-09-01 16:47:52 +00:00
|
|
|
if ((++intel_crtc->unpin_work->pending) > 1)
|
|
|
|
DRM_ERROR("Prepared flip multiple times\n");
|
2010-01-14 21:18:02 +00:00
|
|
|
} else {
|
|
|
|
DRM_DEBUG_DRIVER("preparing flip with no unpin work?\n");
|
|
|
|
}
|
2009-11-18 16:25:18 +00:00
|
|
|
spin_unlock_irqrestore(&dev->event_lock, flags);
|
|
|
|
}
|
|
|
|
|
2011-06-16 16:19:13 +00: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_private *dev_priv = dev->dev_private;
|
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
|
u32 flip_mask;
|
2012-04-26 21:28:05 +00:00
|
|
|
struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
|
2011-06-16 16:19:13 +00:00
|
|
|
int ret;
|
|
|
|
|
2012-04-26 21:28:05 +00:00
|
|
|
ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
|
2011-06-16 16:19:13 +00:00
|
|
|
if (ret)
|
2012-04-17 18:35:53 +00:00
|
|
|
goto err;
|
2011-06-16 16:19:13 +00:00
|
|
|
|
2012-04-26 21:28:05 +00:00
|
|
|
ret = intel_ring_begin(ring, 6);
|
2011-06-16 16:19:13 +00:00
|
|
|
if (ret)
|
2012-04-17 18:35:53 +00:00
|
|
|
goto err_unpin;
|
2011-06-16 16:19:13 +00: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;
|
2012-04-26 21:28:05 +00:00
|
|
|
intel_ring_emit(ring, MI_WAIT_FOR_EVENT | flip_mask);
|
|
|
|
intel_ring_emit(ring, MI_NOOP);
|
|
|
|
intel_ring_emit(ring, MI_DISPLAY_FLIP |
|
|
|
|
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
|
|
|
|
intel_ring_emit(ring, fb->pitches[0]);
|
2012-07-05 10:17:29 +00:00
|
|
|
intel_ring_emit(ring, obj->gtt_offset + intel_crtc->dspaddr_offset);
|
2012-04-26 21:28:05 +00:00
|
|
|
intel_ring_emit(ring, 0); /* aux display base address, unused */
|
|
|
|
intel_ring_advance(ring);
|
2012-04-17 18:35:53 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
err_unpin:
|
|
|
|
intel_unpin_fb_obj(obj);
|
|
|
|
err:
|
2011-06-16 16:19:13 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
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_private *dev_priv = dev->dev_private;
|
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
|
u32 flip_mask;
|
2012-04-26 21:28:05 +00:00
|
|
|
struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
|
2011-06-16 16:19:13 +00:00
|
|
|
int ret;
|
|
|
|
|
2012-04-26 21:28:05 +00:00
|
|
|
ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
|
2011-06-16 16:19:13 +00:00
|
|
|
if (ret)
|
2012-04-17 18:35:53 +00:00
|
|
|
goto err;
|
2011-06-16 16:19:13 +00:00
|
|
|
|
2012-04-26 21:28:05 +00:00
|
|
|
ret = intel_ring_begin(ring, 6);
|
2011-06-16 16:19:13 +00:00
|
|
|
if (ret)
|
2012-04-17 18:35:53 +00:00
|
|
|
goto err_unpin;
|
2011-06-16 16:19:13 +00:00
|
|
|
|
|
|
|
if (intel_crtc->plane)
|
|
|
|
flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
|
|
|
|
else
|
|
|
|
flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
|
2012-04-26 21:28:05 +00:00
|
|
|
intel_ring_emit(ring, MI_WAIT_FOR_EVENT | flip_mask);
|
|
|
|
intel_ring_emit(ring, MI_NOOP);
|
|
|
|
intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 |
|
|
|
|
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
|
|
|
|
intel_ring_emit(ring, fb->pitches[0]);
|
2012-07-05 10:17:29 +00:00
|
|
|
intel_ring_emit(ring, obj->gtt_offset + intel_crtc->dspaddr_offset);
|
2012-04-26 21:28:05 +00:00
|
|
|
intel_ring_emit(ring, MI_NOOP);
|
|
|
|
|
|
|
|
intel_ring_advance(ring);
|
2012-04-17 18:35:53 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
err_unpin:
|
|
|
|
intel_unpin_fb_obj(obj);
|
|
|
|
err:
|
2011-06-16 16:19:13 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
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_private *dev_priv = dev->dev_private;
|
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
|
uint32_t pf, pipesrc;
|
2012-04-26 21:28:05 +00:00
|
|
|
struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
|
2011-06-16 16:19:13 +00:00
|
|
|
int ret;
|
|
|
|
|
2012-04-26 21:28:05 +00:00
|
|
|
ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
|
2011-06-16 16:19:13 +00:00
|
|
|
if (ret)
|
2012-04-17 18:35:53 +00:00
|
|
|
goto err;
|
2011-06-16 16:19:13 +00:00
|
|
|
|
2012-04-26 21:28:05 +00:00
|
|
|
ret = intel_ring_begin(ring, 4);
|
2011-06-16 16:19:13 +00:00
|
|
|
if (ret)
|
2012-04-17 18:35:53 +00:00
|
|
|
goto err_unpin;
|
2011-06-16 16:19:13 +00: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.
|
|
|
|
*/
|
2012-04-26 21:28:05 +00:00
|
|
|
intel_ring_emit(ring, MI_DISPLAY_FLIP |
|
|
|
|
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
|
|
|
|
intel_ring_emit(ring, fb->pitches[0]);
|
2012-07-05 10:17:30 +00:00
|
|
|
intel_ring_emit(ring,
|
|
|
|
(obj->gtt_offset + intel_crtc->dspaddr_offset) |
|
|
|
|
obj->tiling_mode);
|
2011-06-16 16:19:13 +00:00
|
|
|
|
|
|
|
/* 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;
|
2012-04-26 21:28:05 +00:00
|
|
|
intel_ring_emit(ring, pf | pipesrc);
|
|
|
|
intel_ring_advance(ring);
|
2012-04-17 18:35:53 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
err_unpin:
|
|
|
|
intel_unpin_fb_obj(obj);
|
|
|
|
err:
|
2011-06-16 16:19:13 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
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_private *dev_priv = dev->dev_private;
|
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
2012-04-26 21:28:05 +00:00
|
|
|
struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
|
2011-06-16 16:19:13 +00:00
|
|
|
uint32_t pf, pipesrc;
|
|
|
|
int ret;
|
|
|
|
|
2012-04-26 21:28:05 +00:00
|
|
|
ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
|
2011-06-16 16:19:13 +00:00
|
|
|
if (ret)
|
2012-04-17 18:35:53 +00:00
|
|
|
goto err;
|
2011-06-16 16:19:13 +00:00
|
|
|
|
2012-04-26 21:28:05 +00:00
|
|
|
ret = intel_ring_begin(ring, 4);
|
2011-06-16 16:19:13 +00:00
|
|
|
if (ret)
|
2012-04-17 18:35:53 +00:00
|
|
|
goto err_unpin;
|
2011-06-16 16:19:13 +00:00
|
|
|
|
2012-04-26 21:28:05 +00:00
|
|
|
intel_ring_emit(ring, MI_DISPLAY_FLIP |
|
|
|
|
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
|
|
|
|
intel_ring_emit(ring, fb->pitches[0] | obj->tiling_mode);
|
2012-07-05 10:17:30 +00:00
|
|
|
intel_ring_emit(ring, obj->gtt_offset + intel_crtc->dspaddr_offset);
|
2011-06-16 16:19:13 +00:00
|
|
|
|
2012-05-07 09:30:46 +00: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;
|
2011-06-16 16:19:13 +00:00
|
|
|
pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
|
2012-04-26 21:28:05 +00:00
|
|
|
intel_ring_emit(ring, pf | pipesrc);
|
|
|
|
intel_ring_advance(ring);
|
2012-04-17 18:35:53 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
err_unpin:
|
|
|
|
intel_unpin_fb_obj(obj);
|
|
|
|
err:
|
2011-06-16 16:19:13 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-06-16 19:18:54 +00:00
|
|
|
/*
|
|
|
|
* On gen7 we currently use the blit ring because (in early silicon at least)
|
|
|
|
* the render ring doesn't give us interrpts for page flip completion, which
|
|
|
|
* means clients will hang after the first flip is queued. Fortunately the
|
|
|
|
* blit ring generates interrupts properly, so use it instead.
|
|
|
|
*/
|
|
|
|
static int intel_gen7_queue_flip(struct drm_device *dev,
|
|
|
|
struct drm_crtc *crtc,
|
|
|
|
struct drm_framebuffer *fb,
|
|
|
|
struct drm_i915_gem_object *obj)
|
|
|
|
{
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
|
struct intel_ring_buffer *ring = &dev_priv->ring[BCS];
|
2012-05-23 12:02:00 +00:00
|
|
|
uint32_t plane_bit = 0;
|
2011-06-16 19:18:54 +00:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
|
|
|
|
if (ret)
|
2012-04-17 18:35:53 +00:00
|
|
|
goto err;
|
2011-06-16 19:18:54 +00:00
|
|
|
|
2012-05-23 12:02:00 +00: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");
|
|
|
|
ret = -ENODEV;
|
2012-06-18 22:03:38 +00:00
|
|
|
goto err_unpin;
|
2012-05-23 12:02:00 +00:00
|
|
|
}
|
|
|
|
|
2011-06-16 19:18:54 +00:00
|
|
|
ret = intel_ring_begin(ring, 4);
|
|
|
|
if (ret)
|
2012-04-17 18:35:53 +00:00
|
|
|
goto err_unpin;
|
2011-06-16 19:18:54 +00:00
|
|
|
|
2012-05-23 12:02:00 +00:00
|
|
|
intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane_bit);
|
2011-12-19 22:06:49 +00:00
|
|
|
intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode));
|
2012-07-05 10:17:30 +00:00
|
|
|
intel_ring_emit(ring, obj->gtt_offset + intel_crtc->dspaddr_offset);
|
2011-06-16 19:18:54 +00:00
|
|
|
intel_ring_emit(ring, (MI_NOOP));
|
|
|
|
intel_ring_advance(ring);
|
2012-04-17 18:35:53 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
err_unpin:
|
|
|
|
intel_unpin_fb_obj(obj);
|
|
|
|
err:
|
2011-06-16 19:18:54 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-06-16 16:19:13 +00:00
|
|
|
static int intel_default_queue_flip(struct drm_device *dev,
|
|
|
|
struct drm_crtc *crtc,
|
|
|
|
struct drm_framebuffer *fb,
|
|
|
|
struct drm_i915_gem_object *obj)
|
|
|
|
{
|
|
|
|
return -ENODEV;
|
|
|
|
}
|
|
|
|
|
2009-11-18 16:25:18 +00:00
|
|
|
static int intel_crtc_page_flip(struct drm_crtc *crtc,
|
|
|
|
struct drm_framebuffer *fb,
|
|
|
|
struct drm_pending_vblank_event *event)
|
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
struct intel_framebuffer *intel_fb;
|
2010-11-08 19:18:58 +00:00
|
|
|
struct drm_i915_gem_object *obj;
|
2009-11-18 16:25:18 +00:00
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
|
struct intel_unpin_work *work;
|
2011-06-16 16:19:13 +00:00
|
|
|
unsigned long flags;
|
2010-08-08 09:15:59 +00:00
|
|
|
int ret;
|
2009-11-18 16:25:18 +00:00
|
|
|
|
2012-05-24 18:08:59 +00:00
|
|
|
/* Can't change pixel format via MI display flips. */
|
|
|
|
if (fb->pixel_format != crtc->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->fb->offsets[0] ||
|
|
|
|
fb->pitches[0] != crtc->fb->pitches[0]))
|
|
|
|
return -EINVAL;
|
|
|
|
|
2009-11-18 16:25:18 +00:00
|
|
|
work = kzalloc(sizeof *work, GFP_KERNEL);
|
|
|
|
if (work == NULL)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
work->event = event;
|
|
|
|
work->dev = crtc->dev;
|
|
|
|
intel_fb = to_intel_framebuffer(crtc->fb);
|
2010-01-26 22:40:05 +00:00
|
|
|
work->old_fb_obj = intel_fb->obj;
|
2009-11-18 16:25:18 +00:00
|
|
|
INIT_WORK(&work->work, intel_unpin_work_fn);
|
|
|
|
|
2011-08-29 16:45:28 +00:00
|
|
|
ret = drm_vblank_get(dev, intel_crtc->pipe);
|
|
|
|
if (ret)
|
|
|
|
goto free_work;
|
|
|
|
|
2009-11-18 16:25:18 +00:00
|
|
|
/* We borrow the event spin lock for protecting unpin_work */
|
|
|
|
spin_lock_irqsave(&dev->event_lock, flags);
|
|
|
|
if (intel_crtc->unpin_work) {
|
|
|
|
spin_unlock_irqrestore(&dev->event_lock, flags);
|
|
|
|
kfree(work);
|
2011-08-29 16:45:28 +00:00
|
|
|
drm_vblank_put(dev, intel_crtc->pipe);
|
2010-05-27 12:18:13 +00:00
|
|
|
|
|
|
|
DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
|
2009-11-18 16:25:18 +00:00
|
|
|
return -EBUSY;
|
|
|
|
}
|
|
|
|
intel_crtc->unpin_work = work;
|
|
|
|
spin_unlock_irqrestore(&dev->event_lock, flags);
|
|
|
|
|
|
|
|
intel_fb = to_intel_framebuffer(fb);
|
|
|
|
obj = intel_fb->obj;
|
|
|
|
|
2012-05-23 10:13:58 +00:00
|
|
|
ret = i915_mutex_lock_interruptible(dev);
|
|
|
|
if (ret)
|
|
|
|
goto cleanup;
|
2009-11-18 16:25:18 +00:00
|
|
|
|
2010-02-10 23:09:44 +00:00
|
|
|
/* Reference the objects for the scheduled work. */
|
2010-11-08 19:18:58 +00:00
|
|
|
drm_gem_object_reference(&work->old_fb_obj->base);
|
|
|
|
drm_gem_object_reference(&obj->base);
|
2009-11-18 16:25:18 +00:00
|
|
|
|
|
|
|
crtc->fb = fb;
|
2010-06-07 13:03:04 +00:00
|
|
|
|
2010-10-27 11:45:26 +00:00
|
|
|
work->pending_flip_obj = obj;
|
|
|
|
|
2010-09-01 16:47:52 +00:00
|
|
|
work->enable_stall_check = true;
|
|
|
|
|
2010-10-27 11:45:26 +00:00
|
|
|
/* Block clients from rendering to the new back buffer until
|
|
|
|
* the flip occurs and the object is no longer visible.
|
|
|
|
*/
|
2010-11-08 19:18:58 +00:00
|
|
|
atomic_add(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip);
|
2010-10-27 11:45:26 +00:00
|
|
|
|
2011-06-16 16:19:13 +00:00
|
|
|
ret = dev_priv->display.queue_flip(dev, crtc, fb, obj);
|
|
|
|
if (ret)
|
|
|
|
goto cleanup_pending;
|
2009-11-18 16:25:18 +00:00
|
|
|
|
2011-07-08 11:22:41 +00:00
|
|
|
intel_disable_fbc(dev);
|
2012-07-21 11:31:41 +00:00
|
|
|
intel_mark_fb_busy(obj);
|
2009-11-18 16:25:18 +00:00
|
|
|
mutex_unlock(&dev->struct_mutex);
|
|
|
|
|
2010-07-01 23:48:37 +00:00
|
|
|
trace_i915_flip_request(intel_crtc->plane, obj);
|
|
|
|
|
2009-11-18 16:25:18 +00:00
|
|
|
return 0;
|
2010-06-07 13:03:04 +00:00
|
|
|
|
2011-06-16 16:19:13 +00:00
|
|
|
cleanup_pending:
|
|
|
|
atomic_sub(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip);
|
2010-11-08 19:18:58 +00:00
|
|
|
drm_gem_object_unreference(&work->old_fb_obj->base);
|
|
|
|
drm_gem_object_unreference(&obj->base);
|
2010-06-07 13:03:04 +00:00
|
|
|
mutex_unlock(&dev->struct_mutex);
|
|
|
|
|
2012-05-23 10:13:58 +00:00
|
|
|
cleanup:
|
2010-06-07 13:03:04 +00:00
|
|
|
spin_lock_irqsave(&dev->event_lock, flags);
|
|
|
|
intel_crtc->unpin_work = NULL;
|
|
|
|
spin_unlock_irqrestore(&dev->event_lock, flags);
|
|
|
|
|
2011-08-29 16:45:28 +00:00
|
|
|
drm_vblank_put(dev, intel_crtc->pipe);
|
|
|
|
free_work:
|
2010-06-07 13:03:04 +00:00
|
|
|
kfree(work);
|
|
|
|
|
|
|
|
return ret;
|
2009-11-18 16:25:18 +00:00
|
|
|
}
|
|
|
|
|
2011-04-12 17:06:51 +00:00
|
|
|
static struct drm_crtc_helper_funcs intel_helper_funcs = {
|
|
|
|
.mode_set_base_atomic = intel_pipe_set_base_atomic,
|
|
|
|
.load_lut = intel_crtc_load_lut,
|
2012-07-08 20:34:21 +00:00
|
|
|
.disable = intel_crtc_noop,
|
2011-04-12 17:06:51 +00:00
|
|
|
};
|
|
|
|
|
2012-07-08 17:41:43 +00:00
|
|
|
bool intel_encoder_check_is_cloned(struct intel_encoder *encoder)
|
2010-12-03 15:37:31 +00:00
|
|
|
{
|
2012-07-08 17:41:43 +00:00
|
|
|
struct intel_encoder *other_encoder;
|
|
|
|
struct drm_crtc *crtc = &encoder->new_crtc->base;
|
2010-12-03 15:37:31 +00:00
|
|
|
|
2012-07-08 17:41:43 +00:00
|
|
|
if (WARN_ON(!crtc))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
list_for_each_entry(other_encoder,
|
|
|
|
&crtc->dev->mode_config.encoder_list,
|
|
|
|
base.head) {
|
|
|
|
|
|
|
|
if (&other_encoder->new_crtc->base != crtc ||
|
|
|
|
encoder == other_encoder)
|
|
|
|
continue;
|
|
|
|
else
|
|
|
|
return true;
|
2012-03-22 15:00:50 +00:00
|
|
|
}
|
|
|
|
|
2012-07-08 17:41:43 +00:00
|
|
|
return false;
|
|
|
|
}
|
2010-12-03 15:37:31 +00:00
|
|
|
|
2012-07-02 07:35:43 +00:00
|
|
|
static bool intel_encoder_crtc_ok(struct drm_encoder *encoder,
|
|
|
|
struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
struct drm_device *dev;
|
|
|
|
struct drm_crtc *tmp;
|
|
|
|
int crtc_mask = 1;
|
2010-12-03 15:37:31 +00:00
|
|
|
|
2012-07-02 07:35:43 +00:00
|
|
|
WARN(!crtc, "checking null crtc?\n");
|
2010-12-03 15:37:31 +00:00
|
|
|
|
2012-07-02 07:35:43 +00:00
|
|
|
dev = crtc->dev;
|
2010-12-03 15:37:31 +00:00
|
|
|
|
2012-07-02 07:35:43 +00:00
|
|
|
list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) {
|
|
|
|
if (tmp == crtc)
|
|
|
|
break;
|
|
|
|
crtc_mask <<= 1;
|
|
|
|
}
|
2010-12-03 15:37:31 +00:00
|
|
|
|
2012-07-02 07:35:43 +00:00
|
|
|
if (encoder->possible_crtcs & crtc_mask)
|
|
|
|
return true;
|
|
|
|
return false;
|
2010-12-03 15:37:31 +00:00
|
|
|
}
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00: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 20:34:27 +00:00
|
|
|
/**
|
|
|
|
* intel_modeset_update_staged_output_state
|
|
|
|
*
|
|
|
|
* Updates the staged output configuration state, e.g. after we've read out the
|
|
|
|
* current hw state.
|
|
|
|
*/
|
|
|
|
static void intel_modeset_update_staged_output_state(struct drm_device *dev)
|
2011-04-12 17:06:51 +00: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 20:34:27 +00:00
|
|
|
struct intel_encoder *encoder;
|
|
|
|
struct intel_connector *connector;
|
2011-04-12 17:06:51 +00: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 20:34:27 +00:00
|
|
|
list_for_each_entry(connector, &dev->mode_config.connector_list,
|
|
|
|
base.head) {
|
|
|
|
connector->new_encoder =
|
|
|
|
to_intel_encoder(connector->base.encoder);
|
|
|
|
}
|
2011-04-12 17:06:51 +00: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 20:34:27 +00:00
|
|
|
list_for_each_entry(encoder, &dev->mode_config.encoder_list,
|
|
|
|
base.head) {
|
|
|
|
encoder->new_crtc =
|
|
|
|
to_intel_crtc(encoder->base.crtc);
|
|
|
|
}
|
2011-04-12 17:06:51 +00: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 20:34:27 +00:00
|
|
|
/**
|
|
|
|
* intel_modeset_commit_output_state
|
|
|
|
*
|
|
|
|
* This function copies the stage display pipe configuration to the real one.
|
|
|
|
*/
|
|
|
|
static void intel_modeset_commit_output_state(struct drm_device *dev)
|
|
|
|
{
|
|
|
|
struct intel_encoder *encoder;
|
|
|
|
struct intel_connector *connector;
|
2011-04-12 17:06:51 +00: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 20:34:27 +00:00
|
|
|
list_for_each_entry(connector, &dev->mode_config.connector_list,
|
|
|
|
base.head) {
|
|
|
|
connector->base.encoder = &connector->new_encoder->base;
|
|
|
|
}
|
2011-04-12 17:06:51 +00: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 20:34:27 +00:00
|
|
|
list_for_each_entry(encoder, &dev->mode_config.encoder_list,
|
|
|
|
base.head) {
|
|
|
|
encoder->base.crtc = &encoder->new_crtc->base;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-08 17:40:39 +00:00
|
|
|
static struct drm_display_mode *
|
|
|
|
intel_modeset_adjusted_mode(struct drm_crtc *crtc,
|
|
|
|
struct drm_display_mode *mode)
|
2012-04-20 16:11:53 +00:00
|
|
|
{
|
2012-07-08 17:40:39 +00:00
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct drm_display_mode *adjusted_mode;
|
|
|
|
struct drm_encoder_helper_funcs *encoder_funcs;
|
|
|
|
struct intel_encoder *encoder;
|
2012-04-20 16:11:53 +00:00
|
|
|
|
2012-07-08 17:40:39 +00:00
|
|
|
adjusted_mode = drm_mode_duplicate(dev, mode);
|
|
|
|
if (!adjusted_mode)
|
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
|
|
|
|
/* 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.
|
|
|
|
*/
|
|
|
|
list_for_each_entry(encoder, &dev->mode_config.encoder_list,
|
|
|
|
base.head) {
|
|
|
|
|
|
|
|
if (&encoder->new_crtc->base != crtc)
|
|
|
|
continue;
|
|
|
|
encoder_funcs = encoder->base.helper_private;
|
|
|
|
if (!(encoder_funcs->mode_fixup(&encoder->base, mode,
|
|
|
|
adjusted_mode))) {
|
|
|
|
DRM_DEBUG_KMS("Encoder fixup failed\n");
|
|
|
|
goto fail;
|
|
|
|
}
|
2012-04-20 16:11:53 +00:00
|
|
|
}
|
|
|
|
|
2012-07-08 17:40:39 +00:00
|
|
|
if (!(intel_crtc_mode_fixup(crtc, mode, adjusted_mode))) {
|
|
|
|
DRM_DEBUG_KMS("CRTC fixup failed\n");
|
|
|
|
goto fail;
|
2012-04-20 16:11:53 +00:00
|
|
|
}
|
2012-07-08 17:40:39 +00:00
|
|
|
DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
|
|
|
|
|
|
|
|
return adjusted_mode;
|
|
|
|
fail:
|
|
|
|
drm_mode_destroy(dev, adjusted_mode);
|
|
|
|
return ERR_PTR(-EINVAL);
|
2012-04-20 16:11:53 +00:00
|
|
|
}
|
|
|
|
|
2012-07-08 19:14:38 +00:00
|
|
|
/* Computes which crtcs are affected and sets the relevant bits in the mask. For
|
|
|
|
* simplicity we use the crtc's pipe number (because it's easier to obtain). */
|
|
|
|
static void
|
|
|
|
intel_modeset_affected_pipes(struct drm_crtc *crtc, unsigned *modeset_pipes,
|
|
|
|
unsigned *prepare_pipes, unsigned *disable_pipes)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
{
|
|
|
|
struct intel_crtc *intel_crtc;
|
2012-07-08 19:14:38 +00:00
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct intel_encoder *encoder;
|
|
|
|
struct intel_connector *connector;
|
|
|
|
struct drm_crtc *tmp_crtc;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2012-07-08 19:14:38 +00:00
|
|
|
*disable_pipes = *modeset_pipes = *prepare_pipes = 0;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2012-07-08 19:14:38 +00:00
|
|
|
/* Check which crtcs have changed outputs connected to them, these need
|
|
|
|
* to be part of the prepare_pipes mask. We don't (yet) support global
|
|
|
|
* modeset across multiple crtcs, so modeset_pipes will only have one
|
|
|
|
* bit set at most. */
|
|
|
|
list_for_each_entry(connector, &dev->mode_config.connector_list,
|
|
|
|
base.head) {
|
|
|
|
if (connector->base.encoder == &connector->new_encoder->base)
|
|
|
|
continue;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2012-07-08 19:14:38 +00:00
|
|
|
if (connector->base.encoder) {
|
|
|
|
tmp_crtc = connector->base.encoder->crtc;
|
|
|
|
|
|
|
|
*prepare_pipes |= 1 << to_intel_crtc(tmp_crtc)->pipe;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (connector->new_encoder)
|
|
|
|
*prepare_pipes |=
|
|
|
|
1 << connector->new_encoder->new_crtc->pipe;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
2012-07-08 19:14:38 +00:00
|
|
|
list_for_each_entry(encoder, &dev->mode_config.encoder_list,
|
|
|
|
base.head) {
|
|
|
|
if (encoder->base.crtc == &encoder->new_crtc->base)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (encoder->base.crtc) {
|
|
|
|
tmp_crtc = encoder->base.crtc;
|
|
|
|
|
|
|
|
*prepare_pipes |= 1 << to_intel_crtc(tmp_crtc)->pipe;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (encoder->new_crtc)
|
|
|
|
*prepare_pipes |= 1 << encoder->new_crtc->pipe;
|
2009-09-10 22:28:06 +00:00
|
|
|
}
|
|
|
|
|
2012-07-08 19:14:38 +00:00
|
|
|
/* Check for any pipes that will be fully disabled ... */
|
|
|
|
list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list,
|
|
|
|
base.head) {
|
|
|
|
bool used = false;
|
2009-12-02 21:42:53 +00:00
|
|
|
|
2012-07-08 19:14:38 +00:00
|
|
|
/* Don't try to disable disabled crtcs. */
|
|
|
|
if (!intel_crtc->base.enabled)
|
|
|
|
continue;
|
2010-09-10 17:47:20 +00:00
|
|
|
|
2012-07-08 19:14:38 +00:00
|
|
|
list_for_each_entry(encoder, &dev->mode_config.encoder_list,
|
|
|
|
base.head) {
|
|
|
|
if (encoder->new_crtc == intel_crtc)
|
|
|
|
used = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!used)
|
|
|
|
*disable_pipes |= 1 << intel_crtc->pipe;
|
2010-09-10 17:47:20 +00:00
|
|
|
}
|
|
|
|
|
2012-07-08 19:14:38 +00:00
|
|
|
|
|
|
|
/* set_mode is also used to update properties on life display pipes. */
|
|
|
|
intel_crtc = to_intel_crtc(crtc);
|
|
|
|
if (crtc->enabled)
|
|
|
|
*prepare_pipes |= 1 << intel_crtc->pipe;
|
|
|
|
|
|
|
|
/* We only support modeset on one single crtc, hence we need to do that
|
|
|
|
* only for the passed in crtc iff we change anything else than just
|
|
|
|
* disable crtcs.
|
|
|
|
*
|
|
|
|
* This is actually not true, to be fully compatible with the old crtc
|
|
|
|
* helper we automatically disable _any_ output (i.e. doesn't need to be
|
|
|
|
* connected to the crtc we're modesetting on) if it's disconnected.
|
|
|
|
* Which is a rather nutty api (since changed the output configuration
|
|
|
|
* without userspace's explicit request can lead to confusion), but
|
|
|
|
* alas. Hence we currently need to modeset on all pipes we prepare. */
|
|
|
|
if (*prepare_pipes)
|
|
|
|
*modeset_pipes = *prepare_pipes;
|
|
|
|
|
|
|
|
/* ... and mask these out. */
|
|
|
|
*modeset_pipes &= ~(*disable_pipes);
|
|
|
|
*prepare_pipes &= ~(*disable_pipes);
|
|
|
|
}
|
|
|
|
|
2012-07-10 08:42:52 +00:00
|
|
|
static bool intel_crtc_in_use(struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
struct drm_encoder *encoder;
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
|
|
|
|
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
|
|
|
|
if (encoder->crtc == crtc)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
intel_modeset_update_state(struct drm_device *dev, unsigned prepare_pipes)
|
|
|
|
{
|
|
|
|
struct intel_encoder *intel_encoder;
|
|
|
|
struct intel_crtc *intel_crtc;
|
|
|
|
struct drm_connector *connector;
|
|
|
|
|
|
|
|
list_for_each_entry(intel_encoder, &dev->mode_config.encoder_list,
|
|
|
|
base.head) {
|
|
|
|
if (!intel_encoder->base.crtc)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
intel_crtc = to_intel_crtc(intel_encoder->base.crtc);
|
|
|
|
|
|
|
|
if (prepare_pipes & (1 << intel_crtc->pipe))
|
|
|
|
intel_encoder->connectors_active = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
intel_modeset_commit_output_state(dev);
|
|
|
|
|
|
|
|
/* Update computed state. */
|
|
|
|
list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list,
|
|
|
|
base.head) {
|
|
|
|
intel_crtc->base.enabled = intel_crtc_in_use(&intel_crtc->base);
|
|
|
|
}
|
|
|
|
|
|
|
|
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
|
|
|
if (!connector->encoder || !connector->encoder->crtc)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
intel_crtc = to_intel_crtc(connector->encoder->crtc);
|
|
|
|
|
|
|
|
if (prepare_pipes & (1 << intel_crtc->pipe)) {
|
2012-09-06 20:08:35 +00:00
|
|
|
struct drm_property *dpms_property =
|
|
|
|
dev->mode_config.dpms_property;
|
|
|
|
|
2012-07-10 08:42:52 +00:00
|
|
|
connector->dpms = DRM_MODE_DPMS_ON;
|
2012-09-06 20:08:35 +00:00
|
|
|
drm_connector_property_set_value(connector,
|
|
|
|
dpms_property,
|
|
|
|
DRM_MODE_DPMS_ON);
|
2012-07-10 08:42:52 +00:00
|
|
|
|
|
|
|
intel_encoder = to_intel_encoder(connector->encoder);
|
|
|
|
intel_encoder->connectors_active = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2012-07-08 20:08:04 +00:00
|
|
|
#define for_each_intel_crtc_masked(dev, mask, intel_crtc) \
|
|
|
|
list_for_each_entry((intel_crtc), \
|
|
|
|
&(dev)->mode_config.crtc_list, \
|
|
|
|
base.head) \
|
|
|
|
if (mask & (1 <<(intel_crtc)->pipe)) \
|
|
|
|
|
2012-08-31 15:37:33 +00:00
|
|
|
void
|
2012-07-10 07:50:11 +00:00
|
|
|
intel_modeset_check_state(struct drm_device *dev)
|
|
|
|
{
|
|
|
|
struct intel_crtc *crtc;
|
|
|
|
struct intel_encoder *encoder;
|
|
|
|
struct intel_connector *connector;
|
|
|
|
|
|
|
|
list_for_each_entry(connector, &dev->mode_config.connector_list,
|
|
|
|
base.head) {
|
|
|
|
/* This also checks the encoder/connector hw state with the
|
|
|
|
* ->get_hw_state callbacks. */
|
|
|
|
intel_connector_check_state(connector);
|
|
|
|
|
|
|
|
WARN(&connector->new_encoder->base != connector->base.encoder,
|
|
|
|
"connector's staged encoder doesn't match current encoder\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
list_for_each_entry(encoder, &dev->mode_config.encoder_list,
|
|
|
|
base.head) {
|
|
|
|
bool enabled = false;
|
|
|
|
bool active = false;
|
|
|
|
enum pipe pipe, tracked_pipe;
|
|
|
|
|
|
|
|
DRM_DEBUG_KMS("[ENCODER:%d:%s]\n",
|
|
|
|
encoder->base.base.id,
|
|
|
|
drm_get_encoder_name(&encoder->base));
|
|
|
|
|
|
|
|
WARN(&encoder->new_crtc->base != encoder->base.crtc,
|
|
|
|
"encoder's stage crtc doesn't match current crtc\n");
|
|
|
|
WARN(encoder->connectors_active && !encoder->base.crtc,
|
|
|
|
"encoder's active_connectors set, but no crtc\n");
|
|
|
|
|
|
|
|
list_for_each_entry(connector, &dev->mode_config.connector_list,
|
|
|
|
base.head) {
|
|
|
|
if (connector->base.encoder != &encoder->base)
|
|
|
|
continue;
|
|
|
|
enabled = true;
|
|
|
|
if (connector->base.dpms != DRM_MODE_DPMS_OFF)
|
|
|
|
active = true;
|
|
|
|
}
|
|
|
|
WARN(!!encoder->base.crtc != enabled,
|
|
|
|
"encoder's enabled state mismatch "
|
|
|
|
"(expected %i, found %i)\n",
|
|
|
|
!!encoder->base.crtc, enabled);
|
|
|
|
WARN(active && !encoder->base.crtc,
|
|
|
|
"active encoder with no crtc\n");
|
|
|
|
|
|
|
|
WARN(encoder->connectors_active != active,
|
|
|
|
"encoder's computed active state doesn't match tracked active state "
|
|
|
|
"(expected %i, found %i)\n", active, encoder->connectors_active);
|
|
|
|
|
|
|
|
active = encoder->get_hw_state(encoder, &pipe);
|
|
|
|
WARN(active != encoder->connectors_active,
|
|
|
|
"encoder's hw state doesn't match sw tracking "
|
|
|
|
"(expected %i, found %i)\n",
|
|
|
|
encoder->connectors_active, active);
|
|
|
|
|
|
|
|
if (!encoder->base.crtc)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
tracked_pipe = to_intel_crtc(encoder->base.crtc)->pipe;
|
|
|
|
WARN(active && pipe != tracked_pipe,
|
|
|
|
"active encoder's pipe doesn't match"
|
|
|
|
"(expected %i, found %i)\n",
|
|
|
|
tracked_pipe, pipe);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
list_for_each_entry(crtc, &dev->mode_config.crtc_list,
|
|
|
|
base.head) {
|
|
|
|
bool enabled = false;
|
|
|
|
bool active = false;
|
|
|
|
|
|
|
|
DRM_DEBUG_KMS("[CRTC:%d]\n",
|
|
|
|
crtc->base.base.id);
|
|
|
|
|
|
|
|
WARN(crtc->active && !crtc->base.enabled,
|
|
|
|
"active crtc, but not enabled in sw tracking\n");
|
|
|
|
|
|
|
|
list_for_each_entry(encoder, &dev->mode_config.encoder_list,
|
|
|
|
base.head) {
|
|
|
|
if (encoder->base.crtc != &crtc->base)
|
|
|
|
continue;
|
|
|
|
enabled = true;
|
|
|
|
if (encoder->connectors_active)
|
|
|
|
active = true;
|
|
|
|
}
|
|
|
|
WARN(active != crtc->active,
|
|
|
|
"crtc's computed active state doesn't match tracked active state "
|
|
|
|
"(expected %i, found %i)\n", active, crtc->active);
|
|
|
|
WARN(enabled != crtc->base.enabled,
|
|
|
|
"crtc's computed enabled state doesn't match tracked enabled state "
|
|
|
|
"(expected %i, found %i)\n", enabled, crtc->base.enabled);
|
|
|
|
|
|
|
|
assert_pipe(dev->dev_private, crtc->pipe, crtc->active);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-02 07:56:42 +00:00
|
|
|
bool intel_set_mode(struct drm_crtc *crtc,
|
|
|
|
struct drm_display_mode *mode,
|
drm/i915: push crtc->fb update into pipe_set_base
Passing in the old fb, having overwritten the current fb, leads to
some neatly convoluted code. It's much simpler if we defer the
crtc->fb update to the place that updates the hw, in pipe_set_base.
This way we also don't need to restore anything in case something
fails - we only update crtc->fb once things have succeeded.
The real reason for this change is that now we keep the old fb
assigned to crtc->fb, which allows us to finally move the crtc disable
case into the common low-level set_mode function in the next patch.
Also don't clobber crtc->x and crtc->y, we neatly pass these down the
callchain already. Unfortunately we can't do the same with crtc->mode,
because that one is being used in the mode_set callbacks.
v2: Don't restore the drm_crtc object any more on failed modesets,
since we've lose an fb reference otherwise. Also (and this is the
reason this has been found), this totally confused the modeset state
tracking, since it clobbers crtc->enabled. Issue reported by Paulo
Zanoni.
v3: Rip out the entire crtc saving into struct intel_set_config, not
just the restoring part.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-05 20:51:56 +00:00
|
|
|
int x, int y, struct drm_framebuffer *fb)
|
2012-07-02 07:56:42 +00:00
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
2012-07-02 09:18:29 +00:00
|
|
|
drm_i915_private_t *dev_priv = dev->dev_private;
|
2012-07-02 07:56:42 +00:00
|
|
|
struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode;
|
|
|
|
struct drm_encoder_helper_funcs *encoder_funcs;
|
|
|
|
struct drm_encoder *encoder;
|
2012-07-08 20:08:04 +00:00
|
|
|
struct intel_crtc *intel_crtc;
|
|
|
|
unsigned disable_pipes, prepare_pipes, modeset_pipes;
|
2012-07-02 07:56:42 +00:00
|
|
|
bool ret = true;
|
|
|
|
|
2012-07-08 19:14:38 +00:00
|
|
|
intel_modeset_affected_pipes(crtc, &modeset_pipes,
|
2012-07-08 20:08:04 +00:00
|
|
|
&prepare_pipes, &disable_pipes);
|
|
|
|
|
|
|
|
DRM_DEBUG_KMS("set mode pipe masks: modeset: %x, prepare: %x, disable: %x\n",
|
|
|
|
modeset_pipes, prepare_pipes, disable_pipes);
|
2012-07-08 19:14:38 +00:00
|
|
|
|
2012-07-08 20:34:21 +00:00
|
|
|
for_each_intel_crtc_masked(dev, disable_pipes, intel_crtc)
|
|
|
|
intel_crtc_disable(&intel_crtc->base);
|
2012-07-05 21:36:17 +00:00
|
|
|
|
2012-07-02 07:56:42 +00:00
|
|
|
saved_hwmode = crtc->hwmode;
|
|
|
|
saved_mode = crtc->mode;
|
|
|
|
|
2012-07-08 20:08:04 +00:00
|
|
|
/* Hack: Because we don't (yet) support global modeset on multiple
|
|
|
|
* crtcs, we don't keep track of the new mode for more than one crtc.
|
|
|
|
* Hence simply check whether any bit is set in modeset_pipes in all the
|
|
|
|
* pieces of code that are not yet converted to deal with mutliple crtcs
|
|
|
|
* changing their mode at the same time. */
|
|
|
|
adjusted_mode = NULL;
|
|
|
|
if (modeset_pipes) {
|
|
|
|
adjusted_mode = intel_modeset_adjusted_mode(crtc, mode);
|
|
|
|
if (IS_ERR(adjusted_mode)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2012-07-02 07:56:42 +00:00
|
|
|
|
2012-07-10 08:42:52 +00:00
|
|
|
for_each_intel_crtc_masked(dev, prepare_pipes, intel_crtc) {
|
|
|
|
if (intel_crtc->base.enabled)
|
|
|
|
dev_priv->display.crtc_disable(&intel_crtc->base);
|
|
|
|
}
|
2012-07-02 07:56:42 +00:00
|
|
|
|
2012-09-10 19:58:30 +00:00
|
|
|
/* crtc->mode is already used by the ->mode_set callbacks, hence we need
|
|
|
|
* to set it here already despite that we pass it down the callchain.
|
|
|
|
*/
|
|
|
|
if (modeset_pipes)
|
2012-07-08 20:08:04 +00:00
|
|
|
crtc->mode = *mode;
|
2012-07-08 17:40:39 +00:00
|
|
|
|
2012-07-10 08:42:52 +00:00
|
|
|
/* Only after disabling all output pipelines that will be changed can we
|
|
|
|
* update the the output configuration. */
|
|
|
|
intel_modeset_update_state(dev, prepare_pipes);
|
|
|
|
|
2012-07-02 07:56:42 +00:00
|
|
|
/* Set up the DPLL and any encoders state that needs to adjust or depend
|
|
|
|
* on the DPLL.
|
|
|
|
*/
|
2012-07-08 20:08:04 +00:00
|
|
|
for_each_intel_crtc_masked(dev, modeset_pipes, intel_crtc) {
|
|
|
|
ret = !intel_crtc_mode_set(&intel_crtc->base,
|
|
|
|
mode, adjusted_mode,
|
|
|
|
x, y, fb);
|
|
|
|
if (!ret)
|
|
|
|
goto done;
|
2012-07-02 07:56:42 +00:00
|
|
|
|
2012-07-08 20:08:04 +00:00
|
|
|
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
2012-07-02 07:56:42 +00:00
|
|
|
|
2012-07-08 20:08:04 +00:00
|
|
|
if (encoder->crtc != &intel_crtc->base)
|
|
|
|
continue;
|
2012-07-02 07:56:42 +00:00
|
|
|
|
2012-07-08 20:08:04 +00:00
|
|
|
DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%d:%s]\n",
|
|
|
|
encoder->base.id, drm_get_encoder_name(encoder),
|
|
|
|
mode->base.id, mode->name);
|
|
|
|
encoder_funcs = encoder->helper_private;
|
|
|
|
encoder_funcs->mode_set(encoder, mode, adjusted_mode);
|
|
|
|
}
|
2012-07-02 07:56:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Now enable the clocks, plane, pipe, and connectors that we set up. */
|
2012-07-08 20:08:04 +00:00
|
|
|
for_each_intel_crtc_masked(dev, prepare_pipes, intel_crtc)
|
|
|
|
dev_priv->display.crtc_enable(&intel_crtc->base);
|
2012-07-02 07:56:42 +00:00
|
|
|
|
2012-07-08 20:08:04 +00:00
|
|
|
if (modeset_pipes) {
|
|
|
|
/* Store real post-adjustment hardware mode. */
|
|
|
|
crtc->hwmode = *adjusted_mode;
|
2012-07-02 07:56:42 +00:00
|
|
|
|
2012-07-08 20:08:04 +00:00
|
|
|
/* Calculate and store various constants which
|
|
|
|
* are later needed by vblank and swap-completion
|
|
|
|
* timestamping. They are derived from true hwmode.
|
|
|
|
*/
|
|
|
|
drm_calc_timestamping_constants(crtc);
|
|
|
|
}
|
2012-07-02 07:56:42 +00:00
|
|
|
|
|
|
|
/* FIXME: add subpixel order */
|
|
|
|
done:
|
|
|
|
drm_mode_destroy(dev, adjusted_mode);
|
2012-07-08 20:08:04 +00:00
|
|
|
if (!ret && crtc->enabled) {
|
2012-07-02 07:56:42 +00:00
|
|
|
crtc->hwmode = saved_hwmode;
|
|
|
|
crtc->mode = saved_mode;
|
2012-07-10 07:50:11 +00:00
|
|
|
} else {
|
|
|
|
intel_modeset_check_state(dev);
|
2012-07-02 07:56:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2012-07-08 20:08:04 +00:00
|
|
|
#undef for_each_intel_crtc_masked
|
|
|
|
|
2012-07-04 20:16:09 +00:00
|
|
|
static void intel_set_config_free(struct intel_set_config *config)
|
|
|
|
{
|
|
|
|
if (!config)
|
|
|
|
return;
|
|
|
|
|
2012-07-05 14:20:48 +00:00
|
|
|
kfree(config->save_connector_encoders);
|
|
|
|
kfree(config->save_encoder_crtcs);
|
2012-07-04 20:16:09 +00:00
|
|
|
kfree(config);
|
|
|
|
}
|
|
|
|
|
2012-07-04 20:24:08 +00:00
|
|
|
static int intel_set_config_save_state(struct drm_device *dev,
|
|
|
|
struct intel_set_config *config)
|
|
|
|
{
|
|
|
|
struct drm_encoder *encoder;
|
|
|
|
struct drm_connector *connector;
|
|
|
|
int count;
|
|
|
|
|
2012-07-05 14:20:48 +00:00
|
|
|
config->save_encoder_crtcs =
|
|
|
|
kcalloc(dev->mode_config.num_encoder,
|
|
|
|
sizeof(struct drm_crtc *), GFP_KERNEL);
|
|
|
|
if (!config->save_encoder_crtcs)
|
2012-07-04 20:24:08 +00:00
|
|
|
return -ENOMEM;
|
|
|
|
|
2012-07-05 14:20:48 +00:00
|
|
|
config->save_connector_encoders =
|
|
|
|
kcalloc(dev->mode_config.num_connector,
|
|
|
|
sizeof(struct drm_encoder *), GFP_KERNEL);
|
|
|
|
if (!config->save_connector_encoders)
|
2012-07-04 20:24:08 +00:00
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
/* Copy data. Note that driver private data is not affected.
|
|
|
|
* Should anything bad happen only the expected state is
|
|
|
|
* restored, not the drivers personal bookkeeping.
|
|
|
|
*/
|
|
|
|
count = 0;
|
|
|
|
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
2012-07-05 14:20:48 +00:00
|
|
|
config->save_encoder_crtcs[count++] = encoder->crtc;
|
2012-07-04 20:24:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
count = 0;
|
|
|
|
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
2012-07-05 14:20:48 +00:00
|
|
|
config->save_connector_encoders[count++] = connector->encoder;
|
2012-07-04 20:24:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void intel_set_config_restore_state(struct drm_device *dev,
|
|
|
|
struct intel_set_config *config)
|
|
|
|
{
|
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 20:34:27 +00:00
|
|
|
struct intel_encoder *encoder;
|
|
|
|
struct intel_connector *connector;
|
2012-07-04 20:24:08 +00:00
|
|
|
int count;
|
|
|
|
|
|
|
|
count = 0;
|
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 20:34:27 +00:00
|
|
|
list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) {
|
|
|
|
encoder->new_crtc =
|
|
|
|
to_intel_crtc(config->save_encoder_crtcs[count++]);
|
2012-07-04 20:24:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
count = 0;
|
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 20:34:27 +00:00
|
|
|
list_for_each_entry(connector, &dev->mode_config.connector_list, base.head) {
|
|
|
|
connector->new_encoder =
|
|
|
|
to_intel_encoder(config->save_connector_encoders[count++]);
|
2012-07-04 20:24:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-04 20:41:29 +00:00
|
|
|
static void
|
|
|
|
intel_set_config_compute_mode_changes(struct drm_mode_set *set,
|
|
|
|
struct intel_set_config *config)
|
|
|
|
{
|
|
|
|
|
|
|
|
/* We should be able to check here if the fb has the same properties
|
|
|
|
* and then just flip_or_move it */
|
|
|
|
if (set->crtc->fb != set->fb) {
|
|
|
|
/* If we have no fb then treat it as a full mode set */
|
|
|
|
if (set->crtc->fb == NULL) {
|
|
|
|
DRM_DEBUG_KMS("crtc has no fb, full mode set\n");
|
|
|
|
config->mode_changed = true;
|
|
|
|
} else if (set->fb == NULL) {
|
|
|
|
config->mode_changed = true;
|
|
|
|
} else if (set->fb->depth != set->crtc->fb->depth) {
|
|
|
|
config->mode_changed = true;
|
|
|
|
} else if (set->fb->bits_per_pixel !=
|
|
|
|
set->crtc->fb->bits_per_pixel) {
|
|
|
|
config->mode_changed = true;
|
|
|
|
} else
|
|
|
|
config->fb_changed = true;
|
|
|
|
}
|
|
|
|
|
2012-07-10 16:11:08 +00:00
|
|
|
if (set->fb && (set->x != set->crtc->x || set->y != set->crtc->y))
|
2012-07-04 20:41:29 +00:00
|
|
|
config->fb_changed = true;
|
|
|
|
|
|
|
|
if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) {
|
|
|
|
DRM_DEBUG_KMS("modes are different, full mode set\n");
|
|
|
|
drm_mode_debug_printmodeline(&set->crtc->mode);
|
|
|
|
drm_mode_debug_printmodeline(set->mode);
|
|
|
|
config->mode_changed = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-04 20:42:15 +00:00
|
|
|
static int
|
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 20:34:27 +00:00
|
|
|
intel_modeset_stage_output_state(struct drm_device *dev,
|
|
|
|
struct drm_mode_set *set,
|
|
|
|
struct intel_set_config *config)
|
2012-07-02 07:35:43 +00:00
|
|
|
{
|
2012-07-04 20:24:08 +00:00
|
|
|
struct drm_crtc *new_crtc;
|
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 20:34:27 +00:00
|
|
|
struct intel_connector *connector;
|
|
|
|
struct intel_encoder *encoder;
|
2012-07-04 20:42:15 +00:00
|
|
|
int count, ro;
|
2012-07-02 07:35:43 +00: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 20:34:27 +00:00
|
|
|
/* The upper layers ensure that we either disabl a crtc or have a list
|
|
|
|
* of connectors. For paranoia, double-check this. */
|
|
|
|
WARN_ON(!set->fb && (set->num_connectors != 0));
|
|
|
|
WARN_ON(set->fb && (set->num_connectors == 0));
|
|
|
|
|
2012-07-02 07:35:43 +00:00
|
|
|
count = 0;
|
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 20:34:27 +00:00
|
|
|
list_for_each_entry(connector, &dev->mode_config.connector_list,
|
|
|
|
base.head) {
|
|
|
|
/* Otherwise traverse passed in connector list and get encoders
|
|
|
|
* for them. */
|
2012-07-02 07:35:43 +00:00
|
|
|
for (ro = 0; ro < set->num_connectors; ro++) {
|
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 20:34:27 +00:00
|
|
|
if (set->connectors[ro] == &connector->base) {
|
|
|
|
connector->new_encoder = connector->encoder;
|
2012-07-02 07:35:43 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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 20:34:27 +00:00
|
|
|
/* If we disable the crtc, disable all its connectors. Also, if
|
|
|
|
* the connector is on the changing crtc but not on the new
|
|
|
|
* connector list, disable it. */
|
|
|
|
if ((!set->fb || ro == set->num_connectors) &&
|
|
|
|
connector->base.encoder &&
|
|
|
|
connector->base.encoder->crtc == set->crtc) {
|
|
|
|
connector->new_encoder = NULL;
|
|
|
|
|
|
|
|
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n",
|
|
|
|
connector->base.base.id,
|
|
|
|
drm_get_connector_name(&connector->base));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (&connector->new_encoder->base != connector->base.encoder) {
|
2012-07-02 07:35:43 +00:00
|
|
|
DRM_DEBUG_KMS("encoder changed, full mode switch\n");
|
2012-07-04 20:41:29 +00:00
|
|
|
config->mode_changed = true;
|
2012-07-02 07:35:43 +00: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 20:34:27 +00:00
|
|
|
|
|
|
|
/* Disable all disconnected encoders. */
|
|
|
|
if (connector->base.status == connector_status_disconnected)
|
|
|
|
connector->new_encoder = NULL;
|
2012-07-02 07:35:43 +00: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 20:34:27 +00:00
|
|
|
/* connector->new_encoder is now updated for all connectors. */
|
2012-07-02 07:35:43 +00: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 20:34:27 +00:00
|
|
|
/* Update crtc of enabled connectors. */
|
2012-07-02 07:35:43 +00:00
|
|
|
count = 0;
|
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 20:34:27 +00:00
|
|
|
list_for_each_entry(connector, &dev->mode_config.connector_list,
|
|
|
|
base.head) {
|
|
|
|
if (!connector->new_encoder)
|
2012-07-02 07:35:43 +00:00
|
|
|
continue;
|
|
|
|
|
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 20:34:27 +00:00
|
|
|
new_crtc = connector->new_encoder->base.crtc;
|
2012-07-02 07:35:43 +00:00
|
|
|
|
|
|
|
for (ro = 0; ro < set->num_connectors; ro++) {
|
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 20:34:27 +00:00
|
|
|
if (set->connectors[ro] == &connector->base)
|
2012-07-02 07:35:43 +00:00
|
|
|
new_crtc = set->crtc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make sure the new CRTC will work with the encoder */
|
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 20:34:27 +00:00
|
|
|
if (!intel_encoder_crtc_ok(&connector->new_encoder->base,
|
|
|
|
new_crtc)) {
|
2012-07-04 20:41:29 +00:00
|
|
|
return -EINVAL;
|
2012-07-02 07:35:43 +00: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 20:34:27 +00:00
|
|
|
connector->encoder->new_crtc = to_intel_crtc(new_crtc);
|
|
|
|
|
|
|
|
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n",
|
|
|
|
connector->base.base.id,
|
|
|
|
drm_get_connector_name(&connector->base),
|
|
|
|
new_crtc->base.id);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check for any encoders that needs to be disabled. */
|
|
|
|
list_for_each_entry(encoder, &dev->mode_config.encoder_list,
|
|
|
|
base.head) {
|
|
|
|
list_for_each_entry(connector,
|
|
|
|
&dev->mode_config.connector_list,
|
|
|
|
base.head) {
|
|
|
|
if (connector->new_encoder == encoder) {
|
|
|
|
WARN_ON(!connector->new_encoder->new_crtc);
|
|
|
|
|
|
|
|
goto next_encoder;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
encoder->new_crtc = NULL;
|
|
|
|
next_encoder:
|
|
|
|
/* Only now check for crtc changes so we don't miss encoders
|
|
|
|
* that will be disabled. */
|
|
|
|
if (&encoder->new_crtc->base != encoder->base.crtc) {
|
2012-07-02 07:35:43 +00:00
|
|
|
DRM_DEBUG_KMS("crtc changed, full mode switch\n");
|
2012-07-04 20:41:29 +00:00
|
|
|
config->mode_changed = true;
|
2012-07-02 07:35:43 +00: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 20:34:27 +00:00
|
|
|
/* Now we've also updated encoder->new_crtc for all encoders. */
|
2012-07-02 07:35:43 +00:00
|
|
|
|
2012-07-04 20:42:15 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int intel_crtc_set_config(struct drm_mode_set *set)
|
|
|
|
{
|
|
|
|
struct drm_device *dev;
|
|
|
|
struct drm_mode_set save_set;
|
|
|
|
struct intel_set_config *config;
|
|
|
|
int ret;
|
|
|
|
|
2012-07-05 14:09:09 +00:00
|
|
|
BUG_ON(!set);
|
|
|
|
BUG_ON(!set->crtc);
|
|
|
|
BUG_ON(!set->crtc->helper_private);
|
2012-07-04 20:42:15 +00:00
|
|
|
|
|
|
|
if (!set->mode)
|
|
|
|
set->fb = NULL;
|
|
|
|
|
2012-07-10 15:53:42 +00:00
|
|
|
/* The fb helper likes to play gross jokes with ->mode_set_config.
|
|
|
|
* Unfortunately the crtc helper doesn't do much at all for this case,
|
|
|
|
* so we have to cope with this madness until the fb helper is fixed up. */
|
|
|
|
if (set->fb && set->num_connectors == 0)
|
|
|
|
return 0;
|
|
|
|
|
2012-07-04 20:42:15 +00:00
|
|
|
if (set->fb) {
|
|
|
|
DRM_DEBUG_KMS("[CRTC:%d] [FB:%d] #connectors=%d (x y) (%i %i)\n",
|
|
|
|
set->crtc->base.id, set->fb->base.id,
|
|
|
|
(int)set->num_connectors, set->x, set->y);
|
|
|
|
} else {
|
|
|
|
DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id);
|
|
|
|
}
|
|
|
|
|
|
|
|
dev = set->crtc->dev;
|
|
|
|
|
|
|
|
ret = -ENOMEM;
|
|
|
|
config = kzalloc(sizeof(*config), GFP_KERNEL);
|
|
|
|
if (!config)
|
|
|
|
goto out_config;
|
|
|
|
|
|
|
|
ret = intel_set_config_save_state(dev, config);
|
|
|
|
if (ret)
|
|
|
|
goto out_config;
|
|
|
|
|
|
|
|
save_set.crtc = set->crtc;
|
|
|
|
save_set.mode = &set->crtc->mode;
|
|
|
|
save_set.x = set->crtc->x;
|
|
|
|
save_set.y = set->crtc->y;
|
|
|
|
save_set.fb = set->crtc->fb;
|
|
|
|
|
|
|
|
/* Compute whether we need a full modeset, only an fb base update or no
|
|
|
|
* change at all. In the future we might also check whether only the
|
|
|
|
* mode changed, e.g. for LVDS where we only change the panel fitter in
|
|
|
|
* such cases. */
|
|
|
|
intel_set_config_compute_mode_changes(set, config);
|
|
|
|
|
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 20:34:27 +00:00
|
|
|
ret = intel_modeset_stage_output_state(dev, set, config);
|
2012-07-04 20:42:15 +00:00
|
|
|
if (ret)
|
|
|
|
goto fail;
|
|
|
|
|
2012-07-04 20:41:29 +00:00
|
|
|
if (config->mode_changed) {
|
2012-07-05 21:36:17 +00:00
|
|
|
if (set->mode) {
|
2012-07-02 07:35:43 +00:00
|
|
|
DRM_DEBUG_KMS("attempting to set mode from"
|
|
|
|
" userspace\n");
|
|
|
|
drm_mode_debug_printmodeline(set->mode);
|
2012-07-05 21:36:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!intel_set_mode(set->crtc, set->mode,
|
|
|
|
set->x, set->y, set->fb)) {
|
|
|
|
DRM_ERROR("failed to set mode on [CRTC:%d]\n",
|
|
|
|
set->crtc->base.id);
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto fail;
|
|
|
|
}
|
2012-07-04 20:41:29 +00:00
|
|
|
} else if (config->fb_changed) {
|
2012-07-02 07:47:37 +00:00
|
|
|
ret = intel_pipe_set_base(set->crtc,
|
drm/i915: push crtc->fb update into pipe_set_base
Passing in the old fb, having overwritten the current fb, leads to
some neatly convoluted code. It's much simpler if we defer the
crtc->fb update to the place that updates the hw, in pipe_set_base.
This way we also don't need to restore anything in case something
fails - we only update crtc->fb once things have succeeded.
The real reason for this change is that now we keep the old fb
assigned to crtc->fb, which allows us to finally move the crtc disable
case into the common low-level set_mode function in the next patch.
Also don't clobber crtc->x and crtc->y, we neatly pass these down the
callchain already. Unfortunately we can't do the same with crtc->mode,
because that one is being used in the mode_set callbacks.
v2: Don't restore the drm_crtc object any more on failed modesets,
since we've lose an fb reference otherwise. Also (and this is the
reason this has been found), this totally confused the modeset state
tracking, since it clobbers crtc->enabled. Issue reported by Paulo
Zanoni.
v3: Rip out the entire crtc saving into struct intel_set_config, not
just the restoring part.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2012-07-05 20:51:56 +00:00
|
|
|
set->x, set->y, set->fb);
|
2012-07-02 07:35:43 +00:00
|
|
|
}
|
|
|
|
|
2012-07-04 20:16:09 +00:00
|
|
|
intel_set_config_free(config);
|
|
|
|
|
2012-07-02 07:35:43 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
fail:
|
2012-07-04 20:24:08 +00:00
|
|
|
intel_set_config_restore_state(dev, config);
|
2012-07-02 07:35:43 +00:00
|
|
|
|
|
|
|
/* Try to restore the config */
|
2012-07-04 20:41:29 +00:00
|
|
|
if (config->mode_changed &&
|
2012-07-02 07:56:42 +00:00
|
|
|
!intel_set_mode(save_set.crtc, save_set.mode,
|
|
|
|
save_set.x, save_set.y, save_set.fb))
|
2012-07-02 07:35:43 +00:00
|
|
|
DRM_ERROR("failed to restore config after modeset failure\n");
|
|
|
|
|
2012-07-04 20:16:09 +00:00
|
|
|
out_config:
|
|
|
|
intel_set_config_free(config);
|
2012-07-02 07:35:43 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-04-12 17:06:51 +00:00
|
|
|
static const struct drm_crtc_funcs intel_crtc_funcs = {
|
|
|
|
.cursor_set = intel_crtc_cursor_set,
|
|
|
|
.cursor_move = intel_crtc_cursor_move,
|
|
|
|
.gamma_set = intel_crtc_gamma_set,
|
2012-07-02 07:35:43 +00:00
|
|
|
.set_config = intel_crtc_set_config,
|
2011-04-12 17:06:51 +00:00
|
|
|
.destroy = intel_crtc_destroy,
|
|
|
|
.page_flip = intel_crtc_page_flip,
|
|
|
|
};
|
|
|
|
|
2012-04-20 16:11:53 +00:00
|
|
|
static void intel_pch_pll_init(struct drm_device *dev)
|
|
|
|
{
|
|
|
|
drm_i915_private_t *dev_priv = dev->dev_private;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (dev_priv->num_pch_pll == 0) {
|
|
|
|
DRM_DEBUG_KMS("No PCH PLLs on this hardware, skipping initialisation\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < dev_priv->num_pch_pll; i++) {
|
|
|
|
dev_priv->pch_plls[i].pll_reg = _PCH_DPLL(i);
|
|
|
|
dev_priv->pch_plls[i].fp0_reg = _PCH_FP0(i);
|
|
|
|
dev_priv->pch_plls[i].fp1_reg = _PCH_FP1(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-18 20:18:47 +00:00
|
|
|
static void intel_crtc_init(struct drm_device *dev, int pipe)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
{
|
2009-12-02 21:42:53 +00:00
|
|
|
drm_i915_private_t *dev_priv = dev->dev_private;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
struct intel_crtc *intel_crtc;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
intel_crtc = kzalloc(sizeof(struct intel_crtc) + (INTELFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
|
|
|
|
if (intel_crtc == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
drm_crtc_init(dev, &intel_crtc->base, &intel_crtc_funcs);
|
|
|
|
|
|
|
|
drm_mode_crtc_set_gamma_size(&intel_crtc->base, 256);
|
|
|
|
for (i = 0; i < 256; i++) {
|
|
|
|
intel_crtc->lut_r[i] = i;
|
|
|
|
intel_crtc->lut_g[i] = i;
|
|
|
|
intel_crtc->lut_b[i] = i;
|
|
|
|
}
|
|
|
|
|
2009-09-10 22:28:06 +00:00
|
|
|
/* Swap pipes & planes for FBC on pre-965 */
|
|
|
|
intel_crtc->pipe = pipe;
|
|
|
|
intel_crtc->plane = pipe;
|
2010-09-13 15:53:12 +00:00
|
|
|
if (IS_MOBILE(dev) && IS_GEN3(dev)) {
|
2009-10-09 03:39:41 +00:00
|
|
|
DRM_DEBUG_KMS("swapping pipes & planes for FBC\n");
|
2010-09-13 15:53:12 +00:00
|
|
|
intel_crtc->plane = !pipe;
|
2009-09-10 22:28:06 +00:00
|
|
|
}
|
|
|
|
|
2009-12-02 21:42:53 +00:00
|
|
|
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;
|
|
|
|
|
2011-06-24 19:19:22 +00:00
|
|
|
intel_crtc->bpp = 24; /* default for pre-Ironlake */
|
2010-09-10 17:47:20 +00:00
|
|
|
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
|
|
|
|
}
|
|
|
|
|
2009-04-29 21:43:54 +00:00
|
|
|
int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
|
2010-11-08 19:18:58 +00:00
|
|
|
struct drm_file *file)
|
2009-04-29 21:43:54 +00:00
|
|
|
{
|
|
|
|
struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data;
|
2009-08-11 14:05:30 +00:00
|
|
|
struct drm_mode_object *drmmode_obj;
|
|
|
|
struct intel_crtc *crtc;
|
2009-04-29 21:43:54 +00:00
|
|
|
|
2012-04-24 07:55:08 +00:00
|
|
|
if (!drm_core_check_feature(dev, DRIVER_MODESET))
|
|
|
|
return -ENODEV;
|
2009-04-29 21:43:54 +00:00
|
|
|
|
2009-08-11 14:05:30 +00:00
|
|
|
drmmode_obj = drm_mode_object_find(dev, pipe_from_crtc_id->crtc_id,
|
|
|
|
DRM_MODE_OBJECT_CRTC);
|
2009-04-29 21:43:54 +00:00
|
|
|
|
2009-08-11 14:05:30 +00:00
|
|
|
if (!drmmode_obj) {
|
2009-04-29 21:43:54 +00:00
|
|
|
DRM_ERROR("no such CRTC id\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2009-08-11 14:05:30 +00:00
|
|
|
crtc = to_intel_crtc(obj_to_crtc(drmmode_obj));
|
|
|
|
pipe_from_crtc_id->pipe = crtc->pipe;
|
2009-04-29 21:43:54 +00:00
|
|
|
|
2009-08-11 14:05:30 +00:00
|
|
|
return 0;
|
2009-04-29 21:43:54 +00:00
|
|
|
}
|
|
|
|
|
2012-07-12 18:08:18 +00:00
|
|
|
static int intel_encoder_clones(struct intel_encoder *encoder)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
{
|
2012-07-12 18:08:18 +00:00
|
|
|
struct drm_device *dev = encoder->base.dev;
|
|
|
|
struct intel_encoder *source_encoder;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
int index_mask = 0;
|
|
|
|
int entry = 0;
|
|
|
|
|
2012-07-12 18:08:18 +00:00
|
|
|
list_for_each_entry(source_encoder,
|
|
|
|
&dev->mode_config.encoder_list, base.head) {
|
|
|
|
|
|
|
|
if (encoder == source_encoder)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
index_mask |= (1 << entry);
|
2012-07-12 18:08:18 +00:00
|
|
|
|
|
|
|
/* Intel hw has only one MUX where enocoders could be cloned. */
|
|
|
|
if (encoder->cloneable && source_encoder->cloneable)
|
|
|
|
index_mask |= (1 << entry);
|
|
|
|
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
entry++;
|
|
|
|
}
|
2010-09-09 14:14:28 +00:00
|
|
|
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
return index_mask;
|
|
|
|
}
|
|
|
|
|
2010-12-14 19:21:29 +00:00
|
|
|
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(ILK_DISPLAY_CHICKEN_FUSES) & ILK_eDP_A_DISABLE))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
static void intel_setup_outputs(struct drm_device *dev)
|
|
|
|
{
|
2009-01-22 21:01:02 +00:00
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
2010-09-09 14:14:28 +00:00
|
|
|
struct intel_encoder *encoder;
|
2010-07-16 18:46:29 +00:00
|
|
|
bool dpd_is_edp = false;
|
2012-02-09 09:35:53 +00:00
|
|
|
bool has_lvds;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2012-02-09 09:35:53 +00:00
|
|
|
has_lvds = intel_lvds_init(dev);
|
2010-11-29 18:00:23 +00:00
|
|
|
if (!has_lvds && !HAS_PCH_SPLIT(dev)) {
|
|
|
|
/* disable the panel fitter on everything but LVDS */
|
|
|
|
I915_WRITE(PFIT_CONTROL, 0);
|
|
|
|
}
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2009-10-22 23:11:14 +00:00
|
|
|
if (HAS_PCH_SPLIT(dev)) {
|
2010-07-16 18:46:29 +00:00
|
|
|
dpd_is_edp = intel_dpd_is_edp(dev);
|
2009-06-05 07:38:43 +00:00
|
|
|
|
2010-12-14 19:21:29 +00:00
|
|
|
if (has_edp_a(dev))
|
2012-07-17 20:53:45 +00:00
|
|
|
intel_dp_init(dev, DP_A, PORT_A);
|
2009-07-23 17:00:32 +00:00
|
|
|
|
2010-07-16 18:46:29 +00:00
|
|
|
if (dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED))
|
2012-07-17 20:53:45 +00:00
|
|
|
intel_dp_init(dev, PCH_DP_D, PORT_D);
|
2010-07-16 18:46:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
intel_crt_init(dev);
|
|
|
|
|
2012-05-09 18:37:27 +00:00
|
|
|
if (IS_HASWELL(dev)) {
|
|
|
|
int found;
|
|
|
|
|
|
|
|
/* Haswell uses DDI functions to detect digital outputs */
|
|
|
|
found = I915_READ(DDI_BUF_CTL_A) & DDI_INIT_DISPLAY_DETECTED;
|
|
|
|
/* DDI A only supports eDP */
|
|
|
|
if (found)
|
|
|
|
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);
|
|
|
|
} else if (HAS_PCH_SPLIT(dev)) {
|
2010-07-16 18:46:29 +00:00
|
|
|
int found;
|
|
|
|
|
2009-06-05 07:38:43 +00:00
|
|
|
if (I915_READ(HDMIB) & PORT_DETECTED) {
|
2010-03-30 07:11:33 +00:00
|
|
|
/* PCH SDVOB multiplex with HDMIB */
|
2012-03-23 22:43:35 +00:00
|
|
|
found = intel_sdvo_init(dev, PCH_SDVOB, true);
|
2009-06-05 07:38:43 +00:00
|
|
|
if (!found)
|
2012-07-12 18:19:59 +00:00
|
|
|
intel_hdmi_init(dev, HDMIB, PORT_B);
|
2009-07-23 17:00:31 +00:00
|
|
|
if (!found && (I915_READ(PCH_DP_B) & DP_DETECTED))
|
2012-07-17 20:53:45 +00:00
|
|
|
intel_dp_init(dev, PCH_DP_B, PORT_B);
|
2009-06-05 07:38:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (I915_READ(HDMIC) & PORT_DETECTED)
|
2012-07-12 18:19:59 +00:00
|
|
|
intel_hdmi_init(dev, HDMIC, PORT_C);
|
2009-06-05 07:38:43 +00:00
|
|
|
|
2012-06-11 18:39:56 +00:00
|
|
|
if (!dpd_is_edp && I915_READ(HDMID) & PORT_DETECTED)
|
2012-07-12 18:19:59 +00:00
|
|
|
intel_hdmi_init(dev, HDMID, PORT_D);
|
2009-06-05 07:38:43 +00:00
|
|
|
|
2009-07-23 17:00:31 +00:00
|
|
|
if (I915_READ(PCH_DP_C) & DP_DETECTED)
|
2012-07-17 20:53:45 +00:00
|
|
|
intel_dp_init(dev, PCH_DP_C, PORT_C);
|
2009-07-23 17:00:31 +00:00
|
|
|
|
2010-07-16 18:46:29 +00:00
|
|
|
if (!dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED))
|
2012-07-17 20:53:45 +00:00
|
|
|
intel_dp_init(dev, PCH_DP_D, PORT_D);
|
2012-06-15 18:55:16 +00:00
|
|
|
} else if (IS_VALLEYVIEW(dev)) {
|
|
|
|
int found;
|
|
|
|
|
|
|
|
if (I915_READ(SDVOB) & PORT_DETECTED) {
|
|
|
|
/* SDVOB multiplex with HDMIB */
|
|
|
|
found = intel_sdvo_init(dev, SDVOB, true);
|
|
|
|
if (!found)
|
2012-07-12 18:19:59 +00:00
|
|
|
intel_hdmi_init(dev, SDVOB, PORT_B);
|
2012-06-15 18:55:16 +00:00
|
|
|
if (!found && (I915_READ(DP_B) & DP_DETECTED))
|
2012-07-17 20:53:45 +00:00
|
|
|
intel_dp_init(dev, DP_B, PORT_B);
|
2012-06-15 18:55:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (I915_READ(SDVOC) & PORT_DETECTED)
|
2012-07-12 18:19:59 +00:00
|
|
|
intel_hdmi_init(dev, SDVOC, PORT_C);
|
2009-07-23 17:00:31 +00:00
|
|
|
|
2012-06-15 18:55:16 +00:00
|
|
|
/* Shares lanes with HDMI on SDVOC */
|
|
|
|
if (I915_READ(DP_C) & DP_DETECTED)
|
2012-07-17 20:53:45 +00:00
|
|
|
intel_dp_init(dev, DP_C, PORT_C);
|
2009-11-27 03:44:36 +00:00
|
|
|
} else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) {
|
2009-08-24 05:50:23 +00:00
|
|
|
bool found = false;
|
2009-01-02 21:33:00 +00:00
|
|
|
|
2009-01-22 21:01:02 +00:00
|
|
|
if (I915_READ(SDVOB) & SDVO_DETECTED) {
|
2009-12-11 19:07:17 +00:00
|
|
|
DRM_DEBUG_KMS("probing SDVOB\n");
|
2012-03-23 22:43:35 +00:00
|
|
|
found = intel_sdvo_init(dev, SDVOB, true);
|
2009-12-11 19:07:17 +00:00
|
|
|
if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) {
|
|
|
|
DRM_DEBUG_KMS("probing HDMI on SDVOB\n");
|
2012-07-12 18:19:59 +00:00
|
|
|
intel_hdmi_init(dev, SDVOB, PORT_B);
|
2009-12-11 19:07:17 +00:00
|
|
|
}
|
2009-08-24 05:50:23 +00:00
|
|
|
|
2009-12-11 19:07:17 +00:00
|
|
|
if (!found && SUPPORTS_INTEGRATED_DP(dev)) {
|
|
|
|
DRM_DEBUG_KMS("probing DP_B\n");
|
2012-07-17 20:53:45 +00:00
|
|
|
intel_dp_init(dev, DP_B, PORT_B);
|
2009-12-11 19:07:17 +00:00
|
|
|
}
|
2009-01-22 21:01:02 +00:00
|
|
|
}
|
2009-03-13 19:42:14 +00:00
|
|
|
|
|
|
|
/* Before G4X SDVOC doesn't have its own detect register */
|
|
|
|
|
2009-12-11 19:07:17 +00:00
|
|
|
if (I915_READ(SDVOB) & SDVO_DETECTED) {
|
|
|
|
DRM_DEBUG_KMS("probing SDVOC\n");
|
2012-03-23 22:43:35 +00:00
|
|
|
found = intel_sdvo_init(dev, SDVOC, false);
|
2009-12-11 19:07:17 +00:00
|
|
|
}
|
2009-08-24 05:50:23 +00:00
|
|
|
|
|
|
|
if (!found && (I915_READ(SDVOC) & SDVO_DETECTED)) {
|
|
|
|
|
2009-12-11 19:07:17 +00:00
|
|
|
if (SUPPORTS_INTEGRATED_HDMI(dev)) {
|
|
|
|
DRM_DEBUG_KMS("probing HDMI on SDVOC\n");
|
2012-07-12 18:19:59 +00:00
|
|
|
intel_hdmi_init(dev, SDVOC, PORT_C);
|
2009-12-11 19:07:17 +00:00
|
|
|
}
|
|
|
|
if (SUPPORTS_INTEGRATED_DP(dev)) {
|
|
|
|
DRM_DEBUG_KMS("probing DP_C\n");
|
2012-07-17 20:53:45 +00:00
|
|
|
intel_dp_init(dev, DP_C, PORT_C);
|
2009-12-11 19:07:17 +00:00
|
|
|
}
|
2009-01-22 21:01:02 +00:00
|
|
|
}
|
2009-08-24 05:50:23 +00:00
|
|
|
|
2009-12-11 19:07:17 +00:00
|
|
|
if (SUPPORTS_INTEGRATED_DP(dev) &&
|
|
|
|
(I915_READ(DP_D) & DP_DETECTED)) {
|
|
|
|
DRM_DEBUG_KMS("probing DP_D\n");
|
2012-07-17 20:53:45 +00:00
|
|
|
intel_dp_init(dev, DP_D, PORT_D);
|
2009-12-11 19:07:17 +00:00
|
|
|
}
|
2009-10-22 23:11:14 +00:00
|
|
|
} else if (IS_GEN2(dev))
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
intel_dvo_init(dev);
|
|
|
|
|
2009-11-27 03:44:36 +00:00
|
|
|
if (SUPPORTS_TV(dev))
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
intel_tv_init(dev);
|
|
|
|
|
2010-09-09 14:14:28 +00:00
|
|
|
list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) {
|
|
|
|
encoder->base.possible_crtcs = encoder->crtc_mask;
|
|
|
|
encoder->base.possible_clones =
|
2012-07-12 18:08:18 +00:00
|
|
|
intel_encoder_clones(encoder);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
2011-01-11 17:06:04 +00:00
|
|
|
|
2012-07-03 18:57:33 +00:00
|
|
|
if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
|
2011-09-27 05:24:57 +00:00
|
|
|
ironlake_init_pch_refclk(dev);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
|
|
|
|
{
|
|
|
|
struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
|
|
|
|
|
|
|
|
drm_framebuffer_cleanup(fb);
|
2010-11-08 19:18:58 +00:00
|
|
|
drm_gem_object_unreference_unlocked(&intel_fb->obj->base);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
|
|
|
kfree(intel_fb);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb,
|
2010-11-08 19:18:58 +00:00
|
|
|
struct drm_file *file,
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
unsigned int *handle)
|
|
|
|
{
|
|
|
|
struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
|
2010-11-08 19:18:58 +00:00
|
|
|
struct drm_i915_gem_object *obj = intel_fb->obj;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2010-11-08 19:18:58 +00:00
|
|
|
return drm_gem_handle_create(file, &obj->base, handle);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static const struct drm_framebuffer_funcs intel_fb_funcs = {
|
|
|
|
.destroy = intel_user_framebuffer_destroy,
|
|
|
|
.create_handle = intel_user_framebuffer_create_handle,
|
|
|
|
};
|
|
|
|
|
2010-03-30 05:34:13 +00:00
|
|
|
int intel_framebuffer_init(struct drm_device *dev,
|
|
|
|
struct intel_framebuffer *intel_fb,
|
2011-11-14 22:51:28 +00:00
|
|
|
struct drm_mode_fb_cmd2 *mode_cmd,
|
2010-11-08 19:18:58 +00:00
|
|
|
struct drm_i915_gem_object *obj)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
2010-11-08 19:18:58 +00:00
|
|
|
if (obj->tiling_mode == I915_TILING_Y)
|
2010-08-08 11:34:44 +00:00
|
|
|
return -EINVAL;
|
|
|
|
|
2011-11-14 22:51:28 +00:00
|
|
|
if (mode_cmd->pitches[0] & 63)
|
2010-08-08 11:34:44 +00:00
|
|
|
return -EINVAL;
|
|
|
|
|
2011-11-14 22:51:28 +00:00
|
|
|
switch (mode_cmd->pixel_format) {
|
2011-11-17 16:05:13 +00:00
|
|
|
case DRM_FORMAT_RGB332:
|
|
|
|
case DRM_FORMAT_RGB565:
|
|
|
|
case DRM_FORMAT_XRGB8888:
|
2012-03-07 16:49:29 +00:00
|
|
|
case DRM_FORMAT_XBGR8888:
|
2011-11-17 16:05:13 +00:00
|
|
|
case DRM_FORMAT_ARGB8888:
|
|
|
|
case DRM_FORMAT_XRGB2101010:
|
|
|
|
case DRM_FORMAT_ARGB2101010:
|
2011-11-14 22:51:28 +00:00
|
|
|
/* RGB formats are common across chipsets */
|
2011-06-24 19:19:27 +00:00
|
|
|
break;
|
2011-11-17 16:05:13 +00:00
|
|
|
case DRM_FORMAT_YUYV:
|
|
|
|
case DRM_FORMAT_UYVY:
|
|
|
|
case DRM_FORMAT_YVYU:
|
|
|
|
case DRM_FORMAT_VYUY:
|
2010-08-08 11:34:44 +00:00
|
|
|
break;
|
|
|
|
default:
|
2012-01-17 17:25:45 +00:00
|
|
|
DRM_DEBUG_KMS("unsupported pixel format %u\n",
|
|
|
|
mode_cmd->pixel_format);
|
2010-08-08 11:34:44 +00:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
ret = drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_funcs);
|
|
|
|
if (ret) {
|
|
|
|
DRM_ERROR("framebuffer init failed %d\n", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
drm_helper_mode_fill_fb_struct(&intel_fb->base, mode_cmd);
|
|
|
|
intel_fb->obj = obj;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct drm_framebuffer *
|
|
|
|
intel_user_framebuffer_create(struct drm_device *dev,
|
|
|
|
struct drm_file *filp,
|
2011-11-14 22:51:28 +00:00
|
|
|
struct drm_mode_fb_cmd2 *mode_cmd)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
{
|
2010-11-08 19:18:58 +00:00
|
|
|
struct drm_i915_gem_object *obj;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2011-11-14 22:51:28 +00:00
|
|
|
obj = to_intel_bo(drm_gem_object_lookup(dev, filp,
|
|
|
|
mode_cmd->handles[0]));
|
2011-02-19 11:31:06 +00:00
|
|
|
if (&obj->base == NULL)
|
2010-08-08 12:36:38 +00:00
|
|
|
return ERR_PTR(-ENOENT);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2011-04-19 07:36:26 +00:00
|
|
|
return intel_framebuffer_create(dev, mode_cmd, obj);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static const struct drm_mode_config_funcs intel_mode_funcs = {
|
|
|
|
.fb_create = intel_user_framebuffer_create,
|
2010-05-07 06:42:51 +00:00
|
|
|
.output_poll_changed = intel_fb_output_poll_changed,
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
};
|
|
|
|
|
2009-09-21 17:42:27 +00:00
|
|
|
/* Set up chip specific display functions */
|
|
|
|
static void intel_init_display(struct drm_device *dev)
|
|
|
|
{
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
|
|
|
|
/* We always want a DPMS function */
|
2011-03-30 20:01:02 +00:00
|
|
|
if (HAS_PCH_SPLIT(dev)) {
|
|
|
|
dev_priv->display.crtc_mode_set = ironlake_crtc_mode_set;
|
2012-06-29 20:39:33 +00:00
|
|
|
dev_priv->display.crtc_enable = ironlake_crtc_enable;
|
|
|
|
dev_priv->display.crtc_disable = ironlake_crtc_disable;
|
2012-04-20 16:11:53 +00:00
|
|
|
dev_priv->display.off = ironlake_crtc_off;
|
2011-06-24 19:19:23 +00:00
|
|
|
dev_priv->display.update_plane = ironlake_update_plane;
|
2011-03-30 20:01:02 +00:00
|
|
|
} else {
|
|
|
|
dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
|
2012-06-29 20:39:33 +00:00
|
|
|
dev_priv->display.crtc_enable = i9xx_crtc_enable;
|
|
|
|
dev_priv->display.crtc_disable = i9xx_crtc_disable;
|
2012-04-20 16:11:53 +00:00
|
|
|
dev_priv->display.off = i9xx_crtc_off;
|
2011-06-24 19:19:23 +00:00
|
|
|
dev_priv->display.update_plane = i9xx_update_plane;
|
2011-03-30 20:01:02 +00:00
|
|
|
}
|
2009-09-21 17:42:27 +00:00
|
|
|
|
|
|
|
/* Returns the core display clock speed */
|
2012-03-28 20:39:23 +00:00
|
|
|
if (IS_VALLEYVIEW(dev))
|
|
|
|
dev_priv->display.get_display_clock_speed =
|
|
|
|
valleyview_get_display_clock_speed;
|
|
|
|
else if (IS_I945G(dev) || (IS_G33(dev) && !IS_PINEVIEW_M(dev)))
|
2009-09-21 17:42:27 +00:00
|
|
|
dev_priv->display.get_display_clock_speed =
|
|
|
|
i945_get_display_clock_speed;
|
|
|
|
else if (IS_I915G(dev))
|
|
|
|
dev_priv->display.get_display_clock_speed =
|
|
|
|
i915_get_display_clock_speed;
|
2009-12-03 22:14:42 +00:00
|
|
|
else if (IS_I945GM(dev) || IS_845G(dev) || IS_PINEVIEW_M(dev))
|
2009-09-21 17:42:27 +00:00
|
|
|
dev_priv->display.get_display_clock_speed =
|
|
|
|
i9xx_misc_get_display_clock_speed;
|
|
|
|
else if (IS_I915GM(dev))
|
|
|
|
dev_priv->display.get_display_clock_speed =
|
|
|
|
i915gm_get_display_clock_speed;
|
|
|
|
else if (IS_I865G(dev))
|
|
|
|
dev_priv->display.get_display_clock_speed =
|
|
|
|
i865_get_display_clock_speed;
|
2009-09-15 20:57:33 +00:00
|
|
|
else if (IS_I85X(dev))
|
2009-09-21 17:42:27 +00:00
|
|
|
dev_priv->display.get_display_clock_speed =
|
|
|
|
i855_get_display_clock_speed;
|
|
|
|
else /* 852, 830 */
|
|
|
|
dev_priv->display.get_display_clock_speed =
|
|
|
|
i830_get_display_clock_speed;
|
|
|
|
|
2010-04-01 05:07:53 +00:00
|
|
|
if (HAS_PCH_SPLIT(dev)) {
|
2010-10-21 13:57:17 +00:00
|
|
|
if (IS_GEN5(dev)) {
|
2011-04-28 21:27:04 +00:00
|
|
|
dev_priv->display.fdi_link_train = ironlake_fdi_link_train;
|
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 06:25:34 +00:00
|
|
|
dev_priv->display.write_eld = ironlake_write_eld;
|
2010-12-15 07:42:31 +00:00
|
|
|
} else if (IS_GEN6(dev)) {
|
2011-04-28 21:27:04 +00:00
|
|
|
dev_priv->display.fdi_link_train = gen6_fdi_link_train;
|
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 06:25:34 +00:00
|
|
|
dev_priv->display.write_eld = ironlake_write_eld;
|
2011-04-28 22:09:55 +00:00
|
|
|
} else if (IS_IVYBRIDGE(dev)) {
|
|
|
|
/* FIXME: detect B0+ stepping and use auto training */
|
|
|
|
dev_priv->display.fdi_link_train = ivb_manual_fdi_link_train;
|
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 06:25:34 +00:00
|
|
|
dev_priv->display.write_eld = ironlake_write_eld;
|
2012-05-09 18:37:21 +00:00
|
|
|
} else if (IS_HASWELL(dev)) {
|
|
|
|
dev_priv->display.fdi_link_train = hsw_fdi_link_train;
|
2012-08-16 14:43:37 +00:00
|
|
|
dev_priv->display.write_eld = haswell_write_eld;
|
2010-04-01 05:07:53 +00:00
|
|
|
} else
|
|
|
|
dev_priv->display.update_wm = NULL;
|
2011-04-28 22:04:31 +00:00
|
|
|
} else if (IS_G4X(dev)) {
|
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 06:25:34 +00:00
|
|
|
dev_priv->display.write_eld = g4x_write_eld;
|
2009-09-21 17:42:27 +00:00
|
|
|
}
|
2011-06-16 16:19:13 +00:00
|
|
|
|
|
|
|
/* Default just returns -ENODEV to indicate unsupported */
|
|
|
|
dev_priv->display.queue_flip = intel_default_queue_flip;
|
|
|
|
|
|
|
|
switch (INTEL_INFO(dev)->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;
|
2011-06-16 19:18:54 +00:00
|
|
|
case 7:
|
|
|
|
dev_priv->display.queue_flip = intel_gen7_queue_flip;
|
|
|
|
break;
|
2011-06-16 16:19:13 +00:00
|
|
|
}
|
2009-09-21 17:42:27 +00:00
|
|
|
}
|
|
|
|
|
2010-07-19 20:53:12 +00:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
2011-08-16 19:34:10 +00:00
|
|
|
static void quirk_pipea_force(struct drm_device *dev)
|
2010-07-19 20:53:12 +00:00
|
|
|
{
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
|
|
|
|
dev_priv->quirks |= QUIRK_PIPEA_FORCE;
|
2012-04-01 11:16:49 +00:00
|
|
|
DRM_INFO("applying pipe a force quirk\n");
|
2010-07-19 20:53:12 +00:00
|
|
|
}
|
|
|
|
|
2011-07-12 21:56:22 +00:00
|
|
|
/*
|
|
|
|
* 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;
|
2012-04-01 11:16:49 +00:00
|
|
|
DRM_INFO("applying lvds SSC disable quirk\n");
|
2011-07-12 21:56:22 +00:00
|
|
|
}
|
|
|
|
|
2012-03-15 14:56:26 +00:00
|
|
|
/*
|
2012-03-15 14:56:27 +00:00
|
|
|
* A machine (e.g. Acer Aspire 5734Z) may need to invert the panel backlight
|
|
|
|
* brightness value
|
2012-03-15 14:56:26 +00:00
|
|
|
*/
|
|
|
|
static void quirk_invert_brightness(struct drm_device *dev)
|
|
|
|
{
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
dev_priv->quirks |= QUIRK_INVERT_BRIGHTNESS;
|
2012-04-01 11:16:49 +00:00
|
|
|
DRM_INFO("applying inverted panel brightness quirk\n");
|
2011-07-12 21:56:22 +00:00
|
|
|
}
|
|
|
|
|
2010-07-19 20:53:12 +00:00
|
|
|
struct intel_quirk {
|
|
|
|
int device;
|
|
|
|
int subsystem_vendor;
|
|
|
|
int subsystem_device;
|
|
|
|
void (*hook)(struct drm_device *dev);
|
|
|
|
};
|
|
|
|
|
2012-04-16 21:07:40 +00:00
|
|
|
static struct intel_quirk intel_quirks[] = {
|
2010-07-19 20:53:12 +00:00
|
|
|
/* HP Mini needs pipe A force quirk (LP: #322104) */
|
2011-08-16 19:34:10 +00:00
|
|
|
{ 0x27ae, 0x103c, 0x361a, quirk_pipea_force },
|
2010-07-19 20:53:12 +00:00
|
|
|
|
|
|
|
/* 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 },
|
|
|
|
|
|
|
|
/* 855 & before need to leave pipe A & dpll A up */
|
|
|
|
{ 0x3582, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force },
|
|
|
|
{ 0x2562, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force },
|
2012-08-12 19:19:34 +00:00
|
|
|
{ 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force },
|
2011-07-12 21:56:22 +00:00
|
|
|
|
|
|
|
/* Lenovo U160 cannot use SSC on LVDS */
|
|
|
|
{ 0x0046, 0x17aa, 0x3920, quirk_ssc_force_disable },
|
2011-07-28 16:52:06 +00:00
|
|
|
|
|
|
|
/* Sony Vaio Y cannot use SSC on LVDS */
|
|
|
|
{ 0x0046, 0x104d, 0x9076, quirk_ssc_force_disable },
|
2012-03-15 14:56:27 +00:00
|
|
|
|
|
|
|
/* Acer Aspire 5734Z must invert backlight brightness */
|
|
|
|
{ 0x2a42, 0x1025, 0x0459, quirk_invert_brightness },
|
2010-07-19 20:53:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-13 22:11:26 +00:00
|
|
|
/* 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;
|
|
|
|
u32 vga_reg;
|
|
|
|
|
|
|
|
if (HAS_PCH_SPLIT(dev))
|
|
|
|
vga_reg = CPU_VGACNTRL;
|
|
|
|
else
|
|
|
|
vga_reg = VGACNTRL;
|
|
|
|
|
|
|
|
vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO);
|
2012-04-06 18:46:27 +00:00
|
|
|
outb(SR01, VGA_SR_INDEX);
|
2010-08-13 22:11:26 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2012-04-10 13:50:11 +00:00
|
|
|
void intel_modeset_init_hw(struct drm_device *dev)
|
|
|
|
{
|
2012-07-06 18:42:36 +00:00
|
|
|
/* We attempt to init the necessary power wells early in the initialization
|
|
|
|
* time, so the subsystems that expect power to be enabled can work.
|
|
|
|
*/
|
|
|
|
intel_init_power_wells(dev);
|
|
|
|
|
2012-06-28 18:55:35 +00:00
|
|
|
intel_prepare_ddi(dev);
|
|
|
|
|
2012-04-10 13:50:11 +00:00
|
|
|
intel_init_clock_gating(dev);
|
|
|
|
|
2012-06-24 14:42:33 +00:00
|
|
|
mutex_lock(&dev->struct_mutex);
|
2012-06-24 14:42:32 +00:00
|
|
|
intel_enable_gt_powersave(dev);
|
2012-06-24 14:42:33 +00:00
|
|
|
mutex_unlock(&dev->struct_mutex);
|
2012-04-10 13:50:11 +00:00
|
|
|
}
|
|
|
|
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
void intel_modeset_init(struct drm_device *dev)
|
|
|
|
{
|
2009-08-17 20:31:43 +00:00
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
2011-12-13 21:19:38 +00:00
|
|
|
int i, ret;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
|
|
|
drm_mode_config_init(dev);
|
|
|
|
|
|
|
|
dev->mode_config.min_width = 0;
|
|
|
|
dev->mode_config.min_height = 0;
|
|
|
|
|
2011-09-29 15:20:42 +00:00
|
|
|
dev->mode_config.preferred_depth = 24;
|
|
|
|
dev->mode_config.prefer_shadow = 1;
|
|
|
|
|
2012-05-17 11:27:23 +00:00
|
|
|
dev->mode_config.funcs = &intel_mode_funcs;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2010-07-19 20:53:12 +00:00
|
|
|
intel_init_quirks(dev);
|
|
|
|
|
2012-04-18 18:29:26 +00:00
|
|
|
intel_init_pm(dev);
|
|
|
|
|
2009-09-21 17:42:27 +00:00
|
|
|
intel_init_display(dev);
|
|
|
|
|
2010-09-16 23:32:17 +00:00
|
|
|
if (IS_GEN2(dev)) {
|
|
|
|
dev->mode_config.max_width = 2048;
|
|
|
|
dev->mode_config.max_height = 2048;
|
|
|
|
} else if (IS_GEN3(dev)) {
|
2009-07-13 06:53:17 +00:00
|
|
|
dev->mode_config.max_width = 4096;
|
|
|
|
dev->mode_config.max_height = 4096;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
} else {
|
2010-09-16 23:32:17 +00:00
|
|
|
dev->mode_config.max_width = 8192;
|
|
|
|
dev->mode_config.max_height = 8192;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
2012-06-07 13:55:57 +00:00
|
|
|
dev->mode_config.fb_base = dev_priv->mm.gtt_base_addr;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2009-10-09 03:39:41 +00:00
|
|
|
DRM_DEBUG_KMS("%d display pipe%s available.\n",
|
2010-06-06 08:59:41 +00:00
|
|
|
dev_priv->num_pipe, dev_priv->num_pipe > 1 ? "s" : "");
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
|
2010-06-06 08:59:41 +00:00
|
|
|
for (i = 0; i < dev_priv->num_pipe; i++) {
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
intel_crtc_init(dev, i);
|
2012-01-13 23:48:39 +00:00
|
|
|
ret = intel_plane_init(dev, i);
|
|
|
|
if (ret)
|
|
|
|
DRM_DEBUG_KMS("plane %d init failed: %d\n", i, ret);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
2012-04-20 16:11:53 +00:00
|
|
|
intel_pch_pll_init(dev);
|
|
|
|
|
2010-08-13 22:11:26 +00:00
|
|
|
/* Just disable it once at startup */
|
|
|
|
i915_disable_vga(dev);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
intel_setup_outputs(dev);
|
2011-03-29 09:40:27 +00: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 18:28:59 +00:00
|
|
|
static void
|
|
|
|
intel_connector_break_all_links(struct intel_connector *connector)
|
|
|
|
{
|
|
|
|
connector->base.dpms = DRM_MODE_DPMS_OFF;
|
|
|
|
connector->base.encoder = NULL;
|
|
|
|
connector->encoder->connectors_active = false;
|
|
|
|
connector->encoder->base.crtc = NULL;
|
|
|
|
}
|
|
|
|
|
2012-07-04 15:51:47 +00:00
|
|
|
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;
|
|
|
|
|
|
|
|
/* 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. */
|
|
|
|
list_for_each_entry(connector,
|
|
|
|
&dev->mode_config.connector_list,
|
|
|
|
base.head) {
|
|
|
|
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))
|
|
|
|
intel_release_load_detect_pipe(crt, &load_detect_temp);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
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 18:28:59 +00: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;
|
|
|
|
u32 reg, val;
|
|
|
|
|
|
|
|
/* Clear any frame start delays used for debugging left by the BIOS */
|
|
|
|
reg = PIPECONF(crtc->pipe);
|
|
|
|
I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
|
|
|
|
|
|
|
|
/* We need to sanitize the plane -> pipe mapping first because this will
|
|
|
|
* disable the crtc (and hence change the state) if it is wrong. */
|
|
|
|
if (!HAS_PCH_SPLIT(dev)) {
|
|
|
|
struct intel_connector *connector;
|
|
|
|
bool plane;
|
|
|
|
|
|
|
|
reg = DSPCNTR(crtc->plane);
|
|
|
|
val = I915_READ(reg);
|
|
|
|
|
|
|
|
if ((val & DISPLAY_PLANE_ENABLE) == 0 &&
|
|
|
|
(!!(val & DISPPLANE_SEL_PIPE_MASK) == crtc->pipe))
|
|
|
|
goto ok;
|
|
|
|
|
|
|
|
DRM_DEBUG_KMS("[CRTC:%d] wrong plane connection detected!\n",
|
|
|
|
crtc->base.base.id);
|
|
|
|
|
|
|
|
/* Pipe has the wrong plane attached and the plane is active.
|
|
|
|
* Temporarily change the plane mapping and disable everything
|
|
|
|
* ... */
|
|
|
|
plane = crtc->plane;
|
|
|
|
crtc->plane = !plane;
|
|
|
|
dev_priv->display.crtc_disable(&crtc->base);
|
|
|
|
crtc->plane = plane;
|
|
|
|
|
|
|
|
/* ... and break all links. */
|
|
|
|
list_for_each_entry(connector, &dev->mode_config.connector_list,
|
|
|
|
base.head) {
|
|
|
|
if (connector->encoder->base.crtc != &crtc->base)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
intel_connector_break_all_links(connector);
|
|
|
|
}
|
|
|
|
|
|
|
|
WARN_ON(crtc->active);
|
|
|
|
crtc->base.enabled = false;
|
|
|
|
}
|
|
|
|
ok:
|
|
|
|
|
2012-07-04 15:51:47 +00:00
|
|
|
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 18:28:59 +00:00
|
|
|
/* Adjust the state of the output pipe according to whether we
|
|
|
|
* have active connectors/encoders. */
|
|
|
|
intel_crtc_update_dpms(&crtc->base);
|
|
|
|
|
|
|
|
if (crtc->active != crtc->base.enabled) {
|
|
|
|
struct intel_encoder *encoder;
|
|
|
|
|
|
|
|
/* This can happen either due to bugs in the get_hw_state
|
|
|
|
* functions or because the pipe is force-enabled due to the
|
|
|
|
* pipe A quirk. */
|
|
|
|
DRM_DEBUG_KMS("[CRTC:%d] hw state adjusted, was %s, now %s\n",
|
|
|
|
crtc->base.base.id,
|
|
|
|
crtc->base.enabled ? "enabled" : "disabled",
|
|
|
|
crtc->active ? "enabled" : "disabled");
|
|
|
|
|
|
|
|
crtc->base.enabled = crtc->active;
|
|
|
|
|
|
|
|
/* Because we only establish the connector -> encoder ->
|
|
|
|
* crtc links if something is active, this means the
|
|
|
|
* crtc is now deactivated. Break the links. connector
|
|
|
|
* -> encoder links are only establish when things are
|
|
|
|
* actually up, hence no need to break them. */
|
|
|
|
WARN_ON(crtc->active);
|
|
|
|
|
|
|
|
for_each_encoder_on_crtc(dev, &crtc->base, encoder) {
|
|
|
|
WARN_ON(encoder->connectors_active);
|
|
|
|
encoder->base.crtc = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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 (encoder->connectors_active && !has_active_crtc) {
|
|
|
|
DRM_DEBUG_KMS("[ENCODER:%d:%s] has active connectors but no active pipe!\n",
|
|
|
|
encoder->base.base.id,
|
|
|
|
drm_get_encoder_name(&encoder->base));
|
|
|
|
|
|
|
|
/* 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,
|
|
|
|
drm_get_encoder_name(&encoder->base));
|
|
|
|
encoder->disable(encoder);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 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. */
|
|
|
|
list_for_each_entry(connector,
|
|
|
|
&dev->mode_config.connector_list,
|
|
|
|
base.head) {
|
|
|
|
if (connector->encoder != encoder)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
intel_connector_break_all_links(connector);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Enabled encoders without active connectors will be fixed in
|
|
|
|
* the crtc fixup. */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Scan out the current hw modeset state, sanitizes it and maps it into the drm
|
|
|
|
* and i915 state tracking structures. */
|
|
|
|
void intel_modeset_setup_hw_state(struct drm_device *dev)
|
|
|
|
{
|
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
enum pipe pipe;
|
|
|
|
u32 tmp;
|
|
|
|
struct intel_crtc *crtc;
|
|
|
|
struct intel_encoder *encoder;
|
|
|
|
struct intel_connector *connector;
|
|
|
|
|
|
|
|
for_each_pipe(pipe) {
|
|
|
|
crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
|
|
|
|
|
|
|
|
tmp = I915_READ(PIPECONF(pipe));
|
|
|
|
if (tmp & PIPECONF_ENABLE)
|
|
|
|
crtc->active = true;
|
|
|
|
else
|
|
|
|
crtc->active = false;
|
|
|
|
|
|
|
|
crtc->base.enabled = crtc->active;
|
|
|
|
|
|
|
|
DRM_DEBUG_KMS("[CRTC:%d] hw state readout: %s\n",
|
|
|
|
crtc->base.base.id,
|
|
|
|
crtc->active ? "enabled" : "disabled");
|
|
|
|
}
|
|
|
|
|
|
|
|
list_for_each_entry(encoder, &dev->mode_config.encoder_list,
|
|
|
|
base.head) {
|
|
|
|
pipe = 0;
|
|
|
|
|
|
|
|
if (encoder->get_hw_state(encoder, &pipe)) {
|
|
|
|
encoder->base.crtc =
|
|
|
|
dev_priv->pipe_to_crtc_mapping[pipe];
|
|
|
|
} else {
|
|
|
|
encoder->base.crtc = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
encoder->connectors_active = false;
|
|
|
|
DRM_DEBUG_KMS("[ENCODER:%d:%s] hw state readout: %s, pipe=%i\n",
|
|
|
|
encoder->base.base.id,
|
|
|
|
drm_get_encoder_name(&encoder->base),
|
|
|
|
encoder->base.crtc ? "enabled" : "disabled",
|
|
|
|
pipe);
|
|
|
|
}
|
|
|
|
|
|
|
|
list_for_each_entry(connector, &dev->mode_config.connector_list,
|
|
|
|
base.head) {
|
|
|
|
if (connector->get_hw_state(connector)) {
|
|
|
|
connector->base.dpms = DRM_MODE_DPMS_ON;
|
|
|
|
connector->encoder->connectors_active = true;
|
|
|
|
connector->base.encoder = &connector->encoder->base;
|
|
|
|
} 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,
|
|
|
|
drm_get_connector_name(&connector->base),
|
|
|
|
connector->base.encoder ? "enabled" : "disabled");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* HW state is read out, now we need to sanitize this mess. */
|
|
|
|
list_for_each_entry(encoder, &dev->mode_config.encoder_list,
|
|
|
|
base.head) {
|
|
|
|
intel_sanitize_encoder(encoder);
|
|
|
|
}
|
|
|
|
|
|
|
|
for_each_pipe(pipe) {
|
|
|
|
crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
|
|
|
|
intel_sanitize_crtc(crtc);
|
|
|
|
}
|
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 20:34:27 +00:00
|
|
|
|
|
|
|
intel_modeset_update_staged_output_state(dev);
|
2012-07-10 07:50:11 +00:00
|
|
|
|
|
|
|
intel_modeset_check_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 18:28:59 +00:00
|
|
|
}
|
|
|
|
|
2011-03-29 09:40:27 +00:00
|
|
|
void intel_modeset_gem_init(struct drm_device *dev)
|
|
|
|
{
|
2012-05-09 10:56:28 +00:00
|
|
|
intel_modeset_init_hw(dev);
|
2009-09-15 20:57:34 +00:00
|
|
|
|
|
|
|
intel_setup_overlay(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 18:28:59 +00:00
|
|
|
|
|
|
|
intel_modeset_setup_hw_state(dev);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void intel_modeset_cleanup(struct drm_device *dev)
|
|
|
|
{
|
2009-08-17 20:31:43 +00:00
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
struct drm_crtc *crtc;
|
|
|
|
struct intel_crtc *intel_crtc;
|
|
|
|
|
2010-10-04 02:36:26 +00:00
|
|
|
drm_kms_helper_poll_fini(dev);
|
2009-08-17 20:31:43 +00:00
|
|
|
mutex_lock(&dev->struct_mutex);
|
|
|
|
|
2010-10-07 23:01:13 +00:00
|
|
|
intel_unregister_dsm_handler();
|
|
|
|
|
|
|
|
|
2009-08-17 20:31:43 +00:00
|
|
|
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
|
|
|
/* Skip inactive CRTCs */
|
|
|
|
if (!crtc->fb)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
intel_crtc = to_intel_crtc(crtc);
|
2010-08-20 19:40:52 +00:00
|
|
|
intel_increase_pllclock(crtc);
|
2009-08-17 20:31:43 +00:00
|
|
|
}
|
|
|
|
|
2011-07-08 11:22:37 +00:00
|
|
|
intel_disable_fbc(dev);
|
2009-09-21 17:42:27 +00:00
|
|
|
|
2012-06-24 14:42:32 +00:00
|
|
|
intel_disable_gt_powersave(dev);
|
2010-12-05 17:27:06 +00:00
|
|
|
|
2012-06-29 21:32:16 +00:00
|
|
|
ironlake_teardown_rc6(dev);
|
|
|
|
|
2012-03-28 20:39:25 +00:00
|
|
|
if (IS_VALLEYVIEW(dev))
|
|
|
|
vlv_init_dpio(dev);
|
|
|
|
|
2009-11-11 17:19:17 +00:00
|
|
|
mutex_unlock(&dev->struct_mutex);
|
|
|
|
|
2010-08-20 16:26:46 +00:00
|
|
|
/* Disable the irq before mode object teardown, for the irq might
|
|
|
|
* enqueue unpin/hotplug work. */
|
|
|
|
drm_irq_uninstall(dev);
|
|
|
|
cancel_work_sync(&dev_priv->hotplug_work);
|
2012-08-08 21:35:35 +00:00
|
|
|
cancel_work_sync(&dev_priv->rps.work);
|
2010-08-20 16:26:46 +00:00
|
|
|
|
2011-07-08 11:22:42 +00:00
|
|
|
/* flush any delayed tasks or pending work */
|
|
|
|
flush_scheduled_work();
|
|
|
|
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
drm_mode_config_cleanup(dev);
|
|
|
|
}
|
|
|
|
|
2010-03-30 06:39:29 +00:00
|
|
|
/*
|
|
|
|
* Return which encoder is currently attached for connector.
|
|
|
|
*/
|
2010-09-09 15:20:55 +00:00
|
|
|
struct drm_encoder *intel_best_encoder(struct drm_connector *connector)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
{
|
2010-09-09 15:20:55 +00:00
|
|
|
return &intel_attached_encoder(connector)->base;
|
|
|
|
}
|
2010-03-30 06:39:29 +00:00
|
|
|
|
2010-09-09 15:20:55 +00:00
|
|
|
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);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 22:24:08 +00:00
|
|
|
}
|
2009-09-21 04:33:58 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
u16 gmch_ctrl;
|
|
|
|
|
|
|
|
pci_read_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, &gmch_ctrl);
|
|
|
|
if (state)
|
|
|
|
gmch_ctrl &= ~INTEL_GMCH_VGA_DISABLE;
|
|
|
|
else
|
|
|
|
gmch_ctrl |= INTEL_GMCH_VGA_DISABLE;
|
|
|
|
pci_write_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, gmch_ctrl);
|
|
|
|
return 0;
|
|
|
|
}
|
2010-11-21 13:12:35 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_DEBUG_FS
|
|
|
|
#include <linux/seq_file.h>
|
|
|
|
|
|
|
|
struct intel_display_error_state {
|
|
|
|
struct intel_cursor_error_state {
|
|
|
|
u32 control;
|
|
|
|
u32 position;
|
|
|
|
u32 base;
|
|
|
|
u32 size;
|
2012-08-15 18:23:25 +00:00
|
|
|
} cursor[I915_MAX_PIPES];
|
2010-11-21 13:12:35 +00:00
|
|
|
|
|
|
|
struct intel_pipe_error_state {
|
|
|
|
u32 conf;
|
|
|
|
u32 source;
|
|
|
|
|
|
|
|
u32 htotal;
|
|
|
|
u32 hblank;
|
|
|
|
u32 hsync;
|
|
|
|
u32 vtotal;
|
|
|
|
u32 vblank;
|
|
|
|
u32 vsync;
|
2012-08-15 18:23:25 +00:00
|
|
|
} pipe[I915_MAX_PIPES];
|
2010-11-21 13:12:35 +00:00
|
|
|
|
|
|
|
struct intel_plane_error_state {
|
|
|
|
u32 control;
|
|
|
|
u32 stride;
|
|
|
|
u32 size;
|
|
|
|
u32 pos;
|
|
|
|
u32 addr;
|
|
|
|
u32 surface;
|
|
|
|
u32 tile_offset;
|
2012-08-15 18:23:25 +00:00
|
|
|
} plane[I915_MAX_PIPES];
|
2010-11-21 13:12:35 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct intel_display_error_state *
|
|
|
|
intel_display_capture_error_state(struct drm_device *dev)
|
|
|
|
{
|
2011-08-16 19:34:10 +00:00
|
|
|
drm_i915_private_t *dev_priv = dev->dev_private;
|
2010-11-21 13:12:35 +00:00
|
|
|
struct intel_display_error_state *error;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
error = kmalloc(sizeof(*error), GFP_ATOMIC);
|
|
|
|
if (error == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
2012-08-15 18:23:25 +00:00
|
|
|
for_each_pipe(i) {
|
2010-11-21 13:12:35 +00:00
|
|
|
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));
|
|
|
|
error->plane[i].size = I915_READ(DSPSIZE(i));
|
2011-08-16 19:34:10 +00:00
|
|
|
error->plane[i].pos = I915_READ(DSPPOS(i));
|
2010-11-21 13:12:35 +00:00
|
|
|
error->plane[i].addr = I915_READ(DSPADDR(i));
|
|
|
|
if (INTEL_INFO(dev)->gen >= 4) {
|
|
|
|
error->plane[i].surface = I915_READ(DSPSURF(i));
|
|
|
|
error->plane[i].tile_offset = I915_READ(DSPTILEOFF(i));
|
|
|
|
}
|
|
|
|
|
|
|
|
error->pipe[i].conf = I915_READ(PIPECONF(i));
|
|
|
|
error->pipe[i].source = I915_READ(PIPESRC(i));
|
|
|
|
error->pipe[i].htotal = I915_READ(HTOTAL(i));
|
|
|
|
error->pipe[i].hblank = I915_READ(HBLANK(i));
|
|
|
|
error->pipe[i].hsync = I915_READ(HSYNC(i));
|
|
|
|
error->pipe[i].vtotal = I915_READ(VTOTAL(i));
|
|
|
|
error->pipe[i].vblank = I915_READ(VBLANK(i));
|
|
|
|
error->pipe[i].vsync = I915_READ(VSYNC(i));
|
|
|
|
}
|
|
|
|
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
intel_display_print_error_state(struct seq_file *m,
|
|
|
|
struct drm_device *dev,
|
|
|
|
struct intel_display_error_state *error)
|
|
|
|
{
|
2012-08-15 18:23:25 +00:00
|
|
|
drm_i915_private_t *dev_priv = dev->dev_private;
|
2010-11-21 13:12:35 +00:00
|
|
|
int i;
|
|
|
|
|
2012-08-15 18:23:25 +00:00
|
|
|
seq_printf(m, "Num Pipes: %d\n", dev_priv->num_pipe);
|
|
|
|
for_each_pipe(i) {
|
2010-11-21 13:12:35 +00:00
|
|
|
seq_printf(m, "Pipe [%d]:\n", i);
|
|
|
|
seq_printf(m, " CONF: %08x\n", error->pipe[i].conf);
|
|
|
|
seq_printf(m, " SRC: %08x\n", error->pipe[i].source);
|
|
|
|
seq_printf(m, " HTOTAL: %08x\n", error->pipe[i].htotal);
|
|
|
|
seq_printf(m, " HBLANK: %08x\n", error->pipe[i].hblank);
|
|
|
|
seq_printf(m, " HSYNC: %08x\n", error->pipe[i].hsync);
|
|
|
|
seq_printf(m, " VTOTAL: %08x\n", error->pipe[i].vtotal);
|
|
|
|
seq_printf(m, " VBLANK: %08x\n", error->pipe[i].vblank);
|
|
|
|
seq_printf(m, " VSYNC: %08x\n", error->pipe[i].vsync);
|
|
|
|
|
|
|
|
seq_printf(m, "Plane [%d]:\n", i);
|
|
|
|
seq_printf(m, " CNTR: %08x\n", error->plane[i].control);
|
|
|
|
seq_printf(m, " STRIDE: %08x\n", error->plane[i].stride);
|
|
|
|
seq_printf(m, " SIZE: %08x\n", error->plane[i].size);
|
|
|
|
seq_printf(m, " POS: %08x\n", error->plane[i].pos);
|
|
|
|
seq_printf(m, " ADDR: %08x\n", error->plane[i].addr);
|
|
|
|
if (INTEL_INFO(dev)->gen >= 4) {
|
|
|
|
seq_printf(m, " SURF: %08x\n", error->plane[i].surface);
|
|
|
|
seq_printf(m, " TILEOFF: %08x\n", error->plane[i].tile_offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
seq_printf(m, "Cursor [%d]:\n", i);
|
|
|
|
seq_printf(m, " CNTR: %08x\n", error->cursor[i].control);
|
|
|
|
seq_printf(m, " POS: %08x\n", error->cursor[i].position);
|
|
|
|
seq_printf(m, " BASE: %08x\n", error->cursor[i].base);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|