Skip to content

Commit

Permalink
Merge branch 'drm-intel-fixes' of git://people.freedesktop.org/~keith…
Browse files Browse the repository at this point in the history
…p/linux into drm-fixes

* 'drm-intel-fixes' of git://people.freedesktop.org/~keithp/linux: (24 commits)
  drm/i915: fixup forcewake spinlock fallout in drpc debugfs function
  drm/i915: debugfs: show semaphore registers also on gen7
  drm/i915: allow userspace forcewake references also on gen7
  drm/i915: Re-enable gen7 RC6 and GPU turbo after resume.
  drm/i915: Correct debugfs printout for RC1e.
  Revert "drm/i915: Work around gen7 BLT ring synchronization issues."
  drm/i915: rip out the HWSTAM missed irq workaround
  drm/i915: paper over missed irq issues with force wake voodoo
  drm/i915: Hold gt_lock across forcewake register reads
  drm/i915: Hold gt_lock during reset
  drm/i915: Move reset forcewake processing to gen6_do_reset
  drm/i915: protect force_wake_(get|put) with the gt_lock
  drm/i915: convert force_wake_get to func pointer in the gpu reset code
  drm/i915: sprite init failure on pre-SNB is not a failure
  drm/i915: VBT Parser cleanup for eDP block
  drm/i915: mask transcoder select bits before setting them on LVDS
  drm/i915: Add Clientron E830 to the ignore LVDS list
  CHROMIUM: i915: Add DMI override to skip CRT initialization on ZGB
  drm/i915: handle 3rd pipe
  drm/i915: simplify pipe checking
  ...
  • Loading branch information
Dave Airlie committed Jan 26, 2012
2 parents 9f1feed + 93b525d commit c8fe74a
Show file tree
Hide file tree
Showing 14 changed files with 167 additions and 199 deletions.
31 changes: 20 additions & 11 deletions drivers/gpu/drm/i915/i915_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,11 @@ static const char *cache_level_str(int type)
static void
describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
{
seq_printf(m, "%p: %s%s %8zd %04x %04x %d %d%s%s%s",
seq_printf(m, "%p: %s%s %8zdKiB %04x %04x %d %d%s%s%s",
&obj->base,
get_pin_flag(obj),
get_tiling_flag(obj),
obj->base.size,
obj->base.size / 1024,
obj->base.read_domains,
obj->base.write_domain,
obj->last_rendering_seqno,
Expand Down Expand Up @@ -653,7 +653,7 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data)
seq_printf(m, " Size : %08x\n", ring->size);
seq_printf(m, " Active : %08x\n", intel_ring_get_active_head(ring));
seq_printf(m, " NOPID : %08x\n", I915_READ_NOPID(ring));
if (IS_GEN6(dev)) {
if (IS_GEN6(dev) || IS_GEN7(dev)) {
seq_printf(m, " Sync 0 : %08x\n", I915_READ_SYNC_0(ring));
seq_printf(m, " Sync 1 : %08x\n", I915_READ_SYNC_1(ring));
}
Expand Down Expand Up @@ -1075,16 +1075,21 @@ static int gen6_drpc_info(struct seq_file *m)
struct drm_device *dev = node->minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 rpmodectl1, gt_core_status, rcctl1;
unsigned forcewake_count;
int count=0, ret;


ret = mutex_lock_interruptible(&dev->struct_mutex);
if (ret)
return ret;

if (atomic_read(&dev_priv->forcewake_count)) {
seq_printf(m, "RC information inaccurate because userspace "
"holds a reference \n");
spin_lock_irq(&dev_priv->gt_lock);
forcewake_count = dev_priv->forcewake_count;
spin_unlock_irq(&dev_priv->gt_lock);

if (forcewake_count) {
seq_printf(m, "RC information inaccurate because somebody "
"holds a forcewake reference \n");
} else {
/* NB: we cannot use forcewake, else we read the wrong values */
while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1))
Expand All @@ -1106,7 +1111,7 @@ static int gen6_drpc_info(struct seq_file *m)
seq_printf(m, "SW control enabled: %s\n",
yesno((rpmodectl1 & GEN6_RP_MEDIA_MODE_MASK) ==
GEN6_RP_MEDIA_SW_MODE));
seq_printf(m, "RC6 Enabled: %s\n",
seq_printf(m, "RC1e Enabled: %s\n",
yesno(rcctl1 & GEN6_RC_CTL_RC1e_ENABLE));
seq_printf(m, "RC6 Enabled: %s\n",
yesno(rcctl1 & GEN6_RC_CTL_RC6_ENABLE));
Expand Down Expand Up @@ -1398,9 +1403,13 @@ static int i915_gen6_forcewake_count_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;
unsigned forcewake_count;

spin_lock_irq(&dev_priv->gt_lock);
forcewake_count = dev_priv->forcewake_count;
spin_unlock_irq(&dev_priv->gt_lock);

seq_printf(m, "forcewake count = %d\n",
atomic_read(&dev_priv->forcewake_count));
seq_printf(m, "forcewake count = %u\n", forcewake_count);

return 0;
}
Expand Down Expand Up @@ -1665,7 +1674,7 @@ static int i915_forcewake_open(struct inode *inode, struct file *file)
struct drm_i915_private *dev_priv = dev->dev_private;
int ret;

if (!IS_GEN6(dev))
if (INTEL_INFO(dev)->gen < 6)
return 0;

ret = mutex_lock_interruptible(&dev->struct_mutex);
Expand All @@ -1682,7 +1691,7 @@ int i915_forcewake_release(struct inode *inode, struct file *file)
struct drm_device *dev = inode->i_private;
struct drm_i915_private *dev_priv = dev->dev_private;

if (!IS_GEN6(dev))
if (INTEL_INFO(dev)->gen < 6)
return 0;

/*
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/i915_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -2045,6 +2045,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
if (!IS_I945G(dev) && !IS_I945GM(dev))
pci_enable_msi(dev->pdev);

spin_lock_init(&dev_priv->gt_lock);
spin_lock_init(&dev_priv->irq_lock);
spin_lock_init(&dev_priv->error_lock);
spin_lock_init(&dev_priv->rps_lock);
Expand Down
56 changes: 44 additions & 12 deletions drivers/gpu/drm/i915/i915_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,11 +368,12 @@ void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
*/
void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
{
WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
unsigned long irqflags;

/* Forcewake is atomic in case we get in here without the lock */
if (atomic_add_return(1, &dev_priv->forcewake_count) == 1)
spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
if (dev_priv->forcewake_count++ == 0)
dev_priv->display.force_wake_get(dev_priv);
spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
}

void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
Expand All @@ -392,10 +393,12 @@ void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv)
*/
void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
{
WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
unsigned long irqflags;

if (atomic_dec_and_test(&dev_priv->forcewake_count))
spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
if (--dev_priv->forcewake_count == 0)
dev_priv->display.force_wake_put(dev_priv);
spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
}

void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
Expand Down Expand Up @@ -597,9 +600,36 @@ static int ironlake_do_reset(struct drm_device *dev, u8 flags)
static int gen6_do_reset(struct drm_device *dev, u8 flags)
{
struct drm_i915_private *dev_priv = dev->dev_private;
int ret;
unsigned long irqflags;

I915_WRITE(GEN6_GDRST, GEN6_GRDOM_FULL);
return wait_for((I915_READ(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500);
/* Hold gt_lock across reset to prevent any register access
* with forcewake not set correctly
*/
spin_lock_irqsave(&dev_priv->gt_lock, irqflags);

/* Reset the chip */

/* GEN6_GDRST is not in the gt power well, no need to check
* for fifo space for the write or forcewake the chip for
* the read
*/
I915_WRITE_NOTRACE(GEN6_GDRST, GEN6_GRDOM_FULL);

/* Spin waiting for the device to ack the reset request */
ret = wait_for((I915_READ_NOTRACE(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500);

/* If reset with a user forcewake, try to restore, otherwise turn it off */
if (dev_priv->forcewake_count)
dev_priv->display.force_wake_get(dev_priv);
else
dev_priv->display.force_wake_put(dev_priv);

/* Restore fifo count */
dev_priv->gt_fifo_count = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);

spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
return ret;
}

/**
Expand Down Expand Up @@ -643,9 +673,6 @@ int i915_reset(struct drm_device *dev, u8 flags)
case 7:
case 6:
ret = gen6_do_reset(dev, flags);
/* If reset with a user forcewake, try to restore */
if (atomic_read(&dev_priv->forcewake_count))
__gen6_gt_force_wake_get(dev_priv);
break;
case 5:
ret = ironlake_do_reset(dev, flags);
Expand Down Expand Up @@ -927,9 +954,14 @@ MODULE_LICENSE("GPL and additional rights");
u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
u##x val = 0; \
if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
gen6_gt_force_wake_get(dev_priv); \
unsigned long irqflags; \
spin_lock_irqsave(&dev_priv->gt_lock, irqflags); \
if (dev_priv->forcewake_count == 0) \
dev_priv->display.force_wake_get(dev_priv); \
val = read##y(dev_priv->regs + reg); \
gen6_gt_force_wake_put(dev_priv); \
if (dev_priv->forcewake_count == 0) \
dev_priv->display.force_wake_put(dev_priv); \
spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \
} else { \
val = read##y(dev_priv->regs + reg); \
} \
Expand Down
10 changes: 7 additions & 3 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,13 @@ typedef struct drm_i915_private {
int relative_constants_mode;

void __iomem *regs;
u32 gt_fifo_count;
/** gt_fifo_count and the subsequent register write are synchronized
* with dev->struct_mutex. */
unsigned gt_fifo_count;
/** forcewake_count is protected by gt_lock */
unsigned forcewake_count;
/** gt_lock is also taken in irq contexts. */
struct spinlock gt_lock;

struct intel_gmbus {
struct i2c_adapter adapter;
Expand Down Expand Up @@ -741,8 +747,6 @@ typedef struct drm_i915_private {

struct drm_property *broadcast_rgb_property;
struct drm_property *force_audio_property;

atomic_t forcewake_count;
} drm_i915_private_t;

enum i915_cache_level {
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/i915/i915_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -1751,7 +1751,8 @@ static void ironlake_irq_preinstall(struct drm_device *dev)
INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work);

I915_WRITE(HWSTAM, 0xeffe);
if (IS_GEN6(dev) || IS_GEN7(dev)) {

if (IS_GEN6(dev)) {
/* Workaround stalls observed on Sandy Bridge GPUs by
* making the blitter command streamer generate a
* write to the Hardware Status Page for
Expand Down
11 changes: 8 additions & 3 deletions drivers/gpu/drm/i915/i915_suspend.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,19 @@
#include "drm.h"
#include "i915_drm.h"
#include "intel_drv.h"
#include "i915_reg.h"

static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 dpll_reg;

/* On IVB, 3rd pipe shares PLL with another one */
if (pipe > 1)
return false;

if (HAS_PCH_SPLIT(dev))
dpll_reg = (pipe == PIPE_A) ? _PCH_DPLL_A : _PCH_DPLL_B;
dpll_reg = PCH_DPLL(pipe);
else
dpll_reg = (pipe == PIPE_A) ? _DPLL_A : _DPLL_B;

Expand Down Expand Up @@ -822,7 +827,7 @@ int i915_save_state(struct drm_device *dev)

if (IS_IRONLAKE_M(dev))
ironlake_disable_drps(dev);
if (IS_GEN6(dev))
if (INTEL_INFO(dev)->gen >= 6)
gen6_disable_rps(dev);

/* Cache mode state */
Expand Down Expand Up @@ -881,7 +886,7 @@ int i915_restore_state(struct drm_device *dev)
intel_init_emon(dev);
}

if (IS_GEN6(dev)) {
if (INTEL_INFO(dev)->gen >= 6) {
gen6_enable_rps(dev_priv);
gen6_update_ring_freq(dev_priv);
}
Expand Down
6 changes: 5 additions & 1 deletion drivers/gpu/drm/i915/intel_bios.h
Original file line number Diff line number Diff line change
Expand Up @@ -467,8 +467,12 @@ struct edp_link_params {
struct bdb_edp {
struct edp_power_seq power_seqs[16];
u32 color_depth;
u32 sdrrs_msa_timing_delay;
struct edp_link_params link_params[16];
u32 sdrrs_msa_timing_delay;

/* ith bit indicates enabled/disabled for (i+1)th panel */
u16 edp_s3d_feature;
u16 edp_t3_optimization;
} __attribute__ ((packed));

void intel_setup_bios(struct drm_device *dev);
Expand Down
23 changes: 23 additions & 0 deletions drivers/gpu/drm/i915/intel_crt.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
* Eric Anholt <eric@anholt.net>
*/

#include <linux/dmi.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include "drmP.h"
Expand Down Expand Up @@ -540,13 +541,35 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = {
.destroy = intel_encoder_destroy,
};

static int __init intel_no_crt_dmi_callback(const struct dmi_system_id *id)
{
DRM_DEBUG_KMS("Skipping CRT initialization for %s\n", id->ident);
return 1;
}

static const struct dmi_system_id intel_no_crt[] = {
{
.callback = intel_no_crt_dmi_callback,
.ident = "ACER ZGB",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ACER"),
DMI_MATCH(DMI_PRODUCT_NAME, "ZGB"),
},
},
{ }
};

void intel_crt_init(struct drm_device *dev)
{
struct drm_connector *connector;
struct intel_crt *crt;
struct intel_connector *intel_connector;
struct drm_i915_private *dev_priv = dev->dev_private;

/* Skip machines without VGA that falsely report hotplug events */
if (dmi_check_system(intel_no_crt))
return;

crt = kzalloc(sizeof(struct intel_crt), GFP_KERNEL);
if (!crt)
return;
Expand Down
22 changes: 11 additions & 11 deletions drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -5808,12 +5808,15 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
if (is_lvds) {
temp = I915_READ(PCH_LVDS);
temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
if (HAS_PCH_CPT(dev))
if (HAS_PCH_CPT(dev)) {
temp &= ~PORT_TRANS_SEL_MASK;
temp |= PORT_TRANS_SEL_CPT(pipe);
else if (pipe == 1)
temp |= LVDS_PIPEB_SELECT;
else
temp &= ~LVDS_PIPEB_SELECT;
} else {
if (pipe == 1)
temp |= LVDS_PIPEB_SELECT;
else
temp &= ~LVDS_PIPEB_SELECT;
}

/* set the corresponsding LVDS_BORDER bit */
temp |= dev_priv->lvds_border_bits;
Expand Down Expand Up @@ -9025,12 +9028,9 @@ void intel_modeset_init(struct drm_device *dev)

for (i = 0; i < dev_priv->num_pipe; i++) {
intel_crtc_init(dev, i);
if (HAS_PCH_SPLIT(dev)) {
ret = intel_plane_init(dev, i);
if (ret)
DRM_ERROR("plane %d init failed: %d\n",
i, ret);
}
ret = intel_plane_init(dev, i);
if (ret)
DRM_DEBUG_KMS("plane %d init failed: %d\n", i, ret);
}

/* Just disable it once at startup */
Expand Down
8 changes: 8 additions & 0 deletions drivers/gpu/drm/i915/intel_lvds.c
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
},
},
{
.callback = intel_no_lvds_dmi_callback,
.ident = "Clientron E830",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Clientron"),
DMI_MATCH(DMI_PRODUCT_NAME, "E830"),
},
},
{
.callback = intel_no_lvds_dmi_callback,
.ident = "Asus EeeBox PC EB1007",
.matches = {
Expand Down
Loading

0 comments on commit c8fe74a

Please sign in to comment.