Commit 5df5242d authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-intel-fixes-2014-04-11' of git://anongit.freedesktop.org/drm-intel into drm-next

Some fixes from Intel.

* tag 'drm-intel-fixes-2014-04-11' of git://anongit.freedesktop.org/drm-intel:
  drm/i915: Always use kref tracking for all contexts.
  drm/i915: do not setup backlight if not available according to VBT
  drm/i915: check VBT for supported backlight type
  drm/i915: Disable self-refresh for untiled fbs on i915gm
  drm/mm: Don't WARN if drm_mm_reserve_node
parents 55101e2d 691e6415
...@@ -207,8 +207,6 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node) ...@@ -207,8 +207,6 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node)
return 0; return 0;
} }
WARN(1, "no hole found for node 0x%lx + 0x%lx\n",
node->start, node->size);
return -ENOSPC; return -ENOSPC;
} }
EXPORT_SYMBOL(drm_mm_reserve_node); EXPORT_SYMBOL(drm_mm_reserve_node);
......
...@@ -1308,6 +1308,7 @@ struct intel_vbt_data { ...@@ -1308,6 +1308,7 @@ struct intel_vbt_data {
struct { struct {
u16 pwm_freq_hz; u16 pwm_freq_hz;
bool present;
bool active_low_pwm; bool active_low_pwm;
} backlight; } backlight;
...@@ -2431,19 +2432,17 @@ int i915_gem_context_open(struct drm_device *dev, struct drm_file *file); ...@@ -2431,19 +2432,17 @@ int i915_gem_context_open(struct drm_device *dev, struct drm_file *file);
int i915_gem_context_enable(struct drm_i915_private *dev_priv); int i915_gem_context_enable(struct drm_i915_private *dev_priv);
void i915_gem_context_close(struct drm_device *dev, struct drm_file *file); void i915_gem_context_close(struct drm_device *dev, struct drm_file *file);
int i915_switch_context(struct intel_ring_buffer *ring, int i915_switch_context(struct intel_ring_buffer *ring,
struct drm_file *file, struct i915_hw_context *to); struct i915_hw_context *to);
struct i915_hw_context * struct i915_hw_context *
i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id); i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id);
void i915_gem_context_free(struct kref *ctx_ref); void i915_gem_context_free(struct kref *ctx_ref);
static inline void i915_gem_context_reference(struct i915_hw_context *ctx) static inline void i915_gem_context_reference(struct i915_hw_context *ctx)
{ {
if (ctx->obj && HAS_HW_CONTEXTS(ctx->obj->base.dev))
kref_get(&ctx->ref); kref_get(&ctx->ref);
} }
static inline void i915_gem_context_unreference(struct i915_hw_context *ctx) static inline void i915_gem_context_unreference(struct i915_hw_context *ctx)
{ {
if (ctx->obj && HAS_HW_CONTEXTS(ctx->obj->base.dev))
kref_put(&ctx->ref, i915_gem_context_free); kref_put(&ctx->ref, i915_gem_context_free);
} }
......
...@@ -2790,7 +2790,7 @@ int i915_gpu_idle(struct drm_device *dev) ...@@ -2790,7 +2790,7 @@ int i915_gpu_idle(struct drm_device *dev)
/* Flush everything onto the inactive list. */ /* Flush everything onto the inactive list. */
for_each_ring(ring, dev_priv, i) { for_each_ring(ring, dev_priv, i) {
ret = i915_switch_context(ring, NULL, ring->default_context); ret = i915_switch_context(ring, ring->default_context);
if (ret) if (ret)
return ret; return ret;
......
...@@ -96,9 +96,6 @@ ...@@ -96,9 +96,6 @@
#define GEN6_CONTEXT_ALIGN (64<<10) #define GEN6_CONTEXT_ALIGN (64<<10)
#define GEN7_CONTEXT_ALIGN 4096 #define GEN7_CONTEXT_ALIGN 4096
static int do_switch(struct intel_ring_buffer *ring,
struct i915_hw_context *to);
static void do_ppgtt_cleanup(struct i915_hw_ppgtt *ppgtt) static void do_ppgtt_cleanup(struct i915_hw_ppgtt *ppgtt)
{ {
struct drm_device *dev = ppgtt->base.dev; struct drm_device *dev = ppgtt->base.dev;
...@@ -185,6 +182,7 @@ void i915_gem_context_free(struct kref *ctx_ref) ...@@ -185,6 +182,7 @@ void i915_gem_context_free(struct kref *ctx_ref)
typeof(*ctx), ref); typeof(*ctx), ref);
struct i915_hw_ppgtt *ppgtt = NULL; struct i915_hw_ppgtt *ppgtt = NULL;
if (ctx->obj) {
/* We refcount even the aliasing PPGTT to keep the code symmetric */ /* We refcount even the aliasing PPGTT to keep the code symmetric */
if (USES_PPGTT(ctx->obj->base.dev)) if (USES_PPGTT(ctx->obj->base.dev))
ppgtt = ctx_to_ppgtt(ctx); ppgtt = ctx_to_ppgtt(ctx);
...@@ -192,6 +190,7 @@ void i915_gem_context_free(struct kref *ctx_ref) ...@@ -192,6 +190,7 @@ void i915_gem_context_free(struct kref *ctx_ref)
/* XXX: Free up the object before tearing down the address space, in /* XXX: Free up the object before tearing down the address space, in
* case we're bound in the PPGTT */ * case we're bound in the PPGTT */
drm_gem_object_unreference(&ctx->obj->base); drm_gem_object_unreference(&ctx->obj->base);
}
if (ppgtt) if (ppgtt)
kref_put(&ppgtt->ref, ppgtt_release); kref_put(&ppgtt->ref, ppgtt_release);
...@@ -232,12 +231,13 @@ __create_hw_context(struct drm_device *dev, ...@@ -232,12 +231,13 @@ __create_hw_context(struct drm_device *dev,
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
kref_init(&ctx->ref); kref_init(&ctx->ref);
list_add_tail(&ctx->link, &dev_priv->context_list);
if (dev_priv->hw_context_size) {
ctx->obj = i915_gem_alloc_object(dev, dev_priv->hw_context_size); ctx->obj = i915_gem_alloc_object(dev, dev_priv->hw_context_size);
INIT_LIST_HEAD(&ctx->link);
if (ctx->obj == NULL) { if (ctx->obj == NULL) {
kfree(ctx); ret = -ENOMEM;
DRM_DEBUG_DRIVER("Context object allocated failed\n"); goto err_out;
return ERR_PTR(-ENOMEM);
} }
if (INTEL_INFO(dev)->gen >= 7) { if (INTEL_INFO(dev)->gen >= 7) {
...@@ -247,17 +247,16 @@ __create_hw_context(struct drm_device *dev, ...@@ -247,17 +247,16 @@ __create_hw_context(struct drm_device *dev,
if (WARN_ON(ret)) if (WARN_ON(ret))
goto err_out; goto err_out;
} }
}
list_add_tail(&ctx->link, &dev_priv->context_list);
/* Default context will never have a file_priv */ /* Default context will never have a file_priv */
if (file_priv == NULL) if (file_priv != NULL) {
return ctx; ret = idr_alloc(&file_priv->context_idr, ctx,
DEFAULT_CONTEXT_ID, 0, GFP_KERNEL);
ret = idr_alloc(&file_priv->context_idr, ctx, DEFAULT_CONTEXT_ID, 0,
GFP_KERNEL);
if (ret < 0) if (ret < 0)
goto err_out; goto err_out;
} else
ret = DEFAULT_CONTEXT_ID;
ctx->file_priv = file_priv; ctx->file_priv = file_priv;
ctx->id = ret; ctx->id = ret;
...@@ -294,7 +293,7 @@ i915_gem_create_context(struct drm_device *dev, ...@@ -294,7 +293,7 @@ i915_gem_create_context(struct drm_device *dev,
if (IS_ERR(ctx)) if (IS_ERR(ctx))
return ctx; return ctx;
if (is_global_default_ctx) { if (is_global_default_ctx && ctx->obj) {
/* We may need to do things with the shrinker which /* We may need to do things with the shrinker which
* require us to immediately switch back to the default * require us to immediately switch back to the default
* context. This can cause a problem as pinning the * context. This can cause a problem as pinning the
...@@ -342,7 +341,7 @@ i915_gem_create_context(struct drm_device *dev, ...@@ -342,7 +341,7 @@ i915_gem_create_context(struct drm_device *dev,
return ctx; return ctx;
err_unpin: err_unpin:
if (is_global_default_ctx) if (is_global_default_ctx && ctx->obj)
i915_gem_object_ggtt_unpin(ctx->obj); i915_gem_object_ggtt_unpin(ctx->obj);
err_destroy: err_destroy:
i915_gem_context_unreference(ctx); i915_gem_context_unreference(ctx);
...@@ -352,32 +351,22 @@ i915_gem_create_context(struct drm_device *dev, ...@@ -352,32 +351,22 @@ i915_gem_create_context(struct drm_device *dev,
void i915_gem_context_reset(struct drm_device *dev) void i915_gem_context_reset(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring;
int i; int i;
if (!HAS_HW_CONTEXTS(dev))
return;
/* Prevent the hardware from restoring the last context (which hung) on /* Prevent the hardware from restoring the last context (which hung) on
* the next switch */ * the next switch */
for (i = 0; i < I915_NUM_RINGS; i++) { for (i = 0; i < I915_NUM_RINGS; i++) {
struct i915_hw_context *dctx; struct intel_ring_buffer *ring = &dev_priv->ring[i];
if (!(INTEL_INFO(dev)->ring_mask & (1<<i))) struct i915_hw_context *dctx = ring->default_context;
continue;
/* Do a fake switch to the default context */ /* Do a fake switch to the default context */
ring = &dev_priv->ring[i]; if (ring->last_context == dctx)
dctx = ring->default_context;
if (WARN_ON(!dctx))
continue; continue;
if (!ring->last_context) if (!ring->last_context)
continue; continue;
if (ring->last_context == dctx) if (dctx->obj && i == RCS) {
continue;
if (i == RCS) {
WARN_ON(i915_gem_obj_ggtt_pin(dctx->obj, WARN_ON(i915_gem_obj_ggtt_pin(dctx->obj,
get_context_alignment(dev), 0)); get_context_alignment(dev), 0));
/* Fake a finish/inactive */ /* Fake a finish/inactive */
...@@ -394,44 +383,35 @@ void i915_gem_context_reset(struct drm_device *dev) ...@@ -394,44 +383,35 @@ void i915_gem_context_reset(struct drm_device *dev)
int i915_gem_context_init(struct drm_device *dev) int i915_gem_context_init(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring; struct i915_hw_context *ctx;
int i; int i;
if (!HAS_HW_CONTEXTS(dev))
return 0;
/* Init should only be called once per module load. Eventually the /* Init should only be called once per module load. Eventually the
* restriction on the context_disabled check can be loosened. */ * restriction on the context_disabled check can be loosened. */
if (WARN_ON(dev_priv->ring[RCS].default_context)) if (WARN_ON(dev_priv->ring[RCS].default_context))
return 0; return 0;
if (HAS_HW_CONTEXTS(dev)) {
dev_priv->hw_context_size = round_up(get_context_size(dev), 4096); dev_priv->hw_context_size = round_up(get_context_size(dev), 4096);
if (dev_priv->hw_context_size > (1<<20)) { if (dev_priv->hw_context_size > (1<<20)) {
DRM_DEBUG_DRIVER("Disabling HW Contexts; invalid size\n"); DRM_DEBUG_DRIVER("Disabling HW Contexts; invalid size %d\n",
return -E2BIG; dev_priv->hw_context_size);
dev_priv->hw_context_size = 0;
} }
dev_priv->ring[RCS].default_context =
i915_gem_create_context(dev, NULL, USES_PPGTT(dev));
if (IS_ERR_OR_NULL(dev_priv->ring[RCS].default_context)) {
DRM_DEBUG_DRIVER("Disabling HW Contexts; create failed %ld\n",
PTR_ERR(dev_priv->ring[RCS].default_context));
return PTR_ERR(dev_priv->ring[RCS].default_context);
} }
for (i = RCS + 1; i < I915_NUM_RINGS; i++) { ctx = i915_gem_create_context(dev, NULL, USES_PPGTT(dev));
if (!(INTEL_INFO(dev)->ring_mask & (1<<i))) if (IS_ERR(ctx)) {
continue; DRM_ERROR("Failed to create default global context (error %ld)\n",
PTR_ERR(ctx));
ring = &dev_priv->ring[i]; return PTR_ERR(ctx);
}
/* NB: RCS will hold a ref for all rings */ /* NB: RCS will hold a ref for all rings */
ring->default_context = dev_priv->ring[RCS].default_context; for (i = 0; i < I915_NUM_RINGS; i++)
} dev_priv->ring[i].default_context = ctx;
DRM_DEBUG_DRIVER("HW context support initialized\n"); DRM_DEBUG_DRIVER("%s context support initialized\n", dev_priv->hw_context_size ? "HW" : "fake");
return 0; return 0;
} }
...@@ -441,9 +421,7 @@ void i915_gem_context_fini(struct drm_device *dev) ...@@ -441,9 +421,7 @@ void i915_gem_context_fini(struct drm_device *dev)
struct i915_hw_context *dctx = dev_priv->ring[RCS].default_context; struct i915_hw_context *dctx = dev_priv->ring[RCS].default_context;
int i; int i;
if (!HAS_HW_CONTEXTS(dev)) if (dctx->obj) {
return;
/* The only known way to stop the gpu from accessing the hw context is /* The only known way to stop the gpu from accessing the hw context is
* to reset it. Do this as the very last operation to avoid confusing * to reset it. Do this as the very last operation to avoid confusing
* other code, leading to spurious errors. */ * other code, leading to spurious errors. */
...@@ -463,11 +441,10 @@ void i915_gem_context_fini(struct drm_device *dev) ...@@ -463,11 +441,10 @@ void i915_gem_context_fini(struct drm_device *dev)
i915_gem_context_unreference(dctx); i915_gem_context_unreference(dctx);
dev_priv->ring[RCS].last_context = NULL; dev_priv->ring[RCS].last_context = NULL;
} }
}
for (i = 0; i < I915_NUM_RINGS; i++) { for (i = 0; i < I915_NUM_RINGS; i++) {
struct intel_ring_buffer *ring = &dev_priv->ring[i]; struct intel_ring_buffer *ring = &dev_priv->ring[i];
if (!(INTEL_INFO(dev)->ring_mask & (1<<i)))
continue;
if (ring->last_context) if (ring->last_context)
i915_gem_context_unreference(ring->last_context); i915_gem_context_unreference(ring->last_context);
...@@ -478,7 +455,6 @@ void i915_gem_context_fini(struct drm_device *dev) ...@@ -478,7 +455,6 @@ void i915_gem_context_fini(struct drm_device *dev)
i915_gem_object_ggtt_unpin(dctx->obj); i915_gem_object_ggtt_unpin(dctx->obj);
i915_gem_context_unreference(dctx); i915_gem_context_unreference(dctx);
dev_priv->mm.aliasing_ppgtt = NULL;
} }
int i915_gem_context_enable(struct drm_i915_private *dev_priv) int i915_gem_context_enable(struct drm_i915_private *dev_priv)
...@@ -486,9 +462,6 @@ int i915_gem_context_enable(struct drm_i915_private *dev_priv) ...@@ -486,9 +462,6 @@ int i915_gem_context_enable(struct drm_i915_private *dev_priv)
struct intel_ring_buffer *ring; struct intel_ring_buffer *ring;
int ret, i; int ret, i;
if (!HAS_HW_CONTEXTS(dev_priv->dev))
return 0;
/* This is the only place the aliasing PPGTT gets enabled, which means /* This is the only place the aliasing PPGTT gets enabled, which means
* it has to happen before we bail on reset */ * it has to happen before we bail on reset */
if (dev_priv->mm.aliasing_ppgtt) { if (dev_priv->mm.aliasing_ppgtt) {
...@@ -503,7 +476,7 @@ int i915_gem_context_enable(struct drm_i915_private *dev_priv) ...@@ -503,7 +476,7 @@ int i915_gem_context_enable(struct drm_i915_private *dev_priv)
BUG_ON(!dev_priv->ring[RCS].default_context); BUG_ON(!dev_priv->ring[RCS].default_context);
for_each_ring(ring, dev_priv, i) { for_each_ring(ring, dev_priv, i) {
ret = do_switch(ring, ring->default_context); ret = i915_switch_context(ring, ring->default_context);
if (ret) if (ret)
return ret; return ret;
} }
...@@ -526,19 +499,6 @@ static int context_idr_cleanup(int id, void *p, void *data) ...@@ -526,19 +499,6 @@ static int context_idr_cleanup(int id, void *p, void *data)
int i915_gem_context_open(struct drm_device *dev, struct drm_file *file) int i915_gem_context_open(struct drm_device *dev, struct drm_file *file)
{ {
struct drm_i915_file_private *file_priv = file->driver_priv; struct drm_i915_file_private *file_priv = file->driver_priv;
struct drm_i915_private *dev_priv = dev->dev_private;
if (!HAS_HW_CONTEXTS(dev)) {
/* Cheat for hang stats */
file_priv->private_default_ctx =
kzalloc(sizeof(struct i915_hw_context), GFP_KERNEL);
if (file_priv->private_default_ctx == NULL)
return -ENOMEM;
file_priv->private_default_ctx->vm = &dev_priv->gtt.base;
return 0;
}
idr_init(&file_priv->context_idr); idr_init(&file_priv->context_idr);
...@@ -559,14 +519,10 @@ void i915_gem_context_close(struct drm_device *dev, struct drm_file *file) ...@@ -559,14 +519,10 @@ void i915_gem_context_close(struct drm_device *dev, struct drm_file *file)
{ {
struct drm_i915_file_private *file_priv = file->driver_priv; struct drm_i915_file_private *file_priv = file->driver_priv;
if (!HAS_HW_CONTEXTS(dev)) {
kfree(file_priv->private_default_ctx);
return;
}
idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL); idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL);
i915_gem_context_unreference(file_priv->private_default_ctx);
idr_destroy(&file_priv->context_idr); idr_destroy(&file_priv->context_idr);
i915_gem_context_unreference(file_priv->private_default_ctx);
} }
struct i915_hw_context * struct i915_hw_context *
...@@ -574,9 +530,6 @@ i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id) ...@@ -574,9 +530,6 @@ i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id)
{ {
struct i915_hw_context *ctx; struct i915_hw_context *ctx;
if (!HAS_HW_CONTEXTS(file_priv->dev_priv->dev))
return file_priv->private_default_ctx;
ctx = (struct i915_hw_context *)idr_find(&file_priv->context_idr, id); ctx = (struct i915_hw_context *)idr_find(&file_priv->context_idr, id);
if (!ctx) if (!ctx)
return ERR_PTR(-ENOENT); return ERR_PTR(-ENOENT);
...@@ -758,7 +711,6 @@ static int do_switch(struct intel_ring_buffer *ring, ...@@ -758,7 +711,6 @@ static int do_switch(struct intel_ring_buffer *ring,
/** /**
* i915_switch_context() - perform a GPU context switch. * i915_switch_context() - perform a GPU context switch.
* @ring: ring for which we'll execute the context switch * @ring: ring for which we'll execute the context switch
* @file_priv: file_priv associated with the context, may be NULL
* @to: the context to switch to * @to: the context to switch to
* *
* The context life cycle is simple. The context refcount is incremented and * The context life cycle is simple. The context refcount is incremented and
...@@ -767,24 +719,30 @@ static int do_switch(struct intel_ring_buffer *ring, ...@@ -767,24 +719,30 @@ static int do_switch(struct intel_ring_buffer *ring,
* object while letting the normal object tracking destroy the backing BO. * object while letting the normal object tracking destroy the backing BO.
*/ */
int i915_switch_context(struct intel_ring_buffer *ring, int i915_switch_context(struct intel_ring_buffer *ring,
struct drm_file *file,
struct i915_hw_context *to) struct i915_hw_context *to)
{ {
struct drm_i915_private *dev_priv = ring->dev->dev_private; struct drm_i915_private *dev_priv = ring->dev->dev_private;
WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
BUG_ON(file && to == NULL); if (to->obj == NULL) { /* We have the fake context */
if (to != ring->last_context) {
/* We have the fake context */ i915_gem_context_reference(to);
if (!HAS_HW_CONTEXTS(ring->dev)) { if (ring->last_context)
i915_gem_context_unreference(ring->last_context);
ring->last_context = to; ring->last_context = to;
}
return 0; return 0;
} }
return do_switch(ring, to); return do_switch(ring, to);
} }
static bool hw_context_enabled(struct drm_device *dev)
{
return to_i915(dev)->hw_context_size;
}
int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
struct drm_file *file) struct drm_file *file)
{ {
...@@ -793,7 +751,7 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, ...@@ -793,7 +751,7 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
struct i915_hw_context *ctx; struct i915_hw_context *ctx;
int ret; int ret;
if (!HAS_HW_CONTEXTS(dev)) if (!hw_context_enabled(dev))
return -ENODEV; return -ENODEV;
ret = i915_mutex_lock_interruptible(dev); ret = i915_mutex_lock_interruptible(dev);
......
...@@ -1221,7 +1221,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, ...@@ -1221,7 +1221,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
if (ret) if (ret)
goto err; goto err;
ret = i915_switch_context(ring, file, ctx); ret = i915_switch_context(ring, ctx);
if (ret) if (ret)
goto err; goto err;
......
...@@ -287,6 +287,9 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv, struct bdb_header *bdb) ...@@ -287,6 +287,9 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
const struct bdb_lfp_backlight_data *backlight_data; const struct bdb_lfp_backlight_data *backlight_data;
const struct bdb_lfp_backlight_data_entry *entry; const struct bdb_lfp_backlight_data_entry *entry;
/* Err to enabling backlight if no backlight block. */
dev_priv->vbt.backlight.present = true;
backlight_data = find_section(bdb, BDB_LVDS_BACKLIGHT); backlight_data = find_section(bdb, BDB_LVDS_BACKLIGHT);
if (!backlight_data) if (!backlight_data)
return; return;
...@@ -299,6 +302,13 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv, struct bdb_header *bdb) ...@@ -299,6 +302,13 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
entry = &backlight_data->data[panel_type]; entry = &backlight_data->data[panel_type];
dev_priv->vbt.backlight.present = entry->type == BDB_BACKLIGHT_TYPE_PWM;
if (!dev_priv->vbt.backlight.present) {
DRM_DEBUG_KMS("PWM backlight not present in VBT (type %u)\n",
entry->type);
return;
}
dev_priv->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz; dev_priv->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz;
dev_priv->vbt.backlight.active_low_pwm = entry->active_low_pwm; dev_priv->vbt.backlight.active_low_pwm = entry->active_low_pwm;
DRM_DEBUG_KMS("VBT backlight PWM modulation frequency %u Hz, " DRM_DEBUG_KMS("VBT backlight PWM modulation frequency %u Hz, "
......
...@@ -374,6 +374,9 @@ struct bdb_lvds_lfp_data { ...@@ -374,6 +374,9 @@ struct bdb_lvds_lfp_data {
struct bdb_lvds_lfp_data_entry data[16]; struct bdb_lvds_lfp_data_entry data[16];
} __packed; } __packed;
#define BDB_BACKLIGHT_TYPE_NONE 0
#define BDB_BACKLIGHT_TYPE_PWM 2
struct bdb_lfp_backlight_data_entry { struct bdb_lfp_backlight_data_entry {
u8 type:2; u8 type:2;
u8 active_low_pwm:1; u8 active_low_pwm:1;
......
...@@ -1065,6 +1065,11 @@ int intel_panel_setup_backlight(struct drm_connector *connector) ...@@ -1065,6 +1065,11 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
unsigned long flags; unsigned long flags;
int ret; int ret;
if (!dev_priv->vbt.backlight.present) {
DRM_DEBUG_KMS("native backlight control not available per VBT\n");
return 0;
}
/* set level and max in panel struct */ /* set level and max in panel struct */
spin_lock_irqsave(&dev_priv->backlight_lock, flags); spin_lock_irqsave(&dev_priv->backlight_lock, flags);
ret = dev_priv->display.setup_backlight(intel_connector); ret = dev_priv->display.setup_backlight(intel_connector);
......
...@@ -1545,6 +1545,16 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc) ...@@ -1545,6 +1545,16 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm); DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm);
if (IS_I915GM(dev) && enabled) {
struct intel_framebuffer *fb;
fb = to_intel_framebuffer(enabled->primary->fb);
/* self-refresh seems busted with untiled */
if (fb->obj->tiling_mode == I915_TILING_NONE)
enabled = NULL;
}
/* /*
* Overlay gets an aggressive default since video jitter is bad. * Overlay gets an aggressive default since video jitter is bad.
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment