From 68b4189ec99e410c8be9c6e898124d6b2a16dd1b Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 19 Apr 2010 15:57:25 -0400 Subject: [PATCH] --- yaml --- r: 196543 b: refs/heads/master c: 0a31a448659d48cbc38f5e7520d8a65f8f1f8276 h: refs/heads/master i: 196541: 4e8bb0c54135b8a9f858f40d7e235fd4008bc5c0 196539: 1b12c4cfa3f64ee74efe7904d7b1777bd14c2f8d 196535: 1f36981083f7212e65d7b2473c8755237dd6ec81 196527: c083176afbb55536a67db58d8e00d31f3520a200 196511: 7555a70bfc145c04a47f01d1a0f4d781ce8f1ca3 196479: a81a123f2a4c0479d10273a33240dadaefa62f0d v: v3 --- [refs] | 2 +- trunk/drivers/gpu/drm/Kconfig | 2 +- trunk/drivers/gpu/drm/drm_auth.c | 3 +- trunk/drivers/gpu/drm/drm_crtc_helper.c | 95 -- trunk/drivers/gpu/drm/drm_dma.c | 4 +- trunk/drivers/gpu/drm/drm_edid.c | 23 +- trunk/drivers/gpu/drm/drm_fb_helper.c | 217 ++--- trunk/drivers/gpu/drm/drm_fops.c | 3 +- trunk/drivers/gpu/drm/i915/i915_dma.c | 2 +- trunk/drivers/gpu/drm/i915/i915_irq.c | 3 +- trunk/drivers/gpu/drm/i915/i915_reg.h | 5 +- trunk/drivers/gpu/drm/i915/intel_crt.c | 5 - trunk/drivers/gpu/drm/i915/intel_display.c | 12 +- trunk/drivers/gpu/drm/i915/intel_dp.c | 2 - trunk/drivers/gpu/drm/i915/intel_drv.h | 2 +- trunk/drivers/gpu/drm/i915/intel_fb.c | 25 +- trunk/drivers/gpu/drm/i915/intel_hdmi.c | 1 - trunk/drivers/gpu/drm/i915/intel_sdvo.c | 2 - .../gpu/drm/nouveau/nouveau_connector.c | 12 - .../drivers/gpu/drm/nouveau/nouveau_display.c | 1 - trunk/drivers/gpu/drm/nouveau/nouveau_drv.h | 1 - trunk/drivers/gpu/drm/nouveau/nouveau_fbcon.c | 81 +- trunk/drivers/gpu/drm/nouveau/nouveau_fbcon.h | 2 +- trunk/drivers/gpu/drm/nouveau/nouveau_grctx.c | 6 +- trunk/drivers/gpu/drm/nouveau/nouveau_state.c | 53 +- trunk/drivers/gpu/drm/nouveau/nv50_display.c | 2 +- trunk/drivers/gpu/drm/radeon/Kconfig | 1 - trunk/drivers/gpu/drm/radeon/atombios_crtc.c | 14 +- trunk/drivers/gpu/drm/radeon/evergreen.c | 55 +- trunk/drivers/gpu/drm/radeon/evergreen_reg.h | 4 - trunk/drivers/gpu/drm/radeon/r100.c | 476 +++------- trunk/drivers/gpu/drm/radeon/r100d.h | 36 - trunk/drivers/gpu/drm/radeon/r300.c | 3 + trunk/drivers/gpu/drm/radeon/r420.c | 32 +- trunk/drivers/gpu/drm/radeon/r500_reg.h | 3 - trunk/drivers/gpu/drm/radeon/r520.c | 2 + trunk/drivers/gpu/drm/radeon/r600.c | 408 +-------- trunk/drivers/gpu/drm/radeon/radeon.h | 129 +-- trunk/drivers/gpu/drm/radeon/radeon_asic.c | 84 -- trunk/drivers/gpu/drm/radeon/radeon_asic.h | 20 - .../drivers/gpu/drm/radeon/radeon_atombios.c | 214 ++--- trunk/drivers/gpu/drm/radeon/radeon_bios.c | 3 +- trunk/drivers/gpu/drm/radeon/radeon_combios.c | 52 +- .../gpu/drm/radeon/radeon_connectors.c | 13 - trunk/drivers/gpu/drm/radeon/radeon_device.c | 28 +- trunk/drivers/gpu/drm/radeon/radeon_display.c | 82 +- trunk/drivers/gpu/drm/radeon/radeon_drv.c | 7 +- .../drivers/gpu/drm/radeon/radeon_encoders.c | 44 +- trunk/drivers/gpu/drm/radeon/radeon_fb.c | 24 +- .../gpu/drm/radeon/radeon_fixed.h} | 40 +- trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c | 7 +- trunk/drivers/gpu/drm/radeon/radeon_kms.c | 18 - .../gpu/drm/radeon/radeon_legacy_crtc.c | 14 +- .../gpu/drm/radeon/radeon_legacy_encoders.c | 15 + trunk/drivers/gpu/drm/radeon/radeon_mode.h | 5 +- trunk/drivers/gpu/drm/radeon/radeon_object.c | 6 - trunk/drivers/gpu/drm/radeon/radeon_pm.c | 814 ++++++------------ trunk/drivers/gpu/drm/radeon/radeon_reg.h | 4 +- trunk/drivers/gpu/drm/radeon/radeon_ring.c | 66 +- trunk/drivers/gpu/drm/radeon/radeon_ttm.c | 6 +- trunk/drivers/gpu/drm/radeon/rs400.c | 3 + trunk/drivers/gpu/drm/radeon/rs600.c | 154 +--- trunk/drivers/gpu/drm/radeon/rs600d.h | 34 - trunk/drivers/gpu/drm/radeon/rs690.c | 283 +++--- trunk/drivers/gpu/drm/radeon/rv515.c | 191 ++-- trunk/drivers/gpu/drm/radeon/rv770.c | 7 +- trunk/drivers/gpu/drm/savage/savage_bci.c | 3 +- trunk/drivers/gpu/drm/ttm/ttm_bo.c | 14 - trunk/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 10 +- trunk/drivers/gpu/vga/Kconfig | 6 +- trunk/drivers/video/efifb.c | 11 +- trunk/drivers/video/fbmem.c | 74 +- trunk/drivers/video/fbsysfs.c | 1 - trunk/drivers/video/offb.c | 28 +- trunk/drivers/video/vesafb.c | 11 +- trunk/drivers/video/vga16fb.c | 26 +- trunk/include/drm/drm_crtc.h | 19 - trunk/include/drm/drm_crtc_helper.h | 3 - trunk/include/drm/drm_edid.h | 2 +- trunk/include/drm/drm_fb_helper.h | 13 +- trunk/include/drm/radeon_drm.h | 1 - trunk/include/drm/ttm/ttm_bo_api.h | 17 - trunk/include/linux/fb.h | 19 +- 83 files changed, 1235 insertions(+), 2990 deletions(-) rename trunk/{include/drm/drm_fixed.h => drivers/gpu/drm/radeon/radeon_fixed.h} (60%) diff --git a/[refs] b/[refs] index f0fd34af4372..029debcccdea 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 26481fb15644b5fd85d4cea020f74a234cdf6803 +refs/heads/master: 0a31a448659d48cbc38f5e7520d8a65f8f1f8276 diff --git a/trunk/drivers/gpu/drm/Kconfig b/trunk/drivers/gpu/drm/Kconfig index 2583ddfcc33e..be5aa7d5206b 100644 --- a/trunk/drivers/gpu/drm/Kconfig +++ b/trunk/drivers/gpu/drm/Kconfig @@ -9,7 +9,6 @@ menuconfig DRM depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG && MMU select I2C select I2C_ALGOBIT - select SLOW_WORK help Kernel-level support for the Direct Rendering Infrastructure (DRI) introduced in XFree86 4.0. If you say Y here, you need to select @@ -24,6 +23,7 @@ config DRM_KMS_HELPER depends on DRM select FB select FRAMEBUFFER_CONSOLE if !EMBEDDED + select SLOW_WORK help FB and CRTC helpers for KMS drivers. diff --git a/trunk/drivers/gpu/drm/drm_auth.c b/trunk/drivers/gpu/drm/drm_auth.c index 3f46772f0cb2..932b5aa96a67 100644 --- a/trunk/drivers/gpu/drm/drm_auth.c +++ b/trunk/drivers/gpu/drm/drm_auth.c @@ -79,9 +79,10 @@ static int drm_add_magic(struct drm_master *master, struct drm_file *priv, struct drm_device *dev = master->minor->dev; DRM_DEBUG("%d\n", magic); - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc(sizeof(*entry), GFP_KERNEL); if (!entry) return -ENOMEM; + memset(entry, 0, sizeof(*entry)); entry->priv = priv; entry->hash_item.key = (unsigned long)magic; mutex_lock(&dev->struct_mutex); diff --git a/trunk/drivers/gpu/drm/drm_crtc_helper.c b/trunk/drivers/gpu/drm/drm_crtc_helper.c index 764401951041..b142ac260d97 100644 --- a/trunk/drivers/gpu/drm/drm_crtc_helper.c +++ b/trunk/drivers/gpu/drm/drm_crtc_helper.c @@ -807,98 +807,3 @@ int drm_helper_resume_force_mode(struct drm_device *dev) return 0; } EXPORT_SYMBOL(drm_helper_resume_force_mode); - -static struct slow_work_ops output_poll_ops; - -#define DRM_OUTPUT_POLL_PERIOD (10*HZ) -static void output_poll_execute(struct slow_work *work) -{ - struct delayed_slow_work *delayed_work = container_of(work, struct delayed_slow_work, work); - struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_slow_work); - struct drm_connector *connector; - enum drm_connector_status old_status, status; - bool repoll = false, changed = false; - int ret; - - mutex_lock(&dev->mode_config.mutex); - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - - /* if this is HPD or polled don't check it - - TV out for instance */ - if (!connector->polled) - continue; - - else if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT)) - repoll = true; - - old_status = connector->status; - /* if we are connected and don't want to poll for disconnect - skip it */ - if (old_status == connector_status_connected && - !(connector->polled & DRM_CONNECTOR_POLL_DISCONNECT) && - !(connector->polled & DRM_CONNECTOR_POLL_HPD)) - continue; - - status = connector->funcs->detect(connector); - if (old_status != status) - changed = true; - } - - mutex_unlock(&dev->mode_config.mutex); - - if (changed) { - /* send a uevent + call fbdev */ - drm_sysfs_hotplug_event(dev); - if (dev->mode_config.funcs->output_poll_changed) - dev->mode_config.funcs->output_poll_changed(dev); - } - - if (repoll) { - ret = delayed_slow_work_enqueue(delayed_work, DRM_OUTPUT_POLL_PERIOD); - if (ret) - DRM_ERROR("delayed enqueue failed %d\n", ret); - } -} - -void drm_kms_helper_poll_init(struct drm_device *dev) -{ - struct drm_connector *connector; - bool poll = false; - int ret; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (connector->polled) - poll = true; - } - slow_work_register_user(THIS_MODULE); - delayed_slow_work_init(&dev->mode_config.output_poll_slow_work, - &output_poll_ops); - - if (poll) { - ret = delayed_slow_work_enqueue(&dev->mode_config.output_poll_slow_work, DRM_OUTPUT_POLL_PERIOD); - if (ret) - DRM_ERROR("delayed enqueue failed %d\n", ret); - } -} -EXPORT_SYMBOL(drm_kms_helper_poll_init); - -void drm_kms_helper_poll_fini(struct drm_device *dev) -{ - delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work); - slow_work_unregister_user(THIS_MODULE); -} -EXPORT_SYMBOL(drm_kms_helper_poll_fini); - -void drm_helper_hpd_irq_event(struct drm_device *dev) -{ - if (!dev->mode_config.poll_enabled) - return; - delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work); - /* schedule a slow work asap */ - delayed_slow_work_enqueue(&dev->mode_config.output_poll_slow_work, 0); -} -EXPORT_SYMBOL(drm_helper_hpd_irq_event); - -static struct slow_work_ops output_poll_ops = { - .execute = output_poll_execute, -}; diff --git a/trunk/drivers/gpu/drm/drm_dma.c b/trunk/drivers/gpu/drm/drm_dma.c index 252cbd74df0e..13f1537413fb 100644 --- a/trunk/drivers/gpu/drm/drm_dma.c +++ b/trunk/drivers/gpu/drm/drm_dma.c @@ -47,10 +47,12 @@ int drm_dma_setup(struct drm_device *dev) { int i; - dev->dma = kzalloc(sizeof(*dev->dma), GFP_KERNEL); + dev->dma = kmalloc(sizeof(*dev->dma), GFP_KERNEL); if (!dev->dma) return -ENOMEM; + memset(dev->dma, 0, sizeof(*dev->dma)); + for (i = 0; i <= DRM_MAX_ORDER; i++) memset(&dev->dma->bufs[i], 0, sizeof(dev->dma->bufs[0])); diff --git a/trunk/drivers/gpu/drm/drm_edid.c b/trunk/drivers/gpu/drm/drm_edid.c index dfd4f3677f3b..71886749fa2c 100644 --- a/trunk/drivers/gpu/drm/drm_edid.c +++ b/trunk/drivers/gpu/drm/drm_edid.c @@ -496,7 +496,7 @@ static struct drm_display_mode drm_dmt_modes[] = { DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1024x768@85Hz */ { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 94500, 1024, 1072, - 1168, 1376, 0, 768, 769, 772, 808, 0, + 1072, 1376, 0, 768, 769, 772, 808, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1152x864@75Hz */ { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216, @@ -658,8 +658,8 @@ static struct drm_display_mode drm_dmt_modes[] = { static const int drm_num_dmt_modes = sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode); -struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, - int hsize, int vsize, int fresh) +static struct drm_display_mode *drm_find_dmt(struct drm_device *dev, + int hsize, int vsize, int fresh) { int i; struct drm_display_mode *ptr, *mode; @@ -677,7 +677,6 @@ struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, } return mode; } -EXPORT_SYMBOL(drm_mode_find_dmt); typedef void detailed_cb(struct detailed_timing *timing, void *closure); @@ -867,7 +866,7 @@ drm_mode_std(struct drm_connector *connector, struct edid *edid, } /* check whether it can be found in default mode table */ - mode = drm_mode_find_dmt(dev, hsize, vsize, vrefresh_rate); + mode = drm_find_dmt(dev, hsize, vsize, vrefresh_rate); if (mode) return mode; @@ -1384,14 +1383,14 @@ drm_est3_modes(struct drm_connector *connector, struct detailed_timing *timing) for (i = 0; i < 6; i++) { for (j = 7; j > 0; j--) { m = (i * 8) + (7 - j); - if (m >= num_est3_modes) + if (m > num_est3_modes) break; if (est[i] & (1 << j)) { - mode = drm_mode_find_dmt(connector->dev, - est3_modes[m].w, - est3_modes[m].h, - est3_modes[m].r - /*, est3_modes[m].rb */); + mode = drm_find_dmt(connector->dev, + est3_modes[m].w, + est3_modes[m].h, + est3_modes[m].r + /*, est3_modes[m].rb */); if (mode) { drm_mode_probed_add(connector, mode); modes++; @@ -1510,6 +1509,7 @@ static int add_detailed_info_eedid(struct drm_connector *connector, char *edid_ext = NULL; struct detailed_timing *timing; int start_offset, end_offset; + int timing_level; if (edid->version == 1 && edid->revision < 3) return 0; @@ -1536,6 +1536,7 @@ static int add_detailed_info_eedid(struct drm_connector *connector, return 0; } + timing_level = standard_timing_level(edid); end_offset = EDID_LENGTH; end_offset -= sizeof(struct detailed_timing); for (i = start_offset; i < end_offset; diff --git a/trunk/drivers/gpu/drm/drm_fb_helper.c b/trunk/drivers/gpu/drm/drm_fb_helper.c index b3779d243aef..b28e56382e86 100644 --- a/trunk/drivers/gpu/drm/drm_fb_helper.c +++ b/trunk/drivers/gpu/drm/drm_fb_helper.c @@ -42,6 +42,8 @@ MODULE_LICENSE("GPL and additional rights"); static LIST_HEAD(kernel_fb_helper_list); +static struct slow_work_ops output_status_change_ops; + /* simple single crtc case helper function */ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper) { @@ -423,13 +425,19 @@ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper) int drm_fb_helper_init(struct drm_device *dev, struct drm_fb_helper *fb_helper, - int crtc_count, int max_conn_count) + int crtc_count, int max_conn_count, + bool polled) { struct drm_crtc *crtc; int ret = 0; int i; fb_helper->dev = dev; + fb_helper->poll_enabled = polled; + + slow_work_register_user(THIS_MODULE); + delayed_slow_work_init(&fb_helper->output_status_change_slow_work, + &output_status_change_ops); INIT_LIST_HEAD(&fb_helper->kernel_fb_list); @@ -477,7 +485,7 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper) if (!list_empty(&fb_helper->kernel_fb_list)) { list_del(&fb_helper->kernel_fb_list); if (list_empty(&kernel_fb_helper_list)) { - printk(KERN_INFO "drm: unregistered panic notifier\n"); + printk(KERN_INFO "unregistered panic notifier\n"); atomic_notifier_chain_unregister(&panic_notifier_list, &paniced); unregister_sysrq_key('v', &sysrq_drm_fb_helper_restore_op); @@ -486,6 +494,8 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper) drm_fb_helper_crtc_free(fb_helper); + delayed_slow_work_cancel(&fb_helper->output_status_change_slow_work); + slow_work_unregister_user(THIS_MODULE); } EXPORT_SYMBOL(drm_fb_helper_fini); @@ -703,7 +713,7 @@ int drm_fb_helper_set_par(struct fb_info *info) if (fb_helper->delayed_hotplug) { fb_helper->delayed_hotplug = false; - drm_fb_helper_hotplug_event(fb_helper); + delayed_slow_work_enqueue(&fb_helper->output_status_change_slow_work, 0); } return 0; } @@ -816,7 +826,7 @@ int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, if (crtc_count == 0 || sizes.fb_width == -1 || sizes.fb_height == -1) { /* hmm everyone went away - assume VGA cable just fell out and will come back later. */ - DRM_INFO("Cannot find any crtc or sizes - going 1024x768\n"); + DRM_ERROR("Cannot find any crtc or sizes - going 1024x768\n"); sizes.fb_width = sizes.surface_width = 1024; sizes.fb_height = sizes.surface_height = 768; } @@ -849,7 +859,7 @@ int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, /* Switch back to kernel console on panic */ /* multi card linked list maybe */ if (list_empty(&kernel_fb_helper_list)) { - printk(KERN_INFO "drm: registered panic notifier\n"); + printk(KERN_INFO "registered panic notifier\n"); atomic_notifier_chain_register(&panic_notifier_list, &paniced); register_sysrq_key('v', &sysrq_drm_fb_helper_restore_op); @@ -1070,79 +1080,6 @@ static void drm_enable_connectors(struct drm_fb_helper *fb_helper, } } -static bool drm_target_cloned(struct drm_fb_helper *fb_helper, - struct drm_display_mode **modes, - bool *enabled, int width, int height) -{ - int count, i, j; - bool can_clone = false; - struct drm_fb_helper_connector *fb_helper_conn; - struct drm_display_mode *dmt_mode, *mode; - - /* only contemplate cloning in the single crtc case */ - if (fb_helper->crtc_count > 1) - return false; - - count = 0; - for (i = 0; i < fb_helper->connector_count; i++) { - if (enabled[i]) - count++; - } - - /* only contemplate cloning if more than one connector is enabled */ - if (count <= 1) - return false; - - /* check the command line or if nothing common pick 1024x768 */ - can_clone = true; - for (i = 0; i < fb_helper->connector_count; i++) { - if (!enabled[i]) - continue; - fb_helper_conn = fb_helper->connector_info[i]; - modes[i] = drm_pick_cmdline_mode(fb_helper_conn, width, height); - if (!modes[i]) { - can_clone = false; - break; - } - for (j = 0; j < i; j++) { - if (!enabled[j]) - continue; - if (!drm_mode_equal(modes[j], modes[i])) - can_clone = false; - } - } - - if (can_clone) { - DRM_DEBUG_KMS("can clone using command line\n"); - return true; - } - - /* try and find a 1024x768 mode on each connector */ - can_clone = true; - dmt_mode = drm_mode_find_dmt(fb_helper->dev, 1024, 768, 60); - - for (i = 0; i < fb_helper->connector_count; i++) { - - if (!enabled[i]) - continue; - - fb_helper_conn = fb_helper->connector_info[i]; - list_for_each_entry(mode, &fb_helper_conn->connector->modes, head) { - if (drm_mode_equal(mode, dmt_mode)) - modes[i] = mode; - } - if (!modes[i]) - can_clone = false; - } - - if (can_clone) { - DRM_DEBUG_KMS("can clone using 1024x768\n"); - return true; - } - DRM_INFO("kms: can't enable cloning when we probably wanted to.\n"); - return false; -} - static bool drm_target_preferred(struct drm_fb_helper *fb_helper, struct drm_display_mode **modes, bool *enabled, int width, int height) @@ -1236,12 +1173,8 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, break; if (o < n) { - /* ignore cloning unless only a single crtc */ - if (fb_helper->crtc_count > 1) - continue; - - if (!drm_mode_equal(modes[o], modes[n])) - continue; + /* ignore cloning for now */ + continue; } crtcs[n] = crtc; @@ -1291,12 +1224,9 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) drm_enable_connectors(fb_helper, enabled); - ret = drm_target_cloned(fb_helper, modes, enabled, width, height); - if (!ret) { - ret = drm_target_preferred(fb_helper, modes, enabled, width, height); - if (!ret) - DRM_ERROR("Unable to find initial modes\n"); - } + ret = drm_target_preferred(fb_helper, modes, enabled, width, height); + if (!ret) + DRM_ERROR("Unable to find initial modes\n"); DRM_DEBUG_KMS("picking CRTCs for %dx%d config\n", width, height); @@ -1362,7 +1292,12 @@ bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel) * we shouldn't end up with no modes here. */ if (count == 0) { - printk(KERN_INFO "No connectors reported connected with modes\n"); + if (fb_helper->poll_enabled) { + delayed_slow_work_enqueue(&fb_helper->output_status_change_slow_work, + 5*HZ); + printk(KERN_INFO "No connectors reported connected with modes - started polling\n"); + } else + printk(KERN_INFO "No connectors reported connected with modes\n"); } drm_setup_crtcs(fb_helper); @@ -1370,16 +1305,71 @@ bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel) } EXPORT_SYMBOL(drm_fb_helper_initial_config); -bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) +/* we got a hotplug irq - need to update fbcon */ +void drm_helper_fb_hpd_irq_event(struct drm_fb_helper *fb_helper) +{ + /* if we don't have the fbdev registered yet do nothing */ + if (!fb_helper->fbdev) + return; + + /* schedule a slow work asap */ + delayed_slow_work_enqueue(&fb_helper->output_status_change_slow_work, 0); +} +EXPORT_SYMBOL(drm_helper_fb_hpd_irq_event); + +bool drm_helper_fb_hotplug_event(struct drm_fb_helper *fb_helper, bool polled) { int count = 0; + int ret; u32 max_width, max_height, bpp_sel; - bool bound = false, crtcs_bound = false; - struct drm_crtc *crtc; if (!fb_helper->fb) return false; + DRM_DEBUG_KMS("\n"); + + max_width = fb_helper->fb->width; + max_height = fb_helper->fb->height; + bpp_sel = fb_helper->fb->bits_per_pixel; + + count = drm_fb_helper_probe_connector_modes(fb_helper, max_width, + max_height); + if (fb_helper->poll_enabled && !polled) { + if (count) { + delayed_slow_work_cancel(&fb_helper->output_status_change_slow_work); + } else { + ret = delayed_slow_work_enqueue(&fb_helper->output_status_change_slow_work, 5*HZ); + } + } + drm_setup_crtcs(fb_helper); + + return drm_fb_helper_single_fb_probe(fb_helper, bpp_sel); +} +EXPORT_SYMBOL(drm_helper_fb_hotplug_event); + +/* + * delayed work queue execution function + * - check if fbdev is actually in use on the gpu + * - if not set delayed flag and repoll if necessary + * - check for connector status change + * - repoll if 0 modes found + *- call driver output status changed notifier + */ +static void output_status_change_execute(struct slow_work *work) +{ + struct delayed_slow_work *delayed_work = container_of(work, struct delayed_slow_work, work); + struct drm_fb_helper *fb_helper = container_of(delayed_work, struct drm_fb_helper, output_status_change_slow_work); + struct drm_connector *connector; + enum drm_connector_status old_status, status; + bool repoll, changed = false; + int ret; + int i; + bool bound = false, crtcs_bound = false; + struct drm_crtc *crtc; + + repoll = fb_helper->poll_enabled; + /* first of all check the fbcon framebuffer is actually bound to any crtc */ + /* take into account that no crtc at all maybe bound */ list_for_each_entry(crtc, &fb_helper->dev->mode_config.crtc_list, head) { if (crtc->fb) crtcs_bound = true; @@ -1387,21 +1377,38 @@ bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) bound = true; } - if (!bound && crtcs_bound) { + if (bound == false && crtcs_bound) { fb_helper->delayed_hotplug = true; - return false; + goto requeue; } - DRM_DEBUG_KMS("\n"); - max_width = fb_helper->fb->width; - max_height = fb_helper->fb->height; - bpp_sel = fb_helper->fb->bits_per_pixel; + for (i = 0; i < fb_helper->connector_count; i++) { + connector = fb_helper->connector_info[i]->connector; + old_status = connector->status; + status = connector->funcs->detect(connector); + if (old_status != status) { + changed = true; + } + if (status == connector_status_connected && repoll) { + DRM_DEBUG("%s is connected - stop polling\n", drm_get_connector_name(connector)); + repoll = false; + } + } - count = drm_fb_helper_probe_connector_modes(fb_helper, max_width, - max_height); - drm_setup_crtcs(fb_helper); + if (changed) { + if (fb_helper->funcs->fb_output_status_changed) + fb_helper->funcs->fb_output_status_changed(fb_helper); + } - return drm_fb_helper_single_fb_probe(fb_helper, bpp_sel); +requeue: + if (repoll) { + ret = delayed_slow_work_enqueue(delayed_work, 5*HZ); + if (ret) + DRM_ERROR("delayed enqueue failed %d\n", ret); + } } -EXPORT_SYMBOL(drm_fb_helper_hotplug_event); + +static struct slow_work_ops output_status_change_ops = { + .execute = output_status_change_execute, +}; diff --git a/trunk/drivers/gpu/drm/drm_fops.c b/trunk/drivers/gpu/drm/drm_fops.c index e7aace20981f..9d532d7fdf59 100644 --- a/trunk/drivers/gpu/drm/drm_fops.c +++ b/trunk/drivers/gpu/drm/drm_fops.c @@ -243,10 +243,11 @@ static int drm_open_helper(struct inode *inode, struct file *filp, DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor_id); - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kmalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; + memset(priv, 0, sizeof(*priv)); filp->private_data = priv; priv->filp = filp; priv->uid = current_euid(); diff --git a/trunk/drivers/gpu/drm/i915/i915_dma.c b/trunk/drivers/gpu/drm/i915/i915_dma.c index 8fe66ac4e1a5..52e468bbd5e4 100644 --- a/trunk/drivers/gpu/drm/i915/i915_dma.c +++ b/trunk/drivers/gpu/drm/i915/i915_dma.c @@ -1493,7 +1493,7 @@ static int i915_load_modeset_init(struct drm_device *dev, I915_WRITE(INSTPM, (1 << 5) | (1 << 21)); intel_fbdev_init(dev); - drm_kms_helper_poll_init(dev); + return 0; destroy_ringbuffer: diff --git a/trunk/drivers/gpu/drm/i915/i915_irq.c b/trunk/drivers/gpu/drm/i915/i915_irq.c index b034ea36731c..ed26b7b7376a 100644 --- a/trunk/drivers/gpu/drm/i915/i915_irq.c +++ b/trunk/drivers/gpu/drm/i915/i915_irq.c @@ -271,7 +271,8 @@ static void i915_hotplug_work_func(struct work_struct *work) } } /* Just fire off a uevent and let userspace tell us what to do */ - drm_helper_hpd_irq_event(dev); + intelfb_hotplug(dev, false); + drm_sysfs_hotplug_event(dev); } static void i915_handle_rps_change(struct drm_device *dev) diff --git a/trunk/drivers/gpu/drm/i915/i915_reg.h b/trunk/drivers/gpu/drm/i915/i915_reg.h index 527d30aecda2..0bbbb7753950 100644 --- a/trunk/drivers/gpu/drm/i915/i915_reg.h +++ b/trunk/drivers/gpu/drm/i915/i915_reg.h @@ -1922,7 +1922,10 @@ /* Display & cursor control */ /* dithering flag on Ironlake */ -#define PIPE_ENABLE_DITHER (1 << 4) +#define PIPE_ENABLE_DITHER (1 << 4) +#define PIPE_DITHER_TYPE_MASK (3 << 2) +#define PIPE_DITHER_TYPE_SPATIAL (0 << 2) +#define PIPE_DITHER_TYPE_ST01 (1 << 2) /* Pipe A */ #define PIPEADSL 0x70000 #define PIPEACONF 0x70008 diff --git a/trunk/drivers/gpu/drm/i915/intel_crt.c b/trunk/drivers/gpu/drm/i915/intel_crt.c index e16ac5a28c3c..26756cd34e3c 100644 --- a/trunk/drivers/gpu/drm/i915/intel_crt.c +++ b/trunk/drivers/gpu/drm/i915/intel_crt.c @@ -577,10 +577,5 @@ void intel_crt_init(struct drm_device *dev) drm_sysfs_connector_add(connector); - if (I915_HAS_HOTPLUG(dev)) - connector->polled = DRM_CONNECTOR_POLL_HPD; - else - connector->polled = DRM_CONNECTOR_POLL_CONNECT; - dev_priv->hotplug_supported_mask |= CRT_HOTPLUG_INT_STATUS; } diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index 4d739a1b13ca..119a41ac3bb6 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -3677,14 +3677,16 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, /* set the dithering flag */ if (IS_I965G(dev)) { if (dev_priv->lvds_dither) { - if (HAS_PCH_SPLIT(dev)) + if (HAS_PCH_SPLIT(dev)) { pipeconf |= PIPE_ENABLE_DITHER; - else + pipeconf |= PIPE_DITHER_TYPE_ST01; + } else lvds |= LVDS_ENABLE_DITHER; } else { - if (HAS_PCH_SPLIT(dev)) + if (HAS_PCH_SPLIT(dev)) { pipeconf &= ~PIPE_ENABLE_DITHER; - else + pipeconf &= ~PIPE_DITHER_TYPE_MASK; + } else lvds &= ~LVDS_ENABLE_DITHER; } } @@ -4959,7 +4961,6 @@ intel_user_framebuffer_create(struct drm_device *dev, static const struct drm_mode_config_funcs intel_mode_funcs = { .fb_create = intel_user_framebuffer_create, - .output_poll_changed = intel_fb_output_poll_changed, }; static struct drm_gem_object * @@ -5347,7 +5348,6 @@ void intel_modeset_cleanup(struct drm_device *dev) mutex_lock(&dev->struct_mutex); - drm_kms_helper_poll_fini(dev); intel_fbdev_fini(dev); list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { diff --git a/trunk/drivers/gpu/drm/i915/intel_dp.c b/trunk/drivers/gpu/drm/i915/intel_dp.c index 6b1c9a27c27a..f6299bb788e5 100644 --- a/trunk/drivers/gpu/drm/i915/intel_dp.c +++ b/trunk/drivers/gpu/drm/i915/intel_dp.c @@ -1392,8 +1392,6 @@ intel_dp_init(struct drm_device *dev, int output_reg) DRM_MODE_CONNECTOR_DisplayPort); drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); - connector->polled = DRM_CONNECTOR_POLL_HPD; - if (output_reg == DP_A) intel_encoder->type = INTEL_OUTPUT_EDP; else diff --git a/trunk/drivers/gpu/drm/i915/intel_drv.h b/trunk/drivers/gpu/drm/i915/intel_drv.h index df931f787665..3230e8d2ea43 100644 --- a/trunk/drivers/gpu/drm/i915/intel_drv.h +++ b/trunk/drivers/gpu/drm/i915/intel_drv.h @@ -235,5 +235,5 @@ extern int intel_overlay_put_image(struct drm_device *dev, void *data, extern int intel_overlay_attrs(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern void intel_fb_output_poll_changed(struct drm_device *dev); +void intelfb_hotplug(struct drm_device *dev, bool polled); #endif /* __INTEL_DRV_H__ */ diff --git a/trunk/drivers/gpu/drm/i915/intel_fb.c b/trunk/drivers/gpu/drm/i915/intel_fb.c index 6f53cf7fbc50..b04e0a86bf9a 100644 --- a/trunk/drivers/gpu/drm/i915/intel_fb.c +++ b/trunk/drivers/gpu/drm/i915/intel_fb.c @@ -128,16 +128,11 @@ static int intelfb_create(struct intel_fbdev *ifbdev, info->fbops = &intelfb_ops; /* setup aperture base/size for vesafb takeover */ - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto out_unpin; - } - info->apertures->ranges[0].base = dev->mode_config.fb_base; + info->aperture_base = dev->mode_config.fb_base; if (IS_I9XX(dev)) - info->apertures->ranges[0].size = pci_resource_len(dev->pdev, 2); + info->aperture_size = pci_resource_len(dev->pdev, 2); else - info->apertures->ranges[0].size = pci_resource_len(dev->pdev, 0); + info->aperture_size = pci_resource_len(dev->pdev, 0); info->fix.smem_start = dev->mode_config.fb_base + obj_priv->gtt_offset; info->fix.smem_len = size; @@ -207,6 +202,12 @@ static int intel_fb_find_or_create_single(struct drm_fb_helper *helper, return new_fb; } +void intelfb_hotplug(struct drm_device *dev, bool polled) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + drm_helper_fb_hpd_irq_event(&dev_priv->fbdev->helper); +} + static struct drm_fb_helper_funcs intel_fb_helper_funcs = { .gamma_set = intel_crtc_fb_gamma_set, .gamma_get = intel_crtc_fb_gamma_get, @@ -250,7 +251,7 @@ int intel_fbdev_init(struct drm_device *dev) ifbdev->helper.funcs = &intel_fb_helper_funcs; drm_fb_helper_init(dev, &ifbdev->helper, 2, - INTELFB_CONN_LIMIT); + INTELFB_CONN_LIMIT, false); drm_fb_helper_single_add_all_connectors(&ifbdev->helper); drm_fb_helper_initial_config(&ifbdev->helper, 32); @@ -268,9 +269,3 @@ void intel_fbdev_fini(struct drm_device *dev) dev_priv->fbdev = NULL; } MODULE_LICENSE("GPL and additional rights"); - -void intel_fb_output_poll_changed(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper); -} diff --git a/trunk/drivers/gpu/drm/i915/intel_hdmi.c b/trunk/drivers/gpu/drm/i915/intel_hdmi.c index 65727f0a79a3..8a1c4eddc030 100644 --- a/trunk/drivers/gpu/drm/i915/intel_hdmi.c +++ b/trunk/drivers/gpu/drm/i915/intel_hdmi.c @@ -237,7 +237,6 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) intel_encoder->type = INTEL_OUTPUT_HDMI; - connector->polled = DRM_CONNECTOR_POLL_HPD; connector->interlace_allowed = 0; connector->doublescan_allowed = 0; intel_encoder->crtc_mask = (1 << 0) | (1 << 1); diff --git a/trunk/drivers/gpu/drm/i915/intel_sdvo.c b/trunk/drivers/gpu/drm/i915/intel_sdvo.c index ca372abc36cd..42ceb15da689 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sdvo.c +++ b/trunk/drivers/gpu/drm/i915/intel_sdvo.c @@ -2244,7 +2244,6 @@ intel_sdvo_dvi_init(struct intel_encoder *intel_encoder, int device) } connector = &intel_connector->base; - connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; encoder->encoder_type = DRM_MODE_ENCODER_TMDS; connector->connector_type = DRM_MODE_CONNECTOR_DVID; @@ -2311,7 +2310,6 @@ intel_sdvo_analog_init(struct intel_encoder *intel_encoder, int device) return false; connector = &intel_connector->base; - connector->polled = DRM_CONNECTOR_POLL_CONNECT; encoder->encoder_type = DRM_MODE_ENCODER_DAC; connector->connector_type = DRM_MODE_CONNECTOR_VGA; sdvo_connector = intel_connector->dev_priv; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c b/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c index 7e663a79829f..14afe1e47e57 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -843,7 +843,6 @@ nouveau_connector_create(struct drm_device *dev, switch (dcb->type) { case DCB_CONNECTOR_VGA: - connector->polled = DRM_CONNECTOR_POLL_CONNECT; if (dev_priv->card_type >= NV_50) { drm_connector_attach_property(connector, dev->mode_config.scaling_mode_property, @@ -855,17 +854,6 @@ nouveau_connector_create(struct drm_device *dev, case DCB_CONNECTOR_TV_3: nv_connector->scaling_mode = DRM_MODE_SCALE_NONE; break; - case DCB_CONNECTOR_DP: - case DCB_CONNECTOR_eDP: - case DCB_CONNECTOR_HDMI_0: - case DCB_CONNECTOR_HDMI_1: - case DCB_CONNECTOR_DVI_I: - case DCB_CONNECTOR_DVI_D: - if (dev_priv->card_type >= NV_50) - connector->polled = DRM_CONNECTOR_POLL_HPD; - else - connector->polled = DRM_CONNECTOR_POLL_CONNECT; - /* fall-through */ default: nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_display.c b/trunk/drivers/gpu/drm/nouveau/nouveau_display.c index 74e6b4ed12c0..9d7928f40fdf 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_display.c @@ -101,6 +101,5 @@ nouveau_user_framebuffer_create(struct drm_device *dev, const struct drm_mode_config_funcs nouveau_mode_config_funcs = { .fb_create = nouveau_user_framebuffer_create, - .output_poll_changed = nouveau_fbcon_output_poll_changed, }; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_drv.h b/trunk/drivers/gpu/drm/nouveau/nouveau_drv.h index 94d8dd27bde8..5b47b79f45e8 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -624,7 +624,6 @@ struct drm_nouveau_private { } debugfs; struct nouveau_fbdev *nfbdev; - struct apertures_struct *apertures; }; static inline struct drm_nouveau_private * diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/trunk/drivers/gpu/drm/nouveau/nouveau_fbcon.c index fd4a2df715e9..f29fa8c117ce 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -152,6 +152,44 @@ static void nouveau_fbcon_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, *blue = nv_crtc->lut.b[regno]; } +#if defined(__i386__) || defined(__x86_64__) +static bool +nouveau_fbcon_has_vesafb_or_efifb(struct drm_device *dev) +{ + struct pci_dev *pdev = dev->pdev; + int ramin; + + if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB && + screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) + return false; + + if (screen_info.lfb_base < pci_resource_start(pdev, 1)) + goto not_fb; + + if (screen_info.lfb_base + screen_info.lfb_size >= + pci_resource_start(pdev, 1) + pci_resource_len(pdev, 1)) + goto not_fb; + + return true; +not_fb: + ramin = 2; + if (pci_resource_len(pdev, ramin) == 0) { + ramin = 3; + if (pci_resource_len(pdev, ramin) == 0) + return false; + } + + if (screen_info.lfb_base < pci_resource_start(pdev, ramin)) + return false; + + if (screen_info.lfb_base + screen_info.lfb_size >= + pci_resource_start(pdev, ramin) + pci_resource_len(pdev, ramin)) + return false; + + return true; +} +#endif + static void nouveau_fbcon_zfill(struct drm_device *dev, struct nouveau_fbdev *nfbdev) { @@ -181,8 +219,7 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev, struct nouveau_framebuffer *nouveau_fb; struct nouveau_bo *nvbo; struct drm_mode_fb_cmd mode_cmd; - struct pci_dev *pdev = dev->pdev; - struct device *device = &pdev->dev; + struct device *device = &dev->pdev->dev; int size, ret; mode_cmd.width = sizes->surface_width; @@ -262,14 +299,28 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev, drm_fb_helper_fill_var(info, &nfbdev->helper, sizes->fb_width, sizes->fb_height); /* FIXME: we really shouldn't expose mmio space at all */ - info->fix.mmio_start = pci_resource_start(pdev, 1); - info->fix.mmio_len = pci_resource_len(pdev, 1); + info->fix.mmio_start = pci_resource_start(dev->pdev, 1); + info->fix.mmio_len = pci_resource_len(dev->pdev, 1); /* Set aperture base/size for vesafb takeover */ - info->apertures = dev_priv->apertures; - if (!info->apertures) { - ret = -ENOMEM; - goto out_unref; +#if defined(__i386__) || defined(__x86_64__) + if (nouveau_fbcon_has_vesafb_or_efifb(dev)) { + /* Some NVIDIA VBIOS' are stupid and decide to put the + * framebuffer in the middle of the PRAMIN BAR for + * whatever reason. We need to know the exact lfb_base + * to get vesafb kicked off, and the only reliable way + * we have left is to find out lfb_base the same way + * vesafb did. + */ + info->aperture_base = screen_info.lfb_base; + info->aperture_size = screen_info.lfb_size; + if (screen_info.orig_video_isVGA == VIDEO_TYPE_VLFB) + info->aperture_size *= 65536; + } else +#endif + { + info->aperture_base = info->fix.mmio_start; + info->aperture_size = info->fix.mmio_len; } info->pixmap.size = 64*1024; @@ -326,11 +377,15 @@ nouveau_fbcon_find_or_create_single(struct drm_fb_helper *helper, return new_fb; } -void -nouveau_fbcon_output_poll_changed(struct drm_device *dev) +void nouveau_fbcon_hotplug(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - drm_fb_helper_hotplug_event(&dev_priv->nfbdev->helper); + drm_helper_fb_hpd_irq_event(&dev_priv->nfbdev->helper); +} + +static void nouveau_fbcon_output_status_changed(struct drm_fb_helper *fb_helper) +{ + drm_helper_fb_hotplug_event(fb_helper, true); } int @@ -370,6 +425,7 @@ static struct drm_fb_helper_funcs nouveau_fbcon_helper_funcs = { .gamma_set = nouveau_fbcon_gamma_set, .gamma_get = nouveau_fbcon_gamma_get, .fb_probe = nouveau_fbcon_find_or_create_single, + .fb_output_status_changed = nouveau_fbcon_output_status_changed, }; @@ -386,7 +442,8 @@ int nouveau_fbcon_init(struct drm_device *dev) dev_priv->nfbdev = nfbdev; nfbdev->helper.funcs = &nouveau_fbcon_helper_funcs; - drm_fb_helper_init(dev, &nfbdev->helper, 2, 4); + drm_fb_helper_init(dev, &nfbdev->helper, + 2, 4, true); drm_fb_helper_single_add_all_connectors(&nfbdev->helper); drm_fb_helper_initial_config(&nfbdev->helper, 32); return 0; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_fbcon.h b/trunk/drivers/gpu/drm/nouveau/nouveau_fbcon.h index e7e12684c37e..bf8e00d4de65 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_fbcon.h +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_fbcon.h @@ -58,6 +58,6 @@ void nouveau_fbcon_zfill_all(struct drm_device *dev); void nouveau_fbcon_save_disable_accel(struct drm_device *dev); void nouveau_fbcon_restore_accel(struct drm_device *dev); -void nouveau_fbcon_output_poll_changed(struct drm_device *dev); +void nouveau_fbcon_hotplug(struct drm_device *dev); #endif /* __NV50_FBCON_H__ */ diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_grctx.c b/trunk/drivers/gpu/drm/nouveau/nouveau_grctx.c index f731c5f60536..32f0e495464c 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_grctx.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_grctx.c @@ -68,12 +68,13 @@ nouveau_grctx_prog_load(struct drm_device *dev) return ret; } - pgraph->ctxprog = kmemdup(fw->data, fw->size, GFP_KERNEL); + pgraph->ctxprog = kmalloc(fw->size, GFP_KERNEL); if (!pgraph->ctxprog) { NV_ERROR(dev, "OOM copying ctxprog\n"); release_firmware(fw); return -ENOMEM; } + memcpy(pgraph->ctxprog, fw->data, fw->size); cp = pgraph->ctxprog; if (le32_to_cpu(cp->signature) != 0x5043564e || @@ -96,13 +97,14 @@ nouveau_grctx_prog_load(struct drm_device *dev) return ret; } - pgraph->ctxvals = kmemdup(fw->data, fw->size, GFP_KERNEL); + pgraph->ctxvals = kmalloc(fw->size, GFP_KERNEL); if (!pgraph->ctxvals) { NV_ERROR(dev, "OOM copying ctxvals\n"); release_firmware(fw); nouveau_grctx_fini(dev); return -ENOMEM; } + memcpy(pgraph->ctxvals, fw->data, fw->size); cv = (void *)pgraph->ctxvals; if (le32_to_cpu(cv->signature) != 0x5643564e || diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_state.c b/trunk/drivers/gpu/drm/nouveau/nouveau_state.c index e632339c323e..92100a9678ba 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_state.c @@ -516,10 +516,8 @@ nouveau_card_init(struct drm_device *dev) dev_priv->init_state = NOUVEAU_CARD_INIT_DONE; - if (drm_core_check_feature(dev, DRIVER_MODESET)) { + if (drm_core_check_feature(dev, DRIVER_MODESET)) nouveau_fbcon_init(dev); - drm_kms_helper_poll_init(dev); - } return 0; @@ -641,48 +639,6 @@ static void nouveau_OF_copy_vbios_to_ramin(struct drm_device *dev) #endif } -static struct apertures_struct *nouveau_get_apertures(struct drm_device *dev) -{ - struct pci_dev *pdev = dev->pdev; - struct apertures_struct *aper = alloc_apertures(3); - if (!aper) - return NULL; - - aper->ranges[0].base = pci_resource_start(pdev, 1); - aper->ranges[0].size = pci_resource_len(pdev, 1); - aper->count = 1; - - if (pci_resource_len(pdev, 2)) { - aper->ranges[aper->count].base = pci_resource_start(pdev, 2); - aper->ranges[aper->count].size = pci_resource_len(pdev, 2); - aper->count++; - } - - if (pci_resource_len(pdev, 3)) { - aper->ranges[aper->count].base = pci_resource_start(pdev, 3); - aper->ranges[aper->count].size = pci_resource_len(pdev, 3); - aper->count++; - } - - return aper; -} - -static int nouveau_remove_conflicting_drivers(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - bool primary = false; - dev_priv->apertures = nouveau_get_apertures(dev); - if (!dev_priv->apertures) - return -ENOMEM; - -#ifdef CONFIG_X86 - primary = dev->pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; -#endif - - remove_conflicting_framebuffers(dev_priv->apertures, "nouveaufb", primary); - return 0; -} - int nouveau_load(struct drm_device *dev, unsigned long flags) { struct drm_nouveau_private *dev_priv; @@ -770,12 +726,6 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) NV_INFO(dev, "Detected an NV%2x generation card (0x%08x)\n", dev_priv->card_type, reg0); - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - int ret = nouveau_remove_conflicting_drivers(dev); - if (ret) - return ret; - } - /* map larger RAMIN aperture on NV40 cards */ dev_priv->ramin = NULL; if (dev_priv->card_type >= NV_40) { @@ -846,7 +796,6 @@ int nouveau_unload(struct drm_device *dev) struct drm_nouveau_private *dev_priv = dev->dev_private; if (drm_core_check_feature(dev, DRIVER_MODESET)) { - drm_kms_helper_poll_fini(dev); nouveau_fbcon_fini(dev); if (dev_priv->card_type >= NV_50) nv50_display_destroy(dev); diff --git a/trunk/drivers/gpu/drm/nouveau/nv50_display.c b/trunk/drivers/gpu/drm/nouveau/nv50_display.c index 34156b69594f..f9b304866e66 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv50_display.c +++ b/trunk/drivers/gpu/drm/nouveau/nv50_display.c @@ -947,7 +947,7 @@ nv50_display_irq_hotplug_bh(struct work_struct *work) if (dev_priv->chipset >= 0x90) nv_wr32(dev, 0xe074, nv_rd32(dev, 0xe074)); - drm_helper_hpd_irq_event(dev); + nouveau_fbcon_hotplug(dev); } void diff --git a/trunk/drivers/gpu/drm/radeon/Kconfig b/trunk/drivers/gpu/drm/radeon/Kconfig index 80c5b3ea28b4..1c02d23f6fcc 100644 --- a/trunk/drivers/gpu/drm/radeon/Kconfig +++ b/trunk/drivers/gpu/drm/radeon/Kconfig @@ -1,7 +1,6 @@ config DRM_RADEON_KMS bool "Enable modesetting on radeon by default - NEW DRIVER" depends on DRM_RADEON - depends on POWER_SUPPLY help Choose this option if you want kernel modesetting enabled by default. diff --git a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c index 03dd6c41dc19..3feca6aec4c4 100644 --- a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include "radeon_fixed.h" #include "radeon.h" #include "atom.h" #include "atom-bits.h" @@ -245,9 +245,6 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) switch (mode) { case DRM_MODE_DPMS_ON: - radeon_crtc->enabled = true; - /* adjust pm to dpms changes BEFORE enabling crtcs */ - radeon_pm_compute_clocks(rdev); atombios_enable_crtc(crtc, ATOM_ENABLE); if (ASIC_IS_DCE3(rdev)) atombios_enable_crtc_memreq(crtc, ATOM_ENABLE); @@ -263,9 +260,6 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) if (ASIC_IS_DCE3(rdev)) atombios_enable_crtc_memreq(crtc, ATOM_DISABLE); atombios_enable_crtc(crtc, ATOM_DISABLE); - radeon_crtc->enabled = false; - /* adjust pm to dpms changes AFTER disabling crtcs */ - radeon_pm_compute_clocks(rdev); break; } } @@ -1162,12 +1156,6 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - - /* adjust pm to upcoming mode change */ - radeon_pm_compute_clocks(rdev); - if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode)) return false; return true; diff --git a/trunk/drivers/gpu/drm/radeon/evergreen.c b/trunk/drivers/gpu/drm/radeon/evergreen.c index 8c8e4d3cbaa3..b3d168fb89e5 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen.c @@ -39,47 +39,6 @@ static void evergreen_gpu_init(struct radeon_device *rdev); void evergreen_fini(struct radeon_device *rdev); -void evergreen_pm_misc(struct radeon_device *rdev) -{ - -} - -void evergreen_pm_prepare(struct radeon_device *rdev) -{ - struct drm_device *ddev = rdev->ddev; - struct drm_crtc *crtc; - struct radeon_crtc *radeon_crtc; - u32 tmp; - - /* disable any active CRTCs */ - list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) { - radeon_crtc = to_radeon_crtc(crtc); - if (radeon_crtc->enabled) { - tmp = RREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset); - tmp |= EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE; - WREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset, tmp); - } - } -} - -void evergreen_pm_finish(struct radeon_device *rdev) -{ - struct drm_device *ddev = rdev->ddev; - struct drm_crtc *crtc; - struct radeon_crtc *radeon_crtc; - u32 tmp; - - /* enable any active CRTCs */ - list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) { - radeon_crtc = to_radeon_crtc(crtc); - if (radeon_crtc->enabled) { - tmp = RREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset); - tmp &= ~EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE; - WREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset, tmp); - } - } -} - bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) { bool connected = false; @@ -1459,7 +1418,6 @@ int evergreen_irq_set(struct radeon_device *rdev) u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0; u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6; - u32 grbm_int_cntl = 0; if (!rdev->irq.installed) { WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n"); @@ -1532,13 +1490,8 @@ int evergreen_irq_set(struct radeon_device *rdev) DRM_DEBUG("evergreen_irq_set: hpd 6\n"); hpd6 |= DC_HPDx_INT_EN; } - if (rdev->irq.gui_idle) { - DRM_DEBUG("gui idle\n"); - grbm_int_cntl |= GUI_IDLE_INT_ENABLE; - } WREG32(CP_INT_CNTL, cp_int_cntl); - WREG32(GRBM_INT_CNTL, grbm_int_cntl); WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2); @@ -1900,11 +1853,6 @@ int evergreen_irq_process(struct radeon_device *rdev) case 181: /* CP EOP event */ DRM_DEBUG("IH: CP EOP\n"); break; - case 233: /* GUI IDLE */ - DRM_DEBUG("IH: CP EOP\n"); - rdev->pm.gui_idle = true; - wake_up(&rdev->irq.idle_queue); - break; default: DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); break; @@ -2115,6 +2063,8 @@ int evergreen_init(struct radeon_device *rdev) r = radeon_clocks_init(rdev); if (r) return r; + /* Initialize power management */ + radeon_pm_init(rdev); /* Fence driver */ r = radeon_fence_driver_init(rdev); if (r) @@ -2176,6 +2126,7 @@ int evergreen_init(struct radeon_device *rdev) void evergreen_fini(struct radeon_device *rdev) { + radeon_pm_fini(rdev); /*r600_blit_fini(rdev);*/ r700_cp_fini(rdev); r600_wb_fini(rdev); diff --git a/trunk/drivers/gpu/drm/radeon/evergreen_reg.h b/trunk/drivers/gpu/drm/radeon/evergreen_reg.h index af86af836f13..f7c7c9643433 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen_reg.h +++ b/trunk/drivers/gpu/drm/radeon/evergreen_reg.h @@ -164,12 +164,8 @@ #define EVERGREEN_CRTC5_REGISTER_OFFSET (0x129f0 - 0x6df0) /* CRTC blocks at 0x6df0, 0x79f0, 0x105f0, 0x111f0, 0x11df0, 0x129f0 */ -#define EVERGREEN_CRTC_V_BLANK_START_END 0x6e34 #define EVERGREEN_CRTC_CONTROL 0x6e70 # define EVERGREEN_CRTC_MASTER_EN (1 << 0) -# define EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE (1 << 24) -#define EVERGREEN_CRTC_STATUS 0x6e8c -#define EVERGREEN_CRTC_STATUS_POSITION 0x6e90 #define EVERGREEN_CRTC_UPDATE_LOCK 0x6ed4 #define EVERGREEN_DC_GPIO_HPD_MASK 0x64b0 diff --git a/trunk/drivers/gpu/drm/radeon/r100.c b/trunk/drivers/gpu/drm/radeon/r100.c index 9a59ba46f078..9bdccb964999 100644 --- a/trunk/drivers/gpu/drm/radeon/r100.c +++ b/trunk/drivers/gpu/drm/radeon/r100.c @@ -37,7 +37,6 @@ #include "rs100d.h" #include "rv200d.h" #include "rv250d.h" -#include "atom.h" #include #include @@ -68,264 +67,6 @@ MODULE_FIRMWARE(FIRMWARE_R520); * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */ -void r100_pm_get_dynpm_state(struct radeon_device *rdev) -{ - int i; - rdev->pm.dynpm_can_upclock = true; - rdev->pm.dynpm_can_downclock = true; - - switch (rdev->pm.dynpm_planned_action) { - case DYNPM_ACTION_MINIMUM: - rdev->pm.requested_power_state_index = 0; - rdev->pm.dynpm_can_downclock = false; - break; - case DYNPM_ACTION_DOWNCLOCK: - if (rdev->pm.current_power_state_index == 0) { - rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index; - rdev->pm.dynpm_can_downclock = false; - } else { - if (rdev->pm.active_crtc_count > 1) { - for (i = 0; i < rdev->pm.num_power_states; i++) { - if (rdev->pm.power_state[i].flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY) - continue; - else if (i >= rdev->pm.current_power_state_index) { - rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index; - break; - } else { - rdev->pm.requested_power_state_index = i; - break; - } - } - } else - rdev->pm.requested_power_state_index = - rdev->pm.current_power_state_index - 1; - } - /* don't use the power state if crtcs are active and no display flag is set */ - if ((rdev->pm.active_crtc_count > 0) && - (rdev->pm.power_state[rdev->pm.requested_power_state_index].clock_info[0].flags & - RADEON_PM_MODE_NO_DISPLAY)) { - rdev->pm.requested_power_state_index++; - } - break; - case DYNPM_ACTION_UPCLOCK: - if (rdev->pm.current_power_state_index == (rdev->pm.num_power_states - 1)) { - rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index; - rdev->pm.dynpm_can_upclock = false; - } else { - if (rdev->pm.active_crtc_count > 1) { - for (i = (rdev->pm.num_power_states - 1); i >= 0; i--) { - if (rdev->pm.power_state[i].flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY) - continue; - else if (i <= rdev->pm.current_power_state_index) { - rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index; - break; - } else { - rdev->pm.requested_power_state_index = i; - break; - } - } - } else - rdev->pm.requested_power_state_index = - rdev->pm.current_power_state_index + 1; - } - break; - case DYNPM_ACTION_DEFAULT: - rdev->pm.requested_power_state_index = rdev->pm.default_power_state_index; - rdev->pm.dynpm_can_upclock = false; - break; - case DYNPM_ACTION_NONE: - default: - DRM_ERROR("Requested mode for not defined action\n"); - return; - } - /* only one clock mode per power state */ - rdev->pm.requested_clock_mode_index = 0; - - DRM_DEBUG("Requested: e: %d m: %d p: %d\n", - rdev->pm.power_state[rdev->pm.requested_power_state_index]. - clock_info[rdev->pm.requested_clock_mode_index].sclk, - rdev->pm.power_state[rdev->pm.requested_power_state_index]. - clock_info[rdev->pm.requested_clock_mode_index].mclk, - rdev->pm.power_state[rdev->pm.requested_power_state_index]. - pcie_lanes); -} - -void r100_pm_init_profile(struct radeon_device *rdev) -{ - /* default */ - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0; - /* low sh */ - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; - /* high sh */ - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 0; - /* low mh */ - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; - /* high mh */ - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 0; -} - -void r100_pm_misc(struct radeon_device *rdev) -{ - int requested_index = rdev->pm.requested_power_state_index; - struct radeon_power_state *ps = &rdev->pm.power_state[requested_index]; - struct radeon_voltage *voltage = &ps->clock_info[0].voltage; - u32 tmp, sclk_cntl, sclk_cntl2, sclk_more_cntl; - - if ((voltage->type == VOLTAGE_GPIO) && (voltage->gpio.valid)) { - if (ps->misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) { - tmp = RREG32(voltage->gpio.reg); - if (voltage->active_high) - tmp |= voltage->gpio.mask; - else - tmp &= ~(voltage->gpio.mask); - WREG32(voltage->gpio.reg, tmp); - if (voltage->delay) - udelay(voltage->delay); - } else { - tmp = RREG32(voltage->gpio.reg); - if (voltage->active_high) - tmp &= ~voltage->gpio.mask; - else - tmp |= voltage->gpio.mask; - WREG32(voltage->gpio.reg, tmp); - if (voltage->delay) - udelay(voltage->delay); - } - } - - sclk_cntl = RREG32_PLL(SCLK_CNTL); - sclk_cntl2 = RREG32_PLL(SCLK_CNTL2); - sclk_cntl2 &= ~REDUCED_SPEED_SCLK_SEL(3); - sclk_more_cntl = RREG32_PLL(SCLK_MORE_CNTL); - sclk_more_cntl &= ~VOLTAGE_DELAY_SEL(3); - if (ps->misc & ATOM_PM_MISCINFO_ASIC_REDUCED_SPEED_SCLK_EN) { - sclk_more_cntl |= REDUCED_SPEED_SCLK_EN; - if (ps->misc & ATOM_PM_MISCINFO_DYN_CLK_3D_IDLE) - sclk_cntl2 |= REDUCED_SPEED_SCLK_MODE; - else - sclk_cntl2 &= ~REDUCED_SPEED_SCLK_MODE; - if (ps->misc & ATOM_PM_MISCINFO_DYNAMIC_CLOCK_DIVIDER_BY_2) - sclk_cntl2 |= REDUCED_SPEED_SCLK_SEL(0); - else if (ps->misc & ATOM_PM_MISCINFO_DYNAMIC_CLOCK_DIVIDER_BY_4) - sclk_cntl2 |= REDUCED_SPEED_SCLK_SEL(2); - } else - sclk_more_cntl &= ~REDUCED_SPEED_SCLK_EN; - - if (ps->misc & ATOM_PM_MISCINFO_ASIC_DYNAMIC_VOLTAGE_EN) { - sclk_more_cntl |= IO_CG_VOLTAGE_DROP; - if (voltage->delay) { - sclk_more_cntl |= VOLTAGE_DROP_SYNC; - switch (voltage->delay) { - case 33: - sclk_more_cntl |= VOLTAGE_DELAY_SEL(0); - break; - case 66: - sclk_more_cntl |= VOLTAGE_DELAY_SEL(1); - break; - case 99: - sclk_more_cntl |= VOLTAGE_DELAY_SEL(2); - break; - case 132: - sclk_more_cntl |= VOLTAGE_DELAY_SEL(3); - break; - } - } else - sclk_more_cntl &= ~VOLTAGE_DROP_SYNC; - } else - sclk_more_cntl &= ~IO_CG_VOLTAGE_DROP; - - if (ps->misc & ATOM_PM_MISCINFO_DYNAMIC_HDP_BLOCK_EN) - sclk_cntl &= ~FORCE_HDP; - else - sclk_cntl |= FORCE_HDP; - - WREG32_PLL(SCLK_CNTL, sclk_cntl); - WREG32_PLL(SCLK_CNTL2, sclk_cntl2); - WREG32_PLL(SCLK_MORE_CNTL, sclk_more_cntl); - - /* set pcie lanes */ - if ((rdev->flags & RADEON_IS_PCIE) && - !(rdev->flags & RADEON_IS_IGP) && - rdev->asic->set_pcie_lanes && - (ps->pcie_lanes != - rdev->pm.power_state[rdev->pm.current_power_state_index].pcie_lanes)) { - radeon_set_pcie_lanes(rdev, - ps->pcie_lanes); - DRM_DEBUG("Setting: p: %d\n", ps->pcie_lanes); - } -} - -void r100_pm_prepare(struct radeon_device *rdev) -{ - struct drm_device *ddev = rdev->ddev; - struct drm_crtc *crtc; - struct radeon_crtc *radeon_crtc; - u32 tmp; - - /* disable any active CRTCs */ - list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) { - radeon_crtc = to_radeon_crtc(crtc); - if (radeon_crtc->enabled) { - if (radeon_crtc->crtc_id) { - tmp = RREG32(RADEON_CRTC2_GEN_CNTL); - tmp |= RADEON_CRTC2_DISP_REQ_EN_B; - WREG32(RADEON_CRTC2_GEN_CNTL, tmp); - } else { - tmp = RREG32(RADEON_CRTC_GEN_CNTL); - tmp |= RADEON_CRTC_DISP_REQ_EN_B; - WREG32(RADEON_CRTC_GEN_CNTL, tmp); - } - } - } -} - -void r100_pm_finish(struct radeon_device *rdev) -{ - struct drm_device *ddev = rdev->ddev; - struct drm_crtc *crtc; - struct radeon_crtc *radeon_crtc; - u32 tmp; - - /* enable any active CRTCs */ - list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) { - radeon_crtc = to_radeon_crtc(crtc); - if (radeon_crtc->enabled) { - if (radeon_crtc->crtc_id) { - tmp = RREG32(RADEON_CRTC2_GEN_CNTL); - tmp &= ~RADEON_CRTC2_DISP_REQ_EN_B; - WREG32(RADEON_CRTC2_GEN_CNTL, tmp); - } else { - tmp = RREG32(RADEON_CRTC_GEN_CNTL); - tmp &= ~RADEON_CRTC_DISP_REQ_EN_B; - WREG32(RADEON_CRTC_GEN_CNTL, tmp); - } - } - } -} - -bool r100_gui_idle(struct radeon_device *rdev) -{ - if (RREG32(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE) - return false; - else - return true; -} - /* hpd for digital panel detect/disconnect */ bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) { @@ -513,9 +254,6 @@ int r100_irq_set(struct radeon_device *rdev) if (rdev->irq.sw_int) { tmp |= RADEON_SW_INT_ENABLE; } - if (rdev->irq.gui_idle) { - tmp |= RADEON_GUI_IDLE_MASK; - } if (rdev->irq.crtc_vblank_int[0]) { tmp |= RADEON_CRTC_VBLANK_MASK; } @@ -550,12 +288,6 @@ static inline uint32_t r100_irq_ack(struct radeon_device *rdev) RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT | RADEON_FP_DETECT_STAT | RADEON_FP2_DETECT_STAT; - /* the interrupt works, but the status bit is permanently asserted */ - if (rdev->irq.gui_idle && radeon_gui_idle(rdev)) { - if (!rdev->irq.gui_idle_acked) - irq_mask |= RADEON_GUI_IDLE_STAT; - } - if (irqs) { WREG32(RADEON_GEN_INT_STATUS, irqs); } @@ -567,9 +299,6 @@ int r100_irq_process(struct radeon_device *rdev) uint32_t status, msi_rearm; bool queue_hotplug = false; - /* reset gui idle ack. the status bit is broken */ - rdev->irq.gui_idle_acked = false; - status = r100_irq_ack(rdev); if (!status) { return IRQ_NONE; @@ -582,12 +311,6 @@ int r100_irq_process(struct radeon_device *rdev) if (status & RADEON_SW_INT_TEST) { radeon_fence_process(rdev); } - /* gui idle interrupt */ - if (status & RADEON_GUI_IDLE_STAT) { - rdev->irq.gui_idle_acked = true; - rdev->pm.gui_idle = true; - wake_up(&rdev->irq.idle_queue); - } /* Vertical blank interrupts */ if (status & RADEON_CRTC_VBLANK_STAT) { drm_handle_vblank(rdev->ddev, 0); @@ -609,8 +332,6 @@ int r100_irq_process(struct radeon_device *rdev) } status = r100_irq_ack(rdev); } - /* reset gui idle ack. the status bit is broken */ - rdev->irq.gui_idle_acked = false; if (queue_hotplug) queue_work(rdev->wq, &rdev->hotplug_work); if (rdev->msi_enabled) { @@ -2643,53 +2364,53 @@ void r100_bandwidth_update(struct radeon_device *rdev) fixed20_12 peak_disp_bw, mem_bw, pix_clk, pix_clk2, temp_ff, crit_point_ff; uint32_t temp, data, mem_trcd, mem_trp, mem_tras; fixed20_12 memtcas_ff[8] = { - dfixed_init(1), - dfixed_init(2), - dfixed_init(3), - dfixed_init(0), - dfixed_init_half(1), - dfixed_init_half(2), - dfixed_init(0), + fixed_init(1), + fixed_init(2), + fixed_init(3), + fixed_init(0), + fixed_init_half(1), + fixed_init_half(2), + fixed_init(0), }; fixed20_12 memtcas_rs480_ff[8] = { - dfixed_init(0), - dfixed_init(1), - dfixed_init(2), - dfixed_init(3), - dfixed_init(0), - dfixed_init_half(1), - dfixed_init_half(2), - dfixed_init_half(3), + fixed_init(0), + fixed_init(1), + fixed_init(2), + fixed_init(3), + fixed_init(0), + fixed_init_half(1), + fixed_init_half(2), + fixed_init_half(3), }; fixed20_12 memtcas2_ff[8] = { - dfixed_init(0), - dfixed_init(1), - dfixed_init(2), - dfixed_init(3), - dfixed_init(4), - dfixed_init(5), - dfixed_init(6), - dfixed_init(7), + fixed_init(0), + fixed_init(1), + fixed_init(2), + fixed_init(3), + fixed_init(4), + fixed_init(5), + fixed_init(6), + fixed_init(7), }; fixed20_12 memtrbs[8] = { - dfixed_init(1), - dfixed_init_half(1), - dfixed_init(2), - dfixed_init_half(2), - dfixed_init(3), - dfixed_init_half(3), - dfixed_init(4), - dfixed_init_half(4) + fixed_init(1), + fixed_init_half(1), + fixed_init(2), + fixed_init_half(2), + fixed_init(3), + fixed_init_half(3), + fixed_init(4), + fixed_init_half(4) }; fixed20_12 memtrbs_r4xx[8] = { - dfixed_init(4), - dfixed_init(5), - dfixed_init(6), - dfixed_init(7), - dfixed_init(8), - dfixed_init(9), - dfixed_init(10), - dfixed_init(11) + fixed_init(4), + fixed_init(5), + fixed_init(6), + fixed_init(7), + fixed_init(8), + fixed_init(9), + fixed_init(10), + fixed_init(11) }; fixed20_12 min_mem_eff; fixed20_12 mc_latency_sclk, mc_latency_mclk, k1; @@ -2720,7 +2441,7 @@ void r100_bandwidth_update(struct radeon_device *rdev) } } - min_mem_eff.full = dfixed_const_8(0); + min_mem_eff.full = rfixed_const_8(0); /* get modes */ if ((rdev->disp_priority == 2) && ASIC_IS_R300(rdev)) { uint32_t mc_init_misc_lat_timer = RREG32(R300_MC_INIT_MISC_LAT_TIMER); @@ -2741,28 +2462,28 @@ void r100_bandwidth_update(struct radeon_device *rdev) mclk_ff = rdev->pm.mclk; temp = (rdev->mc.vram_width / 8) * (rdev->mc.vram_is_ddr ? 2 : 1); - temp_ff.full = dfixed_const(temp); - mem_bw.full = dfixed_mul(mclk_ff, temp_ff); + temp_ff.full = rfixed_const(temp); + mem_bw.full = rfixed_mul(mclk_ff, temp_ff); pix_clk.full = 0; pix_clk2.full = 0; peak_disp_bw.full = 0; if (mode1) { - temp_ff.full = dfixed_const(1000); - pix_clk.full = dfixed_const(mode1->clock); /* convert to fixed point */ - pix_clk.full = dfixed_div(pix_clk, temp_ff); - temp_ff.full = dfixed_const(pixel_bytes1); - peak_disp_bw.full += dfixed_mul(pix_clk, temp_ff); + temp_ff.full = rfixed_const(1000); + pix_clk.full = rfixed_const(mode1->clock); /* convert to fixed point */ + pix_clk.full = rfixed_div(pix_clk, temp_ff); + temp_ff.full = rfixed_const(pixel_bytes1); + peak_disp_bw.full += rfixed_mul(pix_clk, temp_ff); } if (mode2) { - temp_ff.full = dfixed_const(1000); - pix_clk2.full = dfixed_const(mode2->clock); /* convert to fixed point */ - pix_clk2.full = dfixed_div(pix_clk2, temp_ff); - temp_ff.full = dfixed_const(pixel_bytes2); - peak_disp_bw.full += dfixed_mul(pix_clk2, temp_ff); + temp_ff.full = rfixed_const(1000); + pix_clk2.full = rfixed_const(mode2->clock); /* convert to fixed point */ + pix_clk2.full = rfixed_div(pix_clk2, temp_ff); + temp_ff.full = rfixed_const(pixel_bytes2); + peak_disp_bw.full += rfixed_mul(pix_clk2, temp_ff); } - mem_bw.full = dfixed_mul(mem_bw, min_mem_eff); + mem_bw.full = rfixed_mul(mem_bw, min_mem_eff); if (peak_disp_bw.full >= mem_bw.full) { DRM_ERROR("You may not have enough display bandwidth for current mode\n" "If you have flickering problem, try to lower resolution, refresh rate, or color depth\n"); @@ -2804,9 +2525,9 @@ void r100_bandwidth_update(struct radeon_device *rdev) mem_tras = ((temp >> 12) & 0xf) + 4; } /* convert to FF */ - trcd_ff.full = dfixed_const(mem_trcd); - trp_ff.full = dfixed_const(mem_trp); - tras_ff.full = dfixed_const(mem_tras); + trcd_ff.full = rfixed_const(mem_trcd); + trp_ff.full = rfixed_const(mem_trp); + tras_ff.full = rfixed_const(mem_tras); /* Get values from the MEM_SDRAM_MODE_REG register...converting its */ temp = RREG32(RADEON_MEM_SDRAM_MODE_REG); @@ -2824,7 +2545,7 @@ void r100_bandwidth_update(struct radeon_device *rdev) /* extra cas latency stored in bits 23-25 0-4 clocks */ data = (temp >> 23) & 0x7; if (data < 5) - tcas_ff.full += dfixed_const(data); + tcas_ff.full += rfixed_const(data); } if (ASIC_IS_R300(rdev) && !(rdev->flags & RADEON_IS_IGP)) { @@ -2861,72 +2582,72 @@ void r100_bandwidth_update(struct radeon_device *rdev) if (rdev->flags & RADEON_IS_AGP) { fixed20_12 agpmode_ff; - agpmode_ff.full = dfixed_const(radeon_agpmode); - temp_ff.full = dfixed_const_666(16); - sclk_eff_ff.full -= dfixed_mul(agpmode_ff, temp_ff); + agpmode_ff.full = rfixed_const(radeon_agpmode); + temp_ff.full = rfixed_const_666(16); + sclk_eff_ff.full -= rfixed_mul(agpmode_ff, temp_ff); } /* TODO PCIE lanes may affect this - agpmode == 16?? */ if (ASIC_IS_R300(rdev)) { - sclk_delay_ff.full = dfixed_const(250); + sclk_delay_ff.full = rfixed_const(250); } else { if ((rdev->family == CHIP_RV100) || rdev->flags & RADEON_IS_IGP) { if (rdev->mc.vram_is_ddr) - sclk_delay_ff.full = dfixed_const(41); + sclk_delay_ff.full = rfixed_const(41); else - sclk_delay_ff.full = dfixed_const(33); + sclk_delay_ff.full = rfixed_const(33); } else { if (rdev->mc.vram_width == 128) - sclk_delay_ff.full = dfixed_const(57); + sclk_delay_ff.full = rfixed_const(57); else - sclk_delay_ff.full = dfixed_const(41); + sclk_delay_ff.full = rfixed_const(41); } } - mc_latency_sclk.full = dfixed_div(sclk_delay_ff, sclk_eff_ff); + mc_latency_sclk.full = rfixed_div(sclk_delay_ff, sclk_eff_ff); if (rdev->mc.vram_is_ddr) { if (rdev->mc.vram_width == 32) { - k1.full = dfixed_const(40); + k1.full = rfixed_const(40); c = 3; } else { - k1.full = dfixed_const(20); + k1.full = rfixed_const(20); c = 1; } } else { - k1.full = dfixed_const(40); + k1.full = rfixed_const(40); c = 3; } - temp_ff.full = dfixed_const(2); - mc_latency_mclk.full = dfixed_mul(trcd_ff, temp_ff); - temp_ff.full = dfixed_const(c); - mc_latency_mclk.full += dfixed_mul(tcas_ff, temp_ff); - temp_ff.full = dfixed_const(4); - mc_latency_mclk.full += dfixed_mul(tras_ff, temp_ff); - mc_latency_mclk.full += dfixed_mul(trp_ff, temp_ff); + temp_ff.full = rfixed_const(2); + mc_latency_mclk.full = rfixed_mul(trcd_ff, temp_ff); + temp_ff.full = rfixed_const(c); + mc_latency_mclk.full += rfixed_mul(tcas_ff, temp_ff); + temp_ff.full = rfixed_const(4); + mc_latency_mclk.full += rfixed_mul(tras_ff, temp_ff); + mc_latency_mclk.full += rfixed_mul(trp_ff, temp_ff); mc_latency_mclk.full += k1.full; - mc_latency_mclk.full = dfixed_div(mc_latency_mclk, mclk_ff); - mc_latency_mclk.full += dfixed_div(temp_ff, sclk_eff_ff); + mc_latency_mclk.full = rfixed_div(mc_latency_mclk, mclk_ff); + mc_latency_mclk.full += rfixed_div(temp_ff, sclk_eff_ff); /* HW cursor time assuming worst case of full size colour cursor. */ - temp_ff.full = dfixed_const((2 * (cur_size - (rdev->mc.vram_is_ddr + 1)))); + temp_ff.full = rfixed_const((2 * (cur_size - (rdev->mc.vram_is_ddr + 1)))); temp_ff.full += trcd_ff.full; if (temp_ff.full < tras_ff.full) temp_ff.full = tras_ff.full; - cur_latency_mclk.full = dfixed_div(temp_ff, mclk_ff); + cur_latency_mclk.full = rfixed_div(temp_ff, mclk_ff); - temp_ff.full = dfixed_const(cur_size); - cur_latency_sclk.full = dfixed_div(temp_ff, sclk_eff_ff); + temp_ff.full = rfixed_const(cur_size); + cur_latency_sclk.full = rfixed_div(temp_ff, sclk_eff_ff); /* Find the total latency for the display data. */ - disp_latency_overhead.full = dfixed_const(8); - disp_latency_overhead.full = dfixed_div(disp_latency_overhead, sclk_ff); + disp_latency_overhead.full = rfixed_const(8); + disp_latency_overhead.full = rfixed_div(disp_latency_overhead, sclk_ff); mc_latency_mclk.full += disp_latency_overhead.full + cur_latency_mclk.full; mc_latency_sclk.full += disp_latency_overhead.full + cur_latency_sclk.full; @@ -2954,16 +2675,16 @@ void r100_bandwidth_update(struct radeon_device *rdev) /* Find the drain rate of the display buffer. */ - temp_ff.full = dfixed_const((16/pixel_bytes1)); - disp_drain_rate.full = dfixed_div(pix_clk, temp_ff); + temp_ff.full = rfixed_const((16/pixel_bytes1)); + disp_drain_rate.full = rfixed_div(pix_clk, temp_ff); /* Find the critical point of the display buffer. */ - crit_point_ff.full = dfixed_mul(disp_drain_rate, disp_latency); - crit_point_ff.full += dfixed_const_half(0); + crit_point_ff.full = rfixed_mul(disp_drain_rate, disp_latency); + crit_point_ff.full += rfixed_const_half(0); - critical_point = dfixed_trunc(crit_point_ff); + critical_point = rfixed_trunc(crit_point_ff); if (rdev->disp_priority == 2) { critical_point = 0; @@ -3034,8 +2755,8 @@ void r100_bandwidth_update(struct radeon_device *rdev) /* Find the drain rate of the display buffer. */ - temp_ff.full = dfixed_const((16/pixel_bytes2)); - disp_drain_rate2.full = dfixed_div(pix_clk2, temp_ff); + temp_ff.full = rfixed_const((16/pixel_bytes2)); + disp_drain_rate2.full = rfixed_div(pix_clk2, temp_ff); grph2_cntl = RREG32(RADEON_GRPH2_BUFFER_CNTL); grph2_cntl &= ~(RADEON_GRPH_STOP_REQ_MASK); @@ -3056,8 +2777,8 @@ void r100_bandwidth_update(struct radeon_device *rdev) critical_point2 = 0; else { temp = (rdev->mc.vram_width * rdev->mc.vram_is_ddr + 1)/128; - temp_ff.full = dfixed_const(temp); - temp_ff.full = dfixed_mul(mclk_ff, temp_ff); + temp_ff.full = rfixed_const(temp); + temp_ff.full = rfixed_mul(mclk_ff, temp_ff); if (sclk_ff.full < temp_ff.full) temp_ff.full = sclk_ff.full; @@ -3065,15 +2786,15 @@ void r100_bandwidth_update(struct radeon_device *rdev) if (mode1) { temp_ff.full = read_return_rate.full - disp_drain_rate.full; - time_disp1_drop_priority.full = dfixed_div(crit_point_ff, temp_ff); + time_disp1_drop_priority.full = rfixed_div(crit_point_ff, temp_ff); } else { time_disp1_drop_priority.full = 0; } crit_point_ff.full = disp_latency.full + time_disp1_drop_priority.full + disp_latency.full; - crit_point_ff.full = dfixed_mul(crit_point_ff, disp_drain_rate2); - crit_point_ff.full += dfixed_const_half(0); + crit_point_ff.full = rfixed_mul(crit_point_ff, disp_drain_rate2); + crit_point_ff.full += rfixed_const_half(0); - critical_point2 = dfixed_trunc(crit_point_ff); + critical_point2 = rfixed_trunc(crit_point_ff); if (rdev->disp_priority == 2) { critical_point2 = 0; @@ -3770,6 +3491,7 @@ int r100_suspend(struct radeon_device *rdev) void r100_fini(struct radeon_device *rdev) { + radeon_pm_fini(rdev); r100_cp_fini(rdev); r100_wb_fini(rdev); r100_ib_fini(rdev); @@ -3825,6 +3547,8 @@ int r100_init(struct radeon_device *rdev) r100_errata(rdev); /* Initialize clocks */ radeon_get_clock_info(rdev->ddev); + /* Initialize power management */ + radeon_pm_init(rdev); /* initialize AGP */ if (rdev->flags & RADEON_IS_AGP) { r = radeon_agp_init(rdev); diff --git a/trunk/drivers/gpu/drm/radeon/r100d.h b/trunk/drivers/gpu/drm/radeon/r100d.h index d016b16fa116..de8abd104ab7 100644 --- a/trunk/drivers/gpu/drm/radeon/r100d.h +++ b/trunk/drivers/gpu/drm/radeon/r100d.h @@ -838,41 +838,5 @@ #define G_00000D_FORCE_RB(x) (((x) >> 28) & 0x1) #define C_00000D_FORCE_RB 0xEFFFFFFF -/* PLL regs */ -#define SCLK_CNTL 0xd -#define FORCE_HDP (1 << 17) -#define CLK_PWRMGT_CNTL 0x14 -#define GLOBAL_PMAN_EN (1 << 10) -#define DISP_PM (1 << 20) -#define PLL_PWRMGT_CNTL 0x15 -#define MPLL_TURNOFF (1 << 0) -#define SPLL_TURNOFF (1 << 1) -#define PPLL_TURNOFF (1 << 2) -#define P2PLL_TURNOFF (1 << 3) -#define TVPLL_TURNOFF (1 << 4) -#define MOBILE_SU (1 << 16) -#define SU_SCLK_USE_BCLK (1 << 17) -#define SCLK_CNTL2 0x1e -#define REDUCED_SPEED_SCLK_MODE (1 << 16) -#define REDUCED_SPEED_SCLK_SEL(x) ((x) << 17) -#define MCLK_MISC 0x1f -#define EN_MCLK_TRISTATE_IN_SUSPEND (1 << 18) -#define SCLK_MORE_CNTL 0x35 -#define REDUCED_SPEED_SCLK_EN (1 << 16) -#define IO_CG_VOLTAGE_DROP (1 << 17) -#define VOLTAGE_DELAY_SEL(x) ((x) << 20) -#define VOLTAGE_DROP_SYNC (1 << 19) - -/* mmreg */ -#define DISP_PWR_MAN 0xd08 -#define DISP_D3_GRPH_RST (1 << 18) -#define DISP_D3_SUBPIC_RST (1 << 19) -#define DISP_D3_OV0_RST (1 << 20) -#define DISP_D1D2_GRPH_RST (1 << 21) -#define DISP_D1D2_SUBPIC_RST (1 << 22) -#define DISP_D1D2_OV0_RST (1 << 23) -#define DISP_DVO_ENABLE_RST (1 << 24) -#define TV_ENABLE_RST (1 << 25) -#define AUTO_PWRUP_EN (1 << 26) #endif diff --git a/trunk/drivers/gpu/drm/radeon/r300.c b/trunk/drivers/gpu/drm/radeon/r300.c index 5c54db51de85..5d622cb39b33 100644 --- a/trunk/drivers/gpu/drm/radeon/r300.c +++ b/trunk/drivers/gpu/drm/radeon/r300.c @@ -1345,6 +1345,7 @@ int r300_suspend(struct radeon_device *rdev) void r300_fini(struct radeon_device *rdev) { + radeon_pm_fini(rdev); r100_cp_fini(rdev); r100_wb_fini(rdev); r100_ib_fini(rdev); @@ -1400,6 +1401,8 @@ int r300_init(struct radeon_device *rdev) r300_errata(rdev); /* Initialize clocks */ radeon_get_clock_info(rdev->ddev); + /* Initialize power management */ + radeon_pm_init(rdev); /* initialize AGP */ if (rdev->flags & RADEON_IS_AGP) { r = radeon_agp_init(rdev); diff --git a/trunk/drivers/gpu/drm/radeon/r420.c b/trunk/drivers/gpu/drm/radeon/r420.c index 87c0e3840034..3759d8384294 100644 --- a/trunk/drivers/gpu/drm/radeon/r420.c +++ b/trunk/drivers/gpu/drm/radeon/r420.c @@ -36,35 +36,6 @@ #include "r420d.h" #include "r420_reg_safe.h" -void r420_pm_init_profile(struct radeon_device *rdev) -{ - /* default */ - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0; - /* low sh */ - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; - /* high sh */ - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 0; - /* low mh */ - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; - /* high mh */ - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 0; -} - static void r420_set_reg_safe(struct radeon_device *rdev) { rdev->config.r300.reg_safe_bm = r420_reg_safe_bm; @@ -297,6 +268,7 @@ int r420_suspend(struct radeon_device *rdev) void r420_fini(struct radeon_device *rdev) { + radeon_pm_fini(rdev); r100_cp_fini(rdev); r100_wb_fini(rdev); r100_ib_fini(rdev); @@ -356,6 +328,8 @@ int r420_init(struct radeon_device *rdev) /* Initialize clocks */ radeon_get_clock_info(rdev->ddev); + /* Initialize power management */ + radeon_pm_init(rdev); /* initialize AGP */ if (rdev->flags & RADEON_IS_AGP) { r = radeon_agp_init(rdev); diff --git a/trunk/drivers/gpu/drm/radeon/r500_reg.h b/trunk/drivers/gpu/drm/radeon/r500_reg.h index 93c9a2bbccf8..0cf2ad2a5585 100644 --- a/trunk/drivers/gpu/drm/radeon/r500_reg.h +++ b/trunk/drivers/gpu/drm/radeon/r500_reg.h @@ -347,11 +347,9 @@ #define AVIVO_D1CRTC_CONTROL 0x6080 # define AVIVO_CRTC_EN (1 << 0) -# define AVIVO_CRTC_DISP_READ_REQUEST_DISABLE (1 << 24) #define AVIVO_D1CRTC_BLANK_CONTROL 0x6084 #define AVIVO_D1CRTC_INTERLACE_CONTROL 0x6088 #define AVIVO_D1CRTC_INTERLACE_STATUS 0x608c -#define AVIVO_D1CRTC_STATUS_POSITION 0x60a0 #define AVIVO_D1CRTC_FRAME_COUNT 0x60a4 #define AVIVO_D1CRTC_STEREO_CONTROL 0x60c4 @@ -490,7 +488,6 @@ #define AVIVO_D2CRTC_BLANK_CONTROL 0x6884 #define AVIVO_D2CRTC_INTERLACE_CONTROL 0x6888 #define AVIVO_D2CRTC_INTERLACE_STATUS 0x688c -#define AVIVO_D2CRTC_STATUS_POSITION 0x68a0 #define AVIVO_D2CRTC_FRAME_COUNT 0x68a4 #define AVIVO_D2CRTC_STEREO_CONTROL 0x68c4 diff --git a/trunk/drivers/gpu/drm/radeon/r520.c b/trunk/drivers/gpu/drm/radeon/r520.c index 34330df28483..870111e26bd1 100644 --- a/trunk/drivers/gpu/drm/radeon/r520.c +++ b/trunk/drivers/gpu/drm/radeon/r520.c @@ -261,6 +261,8 @@ int r520_init(struct radeon_device *rdev) } /* Initialize clocks */ radeon_get_clock_info(rdev->ddev); + /* Initialize power management */ + radeon_pm_init(rdev); /* initialize AGP */ if (rdev->flags & RADEON_IS_AGP) { r = radeon_agp_init(rdev); diff --git a/trunk/drivers/gpu/drm/radeon/r600.c b/trunk/drivers/gpu/drm/radeon/r600.c index 7ffc3892c652..2ec423c3f3f8 100644 --- a/trunk/drivers/gpu/drm/radeon/r600.c +++ b/trunk/drivers/gpu/drm/radeon/r600.c @@ -92,400 +92,6 @@ void r600_gpu_init(struct radeon_device *rdev); void r600_fini(struct radeon_device *rdev); void r600_irq_disable(struct radeon_device *rdev); -void r600_pm_get_dynpm_state(struct radeon_device *rdev) -{ - int i; - - rdev->pm.dynpm_can_upclock = true; - rdev->pm.dynpm_can_downclock = true; - - /* power state array is low to high, default is first */ - if ((rdev->flags & RADEON_IS_IGP) || (rdev->family == CHIP_R600)) { - int min_power_state_index = 0; - - if (rdev->pm.num_power_states > 2) - min_power_state_index = 1; - - switch (rdev->pm.dynpm_planned_action) { - case DYNPM_ACTION_MINIMUM: - rdev->pm.requested_power_state_index = min_power_state_index; - rdev->pm.requested_clock_mode_index = 0; - rdev->pm.dynpm_can_downclock = false; - break; - case DYNPM_ACTION_DOWNCLOCK: - if (rdev->pm.current_power_state_index == min_power_state_index) { - rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index; - rdev->pm.dynpm_can_downclock = false; - } else { - if (rdev->pm.active_crtc_count > 1) { - for (i = 0; i < rdev->pm.num_power_states; i++) { - if (rdev->pm.power_state[i].flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY) - continue; - else if (i >= rdev->pm.current_power_state_index) { - rdev->pm.requested_power_state_index = - rdev->pm.current_power_state_index; - break; - } else { - rdev->pm.requested_power_state_index = i; - break; - } - } - } else - rdev->pm.requested_power_state_index = - rdev->pm.current_power_state_index - 1; - } - rdev->pm.requested_clock_mode_index = 0; - /* don't use the power state if crtcs are active and no display flag is set */ - if ((rdev->pm.active_crtc_count > 0) && - (rdev->pm.power_state[rdev->pm.requested_power_state_index]. - clock_info[rdev->pm.requested_clock_mode_index].flags & - RADEON_PM_MODE_NO_DISPLAY)) { - rdev->pm.requested_power_state_index++; - } - break; - case DYNPM_ACTION_UPCLOCK: - if (rdev->pm.current_power_state_index == (rdev->pm.num_power_states - 1)) { - rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index; - rdev->pm.dynpm_can_upclock = false; - } else { - if (rdev->pm.active_crtc_count > 1) { - for (i = (rdev->pm.num_power_states - 1); i >= 0; i--) { - if (rdev->pm.power_state[i].flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY) - continue; - else if (i <= rdev->pm.current_power_state_index) { - rdev->pm.requested_power_state_index = - rdev->pm.current_power_state_index; - break; - } else { - rdev->pm.requested_power_state_index = i; - break; - } - } - } else - rdev->pm.requested_power_state_index = - rdev->pm.current_power_state_index + 1; - } - rdev->pm.requested_clock_mode_index = 0; - break; - case DYNPM_ACTION_DEFAULT: - rdev->pm.requested_power_state_index = rdev->pm.default_power_state_index; - rdev->pm.requested_clock_mode_index = 0; - rdev->pm.dynpm_can_upclock = false; - break; - case DYNPM_ACTION_NONE: - default: - DRM_ERROR("Requested mode for not defined action\n"); - return; - } - } else { - /* XXX select a power state based on AC/DC, single/dualhead, etc. */ - /* for now just select the first power state and switch between clock modes */ - /* power state array is low to high, default is first (0) */ - if (rdev->pm.active_crtc_count > 1) { - rdev->pm.requested_power_state_index = -1; - /* start at 1 as we don't want the default mode */ - for (i = 1; i < rdev->pm.num_power_states; i++) { - if (rdev->pm.power_state[i].flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY) - continue; - else if ((rdev->pm.power_state[i].type == POWER_STATE_TYPE_PERFORMANCE) || - (rdev->pm.power_state[i].type == POWER_STATE_TYPE_BATTERY)) { - rdev->pm.requested_power_state_index = i; - break; - } - } - /* if nothing selected, grab the default state. */ - if (rdev->pm.requested_power_state_index == -1) - rdev->pm.requested_power_state_index = 0; - } else - rdev->pm.requested_power_state_index = 1; - - switch (rdev->pm.dynpm_planned_action) { - case DYNPM_ACTION_MINIMUM: - rdev->pm.requested_clock_mode_index = 0; - rdev->pm.dynpm_can_downclock = false; - break; - case DYNPM_ACTION_DOWNCLOCK: - if (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index) { - if (rdev->pm.current_clock_mode_index == 0) { - rdev->pm.requested_clock_mode_index = 0; - rdev->pm.dynpm_can_downclock = false; - } else - rdev->pm.requested_clock_mode_index = - rdev->pm.current_clock_mode_index - 1; - } else { - rdev->pm.requested_clock_mode_index = 0; - rdev->pm.dynpm_can_downclock = false; - } - /* don't use the power state if crtcs are active and no display flag is set */ - if ((rdev->pm.active_crtc_count > 0) && - (rdev->pm.power_state[rdev->pm.requested_power_state_index]. - clock_info[rdev->pm.requested_clock_mode_index].flags & - RADEON_PM_MODE_NO_DISPLAY)) { - rdev->pm.requested_clock_mode_index++; - } - break; - case DYNPM_ACTION_UPCLOCK: - if (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index) { - if (rdev->pm.current_clock_mode_index == - (rdev->pm.power_state[rdev->pm.requested_power_state_index].num_clock_modes - 1)) { - rdev->pm.requested_clock_mode_index = rdev->pm.current_clock_mode_index; - rdev->pm.dynpm_can_upclock = false; - } else - rdev->pm.requested_clock_mode_index = - rdev->pm.current_clock_mode_index + 1; - } else { - rdev->pm.requested_clock_mode_index = - rdev->pm.power_state[rdev->pm.requested_power_state_index].num_clock_modes - 1; - rdev->pm.dynpm_can_upclock = false; - } - break; - case DYNPM_ACTION_DEFAULT: - rdev->pm.requested_power_state_index = rdev->pm.default_power_state_index; - rdev->pm.requested_clock_mode_index = 0; - rdev->pm.dynpm_can_upclock = false; - break; - case DYNPM_ACTION_NONE: - default: - DRM_ERROR("Requested mode for not defined action\n"); - return; - } - } - - DRM_DEBUG("Requested: e: %d m: %d p: %d\n", - rdev->pm.power_state[rdev->pm.requested_power_state_index]. - clock_info[rdev->pm.requested_clock_mode_index].sclk, - rdev->pm.power_state[rdev->pm.requested_power_state_index]. - clock_info[rdev->pm.requested_clock_mode_index].mclk, - rdev->pm.power_state[rdev->pm.requested_power_state_index]. - pcie_lanes); -} - -static int r600_pm_get_type_index(struct radeon_device *rdev, - enum radeon_pm_state_type ps_type, - int instance) -{ - int i; - int found_instance = -1; - - for (i = 0; i < rdev->pm.num_power_states; i++) { - if (rdev->pm.power_state[i].type == ps_type) { - found_instance++; - if (found_instance == instance) - return i; - } - } - /* return default if no match */ - return rdev->pm.default_power_state_index; -} - -void rs780_pm_init_profile(struct radeon_device *rdev) -{ - if (rdev->pm.num_power_states == 2) { - /* default */ - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0; - /* low sh */ - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; - /* high sh */ - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 0; - /* low mh */ - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; - /* high mh */ - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 0; - } else if (rdev->pm.num_power_states == 3) { - /* default */ - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0; - /* low sh */ - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; - /* high sh */ - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 0; - /* low mh */ - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; - /* high mh */ - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 0; - } else { - /* default */ - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0; - /* low sh */ - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; - /* high sh */ - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = 3; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 0; - /* low mh */ - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; - /* high mh */ - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = 3; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 0; - } -} - -void r600_pm_init_profile(struct radeon_device *rdev) -{ - if (rdev->family == CHIP_R600) { - /* XXX */ - /* default */ - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0; - /* low sh */ - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; - /* high sh */ - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 0; - /* low mh */ - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; - /* high mh */ - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 0; - } else { - if (rdev->pm.num_power_states < 4) { - /* default */ - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 2; - /* low sh */ - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 1; - /* high sh */ - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 2; - /* low mh */ - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 1; - /* high mh */ - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 2; - } else { - /* default */ - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 2; - /* low sh */ - if (rdev->flags & RADEON_IS_MOBILITY) { - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = - r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = - r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 2; - } else { - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = - r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = - r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 1; - } - /* high sh */ - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = - r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = - r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 2; - /* low mh */ - if (rdev->flags & RADEON_IS_MOBILITY) { - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = - r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1); - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = - r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1); - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 2; - } else { - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = - r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = - r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 1; - } - /* high mh */ - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = - r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = - r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 2; - } - } -} - -void r600_pm_misc(struct radeon_device *rdev) -{ - -} - -bool r600_gui_idle(struct radeon_device *rdev) -{ - if (RREG32(GRBM_STATUS) & GUI_ACTIVE) - return false; - else - return true; -} - /* hpd for digital panel detect/disconnect */ bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) { @@ -2463,6 +2069,8 @@ int r600_init(struct radeon_device *rdev) r = radeon_clocks_init(rdev); if (r) return r; + /* Initialize power management */ + radeon_pm_init(rdev); /* Fence driver */ r = radeon_fence_driver_init(rdev); if (r) @@ -2527,6 +2135,7 @@ int r600_init(struct radeon_device *rdev) void r600_fini(struct radeon_device *rdev) { + radeon_pm_fini(rdev); r600_audio_fini(rdev); r600_blit_fini(rdev); r600_cp_fini(rdev); @@ -2918,7 +2527,6 @@ int r600_irq_set(struct radeon_device *rdev) u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; u32 mode_int = 0; u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; - u32 grbm_int_cntl = 0; u32 hdmi1, hdmi2; if (!rdev->irq.installed) { @@ -2995,14 +2603,9 @@ int r600_irq_set(struct radeon_device *rdev) DRM_DEBUG("r600_irq_set: hdmi 2\n"); hdmi2 |= R600_HDMI_INT_EN; } - if (rdev->irq.gui_idle) { - DRM_DEBUG("gui idle\n"); - grbm_int_cntl |= GUI_IDLE_INT_ENABLE; - } WREG32(CP_INT_CNTL, cp_int_cntl); WREG32(DxMODE_INT_MASK, mode_int); - WREG32(GRBM_INT_CNTL, grbm_int_cntl); WREG32(R600_HDMI_BLOCK1 + R600_HDMI_CNTL, hdmi1); if (ASIC_IS_DCE3(rdev)) { WREG32(R600_HDMI_BLOCK3 + R600_HDMI_CNTL, hdmi2); @@ -3318,11 +2921,6 @@ int r600_irq_process(struct radeon_device *rdev) case 181: /* CP EOP event */ DRM_DEBUG("IH: CP EOP\n"); break; - case 233: /* GUI IDLE */ - DRM_DEBUG("IH: CP EOP\n"); - rdev->pm.gui_idle = true; - wake_up(&rdev->irq.idle_queue); - break; default: DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); break; diff --git a/trunk/drivers/gpu/drm/radeon/radeon.h b/trunk/drivers/gpu/drm/radeon/radeon.h index 5c9ce2beaca3..ab29d972a167 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon.h +++ b/trunk/drivers/gpu/drm/radeon/radeon.h @@ -89,6 +89,7 @@ extern int radeon_testing; extern int radeon_connector_table; extern int radeon_tv; extern int radeon_new_pll; +extern int radeon_dynpm; extern int radeon_audio; extern int radeon_disp_priority; extern int radeon_hw_i2c; @@ -172,8 +173,6 @@ struct radeon_clock { int radeon_pm_init(struct radeon_device *rdev); void radeon_pm_fini(struct radeon_device *rdev); void radeon_pm_compute_clocks(struct radeon_device *rdev); -void radeon_pm_suspend(struct radeon_device *rdev); -void radeon_pm_resume(struct radeon_device *rdev); void radeon_combios_get_power_modes(struct radeon_device *rdev); void radeon_atombios_get_power_modes(struct radeon_device *rdev); @@ -377,9 +376,6 @@ struct radeon_irq { wait_queue_head_t vblank_queue; /* FIXME: use defines for max hpd/dacs */ bool hpd[6]; - bool gui_idle; - bool gui_idle_acked; - wait_queue_head_t idle_queue; /* FIXME: use defines for max HDMI blocks */ bool hdmi[2]; spinlock_t sw_lock; @@ -469,9 +465,7 @@ int radeon_ib_test(struct radeon_device *rdev); extern void radeon_ib_bogus_add(struct radeon_device *rdev, struct radeon_ib *ib); /* Ring access between begin & end cannot sleep */ void radeon_ring_free_size(struct radeon_device *rdev); -int radeon_ring_alloc(struct radeon_device *rdev, unsigned ndw); int radeon_ring_lock(struct radeon_device *rdev, unsigned ndw); -void radeon_ring_commit(struct radeon_device *rdev); void radeon_ring_unlock_commit(struct radeon_device *rdev); void radeon_ring_unlock_undo(struct radeon_device *rdev); int radeon_ring_test(struct radeon_device *rdev); @@ -606,24 +600,17 @@ struct radeon_wb { * Equation between gpu/memory clock and available bandwidth is hw dependent * (type of memory, bus size, efficiency, ...) */ - -enum radeon_pm_method { - PM_METHOD_PROFILE, - PM_METHOD_DYNPM, -}; - -enum radeon_dynpm_state { - DYNPM_STATE_DISABLED, - DYNPM_STATE_MINIMUM, - DYNPM_STATE_PAUSED, - DYNPM_STATE_ACTIVE +enum radeon_pm_state { + PM_STATE_DISABLED, + PM_STATE_MINIMUM, + PM_STATE_PAUSED, + PM_STATE_ACTIVE }; -enum radeon_dynpm_action { - DYNPM_ACTION_NONE, - DYNPM_ACTION_MINIMUM, - DYNPM_ACTION_DOWNCLOCK, - DYNPM_ACTION_UPCLOCK, - DYNPM_ACTION_DEFAULT +enum radeon_pm_action { + PM_ACTION_NONE, + PM_ACTION_MINIMUM, + PM_ACTION_DOWNCLOCK, + PM_ACTION_UPCLOCK }; enum radeon_voltage_type { @@ -641,25 +628,11 @@ enum radeon_pm_state_type { POWER_STATE_TYPE_PERFORMANCE, }; -enum radeon_pm_profile_type { - PM_PROFILE_DEFAULT, - PM_PROFILE_AUTO, - PM_PROFILE_LOW, - PM_PROFILE_HIGH, -}; - -#define PM_PROFILE_DEFAULT_IDX 0 -#define PM_PROFILE_LOW_SH_IDX 1 -#define PM_PROFILE_HIGH_SH_IDX 2 -#define PM_PROFILE_LOW_MH_IDX 3 -#define PM_PROFILE_HIGH_MH_IDX 4 -#define PM_PROFILE_MAX 5 - -struct radeon_pm_profile { - int dpms_off_ps_idx; - int dpms_on_ps_idx; - int dpms_off_cm_idx; - int dpms_on_cm_idx; +enum radeon_pm_clock_mode_type { + POWER_MODE_TYPE_DEFAULT, + POWER_MODE_TYPE_LOW, + POWER_MODE_TYPE_MID, + POWER_MODE_TYPE_HIGH, }; struct radeon_voltage { @@ -676,8 +649,12 @@ struct radeon_voltage { u32 voltage; }; -/* clock mode flags */ -#define RADEON_PM_MODE_NO_DISPLAY (1 << 0) +struct radeon_pm_non_clock_info { + /* pcie lanes */ + int pcie_lanes; + /* standardized non-clock flags */ + u32 flags; +}; struct radeon_pm_clock_info { /* memory clock */ @@ -686,13 +663,10 @@ struct radeon_pm_clock_info { u32 sclk; /* voltage info */ struct radeon_voltage voltage; - /* standardized clock flags */ + /* standardized clock flags - not sure we'll need these */ u32 flags; }; -/* state flags */ -#define RADEON_PM_STATE_SINGLE_DISPLAY_ONLY (1 << 0) - struct radeon_power_state { enum radeon_pm_state_type type; /* XXX: use a define for num clock modes */ @@ -700,11 +674,9 @@ struct radeon_power_state { /* number of valid clock modes in this power state */ int num_clock_modes; struct radeon_pm_clock_info *default_clock_mode; - /* standardized state flags */ - u32 flags; - u32 misc; /* vbios specific flags */ - u32 misc2; /* vbios specific flags */ - int pcie_lanes; /* pcie lanes */ + /* non clock info about this state */ + struct radeon_pm_non_clock_info non_clock_info; + bool voltage_drop_active; }; /* @@ -714,11 +686,14 @@ struct radeon_power_state { struct radeon_pm { struct mutex mutex; - u32 active_crtcs; - int active_crtc_count; + struct delayed_work idle_work; + enum radeon_pm_state state; + enum radeon_pm_action planned_action; + unsigned long action_timeout; + bool downclocked; + int active_crtcs; int req_vblank; bool vblank_sync; - bool gui_idle; fixed20_12 max_bandwidth; fixed20_12 igp_sideport_mclk; fixed20_12 igp_system_mclk; @@ -735,27 +710,12 @@ struct radeon_pm { struct radeon_power_state power_state[8]; /* number of valid power states */ int num_power_states; - int current_power_state_index; - int current_clock_mode_index; - int requested_power_state_index; - int requested_clock_mode_index; - int default_power_state_index; - u32 current_sclk; - u32 current_mclk; + struct radeon_power_state *current_power_state; + struct radeon_pm_clock_info *current_clock_mode; + struct radeon_power_state *requested_power_state; + struct radeon_pm_clock_info *requested_clock_mode; + struct radeon_power_state *default_power_state; struct radeon_i2c_chan *i2c_bus; - /* selected pm method */ - enum radeon_pm_method pm_method; - /* dynpm power management */ - struct delayed_work dynpm_idle_work; - enum radeon_dynpm_state dynpm_state; - enum radeon_dynpm_action dynpm_planned_action; - unsigned long dynpm_action_timeout; - bool dynpm_can_upclock; - bool dynpm_can_downclock; - /* profile-based power management */ - enum radeon_pm_profile_type profile; - int profile_index; - struct radeon_pm_profile profiles[PM_PROFILE_MAX]; }; @@ -843,13 +803,6 @@ struct radeon_asic { * through ring. */ void (*ioctl_wait_idle)(struct radeon_device *rdev, struct radeon_bo *bo); - bool (*gui_idle)(struct radeon_device *rdev); - /* power management */ - void (*pm_misc)(struct radeon_device *rdev); - void (*pm_prepare)(struct radeon_device *rdev); - void (*pm_finish)(struct radeon_device *rdev); - void (*pm_init_profile)(struct radeon_device *rdev); - void (*pm_get_dynpm_state)(struct radeon_device *rdev); }; /* @@ -1056,7 +1009,6 @@ struct radeon_device { struct work_struct hotplug_work; int num_crtc; /* number of crtcs */ struct mutex dc_hw_i2c_mutex; /* display controller hw i2c mutex */ - struct mutex vram_mutex; /* audio stuff */ struct timer_list audio_timer; @@ -1067,7 +1019,6 @@ struct radeon_device { uint8_t audio_category_code; bool powered_down; - struct notifier_block acpi_nb; }; int radeon_device_init(struct radeon_device *rdev, @@ -1258,12 +1209,6 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) #define radeon_hpd_fini(rdev) (rdev)->asic->hpd_fini((rdev)) #define radeon_hpd_sense(rdev, hpd) (rdev)->asic->hpd_sense((rdev), (hpd)) #define radeon_hpd_set_polarity(rdev, hpd) (rdev)->asic->hpd_set_polarity((rdev), (hpd)) -#define radeon_gui_idle(rdev) (rdev)->asic->gui_idle((rdev)) -#define radeon_pm_misc(rdev) (rdev)->asic->pm_misc((rdev)) -#define radeon_pm_prepare(rdev) (rdev)->asic->pm_prepare((rdev)) -#define radeon_pm_finish(rdev) (rdev)->asic->pm_finish((rdev)) -#define radeon_pm_init_profile(rdev) (rdev)->asic->pm_init_profile((rdev)) -#define radeon_pm_get_dynpm_state(rdev) (rdev)->asic->pm_get_dynpm_state((rdev)) /* Common functions */ /* AGP */ diff --git a/trunk/drivers/gpu/drm/radeon/radeon_asic.c b/trunk/drivers/gpu/drm/radeon/radeon_asic.c index e57df08d4aeb..f835333c1b69 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_asic.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_asic.c @@ -165,12 +165,6 @@ static struct radeon_asic r100_asic = { .hpd_sense = &r100_hpd_sense, .hpd_set_polarity = &r100_hpd_set_polarity, .ioctl_wait_idle = NULL, - .gui_idle = &r100_gui_idle, - .pm_misc = &r100_pm_misc, - .pm_prepare = &r100_pm_prepare, - .pm_finish = &r100_pm_finish, - .pm_init_profile = &r100_pm_init_profile, - .pm_get_dynpm_state = &r100_pm_get_dynpm_state, }; static struct radeon_asic r200_asic = { @@ -209,12 +203,6 @@ static struct radeon_asic r200_asic = { .hpd_sense = &r100_hpd_sense, .hpd_set_polarity = &r100_hpd_set_polarity, .ioctl_wait_idle = NULL, - .gui_idle = &r100_gui_idle, - .pm_misc = &r100_pm_misc, - .pm_prepare = &r100_pm_prepare, - .pm_finish = &r100_pm_finish, - .pm_init_profile = &r100_pm_init_profile, - .pm_get_dynpm_state = &r100_pm_get_dynpm_state, }; static struct radeon_asic r300_asic = { @@ -254,12 +242,6 @@ static struct radeon_asic r300_asic = { .hpd_sense = &r100_hpd_sense, .hpd_set_polarity = &r100_hpd_set_polarity, .ioctl_wait_idle = NULL, - .gui_idle = &r100_gui_idle, - .pm_misc = &r100_pm_misc, - .pm_prepare = &r100_pm_prepare, - .pm_finish = &r100_pm_finish, - .pm_init_profile = &r100_pm_init_profile, - .pm_get_dynpm_state = &r100_pm_get_dynpm_state, }; static struct radeon_asic r300_asic_pcie = { @@ -298,12 +280,6 @@ static struct radeon_asic r300_asic_pcie = { .hpd_sense = &r100_hpd_sense, .hpd_set_polarity = &r100_hpd_set_polarity, .ioctl_wait_idle = NULL, - .gui_idle = &r100_gui_idle, - .pm_misc = &r100_pm_misc, - .pm_prepare = &r100_pm_prepare, - .pm_finish = &r100_pm_finish, - .pm_init_profile = &r100_pm_init_profile, - .pm_get_dynpm_state = &r100_pm_get_dynpm_state, }; static struct radeon_asic r420_asic = { @@ -343,12 +319,6 @@ static struct radeon_asic r420_asic = { .hpd_sense = &r100_hpd_sense, .hpd_set_polarity = &r100_hpd_set_polarity, .ioctl_wait_idle = NULL, - .gui_idle = &r100_gui_idle, - .pm_misc = &r100_pm_misc, - .pm_prepare = &r100_pm_prepare, - .pm_finish = &r100_pm_finish, - .pm_init_profile = &r420_pm_init_profile, - .pm_get_dynpm_state = &r100_pm_get_dynpm_state, }; static struct radeon_asic rs400_asic = { @@ -388,12 +358,6 @@ static struct radeon_asic rs400_asic = { .hpd_sense = &r100_hpd_sense, .hpd_set_polarity = &r100_hpd_set_polarity, .ioctl_wait_idle = NULL, - .gui_idle = &r100_gui_idle, - .pm_misc = &r100_pm_misc, - .pm_prepare = &r100_pm_prepare, - .pm_finish = &r100_pm_finish, - .pm_init_profile = &r100_pm_init_profile, - .pm_get_dynpm_state = &r100_pm_get_dynpm_state, }; static struct radeon_asic rs600_asic = { @@ -433,12 +397,6 @@ static struct radeon_asic rs600_asic = { .hpd_sense = &rs600_hpd_sense, .hpd_set_polarity = &rs600_hpd_set_polarity, .ioctl_wait_idle = NULL, - .gui_idle = &r100_gui_idle, - .pm_misc = &rs600_pm_misc, - .pm_prepare = &rs600_pm_prepare, - .pm_finish = &rs600_pm_finish, - .pm_init_profile = &r420_pm_init_profile, - .pm_get_dynpm_state = &r100_pm_get_dynpm_state, }; static struct radeon_asic rs690_asic = { @@ -478,12 +436,6 @@ static struct radeon_asic rs690_asic = { .hpd_sense = &rs600_hpd_sense, .hpd_set_polarity = &rs600_hpd_set_polarity, .ioctl_wait_idle = NULL, - .gui_idle = &r100_gui_idle, - .pm_misc = &rs600_pm_misc, - .pm_prepare = &rs600_pm_prepare, - .pm_finish = &rs600_pm_finish, - .pm_init_profile = &r420_pm_init_profile, - .pm_get_dynpm_state = &r100_pm_get_dynpm_state, }; static struct radeon_asic rv515_asic = { @@ -523,12 +475,6 @@ static struct radeon_asic rv515_asic = { .hpd_sense = &rs600_hpd_sense, .hpd_set_polarity = &rs600_hpd_set_polarity, .ioctl_wait_idle = NULL, - .gui_idle = &r100_gui_idle, - .pm_misc = &rs600_pm_misc, - .pm_prepare = &rs600_pm_prepare, - .pm_finish = &rs600_pm_finish, - .pm_init_profile = &r420_pm_init_profile, - .pm_get_dynpm_state = &r100_pm_get_dynpm_state, }; static struct radeon_asic r520_asic = { @@ -568,12 +514,6 @@ static struct radeon_asic r520_asic = { .hpd_sense = &rs600_hpd_sense, .hpd_set_polarity = &rs600_hpd_set_polarity, .ioctl_wait_idle = NULL, - .gui_idle = &r100_gui_idle, - .pm_misc = &rs600_pm_misc, - .pm_prepare = &rs600_pm_prepare, - .pm_finish = &rs600_pm_finish, - .pm_init_profile = &r420_pm_init_profile, - .pm_get_dynpm_state = &r100_pm_get_dynpm_state, }; static struct radeon_asic r600_asic = { @@ -612,12 +552,6 @@ static struct radeon_asic r600_asic = { .hpd_sense = &r600_hpd_sense, .hpd_set_polarity = &r600_hpd_set_polarity, .ioctl_wait_idle = r600_ioctl_wait_idle, - .gui_idle = &r600_gui_idle, - .pm_misc = &r600_pm_misc, - .pm_prepare = &rs600_pm_prepare, - .pm_finish = &rs600_pm_finish, - .pm_init_profile = &r600_pm_init_profile, - .pm_get_dynpm_state = &r600_pm_get_dynpm_state, }; static struct radeon_asic rs780_asic = { @@ -656,12 +590,6 @@ static struct radeon_asic rs780_asic = { .hpd_sense = &r600_hpd_sense, .hpd_set_polarity = &r600_hpd_set_polarity, .ioctl_wait_idle = r600_ioctl_wait_idle, - .gui_idle = &r600_gui_idle, - .pm_misc = &r600_pm_misc, - .pm_prepare = &rs600_pm_prepare, - .pm_finish = &rs600_pm_finish, - .pm_init_profile = &rs780_pm_init_profile, - .pm_get_dynpm_state = &r600_pm_get_dynpm_state, }; static struct radeon_asic rv770_asic = { @@ -700,12 +628,6 @@ static struct radeon_asic rv770_asic = { .hpd_sense = &r600_hpd_sense, .hpd_set_polarity = &r600_hpd_set_polarity, .ioctl_wait_idle = r600_ioctl_wait_idle, - .gui_idle = &r600_gui_idle, - .pm_misc = &rv770_pm_misc, - .pm_prepare = &rs600_pm_prepare, - .pm_finish = &rs600_pm_finish, - .pm_init_profile = &r600_pm_init_profile, - .pm_get_dynpm_state = &r600_pm_get_dynpm_state, }; static struct radeon_asic evergreen_asic = { @@ -742,12 +664,6 @@ static struct radeon_asic evergreen_asic = { .hpd_fini = &evergreen_hpd_fini, .hpd_sense = &evergreen_hpd_sense, .hpd_set_polarity = &evergreen_hpd_set_polarity, - .gui_idle = &r600_gui_idle, - .pm_misc = &evergreen_pm_misc, - .pm_prepare = &evergreen_pm_prepare, - .pm_finish = &evergreen_pm_finish, - .pm_init_profile = &r600_pm_init_profile, - .pm_get_dynpm_state = &r600_pm_get_dynpm_state, }; int radeon_asic_init(struct radeon_device *rdev) diff --git a/trunk/drivers/gpu/drm/radeon/radeon_asic.h b/trunk/drivers/gpu/drm/radeon/radeon_asic.h index 5c40a3dfaca2..ef2c7ba1bdc9 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_asic.h +++ b/trunk/drivers/gpu/drm/radeon/radeon_asic.h @@ -126,13 +126,6 @@ int r100_cs_packet_parse(struct radeon_cs_parser *p, void r100_enable_bm(struct radeon_device *rdev); void r100_set_common_regs(struct radeon_device *rdev); void r100_bm_disable(struct radeon_device *rdev); -extern bool r100_gui_idle(struct radeon_device *rdev); -extern void r100_pm_misc(struct radeon_device *rdev); -extern void r100_pm_prepare(struct radeon_device *rdev); -extern void r100_pm_finish(struct radeon_device *rdev); -extern void r100_pm_init_profile(struct radeon_device *rdev); -extern void r100_pm_get_dynpm_state(struct radeon_device *rdev); - /* * r200,rv250,rs300,rv280 */ @@ -169,7 +162,6 @@ extern int r420_init(struct radeon_device *rdev); extern void r420_fini(struct radeon_device *rdev); extern int r420_suspend(struct radeon_device *rdev); extern int r420_resume(struct radeon_device *rdev); -extern void r420_pm_init_profile(struct radeon_device *rdev); /* * rs400,rs480 @@ -204,9 +196,6 @@ void rs600_hpd_fini(struct radeon_device *rdev); bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); void rs600_hpd_set_polarity(struct radeon_device *rdev, enum radeon_hpd_id hpd); -extern void rs600_pm_misc(struct radeon_device *rdev); -extern void rs600_pm_prepare(struct radeon_device *rdev); -extern void rs600_pm_finish(struct radeon_device *rdev); /* * rs690,rs740 @@ -280,11 +269,6 @@ bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); void r600_hpd_set_polarity(struct radeon_device *rdev, enum radeon_hpd_id hpd); extern void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo); -extern bool r600_gui_idle(struct radeon_device *rdev); -extern void r600_pm_misc(struct radeon_device *rdev); -extern void r600_pm_init_profile(struct radeon_device *rdev); -extern void rs780_pm_init_profile(struct radeon_device *rdev); -extern void r600_pm_get_dynpm_state(struct radeon_device *rdev); /* * rv770,rv730,rv710,rv740 @@ -293,7 +277,6 @@ int rv770_init(struct radeon_device *rdev); void rv770_fini(struct radeon_device *rdev); int rv770_suspend(struct radeon_device *rdev); int rv770_resume(struct radeon_device *rdev); -extern void rv770_pm_misc(struct radeon_device *rdev); /* * evergreen @@ -314,8 +297,5 @@ void evergreen_hpd_set_polarity(struct radeon_device *rdev, u32 evergreen_get_vblank_counter(struct radeon_device *rdev, int crtc); int evergreen_irq_set(struct radeon_device *rdev); int evergreen_irq_process(struct radeon_device *rdev); -extern void evergreen_pm_misc(struct radeon_device *rdev); -extern void evergreen_pm_prepare(struct radeon_device *rdev); -extern void evergreen_pm_finish(struct radeon_device *rdev); #endif diff --git a/trunk/drivers/gpu/drm/radeon/radeon_atombios.c b/trunk/drivers/gpu/drm/radeon/radeon_atombios.c index 9149e4a3af0f..273019925e0b 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1174,7 +1174,7 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct lvds->native_mode.vtotal = lvds->native_mode.vdisplay + le16_to_cpu(lvds_info->info.sLCDTiming.usVBlanking_Time); lvds->native_mode.vsync_start = lvds->native_mode.vdisplay + - le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncOffset); + le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth); lvds->native_mode.vsync_end = lvds->native_mode.vsync_start + le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth); lvds->panel_pwr_delay = @@ -1442,29 +1442,29 @@ radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder) static const char *thermal_controller_names[] = { "NONE", - "lm63", - "adm1032", - "adm1030", - "max6649", - "lm64", - "f75375", - "asc7xxx", + "LM63", + "ADM1032", + "ADM1030", + "MUA6649", + "LM64", + "F75375", + "ASC7512", }; static const char *pp_lib_thermal_controller_names[] = { "NONE", - "lm63", - "adm1032", - "adm1030", - "max6649", - "lm64", - "f75375", + "LM63", + "ADM1032", + "ADM1030", + "MUA6649", + "LM64", + "F75375", "RV6xx", "RV770", - "adt7473", + "ADT7473", "External GPIO", "Evergreen", - "adt7473 with internal", + "ADT7473 with internal", }; @@ -1489,7 +1489,7 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) int state_index = 0, mode_index = 0; struct radeon_i2c_bus_rec i2c_bus; - rdev->pm.default_power_state_index = -1; + rdev->pm.default_power_state = NULL; if (atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset)) { @@ -1502,19 +1502,10 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) power_info->info.ucOverdriveControllerAddress >> 1); i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info.ucOverdriveI2cLine); rdev->pm.i2c_bus = radeon_i2c_create(rdev->ddev, &i2c_bus, "Thermal"); - if (rdev->pm.i2c_bus) { - struct i2c_board_info info = { }; - const char *name = thermal_controller_names[power_info->info. - ucOverdriveThermalController]; - info.addr = power_info->info.ucOverdriveControllerAddress >> 1; - strlcpy(info.type, name, sizeof(info.type)); - i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); - } } num_modes = power_info->info.ucNumOfPowerModeEntries; if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK) num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK; - /* last mode is usually default, array is low to high */ for (i = 0; i < num_modes; i++) { rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; switch (frev) { @@ -1528,7 +1519,13 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) continue; - rdev->pm.power_state[state_index].pcie_lanes = + /* skip overclock modes for now */ + if ((rdev->pm.power_state[state_index].clock_info[0].mclk > + rdev->clock.default_mclk + RADEON_MODE_OVERCLOCK_MARGIN) || + (rdev->pm.power_state[state_index].clock_info[0].sclk > + rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN)) + continue; + rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = power_info->info.asPowerPlayInfo[i].ucNumPciELanes; misc = le32_to_cpu(power_info->info.asPowerPlayInfo[i].ulMiscInfo); if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) { @@ -1549,8 +1546,6 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex; } - rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - rdev->pm.power_state[state_index].misc = misc; /* order matters! */ if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) rdev->pm.power_state[state_index].type = @@ -1564,23 +1559,15 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) rdev->pm.power_state[state_index].type = POWER_STATE_TYPE_BALANCED; - if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) { + if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) rdev->pm.power_state[state_index].type = POWER_STATE_TYPE_PERFORMANCE; - rdev->pm.power_state[state_index].flags &= - ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - } if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { rdev->pm.power_state[state_index].type = POWER_STATE_TYPE_DEFAULT; - rdev->pm.default_power_state_index = state_index; + rdev->pm.default_power_state = &rdev->pm.power_state[state_index]; rdev->pm.power_state[state_index].default_clock_mode = &rdev->pm.power_state[state_index].clock_info[0]; - rdev->pm.power_state[state_index].flags &= - ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - } else if (state_index == 0) { - rdev->pm.power_state[state_index].clock_info[0].flags |= - RADEON_PM_MODE_NO_DISPLAY; } state_index++; break; @@ -1594,7 +1581,13 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) continue; - rdev->pm.power_state[state_index].pcie_lanes = + /* skip overclock modes for now */ + if ((rdev->pm.power_state[state_index].clock_info[0].mclk > + rdev->clock.default_mclk + RADEON_MODE_OVERCLOCK_MARGIN) || + (rdev->pm.power_state[state_index].clock_info[0].sclk > + rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN)) + continue; + rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = power_info->info_2.asPowerPlayInfo[i].ucNumPciELanes; misc = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo); misc2 = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo2); @@ -1616,9 +1609,6 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex; } - rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - rdev->pm.power_state[state_index].misc = misc; - rdev->pm.power_state[state_index].misc2 = misc2; /* order matters! */ if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) rdev->pm.power_state[state_index].type = @@ -1632,29 +1622,18 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) rdev->pm.power_state[state_index].type = POWER_STATE_TYPE_BALANCED; - if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) { + if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) rdev->pm.power_state[state_index].type = POWER_STATE_TYPE_PERFORMANCE; - rdev->pm.power_state[state_index].flags &= - ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - } if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE) rdev->pm.power_state[state_index].type = POWER_STATE_TYPE_BALANCED; - if (misc2 & ATOM_PM_MISCINFO2_MULTI_DISPLAY_SUPPORT) - rdev->pm.power_state[state_index].flags &= - ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { rdev->pm.power_state[state_index].type = POWER_STATE_TYPE_DEFAULT; - rdev->pm.default_power_state_index = state_index; + rdev->pm.default_power_state = &rdev->pm.power_state[state_index]; rdev->pm.power_state[state_index].default_clock_mode = &rdev->pm.power_state[state_index].clock_info[0]; - rdev->pm.power_state[state_index].flags &= - ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - } else if (state_index == 0) { - rdev->pm.power_state[state_index].clock_info[0].flags |= - RADEON_PM_MODE_NO_DISPLAY; } state_index++; break; @@ -1668,7 +1647,13 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) continue; - rdev->pm.power_state[state_index].pcie_lanes = + /* skip overclock modes for now */ + if ((rdev->pm.power_state[state_index].clock_info[0].mclk > + rdev->clock.default_mclk + RADEON_MODE_OVERCLOCK_MARGIN) || + (rdev->pm.power_state[state_index].clock_info[0].sclk > + rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN)) + continue; + rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = power_info->info_3.asPowerPlayInfo[i].ucNumPciELanes; misc = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo); misc2 = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo2); @@ -1696,9 +1681,6 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) power_info->info_3.asPowerPlayInfo[i].ucVDDCI_VoltageDropIndex; } } - rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - rdev->pm.power_state[state_index].misc = misc; - rdev->pm.power_state[state_index].misc2 = misc2; /* order matters! */ if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) rdev->pm.power_state[state_index].type = @@ -1712,76 +1694,48 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) rdev->pm.power_state[state_index].type = POWER_STATE_TYPE_BALANCED; - if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) { + if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) rdev->pm.power_state[state_index].type = POWER_STATE_TYPE_PERFORMANCE; - rdev->pm.power_state[state_index].flags &= - ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - } if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE) rdev->pm.power_state[state_index].type = POWER_STATE_TYPE_BALANCED; if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { rdev->pm.power_state[state_index].type = POWER_STATE_TYPE_DEFAULT; - rdev->pm.default_power_state_index = state_index; + rdev->pm.default_power_state = &rdev->pm.power_state[state_index]; rdev->pm.power_state[state_index].default_clock_mode = &rdev->pm.power_state[state_index].clock_info[0]; - } else if (state_index == 0) { - rdev->pm.power_state[state_index].clock_info[0].flags |= - RADEON_PM_MODE_NO_DISPLAY; } state_index++; break; } } - /* last mode is usually default */ - if (rdev->pm.default_power_state_index == -1) { - rdev->pm.power_state[state_index - 1].type = - POWER_STATE_TYPE_DEFAULT; - rdev->pm.default_power_state_index = state_index - 1; - rdev->pm.power_state[state_index - 1].default_clock_mode = - &rdev->pm.power_state[state_index - 1].clock_info[0]; - rdev->pm.power_state[state_index].flags &= - ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - rdev->pm.power_state[state_index].misc = 0; - rdev->pm.power_state[state_index].misc2 = 0; - } } else { /* add the i2c bus for thermal/fan chip */ /* no support for internal controller yet */ - ATOM_PPLIB_THERMALCONTROLLER *controller = &power_info->info_4.sThermalController; - if (controller->ucType > 0) { - if ((controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) || - (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) || - (controller->ucType == ATOM_PP_THERMALCONTROLLER_EVERGREEN)) { + if (power_info->info_4.sThermalController.ucType > 0) { + if ((power_info->info_4.sThermalController.ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) || + (power_info->info_4.sThermalController.ucType == ATOM_PP_THERMALCONTROLLER_RV770) || + (power_info->info_4.sThermalController.ucType == ATOM_PP_THERMALCONTROLLER_EVERGREEN)) { DRM_INFO("Internal thermal controller %s fan control\n", - (controller->ucFanParameters & + (power_info->info_4.sThermalController.ucFanParameters & ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); - } else if ((controller->ucType == + } else if ((power_info->info_4.sThermalController.ucType == ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) || - (controller->ucType == + (power_info->info_4.sThermalController.ucType == ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL)) { DRM_INFO("Special thermal controller config\n"); } else { DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n", - pp_lib_thermal_controller_names[controller->ucType], - controller->ucI2cAddress >> 1, - (controller->ucFanParameters & + pp_lib_thermal_controller_names[power_info->info_4.sThermalController.ucType], + power_info->info_4.sThermalController.ucI2cAddress >> 1, + (power_info->info_4.sThermalController.ucFanParameters & ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); - i2c_bus = radeon_lookup_i2c_gpio(rdev, controller->ucI2cLine); + i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info_4.sThermalController.ucI2cLine); rdev->pm.i2c_bus = radeon_i2c_create(rdev->ddev, &i2c_bus, "Thermal"); - if (rdev->pm.i2c_bus) { - struct i2c_board_info info = { }; - const char *name = pp_lib_thermal_controller_names[controller->ucType]; - info.addr = controller->ucI2cAddress >> 1; - strlcpy(info.type, name, sizeof(info.type)); - i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); - } - } } - /* first mode is usually default, followed by low to high */ for (i = 0; i < power_info->info_4.ucNumStates; i++) { mode_index = 0; power_state = (struct _ATOM_PPLIB_STATE *) @@ -1810,6 +1764,10 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) /* skip invalid modes */ if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0) continue; + /* skip overclock modes for now */ + if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk > + rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN) + continue; rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = VOLTAGE_SW; rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = @@ -1833,6 +1791,12 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk == 0) || (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0)) continue; + /* skip overclock modes for now */ + if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk > + rdev->clock.default_mclk + RADEON_MODE_OVERCLOCK_MARGIN) || + (rdev->pm.power_state[state_index].clock_info[mode_index].sclk > + rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN)) + continue; rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = VOLTAGE_SW; rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = @@ -1857,6 +1821,12 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk == 0) || (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0)) continue; + /* skip overclock modes for now */ + if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk > + rdev->clock.default_mclk + RADEON_MODE_OVERCLOCK_MARGIN) || + (rdev->pm.power_state[state_index].clock_info[mode_index].sclk > + rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN)) + continue; rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = VOLTAGE_SW; rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = @@ -1868,9 +1838,7 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) if (mode_index) { misc = le32_to_cpu(non_clock_info->ulCapsAndSettings); misc2 = le16_to_cpu(non_clock_info->usClassification); - rdev->pm.power_state[state_index].misc = misc; - rdev->pm.power_state[state_index].misc2 = misc2; - rdev->pm.power_state[state_index].pcie_lanes = + rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = ((misc & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1; switch (misc2 & ATOM_PPLIB_CLASSIFICATION_UI_MASK) { @@ -1887,36 +1855,22 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) POWER_STATE_TYPE_PERFORMANCE; break; } - rdev->pm.power_state[state_index].flags = 0; - if (misc & ATOM_PPLIB_SINGLE_DISPLAY_ONLY) - rdev->pm.power_state[state_index].flags |= - RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; if (misc2 & ATOM_PPLIB_CLASSIFICATION_BOOT) { rdev->pm.power_state[state_index].type = POWER_STATE_TYPE_DEFAULT; - rdev->pm.default_power_state_index = state_index; + rdev->pm.default_power_state = &rdev->pm.power_state[state_index]; rdev->pm.power_state[state_index].default_clock_mode = &rdev->pm.power_state[state_index].clock_info[mode_index - 1]; } state_index++; } } - /* if multiple clock modes, mark the lowest as no display */ - for (i = 0; i < state_index; i++) { - if (rdev->pm.power_state[i].num_clock_modes > 1) - rdev->pm.power_state[i].clock_info[0].flags |= - RADEON_PM_MODE_NO_DISPLAY; - } - /* first mode is usually default */ - if (rdev->pm.default_power_state_index == -1) { - rdev->pm.power_state[0].type = - POWER_STATE_TYPE_DEFAULT; - rdev->pm.default_power_state_index = 0; - rdev->pm.power_state[0].default_clock_mode = - &rdev->pm.power_state[0].clock_info[0]; - } } } else { + /* XXX figure out some good default low power mode for cards w/out power tables */ + } + + if (rdev->pm.default_power_state == NULL) { /* add the default mode */ rdev->pm.power_state[state_index].type = POWER_STATE_TYPE_DEFAULT; @@ -1926,16 +1880,18 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) rdev->pm.power_state[state_index].default_clock_mode = &rdev->pm.power_state[state_index].clock_info[0]; rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; - rdev->pm.power_state[state_index].pcie_lanes = 16; - rdev->pm.default_power_state_index = state_index; - rdev->pm.power_state[state_index].flags = 0; + if (rdev->asic->get_pcie_lanes) + rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = radeon_get_pcie_lanes(rdev); + else + rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = 16; + rdev->pm.default_power_state = &rdev->pm.power_state[state_index]; state_index++; } - rdev->pm.num_power_states = state_index; - rdev->pm.current_power_state_index = rdev->pm.default_power_state_index; - rdev->pm.current_clock_mode_index = 0; + rdev->pm.current_power_state = rdev->pm.default_power_state; + rdev->pm.current_clock_mode = + rdev->pm.default_power_state->default_clock_mode; } void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable) diff --git a/trunk/drivers/gpu/drm/radeon/radeon_bios.c b/trunk/drivers/gpu/drm/radeon/radeon_bios.c index fbba938f8048..8ad71f701316 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_bios.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_bios.c @@ -85,11 +85,12 @@ static bool radeon_read_bios(struct radeon_device *rdev) pci_unmap_rom(rdev->pdev, bios); return false; } - rdev->bios = kmemdup(bios, size, GFP_KERNEL); + rdev->bios = kmalloc(size, GFP_KERNEL); if (rdev->bios == NULL) { pci_unmap_rom(rdev->pdev, bios); return false; } + memcpy(rdev->bios, bios, size); pci_unmap_rom(rdev->pdev, bios); return true; } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_combios.c b/trunk/drivers/gpu/drm/radeon/radeon_combios.c index 93f18bbf744a..0f1fd9254e30 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_combios.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_combios.c @@ -1113,20 +1113,18 @@ struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder break; if ((RBIOS16(tmp) == lvds->native_mode.hdisplay) && - (RBIOS16(tmp + 2) == lvds->native_mode.vdisplay)) { - lvds->native_mode.htotal = lvds->native_mode.hdisplay + - (RBIOS16(tmp + 17) - RBIOS16(tmp + 19)) * 8; - lvds->native_mode.hsync_start = lvds->native_mode.hdisplay + - (RBIOS16(tmp + 21) - RBIOS16(tmp + 19) - 1) * 8; - lvds->native_mode.hsync_end = lvds->native_mode.hsync_start + - (RBIOS8(tmp + 23) * 8); - - lvds->native_mode.vtotal = lvds->native_mode.vdisplay + - (RBIOS16(tmp + 24) - RBIOS16(tmp + 26)); - lvds->native_mode.vsync_start = lvds->native_mode.vdisplay + - ((RBIOS16(tmp + 28) & 0x7ff) - RBIOS16(tmp + 26)); - lvds->native_mode.vsync_end = lvds->native_mode.vsync_start + - ((RBIOS16(tmp + 28) & 0xf800) >> 11); + (RBIOS16(tmp + 2) == + lvds->native_mode.vdisplay)) { + lvds->native_mode.htotal = RBIOS16(tmp + 17) * 8; + lvds->native_mode.hsync_start = RBIOS16(tmp + 21) * 8; + lvds->native_mode.hsync_end = (RBIOS8(tmp + 23) + + RBIOS16(tmp + 21)) * 8; + + lvds->native_mode.vtotal = RBIOS16(tmp + 24); + lvds->native_mode.vsync_start = RBIOS16(tmp + 28) & 0x7ff; + lvds->native_mode.vsync_end = + ((RBIOS16(tmp + 28) & 0xf800) >> 11) + + (RBIOS16(tmp + 28) & 0x7ff); lvds->native_mode.clock = RBIOS16(tmp + 9) * 10; lvds->native_mode.flags = 0; @@ -2368,7 +2366,7 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev) u8 rev, blocks, tmp; int state_index = 0; - rdev->pm.default_power_state_index = -1; + rdev->pm.default_power_state = NULL; if (rdev->flags & RADEON_IS_MOBILITY) { offset = combios_get_table_offset(dev, COMBIOS_POWERPLAY_INFO_TABLE); @@ -2382,13 +2380,17 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev) if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) goto default_mode; + /* skip overclock modes for now */ + if ((rdev->pm.power_state[state_index].clock_info[0].mclk > + rdev->clock.default_mclk + RADEON_MODE_OVERCLOCK_MARGIN) || + (rdev->pm.power_state[state_index].clock_info[0].sclk > + rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN)) + goto default_mode; rdev->pm.power_state[state_index].type = POWER_STATE_TYPE_BATTERY; misc = RBIOS16(offset + 0x5 + 0x0); if (rev > 4) misc2 = RBIOS16(offset + 0x5 + 0xe); - rdev->pm.power_state[state_index].misc = misc; - rdev->pm.power_state[state_index].misc2 = misc2; if (misc & 0x4) { rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_GPIO; if (misc & 0x8) @@ -2435,9 +2437,8 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev) } else rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; if (rev > 6) - rdev->pm.power_state[state_index].pcie_lanes = + rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = RBIOS8(offset + 0x5 + 0x10); - rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; state_index++; } else { /* XXX figure out some good default low power mode for mobility cards w/out power tables */ @@ -2455,13 +2456,16 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev) rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk; rdev->pm.power_state[state_index].default_clock_mode = &rdev->pm.power_state[state_index].clock_info[0]; rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; - rdev->pm.power_state[state_index].pcie_lanes = 16; - rdev->pm.power_state[state_index].flags = 0; - rdev->pm.default_power_state_index = state_index; + if (rdev->asic->get_pcie_lanes) + rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = radeon_get_pcie_lanes(rdev); + else + rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = 16; + rdev->pm.default_power_state = &rdev->pm.power_state[state_index]; rdev->pm.num_power_states = state_index + 1; - rdev->pm.current_power_state_index = rdev->pm.default_power_state_index; - rdev->pm.current_clock_mode_index = 0; + rdev->pm.current_power_state = rdev->pm.default_power_state; + rdev->pm.current_clock_mode = + rdev->pm.default_power_state->default_clock_mode; } void radeon_external_tmds_setup(struct drm_encoder *encoder) diff --git a/trunk/drivers/gpu/drm/radeon/radeon_connectors.c b/trunk/drivers/gpu/drm/radeon/radeon_connectors.c index 765854ed33c2..c48934677adf 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_connectors.c @@ -1085,7 +1085,6 @@ radeon_add_atom_connector(struct drm_device *dev, drm_connector_attach_property(&radeon_connector->base, rdev->mode_info.load_detect_property, 1); - connector->polled = DRM_CONNECTOR_POLL_CONNECT; break; case DRM_MODE_CONNECTOR_DVIA: drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); @@ -1212,12 +1211,6 @@ radeon_add_atom_connector(struct drm_device *dev, break; } - if (hpd->hpd == RADEON_HPD_NONE) { - if (i2c_bus->valid) - connector->polled = DRM_CONNECTOR_POLL_CONNECT; - } else - connector->polled = DRM_CONNECTOR_POLL_HPD; - connector->display_info.subpixel_order = subpixel_order; drm_sysfs_connector_add(connector); return; @@ -1279,7 +1272,6 @@ radeon_add_legacy_connector(struct drm_device *dev, drm_connector_attach_property(&radeon_connector->base, rdev->mode_info.load_detect_property, 1); - connector->polled = DRM_CONNECTOR_POLL_CONNECT; break; case DRM_MODE_CONNECTOR_DVIA: drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); @@ -1346,11 +1338,6 @@ radeon_add_legacy_connector(struct drm_device *dev, break; } - if (hpd->hpd == RADEON_HPD_NONE) { - if (i2c_bus->valid) - connector->polled = DRM_CONNECTOR_POLL_CONNECT; - } else - connector->polled = DRM_CONNECTOR_POLL_HPD; connector->display_info.subpixel_order = subpixel_order; drm_sysfs_connector_add(connector); return; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_device.c b/trunk/drivers/gpu/drm/radeon/radeon_device.c index a20b612ffe75..26217ffe0355 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_device.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_device.c @@ -299,24 +299,24 @@ void radeon_update_bandwidth_info(struct radeon_device *rdev) sclk = radeon_get_engine_clock(rdev); mclk = rdev->clock.default_mclk; - a.full = dfixed_const(100); - rdev->pm.sclk.full = dfixed_const(sclk); - rdev->pm.sclk.full = dfixed_div(rdev->pm.sclk, a); - rdev->pm.mclk.full = dfixed_const(mclk); - rdev->pm.mclk.full = dfixed_div(rdev->pm.mclk, a); + a.full = rfixed_const(100); + rdev->pm.sclk.full = rfixed_const(sclk); + rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); + rdev->pm.mclk.full = rfixed_const(mclk); + rdev->pm.mclk.full = rfixed_div(rdev->pm.mclk, a); - a.full = dfixed_const(16); + a.full = rfixed_const(16); /* core_bandwidth = sclk(Mhz) * 16 */ - rdev->pm.core_bandwidth.full = dfixed_div(rdev->pm.sclk, a); + rdev->pm.core_bandwidth.full = rfixed_div(rdev->pm.sclk, a); } else { sclk = radeon_get_engine_clock(rdev); mclk = radeon_get_memory_clock(rdev); - a.full = dfixed_const(100); - rdev->pm.sclk.full = dfixed_const(sclk); - rdev->pm.sclk.full = dfixed_div(rdev->pm.sclk, a); - rdev->pm.mclk.full = dfixed_const(mclk); - rdev->pm.mclk.full = dfixed_div(rdev->pm.mclk, a); + a.full = rfixed_const(100); + rdev->pm.sclk.full = rfixed_const(sclk); + rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); + rdev->pm.mclk.full = rfixed_const(mclk); + rdev->pm.mclk.full = rfixed_div(rdev->pm.mclk, a); } } @@ -599,11 +599,9 @@ int radeon_device_init(struct radeon_device *rdev, spin_lock_init(&rdev->ih.lock); mutex_init(&rdev->gem.mutex); mutex_init(&rdev->pm.mutex); - mutex_init(&rdev->vram_mutex); rwlock_init(&rdev->fence_drv.lock); INIT_LIST_HEAD(&rdev->gem.objects); init_waitqueue_head(&rdev->irq.vblank_queue); - init_waitqueue_head(&rdev->irq.idle_queue); /* setup workqueue */ rdev->wq = create_workqueue("radeon"); @@ -748,7 +746,6 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) radeon_save_bios_scratch_regs(rdev); - radeon_pm_suspend(rdev); radeon_suspend(rdev); radeon_hpd_fini(rdev); /* evict remaining vram memory */ @@ -784,7 +781,6 @@ int radeon_resume_kms(struct drm_device *dev) /* resume AGP if in use */ radeon_agp_resume(rdev); radeon_resume(rdev); - radeon_pm_resume(rdev); radeon_restore_bios_scratch_regs(rdev); radeon_fbdev_set_suspend(rdev, 0); release_console_sem(); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_display.c b/trunk/drivers/gpu/drm/radeon/radeon_display.c index f48f42454fbb..243c1c4bc836 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_display.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_display.c @@ -633,37 +633,37 @@ calc_fb_div(struct radeon_pll *pll, vco_freq = freq * post_div; /* feedback_divider = vco_freq * ref_div / pll->reference_freq; */ - a.full = dfixed_const(pll->reference_freq); - feedback_divider.full = dfixed_const(vco_freq); - feedback_divider.full = dfixed_div(feedback_divider, a); - a.full = dfixed_const(ref_div); - feedback_divider.full = dfixed_mul(feedback_divider, a); + a.full = rfixed_const(pll->reference_freq); + feedback_divider.full = rfixed_const(vco_freq); + feedback_divider.full = rfixed_div(feedback_divider, a); + a.full = rfixed_const(ref_div); + feedback_divider.full = rfixed_mul(feedback_divider, a); if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) { /* feedback_divider = floor((feedback_divider * 10.0) + 0.5) * 0.1; */ - a.full = dfixed_const(10); - feedback_divider.full = dfixed_mul(feedback_divider, a); - feedback_divider.full += dfixed_const_half(0); - feedback_divider.full = dfixed_floor(feedback_divider); - feedback_divider.full = dfixed_div(feedback_divider, a); + a.full = rfixed_const(10); + feedback_divider.full = rfixed_mul(feedback_divider, a); + feedback_divider.full += rfixed_const_half(0); + feedback_divider.full = rfixed_floor(feedback_divider); + feedback_divider.full = rfixed_div(feedback_divider, a); /* *fb_div = floor(feedback_divider); */ - a.full = dfixed_floor(feedback_divider); - *fb_div = dfixed_trunc(a); + a.full = rfixed_floor(feedback_divider); + *fb_div = rfixed_trunc(a); /* *fb_div_frac = fmod(feedback_divider, 1.0) * 10.0; */ - a.full = dfixed_const(10); - b.full = dfixed_mul(feedback_divider, a); + a.full = rfixed_const(10); + b.full = rfixed_mul(feedback_divider, a); - feedback_divider.full = dfixed_floor(feedback_divider); - feedback_divider.full = dfixed_mul(feedback_divider, a); + feedback_divider.full = rfixed_floor(feedback_divider); + feedback_divider.full = rfixed_mul(feedback_divider, a); feedback_divider.full = b.full - feedback_divider.full; - *fb_div_frac = dfixed_trunc(feedback_divider); + *fb_div_frac = rfixed_trunc(feedback_divider); } else { /* *fb_div = floor(feedback_divider + 0.5); */ - feedback_divider.full += dfixed_const_half(0); - feedback_divider.full = dfixed_floor(feedback_divider); + feedback_divider.full += rfixed_const_half(0); + feedback_divider.full = rfixed_floor(feedback_divider); - *fb_div = dfixed_trunc(feedback_divider); + *fb_div = rfixed_trunc(feedback_divider); *fb_div_frac = 0; } @@ -693,10 +693,10 @@ calc_fb_ref_div(struct radeon_pll *pll, pll_out_max = pll->pll_out_max; } - ffreq.full = dfixed_const(freq); + ffreq.full = rfixed_const(freq); /* max_error = ffreq * 0.0025; */ - a.full = dfixed_const(400); - max_error.full = dfixed_div(ffreq, a); + a.full = rfixed_const(400); + max_error.full = rfixed_div(ffreq, a); for ((*ref_div) = pll->min_ref_div; (*ref_div) < pll->max_ref_div; ++(*ref_div)) { if (calc_fb_div(pll, freq, post_div, (*ref_div), fb_div, fb_div_frac)) { @@ -707,9 +707,9 @@ calc_fb_ref_div(struct radeon_pll *pll, continue; /* pll_out = vco / post_div; */ - a.full = dfixed_const(post_div); - pll_out.full = dfixed_const(vco); - pll_out.full = dfixed_div(pll_out, a); + a.full = rfixed_const(post_div); + pll_out.full = rfixed_const(vco); + pll_out.full = rfixed_div(pll_out, a); if (pll_out.full >= ffreq.full) { error.full = pll_out.full - ffreq.full; @@ -888,15 +888,8 @@ radeon_user_framebuffer_create(struct drm_device *dev, return &radeon_fb->base; } -static void radeon_output_poll_changed(struct drm_device *dev) -{ - struct radeon_device *rdev = dev->dev_private; - radeon_fb_output_poll_changed(rdev); -} - static const struct drm_mode_config_funcs radeon_mode_funcs = { .fb_create = radeon_user_framebuffer_create, - .output_poll_changed = radeon_output_poll_changed }; struct drm_prop_enum_list { @@ -1037,12 +1030,7 @@ int radeon_modeset_init(struct radeon_device *rdev) /* initialize hpd */ radeon_hpd_init(rdev); - /* Initialize power management */ - radeon_pm_init(rdev); - radeon_fbdev_init(rdev); - drm_kms_helper_poll_init(rdev->ddev); - return 0; } @@ -1050,10 +1038,8 @@ void radeon_modeset_fini(struct radeon_device *rdev) { radeon_fbdev_fini(rdev); kfree(rdev->mode_info.bios_hardcoded_edid); - radeon_pm_fini(rdev); if (rdev->mode_info.mode_config_initialized) { - drm_kms_helper_poll_fini(rdev->ddev); radeon_hpd_fini(rdev); drm_mode_config_cleanup(rdev->ddev); rdev->mode_info.mode_config_initialized = false; @@ -1103,15 +1089,15 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, } if (radeon_crtc->rmx_type != RMX_OFF) { fixed20_12 a, b; - a.full = dfixed_const(crtc->mode.vdisplay); - b.full = dfixed_const(radeon_crtc->native_mode.hdisplay); - radeon_crtc->vsc.full = dfixed_div(a, b); - a.full = dfixed_const(crtc->mode.hdisplay); - b.full = dfixed_const(radeon_crtc->native_mode.vdisplay); - radeon_crtc->hsc.full = dfixed_div(a, b); + a.full = rfixed_const(crtc->mode.vdisplay); + b.full = rfixed_const(radeon_crtc->native_mode.hdisplay); + radeon_crtc->vsc.full = rfixed_div(a, b); + a.full = rfixed_const(crtc->mode.hdisplay); + b.full = rfixed_const(radeon_crtc->native_mode.vdisplay); + radeon_crtc->hsc.full = rfixed_div(a, b); } else { - radeon_crtc->vsc.full = dfixed_const(1); - radeon_crtc->hsc.full = dfixed_const(1); + radeon_crtc->vsc.full = rfixed_const(1); + radeon_crtc->hsc.full = rfixed_const(1); } return true; } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_drv.c b/trunk/drivers/gpu/drm/radeon/radeon_drv.c index 4afba1eca2a7..4b05563d99e1 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_drv.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_drv.c @@ -44,10 +44,9 @@ * - 2.1.0 - add square tiling interface * - 2.2.0 - add r6xx/r7xx const buffer support * - 2.3.0 - add MSPOS + 3D texture + r500 VAP regs - * - 2.4.0 - add crtc id query */ #define KMS_DRIVER_MAJOR 2 -#define KMS_DRIVER_MINOR 4 +#define KMS_DRIVER_MINOR 3 #define KMS_DRIVER_PATCHLEVEL 0 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); int radeon_driver_unload_kms(struct drm_device *dev); @@ -92,6 +91,7 @@ int radeon_testing = 0; int radeon_connector_table = 0; int radeon_tv = 1; int radeon_new_pll = -1; +int radeon_dynpm = -1; int radeon_audio = 1; int radeon_disp_priority = 0; int radeon_hw_i2c = 0; @@ -132,6 +132,9 @@ module_param_named(tv, radeon_tv, int, 0444); MODULE_PARM_DESC(new_pll, "Select new PLL code"); module_param_named(new_pll, radeon_new_pll, int, 0444); +MODULE_PARM_DESC(dynpm, "Disable/Enable dynamic power management (1 = enable)"); +module_param_named(dynpm, radeon_dynpm, int, 0444); + MODULE_PARM_DESC(audio, "Audio enable (0 = disable)"); module_param_named(audio, radeon_audio, int, 0444); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_encoders.c b/trunk/drivers/gpu/drm/radeon/radeon_encoders.c index b5dff14ea8c6..30293bec0801 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_encoders.c @@ -262,6 +262,9 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; + /* adjust pm to upcoming mode change */ + radeon_pm_compute_clocks(rdev); + /* set the active encoder to connector routing */ radeon_encoder_set_active_device(encoder); drm_mode_set_crtcinfo(adjusted_mode, 0); @@ -1071,6 +1074,8 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) } radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); + /* adjust pm to dpms change */ + radeon_pm_compute_clocks(rdev); } union crtc_source_param { @@ -1504,49 +1509,10 @@ static void radeon_atom_encoder_commit(struct drm_encoder *encoder) static void radeon_atom_encoder_disable(struct drm_encoder *encoder) { - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder_atom_dig *dig; radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_TMDS1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: - case ENCODER_OBJECT_ID_INTERNAL_LVDS: - case ENCODER_OBJECT_ID_INTERNAL_LVTM1: - atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_DISABLE); - break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: - if (ASIC_IS_DCE4(rdev)) - /* disable the transmitter */ - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); - else { - /* disable the encoder and transmitter */ - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); - atombios_dig_encoder_setup(encoder, ATOM_DISABLE); - } - break; - case ENCODER_OBJECT_ID_INTERNAL_DDI: - atombios_ddia_setup(encoder, ATOM_DISABLE); - break; - case ENCODER_OBJECT_ID_INTERNAL_DVO1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: - atombios_external_tmds_setup(encoder, ATOM_DISABLE); - break; - case ENCODER_OBJECT_ID_INTERNAL_DAC1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: - case ENCODER_OBJECT_ID_INTERNAL_DAC2: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: - atombios_dac_setup(encoder, ATOM_DISABLE); - if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) - atombios_tv_setup(encoder, ATOM_DISABLE); - break; - } - if (radeon_encoder_is_digital(encoder)) { if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) r600_hdmi_disable(encoder); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_fb.c b/trunk/drivers/gpu/drm/radeon/radeon_fb.c index e192acfbf0cd..fcb5b52727b0 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_fb.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_fb.c @@ -236,13 +236,8 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev, drm_fb_helper_fill_var(info, &rfbdev->helper, sizes->fb_width, sizes->fb_height); /* setup aperture base/size for vesafb takeover */ - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto out_unref; - } - info->apertures->ranges[0].base = rdev->ddev->mode_config.fb_base; - info->apertures->ranges[0].size = rdev->mc.real_vram_size; + info->aperture_base = rdev->ddev->mode_config.fb_base; + info->aperture_size = rdev->mc.real_vram_size; info->fix.mmio_start = 0; info->fix.mmio_len = 0; @@ -316,9 +311,16 @@ int radeon_parse_options(char *options) return 0; } -void radeon_fb_output_poll_changed(struct radeon_device *rdev) +void radeonfb_hotplug(struct drm_device *dev, bool polled) +{ + struct radeon_device *rdev = dev->dev_private; + + drm_helper_fb_hpd_irq_event(&rdev->mode_info.rfbdev->helper); +} + +static void radeon_fb_output_status_changed(struct drm_fb_helper *fb_helper) { - drm_fb_helper_hotplug_event(&rdev->mode_info.rfbdev->helper); + drm_helper_fb_hotplug_event(fb_helper, true); } static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfbdev) @@ -357,6 +359,7 @@ static struct drm_fb_helper_funcs radeon_fb_helper_funcs = { .gamma_set = radeon_crtc_fb_gamma_set, .gamma_get = radeon_crtc_fb_gamma_get, .fb_probe = radeon_fb_find_or_create_single, + .fb_output_status_changed = radeon_fb_output_status_changed, }; int radeon_fbdev_init(struct radeon_device *rdev) @@ -378,10 +381,11 @@ int radeon_fbdev_init(struct radeon_device *rdev) drm_fb_helper_init(rdev->ddev, &rfbdev->helper, rdev->num_crtc, - RADEONFB_CONN_LIMIT); + RADEONFB_CONN_LIMIT, true); drm_fb_helper_single_add_all_connectors(&rfbdev->helper); drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel); return 0; + } void radeon_fbdev_fini(struct radeon_device *rdev) diff --git a/trunk/include/drm/drm_fixed.h b/trunk/drivers/gpu/drm/radeon/radeon_fixed.h similarity index 60% rename from trunk/include/drm/drm_fixed.h rename to trunk/drivers/gpu/drm/radeon/radeon_fixed.h index 4a08a664ff1f..3d4d84e078ac 100644 --- a/trunk/include/drm/drm_fixed.h +++ b/trunk/drivers/gpu/drm/radeon/radeon_fixed.h @@ -21,41 +21,41 @@ * * Authors: Dave Airlie */ -#ifndef DRM_FIXED_H -#define DRM_FIXED_H +#ifndef RADEON_FIXED_H +#define RADEON_FIXED_H -typedef union dfixed { +typedef union rfixed { u32 full; } fixed20_12; -#define dfixed_const(A) (u32)(((A) << 12))/* + ((B + 0.000122)*4096)) */ -#define dfixed_const_half(A) (u32)(((A) << 12) + 2048) -#define dfixed_const_666(A) (u32)(((A) << 12) + 2731) -#define dfixed_const_8(A) (u32)(((A) << 12) + 3277) -#define dfixed_mul(A, B) ((u64)((u64)(A).full * (B).full + 2048) >> 12) -#define dfixed_init(A) { .full = dfixed_const((A)) } -#define dfixed_init_half(A) { .full = dfixed_const_half((A)) } -#define dfixed_trunc(A) ((A).full >> 12) +#define rfixed_const(A) (u32)(((A) << 12))/* + ((B + 0.000122)*4096)) */ +#define rfixed_const_half(A) (u32)(((A) << 12) + 2048) +#define rfixed_const_666(A) (u32)(((A) << 12) + 2731) +#define rfixed_const_8(A) (u32)(((A) << 12) + 3277) +#define rfixed_mul(A, B) ((u64)((u64)(A).full * (B).full + 2048) >> 12) +#define fixed_init(A) { .full = rfixed_const((A)) } +#define fixed_init_half(A) { .full = rfixed_const_half((A)) } +#define rfixed_trunc(A) ((A).full >> 12) -static inline u32 dfixed_floor(fixed20_12 A) +static inline u32 rfixed_floor(fixed20_12 A) { - u32 non_frac = dfixed_trunc(A); + u32 non_frac = rfixed_trunc(A); - return dfixed_const(non_frac); + return rfixed_const(non_frac); } -static inline u32 dfixed_ceil(fixed20_12 A) +static inline u32 rfixed_ceil(fixed20_12 A) { - u32 non_frac = dfixed_trunc(A); + u32 non_frac = rfixed_trunc(A); - if (A.full > dfixed_const(non_frac)) - return dfixed_const(non_frac + 1); + if (A.full > rfixed_const(non_frac)) + return rfixed_const(non_frac + 1); else - return dfixed_const(non_frac); + return rfixed_const(non_frac); } -static inline u32 dfixed_div(fixed20_12 A, fixed20_12 B) +static inline u32 rfixed_div(fixed20_12 A, fixed20_12 B) { u64 tmp = ((u64)A.full << 13); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c b/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c index 059bfa4098d7..a95907aa7eae 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c @@ -26,7 +26,6 @@ * Jerome Glisse */ #include "drmP.h" -#include "drm_crtc_helper.h" #include "radeon_drm.h" #include "radeon_reg.h" #include "radeon.h" @@ -56,7 +55,9 @@ static void radeon_hotplug_work_func(struct work_struct *work) radeon_connector_hotplug(connector); } /* Just fire off a uevent and let userspace tell us what to do */ - drm_helper_hpd_irq_event(dev); + radeonfb_hotplug(dev, false); + + drm_sysfs_hotplug_event(dev); } void radeon_driver_irq_preinstall_kms(struct drm_device *dev) @@ -68,7 +69,6 @@ void radeon_driver_irq_preinstall_kms(struct drm_device *dev) /* Disable *all* interrupts */ rdev->irq.sw_int = false; - rdev->irq.gui_idle = false; for (i = 0; i < rdev->num_crtc; i++) rdev->irq.crtc_vblank_int[i] = false; for (i = 0; i < 6; i++) @@ -98,7 +98,6 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev) } /* Disable *all* interrupts */ rdev->irq.sw_int = false; - rdev->irq.gui_idle = false; for (i = 0; i < rdev->num_crtc; i++) rdev->irq.crtc_vblank_int[i] = false; for (i = 0; i < 6; i++) diff --git a/trunk/drivers/gpu/drm/radeon/radeon_kms.c b/trunk/drivers/gpu/drm/radeon/radeon_kms.c index 021572a3dd9c..d3657dcfdd26 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_kms.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_kms.c @@ -98,15 +98,11 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { struct radeon_device *rdev = dev->dev_private; struct drm_radeon_info *info; - struct radeon_mode_info *minfo = &rdev->mode_info; uint32_t *value_ptr; uint32_t value; - struct drm_crtc *crtc; - int i, found; info = data; value_ptr = (uint32_t *)((unsigned long)info->value); - value = *value_ptr; switch (info->request) { case RADEON_INFO_DEVICE_ID: value = dev->pci_device; @@ -120,20 +116,6 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) case RADEON_INFO_ACCEL_WORKING: value = rdev->accel_working; break; - case RADEON_INFO_CRTC_FROM_ID: - for (i = 0, found = 0; i < rdev->num_crtc; i++) { - crtc = (struct drm_crtc *)minfo->crtcs[i]; - if (crtc && crtc->base.id == value) { - value = i; - found = 1; - break; - } - } - if (!found) { - DRM_DEBUG("unknown crtc id %d\n", value); - return -EINVAL; - } - break; default: DRM_DEBUG("Invalid request %d\n", info->request); return -EINVAL; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index e1e5255396ac..88865e38fe30 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include "radeon_fixed.h" #include "radeon.h" #include "atom.h" @@ -314,9 +314,6 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) switch (mode) { case DRM_MODE_DPMS_ON: - radeon_crtc->enabled = true; - /* adjust pm to dpms changes BEFORE enabling crtcs */ - radeon_pm_compute_clocks(rdev); if (radeon_crtc->crtc_id) WREG32_P(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_EN, ~(RADEON_CRTC2_EN | mask)); else { @@ -338,9 +335,6 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) RADEON_CRTC_DISP_REQ_EN_B)); WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~mask); } - radeon_crtc->enabled = false; - /* adjust pm to dpms changes AFTER disabling crtcs */ - radeon_pm_compute_clocks(rdev); break; } } @@ -972,12 +966,6 @@ static bool radeon_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - - /* adjust pm to upcoming mode change */ - radeon_pm_compute_clocks(rdev); - if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode)) return false; return true; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 341df86a253b..2441cca7d775 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c @@ -116,6 +116,8 @@ static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) else radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); + /* adjust pm to dpms change */ + radeon_pm_compute_clocks(rdev); } static void radeon_legacy_lvds_prepare(struct drm_encoder *encoder) @@ -215,6 +217,11 @@ static bool radeon_legacy_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *adjusted_mode) { struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct drm_device *dev = encoder->dev; + struct radeon_device *rdev = dev->dev_private; + + /* adjust pm to upcoming mode change */ + radeon_pm_compute_clocks(rdev); /* set the active encoder to connector routing */ radeon_encoder_set_active_device(encoder); @@ -287,6 +294,8 @@ static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode else radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); + /* adjust pm to dpms change */ + radeon_pm_compute_clocks(rdev); } static void radeon_legacy_primary_dac_prepare(struct drm_encoder *encoder) @@ -473,6 +482,8 @@ static void radeon_legacy_tmds_int_dpms(struct drm_encoder *encoder, int mode) else radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); + /* adjust pm to dpms change */ + radeon_pm_compute_clocks(rdev); } static void radeon_legacy_tmds_int_prepare(struct drm_encoder *encoder) @@ -639,6 +650,8 @@ static void radeon_legacy_tmds_ext_dpms(struct drm_encoder *encoder, int mode) else radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); + /* adjust pm to dpms change */ + radeon_pm_compute_clocks(rdev); } static void radeon_legacy_tmds_ext_prepare(struct drm_encoder *encoder) @@ -847,6 +860,8 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) else radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); + /* adjust pm to dpms change */ + radeon_pm_compute_clocks(rdev); } static void radeon_legacy_tv_dac_prepare(struct drm_encoder *encoder) diff --git a/trunk/drivers/gpu/drm/radeon/radeon_mode.h b/trunk/drivers/gpu/drm/radeon/radeon_mode.h index 38c0b63e9bbd..dd451c55c533 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_mode.h +++ b/trunk/drivers/gpu/drm/radeon/radeon_mode.h @@ -34,10 +34,10 @@ #include #include #include -#include #include #include #include +#include "radeon_fixed.h" struct radeon_bo; struct radeon_device; @@ -586,6 +586,5 @@ void radeon_fbdev_fini(struct radeon_device *rdev); void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state); int radeon_fbdev_total_size(struct radeon_device *rdev); bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj); - -void radeon_fb_output_poll_changed(struct radeon_device *rdev); +void radeonfb_hotplug(struct drm_device *dev, bool polled); #endif diff --git a/trunk/drivers/gpu/drm/radeon/radeon_object.c b/trunk/drivers/gpu/drm/radeon/radeon_object.c index a8d18bcae7db..6a8617bac142 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_object.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_object.c @@ -112,11 +112,9 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, radeon_ttm_placement_from_domain(bo, domain); /* Kernel allocation are uninterruptible */ - mutex_lock(&rdev->vram_mutex); r = ttm_bo_init(&rdev->mman.bdev, &bo->tbo, size, type, &bo->placement, 0, 0, !kernel, NULL, size, &radeon_ttm_bo_destroy); - mutex_unlock(&rdev->vram_mutex); if (unlikely(r != 0)) { if (r != -ERESTARTSYS) dev_err(rdev->dev, @@ -168,15 +166,11 @@ void radeon_bo_kunmap(struct radeon_bo *bo) void radeon_bo_unref(struct radeon_bo **bo) { struct ttm_buffer_object *tbo; - struct radeon_device *rdev; if ((*bo) == NULL) return; - rdev = (*bo)->rdev; tbo = &((*bo)->tbo); - mutex_lock(&rdev->vram_mutex); ttm_bo_unref(&tbo); - mutex_unlock(&rdev->vram_mutex); if (tbo == NULL) *bo = NULL; } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_pm.c b/trunk/drivers/gpu/drm/radeon/radeon_pm.c index a8d162c6f829..a4b57493aa78 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_pm.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_pm.c @@ -23,122 +23,164 @@ #include "drmP.h" #include "radeon.h" #include "avivod.h" -#ifdef CONFIG_ACPI -#include -#endif -#include #define RADEON_IDLE_LOOP_MS 100 #define RADEON_RECLOCK_DELAY_MS 200 #define RADEON_WAIT_VBLANK_TIMEOUT 200 -#define RADEON_WAIT_IDLE_TIMEOUT 200 -static void radeon_dynpm_idle_work_handler(struct work_struct *work); -static int radeon_debugfs_pm_init(struct radeon_device *rdev); -static bool radeon_pm_in_vbl(struct radeon_device *rdev); static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish); -static void radeon_pm_update_profile(struct radeon_device *rdev); +static void radeon_pm_set_clocks_locked(struct radeon_device *rdev); static void radeon_pm_set_clocks(struct radeon_device *rdev); +static void radeon_pm_idle_work_handler(struct work_struct *work); +static int radeon_debugfs_pm_init(struct radeon_device *rdev); + +static const char *pm_state_names[4] = { + "PM_STATE_DISABLED", + "PM_STATE_MINIMUM", + "PM_STATE_PAUSED", + "PM_STATE_ACTIVE" +}; -#define ACPI_AC_CLASS "ac_adapter" +static const char *pm_state_types[5] = { + "Default", + "Powersave", + "Battery", + "Balanced", + "Performance", +}; -#ifdef CONFIG_ACPI -static int radeon_acpi_event(struct notifier_block *nb, - unsigned long val, - void *data) +static void radeon_print_power_mode_info(struct radeon_device *rdev) { - struct radeon_device *rdev = container_of(nb, struct radeon_device, acpi_nb); - struct acpi_bus_event *entry = (struct acpi_bus_event *)data; + int i, j; + bool is_default; - if (strcmp(entry->device_class, ACPI_AC_CLASS) == 0) { - if (power_supply_is_system_supplied() > 0) - DRM_DEBUG("pm: AC\n"); + DRM_INFO("%d Power State(s)\n", rdev->pm.num_power_states); + for (i = 0; i < rdev->pm.num_power_states; i++) { + if (rdev->pm.default_power_state == &rdev->pm.power_state[i]) + is_default = true; else - DRM_DEBUG("pm: DC\n"); - - if (rdev->pm.pm_method == PM_METHOD_PROFILE) { - if (rdev->pm.profile == PM_PROFILE_AUTO) { - mutex_lock(&rdev->pm.mutex); - radeon_pm_update_profile(rdev); - radeon_pm_set_clocks(rdev); - mutex_unlock(&rdev->pm.mutex); - } + is_default = false; + DRM_INFO("State %d %s %s\n", i, + pm_state_types[rdev->pm.power_state[i].type], + is_default ? "(default)" : ""); + if ((rdev->flags & RADEON_IS_PCIE) && !(rdev->flags & RADEON_IS_IGP)) + DRM_INFO("\t%d PCIE Lanes\n", rdev->pm.power_state[i].non_clock_info.pcie_lanes); + DRM_INFO("\t%d Clock Mode(s)\n", rdev->pm.power_state[i].num_clock_modes); + for (j = 0; j < rdev->pm.power_state[i].num_clock_modes; j++) { + if (rdev->flags & RADEON_IS_IGP) + DRM_INFO("\t\t%d engine: %d\n", + j, + rdev->pm.power_state[i].clock_info[j].sclk * 10); + else + DRM_INFO("\t\t%d engine/memory: %d/%d\n", + j, + rdev->pm.power_state[i].clock_info[j].sclk * 10, + rdev->pm.power_state[i].clock_info[j].mclk * 10); } } - - return NOTIFY_OK; } -#endif -static void radeon_pm_update_profile(struct radeon_device *rdev) +static struct radeon_power_state * radeon_pick_power_state(struct radeon_device *rdev, + enum radeon_pm_state_type type) { - switch (rdev->pm.profile) { - case PM_PROFILE_DEFAULT: - rdev->pm.profile_index = PM_PROFILE_DEFAULT_IDX; - break; - case PM_PROFILE_AUTO: - if (power_supply_is_system_supplied() > 0) { - if (rdev->pm.active_crtc_count > 1) - rdev->pm.profile_index = PM_PROFILE_HIGH_MH_IDX; - else - rdev->pm.profile_index = PM_PROFILE_HIGH_SH_IDX; + int i, j; + enum radeon_pm_state_type wanted_types[2]; + int wanted_count; + + switch (type) { + case POWER_STATE_TYPE_DEFAULT: + default: + return rdev->pm.default_power_state; + case POWER_STATE_TYPE_POWERSAVE: + if (rdev->flags & RADEON_IS_MOBILITY) { + wanted_types[0] = POWER_STATE_TYPE_POWERSAVE; + wanted_types[1] = POWER_STATE_TYPE_BATTERY; + wanted_count = 2; } else { - if (rdev->pm.active_crtc_count > 1) - rdev->pm.profile_index = PM_PROFILE_LOW_MH_IDX; - else - rdev->pm.profile_index = PM_PROFILE_LOW_SH_IDX; + wanted_types[0] = POWER_STATE_TYPE_PERFORMANCE; + wanted_count = 1; } break; - case PM_PROFILE_LOW: - if (rdev->pm.active_crtc_count > 1) - rdev->pm.profile_index = PM_PROFILE_LOW_MH_IDX; - else - rdev->pm.profile_index = PM_PROFILE_LOW_SH_IDX; + case POWER_STATE_TYPE_BATTERY: + if (rdev->flags & RADEON_IS_MOBILITY) { + wanted_types[0] = POWER_STATE_TYPE_BATTERY; + wanted_types[1] = POWER_STATE_TYPE_POWERSAVE; + wanted_count = 2; + } else { + wanted_types[0] = POWER_STATE_TYPE_PERFORMANCE; + wanted_count = 1; + } break; - case PM_PROFILE_HIGH: - if (rdev->pm.active_crtc_count > 1) - rdev->pm.profile_index = PM_PROFILE_HIGH_MH_IDX; - else - rdev->pm.profile_index = PM_PROFILE_HIGH_SH_IDX; + case POWER_STATE_TYPE_BALANCED: + case POWER_STATE_TYPE_PERFORMANCE: + wanted_types[0] = type; + wanted_count = 1; break; } - if (rdev->pm.active_crtc_count == 0) { - rdev->pm.requested_power_state_index = - rdev->pm.profiles[rdev->pm.profile_index].dpms_off_ps_idx; - rdev->pm.requested_clock_mode_index = - rdev->pm.profiles[rdev->pm.profile_index].dpms_off_cm_idx; - } else { - rdev->pm.requested_power_state_index = - rdev->pm.profiles[rdev->pm.profile_index].dpms_on_ps_idx; - rdev->pm.requested_clock_mode_index = - rdev->pm.profiles[rdev->pm.profile_index].dpms_on_cm_idx; + for (i = 0; i < wanted_count; i++) { + for (j = 0; j < rdev->pm.num_power_states; j++) { + if (rdev->pm.power_state[j].type == wanted_types[i]) + return &rdev->pm.power_state[j]; + } } + + return rdev->pm.default_power_state; } -static void radeon_unmap_vram_bos(struct radeon_device *rdev) +static struct radeon_pm_clock_info * radeon_pick_clock_mode(struct radeon_device *rdev, + struct radeon_power_state *power_state, + enum radeon_pm_clock_mode_type type) { - struct radeon_bo *bo, *n; - - if (list_empty(&rdev->gem.objects)) - return; - - list_for_each_entry_safe(bo, n, &rdev->gem.objects, list) { - if (bo->tbo.mem.mem_type == TTM_PL_VRAM) - ttm_bo_unmap_virtual(&bo->tbo); + switch (type) { + case POWER_MODE_TYPE_DEFAULT: + default: + return power_state->default_clock_mode; + case POWER_MODE_TYPE_LOW: + return &power_state->clock_info[0]; + case POWER_MODE_TYPE_MID: + if (power_state->num_clock_modes > 2) + return &power_state->clock_info[1]; + else + return &power_state->clock_info[0]; + break; + case POWER_MODE_TYPE_HIGH: + return &power_state->clock_info[power_state->num_clock_modes - 1]; } - if (rdev->gart.table.vram.robj) - ttm_bo_unmap_virtual(&rdev->gart.table.vram.robj->tbo); - - if (rdev->stollen_vga_memory) - ttm_bo_unmap_virtual(&rdev->stollen_vga_memory->tbo); +} - if (rdev->r600_blit.shader_obj) - ttm_bo_unmap_virtual(&rdev->r600_blit.shader_obj->tbo); +static void radeon_get_power_state(struct radeon_device *rdev, + enum radeon_pm_action action) +{ + switch (action) { + case PM_ACTION_MINIMUM: + rdev->pm.requested_power_state = radeon_pick_power_state(rdev, POWER_STATE_TYPE_BATTERY); + rdev->pm.requested_clock_mode = + radeon_pick_clock_mode(rdev, rdev->pm.requested_power_state, POWER_MODE_TYPE_LOW); + break; + case PM_ACTION_DOWNCLOCK: + rdev->pm.requested_power_state = radeon_pick_power_state(rdev, POWER_STATE_TYPE_POWERSAVE); + rdev->pm.requested_clock_mode = + radeon_pick_clock_mode(rdev, rdev->pm.requested_power_state, POWER_MODE_TYPE_MID); + break; + case PM_ACTION_UPCLOCK: + rdev->pm.requested_power_state = radeon_pick_power_state(rdev, POWER_STATE_TYPE_DEFAULT); + rdev->pm.requested_clock_mode = + radeon_pick_clock_mode(rdev, rdev->pm.requested_power_state, POWER_MODE_TYPE_HIGH); + break; + case PM_ACTION_NONE: + default: + DRM_ERROR("Requested mode for not defined action\n"); + return; + } + DRM_INFO("Requested: e: %d m: %d p: %d\n", + rdev->pm.requested_clock_mode->sclk, + rdev->pm.requested_clock_mode->mclk, + rdev->pm.requested_power_state->non_clock_info.pcie_lanes); } -static void radeon_sync_with_vblank(struct radeon_device *rdev) +static inline void radeon_sync_with_vblank(struct radeon_device *rdev) { if (rdev->pm.active_crtcs) { rdev->pm.vblank_sync = false; @@ -150,332 +192,73 @@ static void radeon_sync_with_vblank(struct radeon_device *rdev) static void radeon_set_power_state(struct radeon_device *rdev) { - u32 sclk, mclk; - - if ((rdev->pm.requested_clock_mode_index == rdev->pm.current_clock_mode_index) && - (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index)) + /* if *_clock_mode are the same, *_power_state are as well */ + if (rdev->pm.requested_clock_mode == rdev->pm.current_clock_mode) return; - if (radeon_gui_idle(rdev)) { - sclk = rdev->pm.power_state[rdev->pm.requested_power_state_index]. - clock_info[rdev->pm.requested_clock_mode_index].sclk; - if (sclk > rdev->clock.default_sclk) - sclk = rdev->clock.default_sclk; - - mclk = rdev->pm.power_state[rdev->pm.requested_power_state_index]. - clock_info[rdev->pm.requested_clock_mode_index].mclk; - if (mclk > rdev->clock.default_mclk) - mclk = rdev->clock.default_mclk; - - /* voltage, pcie lanes, etc.*/ - radeon_pm_misc(rdev); - - if (rdev->pm.pm_method == PM_METHOD_DYNPM) { - radeon_sync_with_vblank(rdev); - - if (!radeon_pm_in_vbl(rdev)) - return; - - radeon_pm_prepare(rdev); - /* set engine clock */ - if (sclk != rdev->pm.current_sclk) { - radeon_pm_debug_check_in_vbl(rdev, false); - radeon_set_engine_clock(rdev, sclk); - radeon_pm_debug_check_in_vbl(rdev, true); - rdev->pm.current_sclk = sclk; - DRM_DEBUG("Setting: e: %d\n", sclk); - } - - /* set memory clock */ - if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { - radeon_pm_debug_check_in_vbl(rdev, false); - radeon_set_memory_clock(rdev, mclk); - radeon_pm_debug_check_in_vbl(rdev, true); - rdev->pm.current_mclk = mclk; - DRM_DEBUG("Setting: m: %d\n", mclk); - } - radeon_pm_finish(rdev); - } else { - /* set engine clock */ - if (sclk != rdev->pm.current_sclk) { - radeon_sync_with_vblank(rdev); - radeon_pm_prepare(rdev); - radeon_set_engine_clock(rdev, sclk); - radeon_pm_finish(rdev); - rdev->pm.current_sclk = sclk; - DRM_DEBUG("Setting: e: %d\n", sclk); - } - /* set memory clock */ - if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { - radeon_sync_with_vblank(rdev); - radeon_pm_prepare(rdev); - radeon_set_memory_clock(rdev, mclk); - radeon_pm_finish(rdev); - rdev->pm.current_mclk = mclk; - DRM_DEBUG("Setting: m: %d\n", mclk); - } - } - - rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index; - rdev->pm.current_clock_mode_index = rdev->pm.requested_clock_mode_index; - } else - DRM_DEBUG("pm: GUI not idle!!!\n"); -} - -static void radeon_pm_set_clocks(struct radeon_device *rdev) -{ - int i; - - mutex_lock(&rdev->ddev->struct_mutex); - mutex_lock(&rdev->vram_mutex); - mutex_lock(&rdev->cp.mutex); - - /* gui idle int has issues on older chips it seems */ - if (rdev->family >= CHIP_R600) { - if (rdev->irq.installed) { - /* wait for GPU idle */ - rdev->pm.gui_idle = false; - rdev->irq.gui_idle = true; - radeon_irq_set(rdev); - wait_event_interruptible_timeout( - rdev->irq.idle_queue, rdev->pm.gui_idle, - msecs_to_jiffies(RADEON_WAIT_IDLE_TIMEOUT)); - rdev->irq.gui_idle = false; - radeon_irq_set(rdev); - } - } else { - if (rdev->cp.ready) { - struct radeon_fence *fence; - radeon_ring_alloc(rdev, 64); - radeon_fence_create(rdev, &fence); - radeon_fence_emit(rdev, fence); - radeon_ring_commit(rdev); - radeon_fence_wait(fence, false); - radeon_fence_unref(&fence); - } - } - radeon_unmap_vram_bos(rdev); - - if (rdev->irq.installed) { - for (i = 0; i < rdev->num_crtc; i++) { - if (rdev->pm.active_crtcs & (1 << i)) { - rdev->pm.req_vblank |= (1 << i); - drm_vblank_get(rdev->ddev, i); - } - } - } - - radeon_set_power_state(rdev); - - if (rdev->irq.installed) { - for (i = 0; i < rdev->num_crtc; i++) { - if (rdev->pm.req_vblank & (1 << i)) { - rdev->pm.req_vblank &= ~(1 << i); - drm_vblank_put(rdev->ddev, i); - } - } - } - - /* update display watermarks based on new power state */ - radeon_update_bandwidth_info(rdev); - if (rdev->pm.active_crtc_count) - radeon_bandwidth_update(rdev); - - rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; - - mutex_unlock(&rdev->cp.mutex); - mutex_unlock(&rdev->vram_mutex); - mutex_unlock(&rdev->ddev->struct_mutex); -} - -static ssize_t radeon_get_pm_profile(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev)); - struct radeon_device *rdev = ddev->dev_private; - int cp = rdev->pm.profile; - - return snprintf(buf, PAGE_SIZE, "%s\n", - (cp == PM_PROFILE_AUTO) ? "auto" : - (cp == PM_PROFILE_LOW) ? "low" : - (cp == PM_PROFILE_HIGH) ? "high" : "default"); -} - -static ssize_t radeon_set_pm_profile(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count) -{ - struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev)); - struct radeon_device *rdev = ddev->dev_private; - - mutex_lock(&rdev->pm.mutex); - if (rdev->pm.pm_method == PM_METHOD_PROFILE) { - if (strncmp("default", buf, strlen("default")) == 0) - rdev->pm.profile = PM_PROFILE_DEFAULT; - else if (strncmp("auto", buf, strlen("auto")) == 0) - rdev->pm.profile = PM_PROFILE_AUTO; - else if (strncmp("low", buf, strlen("low")) == 0) - rdev->pm.profile = PM_PROFILE_LOW; - else if (strncmp("high", buf, strlen("high")) == 0) - rdev->pm.profile = PM_PROFILE_HIGH; - else { - DRM_ERROR("invalid power profile!\n"); - goto fail; - } - radeon_pm_update_profile(rdev); - radeon_pm_set_clocks(rdev); - } -fail: - mutex_unlock(&rdev->pm.mutex); - - return count; -} - -static ssize_t radeon_get_pm_method(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev)); - struct radeon_device *rdev = ddev->dev_private; - int pm = rdev->pm.pm_method; - - return snprintf(buf, PAGE_SIZE, "%s\n", - (pm == PM_METHOD_DYNPM) ? "dynpm" : "profile"); -} - -static ssize_t radeon_set_pm_method(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count) -{ - struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev)); - struct radeon_device *rdev = ddev->dev_private; - - - if (strncmp("dynpm", buf, strlen("dynpm")) == 0) { - mutex_lock(&rdev->pm.mutex); - rdev->pm.pm_method = PM_METHOD_DYNPM; - rdev->pm.dynpm_state = DYNPM_STATE_PAUSED; - rdev->pm.dynpm_planned_action = DYNPM_ACTION_DEFAULT; - mutex_unlock(&rdev->pm.mutex); - } else if (strncmp("profile", buf, strlen("profile")) == 0) { - mutex_lock(&rdev->pm.mutex); - rdev->pm.pm_method = PM_METHOD_PROFILE; - /* disable dynpm */ - rdev->pm.dynpm_state = DYNPM_STATE_DISABLED; - rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; - cancel_delayed_work(&rdev->pm.dynpm_idle_work); - mutex_unlock(&rdev->pm.mutex); - } else { - DRM_ERROR("invalid power method!\n"); - goto fail; + DRM_INFO("Setting: e: %d m: %d p: %d\n", + rdev->pm.requested_clock_mode->sclk, + rdev->pm.requested_clock_mode->mclk, + rdev->pm.requested_power_state->non_clock_info.pcie_lanes); + + /* set pcie lanes */ + /* TODO */ + + /* set voltage */ + /* TODO */ + + /* set engine clock */ + radeon_sync_with_vblank(rdev); + radeon_pm_debug_check_in_vbl(rdev, false); + radeon_set_engine_clock(rdev, rdev->pm.requested_clock_mode->sclk); + radeon_pm_debug_check_in_vbl(rdev, true); + +#if 0 + /* set memory clock */ + if (rdev->asic->set_memory_clock) { + radeon_sync_with_vblank(rdev); + radeon_pm_debug_check_in_vbl(rdev, false); + radeon_set_memory_clock(rdev, rdev->pm.requested_clock_mode->mclk); + radeon_pm_debug_check_in_vbl(rdev, true); } - radeon_pm_compute_clocks(rdev); -fail: - return count; -} - -static DEVICE_ATTR(power_profile, S_IRUGO | S_IWUSR, radeon_get_pm_profile, radeon_set_pm_profile); -static DEVICE_ATTR(power_method, S_IRUGO | S_IWUSR, radeon_get_pm_method, radeon_set_pm_method); - -void radeon_pm_suspend(struct radeon_device *rdev) -{ - mutex_lock(&rdev->pm.mutex); - cancel_delayed_work(&rdev->pm.dynpm_idle_work); - rdev->pm.current_power_state_index = -1; - rdev->pm.current_clock_mode_index = -1; - rdev->pm.current_sclk = 0; - rdev->pm.current_mclk = 0; - mutex_unlock(&rdev->pm.mutex); -} +#endif -void radeon_pm_resume(struct radeon_device *rdev) -{ - radeon_pm_compute_clocks(rdev); + rdev->pm.current_power_state = rdev->pm.requested_power_state; + rdev->pm.current_clock_mode = rdev->pm.requested_clock_mode; } int radeon_pm_init(struct radeon_device *rdev) { - int ret; - /* default to profile method */ - rdev->pm.pm_method = PM_METHOD_PROFILE; - rdev->pm.dynpm_state = DYNPM_STATE_DISABLED; - rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; - rdev->pm.dynpm_can_upclock = true; - rdev->pm.dynpm_can_downclock = true; - rdev->pm.current_sclk = 0; - rdev->pm.current_mclk = 0; + rdev->pm.state = PM_STATE_DISABLED; + rdev->pm.planned_action = PM_ACTION_NONE; + rdev->pm.downclocked = false; if (rdev->bios) { if (rdev->is_atom_bios) radeon_atombios_get_power_modes(rdev); else radeon_combios_get_power_modes(rdev); - radeon_pm_init_profile(rdev); - rdev->pm.current_power_state_index = -1; - rdev->pm.current_clock_mode_index = -1; + radeon_print_power_mode_info(rdev); } - if (rdev->pm.num_power_states > 1) { - if (rdev->pm.pm_method == PM_METHOD_PROFILE) { - mutex_lock(&rdev->pm.mutex); - rdev->pm.profile = PM_PROFILE_DEFAULT; - radeon_pm_update_profile(rdev); - radeon_pm_set_clocks(rdev); - mutex_unlock(&rdev->pm.mutex); - } - - /* where's the best place to put these? */ - ret = device_create_file(rdev->dev, &dev_attr_power_profile); - if (ret) - DRM_ERROR("failed to create device file for power profile\n"); - ret = device_create_file(rdev->dev, &dev_attr_power_method); - if (ret) - DRM_ERROR("failed to create device file for power method\n"); - -#ifdef CONFIG_ACPI - rdev->acpi_nb.notifier_call = radeon_acpi_event; - register_acpi_notifier(&rdev->acpi_nb); -#endif - INIT_DELAYED_WORK(&rdev->pm.dynpm_idle_work, radeon_dynpm_idle_work_handler); + if (radeon_debugfs_pm_init(rdev)) { + DRM_ERROR("Failed to register debugfs file for PM!\n"); + } - if (radeon_debugfs_pm_init(rdev)) { - DRM_ERROR("Failed to register debugfs file for PM!\n"); - } + INIT_DELAYED_WORK(&rdev->pm.idle_work, radeon_pm_idle_work_handler); - DRM_INFO("radeon: power management initialized\n"); + if (radeon_dynpm != -1 && radeon_dynpm) { + rdev->pm.state = PM_STATE_PAUSED; + DRM_INFO("radeon: dynamic power management enabled\n"); } + DRM_INFO("radeon: power management initialized\n"); + return 0; } void radeon_pm_fini(struct radeon_device *rdev) { - if (rdev->pm.num_power_states > 1) { - mutex_lock(&rdev->pm.mutex); - if (rdev->pm.pm_method == PM_METHOD_PROFILE) { - rdev->pm.profile = PM_PROFILE_DEFAULT; - radeon_pm_update_profile(rdev); - radeon_pm_set_clocks(rdev); - } else if (rdev->pm.pm_method == PM_METHOD_DYNPM) { - /* cancel work */ - cancel_delayed_work_sync(&rdev->pm.dynpm_idle_work); - /* reset default clocks */ - rdev->pm.dynpm_state = DYNPM_STATE_DISABLED; - rdev->pm.dynpm_planned_action = DYNPM_ACTION_DEFAULT; - radeon_pm_set_clocks(rdev); - } - mutex_unlock(&rdev->pm.mutex); - - device_remove_file(rdev->dev, &dev_attr_power_profile); - device_remove_file(rdev->dev, &dev_attr_power_method); -#ifdef CONFIG_ACPI - unregister_acpi_notifier(&rdev->acpi_nb); -#endif - } - if (rdev->pm.i2c_bus) radeon_i2c_destroy(rdev->pm.i2c_bus); } @@ -483,167 +266,146 @@ void radeon_pm_fini(struct radeon_device *rdev) void radeon_pm_compute_clocks(struct radeon_device *rdev) { struct drm_device *ddev = rdev->ddev; - struct drm_crtc *crtc; + struct drm_connector *connector; struct radeon_crtc *radeon_crtc; + int count = 0; - if (rdev->pm.num_power_states < 2) + if (rdev->pm.state == PM_STATE_DISABLED) return; mutex_lock(&rdev->pm.mutex); rdev->pm.active_crtcs = 0; - rdev->pm.active_crtc_count = 0; - list_for_each_entry(crtc, - &ddev->mode_config.crtc_list, head) { - radeon_crtc = to_radeon_crtc(crtc); - if (radeon_crtc->enabled) { + list_for_each_entry(connector, + &ddev->mode_config.connector_list, head) { + if (connector->encoder && + connector->encoder->crtc && + connector->dpms != DRM_MODE_DPMS_OFF) { + radeon_crtc = to_radeon_crtc(connector->encoder->crtc); rdev->pm.active_crtcs |= (1 << radeon_crtc->crtc_id); - rdev->pm.active_crtc_count++; + ++count; } } - if (rdev->pm.pm_method == PM_METHOD_PROFILE) { - radeon_pm_update_profile(rdev); - radeon_pm_set_clocks(rdev); - } else if (rdev->pm.pm_method == PM_METHOD_DYNPM) { - if (rdev->pm.dynpm_state != DYNPM_STATE_DISABLED) { - if (rdev->pm.active_crtc_count > 1) { - if (rdev->pm.dynpm_state == DYNPM_STATE_ACTIVE) { - cancel_delayed_work(&rdev->pm.dynpm_idle_work); - - rdev->pm.dynpm_state = DYNPM_STATE_PAUSED; - rdev->pm.dynpm_planned_action = DYNPM_ACTION_DEFAULT; - radeon_pm_get_dynpm_state(rdev); - radeon_pm_set_clocks(rdev); - - DRM_DEBUG("radeon: dynamic power management deactivated\n"); - } - } else if (rdev->pm.active_crtc_count == 1) { - /* TODO: Increase clocks if needed for current mode */ - - if (rdev->pm.dynpm_state == DYNPM_STATE_MINIMUM) { - rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE; - rdev->pm.dynpm_planned_action = DYNPM_ACTION_UPCLOCK; - radeon_pm_get_dynpm_state(rdev); - radeon_pm_set_clocks(rdev); - - queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work, - msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); - } else if (rdev->pm.dynpm_state == DYNPM_STATE_PAUSED) { - rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE; - queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work, - msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); - DRM_DEBUG("radeon: dynamic power management activated\n"); - } - } else { /* count == 0 */ - if (rdev->pm.dynpm_state != DYNPM_STATE_MINIMUM) { - cancel_delayed_work(&rdev->pm.dynpm_idle_work); - - rdev->pm.dynpm_state = DYNPM_STATE_MINIMUM; - rdev->pm.dynpm_planned_action = DYNPM_ACTION_MINIMUM; - radeon_pm_get_dynpm_state(rdev); - radeon_pm_set_clocks(rdev); - } - } + if (count > 1) { + if (rdev->pm.state == PM_STATE_ACTIVE) { + cancel_delayed_work(&rdev->pm.idle_work); + + rdev->pm.state = PM_STATE_PAUSED; + rdev->pm.planned_action = PM_ACTION_UPCLOCK; + if (rdev->pm.downclocked) + radeon_pm_set_clocks(rdev); + + DRM_DEBUG("radeon: dynamic power management deactivated\n"); + } + } else if (count == 1) { + /* TODO: Increase clocks if needed for current mode */ + + if (rdev->pm.state == PM_STATE_MINIMUM) { + rdev->pm.state = PM_STATE_ACTIVE; + rdev->pm.planned_action = PM_ACTION_UPCLOCK; + radeon_pm_set_clocks(rdev); + + queue_delayed_work(rdev->wq, &rdev->pm.idle_work, + msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); + } + else if (rdev->pm.state == PM_STATE_PAUSED) { + rdev->pm.state = PM_STATE_ACTIVE; + queue_delayed_work(rdev->wq, &rdev->pm.idle_work, + msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); + DRM_DEBUG("radeon: dynamic power management activated\n"); + } + } + else { /* count == 0 */ + if (rdev->pm.state != PM_STATE_MINIMUM) { + cancel_delayed_work(&rdev->pm.idle_work); + + rdev->pm.state = PM_STATE_MINIMUM; + rdev->pm.planned_action = PM_ACTION_MINIMUM; + radeon_pm_set_clocks(rdev); } } mutex_unlock(&rdev->pm.mutex); } -static bool radeon_pm_in_vbl(struct radeon_device *rdev) +static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish) { - u32 stat_crtc = 0, vbl = 0, position = 0; + u32 stat_crtc1 = 0, stat_crtc2 = 0; bool in_vbl = true; - if (ASIC_IS_DCE4(rdev)) { - if (rdev->pm.active_crtcs & (1 << 0)) { - vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + - EVERGREEN_CRTC0_REGISTER_OFFSET) & 0xfff; - position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + - EVERGREEN_CRTC0_REGISTER_OFFSET) & 0xfff; - } - if (rdev->pm.active_crtcs & (1 << 1)) { - vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + - EVERGREEN_CRTC1_REGISTER_OFFSET) & 0xfff; - position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + - EVERGREEN_CRTC1_REGISTER_OFFSET) & 0xfff; - } - if (rdev->pm.active_crtcs & (1 << 2)) { - vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + - EVERGREEN_CRTC2_REGISTER_OFFSET) & 0xfff; - position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + - EVERGREEN_CRTC2_REGISTER_OFFSET) & 0xfff; - } - if (rdev->pm.active_crtcs & (1 << 3)) { - vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + - EVERGREEN_CRTC3_REGISTER_OFFSET) & 0xfff; - position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + - EVERGREEN_CRTC3_REGISTER_OFFSET) & 0xfff; - } - if (rdev->pm.active_crtcs & (1 << 4)) { - vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + - EVERGREEN_CRTC4_REGISTER_OFFSET) & 0xfff; - position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + - EVERGREEN_CRTC4_REGISTER_OFFSET) & 0xfff; - } - if (rdev->pm.active_crtcs & (1 << 5)) { - vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + - EVERGREEN_CRTC5_REGISTER_OFFSET) & 0xfff; - position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + - EVERGREEN_CRTC5_REGISTER_OFFSET) & 0xfff; - } - } else if (ASIC_IS_AVIVO(rdev)) { - if (rdev->pm.active_crtcs & (1 << 0)) { - vbl = RREG32(AVIVO_D1CRTC_V_BLANK_START_END) & 0xfff; - position = RREG32(AVIVO_D1CRTC_STATUS_POSITION) & 0xfff; - } - if (rdev->pm.active_crtcs & (1 << 1)) { - vbl = RREG32(AVIVO_D2CRTC_V_BLANK_START_END) & 0xfff; - position = RREG32(AVIVO_D2CRTC_STATUS_POSITION) & 0xfff; - } - if (position < vbl && position > 1) - in_vbl = false; - } else { + if (ASIC_IS_AVIVO(rdev)) { if (rdev->pm.active_crtcs & (1 << 0)) { - stat_crtc = RREG32(RADEON_CRTC_STATUS); - if (!(stat_crtc & 1)) + stat_crtc1 = RREG32(D1CRTC_STATUS); + if (!(stat_crtc1 & 1)) in_vbl = false; } if (rdev->pm.active_crtcs & (1 << 1)) { - stat_crtc = RREG32(RADEON_CRTC2_STATUS); - if (!(stat_crtc & 1)) + stat_crtc2 = RREG32(D2CRTC_STATUS); + if (!(stat_crtc2 & 1)) in_vbl = false; } } - - if (position < vbl && position > 1) - in_vbl = false; - + if (in_vbl == false) + DRM_INFO("not in vbl for pm change %08x %08x at %s\n", stat_crtc1, + stat_crtc2, finish ? "exit" : "entry"); return in_vbl; } +static void radeon_pm_set_clocks_locked(struct radeon_device *rdev) +{ + /*radeon_fence_wait_last(rdev);*/ + switch (rdev->pm.planned_action) { + case PM_ACTION_UPCLOCK: + rdev->pm.downclocked = false; + break; + case PM_ACTION_DOWNCLOCK: + rdev->pm.downclocked = true; + break; + case PM_ACTION_MINIMUM: + break; + case PM_ACTION_NONE: + DRM_ERROR("%s: PM_ACTION_NONE\n", __func__); + break; + } -static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish) + radeon_set_power_state(rdev); + rdev->pm.planned_action = PM_ACTION_NONE; +} + +static void radeon_pm_set_clocks(struct radeon_device *rdev) { - u32 stat_crtc = 0; - bool in_vbl = radeon_pm_in_vbl(rdev); + radeon_get_power_state(rdev, rdev->pm.planned_action); + mutex_lock(&rdev->cp.mutex); - if (in_vbl == false) - DRM_DEBUG("not in vbl for pm change %08x at %s\n", stat_crtc, - finish ? "exit" : "entry"); - return in_vbl; + if (rdev->pm.active_crtcs & (1 << 0)) { + rdev->pm.req_vblank |= (1 << 0); + drm_vblank_get(rdev->ddev, 0); + } + if (rdev->pm.active_crtcs & (1 << 1)) { + rdev->pm.req_vblank |= (1 << 1); + drm_vblank_get(rdev->ddev, 1); + } + radeon_pm_set_clocks_locked(rdev); + if (rdev->pm.req_vblank & (1 << 0)) { + rdev->pm.req_vblank &= ~(1 << 0); + drm_vblank_put(rdev->ddev, 0); + } + if (rdev->pm.req_vblank & (1 << 1)) { + rdev->pm.req_vblank &= ~(1 << 1); + drm_vblank_put(rdev->ddev, 1); + } + + mutex_unlock(&rdev->cp.mutex); } -static void radeon_dynpm_idle_work_handler(struct work_struct *work) +static void radeon_pm_idle_work_handler(struct work_struct *work) { struct radeon_device *rdev; - int resched; rdev = container_of(work, struct radeon_device, - pm.dynpm_idle_work.work); + pm.idle_work.work); - resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev); mutex_lock(&rdev->pm.mutex); - if (rdev->pm.dynpm_state == DYNPM_STATE_ACTIVE) { + if (rdev->pm.state == PM_STATE_ACTIVE) { unsigned long irq_flags; int not_processed = 0; @@ -659,40 +421,35 @@ static void radeon_dynpm_idle_work_handler(struct work_struct *work) read_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); if (not_processed >= 3) { /* should upclock */ - if (rdev->pm.dynpm_planned_action == DYNPM_ACTION_DOWNCLOCK) { - rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; - } else if (rdev->pm.dynpm_planned_action == DYNPM_ACTION_NONE && - rdev->pm.dynpm_can_upclock) { - rdev->pm.dynpm_planned_action = - DYNPM_ACTION_UPCLOCK; - rdev->pm.dynpm_action_timeout = jiffies + + if (rdev->pm.planned_action == PM_ACTION_DOWNCLOCK) { + rdev->pm.planned_action = PM_ACTION_NONE; + } else if (rdev->pm.planned_action == PM_ACTION_NONE && + rdev->pm.downclocked) { + rdev->pm.planned_action = + PM_ACTION_UPCLOCK; + rdev->pm.action_timeout = jiffies + msecs_to_jiffies(RADEON_RECLOCK_DELAY_MS); } } else if (not_processed == 0) { /* should downclock */ - if (rdev->pm.dynpm_planned_action == DYNPM_ACTION_UPCLOCK) { - rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; - } else if (rdev->pm.dynpm_planned_action == DYNPM_ACTION_NONE && - rdev->pm.dynpm_can_downclock) { - rdev->pm.dynpm_planned_action = - DYNPM_ACTION_DOWNCLOCK; - rdev->pm.dynpm_action_timeout = jiffies + + if (rdev->pm.planned_action == PM_ACTION_UPCLOCK) { + rdev->pm.planned_action = PM_ACTION_NONE; + } else if (rdev->pm.planned_action == PM_ACTION_NONE && + !rdev->pm.downclocked) { + rdev->pm.planned_action = + PM_ACTION_DOWNCLOCK; + rdev->pm.action_timeout = jiffies + msecs_to_jiffies(RADEON_RECLOCK_DELAY_MS); } } - /* Note, radeon_pm_set_clocks is called with static_switch set - * to false since we want to wait for vbl to avoid flicker. - */ - if (rdev->pm.dynpm_planned_action != DYNPM_ACTION_NONE && - jiffies > rdev->pm.dynpm_action_timeout) { - radeon_pm_get_dynpm_state(rdev); + if (rdev->pm.planned_action != PM_ACTION_NONE && + jiffies > rdev->pm.action_timeout) { radeon_pm_set_clocks(rdev); } } mutex_unlock(&rdev->pm.mutex); - ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); - queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work, + queue_delayed_work(rdev->wq, &rdev->pm.idle_work, msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); } @@ -707,6 +464,7 @@ static int radeon_debugfs_pm_info(struct seq_file *m, void *data) struct drm_device *dev = node->minor->dev; struct radeon_device *rdev = dev->dev_private; + seq_printf(m, "state: %s\n", pm_state_names[rdev->pm.state]); seq_printf(m, "default engine clock: %u0 kHz\n", rdev->clock.default_sclk); seq_printf(m, "current engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev)); seq_printf(m, "default memory clock: %u0 kHz\n", rdev->clock.default_mclk); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_reg.h b/trunk/drivers/gpu/drm/radeon/radeon_reg.h index c332f46340d5..eabbc9cf30a7 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_reg.h +++ b/trunk/drivers/gpu/drm/radeon/radeon_reg.h @@ -553,6 +553,7 @@ # define RADEON_CRTC_CRNT_VLINE_MASK (0x7ff << 16) #define RADEON_CRTC2_CRNT_FRAME 0x0314 #define RADEON_CRTC2_GUI_TRIG_VLINE 0x0318 +#define RADEON_CRTC2_STATUS 0x03fc #define RADEON_CRTC2_VLINE_CRNT_VLINE 0x0310 #define RADEON_CRTC8_DATA 0x03d5 /* VGA, 0x3b5 */ #define RADEON_CRTC8_IDX 0x03d4 /* VGA, 0x3b4 */ @@ -994,7 +995,6 @@ # define RADEON_FP_DETECT_MASK (1 << 4) # define RADEON_CRTC2_VBLANK_MASK (1 << 9) # define RADEON_FP2_DETECT_MASK (1 << 10) -# define RADEON_GUI_IDLE_MASK (1 << 19) # define RADEON_SW_INT_ENABLE (1 << 25) #define RADEON_GEN_INT_STATUS 0x0044 # define AVIVO_DISPLAY_INT_STATUS (1 << 0) @@ -1006,8 +1006,6 @@ # define RADEON_CRTC2_VBLANK_STAT_ACK (1 << 9) # define RADEON_FP2_DETECT_STAT (1 << 10) # define RADEON_FP2_DETECT_STAT_ACK (1 << 10) -# define RADEON_GUI_IDLE_STAT (1 << 19) -# define RADEON_GUI_IDLE_STAT_ACK (1 << 19) # define RADEON_SW_INT_FIRE (1 << 26) # define RADEON_SW_INT_TEST (1 << 25) # define RADEON_SW_INT_TEST_ACK (1 << 25) diff --git a/trunk/drivers/gpu/drm/radeon/radeon_ring.c b/trunk/drivers/gpu/drm/radeon/radeon_ring.c index 261e98a276db..f6e1e8d4d986 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_ring.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_ring.c @@ -219,26 +219,24 @@ int radeon_ib_pool_init(struct radeon_device *rdev) void radeon_ib_pool_fini(struct radeon_device *rdev) { int r; - struct radeon_bo *robj; if (!rdev->ib_pool.ready) { return; } mutex_lock(&rdev->ib_pool.mutex); radeon_ib_bogus_cleanup(rdev); - robj = rdev->ib_pool.robj; - rdev->ib_pool.robj = NULL; - mutex_unlock(&rdev->ib_pool.mutex); - if (robj) { - r = radeon_bo_reserve(robj, false); + if (rdev->ib_pool.robj) { + r = radeon_bo_reserve(rdev->ib_pool.robj, false); if (likely(r == 0)) { - radeon_bo_kunmap(robj); - radeon_bo_unpin(robj); - radeon_bo_unreserve(robj); + radeon_bo_kunmap(rdev->ib_pool.robj); + radeon_bo_unpin(rdev->ib_pool.robj); + radeon_bo_unreserve(rdev->ib_pool.robj); } - radeon_bo_unref(&robj); + radeon_bo_unref(&rdev->ib_pool.robj); + rdev->ib_pool.robj = NULL; } + mutex_unlock(&rdev->ib_pool.mutex); } @@ -260,41 +258,31 @@ void radeon_ring_free_size(struct radeon_device *rdev) } } -int radeon_ring_alloc(struct radeon_device *rdev, unsigned ndw) +int radeon_ring_lock(struct radeon_device *rdev, unsigned ndw) { int r; /* Align requested size with padding so unlock_commit can * pad safely */ ndw = (ndw + rdev->cp.align_mask) & ~rdev->cp.align_mask; + mutex_lock(&rdev->cp.mutex); while (ndw > (rdev->cp.ring_free_dw - 1)) { radeon_ring_free_size(rdev); if (ndw < rdev->cp.ring_free_dw) { break; } r = radeon_fence_wait_next(rdev); - if (r) + if (r) { + mutex_unlock(&rdev->cp.mutex); return r; + } } rdev->cp.count_dw = ndw; rdev->cp.wptr_old = rdev->cp.wptr; return 0; } -int radeon_ring_lock(struct radeon_device *rdev, unsigned ndw) -{ - int r; - - mutex_lock(&rdev->cp.mutex); - r = radeon_ring_alloc(rdev, ndw); - if (r) { - mutex_unlock(&rdev->cp.mutex); - return r; - } - return 0; -} - -void radeon_ring_commit(struct radeon_device *rdev) +void radeon_ring_unlock_commit(struct radeon_device *rdev) { unsigned count_dw_pad; unsigned i; @@ -307,11 +295,6 @@ void radeon_ring_commit(struct radeon_device *rdev) } DRM_MEMORYBARRIER(); radeon_cp_commit(rdev); -} - -void radeon_ring_unlock_commit(struct radeon_device *rdev) -{ - radeon_ring_commit(rdev); mutex_unlock(&rdev->cp.mutex); } @@ -361,23 +344,20 @@ int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size) void radeon_ring_fini(struct radeon_device *rdev) { int r; - struct radeon_bo *ring_obj; mutex_lock(&rdev->cp.mutex); - ring_obj = rdev->cp.ring_obj; - rdev->cp.ring = NULL; - rdev->cp.ring_obj = NULL; - mutex_unlock(&rdev->cp.mutex); - - if (ring_obj) { - r = radeon_bo_reserve(ring_obj, false); + if (rdev->cp.ring_obj) { + r = radeon_bo_reserve(rdev->cp.ring_obj, false); if (likely(r == 0)) { - radeon_bo_kunmap(ring_obj); - radeon_bo_unpin(ring_obj); - radeon_bo_unreserve(ring_obj); + radeon_bo_kunmap(rdev->cp.ring_obj); + radeon_bo_unpin(rdev->cp.ring_obj); + radeon_bo_unreserve(rdev->cp.ring_obj); } - radeon_bo_unref(&ring_obj); + radeon_bo_unref(&rdev->cp.ring_obj); + rdev->cp.ring = NULL; + rdev->cp.ring_obj = NULL; } + mutex_unlock(&rdev->cp.mutex); } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_ttm.c b/trunk/drivers/gpu/drm/radeon/radeon_ttm.c index 3aa3a65800ab..af98f45954b3 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_ttm.c @@ -607,17 +607,13 @@ static const struct vm_operations_struct *ttm_vm_ops = NULL; static int radeon_ttm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct ttm_buffer_object *bo; - struct radeon_device *rdev; int r; - bo = (struct ttm_buffer_object *)vma->vm_private_data; + bo = (struct ttm_buffer_object *)vma->vm_private_data; if (bo == NULL) { return VM_FAULT_NOPAGE; } - rdev = radeon_get_rdev(bo->bdev); - mutex_lock(&rdev->vram_mutex); r = ttm_vm_ops->fault(vma, vmf); - mutex_unlock(&rdev->vram_mutex); return r; } diff --git a/trunk/drivers/gpu/drm/radeon/rs400.c b/trunk/drivers/gpu/drm/radeon/rs400.c index 9e4240b3bf0b..dc76fe76eb25 100644 --- a/trunk/drivers/gpu/drm/radeon/rs400.c +++ b/trunk/drivers/gpu/drm/radeon/rs400.c @@ -456,6 +456,7 @@ int rs400_suspend(struct radeon_device *rdev) void rs400_fini(struct radeon_device *rdev) { + radeon_pm_fini(rdev); r100_cp_fini(rdev); r100_wb_fini(rdev); r100_ib_fini(rdev); @@ -506,6 +507,8 @@ int rs400_init(struct radeon_device *rdev) /* Initialize clocks */ radeon_get_clock_info(rdev->ddev); + /* Initialize power management */ + radeon_pm_init(rdev); /* initialize memory controller */ rs400_mc_init(rdev); /* Fence driver */ diff --git a/trunk/drivers/gpu/drm/radeon/rs600.c b/trunk/drivers/gpu/drm/radeon/rs600.c index 79887cac5b54..5e3f21861f45 100644 --- a/trunk/drivers/gpu/drm/radeon/rs600.c +++ b/trunk/drivers/gpu/drm/radeon/rs600.c @@ -46,135 +46,6 @@ void rs600_gpu_init(struct radeon_device *rdev); int rs600_mc_wait_for_idle(struct radeon_device *rdev); -void rs600_pm_misc(struct radeon_device *rdev) -{ - int requested_index = rdev->pm.requested_power_state_index; - struct radeon_power_state *ps = &rdev->pm.power_state[requested_index]; - struct radeon_voltage *voltage = &ps->clock_info[0].voltage; - u32 tmp, dyn_pwrmgt_sclk_length, dyn_sclk_vol_cntl; - u32 hdp_dyn_cntl, /*mc_host_dyn_cntl,*/ dyn_backbias_cntl; - - if ((voltage->type == VOLTAGE_GPIO) && (voltage->gpio.valid)) { - if (ps->misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) { - tmp = RREG32(voltage->gpio.reg); - if (voltage->active_high) - tmp |= voltage->gpio.mask; - else - tmp &= ~(voltage->gpio.mask); - WREG32(voltage->gpio.reg, tmp); - if (voltage->delay) - udelay(voltage->delay); - } else { - tmp = RREG32(voltage->gpio.reg); - if (voltage->active_high) - tmp &= ~voltage->gpio.mask; - else - tmp |= voltage->gpio.mask; - WREG32(voltage->gpio.reg, tmp); - if (voltage->delay) - udelay(voltage->delay); - } - } - - dyn_pwrmgt_sclk_length = RREG32_PLL(DYN_PWRMGT_SCLK_LENGTH); - dyn_pwrmgt_sclk_length &= ~REDUCED_POWER_SCLK_HILEN(0xf); - dyn_pwrmgt_sclk_length &= ~REDUCED_POWER_SCLK_LOLEN(0xf); - if (ps->misc & ATOM_PM_MISCINFO_ASIC_REDUCED_SPEED_SCLK_EN) { - if (ps->misc & ATOM_PM_MISCINFO_DYNAMIC_CLOCK_DIVIDER_BY_2) { - dyn_pwrmgt_sclk_length |= REDUCED_POWER_SCLK_HILEN(2); - dyn_pwrmgt_sclk_length |= REDUCED_POWER_SCLK_LOLEN(2); - } else if (ps->misc & ATOM_PM_MISCINFO_DYNAMIC_CLOCK_DIVIDER_BY_4) { - dyn_pwrmgt_sclk_length |= REDUCED_POWER_SCLK_HILEN(4); - dyn_pwrmgt_sclk_length |= REDUCED_POWER_SCLK_LOLEN(4); - } - } else { - dyn_pwrmgt_sclk_length |= REDUCED_POWER_SCLK_HILEN(1); - dyn_pwrmgt_sclk_length |= REDUCED_POWER_SCLK_LOLEN(1); - } - WREG32_PLL(DYN_PWRMGT_SCLK_LENGTH, dyn_pwrmgt_sclk_length); - - dyn_sclk_vol_cntl = RREG32_PLL(DYN_SCLK_VOL_CNTL); - if (ps->misc & ATOM_PM_MISCINFO_ASIC_DYNAMIC_VOLTAGE_EN) { - dyn_sclk_vol_cntl |= IO_CG_VOLTAGE_DROP; - if (voltage->delay) { - dyn_sclk_vol_cntl |= VOLTAGE_DROP_SYNC; - dyn_sclk_vol_cntl |= VOLTAGE_DELAY_SEL(voltage->delay); - } else - dyn_sclk_vol_cntl &= ~VOLTAGE_DROP_SYNC; - } else - dyn_sclk_vol_cntl &= ~IO_CG_VOLTAGE_DROP; - WREG32_PLL(DYN_SCLK_VOL_CNTL, dyn_sclk_vol_cntl); - - hdp_dyn_cntl = RREG32_PLL(HDP_DYN_CNTL); - if (ps->misc & ATOM_PM_MISCINFO_DYNAMIC_HDP_BLOCK_EN) - hdp_dyn_cntl &= ~HDP_FORCEON; - else - hdp_dyn_cntl |= HDP_FORCEON; - WREG32_PLL(HDP_DYN_CNTL, hdp_dyn_cntl); -#if 0 - /* mc_host_dyn seems to cause hangs from time to time */ - mc_host_dyn_cntl = RREG32_PLL(MC_HOST_DYN_CNTL); - if (ps->misc & ATOM_PM_MISCINFO_DYNAMIC_MC_HOST_BLOCK_EN) - mc_host_dyn_cntl &= ~MC_HOST_FORCEON; - else - mc_host_dyn_cntl |= MC_HOST_FORCEON; - WREG32_PLL(MC_HOST_DYN_CNTL, mc_host_dyn_cntl); -#endif - dyn_backbias_cntl = RREG32_PLL(DYN_BACKBIAS_CNTL); - if (ps->misc & ATOM_PM_MISCINFO2_DYNAMIC_BACK_BIAS_EN) - dyn_backbias_cntl |= IO_CG_BACKBIAS_EN; - else - dyn_backbias_cntl &= ~IO_CG_BACKBIAS_EN; - WREG32_PLL(DYN_BACKBIAS_CNTL, dyn_backbias_cntl); - - /* set pcie lanes */ - if ((rdev->flags & RADEON_IS_PCIE) && - !(rdev->flags & RADEON_IS_IGP) && - rdev->asic->set_pcie_lanes && - (ps->pcie_lanes != - rdev->pm.power_state[rdev->pm.current_power_state_index].pcie_lanes)) { - radeon_set_pcie_lanes(rdev, - ps->pcie_lanes); - DRM_DEBUG("Setting: p: %d\n", ps->pcie_lanes); - } -} - -void rs600_pm_prepare(struct radeon_device *rdev) -{ - struct drm_device *ddev = rdev->ddev; - struct drm_crtc *crtc; - struct radeon_crtc *radeon_crtc; - u32 tmp; - - /* disable any active CRTCs */ - list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) { - radeon_crtc = to_radeon_crtc(crtc); - if (radeon_crtc->enabled) { - tmp = RREG32(AVIVO_D1CRTC_CONTROL + radeon_crtc->crtc_offset); - tmp |= AVIVO_CRTC_DISP_READ_REQUEST_DISABLE; - WREG32(AVIVO_D1CRTC_CONTROL + radeon_crtc->crtc_offset, tmp); - } - } -} - -void rs600_pm_finish(struct radeon_device *rdev) -{ - struct drm_device *ddev = rdev->ddev; - struct drm_crtc *crtc; - struct radeon_crtc *radeon_crtc; - u32 tmp; - - /* enable any active CRTCs */ - list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) { - radeon_crtc = to_radeon_crtc(crtc); - if (radeon_crtc->enabled) { - tmp = RREG32(AVIVO_D1CRTC_CONTROL + radeon_crtc->crtc_offset); - tmp &= ~AVIVO_CRTC_DISP_READ_REQUEST_DISABLE; - WREG32(AVIVO_D1CRTC_CONTROL + radeon_crtc->crtc_offset, tmp); - } - } -} - /* hpd for digital panel detect/disconnect */ bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) { @@ -511,9 +382,6 @@ int rs600_irq_set(struct radeon_device *rdev) if (rdev->irq.sw_int) { tmp |= S_000040_SW_INT_EN(1); } - if (rdev->irq.gui_idle) { - tmp |= S_000040_GUI_IDLE(1); - } if (rdev->irq.crtc_vblank_int[0]) { mode_int |= S_006540_D1MODE_VBLANK_INT_MASK(1); } @@ -536,15 +404,9 @@ int rs600_irq_set(struct radeon_device *rdev) static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_int) { uint32_t irqs = RREG32(R_000044_GEN_INT_STATUS); - uint32_t irq_mask = S_000044_SW_INT(1); + uint32_t irq_mask = ~C_000044_SW_INT; u32 tmp; - /* the interrupt works, but the status bit is permanently asserted */ - if (rdev->irq.gui_idle && radeon_gui_idle(rdev)) { - if (!rdev->irq.gui_idle_acked) - irq_mask |= S_000044_GUI_IDLE_STAT(1); - } - if (G_000044_DISPLAY_INT_STAT(irqs)) { *r500_disp_int = RREG32(R_007EDC_DISP_INTERRUPT_STATUS); if (G_007EDC_LB_D1_VBLANK_INTERRUPT(*r500_disp_int)) { @@ -592,9 +454,6 @@ int rs600_irq_process(struct radeon_device *rdev) uint32_t r500_disp_int; bool queue_hotplug = false; - /* reset gui idle ack. the status bit is broken */ - rdev->irq.gui_idle_acked = false; - status = rs600_irq_ack(rdev, &r500_disp_int); if (!status && !r500_disp_int) { return IRQ_NONE; @@ -603,12 +462,6 @@ int rs600_irq_process(struct radeon_device *rdev) /* SW interrupt */ if (G_000044_SW_INT(status)) radeon_fence_process(rdev); - /* GUI idle */ - if (G_000040_GUI_IDLE(status)) { - rdev->irq.gui_idle_acked = true; - rdev->pm.gui_idle = true; - wake_up(&rdev->irq.idle_queue); - } /* Vertical blank interrupts */ if (G_007EDC_LB_D1_VBLANK_INTERRUPT(r500_disp_int)) { drm_handle_vblank(rdev->ddev, 0); @@ -630,8 +483,6 @@ int rs600_irq_process(struct radeon_device *rdev) } status = rs600_irq_ack(rdev, &r500_disp_int); } - /* reset gui idle ack. the status bit is broken */ - rdev->irq.gui_idle_acked = false; if (queue_hotplug) queue_work(rdev->wq, &rdev->hotplug_work); if (rdev->msi_enabled) { @@ -846,6 +697,7 @@ int rs600_suspend(struct radeon_device *rdev) void rs600_fini(struct radeon_device *rdev) { + radeon_pm_fini(rdev); r100_cp_fini(rdev); r100_wb_fini(rdev); r100_ib_fini(rdev); @@ -895,6 +747,8 @@ int rs600_init(struct radeon_device *rdev) /* Initialize clocks */ radeon_get_clock_info(rdev->ddev); + /* Initialize power management */ + radeon_pm_init(rdev); /* initialize memory controller */ rs600_mc_init(rdev); rs600_debugfs(rdev); diff --git a/trunk/drivers/gpu/drm/radeon/rs600d.h b/trunk/drivers/gpu/drm/radeon/rs600d.h index a27c13ac47c3..08c4bebd3011 100644 --- a/trunk/drivers/gpu/drm/radeon/rs600d.h +++ b/trunk/drivers/gpu/drm/radeon/rs600d.h @@ -634,38 +634,4 @@ #define G_006D4C_D2MODE_PRIORITY_B_FORCE_MASK(x) (((x) >> 24) & 0x1) #define C_006D4C_D2MODE_PRIORITY_B_FORCE_MASK 0xFEFFFFFF -/* PLL regs */ -#define GENERAL_PWRMGT 0x8 -#define GLOBAL_PWRMGT_EN (1 << 0) -#define MOBILE_SU (1 << 2) -#define DYN_PWRMGT_SCLK_LENGTH 0xc -#define NORMAL_POWER_SCLK_HILEN(x) ((x) << 0) -#define NORMAL_POWER_SCLK_LOLEN(x) ((x) << 4) -#define REDUCED_POWER_SCLK_HILEN(x) ((x) << 8) -#define REDUCED_POWER_SCLK_LOLEN(x) ((x) << 12) -#define POWER_D1_SCLK_HILEN(x) ((x) << 16) -#define POWER_D1_SCLK_LOLEN(x) ((x) << 20) -#define STATIC_SCREEN_HILEN(x) ((x) << 24) -#define STATIC_SCREEN_LOLEN(x) ((x) << 28) -#define DYN_SCLK_VOL_CNTL 0xe -#define IO_CG_VOLTAGE_DROP (1 << 0) -#define VOLTAGE_DROP_SYNC (1 << 2) -#define VOLTAGE_DELAY_SEL(x) ((x) << 3) -#define HDP_DYN_CNTL 0x10 -#define HDP_FORCEON (1 << 0) -#define MC_HOST_DYN_CNTL 0x1e -#define MC_HOST_FORCEON (1 << 0) -#define DYN_BACKBIAS_CNTL 0x29 -#define IO_CG_BACKBIAS_EN (1 << 0) - -/* mmreg */ -#define DOUT_POWER_MANAGEMENT_CNTL 0x7ee0 -#define PWRDN_WAIT_BUSY_OFF (1 << 0) -#define PWRDN_WAIT_PWRSEQ_OFF (1 << 4) -#define PWRDN_WAIT_PPLL_OFF (1 << 8) -#define PWRUP_WAIT_PPLL_ON (1 << 12) -#define PWRUP_WAIT_MEM_INIT_DONE (1 << 16) -#define PM_ASSERT_RESET (1 << 20) -#define PM_PWRDN_PPLL (1 << 24) - #endif diff --git a/trunk/drivers/gpu/drm/radeon/rs690.c b/trunk/drivers/gpu/drm/radeon/rs690.c index bcc33195ebc2..56a0aec84af2 100644 --- a/trunk/drivers/gpu/drm/radeon/rs690.c +++ b/trunk/drivers/gpu/drm/radeon/rs690.c @@ -76,59 +76,59 @@ void rs690_pm_info(struct radeon_device *rdev) /* Get various system informations from bios */ switch (crev) { case 1: - tmp.full = dfixed_const(100); - rdev->pm.igp_sideport_mclk.full = dfixed_const(info->info.ulBootUpMemoryClock); - rdev->pm.igp_sideport_mclk.full = dfixed_div(rdev->pm.igp_sideport_mclk, tmp); - rdev->pm.igp_system_mclk.full = dfixed_const(le16_to_cpu(info->info.usK8MemoryClock)); - rdev->pm.igp_ht_link_clk.full = dfixed_const(le16_to_cpu(info->info.usFSBClock)); - rdev->pm.igp_ht_link_width.full = dfixed_const(info->info.ucHTLinkWidth); + tmp.full = rfixed_const(100); + rdev->pm.igp_sideport_mclk.full = rfixed_const(info->info.ulBootUpMemoryClock); + rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp); + rdev->pm.igp_system_mclk.full = rfixed_const(le16_to_cpu(info->info.usK8MemoryClock)); + rdev->pm.igp_ht_link_clk.full = rfixed_const(le16_to_cpu(info->info.usFSBClock)); + rdev->pm.igp_ht_link_width.full = rfixed_const(info->info.ucHTLinkWidth); break; case 2: - tmp.full = dfixed_const(100); - rdev->pm.igp_sideport_mclk.full = dfixed_const(info->info_v2.ulBootUpSidePortClock); - rdev->pm.igp_sideport_mclk.full = dfixed_div(rdev->pm.igp_sideport_mclk, tmp); - rdev->pm.igp_system_mclk.full = dfixed_const(info->info_v2.ulBootUpUMAClock); - rdev->pm.igp_system_mclk.full = dfixed_div(rdev->pm.igp_system_mclk, tmp); - rdev->pm.igp_ht_link_clk.full = dfixed_const(info->info_v2.ulHTLinkFreq); - rdev->pm.igp_ht_link_clk.full = dfixed_div(rdev->pm.igp_ht_link_clk, tmp); - rdev->pm.igp_ht_link_width.full = dfixed_const(le16_to_cpu(info->info_v2.usMinHTLinkWidth)); + tmp.full = rfixed_const(100); + rdev->pm.igp_sideport_mclk.full = rfixed_const(info->info_v2.ulBootUpSidePortClock); + rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp); + rdev->pm.igp_system_mclk.full = rfixed_const(info->info_v2.ulBootUpUMAClock); + rdev->pm.igp_system_mclk.full = rfixed_div(rdev->pm.igp_system_mclk, tmp); + rdev->pm.igp_ht_link_clk.full = rfixed_const(info->info_v2.ulHTLinkFreq); + rdev->pm.igp_ht_link_clk.full = rfixed_div(rdev->pm.igp_ht_link_clk, tmp); + rdev->pm.igp_ht_link_width.full = rfixed_const(le16_to_cpu(info->info_v2.usMinHTLinkWidth)); break; default: - tmp.full = dfixed_const(100); + tmp.full = rfixed_const(100); /* We assume the slower possible clock ie worst case */ /* DDR 333Mhz */ - rdev->pm.igp_sideport_mclk.full = dfixed_const(333); + rdev->pm.igp_sideport_mclk.full = rfixed_const(333); /* FIXME: system clock ? */ - rdev->pm.igp_system_mclk.full = dfixed_const(100); - rdev->pm.igp_system_mclk.full = dfixed_div(rdev->pm.igp_system_mclk, tmp); - rdev->pm.igp_ht_link_clk.full = dfixed_const(200); - rdev->pm.igp_ht_link_width.full = dfixed_const(8); + rdev->pm.igp_system_mclk.full = rfixed_const(100); + rdev->pm.igp_system_mclk.full = rfixed_div(rdev->pm.igp_system_mclk, tmp); + rdev->pm.igp_ht_link_clk.full = rfixed_const(200); + rdev->pm.igp_ht_link_width.full = rfixed_const(8); DRM_ERROR("No integrated system info for your GPU, using safe default\n"); break; } } else { - tmp.full = dfixed_const(100); + tmp.full = rfixed_const(100); /* We assume the slower possible clock ie worst case */ /* DDR 333Mhz */ - rdev->pm.igp_sideport_mclk.full = dfixed_const(333); + rdev->pm.igp_sideport_mclk.full = rfixed_const(333); /* FIXME: system clock ? */ - rdev->pm.igp_system_mclk.full = dfixed_const(100); - rdev->pm.igp_system_mclk.full = dfixed_div(rdev->pm.igp_system_mclk, tmp); - rdev->pm.igp_ht_link_clk.full = dfixed_const(200); - rdev->pm.igp_ht_link_width.full = dfixed_const(8); + rdev->pm.igp_system_mclk.full = rfixed_const(100); + rdev->pm.igp_system_mclk.full = rfixed_div(rdev->pm.igp_system_mclk, tmp); + rdev->pm.igp_ht_link_clk.full = rfixed_const(200); + rdev->pm.igp_ht_link_width.full = rfixed_const(8); DRM_ERROR("No integrated system info for your GPU, using safe default\n"); } /* Compute various bandwidth */ /* k8_bandwidth = (memory_clk / 2) * 2 * 8 * 0.5 = memory_clk * 4 */ - tmp.full = dfixed_const(4); - rdev->pm.k8_bandwidth.full = dfixed_mul(rdev->pm.igp_system_mclk, tmp); + tmp.full = rfixed_const(4); + rdev->pm.k8_bandwidth.full = rfixed_mul(rdev->pm.igp_system_mclk, tmp); /* ht_bandwidth = ht_clk * 2 * ht_width / 8 * 0.8 * = ht_clk * ht_width / 5 */ - tmp.full = dfixed_const(5); - rdev->pm.ht_bandwidth.full = dfixed_mul(rdev->pm.igp_ht_link_clk, + tmp.full = rfixed_const(5); + rdev->pm.ht_bandwidth.full = rfixed_mul(rdev->pm.igp_ht_link_clk, rdev->pm.igp_ht_link_width); - rdev->pm.ht_bandwidth.full = dfixed_div(rdev->pm.ht_bandwidth, tmp); + rdev->pm.ht_bandwidth.full = rfixed_div(rdev->pm.ht_bandwidth, tmp); if (tmp.full < rdev->pm.max_bandwidth.full) { /* HT link is a limiting factor */ rdev->pm.max_bandwidth.full = tmp.full; @@ -136,10 +136,10 @@ void rs690_pm_info(struct radeon_device *rdev) /* sideport_bandwidth = (sideport_clk / 2) * 2 * 2 * 0.7 * = (sideport_clk * 14) / 10 */ - tmp.full = dfixed_const(14); - rdev->pm.sideport_bandwidth.full = dfixed_mul(rdev->pm.igp_sideport_mclk, tmp); - tmp.full = dfixed_const(10); - rdev->pm.sideport_bandwidth.full = dfixed_div(rdev->pm.sideport_bandwidth, tmp); + tmp.full = rfixed_const(14); + rdev->pm.sideport_bandwidth.full = rfixed_mul(rdev->pm.igp_sideport_mclk, tmp); + tmp.full = rfixed_const(10); + rdev->pm.sideport_bandwidth.full = rfixed_div(rdev->pm.sideport_bandwidth, tmp); } void rs690_mc_init(struct radeon_device *rdev) @@ -239,20 +239,20 @@ void rs690_crtc_bandwidth_compute(struct radeon_device *rdev, return; } - if (crtc->vsc.full > dfixed_const(2)) - wm->num_line_pair.full = dfixed_const(2); + if (crtc->vsc.full > rfixed_const(2)) + wm->num_line_pair.full = rfixed_const(2); else - wm->num_line_pair.full = dfixed_const(1); - - b.full = dfixed_const(mode->crtc_hdisplay); - c.full = dfixed_const(256); - a.full = dfixed_div(b, c); - request_fifo_depth.full = dfixed_mul(a, wm->num_line_pair); - request_fifo_depth.full = dfixed_ceil(request_fifo_depth); - if (a.full < dfixed_const(4)) { + wm->num_line_pair.full = rfixed_const(1); + + b.full = rfixed_const(mode->crtc_hdisplay); + c.full = rfixed_const(256); + a.full = rfixed_div(b, c); + request_fifo_depth.full = rfixed_mul(a, wm->num_line_pair); + request_fifo_depth.full = rfixed_ceil(request_fifo_depth); + if (a.full < rfixed_const(4)) { wm->lb_request_fifo_depth = 4; } else { - wm->lb_request_fifo_depth = dfixed_trunc(request_fifo_depth); + wm->lb_request_fifo_depth = rfixed_trunc(request_fifo_depth); } /* Determine consumption rate @@ -261,23 +261,23 @@ void rs690_crtc_bandwidth_compute(struct radeon_device *rdev, * vsc = vertical scaling ratio, defined as source/destination * hsc = horizontal scaling ration, defined as source/destination */ - a.full = dfixed_const(mode->clock); - b.full = dfixed_const(1000); - a.full = dfixed_div(a, b); - pclk.full = dfixed_div(b, a); + a.full = rfixed_const(mode->clock); + b.full = rfixed_const(1000); + a.full = rfixed_div(a, b); + pclk.full = rfixed_div(b, a); if (crtc->rmx_type != RMX_OFF) { - b.full = dfixed_const(2); + b.full = rfixed_const(2); if (crtc->vsc.full > b.full) b.full = crtc->vsc.full; - b.full = dfixed_mul(b, crtc->hsc); - c.full = dfixed_const(2); - b.full = dfixed_div(b, c); - consumption_time.full = dfixed_div(pclk, b); + b.full = rfixed_mul(b, crtc->hsc); + c.full = rfixed_const(2); + b.full = rfixed_div(b, c); + consumption_time.full = rfixed_div(pclk, b); } else { consumption_time.full = pclk.full; } - a.full = dfixed_const(1); - wm->consumption_rate.full = dfixed_div(a, consumption_time); + a.full = rfixed_const(1); + wm->consumption_rate.full = rfixed_div(a, consumption_time); /* Determine line time @@ -285,18 +285,18 @@ void rs690_crtc_bandwidth_compute(struct radeon_device *rdev, * LineTime = total number of horizontal pixels * pclk = pixel clock period(ns) */ - a.full = dfixed_const(crtc->base.mode.crtc_htotal); - line_time.full = dfixed_mul(a, pclk); + a.full = rfixed_const(crtc->base.mode.crtc_htotal); + line_time.full = rfixed_mul(a, pclk); /* Determine active time * ActiveTime = time of active region of display within one line, * hactive = total number of horizontal active pixels * htotal = total number of horizontal pixels */ - a.full = dfixed_const(crtc->base.mode.crtc_htotal); - b.full = dfixed_const(crtc->base.mode.crtc_hdisplay); - wm->active_time.full = dfixed_mul(line_time, b); - wm->active_time.full = dfixed_div(wm->active_time, a); + a.full = rfixed_const(crtc->base.mode.crtc_htotal); + b.full = rfixed_const(crtc->base.mode.crtc_hdisplay); + wm->active_time.full = rfixed_mul(line_time, b); + wm->active_time.full = rfixed_div(wm->active_time, a); /* Maximun bandwidth is the minimun bandwidth of all component */ rdev->pm.max_bandwidth = rdev->pm.core_bandwidth; @@ -304,8 +304,8 @@ void rs690_crtc_bandwidth_compute(struct radeon_device *rdev, if (rdev->pm.max_bandwidth.full > rdev->pm.sideport_bandwidth.full && rdev->pm.sideport_bandwidth.full) rdev->pm.max_bandwidth = rdev->pm.sideport_bandwidth; - read_delay_latency.full = dfixed_const(370 * 800 * 1000); - read_delay_latency.full = dfixed_div(read_delay_latency, + read_delay_latency.full = rfixed_const(370 * 800 * 1000); + read_delay_latency.full = rfixed_div(read_delay_latency, rdev->pm.igp_sideport_mclk); } else { if (rdev->pm.max_bandwidth.full > rdev->pm.k8_bandwidth.full && @@ -314,23 +314,23 @@ void rs690_crtc_bandwidth_compute(struct radeon_device *rdev, if (rdev->pm.max_bandwidth.full > rdev->pm.ht_bandwidth.full && rdev->pm.ht_bandwidth.full) rdev->pm.max_bandwidth = rdev->pm.ht_bandwidth; - read_delay_latency.full = dfixed_const(5000); + read_delay_latency.full = rfixed_const(5000); } /* sclk = system clocks(ns) = 1000 / max_bandwidth / 16 */ - a.full = dfixed_const(16); - rdev->pm.sclk.full = dfixed_mul(rdev->pm.max_bandwidth, a); - a.full = dfixed_const(1000); - rdev->pm.sclk.full = dfixed_div(a, rdev->pm.sclk); + a.full = rfixed_const(16); + rdev->pm.sclk.full = rfixed_mul(rdev->pm.max_bandwidth, a); + a.full = rfixed_const(1000); + rdev->pm.sclk.full = rfixed_div(a, rdev->pm.sclk); /* Determine chunk time * ChunkTime = the time it takes the DCP to send one chunk of data * to the LB which consists of pipeline delay and inter chunk gap * sclk = system clock(ns) */ - a.full = dfixed_const(256 * 13); - chunk_time.full = dfixed_mul(rdev->pm.sclk, a); - a.full = dfixed_const(10); - chunk_time.full = dfixed_div(chunk_time, a); + a.full = rfixed_const(256 * 13); + chunk_time.full = rfixed_mul(rdev->pm.sclk, a); + a.full = rfixed_const(10); + chunk_time.full = rfixed_div(chunk_time, a); /* Determine the worst case latency * NumLinePair = Number of line pairs to request(1=2 lines, 2=4 lines) @@ -340,13 +340,13 @@ void rs690_crtc_bandwidth_compute(struct radeon_device *rdev, * ChunkTime = time it takes the DCP to send one chunk of data to the LB * which consists of pipeline delay and inter chunk gap */ - if (dfixed_trunc(wm->num_line_pair) > 1) { - a.full = dfixed_const(3); - wm->worst_case_latency.full = dfixed_mul(a, chunk_time); + if (rfixed_trunc(wm->num_line_pair) > 1) { + a.full = rfixed_const(3); + wm->worst_case_latency.full = rfixed_mul(a, chunk_time); wm->worst_case_latency.full += read_delay_latency.full; } else { - a.full = dfixed_const(2); - wm->worst_case_latency.full = dfixed_mul(a, chunk_time); + a.full = rfixed_const(2); + wm->worst_case_latency.full = rfixed_mul(a, chunk_time); wm->worst_case_latency.full += read_delay_latency.full; } @@ -360,34 +360,34 @@ void rs690_crtc_bandwidth_compute(struct radeon_device *rdev, * of data to the LB which consists of * pipeline delay and inter chunk gap */ - if ((2+wm->lb_request_fifo_depth) >= dfixed_trunc(request_fifo_depth)) { + if ((2+wm->lb_request_fifo_depth) >= rfixed_trunc(request_fifo_depth)) { tolerable_latency.full = line_time.full; } else { - tolerable_latency.full = dfixed_const(wm->lb_request_fifo_depth - 2); + tolerable_latency.full = rfixed_const(wm->lb_request_fifo_depth - 2); tolerable_latency.full = request_fifo_depth.full - tolerable_latency.full; - tolerable_latency.full = dfixed_mul(tolerable_latency, chunk_time); + tolerable_latency.full = rfixed_mul(tolerable_latency, chunk_time); tolerable_latency.full = line_time.full - tolerable_latency.full; } /* We assume worst case 32bits (4 bytes) */ - wm->dbpp.full = dfixed_const(4 * 8); + wm->dbpp.full = rfixed_const(4 * 8); /* Determine the maximum priority mark * width = viewport width in pixels */ - a.full = dfixed_const(16); - wm->priority_mark_max.full = dfixed_const(crtc->base.mode.crtc_hdisplay); - wm->priority_mark_max.full = dfixed_div(wm->priority_mark_max, a); - wm->priority_mark_max.full = dfixed_ceil(wm->priority_mark_max); + a.full = rfixed_const(16); + wm->priority_mark_max.full = rfixed_const(crtc->base.mode.crtc_hdisplay); + wm->priority_mark_max.full = rfixed_div(wm->priority_mark_max, a); + wm->priority_mark_max.full = rfixed_ceil(wm->priority_mark_max); /* Determine estimated width */ estimated_width.full = tolerable_latency.full - wm->worst_case_latency.full; - estimated_width.full = dfixed_div(estimated_width, consumption_time); - if (dfixed_trunc(estimated_width) > crtc->base.mode.crtc_hdisplay) { - wm->priority_mark.full = dfixed_const(10); + estimated_width.full = rfixed_div(estimated_width, consumption_time); + if (rfixed_trunc(estimated_width) > crtc->base.mode.crtc_hdisplay) { + wm->priority_mark.full = rfixed_const(10); } else { - a.full = dfixed_const(16); - wm->priority_mark.full = dfixed_div(estimated_width, a); - wm->priority_mark.full = dfixed_ceil(wm->priority_mark); + a.full = rfixed_const(16); + wm->priority_mark.full = rfixed_div(estimated_width, a); + wm->priority_mark.full = rfixed_ceil(wm->priority_mark); wm->priority_mark.full = wm->priority_mark_max.full - wm->priority_mark.full; } } @@ -439,58 +439,58 @@ void rs690_bandwidth_update(struct radeon_device *rdev) WREG32(R_006D58_LB_MAX_REQ_OUTSTANDING, tmp); if (mode0 && mode1) { - if (dfixed_trunc(wm0.dbpp) > 64) - a.full = dfixed_mul(wm0.dbpp, wm0.num_line_pair); + if (rfixed_trunc(wm0.dbpp) > 64) + a.full = rfixed_mul(wm0.dbpp, wm0.num_line_pair); else a.full = wm0.num_line_pair.full; - if (dfixed_trunc(wm1.dbpp) > 64) - b.full = dfixed_mul(wm1.dbpp, wm1.num_line_pair); + if (rfixed_trunc(wm1.dbpp) > 64) + b.full = rfixed_mul(wm1.dbpp, wm1.num_line_pair); else b.full = wm1.num_line_pair.full; a.full += b.full; - fill_rate.full = dfixed_div(wm0.sclk, a); + fill_rate.full = rfixed_div(wm0.sclk, a); if (wm0.consumption_rate.full > fill_rate.full) { b.full = wm0.consumption_rate.full - fill_rate.full; - b.full = dfixed_mul(b, wm0.active_time); - a.full = dfixed_mul(wm0.worst_case_latency, + b.full = rfixed_mul(b, wm0.active_time); + a.full = rfixed_mul(wm0.worst_case_latency, wm0.consumption_rate); a.full = a.full + b.full; - b.full = dfixed_const(16 * 1000); - priority_mark02.full = dfixed_div(a, b); + b.full = rfixed_const(16 * 1000); + priority_mark02.full = rfixed_div(a, b); } else { - a.full = dfixed_mul(wm0.worst_case_latency, + a.full = rfixed_mul(wm0.worst_case_latency, wm0.consumption_rate); - b.full = dfixed_const(16 * 1000); - priority_mark02.full = dfixed_div(a, b); + b.full = rfixed_const(16 * 1000); + priority_mark02.full = rfixed_div(a, b); } if (wm1.consumption_rate.full > fill_rate.full) { b.full = wm1.consumption_rate.full - fill_rate.full; - b.full = dfixed_mul(b, wm1.active_time); - a.full = dfixed_mul(wm1.worst_case_latency, + b.full = rfixed_mul(b, wm1.active_time); + a.full = rfixed_mul(wm1.worst_case_latency, wm1.consumption_rate); a.full = a.full + b.full; - b.full = dfixed_const(16 * 1000); - priority_mark12.full = dfixed_div(a, b); + b.full = rfixed_const(16 * 1000); + priority_mark12.full = rfixed_div(a, b); } else { - a.full = dfixed_mul(wm1.worst_case_latency, + a.full = rfixed_mul(wm1.worst_case_latency, wm1.consumption_rate); - b.full = dfixed_const(16 * 1000); - priority_mark12.full = dfixed_div(a, b); + b.full = rfixed_const(16 * 1000); + priority_mark12.full = rfixed_div(a, b); } if (wm0.priority_mark.full > priority_mark02.full) priority_mark02.full = wm0.priority_mark.full; - if (dfixed_trunc(priority_mark02) < 0) + if (rfixed_trunc(priority_mark02) < 0) priority_mark02.full = 0; if (wm0.priority_mark_max.full > priority_mark02.full) priority_mark02.full = wm0.priority_mark_max.full; if (wm1.priority_mark.full > priority_mark12.full) priority_mark12.full = wm1.priority_mark.full; - if (dfixed_trunc(priority_mark12) < 0) + if (rfixed_trunc(priority_mark12) < 0) priority_mark12.full = 0; if (wm1.priority_mark_max.full > priority_mark12.full) priority_mark12.full = wm1.priority_mark_max.full; - d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); - d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); + d1mode_priority_a_cnt = rfixed_trunc(priority_mark02); + d2mode_priority_a_cnt = rfixed_trunc(priority_mark12); if (rdev->disp_priority == 2) { d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1); d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1); @@ -500,32 +500,32 @@ void rs690_bandwidth_update(struct radeon_device *rdev) WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); } else if (mode0) { - if (dfixed_trunc(wm0.dbpp) > 64) - a.full = dfixed_mul(wm0.dbpp, wm0.num_line_pair); + if (rfixed_trunc(wm0.dbpp) > 64) + a.full = rfixed_mul(wm0.dbpp, wm0.num_line_pair); else a.full = wm0.num_line_pair.full; - fill_rate.full = dfixed_div(wm0.sclk, a); + fill_rate.full = rfixed_div(wm0.sclk, a); if (wm0.consumption_rate.full > fill_rate.full) { b.full = wm0.consumption_rate.full - fill_rate.full; - b.full = dfixed_mul(b, wm0.active_time); - a.full = dfixed_mul(wm0.worst_case_latency, + b.full = rfixed_mul(b, wm0.active_time); + a.full = rfixed_mul(wm0.worst_case_latency, wm0.consumption_rate); a.full = a.full + b.full; - b.full = dfixed_const(16 * 1000); - priority_mark02.full = dfixed_div(a, b); + b.full = rfixed_const(16 * 1000); + priority_mark02.full = rfixed_div(a, b); } else { - a.full = dfixed_mul(wm0.worst_case_latency, + a.full = rfixed_mul(wm0.worst_case_latency, wm0.consumption_rate); - b.full = dfixed_const(16 * 1000); - priority_mark02.full = dfixed_div(a, b); + b.full = rfixed_const(16 * 1000); + priority_mark02.full = rfixed_div(a, b); } if (wm0.priority_mark.full > priority_mark02.full) priority_mark02.full = wm0.priority_mark.full; - if (dfixed_trunc(priority_mark02) < 0) + if (rfixed_trunc(priority_mark02) < 0) priority_mark02.full = 0; if (wm0.priority_mark_max.full > priority_mark02.full) priority_mark02.full = wm0.priority_mark_max.full; - d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); + d1mode_priority_a_cnt = rfixed_trunc(priority_mark02); if (rdev->disp_priority == 2) d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1); WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); @@ -535,32 +535,32 @@ void rs690_bandwidth_update(struct radeon_device *rdev) WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, S_006D4C_D2MODE_PRIORITY_B_OFF(1)); } else { - if (dfixed_trunc(wm1.dbpp) > 64) - a.full = dfixed_mul(wm1.dbpp, wm1.num_line_pair); + if (rfixed_trunc(wm1.dbpp) > 64) + a.full = rfixed_mul(wm1.dbpp, wm1.num_line_pair); else a.full = wm1.num_line_pair.full; - fill_rate.full = dfixed_div(wm1.sclk, a); + fill_rate.full = rfixed_div(wm1.sclk, a); if (wm1.consumption_rate.full > fill_rate.full) { b.full = wm1.consumption_rate.full - fill_rate.full; - b.full = dfixed_mul(b, wm1.active_time); - a.full = dfixed_mul(wm1.worst_case_latency, + b.full = rfixed_mul(b, wm1.active_time); + a.full = rfixed_mul(wm1.worst_case_latency, wm1.consumption_rate); a.full = a.full + b.full; - b.full = dfixed_const(16 * 1000); - priority_mark12.full = dfixed_div(a, b); + b.full = rfixed_const(16 * 1000); + priority_mark12.full = rfixed_div(a, b); } else { - a.full = dfixed_mul(wm1.worst_case_latency, + a.full = rfixed_mul(wm1.worst_case_latency, wm1.consumption_rate); - b.full = dfixed_const(16 * 1000); - priority_mark12.full = dfixed_div(a, b); + b.full = rfixed_const(16 * 1000); + priority_mark12.full = rfixed_div(a, b); } if (wm1.priority_mark.full > priority_mark12.full) priority_mark12.full = wm1.priority_mark.full; - if (dfixed_trunc(priority_mark12) < 0) + if (rfixed_trunc(priority_mark12) < 0) priority_mark12.full = 0; if (wm1.priority_mark_max.full > priority_mark12.full) priority_mark12.full = wm1.priority_mark_max.full; - d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); + d2mode_priority_a_cnt = rfixed_trunc(priority_mark12); if (rdev->disp_priority == 2) d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1); WREG32(R_006548_D1MODE_PRIORITY_A_CNT, @@ -676,6 +676,7 @@ int rs690_suspend(struct radeon_device *rdev) void rs690_fini(struct radeon_device *rdev) { + radeon_pm_fini(rdev); r100_cp_fini(rdev); r100_wb_fini(rdev); r100_ib_fini(rdev); @@ -726,6 +727,8 @@ int rs690_init(struct radeon_device *rdev) /* Initialize clocks */ radeon_get_clock_info(rdev->ddev); + /* Initialize power management */ + radeon_pm_init(rdev); /* initialize memory controller */ rs690_mc_init(rdev); rv515_debugfs(rdev); diff --git a/trunk/drivers/gpu/drm/radeon/rv515.c b/trunk/drivers/gpu/drm/radeon/rv515.c index 7d9a7b0a180a..c513473d72ae 100644 --- a/trunk/drivers/gpu/drm/radeon/rv515.c +++ b/trunk/drivers/gpu/drm/radeon/rv515.c @@ -445,6 +445,7 @@ void rv515_set_safe_registers(struct radeon_device *rdev) void rv515_fini(struct radeon_device *rdev) { + radeon_pm_fini(rdev); r100_cp_fini(rdev); r100_wb_fini(rdev); r100_ib_fini(rdev); @@ -493,6 +494,8 @@ int rv515_init(struct radeon_device *rdev) return -EINVAL; /* Initialize clocks */ radeon_get_clock_info(rdev->ddev); + /* Initialize power management */ + radeon_pm_init(rdev); /* initialize AGP */ if (rdev->flags & RADEON_IS_AGP) { r = radeon_agp_init(rdev); @@ -792,20 +795,20 @@ void rv515_crtc_bandwidth_compute(struct radeon_device *rdev, return; } - if (crtc->vsc.full > dfixed_const(2)) - wm->num_line_pair.full = dfixed_const(2); + if (crtc->vsc.full > rfixed_const(2)) + wm->num_line_pair.full = rfixed_const(2); else - wm->num_line_pair.full = dfixed_const(1); - - b.full = dfixed_const(mode->crtc_hdisplay); - c.full = dfixed_const(256); - a.full = dfixed_div(b, c); - request_fifo_depth.full = dfixed_mul(a, wm->num_line_pair); - request_fifo_depth.full = dfixed_ceil(request_fifo_depth); - if (a.full < dfixed_const(4)) { + wm->num_line_pair.full = rfixed_const(1); + + b.full = rfixed_const(mode->crtc_hdisplay); + c.full = rfixed_const(256); + a.full = rfixed_div(b, c); + request_fifo_depth.full = rfixed_mul(a, wm->num_line_pair); + request_fifo_depth.full = rfixed_ceil(request_fifo_depth); + if (a.full < rfixed_const(4)) { wm->lb_request_fifo_depth = 4; } else { - wm->lb_request_fifo_depth = dfixed_trunc(request_fifo_depth); + wm->lb_request_fifo_depth = rfixed_trunc(request_fifo_depth); } /* Determine consumption rate @@ -814,23 +817,23 @@ void rv515_crtc_bandwidth_compute(struct radeon_device *rdev, * vsc = vertical scaling ratio, defined as source/destination * hsc = horizontal scaling ration, defined as source/destination */ - a.full = dfixed_const(mode->clock); - b.full = dfixed_const(1000); - a.full = dfixed_div(a, b); - pclk.full = dfixed_div(b, a); + a.full = rfixed_const(mode->clock); + b.full = rfixed_const(1000); + a.full = rfixed_div(a, b); + pclk.full = rfixed_div(b, a); if (crtc->rmx_type != RMX_OFF) { - b.full = dfixed_const(2); + b.full = rfixed_const(2); if (crtc->vsc.full > b.full) b.full = crtc->vsc.full; - b.full = dfixed_mul(b, crtc->hsc); - c.full = dfixed_const(2); - b.full = dfixed_div(b, c); - consumption_time.full = dfixed_div(pclk, b); + b.full = rfixed_mul(b, crtc->hsc); + c.full = rfixed_const(2); + b.full = rfixed_div(b, c); + consumption_time.full = rfixed_div(pclk, b); } else { consumption_time.full = pclk.full; } - a.full = dfixed_const(1); - wm->consumption_rate.full = dfixed_div(a, consumption_time); + a.full = rfixed_const(1); + wm->consumption_rate.full = rfixed_div(a, consumption_time); /* Determine line time @@ -838,27 +841,27 @@ void rv515_crtc_bandwidth_compute(struct radeon_device *rdev, * LineTime = total number of horizontal pixels * pclk = pixel clock period(ns) */ - a.full = dfixed_const(crtc->base.mode.crtc_htotal); - line_time.full = dfixed_mul(a, pclk); + a.full = rfixed_const(crtc->base.mode.crtc_htotal); + line_time.full = rfixed_mul(a, pclk); /* Determine active time * ActiveTime = time of active region of display within one line, * hactive = total number of horizontal active pixels * htotal = total number of horizontal pixels */ - a.full = dfixed_const(crtc->base.mode.crtc_htotal); - b.full = dfixed_const(crtc->base.mode.crtc_hdisplay); - wm->active_time.full = dfixed_mul(line_time, b); - wm->active_time.full = dfixed_div(wm->active_time, a); + a.full = rfixed_const(crtc->base.mode.crtc_htotal); + b.full = rfixed_const(crtc->base.mode.crtc_hdisplay); + wm->active_time.full = rfixed_mul(line_time, b); + wm->active_time.full = rfixed_div(wm->active_time, a); /* Determine chunk time * ChunkTime = the time it takes the DCP to send one chunk of data * to the LB which consists of pipeline delay and inter chunk gap * sclk = system clock(Mhz) */ - a.full = dfixed_const(600 * 1000); - chunk_time.full = dfixed_div(a, rdev->pm.sclk); - read_delay_latency.full = dfixed_const(1000); + a.full = rfixed_const(600 * 1000); + chunk_time.full = rfixed_div(a, rdev->pm.sclk); + read_delay_latency.full = rfixed_const(1000); /* Determine the worst case latency * NumLinePair = Number of line pairs to request(1=2 lines, 2=4 lines) @@ -868,9 +871,9 @@ void rv515_crtc_bandwidth_compute(struct radeon_device *rdev, * ChunkTime = time it takes the DCP to send one chunk of data to the LB * which consists of pipeline delay and inter chunk gap */ - if (dfixed_trunc(wm->num_line_pair) > 1) { - a.full = dfixed_const(3); - wm->worst_case_latency.full = dfixed_mul(a, chunk_time); + if (rfixed_trunc(wm->num_line_pair) > 1) { + a.full = rfixed_const(3); + wm->worst_case_latency.full = rfixed_mul(a, chunk_time); wm->worst_case_latency.full += read_delay_latency.full; } else { wm->worst_case_latency.full = chunk_time.full + read_delay_latency.full; @@ -886,34 +889,34 @@ void rv515_crtc_bandwidth_compute(struct radeon_device *rdev, * of data to the LB which consists of * pipeline delay and inter chunk gap */ - if ((2+wm->lb_request_fifo_depth) >= dfixed_trunc(request_fifo_depth)) { + if ((2+wm->lb_request_fifo_depth) >= rfixed_trunc(request_fifo_depth)) { tolerable_latency.full = line_time.full; } else { - tolerable_latency.full = dfixed_const(wm->lb_request_fifo_depth - 2); + tolerable_latency.full = rfixed_const(wm->lb_request_fifo_depth - 2); tolerable_latency.full = request_fifo_depth.full - tolerable_latency.full; - tolerable_latency.full = dfixed_mul(tolerable_latency, chunk_time); + tolerable_latency.full = rfixed_mul(tolerable_latency, chunk_time); tolerable_latency.full = line_time.full - tolerable_latency.full; } /* We assume worst case 32bits (4 bytes) */ - wm->dbpp.full = dfixed_const(2 * 16); + wm->dbpp.full = rfixed_const(2 * 16); /* Determine the maximum priority mark * width = viewport width in pixels */ - a.full = dfixed_const(16); - wm->priority_mark_max.full = dfixed_const(crtc->base.mode.crtc_hdisplay); - wm->priority_mark_max.full = dfixed_div(wm->priority_mark_max, a); - wm->priority_mark_max.full = dfixed_ceil(wm->priority_mark_max); + a.full = rfixed_const(16); + wm->priority_mark_max.full = rfixed_const(crtc->base.mode.crtc_hdisplay); + wm->priority_mark_max.full = rfixed_div(wm->priority_mark_max, a); + wm->priority_mark_max.full = rfixed_ceil(wm->priority_mark_max); /* Determine estimated width */ estimated_width.full = tolerable_latency.full - wm->worst_case_latency.full; - estimated_width.full = dfixed_div(estimated_width, consumption_time); - if (dfixed_trunc(estimated_width) > crtc->base.mode.crtc_hdisplay) { + estimated_width.full = rfixed_div(estimated_width, consumption_time); + if (rfixed_trunc(estimated_width) > crtc->base.mode.crtc_hdisplay) { wm->priority_mark.full = wm->priority_mark_max.full; } else { - a.full = dfixed_const(16); - wm->priority_mark.full = dfixed_div(estimated_width, a); - wm->priority_mark.full = dfixed_ceil(wm->priority_mark); + a.full = rfixed_const(16); + wm->priority_mark.full = rfixed_div(estimated_width, a); + wm->priority_mark.full = rfixed_ceil(wm->priority_mark); wm->priority_mark.full = wm->priority_mark_max.full - wm->priority_mark.full; } } @@ -942,58 +945,58 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev) WREG32(LB_MAX_REQ_OUTSTANDING, tmp); if (mode0 && mode1) { - if (dfixed_trunc(wm0.dbpp) > 64) - a.full = dfixed_div(wm0.dbpp, wm0.num_line_pair); + if (rfixed_trunc(wm0.dbpp) > 64) + a.full = rfixed_div(wm0.dbpp, wm0.num_line_pair); else a.full = wm0.num_line_pair.full; - if (dfixed_trunc(wm1.dbpp) > 64) - b.full = dfixed_div(wm1.dbpp, wm1.num_line_pair); + if (rfixed_trunc(wm1.dbpp) > 64) + b.full = rfixed_div(wm1.dbpp, wm1.num_line_pair); else b.full = wm1.num_line_pair.full; a.full += b.full; - fill_rate.full = dfixed_div(wm0.sclk, a); + fill_rate.full = rfixed_div(wm0.sclk, a); if (wm0.consumption_rate.full > fill_rate.full) { b.full = wm0.consumption_rate.full - fill_rate.full; - b.full = dfixed_mul(b, wm0.active_time); - a.full = dfixed_const(16); - b.full = dfixed_div(b, a); - a.full = dfixed_mul(wm0.worst_case_latency, + b.full = rfixed_mul(b, wm0.active_time); + a.full = rfixed_const(16); + b.full = rfixed_div(b, a); + a.full = rfixed_mul(wm0.worst_case_latency, wm0.consumption_rate); priority_mark02.full = a.full + b.full; } else { - a.full = dfixed_mul(wm0.worst_case_latency, + a.full = rfixed_mul(wm0.worst_case_latency, wm0.consumption_rate); - b.full = dfixed_const(16 * 1000); - priority_mark02.full = dfixed_div(a, b); + b.full = rfixed_const(16 * 1000); + priority_mark02.full = rfixed_div(a, b); } if (wm1.consumption_rate.full > fill_rate.full) { b.full = wm1.consumption_rate.full - fill_rate.full; - b.full = dfixed_mul(b, wm1.active_time); - a.full = dfixed_const(16); - b.full = dfixed_div(b, a); - a.full = dfixed_mul(wm1.worst_case_latency, + b.full = rfixed_mul(b, wm1.active_time); + a.full = rfixed_const(16); + b.full = rfixed_div(b, a); + a.full = rfixed_mul(wm1.worst_case_latency, wm1.consumption_rate); priority_mark12.full = a.full + b.full; } else { - a.full = dfixed_mul(wm1.worst_case_latency, + a.full = rfixed_mul(wm1.worst_case_latency, wm1.consumption_rate); - b.full = dfixed_const(16 * 1000); - priority_mark12.full = dfixed_div(a, b); + b.full = rfixed_const(16 * 1000); + priority_mark12.full = rfixed_div(a, b); } if (wm0.priority_mark.full > priority_mark02.full) priority_mark02.full = wm0.priority_mark.full; - if (dfixed_trunc(priority_mark02) < 0) + if (rfixed_trunc(priority_mark02) < 0) priority_mark02.full = 0; if (wm0.priority_mark_max.full > priority_mark02.full) priority_mark02.full = wm0.priority_mark_max.full; if (wm1.priority_mark.full > priority_mark12.full) priority_mark12.full = wm1.priority_mark.full; - if (dfixed_trunc(priority_mark12) < 0) + if (rfixed_trunc(priority_mark12) < 0) priority_mark12.full = 0; if (wm1.priority_mark_max.full > priority_mark12.full) priority_mark12.full = wm1.priority_mark_max.full; - d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); - d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); + d1mode_priority_a_cnt = rfixed_trunc(priority_mark02); + d2mode_priority_a_cnt = rfixed_trunc(priority_mark12); if (rdev->disp_priority == 2) { d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; @@ -1003,32 +1006,32 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev) WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); } else if (mode0) { - if (dfixed_trunc(wm0.dbpp) > 64) - a.full = dfixed_div(wm0.dbpp, wm0.num_line_pair); + if (rfixed_trunc(wm0.dbpp) > 64) + a.full = rfixed_div(wm0.dbpp, wm0.num_line_pair); else a.full = wm0.num_line_pair.full; - fill_rate.full = dfixed_div(wm0.sclk, a); + fill_rate.full = rfixed_div(wm0.sclk, a); if (wm0.consumption_rate.full > fill_rate.full) { b.full = wm0.consumption_rate.full - fill_rate.full; - b.full = dfixed_mul(b, wm0.active_time); - a.full = dfixed_const(16); - b.full = dfixed_div(b, a); - a.full = dfixed_mul(wm0.worst_case_latency, + b.full = rfixed_mul(b, wm0.active_time); + a.full = rfixed_const(16); + b.full = rfixed_div(b, a); + a.full = rfixed_mul(wm0.worst_case_latency, wm0.consumption_rate); priority_mark02.full = a.full + b.full; } else { - a.full = dfixed_mul(wm0.worst_case_latency, + a.full = rfixed_mul(wm0.worst_case_latency, wm0.consumption_rate); - b.full = dfixed_const(16); - priority_mark02.full = dfixed_div(a, b); + b.full = rfixed_const(16); + priority_mark02.full = rfixed_div(a, b); } if (wm0.priority_mark.full > priority_mark02.full) priority_mark02.full = wm0.priority_mark.full; - if (dfixed_trunc(priority_mark02) < 0) + if (rfixed_trunc(priority_mark02) < 0) priority_mark02.full = 0; if (wm0.priority_mark_max.full > priority_mark02.full) priority_mark02.full = wm0.priority_mark_max.full; - d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); + d1mode_priority_a_cnt = rfixed_trunc(priority_mark02); if (rdev->disp_priority == 2) d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); @@ -1036,32 +1039,32 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev) WREG32(D2MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF); WREG32(D2MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF); } else { - if (dfixed_trunc(wm1.dbpp) > 64) - a.full = dfixed_div(wm1.dbpp, wm1.num_line_pair); + if (rfixed_trunc(wm1.dbpp) > 64) + a.full = rfixed_div(wm1.dbpp, wm1.num_line_pair); else a.full = wm1.num_line_pair.full; - fill_rate.full = dfixed_div(wm1.sclk, a); + fill_rate.full = rfixed_div(wm1.sclk, a); if (wm1.consumption_rate.full > fill_rate.full) { b.full = wm1.consumption_rate.full - fill_rate.full; - b.full = dfixed_mul(b, wm1.active_time); - a.full = dfixed_const(16); - b.full = dfixed_div(b, a); - a.full = dfixed_mul(wm1.worst_case_latency, + b.full = rfixed_mul(b, wm1.active_time); + a.full = rfixed_const(16); + b.full = rfixed_div(b, a); + a.full = rfixed_mul(wm1.worst_case_latency, wm1.consumption_rate); priority_mark12.full = a.full + b.full; } else { - a.full = dfixed_mul(wm1.worst_case_latency, + a.full = rfixed_mul(wm1.worst_case_latency, wm1.consumption_rate); - b.full = dfixed_const(16 * 1000); - priority_mark12.full = dfixed_div(a, b); + b.full = rfixed_const(16 * 1000); + priority_mark12.full = rfixed_div(a, b); } if (wm1.priority_mark.full > priority_mark12.full) priority_mark12.full = wm1.priority_mark.full; - if (dfixed_trunc(priority_mark12) < 0) + if (rfixed_trunc(priority_mark12) < 0) priority_mark12.full = 0; if (wm1.priority_mark_max.full > priority_mark12.full) priority_mark12.full = wm1.priority_mark_max.full; - d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); + d2mode_priority_a_cnt = rfixed_trunc(priority_mark12); if (rdev->disp_priority == 2) d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; WREG32(D1MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF); diff --git a/trunk/drivers/gpu/drm/radeon/rv770.c b/trunk/drivers/gpu/drm/radeon/rv770.c index 253f24aec031..a74683e18612 100644 --- a/trunk/drivers/gpu/drm/radeon/rv770.c +++ b/trunk/drivers/gpu/drm/radeon/rv770.c @@ -42,10 +42,6 @@ static void rv770_gpu_init(struct radeon_device *rdev); void rv770_fini(struct radeon_device *rdev); -void rv770_pm_misc(struct radeon_device *rdev) -{ - -} /* * GART @@ -1091,6 +1087,8 @@ int rv770_init(struct radeon_device *rdev) r = radeon_clocks_init(rdev); if (r) return r; + /* Initialize power management */ + radeon_pm_init(rdev); /* Fence driver */ r = radeon_fence_driver_init(rdev); if (r) @@ -1159,6 +1157,7 @@ int rv770_init(struct radeon_device *rdev) void rv770_fini(struct radeon_device *rdev) { + radeon_pm_fini(rdev); r600_blit_fini(rdev); r700_cp_fini(rdev); r600_wb_fini(rdev); diff --git a/trunk/drivers/gpu/drm/savage/savage_bci.c b/trunk/drivers/gpu/drm/savage/savage_bci.c index 2d0c9ca484c5..bff6fc2524c8 100644 --- a/trunk/drivers/gpu/drm/savage/savage_bci.c +++ b/trunk/drivers/gpu/drm/savage/savage_bci.c @@ -539,10 +539,11 @@ int savage_driver_load(struct drm_device *dev, unsigned long chipset) { drm_savage_private_t *dev_priv; - dev_priv = kzalloc(sizeof(drm_savage_private_t), GFP_KERNEL); + dev_priv = kmalloc(sizeof(drm_savage_private_t), GFP_KERNEL); if (dev_priv == NULL) return -ENOMEM; + memset(dev_priv, 0, sizeof(drm_savage_private_t)); dev->dev_private = (void *)dev_priv; dev_priv->chipset = (enum savage_family)chipset; diff --git a/trunk/drivers/gpu/drm/ttm/ttm_bo.c b/trunk/drivers/gpu/drm/ttm/ttm_bo.c index 4c2299299ab2..3b5b094b1397 100644 --- a/trunk/drivers/gpu/drm/ttm/ttm_bo.c +++ b/trunk/drivers/gpu/drm/ttm/ttm_bo.c @@ -604,20 +604,6 @@ void ttm_bo_unref(struct ttm_buffer_object **p_bo) } EXPORT_SYMBOL(ttm_bo_unref); -int ttm_bo_lock_delayed_workqueue(struct ttm_bo_device *bdev) -{ - return cancel_delayed_work_sync(&bdev->wq); -} -EXPORT_SYMBOL(ttm_bo_lock_delayed_workqueue); - -void ttm_bo_unlock_delayed_workqueue(struct ttm_bo_device *bdev, int resched) -{ - if (resched) - schedule_delayed_work(&bdev->wq, - ((HZ / 100) < 1) ? 1 : HZ / 100); -} -EXPORT_SYMBOL(ttm_bo_unlock_delayed_workqueue); - static int ttm_bo_evict(struct ttm_buffer_object *bo, bool interruptible, bool no_wait_reserve, bool no_wait_gpu) { diff --git a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index 7421aaad8d09..80125ffc4e28 100644 --- a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c @@ -559,13 +559,8 @@ int vmw_fb_init(struct vmw_private *vmw_priv) info->pixmap.scan_align = 1; #endif - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto err_aper; - } - info->apertures->ranges[0].base = vmw_priv->vram_start; - info->apertures->ranges[0].size = vmw_priv->vram_size; + info->aperture_base = vmw_priv->vram_start; + info->aperture_size = vmw_priv->vram_size; /* * Dirty & Deferred IO @@ -585,7 +580,6 @@ int vmw_fb_init(struct vmw_private *vmw_priv) err_defio: fb_deferred_io_cleanup(info); -err_aper: ttm_bo_kunmap(&par->map); err_unref: ttm_bo_unref((struct ttm_buffer_object **)&par->vmw_bo); diff --git a/trunk/drivers/gpu/vga/Kconfig b/trunk/drivers/gpu/vga/Kconfig index 8d0e31a22027..61ab4daf0bbb 100644 --- a/trunk/drivers/gpu/vga/Kconfig +++ b/trunk/drivers/gpu/vga/Kconfig @@ -18,12 +18,12 @@ config VGA_ARB_MAX_GPUS multiple GPUS. The overhead for each GPU is very small. config VGA_SWITCHEROO - bool "Laptop Hybrid Graphics - GPU switching support" + bool "Laptop Hybrid Grapics - GPU switching support" depends on X86 depends on ACPI help - Many laptops released in 2008/9/10 have two GPUs with a multiplexer + Many laptops released in 2008/9/10 have two gpus with a multiplxer to switch between them. This adds support for dynamic switching when X isn't running and delayed switching until the next logoff. This - feature is called hybrid graphics, ATI PowerXpress, and Nvidia + features is called hybrid graphics, ATI PowerXpress, and Nvidia HybridPower. diff --git a/trunk/drivers/video/efifb.c b/trunk/drivers/video/efifb.c index 3b986567111a..581d2dbf675a 100644 --- a/trunk/drivers/video/efifb.c +++ b/trunk/drivers/video/efifb.c @@ -165,7 +165,7 @@ static void efifb_destroy(struct fb_info *info) { if (info->screen_base) iounmap(info->screen_base); - release_mem_region(info->apertures->ranges[0].base, info->apertures->ranges[0].size); + release_mem_region(info->aperture_base, info->aperture_size); framebuffer_release(info); } @@ -289,13 +289,8 @@ static int __devinit efifb_probe(struct platform_device *dev) info->pseudo_palette = info->par; info->par = NULL; - info->apertures = alloc_apertures(1); - if (!info->apertures) { - err = -ENOMEM; - goto err_release_fb; - } - info->apertures->ranges[0].base = efifb_fix.smem_start; - info->apertures->ranges[0].size = size_remap; + info->aperture_base = efifb_fix.smem_start; + info->aperture_size = size_remap; info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len); if (!info->screen_base) { diff --git a/trunk/drivers/video/fbmem.c b/trunk/drivers/video/fbmem.c index e08b7b5cb326..a15b44e9c003 100644 --- a/trunk/drivers/video/fbmem.c +++ b/trunk/drivers/video/fbmem.c @@ -1468,67 +1468,16 @@ static int fb_check_foreignness(struct fb_info *fi) return 0; } -static bool apertures_overlap(struct aperture *gen, struct aperture *hw) +static bool fb_do_apertures_overlap(struct fb_info *gen, struct fb_info *hw) { /* is the generic aperture base the same as the HW one */ - if (gen->base == hw->base) + if (gen->aperture_base == hw->aperture_base) return true; /* is the generic aperture base inside the hw base->hw base+size */ - if (gen->base > hw->base && gen->base <= hw->base + hw->size) + if (gen->aperture_base > hw->aperture_base && gen->aperture_base <= hw->aperture_base + hw->aperture_size) return true; return false; } - -static bool fb_do_apertures_overlap(struct apertures_struct *gena, - struct apertures_struct *hwa) -{ - int i, j; - if (!hwa || !gena) - return false; - - for (i = 0; i < hwa->count; ++i) { - struct aperture *h = &hwa->ranges[i]; - for (j = 0; j < gena->count; ++j) { - struct aperture *g = &gena->ranges[j]; - printk(KERN_DEBUG "checking generic (%llx %llx) vs hw (%llx %llx)\n", - g->base, g->size, h->base, h->size); - if (apertures_overlap(g, h)) - return true; - } - } - - return false; -} - -#define VGA_FB_PHYS 0xA0000 -void remove_conflicting_framebuffers(struct apertures_struct *a, - const char *name, bool primary) -{ - int i; - - /* check all firmware fbs and kick off if the base addr overlaps */ - for (i = 0 ; i < FB_MAX; i++) { - struct apertures_struct *gen_aper; - if (!registered_fb[i]) - continue; - - if (!(registered_fb[i]->flags & FBINFO_MISC_FIRMWARE)) - continue; - - gen_aper = registered_fb[i]->apertures; - if (fb_do_apertures_overlap(gen_aper, a) || - (primary && gen_aper && gen_aper->count && - gen_aper->ranges[0].base == VGA_FB_PHYS)) { - - printk(KERN_ERR "fb: conflicting fb hw usage " - "%s vs %s - removing generic driver\n", - name, registered_fb[i]->fix.id); - unregister_framebuffer(registered_fb[i]); - } - } -} -EXPORT_SYMBOL(remove_conflicting_framebuffers); - /** * register_framebuffer - registers a frame buffer device * @fb_info: frame buffer info structure @@ -1552,8 +1501,21 @@ register_framebuffer(struct fb_info *fb_info) if (fb_check_foreignness(fb_info)) return -ENOSYS; - remove_conflicting_framebuffers(fb_info->apertures, fb_info->fix.id, - fb_is_primary_device(fb_info)); + /* check all firmware fbs and kick off if the base addr overlaps */ + for (i = 0 ; i < FB_MAX; i++) { + if (!registered_fb[i]) + continue; + + if (registered_fb[i]->flags & FBINFO_MISC_FIRMWARE) { + if (fb_do_apertures_overlap(registered_fb[i], fb_info)) { + printk(KERN_ERR "fb: conflicting fb hw usage " + "%s vs %s - removing generic driver\n", + fb_info->fix.id, + registered_fb[i]->fix.id); + unregister_framebuffer(registered_fb[i]); + } + } + } num_registered_fb++; for (i = 0 ; i < FB_MAX; i++) diff --git a/trunk/drivers/video/fbsysfs.c b/trunk/drivers/video/fbsysfs.c index 0a08f1341227..81aa3129c17d 100644 --- a/trunk/drivers/video/fbsysfs.c +++ b/trunk/drivers/video/fbsysfs.c @@ -80,7 +80,6 @@ EXPORT_SYMBOL(framebuffer_alloc); */ void framebuffer_release(struct fb_info *info) { - kfree(info->apertures); kfree(info); } EXPORT_SYMBOL(framebuffer_release); diff --git a/trunk/drivers/video/offb.c b/trunk/drivers/video/offb.c index 46dda7d8aaee..61f8b8f919b0 100644 --- a/trunk/drivers/video/offb.c +++ b/trunk/drivers/video/offb.c @@ -285,7 +285,7 @@ static void offb_destroy(struct fb_info *info) { if (info->screen_base) iounmap(info->screen_base); - release_mem_region(info->apertures->ranges[0].base, info->apertures->ranges[0].size); + release_mem_region(info->aperture_base, info->aperture_size); framebuffer_release(info); } @@ -491,11 +491,8 @@ static void __init offb_init_fb(const char *name, const char *full_name, var->vmode = FB_VMODE_NONINTERLACED; /* set offb aperture size for generic probing */ - info->apertures = alloc_apertures(1); - if (!info->apertures) - goto out_aper; - info->apertures->ranges[0].base = address; - info->apertures->ranges[0].size = fix->smem_len; + info->aperture_base = address; + info->aperture_size = fix->smem_len; info->fbops = &offb_ops; info->screen_base = ioremap(address, fix->smem_len); @@ -504,20 +501,17 @@ static void __init offb_init_fb(const char *name, const char *full_name, fb_alloc_cmap(&info->cmap, 256, 0); - if (register_framebuffer(info) < 0) - goto out_err; + if (register_framebuffer(info) < 0) { + iounmap(par->cmap_adr); + par->cmap_adr = NULL; + iounmap(info->screen_base); + framebuffer_release(info); + release_mem_region(res_start, res_size); + return; + } printk(KERN_INFO "fb%d: Open Firmware frame buffer device on %s\n", info->node, full_name); - return; - -out_err: - iounmap(info->screen_base); -out_aper: - iounmap(par->cmap_adr); - par->cmap_adr = NULL; - framebuffer_release(info); - release_mem_region(res_start, res_size); } diff --git a/trunk/drivers/video/vesafb.c b/trunk/drivers/video/vesafb.c index 090aa1a9be6e..0cadf7aee27e 100644 --- a/trunk/drivers/video/vesafb.c +++ b/trunk/drivers/video/vesafb.c @@ -177,7 +177,7 @@ static void vesafb_destroy(struct fb_info *info) { if (info->screen_base) iounmap(info->screen_base); - release_mem_region(info->apertures->ranges[0].base, info->apertures->ranges[0].size); + release_mem_region(info->aperture_base, info->aperture_size); framebuffer_release(info); } @@ -295,13 +295,8 @@ static int __init vesafb_probe(struct platform_device *dev) info->par = NULL; /* set vesafb aperture size for generic probing */ - info->apertures = alloc_apertures(1); - if (!info->apertures) { - err = -ENOMEM; - goto err; - } - info->apertures->ranges[0].base = screen_info.lfb_base; - info->apertures->ranges[0].size = size_total; + info->aperture_base = screen_info.lfb_base; + info->aperture_size = size_total; info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len); if (!info->screen_base) { diff --git a/trunk/drivers/video/vga16fb.c b/trunk/drivers/video/vga16fb.c index 149c47ac7e93..bf638a47a5b3 100644 --- a/trunk/drivers/video/vga16fb.c +++ b/trunk/drivers/video/vga16fb.c @@ -1263,19 +1263,10 @@ static void vga16fb_imageblit(struct fb_info *info, const struct fb_image *image vga_imageblit_color(info, image); } -static void vga16fb_destroy(struct fb_info *info) -{ - iounmap(info->screen_base); - fb_dealloc_cmap(&info->cmap); - /* XXX unshare VGA regions */ - framebuffer_release(info); -} - static struct fb_ops vga16fb_ops = { .owner = THIS_MODULE, .fb_open = vga16fb_open, .fb_release = vga16fb_release, - .fb_destroy = vga16fb_destroy, .fb_check_var = vga16fb_check_var, .fb_set_par = vga16fb_set_par, .fb_setcolreg = vga16fb_setcolreg, @@ -1315,11 +1306,6 @@ static int __devinit vga16fb_probe(struct platform_device *dev) ret = -ENOMEM; goto err_fb_alloc; } - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto err_ioremap; - } /* XXX share VGA_FB_PHYS and I/O region with vgacon and others */ info->screen_base = (void __iomem *)VGA_MAP_MEM(VGA_FB_PHYS, 0); @@ -1349,7 +1335,7 @@ static int __devinit vga16fb_probe(struct platform_device *dev) info->fix = vga16fb_fix; /* supports rectangles with widths of multiples of 8 */ info->pixmap.blit_x = 1 << 7 | 1 << 15 | 1 << 23 | 1 << 31; - info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE | + info->flags = FBINFO_FLAG_DEFAULT | FBINFO_HWACCEL_YPAN; i = (info->var.bits_per_pixel == 8) ? 256 : 16; @@ -1368,9 +1354,6 @@ static int __devinit vga16fb_probe(struct platform_device *dev) vga16fb_update_fix(info); - info->apertures->ranges[0].base = VGA_FB_PHYS; - info->apertures->ranges[0].size = VGA_FB_PHYS_LEN; - if (register_framebuffer(info) < 0) { printk(KERN_ERR "vga16fb: unable to register framebuffer\n"); ret = -EINVAL; @@ -1397,8 +1380,13 @@ static int vga16fb_remove(struct platform_device *dev) { struct fb_info *info = platform_get_drvdata(dev); - if (info) + if (info) { unregister_framebuffer(info); + iounmap(info->screen_base); + fb_dealloc_cmap(&info->cmap); + /* XXX unshare VGA regions */ + framebuffer_release(info); + } return 0; } diff --git a/trunk/include/drm/drm_crtc.h b/trunk/include/drm/drm_crtc.h index 93a1a31b9c2d..c560364663a5 100644 --- a/trunk/include/drm/drm_crtc.h +++ b/trunk/include/drm/drm_crtc.h @@ -31,7 +31,6 @@ #include #include -#include struct drm_device; struct drm_mode_set; @@ -461,15 +460,6 @@ enum drm_connector_force { DRM_FORCE_ON_DIGITAL, /* for DVI-I use digital connector */ }; -/* should we poll this connector for connects and disconnects */ -/* hot plug detectable */ -#define DRM_CONNECTOR_POLL_HPD (1 << 0) -/* poll for connections */ -#define DRM_CONNECTOR_POLL_CONNECT (1 << 1) -/* can cleanly poll for disconnections without flickering the screen */ -/* DACs should rarely do this without a lot of testing */ -#define DRM_CONNECTOR_POLL_DISCONNECT (1 << 2) - /** * drm_connector - central DRM connector control structure * @crtc: CRTC this connector is currently connected to, NULL if none @@ -514,8 +504,6 @@ struct drm_connector { u32 property_ids[DRM_CONNECTOR_MAX_PROPERTY]; uint64_t property_values[DRM_CONNECTOR_MAX_PROPERTY]; - uint8_t polled; /* DRM_CONNECTOR_POLL_* */ - /* requested DPMS state */ int dpms; @@ -555,7 +543,6 @@ struct drm_mode_set { */ struct drm_mode_config_funcs { struct drm_framebuffer *(*fb_create)(struct drm_device *dev, struct drm_file *file_priv, struct drm_mode_fb_cmd *mode_cmd); - void (*output_poll_changed)(struct drm_device *dev); }; struct drm_mode_group { @@ -593,10 +580,6 @@ struct drm_mode_config { struct drm_mode_config_funcs *funcs; resource_size_t fb_base; - /* output poll support */ - bool poll_enabled; - struct delayed_slow_work output_poll_slow_work; - /* pointers to standard properties */ struct list_head property_blob_list; struct drm_property *edid_property; @@ -804,6 +787,4 @@ extern int drm_add_modes_noedid(struct drm_connector *connector, int hdisplay, int vdisplay); extern bool drm_edid_is_valid(struct edid *edid); -struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, - int hsize, int vsize, int fresh); #endif /* __DRM_CRTC_H__ */ diff --git a/trunk/include/drm/drm_crtc_helper.h b/trunk/include/drm/drm_crtc_helper.h index dc5873c21e45..b1fa0f8cfa60 100644 --- a/trunk/include/drm/drm_crtc_helper.h +++ b/trunk/include/drm/drm_crtc_helper.h @@ -127,7 +127,4 @@ static inline void drm_connector_helper_add(struct drm_connector *connector, } extern int drm_helper_resume_force_mode(struct drm_device *dev); -extern void drm_kms_helper_poll_init(struct drm_device *dev); -extern void drm_kms_helper_poll_fini(struct drm_device *dev); -extern void drm_helper_hpd_irq_event(struct drm_device *dev); #endif diff --git a/trunk/include/drm/drm_edid.h b/trunk/include/drm/drm_edid.h index 39e2cc5c7e66..d33c3e038606 100644 --- a/trunk/include/drm/drm_edid.h +++ b/trunk/include/drm/drm_edid.h @@ -120,7 +120,7 @@ struct detailed_non_pixel { struct detailed_data_string str; struct detailed_data_monitor_range range; struct detailed_data_wpindex color; - struct std_timing timings[6]; + struct std_timing timings[5]; struct cvt_timing cvt[4]; } data; } __attribute__((packed)); diff --git a/trunk/include/drm/drm_fb_helper.h b/trunk/include/drm/drm_fb_helper.h index f0a6afc47e76..9b55a94feada 100644 --- a/trunk/include/drm/drm_fb_helper.h +++ b/trunk/include/drm/drm_fb_helper.h @@ -30,6 +30,8 @@ #ifndef DRM_FB_HELPER_H #define DRM_FB_HELPER_H +#include + struct drm_fb_helper; struct drm_fb_helper_crtc { @@ -69,6 +71,9 @@ struct drm_fb_helper_funcs { int (*fb_probe)(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes); + + void (*fb_output_status_changed)(struct drm_fb_helper *helper); + }; struct drm_fb_helper_connector { @@ -90,6 +95,8 @@ struct drm_fb_helper { u32 pseudo_palette[17]; struct list_head kernel_fb_list; + struct delayed_slow_work output_status_change_slow_work; + bool poll_enabled; /* we got a hotplug but fbdev wasn't running the console delay until next set_par */ bool delayed_hotplug; @@ -100,7 +107,7 @@ int drm_fb_helper_single_fb_probe(struct drm_fb_helper *helper, int drm_fb_helper_init(struct drm_device *dev, struct drm_fb_helper *helper, int crtc_count, - int max_conn); + int max_conn, bool polled); void drm_fb_helper_fini(struct drm_fb_helper *helper); int drm_fb_helper_blank(int blank, struct fb_info *info); int drm_fb_helper_pan_display(struct fb_var_screeninfo *var, @@ -123,8 +130,10 @@ void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch, int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info); -bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper); +bool drm_helper_fb_hotplug_event(struct drm_fb_helper *fb_helper, + bool polled); bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel); int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper); +void drm_helper_fb_hpd_irq_event(struct drm_fb_helper *fb_helper); #endif diff --git a/trunk/include/drm/radeon_drm.h b/trunk/include/drm/radeon_drm.h index 3ff9fc071dfe..81e614bf2dc3 100644 --- a/trunk/include/drm/radeon_drm.h +++ b/trunk/include/drm/radeon_drm.h @@ -902,7 +902,6 @@ struct drm_radeon_cs { #define RADEON_INFO_NUM_GB_PIPES 0x01 #define RADEON_INFO_NUM_Z_PIPES 0x02 #define RADEON_INFO_ACCEL_WORKING 0x03 -#define RADEON_INFO_CRTC_FROM_ID 0x04 struct drm_radeon_info { uint32_t request; diff --git a/trunk/include/drm/ttm/ttm_bo_api.h b/trunk/include/drm/ttm/ttm_bo_api.h index 267a86c74e2e..3e273e0b9417 100644 --- a/trunk/include/drm/ttm/ttm_bo_api.h +++ b/trunk/include/drm/ttm/ttm_bo_api.h @@ -361,23 +361,6 @@ extern int ttm_bo_validate(struct ttm_buffer_object *bo, */ extern void ttm_bo_unref(struct ttm_buffer_object **bo); -/** - * ttm_bo_lock_delayed_workqueue - * - * Prevent the delayed workqueue from running. - * Returns - * True if the workqueue was queued at the time - */ -extern int ttm_bo_lock_delayed_workqueue(struct ttm_bo_device *bdev); - -/** - * ttm_bo_unlock_delayed_workqueue - * - * Allows the delayed workqueue to run. - */ -extern void ttm_bo_unlock_delayed_workqueue(struct ttm_bo_device *bdev, - int resched); - /** * ttm_bo_synccpu_write_grab * diff --git a/trunk/include/linux/fb.h b/trunk/include/linux/fb.h index 1296af45169d..c10163b4c40e 100644 --- a/trunk/include/linux/fb.h +++ b/trunk/include/linux/fb.h @@ -403,7 +403,6 @@ struct fb_cursor { #include #include #include -#include #include struct vm_area_struct; @@ -863,22 +862,10 @@ struct fb_info { /* we need the PCI or similiar aperture base/size not smem_start/size as smem_start may just be an object allocated inside the aperture so may not actually overlap */ - struct apertures_struct { - unsigned int count; - struct aperture { - resource_size_t base; - resource_size_t size; - } ranges[0]; - } *apertures; + resource_size_t aperture_base; + resource_size_t aperture_size; }; -static inline struct apertures_struct *alloc_apertures(unsigned int max_num) { - struct apertures_struct *a = kzalloc(sizeof(struct apertures_struct) - + max_num * sizeof(struct aperture), GFP_KERNEL); - a->count = max_num; - return a; -} - #ifdef MODULE #define FBINFO_DEFAULT FBINFO_MODULE #else @@ -971,8 +958,6 @@ extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf, /* drivers/video/fbmem.c */ extern int register_framebuffer(struct fb_info *fb_info); extern int unregister_framebuffer(struct fb_info *fb_info); -extern void remove_conflicting_framebuffers(struct apertures_struct *a, - const char *name, bool primary); extern int fb_prepare_logo(struct fb_info *fb_info, int rotate); extern int fb_show_logo(struct fb_info *fb_info, int rotate); extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);