diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-06-03 07:19:45 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-06-03 07:19:45 -0700 |
commit | 1067b6c2bea7fd2cc9da290d865ab3f3b91c8130 (patch) | |
tree | 5b20d5fbe9f9a2b3cfbb794018d74606f5031a88 | |
parent | a652883a244901742d6c9733a9eebdf72e3114ea (diff) | |
parent | d8dcaa1dc50f5aecd38d34180cd99d6af8566c88 (diff) |
Merge branch 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: (41 commits)
drm/radeon/kms: make sure display hw is disabled when suspending
drm/vmwgfx: Allow userspace to change default layout. Bump minor.
drm/vmwgfx: Fix framebuffer modesetting
drm/vmwgfx: Fix vga save / restore with display topology.
vgaarb: use MIT license
vgaarb: convert pr_devel() to pr_debug()
drm: fix typos in Linux DRM Developer's Guide
drm/radeon/kms/pm: voltage fixes
drm/radeon/kms/pm: radeon_set_power_state fixes
drm/radeon/kms/pm: patch default power state with default clocks/voltages on r6xx+
drm/radeon/kms/pm: enable SetVoltage on r7xx/evergreen
drm/radeon/kms/pm: add support for SetVoltage cmd table (V2)
drm/radeon/kms/evergreen: add initial CS parser
drm/kms: disable/enable poll around switcheroo on/off
drm/nouveau: fixup confusion over which handle the DSM is hanging off.
drm/nouveau: attempt to get bios from ACPI v3
drm/nv50: cast IGP memory location to u64 before shifting
drm/ttm: Fix ttm_page_alloc.c
drm/ttm: Fix cached TTM page allocation.
drm/vmwgfx: Remove some leftover debug messages.
...
48 files changed, 3538 insertions, 321 deletions
diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 7583dc7cf64..910c923a9b8 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -389,7 +389,7 @@ </para> <para> If your driver supports memory management (it should!), you'll - need to set that up at load time as well. How you intialize + need to set that up at load time as well. How you initialize it depends on which memory manager you're using, TTM or GEM. </para> <sect3> @@ -399,7 +399,7 @@ aperture space for graphics devices. TTM supports both UMA devices and devices with dedicated video RAM (VRAM), i.e. most discrete graphics devices. If your device has dedicated RAM, supporting - TTM is desireable. TTM also integrates tightly with your + TTM is desirable. TTM also integrates tightly with your driver specific buffer execution function. See the radeon driver for examples. </para> @@ -443,7 +443,7 @@ likely eventually calling ttm_bo_global_init and ttm_bo_global_release, respectively. Also like the previous object, ttm_global_item_ref is used to create an initial reference - count for the TTM, which will call your initalization function. + count for the TTM, which will call your initialization function. </para> </sect3> <sect3> @@ -557,7 +557,7 @@ void intel_crt_init(struct drm_device *dev) CRT connector and encoder combination is created. A device specific i2c bus is also created, for fetching EDID data and performing monitor detection. Once the process is complete, - the new connector is regsitered with sysfs, to make its + the new connector is registered with sysfs, to make its properties available to applications. </para> <sect4> @@ -581,12 +581,12 @@ void intel_crt_init(struct drm_device *dev) <para> For each encoder, CRTC and connector, several functions must be provided, depending on the object type. Encoder objects - need should provide a DPMS (basically on/off) function, mode fixup + need to provide a DPMS (basically on/off) function, mode fixup (for converting requested modes into native hardware timings), and prepare, set and commit functions for use by the core DRM helper functions. Connector helpers need to provide mode fetch and validity functions as well as an encoder matching function for - returing an ideal encoder for a given connector. The core + returning an ideal encoder for a given connector. The core connector functions include a DPMS callback, (deprecated) save/restore routines, detection, mode probing, property handling, and cleanup functions. diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 76440195104..9b2a54117c9 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -860,19 +860,24 @@ static void output_poll_execute(struct slow_work *work) } } -void drm_kms_helper_poll_init(struct drm_device *dev) +void drm_kms_helper_poll_disable(struct drm_device *dev) +{ + if (!dev->mode_config.poll_enabled) + return; + delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work); +} +EXPORT_SYMBOL(drm_kms_helper_poll_disable); + +void drm_kms_helper_poll_enable(struct drm_device *dev) { - struct drm_connector *connector; bool poll = false; + struct drm_connector *connector; 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); @@ -880,11 +885,22 @@ void drm_kms_helper_poll_init(struct drm_device *dev) DRM_ERROR("delayed enqueue failed %d\n", ret); } } +EXPORT_SYMBOL(drm_kms_helper_poll_enable); + +void drm_kms_helper_poll_init(struct drm_device *dev) +{ + slow_work_register_user(THIS_MODULE); + delayed_slow_work_init(&dev->mode_config.output_poll_slow_work, + &output_poll_ops); + dev->mode_config.poll_enabled = true; + + drm_kms_helper_poll_enable(dev); +} 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); + drm_kms_helper_poll_disable(dev); slow_work_unregister_user(THIS_MODULE); } EXPORT_SYMBOL(drm_kms_helper_poll_fini); diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 84ce95602f0..b2ebf02e4f8 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1320,12 +1320,14 @@ static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_ struct drm_device *dev = pci_get_drvdata(pdev); pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; if (state == VGA_SWITCHEROO_ON) { - printk(KERN_INFO "i915: switched off\n"); + printk(KERN_INFO "i915: switched on\n"); /* i915 resume handler doesn't set to D0 */ pci_set_power_state(dev->pdev, PCI_D0); i915_resume(dev); + drm_kms_helper_poll_enable(dev); } else { printk(KERN_ERR "i915: switched off\n"); + drm_kms_helper_poll_disable(dev); i915_suspend(dev, pmm); } } diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index e13f6af0037..d4bcca8a513 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c @@ -34,7 +34,7 @@ static struct nouveau_dsm_priv { bool dsm_detected; acpi_handle dhandle; - acpi_handle dsm_handle; + acpi_handle rom_handle; } nouveau_dsm_priv; static const char nouveau_dsm_muid[] = { @@ -107,9 +107,9 @@ static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switchero static int nouveau_dsm_switchto(enum vga_switcheroo_client_id id) { if (id == VGA_SWITCHEROO_IGD) - return nouveau_dsm_switch_mux(nouveau_dsm_priv.dsm_handle, NOUVEAU_DSM_LED_STAMINA); + return nouveau_dsm_switch_mux(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_LED_STAMINA); else - return nouveau_dsm_switch_mux(nouveau_dsm_priv.dsm_handle, NOUVEAU_DSM_LED_SPEED); + return nouveau_dsm_switch_mux(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_LED_SPEED); } static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id, @@ -118,7 +118,7 @@ static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id, if (id == VGA_SWITCHEROO_IGD) return 0; - return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dsm_handle, state); + return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dhandle, state); } static int nouveau_dsm_init(void) @@ -151,18 +151,18 @@ static bool nouveau_dsm_pci_probe(struct pci_dev *pdev) dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); if (!dhandle) return false; + status = acpi_get_handle(dhandle, "_DSM", &nvidia_handle); if (ACPI_FAILURE(status)) { return false; } - ret= nouveau_dsm(nvidia_handle, NOUVEAU_DSM_SUPPORTED, - NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &result); + ret = nouveau_dsm(dhandle, NOUVEAU_DSM_SUPPORTED, + NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &result); if (ret < 0) return false; nouveau_dsm_priv.dhandle = dhandle; - nouveau_dsm_priv.dsm_handle = nvidia_handle; return true; } @@ -173,6 +173,7 @@ static bool nouveau_dsm_detect(void) struct pci_dev *pdev = NULL; int has_dsm = 0; int vga_count = 0; + while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) { vga_count++; @@ -180,7 +181,7 @@ static bool nouveau_dsm_detect(void) } if (vga_count == 2 && has_dsm) { - acpi_get_name(nouveau_dsm_priv.dsm_handle, ACPI_FULL_PATHNAME, &buffer); + acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME, &buffer); printk(KERN_INFO "VGA switcheroo: detected DSM switching method %s handle\n", acpi_method_name); nouveau_dsm_priv.dsm_detected = true; @@ -204,3 +205,57 @@ void nouveau_unregister_dsm_handler(void) { vga_switcheroo_unregister_handler(); } + +/* retrieve the ROM in 4k blocks */ +static int nouveau_rom_call(acpi_handle rom_handle, uint8_t *bios, + int offset, int len) +{ + acpi_status status; + union acpi_object rom_arg_elements[2], *obj; + struct acpi_object_list rom_arg; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; + + rom_arg.count = 2; + rom_arg.pointer = &rom_arg_elements[0]; + + rom_arg_elements[0].type = ACPI_TYPE_INTEGER; + rom_arg_elements[0].integer.value = offset; + + rom_arg_elements[1].type = ACPI_TYPE_INTEGER; + rom_arg_elements[1].integer.value = len; + + status = acpi_evaluate_object(rom_handle, NULL, &rom_arg, &buffer); + if (ACPI_FAILURE(status)) { + printk(KERN_INFO "failed to evaluate ROM got %s\n", acpi_format_exception(status)); + return -ENODEV; + } + obj = (union acpi_object *)buffer.pointer; + memcpy(bios+offset, obj->buffer.pointer, len); + kfree(buffer.pointer); + return len; +} + +bool nouveau_acpi_rom_supported(struct pci_dev *pdev) +{ + acpi_status status; + acpi_handle dhandle, rom_handle; + + if (!nouveau_dsm_priv.dsm_detected) + return false; + + dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); + if (!dhandle) + return false; + + status = acpi_get_handle(dhandle, "_ROM", &rom_handle); + if (ACPI_FAILURE(status)) + return false; + + nouveau_dsm_priv.rom_handle = rom_handle; + return true; +} + +int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) +{ + return nouveau_rom_call(nouveau_dsm_priv.rom_handle, bios, offset, len); +} diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index e7e69ccce5c..9ba2deaadcc 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -178,6 +178,25 @@ out: pci_disable_rom(dev->pdev); } +static void load_vbios_acpi(struct drm_device *dev, uint8_t *data) +{ + int i; + int ret; + int size = 64 * 1024; + + if (!nouveau_acpi_rom_supported(dev->pdev)) + return; + + for (i = 0; i < (size / ROM_BIOS_PAGE); i++) { + ret = nouveau_acpi_get_bios_chunk(data, + (i * ROM_BIOS_PAGE), + ROM_BIOS_PAGE); + if (ret <= 0) + break; + } + return; +} + struct methods { const char desc[8]; void (*loadbios)(struct drm_device *, uint8_t *); @@ -191,6 +210,7 @@ static struct methods nv04_methods[] = { }; static struct methods nv50_methods[] = { + { "ACPI", load_vbios_acpi, true }, { "PRAMIN", load_vbios_pramin, true }, { "PROM", load_vbios_prom, false }, { "PCIROM", load_vbios_pci, true }, @@ -2807,7 +2827,10 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, gpio->entry); - nv50_gpio_set(bios->dev, gpio->tag, gpio->state_default); + BIOSLOG(bios, "0x%04X: set gpio 0x%02x, state %d\n", + offset, gpio->tag, gpio->state_default); + if (bios->execute) + nv50_gpio_set(bios->dev, gpio->tag, gpio->state_default); /* The NVIDIA binary driver doesn't appear to actually do * any of this, my VBIOS does however. @@ -5533,12 +5556,6 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb, entry->bus = (conn >> 16) & 0xf; entry->location = (conn >> 20) & 0x3; entry->or = (conn >> 24) & 0xf; - /* - * Normal entries consist of a single bit, but dual link has the - * next most significant bit set too - */ - entry->duallink_possible = - ((1 << (ffs(entry->or) - 1)) * 3 == entry->or); switch (entry->type) { case OUTPUT_ANALOG: @@ -5622,6 +5639,16 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb, break; } + if (dcb->version < 0x40) { + /* Normal entries consist of a single bit, but dual link has + * the next most significant bit set too + */ + entry->duallink_possible = + ((1 << (ffs(entry->or) - 1)) * 3 == entry->or); + } else { + entry->duallink_possible = (entry->sorconf.link == 3); + } + /* unsure what DCB version introduces this, 3.0? */ if (conf & 0x100000) entry->i2c_upper_default = true; @@ -6205,6 +6232,30 @@ nouveau_bios_i2c_devices_takedown(struct drm_device *dev) nouveau_i2c_fini(dev, entry); } +static bool +nouveau_bios_posted(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + bool was_locked; + unsigned htotal; + + if (dev_priv->chipset >= NV_50) { + if (NVReadVgaCrtc(dev, 0, 0x00) == 0 && + NVReadVgaCrtc(dev, 0, 0x1a) == 0) + return false; + return true; + } + + was_locked = NVLockVgaCrtcs(dev, false); + htotal = NVReadVgaCrtc(dev, 0, 0x06); + htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x01) << 8; + htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x20) << 4; + htotal |= (NVReadVgaCrtc(dev, 0, 0x25) & 0x01) << 10; + htotal |= (NVReadVgaCrtc(dev, 0, 0x41) & 0x01) << 11; + NVLockVgaCrtcs(dev, was_locked); + return (htotal != 0); +} + int nouveau_bios_init(struct drm_device *dev) { @@ -6239,11 +6290,9 @@ nouveau_bios_init(struct drm_device *dev) bios->execute = false; /* ... unless card isn't POSTed already */ - if (dev_priv->card_type >= NV_10 && - NVReadVgaCrtc(dev, 0, 0x00) == 0 && - NVReadVgaCrtc(dev, 0, 0x1a) == 0) { + if (!nouveau_bios_posted(dev)) { NV_INFO(dev, "Adaptor not initialised\n"); - if (dev_priv->card_type < NV_50) { + if (dev_priv->card_type < NV_40) { NV_ERROR(dev, "Unable to POST this chipset\n"); return -ENODEV; } diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 266b0ff441a..149ed224c3c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -432,24 +432,27 @@ nouveau_connector_set_property(struct drm_connector *connector, } static struct drm_display_mode * -nouveau_connector_native_mode(struct nouveau_connector *connector) +nouveau_connector_native_mode(struct drm_connector *connector) { - struct drm_device *dev = connector->base.dev; + struct drm_connector_helper_funcs *helper = connector->helper_private; + struct nouveau_connector *nv_connector = nouveau_connector(connector); + struct drm_device *dev = connector->dev; struct drm_display_mode *mode, *largest = NULL; int high_w = 0, high_h = 0, high_v = 0; - /* Use preferred mode if there is one.. */ - list_for_each_entry(mode, &connector->base.probed_modes, head) { + list_for_each_entry(mode, &nv_connector->base.probed_modes, head) { + if (helper->mode_valid(connector, mode) != MODE_OK) + continue; + + /* Use preferred mode if there is one.. */ if (mode->type & DRM_MODE_TYPE_PREFERRED) { NV_DEBUG_KMS(dev, "native mode from preferred\n"); return drm_mode_duplicate(dev, mode); } - } - /* Otherwise, take the resolution with the largest width, then height, - * then vertical refresh - */ - list_for_each_entry(mode, &connector->base.probed_modes, head) { + /* Otherwise, take the resolution with the largest width, then + * height, then vertical refresh + */ if (mode->hdisplay < high_w) continue; @@ -553,7 +556,7 @@ nouveau_connector_get_modes(struct drm_connector *connector) */ if (!nv_connector->native_mode) nv_connector->native_mode = - nouveau_connector_native_mode(nv_connector); + nouveau_connector_native_mode(connector); if (ret == 0 && nv_connector->native_mode) { struct drm_display_mode *mode; @@ -584,9 +587,9 @@ nouveau_connector_mode_valid(struct drm_connector *connector, switch (nv_encoder->dcb->type) { case OUTPUT_LVDS: - BUG_ON(!nv_connector->native_mode); - if (mode->hdisplay > nv_connector->native_mode->hdisplay || - mode->vdisplay > nv_connector->native_mode->vdisplay) + if (nv_connector->native_mode && + (mode->hdisplay > nv_connector->native_mode->hdisplay || + mode->vdisplay > nv_connector->native_mode->vdisplay)) return MODE_PANEL; min_clock = 0; @@ -594,8 +597,7 @@ nouveau_connector_mode_valid(struct drm_connector *connector, break; case OUTPUT_TMDS: if ((dev_priv->card_type >= NV_50 && !nouveau_duallink) || - (dev_priv->card_type < NV_50 && - !nv_encoder->dcb->duallink_possible)) + !nv_encoder->dcb->duallink_possible) max_clock = 165000; else max_clock = 330000; @@ -729,7 +731,7 @@ nouveau_connector_create_lvds(struct drm_device *dev, if (ret == 0) goto out; nv_connector->detected_encoder = nv_encoder; - nv_connector->native_mode = nouveau_connector_native_mode(nv_connector); + nv_connector->native_mode = nouveau_connector_native_mode(connector); list_for_each_entry_safe(mode, temp, &connector->probed_modes, head) drm_mode_remove(connector, mode); diff --git a/drivers/gpu/drm/nouveau/nouveau_crtc.h b/drivers/gpu/drm/nouveau/nouveau_crtc.h index 49fa7b2d257..cb1ce2a0916 100644 --- a/drivers/gpu/drm/nouveau/nouveau_crtc.h +++ b/drivers/gpu/drm/nouveau/nouveau_crtc.h @@ -40,6 +40,8 @@ struct nouveau_crtc { int sharpness; int last_dpms; + int cursor_saved_x, cursor_saved_y; + struct { int cpp; bool blanked; diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index c6079e36669..27377043229 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -175,6 +175,13 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state) nouveau_bo_unpin(nouveau_fb->nvbo); } + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); + + nouveau_bo_unmap(nv_crtc->cursor.nvbo); + nouveau_bo_unpin(nv_crtc->cursor.nvbo); + } + NV_INFO(dev, "Evicting buffers...\n"); ttm_bo_evict_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); @@ -314,12 +321,34 @@ nouveau_pci_resume(struct pci_dev *pdev) nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM); } + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); + int ret; + + ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM); + if (!ret) + ret = nouveau_bo_map(nv_crtc->cursor.nvbo); + if (ret) + NV_ERROR(dev, "Could not pin/map cursor.\n"); + } + if (dev_priv->card_type < NV_50) { nv04_display_restore(dev); NVLockVgaCrtcs(dev, false); } else nv50_display_init(dev); + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); + + nv_crtc->cursor.set_offset(nv_crtc, + nv_crtc->cursor.nvbo->bo.offset - + dev_priv->vm_vram_base); + + nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x, + nv_crtc->cursor_saved_y); + } + /* Force CLUT to get re-loaded during modeset */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 5b134438eff..c6971910648 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -851,12 +851,17 @@ extern int nouveau_dma_init(struct nouveau_channel *); extern int nouveau_dma_wait(struct nouveau_channel *, int slots, int size); /* nouveau_acpi.c */ +#define ROM_BIOS_PAGE 4096 #if defined(CONFIG_ACPI) void nouveau_register_dsm_handler(void); void nouveau_unregister_dsm_handler(void); +int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len); +bool nouveau_acpi_rom_supported(struct pci_dev *pdev); #else static inline void nouveau_register_dsm_handler(void) {} static inline void nouveau_unregister_dsm_handler(void) {} +static inline bool nouveau_acpi_rom_supported(struct pci_dev *pdev) { return false; } +static inline int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) { return -EINVAL; } #endif /* nouveau_backlight.c */ diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 775a7017af6..c1fd42b0dad 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -540,7 +540,8 @@ nouveau_mem_detect(struct drm_device *dev) dev_priv->vram_size = nv_rd32(dev, NV04_FIFO_DATA); dev_priv->vram_size &= NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK; if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) - dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10) << 12; + dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10); + dev_priv->vram_sys_base <<= 12; } NV_INFO(dev, "Detected %dMiB VRAM\n", (int)(dev_priv->vram_size >> 20)); diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index e632339c323..147e59c4015 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -376,12 +376,15 @@ out_err: static void nouveau_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state) { + struct drm_device *dev = pci_get_drvdata(pdev); pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; if (state == VGA_SWITCHEROO_ON) { printk(KERN_ERR "VGA switcheroo: switched nouveau on\n"); nouveau_pci_resume(pdev); + drm_kms_helper_poll_enable(dev); } else { printk(KERN_ERR "VGA switcheroo: switched nouveau off\n"); + drm_kms_helper_poll_disable(dev); nouveau_pci_suspend(pdev, pmm); } } @@ -913,6 +916,9 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data, case NOUVEAU_GETPARAM_VM_VRAM_BASE: getparam->value = dev_priv->vm_vram_base; break; + case NOUVEAU_GETPARAM_PTIMER_TIME: |