Merge branch 'for-airlied' of git://people.freedesktop.org/~danvet/drm-intel into drm-next
Daniel writes: "New stuff for -next. Highlights: - prep patches for the modeset rework. Note that one of those patches touches the fb helper in the common drm code. - hasw hdmi audio support (Wang Xingchao) - improved instdone dumping for gen7 (Ben) - unbound tracking and a few follow-up patches from Chris - dma_buf->begin/end_cpu_access plus fix for drm/udl (Dave) - improve mmio error reporting for hsw - prep patch for WQ_NON_REENTRANT removal (Tejun Heo) " * 'for-airlied' of git://people.freedesktop.org/~danvet/drm-intel: (41 commits) drm/i915: Remove __GFP_NO_KSWAPD drm/i915: disable rc6 on ilk when vt-d is enabled drm/i915: Avoid unbinding due to an interrupted pin_and_fence during execbuffer drm/i915: Use new INSTDONE registers (Gen7+) drm/i915: Add new INSTDONE registers drm/i915: Extract reading INSTDONE drm/i915: Use a non-blocking wait for set-to-domain ioctl drm/i915: Juggle code order to ease flow of the next patch drm/i915: Use cpu relocations if the object is in the GTT but not mappable drm/i915: Extract general object init routine drm/i915: Protect private gem objects from truncate (such as imported dmabuf) drm/i915: Only pwrite through the GTT if there is space in the aperture i915: use alloc_ordered_workqueue() instead of explicit UNBOUND w/ max_active = 1 drm/i915: Find unclaimed MMIO writes. drm/i915: Add ERR_INT to gen7 error state drm/i915: Cantiga+ cannot handle a hsync front porch of 0 drm/i915: fix reassignment of variable "intel_dp->DP" drm/i915: Try harder to allocate an mmap_offset drm/i915: Show pin count in debugfs drm/i915: Show (count, size) of purgeable objects in i915_gem_objects ...
This commit is contained in:
Коммит
65983bd605
|
@ -1230,7 +1230,6 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
|
|||
struct drm_device *dev = fb_helper->dev;
|
||||
struct drm_fb_helper_crtc **crtcs;
|
||||
struct drm_display_mode **modes;
|
||||
struct drm_encoder *encoder;
|
||||
struct drm_mode_set *modeset;
|
||||
bool *enabled;
|
||||
int width, height;
|
||||
|
@ -1241,11 +1240,6 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
|
|||
width = dev->mode_config.max_width;
|
||||
height = dev->mode_config.max_height;
|
||||
|
||||
/* clean out all the encoder/crtc combos */
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||
encoder->crtc = NULL;
|
||||
}
|
||||
|
||||
crtcs = kcalloc(dev->mode_config.num_connector,
|
||||
sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL);
|
||||
modes = kcalloc(dev->mode_config.num_connector,
|
||||
|
|
|
@ -58,13 +58,12 @@ struct intel_dvo_dev_ops {
|
|||
void (*create_resources)(struct intel_dvo_device *dvo);
|
||||
|
||||
/*
|
||||
* Turn on/off output or set intermediate power levels if available.
|
||||
* Turn on/off output.
|
||||
*
|
||||
* Unsupported intermediate modes drop to the lower power setting.
|
||||
* If the mode is DPMSModeOff, the output must be disabled,
|
||||
* as the DPLL may be disabled afterwards.
|
||||
* Because none of our dvo drivers support an intermediate power levels,
|
||||
* we don't expose this in the interfac.
|
||||
*/
|
||||
void (*dpms)(struct intel_dvo_device *dvo, int mode);
|
||||
void (*dpms)(struct intel_dvo_device *dvo, bool enable);
|
||||
|
||||
/*
|
||||
* Callback for testing a video mode for a given output.
|
||||
|
|
|
@ -163,7 +163,7 @@ struct ch7017_priv {
|
|||
};
|
||||
|
||||
static void ch7017_dump_regs(struct intel_dvo_device *dvo);
|
||||
static void ch7017_dpms(struct intel_dvo_device *dvo, int mode);
|
||||
static void ch7017_dpms(struct intel_dvo_device *dvo, bool enable);
|
||||
|
||||
static bool ch7017_read(struct intel_dvo_device *dvo, u8 addr, u8 *val)
|
||||
{
|
||||
|
@ -309,7 +309,7 @@ static void ch7017_mode_set(struct intel_dvo_device *dvo,
|
|||
lvds_power_down = CH7017_LVDS_POWER_DOWN_DEFAULT_RESERVED |
|
||||
(mode->hdisplay & 0x0700) >> 8;
|
||||
|
||||
ch7017_dpms(dvo, DRM_MODE_DPMS_OFF);
|
||||
ch7017_dpms(dvo, false);
|
||||
ch7017_write(dvo, CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT,
|
||||
horizontal_active_pixel_input);
|
||||
ch7017_write(dvo, CH7017_HORIZONTAL_ACTIVE_PIXEL_OUTPUT,
|
||||
|
@ -331,7 +331,7 @@ static void ch7017_mode_set(struct intel_dvo_device *dvo,
|
|||
}
|
||||
|
||||
/* set the CH7017 power state */
|
||||
static void ch7017_dpms(struct intel_dvo_device *dvo, int mode)
|
||||
static void ch7017_dpms(struct intel_dvo_device *dvo, bool enable)
|
||||
{
|
||||
uint8_t val;
|
||||
|
||||
|
@ -345,7 +345,7 @@ static void ch7017_dpms(struct intel_dvo_device *dvo, int mode)
|
|||
CH7017_DAC3_POWER_DOWN |
|
||||
CH7017_TV_POWER_DOWN_EN);
|
||||
|
||||
if (mode == DRM_MODE_DPMS_ON) {
|
||||
if (enable) {
|
||||
/* Turn on the LVDS */
|
||||
ch7017_write(dvo, CH7017_LVDS_POWER_DOWN,
|
||||
val & ~CH7017_LVDS_POWER_DOWN_EN);
|
||||
|
|
|
@ -289,9 +289,9 @@ static void ch7xxx_mode_set(struct intel_dvo_device *dvo,
|
|||
}
|
||||
|
||||
/* set the CH7xxx power state */
|
||||
static void ch7xxx_dpms(struct intel_dvo_device *dvo, int mode)
|
||||
static void ch7xxx_dpms(struct intel_dvo_device *dvo, bool enable)
|
||||
{
|
||||
if (mode == DRM_MODE_DPMS_ON)
|
||||
if (enable)
|
||||
ch7xxx_writeb(dvo, CH7xxx_PM, CH7xxx_PM_DVIL | CH7xxx_PM_DVIP);
|
||||
else
|
||||
ch7xxx_writeb(dvo, CH7xxx_PM, CH7xxx_PM_FPD);
|
||||
|
|
|
@ -288,7 +288,7 @@ static enum drm_mode_status ivch_mode_valid(struct intel_dvo_device *dvo,
|
|||
}
|
||||
|
||||
/** Sets the power state of the panel connected to the ivch */
|
||||
static void ivch_dpms(struct intel_dvo_device *dvo, int mode)
|
||||
static void ivch_dpms(struct intel_dvo_device *dvo, bool enable)
|
||||
{
|
||||
int i;
|
||||
uint16_t vr01, vr30, backlight;
|
||||
|
@ -297,13 +297,13 @@ static void ivch_dpms(struct intel_dvo_device *dvo, int mode)
|
|||
if (!ivch_read(dvo, VR01, &vr01))
|
||||
return;
|
||||
|
||||
if (mode == DRM_MODE_DPMS_ON)
|
||||
if (enable)
|
||||
backlight = 1;
|
||||
else
|
||||
backlight = 0;
|
||||
ivch_write(dvo, VR80, backlight);
|
||||
|
||||
if (mode == DRM_MODE_DPMS_ON)
|
||||
if (enable)
|
||||
vr01 |= VR01_LCD_ENABLE | VR01_DVO_ENABLE;
|
||||
else
|
||||
vr01 &= ~(VR01_LCD_ENABLE | VR01_DVO_ENABLE);
|
||||
|
@ -315,7 +315,7 @@ static void ivch_dpms(struct intel_dvo_device *dvo, int mode)
|
|||
if (!ivch_read(dvo, VR30, &vr30))
|
||||
break;
|
||||
|
||||
if (((vr30 & VR30_PANEL_ON) != 0) == (mode == DRM_MODE_DPMS_ON))
|
||||
if (((vr30 & VR30_PANEL_ON) != 0) == enable)
|
||||
break;
|
||||
udelay(1000);
|
||||
}
|
||||
|
|
|
@ -74,11 +74,6 @@ struct ns2501_priv {
|
|||
|
||||
#define NSPTR(d) ((NS2501Ptr)(d->DriverPrivate.ptr))
|
||||
|
||||
/*
|
||||
* Include the PLL launcher prototype
|
||||
*/
|
||||
extern void intel_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe);
|
||||
|
||||
/*
|
||||
* For reasons unclear to me, the ns2501 at least on the Fujitsu/Siemens
|
||||
* laptops does not react on the i2c bus unless
|
||||
|
@ -113,8 +108,6 @@ static void enable_dvo(struct intel_dvo_device *dvo)
|
|||
I915_WRITE(DVOC_SRCDIM, 0x400300); // 1024x768
|
||||
I915_WRITE(FW_BLC, 0x1080304);
|
||||
|
||||
intel_enable_pll(dev_priv, 0);
|
||||
|
||||
I915_WRITE(DVOC, 0x90004084);
|
||||
}
|
||||
|
||||
|
@ -500,19 +493,19 @@ static void ns2501_mode_set(struct intel_dvo_device *dvo,
|
|||
}
|
||||
|
||||
/* set the NS2501 power state */
|
||||
static void ns2501_dpms(struct intel_dvo_device *dvo, int mode)
|
||||
static void ns2501_dpms(struct intel_dvo_device *dvo, bool enable)
|
||||
{
|
||||
bool ok;
|
||||
bool restore = false;
|
||||
struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
|
||||
unsigned char ch;
|
||||
|
||||
DRM_DEBUG_KMS("%s: Trying set the dpms of the DVO to %d\n",
|
||||
__FUNCTION__, mode);
|
||||
DRM_DEBUG_KMS("%s: Trying set the dpms of the DVO to %i\n",
|
||||
__FUNCTION__, enable);
|
||||
|
||||
ch = ns->reg_8_shadow;
|
||||
|
||||
if (mode == DRM_MODE_DPMS_ON)
|
||||
if (enable)
|
||||
ch |= NS2501_8_PD;
|
||||
else
|
||||
ch &= ~NS2501_8_PD;
|
||||
|
@ -526,12 +519,10 @@ static void ns2501_dpms(struct intel_dvo_device *dvo, int mode)
|
|||
ok &= ns2501_writeb(dvo, NS2501_REG8, ch);
|
||||
ok &=
|
||||
ns2501_writeb(dvo, 0x34,
|
||||
(mode ==
|
||||
DRM_MODE_DPMS_ON) ? (0x03) : (0x00));
|
||||
enable ? 0x03 : 0x00);
|
||||
ok &=
|
||||
ns2501_writeb(dvo, 0x35,
|
||||
(mode ==
|
||||
DRM_MODE_DPMS_ON) ? (0xff) : (0x00));
|
||||
enable ? 0xff : 0x00);
|
||||
if (!ok) {
|
||||
if (restore)
|
||||
restore_dvo(dvo);
|
||||
|
|
|
@ -208,7 +208,7 @@ static void sil164_mode_set(struct intel_dvo_device *dvo,
|
|||
}
|
||||
|
||||
/* set the SIL164 power state */
|
||||
static void sil164_dpms(struct intel_dvo_device *dvo, int mode)
|
||||
static void sil164_dpms(struct intel_dvo_device *dvo, bool enable)
|
||||
{
|
||||
int ret;
|
||||
unsigned char ch;
|
||||
|
@ -217,7 +217,7 @@ static void sil164_dpms(struct intel_dvo_device *dvo, int mode)
|
|||
if (ret == false)
|
||||
return;
|
||||
|
||||
if (mode == DRM_MODE_DPMS_ON)
|
||||
if (enable)
|
||||
ch |= SIL164_8_PD;
|
||||
else
|
||||
ch &= ~SIL164_8_PD;
|
||||
|
|
|
@ -234,14 +234,14 @@ static void tfp410_mode_set(struct intel_dvo_device *dvo,
|
|||
}
|
||||
|
||||
/* set the tfp410 power state */
|
||||
static void tfp410_dpms(struct intel_dvo_device *dvo, int mode)
|
||||
static void tfp410_dpms(struct intel_dvo_device *dvo, bool enable)
|
||||
{
|
||||
uint8_t ctl1;
|
||||
|
||||
if (!tfp410_readb(dvo, TFP410_CTL_1, &ctl1))
|
||||
return;
|
||||
|
||||
if (mode == DRM_MODE_DPMS_ON)
|
||||
if (enable)
|
||||
ctl1 |= TFP410_CTL_1_PD;
|
||||
else
|
||||
ctl1 &= ~TFP410_CTL_1_PD;
|
||||
|
|
|
@ -118,6 +118,8 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
|
|||
obj->madv == I915_MADV_DONTNEED ? " purgeable" : "");
|
||||
if (obj->base.name)
|
||||
seq_printf(m, " (name: %d)", obj->base.name);
|
||||
if (obj->pin_count)
|
||||
seq_printf(m, " (pinned x %d)", obj->pin_count);
|
||||
if (obj->fence_reg != I915_FENCE_REG_NONE)
|
||||
seq_printf(m, " (fence: %d)", obj->fence_reg);
|
||||
if (obj->gtt_space != NULL)
|
||||
|
@ -197,8 +199,8 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
|
|||
struct drm_info_node *node = (struct drm_info_node *) m->private;
|
||||
struct drm_device *dev = node->minor->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u32 count, mappable_count;
|
||||
size_t size, mappable_size;
|
||||
u32 count, mappable_count, purgeable_count;
|
||||
size_t size, mappable_size, purgeable_size;
|
||||
struct drm_i915_gem_object *obj;
|
||||
int ret;
|
||||
|
||||
|
@ -211,7 +213,7 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
|
|||
dev_priv->mm.object_memory);
|
||||
|
||||
size = count = mappable_size = mappable_count = 0;
|
||||
count_objects(&dev_priv->mm.gtt_list, gtt_list);
|
||||
count_objects(&dev_priv->mm.bound_list, gtt_list);
|
||||
seq_printf(m, "%u [%u] objects, %zu [%zu] bytes in gtt\n",
|
||||
count, mappable_count, size, mappable_size);
|
||||
|
||||
|
@ -225,8 +227,16 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
|
|||
seq_printf(m, " %u [%u] inactive objects, %zu [%zu] bytes\n",
|
||||
count, mappable_count, size, mappable_size);
|
||||
|
||||
size = count = purgeable_size = purgeable_count = 0;
|
||||
list_for_each_entry(obj, &dev_priv->mm.unbound_list, gtt_list) {
|
||||
size += obj->base.size, ++count;
|
||||
if (obj->madv == I915_MADV_DONTNEED)
|
||||
purgeable_size += obj->base.size, ++purgeable_count;
|
||||
}
|
||||
seq_printf(m, "%u unbound objects, %zu bytes\n", count, size);
|
||||
|
||||
size = count = mappable_size = mappable_count = 0;
|
||||
list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) {
|
||||
list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) {
|
||||
if (obj->fault_mappable) {
|
||||
size += obj->gtt_space->size;
|
||||
++count;
|
||||
|
@ -235,7 +245,13 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
|
|||
mappable_size += obj->gtt_space->size;
|
||||
++mappable_count;
|
||||
}
|
||||
if (obj->madv == I915_MADV_DONTNEED) {
|
||||
purgeable_size += obj->base.size;
|
||||
++purgeable_count;
|
||||
}
|
||||
}
|
||||
seq_printf(m, "%u purgeable objects, %zu bytes\n",
|
||||
purgeable_count, purgeable_size);
|
||||
seq_printf(m, "%u pinned mappable objects, %zu bytes\n",
|
||||
mappable_count, mappable_size);
|
||||
seq_printf(m, "%u fault mappable objects, %zu bytes\n",
|
||||
|
@ -264,7 +280,7 @@ static int i915_gem_gtt_info(struct seq_file *m, void* data)
|
|||
return ret;
|
||||
|
||||
total_obj_size = total_gtt_size = count = 0;
|
||||
list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) {
|
||||
list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) {
|
||||
if (list == PINNED_LIST && obj->pin_count == 0)
|
||||
continue;
|
||||
|
||||
|
@ -526,7 +542,8 @@ static int i915_gem_fence_regs_info(struct seq_file *m, void *data)
|
|||
for (i = 0; i < dev_priv->num_fence_regs; i++) {
|
||||
struct drm_i915_gem_object *obj = dev_priv->fence_regs[i].obj;
|
||||
|
||||
seq_printf(m, "Fenced object[%2d] = ", i);
|
||||
seq_printf(m, "Fence %d, pin count = %d, object = ",
|
||||
i, dev_priv->fence_regs[i].pin_count);
|
||||
if (obj == NULL)
|
||||
seq_printf(m, "unused");
|
||||
else
|
||||
|
@ -645,10 +662,9 @@ static void i915_ring_error_state(struct seq_file *m,
|
|||
seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir[ring]);
|
||||
seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr[ring]);
|
||||
seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone[ring]);
|
||||
if (ring == RCS && INTEL_INFO(dev)->gen >= 4) {
|
||||
seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1);
|
||||
if (ring == RCS && INTEL_INFO(dev)->gen >= 4)
|
||||
seq_printf(m, " BBADDR: 0x%08llx\n", error->bbaddr);
|
||||
}
|
||||
|
||||
if (INTEL_INFO(dev)->gen >= 4)
|
||||
seq_printf(m, " INSTPS: 0x%08x\n", error->instps[ring]);
|
||||
seq_printf(m, " INSTPM: 0x%08x\n", error->instpm[ring]);
|
||||
|
@ -697,11 +713,17 @@ static int i915_error_state(struct seq_file *m, void *unused)
|
|||
for (i = 0; i < dev_priv->num_fence_regs; i++)
|
||||
seq_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(error->extra_instdone); i++)
|
||||
seq_printf(m, " INSTDONE_%d: 0x%08x\n", i, error->extra_instdone[i]);
|
||||
|
||||
if (INTEL_INFO(dev)->gen >= 6) {
|
||||
seq_printf(m, "ERROR: 0x%08x\n", error->error);
|
||||
seq_printf(m, "DONE_REG: 0x%08x\n", error->done_reg);
|
||||
}
|
||||
|
||||
if (INTEL_INFO(dev)->gen == 7)
|
||||
seq_printf(m, "ERR_INT: 0x%08x\n", error->err_int);
|
||||
|
||||
for_each_ring(ring, dev_priv, i)
|
||||
i915_ring_error_state(m, dev, error, i);
|
||||
|
||||
|
|
|
@ -235,10 +235,10 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
|
|||
}
|
||||
}
|
||||
|
||||
dev_priv->cpp = init->cpp;
|
||||
dev_priv->back_offset = init->back_offset;
|
||||
dev_priv->front_offset = init->front_offset;
|
||||
dev_priv->current_page = 0;
|
||||
dev_priv->dri1.cpp = init->cpp;
|
||||
dev_priv->dri1.back_offset = init->back_offset;
|
||||
dev_priv->dri1.front_offset = init->front_offset;
|
||||
dev_priv->dri1.current_page = 0;
|
||||
if (master_priv->sarea_priv)
|
||||
master_priv->sarea_priv->pf_current_page = 0;
|
||||
|
||||
|
@ -575,7 +575,7 @@ static int i915_dispatch_flip(struct drm_device * dev)
|
|||
|
||||
DRM_DEBUG_DRIVER("%s: page=%d pfCurrentPage=%d\n",
|
||||
__func__,
|
||||
dev_priv->current_page,
|
||||
dev_priv->dri1.current_page,
|
||||
master_priv->sarea_priv->pf_current_page);
|
||||
|
||||
i915_kernel_lost_context(dev);
|
||||
|
@ -589,12 +589,12 @@ static int i915_dispatch_flip(struct drm_device * dev)
|
|||
|
||||
OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP);
|
||||
OUT_RING(0);
|
||||
if (dev_priv->current_page == 0) {
|
||||
OUT_RING(dev_priv->back_offset);
|
||||
dev_priv->current_page = 1;
|
||||
if (dev_priv->dri1.current_page == 0) {
|
||||
OUT_RING(dev_priv->dri1.back_offset);
|
||||
dev_priv->dri1.current_page = 1;
|
||||
} else {
|
||||
OUT_RING(dev_priv->front_offset);
|
||||
dev_priv->current_page = 0;
|
||||
OUT_RING(dev_priv->dri1.front_offset);
|
||||
dev_priv->dri1.current_page = 0;
|
||||
}
|
||||
OUT_RING(0);
|
||||
|
||||
|
@ -613,7 +613,7 @@ static int i915_dispatch_flip(struct drm_device * dev)
|
|||
ADVANCE_LP_RING();
|
||||
}
|
||||
|
||||
master_priv->sarea_priv->pf_current_page = dev_priv->current_page;
|
||||
master_priv->sarea_priv->pf_current_page = dev_priv->dri1.current_page;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1012,6 +1012,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
|
|||
case I915_PARAM_HAS_SEMAPHORES:
|
||||
value = i915_semaphore_is_enabled(dev);
|
||||
break;
|
||||
case I915_PARAM_HAS_PRIME_VMAP_FLUSH:
|
||||
value = 1;
|
||||
break;
|
||||
default:
|
||||
DRM_DEBUG_DRIVER("Unknown parameter %d\n",
|
||||
param->param);
|
||||
|
@ -1555,11 +1558,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
|
|||
*
|
||||
* All tasks on the workqueue are expected to acquire the dev mutex
|
||||
* so there is no point in running more than one instance of the
|
||||
* workqueue at any time: max_active = 1 and NON_REENTRANT.
|
||||
* workqueue at any time. Use an ordered one.
|
||||
*/
|
||||
dev_priv->wq = alloc_workqueue("i915",
|
||||
WQ_UNBOUND | WQ_NON_REENTRANT,
|
||||
1);
|
||||
dev_priv->wq = alloc_ordered_workqueue("i915", 0);
|
||||
if (dev_priv->wq == NULL) {
|
||||
DRM_ERROR("Failed to create our workqueue.\n");
|
||||
ret = -ENOMEM;
|
||||
|
|
|
@ -1174,6 +1174,10 @@ void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \
|
|||
if (unlikely(__fifo_ret)) { \
|
||||
gen6_gt_check_fifodbg(dev_priv); \
|
||||
} \
|
||||
if (IS_HASWELL(dev_priv->dev) && (I915_READ_NOTRACE(GEN7_ERR_INT) & ERR_INT_MMIO_UNCLAIMED)) { \
|
||||
DRM_ERROR("Unclaimed write to %x\n", reg); \
|
||||
writel(ERR_INT_MMIO_UNCLAIMED, dev_priv->regs + GEN7_ERR_INT); \
|
||||
} \
|
||||
}
|
||||
__i915_write(8, b)
|
||||
__i915_write(16, w)
|
||||
|
|
|
@ -196,9 +196,10 @@ struct drm_i915_error_state {
|
|||
u32 cpu_ring_head[I915_NUM_RINGS];
|
||||
u32 cpu_ring_tail[I915_NUM_RINGS];
|
||||
u32 error; /* gen6+ */
|
||||
u32 err_int; /* gen7 */
|
||||
u32 instpm[I915_NUM_RINGS];
|
||||
u32 instps[I915_NUM_RINGS];
|
||||
u32 instdone1;
|
||||
u32 extra_instdone[I915_NUM_INSTDONE_REG];
|
||||
u32 seqno[I915_NUM_RINGS];
|
||||
u64 bbaddr;
|
||||
u32 fault_reg[I915_NUM_RINGS];
|
||||
|
@ -428,12 +429,6 @@ typedef struct drm_i915_private {
|
|||
|
||||
struct resource mch_res;
|
||||
|
||||
unsigned int cpp;
|
||||
int back_offset;
|
||||
int front_offset;
|
||||
int current_page;
|
||||
int page_flipping;
|
||||
|
||||
atomic_t irq_received;
|
||||
|
||||
/* protects the irq masks */
|
||||
|
@ -451,7 +446,6 @@ typedef struct drm_i915_private {
|
|||
u32 hotplug_supported_mask;
|
||||
struct work_struct hotplug_work;
|
||||
|
||||
unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds;
|
||||
int num_pipe;
|
||||
int num_pch_pll;
|
||||
|
||||
|
@ -460,8 +454,7 @@ typedef struct drm_i915_private {
|
|||
struct timer_list hangcheck_timer;
|
||||
int hangcheck_count;
|
||||
uint32_t last_acthd[I915_NUM_RINGS];
|
||||
uint32_t last_instdone;
|
||||
uint32_t last_instdone1;
|
||||
uint32_t prev_instdone[I915_NUM_INSTDONE_REG];
|
||||
|
||||
unsigned int stop_rings;
|
||||
|
||||
|
@ -692,7 +685,13 @@ typedef struct drm_i915_private {
|
|||
struct drm_mm gtt_space;
|
||||
/** List of all objects in gtt_space. Used to restore gtt
|
||||
* mappings on resume */
|
||||
struct list_head gtt_list;
|
||||
struct list_head bound_list;
|
||||
/**
|
||||
* List of objects which are not bound to the GTT (thus
|
||||
* are idle and not used by the GPU) but still have
|
||||
* (presumably uncached) pages still attached.
|
||||
*/
|
||||
struct list_head unbound_list;
|
||||
|
||||
/** Usable portion of the GTT for GEM */
|
||||
unsigned long gtt_start;
|
||||
|
@ -790,6 +789,12 @@ typedef struct drm_i915_private {
|
|||
struct {
|
||||
unsigned allow_batchbuffer : 1;
|
||||
u32 __iomem *gfx_hws_cpu_addr;
|
||||
|
||||
unsigned int cpp;
|
||||
int back_offset;
|
||||
int front_offset;
|
||||
int current_page;
|
||||
int page_flipping;
|
||||
} dri1;
|
||||
|
||||
/* Kernel Modesetting */
|
||||
|
@ -1296,19 +1301,20 @@ int i915_gem_wait_ioctl(struct drm_device *dev, void *data,
|
|||
struct drm_file *file_priv);
|
||||
void i915_gem_load(struct drm_device *dev);
|
||||
int i915_gem_init_object(struct drm_gem_object *obj);
|
||||
void i915_gem_object_init(struct drm_i915_gem_object *obj);
|
||||
struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
|
||||
size_t size);
|
||||
void i915_gem_free_object(struct drm_gem_object *obj);
|
||||
int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj,
|
||||
uint32_t alignment,
|
||||
bool map_and_fenceable);
|
||||
bool map_and_fenceable,
|
||||
bool nonblocking);
|
||||
void i915_gem_object_unpin(struct drm_i915_gem_object *obj);
|
||||
int __must_check i915_gem_object_unbind(struct drm_i915_gem_object *obj);
|
||||
void i915_gem_release_mmap(struct drm_i915_gem_object *obj);
|
||||
void i915_gem_lastclose(struct drm_device *dev);
|
||||
|
||||
int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj,
|
||||
gfp_t gfpmask);
|
||||
int __must_check i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj);
|
||||
int __must_check i915_mutex_lock_interruptible(struct drm_device *dev);
|
||||
int i915_gem_object_sync(struct drm_i915_gem_object *obj,
|
||||
struct intel_ring_buffer *to);
|
||||
|
@ -1449,8 +1455,9 @@ void i915_gem_init_global_gtt(struct drm_device *dev,
|
|||
int __must_check i915_gem_evict_something(struct drm_device *dev, int min_size,
|
||||
unsigned alignment,
|
||||
unsigned cache_level,
|
||||
bool mappable);
|
||||
int i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only);
|
||||
bool mappable,
|
||||
bool nonblock);
|
||||
int i915_gem_evict_everything(struct drm_device *dev);
|
||||
|
||||
/* i915_gem_stolen.c */
|
||||
int i915_gem_init_stolen(struct drm_device *dev);
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -221,7 +221,7 @@ static int create_default_context(struct drm_i915_private *dev_priv)
|
|||
* default context.
|
||||
*/
|
||||
dev_priv->ring[RCS].default_context = ctx;
|
||||
ret = i915_gem_object_pin(ctx->obj, CONTEXT_ALIGN, false);
|
||||
ret = i915_gem_object_pin(ctx->obj, CONTEXT_ALIGN, false, false);
|
||||
if (ret)
|
||||
goto err_destroy;
|
||||
|
||||
|
@ -374,7 +374,7 @@ static int do_switch(struct i915_hw_context *to)
|
|||
if (from_obj == to->obj)
|
||||
return 0;
|
||||
|
||||
ret = i915_gem_object_pin(to->obj, CONTEXT_ALIGN, false);
|
||||
ret = i915_gem_object_pin(to->obj, CONTEXT_ALIGN, false, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme
|
|||
struct drm_i915_gem_object *obj = attachment->dmabuf->priv;
|
||||
struct drm_device *dev = obj->base.dev;
|
||||
int npages = obj->base.size / PAGE_SIZE;
|
||||
struct sg_table *sg = NULL;
|
||||
struct sg_table *sg;
|
||||
int ret;
|
||||
int nents;
|
||||
|
||||
|
@ -41,10 +41,10 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme
|
|||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
if (!obj->pages) {
|
||||
ret = i915_gem_object_get_pages_gtt(obj, __GFP_NORETRY | __GFP_NOWARN);
|
||||
if (ret)
|
||||
goto out;
|
||||
ret = i915_gem_object_get_pages_gtt(obj);
|
||||
if (ret) {
|
||||
sg = ERR_PTR(ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* link the pages into an SG then map the sg */
|
||||
|
@ -89,12 +89,10 @@ static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf)
|
|||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (!obj->pages) {
|
||||
ret = i915_gem_object_get_pages_gtt(obj, __GFP_NORETRY | __GFP_NOWARN);
|
||||
if (ret) {
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
ret = i915_gem_object_get_pages_gtt(obj);
|
||||
if (ret) {
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
obj->dma_buf_vmapping = vmap(obj->pages, obj->base.size / PAGE_SIZE, 0, PAGE_KERNEL);
|
||||
|
@ -151,6 +149,22 @@ static int i915_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int i915_gem_begin_cpu_access(struct dma_buf *dma_buf, size_t start, size_t length, enum dma_data_direction direction)
|
||||
{
|
||||
struct drm_i915_gem_object *obj = dma_buf->priv;
|
||||
struct drm_device *dev = obj->base.dev;
|
||||
int ret;
|
||||
bool write = (direction == DMA_BIDIRECTIONAL || direction == DMA_TO_DEVICE);
|
||||
|
||||
ret = i915_mutex_lock_interruptible(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = i915_gem_object_set_to_cpu_domain(obj, write);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct dma_buf_ops i915_dmabuf_ops = {
|
||||
.map_dma_buf = i915_gem_map_dma_buf,
|
||||
.unmap_dma_buf = i915_gem_unmap_dma_buf,
|
||||
|
@ -162,6 +176,7 @@ static const struct dma_buf_ops i915_dmabuf_ops = {
|
|||
.mmap = i915_gem_dmabuf_mmap,
|
||||
.vmap = i915_gem_dmabuf_vmap,
|
||||
.vunmap = i915_gem_dmabuf_vunmap,
|
||||
.begin_cpu_access = i915_gem_begin_cpu_access,
|
||||
};
|
||||
|
||||
struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
|
||||
|
|
|
@ -45,7 +45,7 @@ mark_free(struct drm_i915_gem_object *obj, struct list_head *unwind)
|
|||
int
|
||||
i915_gem_evict_something(struct drm_device *dev, int min_size,
|
||||
unsigned alignment, unsigned cache_level,
|
||||
bool mappable)
|
||||
bool mappable, bool nonblocking)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
struct list_head eviction_list, unwind_list;
|
||||
|
@ -92,12 +92,16 @@ i915_gem_evict_something(struct drm_device *dev, int min_size,
|
|||
goto found;
|
||||
}
|
||||
|
||||
if (nonblocking)
|
||||
goto none;
|
||||
|
||||
/* Now merge in the soon-to-be-expired objects... */
|
||||
list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) {
|
||||
if (mark_free(obj, &unwind_list))
|
||||
goto found;
|
||||
}
|
||||
|
||||
none:
|
||||
/* Nothing found, clean up and bail out! */
|
||||
while (!list_empty(&unwind_list)) {
|
||||
obj = list_first_entry(&unwind_list,
|
||||
|
@ -148,7 +152,7 @@ found:
|
|||
}
|
||||
|
||||
int
|
||||
i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only)
|
||||
i915_gem_evict_everything(struct drm_device *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_i915_gem_object *obj, *next;
|
||||
|
@ -160,7 +164,7 @@ i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only)
|
|||
if (lists_empty)
|
||||
return -ENOSPC;
|
||||
|
||||
trace_i915_gem_evict_everything(dev, purgeable_only);
|
||||
trace_i915_gem_evict_everything(dev);
|
||||
|
||||
/* The gpu_idle will flush everything in the write domain to the
|
||||
* active list. Then we must move everything off the active list
|
||||
|
@ -174,12 +178,9 @@ i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only)
|
|||
|
||||
/* Having flushed everything, unbind() should never raise an error */
|
||||
list_for_each_entry_safe(obj, next,
|
||||
&dev_priv->mm.inactive_list, mm_list) {
|
||||
if (!purgeable_only || obj->madv != I915_MADV_WILLNEED) {
|
||||
if (obj->pin_count == 0)
|
||||
WARN_ON(i915_gem_object_unbind(obj));
|
||||
}
|
||||
}
|
||||
&dev_priv->mm.inactive_list, mm_list)
|
||||
if (obj->pin_count == 0)
|
||||
WARN_ON(i915_gem_object_unbind(obj));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -95,6 +95,7 @@ eb_destroy(struct eb_objects *eb)
|
|||
static inline int use_cpu_reloc(struct drm_i915_gem_object *obj)
|
||||
{
|
||||
return (obj->base.write_domain == I915_GEM_DOMAIN_CPU ||
|
||||
!obj->map_and_fenceable ||
|
||||
obj->cache_level != I915_CACHE_NONE);
|
||||
}
|
||||
|
||||
|
@ -330,7 +331,8 @@ i915_gem_execbuffer_relocate(struct drm_device *dev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
#define __EXEC_OBJECT_HAS_FENCE (1<<31)
|
||||
#define __EXEC_OBJECT_HAS_PIN (1<<31)
|
||||
#define __EXEC_OBJECT_HAS_FENCE (1<<30)
|
||||
|
||||
static int
|
||||
need_reloc_mappable(struct drm_i915_gem_object *obj)
|
||||
|
@ -340,9 +342,10 @@ need_reloc_mappable(struct drm_i915_gem_object *obj)
|
|||
}
|
||||
|
||||
static int
|
||||
pin_and_fence_object(struct drm_i915_gem_object *obj,
|
||||
struct intel_ring_buffer *ring)
|
||||
i915_gem_execbuffer_reserve_object(struct drm_i915_gem_object *obj,
|
||||
struct intel_ring_buffer *ring)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
|
||||
struct drm_i915_gem_exec_object2 *entry = obj->exec_entry;
|
||||
bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4;
|
||||
bool need_fence, need_mappable;
|
||||
|
@ -354,15 +357,17 @@ pin_and_fence_object(struct drm_i915_gem_object *obj,
|
|||
obj->tiling_mode != I915_TILING_NONE;
|
||||
need_mappable = need_fence || need_reloc_mappable(obj);
|
||||
|
||||
ret = i915_gem_object_pin(obj, entry->alignment, need_mappable);
|
||||
ret = i915_gem_object_pin(obj, entry->alignment, need_mappable, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
entry->flags |= __EXEC_OBJECT_HAS_PIN;
|
||||
|
||||
if (has_fenced_gpu_access) {
|
||||
if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) {
|
||||
ret = i915_gem_object_get_fence(obj);
|
||||
if (ret)
|
||||
goto err_unpin;
|
||||
return ret;
|
||||
|
||||
if (i915_gem_object_pin_fence(obj))
|
||||
entry->flags |= __EXEC_OBJECT_HAS_FENCE;
|
||||
|
@ -371,12 +376,35 @@ pin_and_fence_object(struct drm_i915_gem_object *obj,
|
|||
}
|
||||
}
|
||||
|
||||
/* Ensure ppgtt mapping exists if needed */
|
||||
if (dev_priv->mm.aliasing_ppgtt && !obj->has_aliasing_ppgtt_mapping) {
|
||||
i915_ppgtt_bind_object(dev_priv->mm.aliasing_ppgtt,
|
||||
obj, obj->cache_level);
|
||||
|
||||
obj->has_aliasing_ppgtt_mapping = 1;
|
||||
}
|
||||
|
||||
entry->offset = obj->gtt_offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
err_unpin:
|
||||
i915_gem_object_unpin(obj);
|
||||
return ret;
|
||||
static void
|
||||
i915_gem_execbuffer_unreserve_object(struct drm_i915_gem_object *obj)
|
||||
{
|
||||
struct drm_i915_gem_exec_object2 *entry;
|
||||
|
||||
if (!obj->gtt_space)
|
||||
return;
|
||||
|
||||
entry = obj->exec_entry;
|
||||
|
||||
if (entry->flags & __EXEC_OBJECT_HAS_FENCE)
|
||||
i915_gem_object_unpin_fence(obj);
|
||||
|
||||
if (entry->flags & __EXEC_OBJECT_HAS_PIN)
|
||||
i915_gem_object_unpin(obj);
|
||||
|
||||
entry->flags &= ~(__EXEC_OBJECT_HAS_FENCE | __EXEC_OBJECT_HAS_PIN);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -384,11 +412,10 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
|
|||
struct drm_file *file,
|
||||
struct list_head *objects)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = ring->dev->dev_private;
|
||||
struct drm_i915_gem_object *obj;
|
||||
int ret, retry;
|
||||
bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4;
|
||||
struct list_head ordered_objects;
|
||||
bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4;
|
||||
int retry;
|
||||
|
||||
INIT_LIST_HEAD(&ordered_objects);
|
||||
while (!list_empty(objects)) {
|
||||
|
@ -426,12 +453,12 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
|
|||
* 2. Bind new objects.
|
||||
* 3. Decrement pin count.
|
||||
*
|
||||
* This avoid unnecessary unbinding of later objects in order to makr
|
||||
* This avoid unnecessary unbinding of later objects in order to make
|
||||
* room for the earlier objects *unless* we need to defragment.
|
||||
*/
|
||||
retry = 0;
|
||||
do {
|
||||
ret = 0;
|
||||
int ret = 0;
|
||||
|
||||
/* Unbind any ill-fitting objects or pin. */
|
||||
list_for_each_entry(obj, objects, exec_list) {
|
||||
|
@ -451,7 +478,7 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
|
|||
(need_mappable && !obj->map_and_fenceable))
|
||||
ret = i915_gem_object_unbind(obj);
|
||||
else
|
||||
ret = pin_and_fence_object(obj, ring);
|
||||
ret = i915_gem_execbuffer_reserve_object(obj, ring);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
@ -461,77 +488,22 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
|
|||
if (obj->gtt_space)
|
||||
continue;
|
||||
|
||||
ret = pin_and_fence_object(obj, ring);
|
||||
if (ret) {
|
||||
int ret_ignore;
|
||||
|
||||
/* This can potentially raise a harmless
|
||||
* -EINVAL if we failed to bind in the above
|
||||
* call. It cannot raise -EINTR since we know
|
||||
* that the bo is freshly bound and so will
|
||||
* not need to be flushed or waited upon.
|
||||
*/
|
||||
ret_ignore = i915_gem_object_unbind(obj);
|
||||
(void)ret_ignore;
|
||||
WARN_ON(obj->gtt_space);
|
||||
break;
|
||||
}
|
||||
ret = i915_gem_execbuffer_reserve_object(obj, ring);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Decrement pin count for bound objects */
|
||||
list_for_each_entry(obj, objects, exec_list) {
|
||||
struct drm_i915_gem_exec_object2 *entry;
|
||||
err: /* Decrement pin count for bound objects */
|
||||
list_for_each_entry(obj, objects, exec_list)
|
||||
i915_gem_execbuffer_unreserve_object(obj);
|
||||
|
||||
if (!obj->gtt_space)
|
||||
continue;
|
||||
|
||||
entry = obj->exec_entry;
|
||||
if (entry->flags & __EXEC_OBJECT_HAS_FENCE) {
|
||||
i915_gem_object_unpin_fence(obj);
|
||||
entry->flags &= ~__EXEC_OBJECT_HAS_FENCE;
|
||||
}
|
||||
|
||||
i915_gem_object_unpin(obj);
|
||||
|
||||
/* ... and ensure ppgtt mapping exist if needed. */
|
||||
if (dev_priv->mm.aliasing_ppgtt && !obj->has_aliasing_ppgtt_mapping) {
|
||||
i915_ppgtt_bind_object(dev_priv->mm.aliasing_ppgtt,
|
||||
obj, obj->cache_level);
|
||||
|
||||
obj->has_aliasing_ppgtt_mapping = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != -ENOSPC || retry > 1)
|
||||
if (ret != -ENOSPC || retry++)
|
||||
return ret;
|
||||
|
||||
/* First attempt, just clear anything that is purgeable.
|
||||
* Second attempt, clear the entire GTT.
|
||||
*/
|
||||
ret = i915_gem_evict_everything(ring->dev, retry == 0);
|
||||
ret = i915_gem_evict_everything(ring->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
retry++;
|
||||
} while (1);
|
||||
|
||||
err:
|
||||
list_for_each_entry_continue_reverse(obj, objects, exec_list) {
|
||||
struct drm_i915_gem_exec_object2 *entry;
|
||||
|
||||
if (!obj->gtt_space)
|
||||
continue;
|
||||
|
||||
entry = obj->exec_entry;
|
||||
if (entry->flags & __EXEC_OBJECT_HAS_FENCE) {
|
||||
i915_gem_object_unpin_fence(obj);
|
||||
entry->flags &= ~__EXEC_OBJECT_HAS_FENCE;
|
||||
}
|
||||
|
||||
i915_gem_object_unpin(obj);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -351,7 +351,7 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev)
|
|||
intel_gtt_clear_range(dev_priv->mm.gtt_start / PAGE_SIZE,
|
||||
(dev_priv->mm.gtt_end - dev_priv->mm.gtt_start) / PAGE_SIZE);
|
||||
|
||||
list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) {
|
||||
list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) {
|
||||
i915_gem_clflush_object(obj);
|
||||
i915_gem_gtt_bind_object(obj, obj->cache_level);
|
||||
}
|
||||
|
|
|
@ -1070,6 +1070,36 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* NB: please notice the memset */
|
||||
static void i915_get_extra_instdone(struct drm_device *dev,
|
||||
uint32_t *instdone)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
memset(instdone, 0, sizeof(*instdone) * I915_NUM_INSTDONE_REG);
|
||||
|
||||
switch(INTEL_INFO(dev)->gen) {
|
||||
case 2:
|
||||
case 3:
|
||||
instdone[0] = I915_READ(INSTDONE);
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
instdone[0] = I915_READ(INSTDONE_I965);
|
||||
instdone[1] = I915_READ(INSTDONE1);
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE(1, "Unsupported platform\n");
|
||||
case 7:
|
||||
instdone[0] = I915_READ(GEN7_INSTDONE_1);
|
||||
instdone[1] = I915_READ(GEN7_SC_INSTDONE);
|
||||
instdone[2] = I915_READ(GEN7_SAMPLER_INSTDONE);
|
||||
instdone[3] = I915_READ(GEN7_ROW_INSTDONE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void i915_record_ring_state(struct drm_device *dev,
|
||||
struct drm_i915_error_state *error,
|
||||
struct intel_ring_buffer *ring)
|
||||
|
@ -1091,10 +1121,8 @@ static void i915_record_ring_state(struct drm_device *dev,
|
|||
error->ipehr[ring->id] = I915_READ(RING_IPEHR(ring->mmio_base));
|
||||
error->instdone[ring->id] = I915_READ(RING_INSTDONE(ring->mmio_base));
|
||||
error->instps[ring->id] = I915_READ(RING_INSTPS(ring->mmio_base));
|
||||
if (ring->id == RCS) {
|
||||
error->instdone1 = I915_READ(INSTDONE1);
|
||||
if (ring->id == RCS)
|
||||
error->bbaddr = I915_READ64(BB_ADDR);
|
||||
}
|
||||
} else {
|
||||
error->faddr[ring->id] = I915_READ(DMA_FADD_I8XX);
|
||||
error->ipeir[ring->id] = I915_READ(IPEIR);
|
||||
|
@ -1210,6 +1238,11 @@ static void i915_capture_error_state(struct drm_device *dev)
|
|||
error->done_reg = I915_READ(DONE_REG);
|
||||
}
|
||||
|
||||
if (INTEL_INFO(dev)->gen == 7)
|
||||
error->err_int = I915_READ(GEN7_ERR_INT);
|
||||
|
||||
i915_get_extra_instdone(dev, error->extra_instdone);
|
||||
|
||||
i915_gem_record_fences(dev, error);
|
||||
i915_gem_record_rings(dev, error);
|
||||
|
||||
|
@ -1221,7 +1254,7 @@ static void i915_capture_error_state(struct drm_device *dev)
|
|||
list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list)
|
||||
i++;
|
||||
error->active_bo_count = i;
|
||||
list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list)
|
||||
list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list)
|
||||
if (obj->pin_count)
|
||||
i++;
|
||||
error->pinned_bo_count = i - error->active_bo_count;
|
||||
|
@ -1246,7 +1279,7 @@ static void i915_capture_error_state(struct drm_device *dev)
|
|||
error->pinned_bo_count =
|
||||
capture_pinned_bo(error->pinned_bo,
|
||||
error->pinned_bo_count,
|
||||
&dev_priv->mm.gtt_list);
|
||||
&dev_priv->mm.bound_list);
|
||||
|
||||
do_gettimeofday(&error->time);
|
||||
|
||||
|
@ -1285,24 +1318,26 @@ void i915_destroy_error_state(struct drm_device *dev)
|
|||
static void i915_report_and_clear_eir(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
uint32_t instdone[I915_NUM_INSTDONE_REG];
|
||||
u32 eir = I915_READ(EIR);
|
||||
int pipe;
|
||||
int pipe, i;
|
||||
|
||||
if (!eir)
|
||||
return;
|
||||
|
||||
pr_err("render error detected, EIR: 0x%08x\n", eir);
|
||||
|
||||
i915_get_extra_instdone(dev, instdone);
|
||||
|
||||
if (IS_G4X(dev)) {
|
||||
if (eir & (GM45_ERROR_MEM_PRIV | GM45_ERROR_CP_PRIV)) {
|
||||
u32 ipeir = I915_READ(IPEIR_I965);
|
||||
|
||||
pr_err(" IPEIR: 0x%08x\n", I915_READ(IPEIR_I965));
|
||||
pr_err(" IPEHR: 0x%08x\n", I915_READ(IPEHR_I965));
|
||||
pr_err(" INSTDONE: 0x%08x\n",
|
||||
I915_READ(INSTDONE_I965));
|
||||
for (i = 0; i < ARRAY_SIZE(instdone); i++)
|
||||
pr_err(" INSTDONE_%d: 0x%08x\n", i, instdone[i]);
|
||||
pr_err(" INSTPS: 0x%08x\n", I915_READ(INSTPS));
|
||||
pr_err(" INSTDONE1: 0x%08x\n", I915_READ(INSTDONE1));
|
||||
pr_err(" ACTHD: 0x%08x\n", I915_READ(ACTHD_I965));
|
||||
I915_WRITE(IPEIR_I965, ipeir);
|
||||
POSTING_READ(IPEIR_I965);
|
||||
|
@ -1336,12 +1371,13 @@ static void i915_report_and_clear_eir(struct drm_device *dev)
|
|||
if (eir & I915_ERROR_INSTRUCTION) {
|
||||
pr_err("instruction error\n");
|
||||
pr_err(" INSTPM: 0x%08x\n", I915_READ(INSTPM));
|
||||
for (i = 0; i < ARRAY_SIZE(instdone); i++)
|
||||
pr_err(" INSTDONE_%d: 0x%08x\n", i, instdone[i]);
|
||||
if (INTEL_INFO(dev)->gen < 4) {
|
||||
u32 ipeir = I915_READ(IPEIR);
|
||||
|
||||
pr_err(" IPEIR: 0x%08x\n", I915_READ(IPEIR));
|
||||
pr_err(" IPEHR: 0x%08x\n", I915_READ(IPEHR));
|
||||
pr_err(" INSTDONE: 0x%08x\n", I915_READ(INSTDONE));
|
||||
pr_err(" ACTHD: 0x%08x\n", I915_READ(ACTHD));
|
||||
I915_WRITE(IPEIR, ipeir);
|
||||
POSTING_READ(IPEIR);
|
||||
|
@ -1350,10 +1386,7 @@ static void i915_report_and_clear_eir(struct drm_device *dev)
|
|||
|
||||
pr_err(" IPEIR: 0x%08x\n", I915_READ(IPEIR_I965));
|
||||
pr_err(" IPEHR: 0x%08x\n", I915_READ(IPEHR_I965));
|
||||
pr_err(" INSTDONE: 0x%08x\n",
|
||||
I915_READ(INSTDONE_I965));
|
||||
pr_err(" INSTPS: 0x%08x\n", I915_READ(INSTPS));
|
||||
pr_err(" INSTDONE1: 0x%08x\n", I915_READ(INSTDONE1));
|
||||
pr_err(" ACTHD: 0x%08x\n", I915_READ(ACTHD_I965));
|
||||
I915_WRITE(IPEIR_I965, ipeir);
|
||||
POSTING_READ(IPEIR_I965);
|
||||
|
@ -1668,7 +1701,7 @@ void i915_hangcheck_elapsed(unsigned long data)
|
|||
{
|
||||
struct drm_device *dev = (struct drm_device *)data;
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
uint32_t acthd[I915_NUM_RINGS], instdone, instdone1;
|
||||
uint32_t acthd[I915_NUM_RINGS], instdone[I915_NUM_INSTDONE_REG];
|
||||
struct intel_ring_buffer *ring;
|
||||
bool err = false, idle;
|
||||
int i;
|
||||
|
@ -1696,25 +1729,16 @@ void i915_hangcheck_elapsed(unsigned long data)
|
|||
return;
|
||||
}
|
||||
|
||||
if (INTEL_INFO(dev)->gen < 4) {
|
||||
instdone = I915_READ(INSTDONE);
|
||||
instdone1 = 0;
|
||||
} else {
|
||||
instdone = I915_READ(INSTDONE_I965);
|
||||
instdone1 = I915_READ(INSTDONE1);
|
||||
}
|
||||
|
||||
i915_get_extra_instdone(dev, instdone);
|
||||
if (memcmp(dev_priv->last_acthd, acthd, sizeof(acthd)) == 0 &&
|
||||
dev_priv->last_instdone == instdone &&
|
||||
dev_priv->last_instdone1 == instdone1) {
|
||||
memcmp(dev_priv->prev_instdone, instdone, sizeof(instdone)) == 0) {
|
||||
if (i915_hangcheck_hung(dev))
|
||||
return;
|
||||
} else {
|
||||
dev_priv->hangcheck_count = 0;
|
||||
|
||||
memcpy(dev_priv->last_acthd, acthd, sizeof(acthd));
|
||||
dev_priv->last_instdone = instdone;
|
||||
dev_priv->last_instdone1 = instdone1;
|
||||
memcpy(dev_priv->prev_instdone, instdone, sizeof(instdone));
|
||||
}
|
||||
|
||||
repeat:
|
||||
|
|
|
@ -479,6 +479,11 @@
|
|||
#define IPEIR_I965 0x02064
|
||||
#define IPEHR_I965 0x02068
|
||||
#define INSTDONE_I965 0x0206c
|
||||
#define GEN7_INSTDONE_1 0x0206c
|
||||
#define GEN7_SC_INSTDONE 0x07100
|
||||
#define GEN7_SAMPLER_INSTDONE 0x0e160
|
||||
#define GEN7_ROW_INSTDONE 0x0e164
|
||||
#define I915_NUM_INSTDONE_REG 4
|
||||
#define RING_IPEIR(base) ((base)+0x64)
|
||||
#define RING_IPEHR(base) ((base)+0x68)
|
||||
#define RING_INSTDONE(base) ((base)+0x6c)
|
||||
|
@ -501,6 +506,8 @@
|
|||
#define DMA_FADD_I8XX 0x020d0
|
||||
|
||||
#define ERROR_GEN6 0x040a0
|
||||
#define GEN7_ERR_INT 0x44040
|
||||
#define ERR_INT_MMIO_UNCLAIMED (1<<13)
|
||||
|
||||
/* GM45+ chicken bits -- debug workaround bits that may be required
|
||||
* for various sorts of correct behavior. The top 16 bits of each are
|
||||
|
@ -4248,7 +4255,15 @@
|
|||
#define G4X_HDMIW_HDMIEDID 0x6210C
|
||||
|
||||
#define IBX_HDMIW_HDMIEDID_A 0xE2050
|
||||
#define IBX_HDMIW_HDMIEDID_B 0xE2150
|
||||
#define IBX_HDMIW_HDMIEDID(pipe) _PIPE(pipe, \
|
||||
IBX_HDMIW_HDMIEDID_A, \
|
||||
IBX_HDMIW_HDMIEDID_B)
|
||||
#define IBX_AUD_CNTL_ST_A 0xE20B4
|
||||
#define IBX_AUD_CNTL_ST_B 0xE21B4
|
||||
#define IBX_AUD_CNTL_ST(pipe) _PIPE(pipe, \
|
||||
IBX_AUD_CNTL_ST_A, \
|
||||
IBX_AUD_CNTL_ST_B)
|
||||
#define IBX_ELD_BUFFER_SIZE (0x1f << 10)
|
||||
#define IBX_ELD_ADDRESS (0x1f << 5)
|
||||
#define IBX_ELD_ACK (1 << 4)
|
||||
|
@ -4257,7 +4272,15 @@
|
|||
#define IBX_CP_READYB (1 << 1)
|
||||
|
||||
#define CPT_HDMIW_HDMIEDID_A 0xE5050
|
||||
#define CPT_HDMIW_HDMIEDID_B 0xE5150
|
||||
#define CPT_HDMIW_HDMIEDID(pipe) _PIPE(pipe, \
|
||||
CPT_HDMIW_HDMIEDID_A, \
|
||||
CPT_HDMIW_HDMIEDID_B)
|
||||
#define CPT_AUD_CNTL_ST_A 0xE50B4
|
||||
#define CPT_AUD_CNTL_ST_B 0xE51B4
|
||||
#define CPT_AUD_CNTL_ST(pipe) _PIPE(pipe, \
|
||||
CPT_AUD_CNTL_ST_A, \
|
||||
CPT_AUD_CNTL_ST_B)
|
||||
#define CPT_AUD_CNTRL_ST2 0xE50C0
|
||||
|
||||
/* These are the 4 32-bit write offset registers for each stream
|
||||
|
@ -4267,7 +4290,15 @@
|
|||
#define GEN7_SO_WRITE_OFFSET(n) (0x5280 + (n) * 4)
|
||||
|
||||
#define IBX_AUD_CONFIG_A 0xe2000
|
||||
#define IBX_AUD_CONFIG_B 0xe2100
|
||||
#define IBX_AUD_CFG(pipe) _PIPE(pipe, \
|
||||
IBX_AUD_CONFIG_A, \
|
||||
IBX_AUD_CONFIG_B)
|
||||
#define CPT_AUD_CONFIG_A 0xe5000
|
||||
#define CPT_AUD_CONFIG_B 0xe5100
|
||||
#define CPT_AUD_CFG(pipe) _PIPE(pipe, \
|
||||
CPT_AUD_CONFIG_A, \
|
||||
CPT_AUD_CONFIG_B)
|
||||
#define AUD_CONFIG_N_VALUE_INDEX (1 << 29)
|
||||
#define AUD_CONFIG_N_PROG_ENABLE (1 << 28)
|
||||
#define AUD_CONFIG_UPPER_N_SHIFT 20
|
||||
|
@ -4278,6 +4309,54 @@
|
|||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI (0xf << 16)
|
||||
#define AUD_CONFIG_DISABLE_NCTS (1 << 3)
|
||||
|
||||
/* HSW Audio */
|
||||
#define HSW_AUD_CONFIG_A 0x65000 /* Audio Configuration Transcoder A */
|
||||
#define HSW_AUD_CONFIG_B 0x65100 /* Audio Configuration Transcoder B */
|
||||
#define HSW_AUD_CFG(pipe) _PIPE(pipe, \
|
||||
HSW_AUD_CONFIG_A, \
|
||||
HSW_AUD_CONFIG_B)
|
||||
|
||||
#define HSW_AUD_MISC_CTRL_A 0x65010 /* Audio Misc Control Convert 1 */
|
||||
#define HSW_AUD_MISC_CTRL_B 0x65110 /* Audio Misc Control Convert 2 */
|
||||
#define HSW_AUD_MISC_CTRL(pipe) _PIPE(pipe, \
|
||||
HSW_AUD_MISC_CTRL_A, \
|
||||
HSW_AUD_MISC_CTRL_B)
|
||||
|
||||
#define HSW_AUD_DIP_ELD_CTRL_ST_A 0x650b4 /* Audio DIP and ELD Control State Transcoder A */
|
||||
#define HSW_AUD_DIP_ELD_CTRL_ST_B 0x651b4 /* Audio DIP and ELD Control State Transcoder B */
|
||||
#define HSW_AUD_DIP_ELD_CTRL(pipe) _PIPE(pipe, \
|
||||
HSW_AUD_DIP_ELD_CTRL_ST_A, \
|
||||
HSW_AUD_DIP_ELD_CTRL_ST_B)
|
||||
|
||||
/* Audio Digital Converter */
|
||||
#define HSW_AUD_DIG_CNVT_1 0x65080 /* Audio Converter 1 */
|
||||
#define HSW_AUD_DIG_CNVT_2 0x65180 /* Audio Converter 1 */
|
||||
#define AUD_DIG_CNVT(pipe) _PIPE(pipe, \
|
||||
HSW_AUD_DIG_CNVT_1, \
|
||||
HSW_AUD_DIG_CNVT_2)
|
||||
#define DIP_PORT_SEL_MASK 0x3
|
||||
|
||||
#define HSW_AUD_EDID_DATA_A 0x65050
|
||||
#define HSW_AUD_EDID_DATA_B 0x65150
|
||||
#define HSW_AUD_EDID_DATA(pipe) _PIPE(pipe, \
|
||||
HSW_AUD_EDID_DATA_A, \
|
||||
HSW_AUD_EDID_DATA_B)
|
||||
|
||||
#define HSW_AUD_PIPE_CONV_CFG 0x6507c /* Audio pipe and converter configs */
|
||||
#define HSW_AUD_PIN_ELD_CP_VLD 0x650c0 /* Audio ELD and CP Ready Status */
|
||||
#define AUDIO_INACTIVE_C (1<<11)
|
||||
#define AUDIO_INACTIVE_B (1<<7)
|
||||
#define AUDIO_INACTIVE_A (1<<3)
|
||||
#define AUDIO_OUTPUT_ENABLE_A (1<<2)
|
||||
#define AUDIO_OUTPUT_ENABLE_B (1<<6)
|
||||
#define AUDIO_OUTPUT_ENABLE_C (1<<10)
|
||||
#define AUDIO_ELD_VALID_A (1<<0)
|
||||
#define AUDIO_ELD_VALID_B (1<<4)
|
||||
#define AUDIO_ELD_VALID_C (1<<8)
|
||||
#define AUDIO_CP_READY_A (1<<1)
|
||||
#define AUDIO_CP_READY_B (1<<5)
|
||||
#define AUDIO_CP_READY_C (1<<9)
|
||||
|
||||
/* HSW Power Wells */
|
||||
#define HSW_PWR_WELL_CTL1 0x45400 /* BIOS */
|
||||
#define HSW_PWR_WELL_CTL2 0x45404 /* Driver */
|
||||
|
|
|
@ -214,22 +214,18 @@ TRACE_EVENT(i915_gem_evict,
|
|||
);
|
||||
|
||||
TRACE_EVENT(i915_gem_evict_everything,
|
||||
TP_PROTO(struct drm_device *dev, bool purgeable),
|
||||
TP_ARGS(dev, purgeable),
|
||||
TP_PROTO(struct drm_device *dev),
|
||||
TP_ARGS(dev),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(u32, dev)
|
||||
__field(bool, purgeable)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->dev = dev->primary->index;
|
||||
__entry->purgeable = purgeable;
|
||||
),
|
||||
|
||||
TP_printk("dev=%d%s",
|
||||
__entry->dev,
|
||||
__entry->purgeable ? ", purgeable only" : "")
|
||||
TP_printk("dev=%d", __entry->dev)
|
||||
);
|
||||
|
||||
TRACE_EVENT(i915_gem_ring_dispatch,
|
||||
|
|
|
@ -547,14 +547,12 @@ intel_crt_detect(struct drm_connector *connector, bool force)
|
|||
return connector->status;
|
||||
|
||||
/* for pre-945g platforms use load detect */
|
||||
if (intel_get_load_detect_pipe(&crt->base, connector, NULL,
|
||||
&tmp)) {
|
||||
if (intel_get_load_detect_pipe(connector, NULL, &tmp)) {
|
||||
if (intel_crt_detect_ddc(connector))
|
||||
status = connector_status_connected;
|
||||
else
|
||||
status = intel_crt_load_detect(crt);
|
||||
intel_release_load_detect_pipe(&crt->base, connector,
|
||||
&tmp);
|
||||
intel_release_load_detect_pipe(connector, &tmp);
|
||||
} else
|
||||
status = connector_status_unknown;
|
||||
|
||||
|
@ -694,7 +692,7 @@ void intel_crt_init(struct drm_device *dev)
|
|||
if (IS_HASWELL(dev))
|
||||
crt->base.crtc_mask = (1 << 0);
|
||||
else
|
||||
crt->base.crtc_mask = (1 << 0) | (1 << 1);
|
||||
crt->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
|
||||
|
||||
if (IS_GEN2(dev))
|
||||
connector->interlace_allowed = 0;
|
||||
|
|
|
@ -713,8 +713,12 @@ void intel_ddi_mode_set(struct drm_encoder *encoder,
|
|||
/* Proper support for digital audio needs a new logic and a new set
|
||||
* of registers, so we leave it for future patch bombing.
|
||||
*/
|
||||
DRM_DEBUG_DRIVER("HDMI audio on pipe %c not yet supported on DDI\n",
|
||||
DRM_DEBUG_DRIVER("HDMI audio on pipe %c on DDI\n",
|
||||
pipe_name(intel_crtc->pipe));
|
||||
|
||||
/* write eld */
|
||||
DRM_DEBUG_DRIVER("HDMI audio: write eld information\n");
|
||||
intel_write_eld(encoder, adjusted_mode);
|
||||
}
|
||||
|
||||
/* Enable PIPE_DDI_FUNC_CTL for the pipe to work in HDMI mode */
|
||||
|
|
|
@ -1384,7 +1384,7 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv,
|
|||
enum pipe pipe, int reg)
|
||||
{
|
||||
u32 val = I915_READ(reg);
|
||||
WARN(hdmi_pipe_enabled(dev_priv, val, pipe),
|
||||
WARN(hdmi_pipe_enabled(dev_priv, pipe, val),
|
||||
"PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n",
|
||||
reg, pipe_name(pipe));
|
||||
|
||||
|
@ -1404,13 +1404,13 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
|
|||
|
||||
reg = PCH_ADPA;
|
||||
val = I915_READ(reg);
|
||||
WARN(adpa_pipe_enabled(dev_priv, val, pipe),
|
||||
WARN(adpa_pipe_enabled(dev_priv, pipe, val),
|
||||
"PCH VGA enabled on transcoder %c, should be disabled\n",
|
||||
pipe_name(pipe));
|
||||
|
||||
reg = PCH_LVDS;
|
||||
val = I915_READ(reg);
|
||||
WARN(lvds_pipe_enabled(dev_priv, val, pipe),
|
||||
WARN(lvds_pipe_enabled(dev_priv, pipe, val),
|
||||
"PCH LVDS enabled on transcoder %c, should be disabled\n",
|
||||
pipe_name(pipe));
|
||||
|
||||
|
@ -1432,7 +1432,7 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
|
|||
*
|
||||
* Unfortunately needed by dvo_ns2501 since the dvo depends on it running.
|
||||
*/
|
||||
void intel_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
|
||||
static void intel_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
|
||||
{
|
||||
int reg;
|
||||
u32 val;
|
||||
|
@ -1874,7 +1874,7 @@ static void disable_pch_hdmi(struct drm_i915_private *dev_priv,
|
|||
enum pipe pipe, int reg)
|
||||
{
|
||||
u32 val = I915_READ(reg);
|
||||
if (hdmi_pipe_enabled(dev_priv, val, pipe)) {
|
||||
if (hdmi_pipe_enabled(dev_priv, pipe, val)) {
|
||||
DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n",
|
||||
reg, pipe);
|
||||
I915_WRITE(reg, val & ~PORT_ENABLE);
|
||||
|
@ -1896,12 +1896,12 @@ static void intel_disable_pch_ports(struct drm_i915_private *dev_priv,
|
|||
|
||||
reg = PCH_ADPA;
|
||||
val = I915_READ(reg);
|
||||
if (adpa_pipe_enabled(dev_priv, val, pipe))
|
||||
if (adpa_pipe_enabled(dev_priv, pipe, val))
|
||||
I915_WRITE(reg, val & ~ADPA_DAC_ENABLE);
|
||||
|
||||
reg = PCH_LVDS;
|
||||
val = I915_READ(reg);
|
||||
if (lvds_pipe_enabled(dev_priv, val, pipe)) {
|
||||
if (lvds_pipe_enabled(dev_priv, pipe, val)) {
|
||||
DRM_DEBUG_KMS("disable lvds on pipe %d val 0x%08x\n", pipe, val);
|
||||
I915_WRITE(reg, val & ~LVDS_PORT_EN);
|
||||
POSTING_READ(reg);
|
||||
|
@ -2709,11 +2709,10 @@ static void ivb_manual_fdi_link_train(struct drm_crtc *crtc)
|
|||
DRM_DEBUG_KMS("FDI train done.\n");
|
||||
}
|
||||
|
||||
static void ironlake_fdi_pll_enable(struct drm_crtc *crtc)
|
||||
static void ironlake_fdi_pll_enable(struct intel_crtc *intel_crtc)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_device *dev = intel_crtc->base.dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
int pipe = intel_crtc->pipe;
|
||||
u32 reg, temp;
|
||||
|
||||
|
@ -2754,6 +2753,35 @@ static void ironlake_fdi_pll_enable(struct drm_crtc *crtc)
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void cpt_phase_pointer_disable(struct drm_device *dev, int pipe)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
@ -3201,7 +3229,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
|
|||
is_pch_port = intel_crtc_driving_pch(crtc);
|
||||
|
||||
if (is_pch_port)
|
||||
ironlake_fdi_pll_enable(crtc);
|
||||
ironlake_fdi_pll_enable(intel_crtc);
|
||||
else
|
||||
ironlake_fdi_disable(crtc);
|
||||
|
||||
|
@ -3304,26 +3332,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
|
|||
/* disable PCH DPLL */
|
||||
intel_disable_pch_pll(intel_crtc);
|
||||
|
||||
/* 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);
|
||||
ironlake_fdi_pll_disable(intel_crtc);
|
||||
|
||||
intel_crtc->active = false;
|
||||
intel_update_watermarks(dev);
|
||||
|
@ -3593,6 +3602,13 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
|
|||
if (!(adjusted_mode->private_flags & INTEL_MODE_CRTC_TIMINGS_SET))
|
||||
drm_mode_set_crtcinfo(adjusted_mode, 0);
|
||||
|
||||
/* 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;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -5057,6 +5073,91 @@ static void g4x_write_eld(struct drm_connector *connector,
|
|||
I915_WRITE(G4X_AUD_CNTL_ST, i);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
static void ironlake_write_eld(struct drm_connector *connector,
|
||||
struct drm_crtc *crtc)
|
||||
{
|
||||
|
@ -5069,28 +5170,24 @@ static void ironlake_write_eld(struct drm_connector *connector,
|
|||
int aud_config;
|
||||
int aud_cntl_st;
|
||||
int aud_cntrl_st2;
|
||||
int pipe = to_intel_crtc(crtc)->pipe;
|
||||
|
||||
if (HAS_PCH_IBX(connector->dev)) {
|
||||
hdmiw_hdmiedid = IBX_HDMIW_HDMIEDID_A;
|
||||
aud_config = IBX_AUD_CONFIG_A;
|
||||
aud_cntl_st = IBX_AUD_CNTL_ST_A;
|
||||
hdmiw_hdmiedid = IBX_HDMIW_HDMIEDID(pipe);
|
||||
aud_config = IBX_AUD_CFG(pipe);
|
||||
aud_cntl_st = IBX_AUD_CNTL_ST(pipe);
|
||||
aud_cntrl_st2 = IBX_AUD_CNTL_ST2;
|
||||
} else {
|
||||
hdmiw_hdmiedid = CPT_HDMIW_HDMIEDID_A;
|
||||
aud_config = CPT_AUD_CONFIG_A;
|
||||
aud_cntl_st = CPT_AUD_CNTL_ST_A;
|
||||
hdmiw_hdmiedid = CPT_HDMIW_HDMIEDID(pipe);
|
||||
aud_config = CPT_AUD_CFG(pipe);
|
||||
aud_cntl_st = CPT_AUD_CNTL_ST(pipe);
|
||||
aud_cntrl_st2 = CPT_AUD_CNTRL_ST2;
|
||||
}
|
||||
|
||||
i = to_intel_crtc(crtc)->pipe;
|
||||
hdmiw_hdmiedid += i * 0x100;
|
||||
aud_cntl_st += i * 0x100;
|
||||
aud_config += i * 0x100;
|
||||
|
||||
DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(i));
|
||||
DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(pipe));
|
||||
|
||||
i = I915_READ(aud_cntl_st);
|
||||
i = (i >> 29) & 0x3; /* DIP_Port_Select, 0x1 = PortB */
|
||||
i = (i >> 29) & DIP_PORT_SEL_MASK; /* DIP_Port_Select, 0x1 = PortB */
|
||||
if (!i) {
|
||||
DRM_DEBUG_DRIVER("Audio directed to unknown port\n");
|
||||
/* operate blindly on all ports */
|
||||
|
@ -5584,12 +5681,13 @@ mode_fits_in_fbdev(struct drm_device *dev,
|
|||
return fb;
|
||||
}
|
||||
|
||||
bool intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
|
||||
struct drm_connector *connector,
|
||||
bool intel_get_load_detect_pipe(struct drm_connector *connector,
|
||||
struct drm_display_mode *mode,
|
||||
struct intel_load_detect_pipe *old)
|
||||
{
|
||||
struct intel_crtc *intel_crtc;
|
||||
struct intel_encoder *intel_encoder =
|
||||
intel_attached_encoder(connector);
|
||||
struct drm_crtc *possible_crtc;
|
||||
struct drm_encoder *encoder = &intel_encoder->base;
|
||||
struct drm_crtc *crtc = NULL;
|
||||
|
@ -5615,21 +5713,12 @@ bool intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
|
|||
if (encoder->crtc) {
|
||||
crtc = encoder->crtc;
|
||||
|
||||
intel_crtc = to_intel_crtc(crtc);
|
||||
old->dpms_mode = intel_crtc->dpms_mode;
|
||||
old->dpms_mode = connector->dpms;
|
||||
old->load_detect_temp = false;
|
||||
|
||||
/* Make sure the crtc and connector are running */
|
||||
if (intel_crtc->dpms_mode != DRM_MODE_DPMS_ON) {
|
||||
struct drm_encoder_helper_funcs *encoder_funcs;
|
||||
struct drm_crtc_helper_funcs *crtc_funcs;
|
||||
|
||||
crtc_funcs = crtc->helper_private;
|
||||
crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
|
||||
|
||||
encoder_funcs = encoder->helper_private;
|
||||
encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
|
||||
}
|
||||
if (connector->dpms != DRM_MODE_DPMS_ON)
|
||||
connector->funcs->dpms(connector, DRM_MODE_DPMS_ON);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -5657,7 +5746,7 @@ bool intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
|
|||
connector->encoder = encoder;
|
||||
|
||||
intel_crtc = to_intel_crtc(crtc);
|
||||
old->dpms_mode = intel_crtc->dpms_mode;
|
||||
old->dpms_mode = connector->dpms;
|
||||
old->load_detect_temp = true;
|
||||
old->release_fb = NULL;
|
||||
|
||||
|
@ -5682,33 +5771,34 @@ bool intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
|
|||
DRM_DEBUG_KMS("reusing fbdev for load-detection framebuffer\n");
|
||||
if (IS_ERR(crtc->fb)) {
|
||||
DRM_DEBUG_KMS("failed to allocate framebuffer for load-detection\n");
|
||||
crtc->fb = old_fb;
|
||||
return false;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!drm_crtc_helper_set_mode(crtc, mode, 0, 0, old_fb)) {
|
||||
DRM_DEBUG_KMS("failed to set mode on load-detect pipe\n");
|
||||
if (old->release_fb)
|
||||
old->release_fb->funcs->destroy(old->release_fb);
|
||||
crtc->fb = old_fb;
|
||||
return false;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* let the connector get through one full cycle before testing */
|
||||
intel_wait_for_vblank(dev, intel_crtc->pipe);
|
||||
|
||||
return true;
|
||||
fail:
|
||||
connector->encoder = NULL;
|
||||
encoder->crtc = NULL;
|
||||
crtc->fb = old_fb;
|
||||
return false;
|
||||
}
|
||||
|
||||
void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder,
|
||||
struct drm_connector *connector,
|
||||
void intel_release_load_detect_pipe(struct drm_connector *connector,
|
||||
struct intel_load_detect_pipe *old)
|
||||
{
|
||||
struct intel_encoder *intel_encoder =
|
||||
intel_attached_encoder(connector);
|
||||
struct drm_encoder *encoder = &intel_encoder->base;
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_crtc *crtc = encoder->crtc;
|
||||
struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
|
||||
struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
|
||||
|
||||
DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
|
||||
connector->base.id, drm_get_connector_name(connector),
|
||||
|
@ -5716,6 +5806,7 @@ void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder,
|
|||
|
||||
if (old->load_detect_temp) {
|
||||
connector->encoder = NULL;
|
||||
encoder->crtc = NULL;
|
||||
drm_helper_disable_unused_functions(dev);
|
||||
|
||||
if (old->release_fb)
|
||||
|
@ -5725,10 +5816,8 @@ void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder,
|
|||
}
|
||||
|
||||
/* Switch crtc and encoder back off if necessary */
|
||||
if (old->dpms_mode != DRM_MODE_DPMS_ON) {
|
||||
encoder_funcs->dpms(encoder, old->dpms_mode);
|
||||
crtc_funcs->dpms(crtc, old->dpms_mode);
|
||||
}
|
||||
if (old->dpms_mode != DRM_MODE_DPMS_ON)
|
||||
connector->funcs->dpms(connector, old->dpms_mode);
|
||||
}
|
||||
|
||||
/* Returns the clock of the currently programmed mode of the given pipe. */
|
||||
|
@ -6939,7 +7028,7 @@ static void intel_init_display(struct drm_device *dev)
|
|||
dev_priv->display.write_eld = ironlake_write_eld;
|
||||
} else if (IS_HASWELL(dev)) {
|
||||
dev_priv->display.fdi_link_train = hsw_fdi_link_train;
|
||||
dev_priv->display.write_eld = ironlake_write_eld;
|
||||
dev_priv->display.write_eld = haswell_write_eld;
|
||||
} else
|
||||
dev_priv->display.update_wm = NULL;
|
||||
} else if (IS_G4X(dev)) {
|
||||
|
@ -7017,21 +7106,16 @@ static struct intel_quirk intel_quirks[] = {
|
|||
/* HP Mini needs pipe A force quirk (LP: #322104) */
|
||||
{ 0x27ae, 0x103c, 0x361a, quirk_pipea_force },
|
||||
|
||||
/* Thinkpad R31 needs pipe A force quirk */
|
||||
{ 0x3577, 0x1014, 0x0505, quirk_pipea_force },
|
||||
/* Toshiba Protege R-205, S-209 needs pipe A force quirk */
|
||||
{ 0x2592, 0x1179, 0x0001, quirk_pipea_force },
|
||||
|
||||
/* ThinkPad X30 needs pipe A force quirk (LP: #304614) */
|
||||
{ 0x3577, 0x1014, 0x0513, quirk_pipea_force },
|
||||
/* ThinkPad X40 needs pipe A force quirk */
|
||||
|
||||
/* 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 },
|
||||
{ 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force },
|
||||
|
||||
/* Lenovo U160 cannot use SSC on LVDS */
|
||||
{ 0x0046, 0x17aa, 0x3920, quirk_ssc_force_disable },
|
||||
|
@ -7242,7 +7326,7 @@ struct intel_display_error_state {
|
|||
u32 position;
|
||||
u32 base;
|
||||
u32 size;
|
||||
} cursor[2];
|
||||
} cursor[I915_MAX_PIPES];
|
||||
|
||||
struct intel_pipe_error_state {
|
||||
u32 conf;
|
||||
|
@ -7254,7 +7338,7 @@ struct intel_display_error_state {
|
|||
u32 vtotal;
|
||||
u32 vblank;
|
||||
u32 vsync;
|
||||
} pipe[2];
|
||||
} pipe[I915_MAX_PIPES];
|
||||
|
||||
struct intel_plane_error_state {
|
||||
u32 control;
|
||||
|
@ -7264,7 +7348,7 @@ struct intel_display_error_state {
|
|||
u32 addr;
|
||||
u32 surface;
|
||||
u32 tile_offset;
|
||||
} plane[2];
|
||||
} plane[I915_MAX_PIPES];
|
||||
};
|
||||
|
||||
struct intel_display_error_state *
|
||||
|
@ -7278,7 +7362,7 @@ intel_display_capture_error_state(struct drm_device *dev)
|
|||
if (error == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
for_each_pipe(i) {
|
||||
error->cursor[i].control = I915_READ(CURCNTR(i));
|
||||
error->cursor[i].position = I915_READ(CURPOS(i));
|
||||
error->cursor[i].base = I915_READ(CURBASE(i));
|
||||
|
@ -7311,9 +7395,11 @@ intel_display_print_error_state(struct seq_file *m,
|
|||
struct drm_device *dev,
|
||||
struct intel_display_error_state *error)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
seq_printf(m, "Num Pipes: %d\n", dev_priv->num_pipe);
|
||||
for_each_pipe(i) {
|
||||
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);
|
||||
|
|
|
@ -850,10 +850,8 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
|
|||
* supposed to be read-only.
|
||||
*/
|
||||
intel_dp->DP = I915_READ(intel_dp->output_reg) & DP_DETECTED;
|
||||
intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
|
||||
|
||||
/* Handle DP bits in common between all three register formats */
|
||||
|
||||
intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
|
||||
|
||||
switch (intel_dp->lane_count) {
|
||||
|
|
|
@ -435,12 +435,10 @@ struct intel_load_detect_pipe {
|
|||
bool load_detect_temp;
|
||||
int dpms_mode;
|
||||
};
|
||||
extern bool intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
|
||||
struct drm_connector *connector,
|
||||
extern bool intel_get_load_detect_pipe(struct drm_connector *connector,
|
||||
struct drm_display_mode *mode,
|
||||
struct intel_load_detect_pipe *old);
|
||||
extern void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder,
|
||||
struct drm_connector *connector,
|
||||
extern void intel_release_load_detect_pipe(struct drm_connector *connector,
|
||||
struct intel_load_detect_pipe *old);
|
||||
|
||||
extern void intelfb_restore(void);
|
||||
|
|
|
@ -115,9 +115,9 @@ static void intel_dvo_dpms(struct drm_encoder *encoder, int mode)
|
|||
if (mode == DRM_MODE_DPMS_ON) {
|
||||
I915_WRITE(dvo_reg, temp | DVO_ENABLE);
|
||||
I915_READ(dvo_reg);
|
||||
intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, mode);
|
||||
intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true);
|
||||
} else {
|
||||
intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, mode);
|
||||
intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, false);
|
||||
I915_WRITE(dvo_reg, temp & ~DVO_ENABLE);
|
||||
I915_READ(dvo_reg);
|
||||
}
|
||||
|
|
|
@ -235,54 +235,6 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Workaround for i830 bug where pipe a must be enable to change control regs */
|
||||
static int
|
||||
i830_activate_pipe_a(struct drm_device *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
struct intel_crtc *crtc;
|
||||
struct drm_crtc_helper_funcs *crtc_funcs;
|
||||
struct drm_display_mode vesa_640x480 = {
|
||||
DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
|
||||
752, 800, 0, 480, 489, 492, 525, 0,
|
||||
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)
|
||||
}, *mode;
|
||||
|
||||
crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[0]);
|
||||
if (crtc->dpms_mode == DRM_MODE_DPMS_ON)
|
||||
return 0;
|
||||
|
||||
/* most i8xx have pipe a forced on, so don't trust dpms mode */
|
||||
if (I915_READ(_PIPEACONF) & PIPECONF_ENABLE)
|
||||
return 0;
|
||||
|
||||
crtc_funcs = crtc->base.helper_private;
|
||||
if (crtc_funcs->dpms == NULL)
|
||||
return 0;
|
||||
|
||||
DRM_DEBUG_DRIVER("Enabling pipe A in order to enable overlay\n");
|
||||
|
||||
mode = drm_mode_duplicate(dev, &vesa_640x480);
|
||||
|
||||
if (!drm_crtc_helper_set_mode(&crtc->base, mode,
|
||||
crtc->base.x, crtc->base.y,
|
||||
crtc->base.fb))
|
||||
return 0;
|
||||
|
||||
crtc_funcs->dpms(&crtc->base, DRM_MODE_DPMS_ON);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
i830_deactivate_pipe_a(struct drm_device *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[0];
|
||||
struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
|
||||
|
||||
crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
|
||||
}
|
||||
|
||||
/* overlay needs to be disable in OCMD reg */
|
||||
static int intel_overlay_on(struct intel_overlay *overlay)
|
||||
{
|
||||
|
@ -290,17 +242,12 @@ static int intel_overlay_on(struct intel_overlay *overlay)
|
|||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
|
||||
struct drm_i915_gem_request *request;
|
||||
int pipe_a_quirk = 0;
|
||||
int ret;
|
||||
|
||||
BUG_ON(overlay->active);
|
||||
overlay->active = 1;
|
||||
|
||||
if (IS_I830(dev)) {
|
||||
pipe_a_quirk = i830_activate_pipe_a(dev);
|
||||
if (pipe_a_quirk < 0)
|
||||
return pipe_a_quirk;
|
||||
}
|
||||
WARN_ON(IS_I830(dev) && !(dev_priv->quirks & QUIRK_PIPEA_FORCE));
|
||||
|
||||
request = kzalloc(sizeof(*request), GFP_KERNEL);
|
||||
if (request == NULL) {
|
||||
|
@ -322,9 +269,6 @@ static int intel_overlay_on(struct intel_overlay *overlay)
|
|||
|
||||
ret = intel_overlay_do_wait_request(overlay, request, NULL);
|
||||
out:
|
||||
if (pipe_a_quirk)
|
||||
i830_deactivate_pipe_a(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1439,7 +1383,7 @@ void intel_setup_overlay(struct drm_device *dev)
|
|||
}
|
||||
overlay->flip_addr = reg_bo->phys_obj->handle->busaddr;
|
||||
} else {
|
||||
ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true);
|
||||
ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true, false);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to pin overlay register bo\n");
|
||||
goto out_free_bo;
|
||||
|
|
|
@ -2138,7 +2138,7 @@ intel_alloc_context_page(struct drm_device *dev)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
ret = i915_gem_object_pin(ctx, 4096, true);
|
||||
ret = i915_gem_object_pin(ctx, 4096, true, false);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to pin power context: %d\n", ret);
|
||||
goto err_unref;
|
||||
|
@ -2372,6 +2372,11 @@ int intel_enable_rc6(const struct drm_device *dev)
|
|||
return i915_enable_rc6;
|
||||
|
||||
if (INTEL_INFO(dev)->gen == 5) {
|
||||
#ifdef CONFIG_INTEL_IOMMU
|
||||
/* Disable rc6 on ilk if VT-d is on. */
|
||||
if (intel_iommu_gfx_mapped)
|
||||
return false;
|
||||
#endif
|
||||
DRM_DEBUG_DRIVER("Ironlake: only RC6 available\n");
|
||||
return INTEL_RC6_ENABLE;
|
||||
}
|
||||
|
|
|
@ -391,7 +391,7 @@ init_pipe_control(struct intel_ring_buffer *ring)
|
|||
|
||||
i915_gem_object_set_cache_level(obj, I915_CACHE_LLC);
|
||||
|
||||
ret = i915_gem_object_pin(obj, 4096, true);
|
||||
ret = i915_gem_object_pin(obj, 4096, true, false);
|
||||
if (ret)
|
||||
goto err_unref;
|
||||
|
||||
|
@ -979,7 +979,7 @@ static int init_status_page(struct intel_ring_buffer *ring)
|
|||
|
||||
i915_gem_object_set_cache_level(obj, I915_CACHE_LLC);
|
||||
|
||||
ret = i915_gem_object_pin(obj, 4096, true);
|
||||
ret = i915_gem_object_pin(obj, 4096, true, false);
|
||||
if (ret != 0) {
|
||||
goto err_unref;
|
||||
}
|
||||
|
@ -1036,7 +1036,7 @@ static int intel_init_ring_buffer(struct drm_device *dev,
|
|||
|
||||
ring->obj = obj;
|
||||
|
||||
ret = i915_gem_object_pin(obj, PAGE_SIZE, true);
|
||||
ret = i915_gem_object_pin(obj, PAGE_SIZE, true, false);
|
||||
if (ret)
|
||||
goto err_unref;
|
||||
|
||||
|
|
|
@ -1303,12 +1303,9 @@ intel_tv_detect(struct drm_connector *connector, bool force)
|
|||
if (force) {
|
||||
struct intel_load_detect_pipe tmp;
|
||||
|
||||
if (intel_get_load_detect_pipe(&intel_tv->base, connector,
|
||||
&mode, &tmp)) {
|
||||
if (intel_get_load_detect_pipe(connector, &mode, &tmp)) {
|
||||
type = intel_tv_detect_type(intel_tv, connector);
|
||||
intel_release_load_detect_pipe(&intel_tv->base,
|
||||
connector,
|
||||
&tmp);
|
||||
intel_release_load_detect_pipe(connector, &tmp);
|
||||
} else
|
||||
return connector_status_unknown;
|
||||
} else
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/dma-buf.h>
|
||||
|
||||
#include "drmP.h"
|
||||
#include "drm.h"
|
||||
|
@ -377,16 +378,33 @@ static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb,
|
|||
{
|
||||
struct udl_framebuffer *ufb = to_udl_fb(fb);
|
||||
int i;
|
||||
int ret = 0;
|
||||
|
||||
if (!ufb->active_16)
|
||||
return 0;
|
||||
|
||||
if (ufb->obj->base.import_attach) {
|
||||
ret = dma_buf_begin_cpu_access(ufb->obj->base.import_attach->dmabuf,
|
||||
0, ufb->obj->base.size,
|
||||
DMA_FROM_DEVICE);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_clips; i++) {
|
||||
udl_handle_damage(ufb, clips[i].x1, clips[i].y1,
|
||||
ret = udl_handle_damage(ufb, clips[i].x1, clips[i].y1,
|
||||
clips[i].x2 - clips[i].x1,
|
||||
clips[i].y2 - clips[i].y1);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
||||
if (ufb->obj->base.import_attach) {
|
||||
dma_buf_end_cpu_access(ufb->obj->base.import_attach->dmabuf,
|
||||
0, ufb->obj->base.size,
|
||||
DMA_FROM_DEVICE);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void udl_user_framebuffer_destroy(struct drm_framebuffer *fb)
|
||||
|
|
|
@ -181,11 +181,6 @@ int udl_gem_vmap(struct udl_gem_object *obj)
|
|||
int ret;
|
||||
|
||||
if (obj->base.import_attach) {
|
||||
ret = dma_buf_begin_cpu_access(obj->base.import_attach->dmabuf,
|
||||
0, obj->base.size, DMA_BIDIRECTIONAL);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
obj->vmapping = dma_buf_vmap(obj->base.import_attach->dmabuf);
|
||||
if (!obj->vmapping)
|
||||
return -ENOMEM;
|
||||
|
@ -206,8 +201,6 @@ void udl_gem_vunmap(struct udl_gem_object *obj)
|
|||
{
|
||||
if (obj->base.import_attach) {
|
||||
dma_buf_vunmap(obj->base.import_attach->dmabuf, obj->vmapping);
|
||||
dma_buf_end_cpu_access(obj->base.import_attach->dmabuf, 0,
|
||||
obj->base.size, DMA_BIDIRECTIONAL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -312,6 +312,7 @@ typedef struct drm_i915_irq_wait {
|
|||
#define I915_PARAM_HAS_ALIASING_PPGTT 18
|
||||
#define I915_PARAM_HAS_WAIT_TIMEOUT 19
|
||||
#define I915_PARAM_HAS_SEMAPHORES 20
|
||||
#define I915_PARAM_HAS_PRIME_VMAP_FLUSH 21
|
||||
|
||||
typedef struct drm_i915_getparam {
|
||||
int param;
|
||||
|
|
Загрузка…
Ссылка в новой задаче