mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 06:31:49 +00:00
Merge branch 'drm-intel-next' of git://git.kernel.org/pub/scm/linux/kernel/git/anholt/drm-intel
* 'drm-intel-next' of git://git.kernel.org/pub/scm/linux/kernel/git/anholt/drm-intel: drm/i915: Add new GET_PIPE_FROM_CRTC_ID ioctl. drm/i915: Set HDMI hot plug interrupt enable for only the output in question. drm/i915: Include 965GME pci ID in IS_I965GM(dev) to match UMS. drm/i915: Use the GM45 VGA hotplug workaround on G45 as well. drm/i915: ignore LVDS on intel graphics systems that lie about having it drm/i915: sanity check IER at wait_request time drm/i915: workaround IGD i2c bus issue in kernel side (v2) drm/i915: Don't allow binding objects into the last page of the aperture. drm/i915: save/restore fence registers across suspend/resume drm/i915: x86 always has writeq. Add I915_READ64 for symmetry.
This commit is contained in:
commit
40f293ff83
@ -1011,8 +1011,16 @@ static int i915_load_modeset_init(struct drm_device *dev)
|
||||
/* Basic memrange allocator for stolen space (aka vram) */
|
||||
drm_mm_init(&dev_priv->vram, 0, prealloc_size);
|
||||
|
||||
/* Let GEM Manage from end of prealloc space to end of aperture */
|
||||
i915_gem_do_init(dev, prealloc_size, agp_size);
|
||||
/* Let GEM Manage from end of prealloc space to end of aperture.
|
||||
*
|
||||
* However, leave one page at the end still bound to the scratch page.
|
||||
* There are a number of places where the hardware apparently
|
||||
* prefetches past the end of the object, and we've seen multiple
|
||||
* hangs with the GPU head pointer stuck in a batchbuffer bound
|
||||
* at the last page of the aperture. One page should be enough to
|
||||
* keep any prefetching inside of the aperture.
|
||||
*/
|
||||
i915_gem_do_init(dev, prealloc_size, agp_size - 4096);
|
||||
|
||||
ret = i915_gem_init_ringbuffer(dev);
|
||||
if (ret)
|
||||
@ -1350,6 +1358,7 @@ struct drm_ioctl_desc i915_ioctls[] = {
|
||||
DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, 0),
|
||||
DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, 0),
|
||||
DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, 0),
|
||||
DRM_IOCTL_DEF(DRM_I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, 0),
|
||||
};
|
||||
|
||||
int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
|
||||
|
@ -283,6 +283,7 @@ typedef struct drm_i915_private {
|
||||
u8 saveAR[21];
|
||||
u8 saveDACMASK;
|
||||
u8 saveCR[37];
|
||||
uint64_t saveFENCE[16];
|
||||
|
||||
struct {
|
||||
struct drm_mm gtt_space;
|
||||
@ -705,13 +706,8 @@ extern void intel_modeset_cleanup(struct drm_device *dev);
|
||||
#define I915_WRITE16(reg, val) writel(val, dev_priv->regs + (reg))
|
||||
#define I915_READ8(reg) readb(dev_priv->regs + (reg))
|
||||
#define I915_WRITE8(reg, val) writeb(val, dev_priv->regs + (reg))
|
||||
#ifdef writeq
|
||||
#define I915_WRITE64(reg, val) writeq(val, dev_priv->regs + (reg))
|
||||
#else
|
||||
#define I915_WRITE64(reg, val) (writel(val, dev_priv->regs + (reg)), \
|
||||
writel(upper_32_bits(val), dev_priv->regs + \
|
||||
(reg) + 4))
|
||||
#endif
|
||||
#define I915_READ64(reg) readq(dev_priv->regs + (reg))
|
||||
#define POSTING_READ(reg) (void)I915_READ(reg)
|
||||
|
||||
#define I915_VERBOSE 0
|
||||
@ -790,7 +786,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
|
||||
(dev)->pci_device == 0x2E22 || \
|
||||
(dev)->pci_device == 0x2E32)
|
||||
|
||||
#define IS_I965GM(dev) ((dev)->pci_device == 0x2A02)
|
||||
#define IS_I965GM(dev) ((dev)->pci_device == 0x2A02 || \
|
||||
(dev)->pci_device == 0x2A12)
|
||||
|
||||
#define IS_GM45(dev) ((dev)->pci_device == 0x2A42)
|
||||
|
||||
|
@ -1691,11 +1691,20 @@ static int
|
||||
i915_wait_request(struct drm_device *dev, uint32_t seqno)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
u32 ier;
|
||||
int ret = 0;
|
||||
|
||||
BUG_ON(seqno == 0);
|
||||
|
||||
if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) {
|
||||
ier = I915_READ(IER);
|
||||
if (!ier) {
|
||||
DRM_ERROR("something (likely vbetool) disabled "
|
||||
"interrupts, re-enabling\n");
|
||||
i915_driver_irq_preinstall(dev);
|
||||
i915_driver_irq_postinstall(dev);
|
||||
}
|
||||
|
||||
dev_priv->mm.waiting_gem_seqno = seqno;
|
||||
i915_user_irq_get(dev);
|
||||
ret = wait_event_interruptible(dev_priv->irq_queue,
|
||||
|
@ -526,6 +526,7 @@
|
||||
#define DPLLA_INPUT_BUFFER_ENABLE (1 << 0)
|
||||
#define D_STATE 0x6104
|
||||
#define CG_2D_DIS 0x6200
|
||||
#define DPCUNIT_CLOCK_GATE_DISABLE (1 << 24)
|
||||
#define CG_3D_DIS 0x6204
|
||||
|
||||
/*
|
||||
|
@ -349,6 +349,18 @@ int i915_save_state(struct drm_device *dev)
|
||||
for (i = 0; i < 3; i++)
|
||||
dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2));
|
||||
|
||||
/* Fences */
|
||||
if (IS_I965G(dev)) {
|
||||
for (i = 0; i < 16; i++)
|
||||
dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8));
|
||||
} else {
|
||||
for (i = 0; i < 8; i++)
|
||||
dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4));
|
||||
|
||||
if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
|
||||
for (i = 0; i < 8; i++)
|
||||
dev_priv->saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4));
|
||||
}
|
||||
i915_save_vga(dev);
|
||||
|
||||
return 0;
|
||||
@ -371,6 +383,18 @@ int i915_restore_state(struct drm_device *dev)
|
||||
/* Display arbitration */
|
||||
I915_WRITE(DSPARB, dev_priv->saveDSPARB);
|
||||
|
||||
/* Fences */
|
||||
if (IS_I965G(dev)) {
|
||||
for (i = 0; i < 16; i++)
|
||||
I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->saveFENCE[i]);
|
||||
} else {
|
||||
for (i = 0; i < 8; i++)
|
||||
I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]);
|
||||
if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
|
||||
for (i = 0; i < 8; i++)
|
||||
I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]);
|
||||
}
|
||||
|
||||
/* Pipe & plane A info */
|
||||
/* Prime the clock */
|
||||
if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) {
|
||||
|
@ -161,7 +161,7 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
|
||||
hotplug_en &= CRT_FORCE_HOTPLUG_MASK;
|
||||
hotplug_en |= CRT_HOTPLUG_FORCE_DETECT;
|
||||
|
||||
if (IS_GM45(dev))
|
||||
if (IS_G4X(dev))
|
||||
hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64;
|
||||
|
||||
hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50;
|
||||
|
@ -1804,6 +1804,37 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
|
||||
}
|
||||
}
|
||||
|
||||
int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data;
|
||||
struct drm_crtc *crtc = NULL;
|
||||
int pipe = -1;
|
||||
|
||||
if (!dev_priv) {
|
||||
DRM_ERROR("called with no initialization\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
if (crtc->base.id == pipe_from_crtc_id->crtc_id) {
|
||||
pipe = intel_crtc->pipe;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pipe == -1) {
|
||||
DRM_ERROR("no such CRTC id\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pipe_from_crtc_id->pipe = pipe;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe)
|
||||
{
|
||||
struct drm_crtc *crtc = NULL;
|
||||
|
@ -109,7 +109,7 @@ struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg,
|
||||
void intel_i2c_destroy(struct intel_i2c_chan *chan);
|
||||
int intel_ddc_get_modes(struct intel_output *intel_output);
|
||||
extern bool intel_ddc_probe(struct intel_output *intel_output);
|
||||
|
||||
void intel_i2c_quirk_set(struct drm_device *dev, bool enable);
|
||||
extern void intel_crt_init(struct drm_device *dev);
|
||||
extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg);
|
||||
extern bool intel_sdvo_init(struct drm_device *dev, int output_device);
|
||||
@ -125,6 +125,8 @@ extern struct drm_encoder *intel_best_encoder(struct drm_connector *connector);
|
||||
|
||||
extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
|
||||
struct drm_crtc *crtc);
|
||||
int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
extern void intel_wait_for_vblank(struct drm_device *dev);
|
||||
extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe);
|
||||
extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
|
||||
|
@ -155,11 +155,18 @@ intel_hdmi_detect(struct drm_connector *connector)
|
||||
|
||||
temp = I915_READ(PORT_HOTPLUG_EN);
|
||||
|
||||
I915_WRITE(PORT_HOTPLUG_EN,
|
||||
temp |
|
||||
HDMIB_HOTPLUG_INT_EN |
|
||||
HDMIC_HOTPLUG_INT_EN |
|
||||
HDMID_HOTPLUG_INT_EN);
|
||||
switch (hdmi_priv->sdvox_reg) {
|
||||
case SDVOB:
|
||||
temp |= HDMIB_HOTPLUG_INT_EN;
|
||||
break;
|
||||
case SDVOC:
|
||||
temp |= HDMIC_HOTPLUG_INT_EN;
|
||||
break;
|
||||
default:
|
||||
return connector_status_unknown;
|
||||
}
|
||||
|
||||
I915_WRITE(PORT_HOTPLUG_EN, temp);
|
||||
|
||||
POSTING_READ(PORT_HOTPLUG_EN);
|
||||
|
||||
|
@ -34,6 +34,21 @@
|
||||
#include "i915_drm.h"
|
||||
#include "i915_drv.h"
|
||||
|
||||
void intel_i2c_quirk_set(struct drm_device *dev, bool enable)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
/* When using bit bashing for I2C, this bit needs to be set to 1 */
|
||||
if (!IS_IGD(dev))
|
||||
return;
|
||||
if (enable)
|
||||
I915_WRITE(CG_2D_DIS,
|
||||
I915_READ(CG_2D_DIS) | DPCUNIT_CLOCK_GATE_DISABLE);
|
||||
else
|
||||
I915_WRITE(CG_2D_DIS,
|
||||
I915_READ(CG_2D_DIS) & (~DPCUNIT_CLOCK_GATE_DISABLE));
|
||||
}
|
||||
|
||||
/*
|
||||
* Intel GPIO access functions
|
||||
*/
|
||||
@ -153,8 +168,10 @@ struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg,
|
||||
goto out_free;
|
||||
|
||||
/* JJJ: raise SCL and SDA? */
|
||||
intel_i2c_quirk_set(dev, true);
|
||||
set_data(chan, 1);
|
||||
set_clock(chan, 1);
|
||||
intel_i2c_quirk_set(dev, false);
|
||||
udelay(20);
|
||||
|
||||
return chan;
|
||||
|
@ -384,7 +384,51 @@ static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
|
||||
.destroy = intel_lvds_enc_destroy,
|
||||
};
|
||||
|
||||
static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id)
|
||||
{
|
||||
DRM_DEBUG("Skipping LVDS initialization for %s\n", id->ident);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* These systems claim to have LVDS, but really don't */
|
||||
static const struct dmi_system_id __initdata intel_no_lvds[] = {
|
||||
{
|
||||
.callback = intel_no_lvds_dmi_callback,
|
||||
.ident = "Apple Mac Mini (Core series)",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = intel_no_lvds_dmi_callback,
|
||||
.ident = "Apple Mac Mini (Core 2 series)",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Macmini2,1"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = intel_no_lvds_dmi_callback,
|
||||
.ident = "MSI IM-945GSE-A",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "MSI"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "A9830IMS"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = intel_no_lvds_dmi_callback,
|
||||
.ident = "Dell Studio Hybrid",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Studio Hybrid 140g"),
|
||||
},
|
||||
},
|
||||
|
||||
/* FIXME: add a check for the Aopen Mini PC */
|
||||
|
||||
{ } /* terminating entry */
|
||||
};
|
||||
|
||||
/**
|
||||
* intel_lvds_init - setup LVDS connectors on this device
|
||||
@ -404,15 +448,9 @@ void intel_lvds_init(struct drm_device *dev)
|
||||
u32 lvds;
|
||||
int pipe;
|
||||
|
||||
/* Blacklist machines that we know falsely report LVDS. */
|
||||
/* FIXME: add a check for the Aopen Mini PC */
|
||||
|
||||
/* Apple Mac Mini Core Duo and Mac Mini Core 2 Duo */
|
||||
if(dmi_match(DMI_PRODUCT_NAME, "Macmini1,1") ||
|
||||
dmi_match(DMI_PRODUCT_NAME, "Macmini2,1")) {
|
||||
DRM_DEBUG("Skipping LVDS initialization for Apple Mac Mini\n");
|
||||
/* Skip init on machines we know falsely report LVDS */
|
||||
if (dmi_check_system(intel_no_lvds))
|
||||
return;
|
||||
}
|
||||
|
||||
intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
|
||||
if (!intel_output) {
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <linux/fb.h>
|
||||
#include "drmP.h"
|
||||
#include "intel_drv.h"
|
||||
#include "i915_drv.h"
|
||||
|
||||
/**
|
||||
* intel_ddc_probe
|
||||
@ -52,7 +53,10 @@ bool intel_ddc_probe(struct intel_output *intel_output)
|
||||
}
|
||||
};
|
||||
|
||||
intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, true);
|
||||
ret = i2c_transfer(&intel_output->ddc_bus->adapter, msgs, 2);
|
||||
intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, false);
|
||||
|
||||
if (ret == 2)
|
||||
return true;
|
||||
|
||||
@ -70,8 +74,10 @@ int intel_ddc_get_modes(struct intel_output *intel_output)
|
||||
struct edid *edid;
|
||||
int ret = 0;
|
||||
|
||||
intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, true);
|
||||
edid = drm_get_edid(&intel_output->base,
|
||||
&intel_output->ddc_bus->adapter);
|
||||
intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, false);
|
||||
if (edid) {
|
||||
drm_mode_connector_update_edid_property(&intel_output->base,
|
||||
edid);
|
||||
|
@ -184,6 +184,7 @@ typedef struct _drm_i915_sarea {
|
||||
#define DRM_I915_GEM_GET_TILING 0x22
|
||||
#define DRM_I915_GEM_GET_APERTURE 0x23
|
||||
#define DRM_I915_GEM_MMAP_GTT 0x24
|
||||
#define DRM_I915_GET_PIPE_FROM_CRTC_ID 0x25
|
||||
|
||||
#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
|
||||
#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
|
||||
@ -219,6 +220,7 @@ typedef struct _drm_i915_sarea {
|
||||
#define DRM_IOCTL_I915_GEM_SET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling)
|
||||
#define DRM_IOCTL_I915_GEM_GET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling)
|
||||
#define DRM_IOCTL_I915_GEM_GET_APERTURE DRM_IOR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_APERTURE, struct drm_i915_gem_get_aperture)
|
||||
#define DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_PIPE_FROM_CRTC_ID, struct drm_intel_get_pipe_from_crtc_id)
|
||||
|
||||
/* Allow drivers to submit batchbuffers directly to hardware, relying
|
||||
* on the security mechanisms provided by hardware.
|
||||
@ -657,4 +659,12 @@ struct drm_i915_gem_get_aperture {
|
||||
__u64 aper_available_size;
|
||||
};
|
||||
|
||||
struct drm_i915_get_pipe_from_crtc_id {
|
||||
/** ID of CRTC being requested **/
|
||||
__u32 crtc_id;
|
||||
|
||||
/** pipe of requested CRTC **/
|
||||
__u32 pipe;
|
||||
};
|
||||
|
||||
#endif /* _I915_DRM_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user