Merge remote branch 'nouveau/for-airlied' into drm-linus
authorDave Airlie <airlied@redhat.com>
Mon, 15 Mar 2010 01:07:33 +0000 (11:07 +1000)
committerDave Airlie <airlied@redhat.com>
Mon, 15 Mar 2010 01:07:33 +0000 (11:07 +1000)
* nouveau/for-airlied:
  drm/nouveau: add module option to disable TV detection
  drm/nouveau: Never evict VRAM buffers to system.
  drm/nv50: fix connector table parsing for some cards
  drm/nv50: add a memory barrier to pushbuf submission
  drm/nouveau: print a message very early during suspend
  drm/nv04-nv40: Fix up the programmed horizontal sync pulse delay.
  drm/nouveau: Gigabyte NX85T connector table lies, it has DVI-I not HDMI
  drm/nouveau: add option to allow override of dcb connector table types
  drm/nv50: Improve PGRAPH interrupt handling.
  drm/nv50: Make ctxprog wait until interrupt handler is done.
  drm/nouveau: Fix fbcon corruption with font width not divisible by 8
  drm/nv50: Remove redundant/incorrect ctxvals initialisation.

1  2 
drivers/gpu/drm/nouveau/nouveau_drv.c
drivers/gpu/drm/nouveau/nouveau_drv.h
drivers/gpu/drm/nouveau/nouveau_state.c
drivers/gpu/drm/nouveau/nv04_crtc.c

@@@ -83,6 -83,14 +83,14 @@@ MODULE_PARM_DESC(nofbaccel, "Disable fb
  int nouveau_nofbaccel = 0;
  module_param_named(nofbaccel, nouveau_nofbaccel, int, 0400);
  
+ MODULE_PARM_DESC(override_conntype, "Ignore DCB connector type");
+ int nouveau_override_conntype = 0;
+ module_param_named(override_conntype, nouveau_override_conntype, int, 0400);
+ MODULE_PARM_DESC(tv_disable, "Disable TV-out detection\n");
+ int nouveau_tv_disable = 0;
+ module_param_named(tv_disable, nouveau_tv_disable, int, 0400);
  MODULE_PARM_DESC(tv_norm, "Default TV norm.\n"
                 "\t\tSupported: PAL, PAL-M, PAL-N, PAL-Nc, NTSC-M, NTSC-J,\n"
                 "\t\t\thd480i, hd480p, hd576i, hd576p, hd720p, hd1080i.\n"
@@@ -135,7 -143,7 +143,7 @@@ nouveau_pci_remove(struct pci_dev *pdev
        drm_put_dev(dev);
  }
  
 -static int
 +int
  nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
  {
        struct drm_device *dev = pci_get_drvdata(pdev);
        if (pm_state.event == PM_EVENT_PRETHAW)
                return 0;
  
+       NV_INFO(dev, "Disabling fbcon acceleration...\n");
        fbdev_flags = dev_priv->fbdev_info->flags;
        dev_priv->fbdev_info->flags |= FBINFO_HWACCEL_DISABLED;
  
+       NV_INFO(dev, "Unpinning framebuffer(s)...\n");
        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
                struct nouveau_framebuffer *nouveau_fb;
  
@@@ -233,7 -243,7 +243,7 @@@ out_abort
        return ret;
  }
  
 -static int
 +int
  nouveau_pci_resume(struct pci_dev *pdev)
  {
        struct drm_device *dev = pci_get_drvdata(pdev);
@@@ -402,10 -412,8 +412,10 @@@ static int __init nouveau_init(void
                        nouveau_modeset = 1;
        }
  
 -      if (nouveau_modeset == 1)
 +      if (nouveau_modeset == 1) {
                driver.driver_features |= DRIVER_MODESET;
 +              nouveau_register_dsm_handler();
 +      }
  
        return drm_init(&driver);
  }
  static void __exit nouveau_exit(void)
  {
        drm_exit(&driver);
 +      nouveau_unregister_dsm_handler();
  }
  
  module_init(nouveau_init);
@@@ -622,6 -622,7 +622,6 @@@ struct drm_nouveau_private 
        } susres;
  
        struct backlight_device *backlight;
 -      bool acpi_dsm;
  
        struct nouveau_channel *evo;
  
@@@ -681,6 -682,7 +681,7 @@@ extern int nouveau_uscript_tmds
  extern int nouveau_vram_pushbuf;
  extern int nouveau_vram_notify;
  extern int nouveau_fbpercrtc;
+ extern int nouveau_tv_disable;
  extern char *nouveau_tv_norm;
  extern int nouveau_reg_debug;
  extern char *nouveau_vbios;
@@@ -688,10 -690,8 +689,11 @@@ extern int nouveau_ctxfw
  extern int nouveau_ignorelid;
  extern int nouveau_nofbaccel;
  extern int nouveau_noaccel;
+ extern int nouveau_override_conntype;
  
 +extern int nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state);
 +extern int nouveau_pci_resume(struct pci_dev *pdev);
 +
  /* nouveau_state.c */
  extern void nouveau_preclose(struct drm_device *dev, struct drm_file *);
  extern int  nouveau_load(struct drm_device *, unsigned long flags);
@@@ -852,12 -852,18 +854,12 @@@ extern int  nouveau_dma_init(struct nou
  extern int  nouveau_dma_wait(struct nouveau_channel *, int slots, int size);
  
  /* nouveau_acpi.c */
 -#ifdef CONFIG_ACPI
 -extern int nouveau_hybrid_setup(struct drm_device *dev);
 -extern bool nouveau_dsm_probe(struct drm_device *dev);
 +#if defined(CONFIG_ACPI)
 +void nouveau_register_dsm_handler(void);
 +void nouveau_unregister_dsm_handler(void);
  #else
 -static inline int nouveau_hybrid_setup(struct drm_device *dev)
 -{
 -      return 0;
 -}
 -static inline bool nouveau_dsm_probe(struct drm_device *dev)
 -{
 -      return false;
 -}
 +static inline void nouveau_register_dsm_handler(void) {}
 +static inline void nouveau_unregister_dsm_handler(void) {}
  #endif
  
  /* nouveau_backlight.c */
@@@ -926,6 -932,10 +928,10 @@@ extern void nv40_fb_takedown(struct drm
  extern void nv40_fb_set_region_tiling(struct drm_device *, int, uint32_t,
                                      uint32_t, uint32_t);
  
+ /* nv50_fb.c */
+ extern int  nv50_fb_init(struct drm_device *);
+ extern void nv50_fb_takedown(struct drm_device *);
  /* nv04_fifo.c */
  extern int  nv04_fifo_init(struct drm_device *);
  extern void nv04_fifo_disable(struct drm_device *);
  #include "drm_sarea.h"
  #include "drm_crtc_helper.h"
  #include <linux/vgaarb.h>
 +#include <linux/vga_switcheroo.h>
  
  #include "nouveau_drv.h"
  #include "nouveau_drm.h"
  #include "nv50_display.h"
  
- static int nouveau_stub_init(struct drm_device *dev) { return 0; }
  static void nouveau_stub_takedown(struct drm_device *dev) {}
  
  static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->timer.init              = nv04_timer_init;
                engine->timer.read              = nv04_timer_read;
                engine->timer.takedown          = nv04_timer_takedown;
-               engine->fb.init                 = nouveau_stub_init;
-               engine->fb.takedown             = nouveau_stub_takedown;
+               engine->fb.init                 = nv50_fb_init;
+               engine->fb.takedown             = nv50_fb_takedown;
                engine->graph.grclass           = nv50_graph_grclass;
                engine->graph.init              = nv50_graph_init;
                engine->graph.takedown          = nv50_graph_takedown;
@@@ -372,30 -370,6 +371,30 @@@ out_err
        return ret;
  }
  
 +static void nouveau_switcheroo_set_state(struct pci_dev *pdev,
 +                                       enum vga_switcheroo_state state)
 +{
 +      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);
 +      } else {
 +              printk(KERN_ERR "VGA switcheroo: switched nouveau off\n");
 +              nouveau_pci_suspend(pdev, pmm);
 +      }
 +}
 +
 +static bool nouveau_switcheroo_can_switch(struct pci_dev *pdev)
 +{
 +      struct drm_device *dev = pci_get_drvdata(pdev);
 +      bool can_switch;
 +
 +      spin_lock(&dev->count_lock);
 +      can_switch = (dev->open_count == 0);
 +      spin_unlock(&dev->count_lock);
 +      return can_switch;
 +}
 +
  int
  nouveau_card_init(struct drm_device *dev)
  {
                return 0;
  
        vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode);
 +      vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state,
 +                                     nouveau_switcheroo_can_switch);
  
        /* Initialise internal driver API hooks */
        ret = nouveau_init_engine_ptrs(dev);
@@@ -645,6 -617,11 +644,6 @@@ int nouveau_load(struct drm_device *dev
        NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n",
                 dev->pci_vendor, dev->pci_device, dev->pdev->class);
  
 -      dev_priv->acpi_dsm = nouveau_dsm_probe(dev);
 -
 -      if (dev_priv->acpi_dsm)
 -              nouveau_hybrid_setup(dev);
 -
        dev_priv->wq = create_workqueue("nouveau");
        if (!dev_priv->wq)
                return -EINVAL;
@@@ -230,9 -230,9 +230,9 @@@ nv_crtc_mode_set_vga(struct drm_crtc *c
        struct drm_framebuffer *fb = crtc->fb;
  
        /* Calculate our timings */
-       int horizDisplay        = (mode->crtc_hdisplay >> 3)    - 1;
-       int horizStart          = (mode->crtc_hsync_start >> 3)         - 1;
-       int horizEnd            = (mode->crtc_hsync_end >> 3)   - 1;
+       int horizDisplay        = (mode->crtc_hdisplay >> 3)            - 1;
+       int horizStart          = (mode->crtc_hsync_start >> 3)         + 1;
+       int horizEnd            = (mode->crtc_hsync_end >> 3)           + 1;
        int horizTotal          = (mode->crtc_htotal >> 3)              - 5;
        int horizBlankStart     = (mode->crtc_hdisplay >> 3)            - 1;
        int horizBlankEnd       = (mode->crtc_htotal >> 3)              - 1;
@@@ -926,7 -926,9 +926,7 @@@ nv04_crtc_cursor_set(struct drm_crtc *c
        nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.offset);
        nv_crtc->cursor.show(nv_crtc, true);
  out:
 -      mutex_lock(&dev->struct_mutex);
 -      drm_gem_object_unreference(gem);
 -      mutex_unlock(&dev->struct_mutex);
 +      drm_gem_object_unreference_unlocked(gem);
        return ret;
  }