summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/pci/drm/drmP.h1
-rw-r--r--sys/dev/pci/drm/i915_drv.h5
-rw-r--r--sys/dev/pci/drm/intel_drv.h3
-rw-r--r--sys/dev/pci/drm/intel_pm.c104
4 files changed, 57 insertions, 56 deletions
diff --git a/sys/dev/pci/drm/drmP.h b/sys/dev/pci/drm/drmP.h
index cb4796ec8eb..0b04858cd12 100644
--- a/sys/dev/pci/drm/drmP.h
+++ b/sys/dev/pci/drm/drmP.h
@@ -119,6 +119,7 @@
#define PAGE_ALIGN(addr) (((addr) + PAGE_MASK) & ~PAGE_MASK)
#define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
+#define jiffies_to_msecs(x) (((int64_t)(x)) * 1000 / hz)
#define msecs_to_jiffies(x) (((int64_t)(x)) * hz / 1000)
#define time_after_eq(a,b) ((long)(b) - (long)(a) <= 0)
#define drm_msleep(x, msg) delay(x * 1000)
diff --git a/sys/dev/pci/drm/i915_drv.h b/sys/dev/pci/drm/i915_drv.h
index 2ce618b8354..4e766505866 100644
--- a/sys/dev/pci/drm/i915_drv.h
+++ b/sys/dev/pci/drm/i915_drv.h
@@ -439,9 +439,8 @@ struct intel_gen6_power_mgmt {
u8 min_delay;
u8 max_delay;
-#if 0
- struct delayed_work delayed_resume_work;
-#endif
+ struct workq_task delayed_resume_task;
+ struct timeout delayed_resume_to;
/*
* Protects RPS/RC6 register access and PCU communication.
diff --git a/sys/dev/pci/drm/intel_drv.h b/sys/dev/pci/drm/intel_drv.h
index fb86620c125..5eaadbafbe9 100644
--- a/sys/dev/pci/drm/intel_drv.h
+++ b/sys/dev/pci/drm/intel_drv.h
@@ -376,7 +376,8 @@ struct intel_unpin_work {
};
struct intel_fbc_work {
-// struct delayed_work work;
+ struct workq_task task;
+ struct timeout to;
struct drm_crtc *crtc;
struct drm_framebuffer *fb;
int interval;
diff --git a/sys/dev/pci/drm/intel_pm.c b/sys/dev/pci/drm/intel_pm.c
index 49041dabcf3..8aa880fd994 100644
--- a/sys/dev/pci/drm/intel_pm.c
+++ b/sys/dev/pci/drm/intel_pm.c
@@ -147,6 +147,12 @@ void vlv_force_wake_get(struct inteldrm_softc *);
void vlv_force_wake_put(struct inteldrm_softc *);
void intel_gt_reset(struct drm_device *);
void intel_gt_init(struct drm_device *);
+void intel_fbc_work_tick(void *);
+void intel_fbc_work_fn(void *, void *);
+void intel_gen6_powersave_tick(void *);
+void intel_gen6_powersave_work(void *, void *);
+
+extern int ticks;
bool
intel_crtc_active(struct drm_crtc *crtc)
@@ -385,13 +391,19 @@ intel_fbc_enabled(struct drm_device *dev)
return dev_priv->display.fbc_enabled(dev);
}
-#ifdef notyet
void
-intel_fbc_work_fn(struct work_struct *__work)
+intel_fbc_work_tick(void *arg)
+{
+ struct intel_fbc_work *work = arg;
+
+ workq_queue_task(NULL, &work->task, 0,
+ intel_fbc_work_fn, work, NULL);
+}
+
+void
+intel_fbc_work_fn(void *arg1, void *arg2)
{
- struct intel_fbc_work *work =
- container_of(to_delayed_work(__work),
- struct intel_fbc_work, work);
+ struct intel_fbc_work *work = arg1;
struct drm_device *dev = work->crtc->dev;
struct inteldrm_softc *dev_priv = dev->dev_private;
@@ -415,7 +427,6 @@ intel_fbc_work_fn(struct work_struct *__work)
free(work, M_DRM);
}
-#endif
void
intel_cancel_fbc_work(struct inteldrm_softc *dev_priv)
@@ -429,11 +440,9 @@ intel_cancel_fbc_work(struct inteldrm_softc *dev_priv)
* dev_priv->fbc_work, so we can perform the cancellation
* entirely asynchronously.
*/
-#ifdef notyet
- if (cancel_delayed_work(&dev_priv->fbc_work->work))
+ if (timeout_del(&dev_priv->fbc_work->to))
/* tasklet was killed before being run, clean up */
free(dev_priv->fbc_work, M_DRM);
-#endif
/* Mark the work as no longer wanted so that if it does
* wake-up (because the work was already running and waiting
@@ -464,7 +473,7 @@ intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
work->crtc = crtc;
work->fb = crtc->fb;
work->interval = interval;
-// INIT_DELAYED_WORK(&work->work, intel_fbc_work_fn);
+ timeout_set(&work->to, intel_fbc_work_tick, work);
dev_priv->fbc_work = work;
@@ -481,7 +490,7 @@ intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
* and indeed performing the enable as a co-routine and not
* waiting synchronously upon the vblank.
*/
-// schedule_delayed_work(&work->work, msecs_to_jiffies(50));
+ timeout_add_msec(&work->to, 50);
}
void
@@ -2420,9 +2429,6 @@ intel_update_sprite_watermarks(struct drm_device *dev, int pipe,
struct drm_i915_gem_object *
intel_alloc_context_page(struct drm_device *dev)
{
- printf("%s stub\n", __func__);
- return NULL;
-#ifdef notyet
struct drm_i915_gem_object *ctx;
int ret;
@@ -2436,7 +2442,7 @@ intel_alloc_context_page(struct drm_device *dev)
return NULL;
}
- ret = i915_gem_object_pin(ctx, 4096, true, false);
+ ret = i915_gem_object_pin(ctx, 4096, true /*, false */);
if (ret) {
DRM_ERROR("failed to pin power context: %d\n", ret);
goto err_unref;
@@ -2454,9 +2460,8 @@ err_unpin:
i915_gem_object_unpin(ctx);
err_unref:
drm_gem_object_unreference(&ctx->base);
- mutex_unlock(&dev->struct_mutex);
+ DRM_UNLOCK();
return NULL;
-#endif
}
struct mutex mchdev_lock;
@@ -2555,7 +2560,7 @@ ironlake_enable_drps(struct drm_device *dev)
dev_priv->ips.last_count1 = I915_READ(0x112e4) + I915_READ(0x112e8) +
I915_READ(0x112e0);
-// dev_priv->ips.last_time1 = jiffies_to_msecs(jiffies);
+ dev_priv->ips.last_time1 = jiffies_to_msecs(ticks);
dev_priv->ips.last_count2 = I915_READ(0x112f4);
nanotime(&dev_priv->ips.last_time2);
@@ -2845,8 +2850,6 @@ gen6_enable_rps(struct drm_device *dev)
void
gen6_update_ring_freq(struct drm_device *dev)
{
- printf("%s stub\n", __func__);
-#ifdef notyet
struct inteldrm_softc *dev_priv = dev->dev_private;
int min_freq = 15;
int gpu_freq;
@@ -2855,6 +2858,7 @@ gen6_update_ring_freq(struct drm_device *dev)
rw_assert_wrlock(&dev_priv->rps.hw_lock);
+#ifdef notyet
max_ia_freq = cpufreq_quick_get_max(0);
/*
* Default to measured freq if none found, PCU will ensure we don't go
@@ -2865,6 +2869,10 @@ gen6_update_ring_freq(struct drm_device *dev)
/* Convert from kHz to MHz */
max_ia_freq /= 1000;
+#else
+ /* we ideally want the max so avoid cpuspeed */
+ max_ia_freq = (curcpu()->ci_tsc_freq + 4999) / 1000000;
+#endif
/*
* For each potential GPU frequency, load a ring frequency we'd like
@@ -2874,6 +2882,7 @@ gen6_update_ring_freq(struct drm_device *dev)
for (gpu_freq = dev_priv->rps.max_delay; gpu_freq >= dev_priv->rps.min_delay;
gpu_freq--) {
int diff = dev_priv->rps.max_delay - gpu_freq;
+ int d;
/*
* For GPU frequencies less than 750MHz, just use the lowest
@@ -2883,14 +2892,14 @@ gen6_update_ring_freq(struct drm_device *dev)
ia_freq = 800;
else
ia_freq = max_ia_freq - ((diff * scaling_factor) / 2);
- ia_freq = DIV_ROUND_CLOSEST(ia_freq, 100);
+ d = 100;
+ ia_freq = (ia_freq + d / 2) / d;
ia_freq <<= GEN6_PCODE_FREQ_IA_RATIO_SHIFT;
sandybridge_pcode_write(dev_priv,
GEN6_PCODE_WRITE_MIN_FREQ_TABLE,
ia_freq | gpu_freq);
}
-#endif
}
void
@@ -3052,12 +3061,9 @@ static const struct cparams {
unsigned long
__i915_chipset_val(struct inteldrm_softc *dev_priv)
{
- printf("%s stub\n", __func__);
- return 0;
-#ifdef notyet
u64 total_count, diff, ret;
u32 count1, count2, count3, m = 0, c = 0;
- unsigned long now = jiffies_to_msecs(jiffies), diff1;
+ unsigned long now = jiffies_to_msecs(ticks), diff1;
int i;
// assert_spin_locked(&mchdev_lock);
@@ -3095,9 +3101,9 @@ __i915_chipset_val(struct inteldrm_softc *dev_priv)
}
}
- diff = div_u64(diff, diff1);
+ diff = diff / diff1;
ret = ((m * diff) + c);
- ret = div_u64(ret, 10);
+ ret = ret / 10;
dev_priv->ips.last_count1 = total_count;
dev_priv->ips.last_time1 = now;
@@ -3105,7 +3111,6 @@ __i915_chipset_val(struct inteldrm_softc *dev_priv)
dev_priv->ips.chipset_power = ret;
return ret;
-#endif
}
unsigned long
@@ -3286,8 +3291,6 @@ pvid_to_extvid(struct inteldrm_softc *dev_priv, u8 pxvid)
void
__i915_update_gfx_val(struct inteldrm_softc *dev_priv)
{
- printf("%s stub\n", __func__);
-#ifdef notyet
struct timespec now, diff1;
u64 diff;
unsigned long diffms;
@@ -3296,7 +3299,7 @@ __i915_update_gfx_val(struct inteldrm_softc *dev_priv)
// assert_spin_locked(&mchdev_lock);
nanotime(&now);
- diff1 = timespec_sub(now, dev_priv->ips.last_time2);
+ timespecsub(&now, &dev_priv->ips.last_time2, &diff1);
/* Don't divide by 0 */
diffms = diff1.tv_sec * 1000 + diff1.tv_nsec / 1000000;
@@ -3317,9 +3320,8 @@ __i915_update_gfx_val(struct inteldrm_softc *dev_priv)
/* More magic constants... */
diff = diff * 1181;
- diff = div_u64(diff, diffms * 10);
+ diff = diff / (diffms * 10);
dev_priv->ips.gfx_power = diff;
-#endif
}
void
@@ -3654,22 +3656,26 @@ intel_disable_gt_powersave(struct drm_device *dev)
ironlake_disable_drps(dev);
ironlake_disable_rc6(dev);
} else if (INTEL_INFO(dev)->gen >= 6 && !IS_VALLEYVIEW(dev)) {
-#ifdef notyet
- cancel_delayed_work_sync(&dev_priv->rps.delayed_resume_work);
-#endif
+ timeout_del(&dev_priv->rps.delayed_resume_to);
rw_enter_write(&dev_priv->rps.hw_lock);
gen6_disable_rps(dev);
rw_exit_write(&dev_priv->rps.hw_lock);
}
}
-#ifdef notyet
void
-intel_gen6_powersave_work(struct work_struct *work)
+intel_gen6_powersave_tick(void *arg)
+{
+ drm_i915_private_t *dev_priv = arg;
+
+ workq_queue_task(NULL, &dev_priv->rps.delayed_resume_task, 0,
+ intel_gen6_powersave_work, dev_priv, NULL);
+}
+
+void
+intel_gen6_powersave_work(void *arg1, void *arg2)
{
- struct inteldrm_softc *dev_priv =
- container_of(work, struct inteldrm_softc,
- rps.delayed_resume_work.work);
+ drm_i915_private_t *dev_priv = arg1;
struct drm_device *dev = (struct drm_device *)dev_priv->drmdev;
rw_enter_write(&dev_priv->rps.hw_lock);
@@ -3677,12 +3683,11 @@ intel_gen6_powersave_work(struct work_struct *work)
gen6_update_ring_freq(dev);
rw_exit_write(&dev_priv->rps.hw_lock);
}
-#endif
void
intel_enable_gt_powersave(struct drm_device *dev)
{
-// struct inteldrm_softc *dev_priv = dev->dev_private;
+ struct inteldrm_softc *dev_priv = dev->dev_private;
if (IS_IRONLAKE_M(dev)) {
ironlake_enable_drps(dev);
@@ -3694,10 +3699,7 @@ intel_enable_gt_powersave(struct drm_device *dev)
* done at any specific time, so do this out of our fast path
* to make resume and init faster.
*/
-#ifdef notyet
- schedule_delayed_work(&dev_priv->rps.delayed_resume_work,
- round_jiffies_up_relative(HZ));
-#endif
+ timeout_add_sec(&dev_priv->rps.delayed_resume_to, 1);
}
}
@@ -4685,10 +4687,8 @@ intel_gt_init(struct drm_device *dev)
dev_priv->gt.force_wake_get = __gen6_gt_force_wake_get;
dev_priv->gt.force_wake_put = __gen6_gt_force_wake_put;
}
-#ifdef notyet
- INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work,
- intel_gen6_powersave_work);
-#endif
+ timeout_set(&dev_priv->rps.delayed_resume_to, intel_gen6_powersave_tick,
+ dev_priv);
}
int