]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge remote branch 'nouveau/for-airlied' of ../drm-nouveau-next into drm-testing
authorDave Airlie <airlied@redhat.com>
Tue, 1 Jun 2010 01:32:29 +0000 (11:32 +1000)
committerDave Airlie <airlied@redhat.com>
Tue, 1 Jun 2010 01:32:29 +0000 (11:32 +1000)
* 'nouveau/for-airlied' of ../drm-nouveau-next:
  drm/nv50: cast IGP memory location to u64 before shifting
  drm/nv50: use alternate source of SOR_MODE_CTRL for DP hack
  drm/nouveau: fix dual-link displays when plugged into single-link outputs
  drm/nv50: obey dcb->duallink_possible
  drm/nv50: fix duallink_possible calculation for DCB 4.0 cards
  drm/nouveau: don't execute INIT_GPIO unless we're really running the table
  drm/nv40: allow cold-booting of nv4x chipsets
  drm/nouveau: fix POST detection for certain chipsets
  drm/nouveau: Add getparam for current PTIMER time.
  drm/nouveau: allow cursor image and position to survive suspend

1  2 
drivers/gpu/drm/nouveau/nouveau_bios.c
drivers/gpu/drm/nouveau/nouveau_connector.c
drivers/gpu/drm/nouveau/nouveau_state.c

index 745ff3788e9d96a8b170a7ae8a8c6ff468bbc130,9f30fb8eafe8a576c1d625fb05551ea2fda4321a..9ba2deaadcc7d38b833ff63fc99f4b76cc144ac1
@@@ -178,25 -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 *);
@@@ -210,7 -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 },
@@@ -2827,7 -2807,10 +2827,10 @@@ init_gpio(struct nvbios *bios, uint16_
  
                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.
@@@ -5553,12 -5536,6 +5556,6 @@@ parse_dcb20_entry(struct drm_device *de
        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:
                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;
@@@ -6225,6 -6212,30 +6232,30 @@@ nouveau_bios_i2c_devices_takedown(struc
                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)
  {
        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;
                }
index 266b0ff441af37b75ee555360bdcd68ce1cd881f,256e82bd91dd616e83be300e58b45f2068745f9f..149ed224c3cb48c86c56e2f4b9bb18a599190d10
@@@ -241,8 -241,7 +241,8 @@@ nouveau_connector_detect(struct drm_con
        if (nv_encoder && nv_connector->native_mode) {
                unsigned status = connector_status_connected;
  
 -#ifdef CONFIG_ACPI
 +#if defined(CONFIG_ACPI_BUTTON) || \
 +      (defined(CONFIG_ACPI_BUTTON_MODULE) && defined(MODULE))
                if (!nouveau_ignorelid && !acpi_lid_open())
                        status = connector_status_unknown;
  #endif
@@@ -432,24 -431,27 +432,27 @@@ nouveau_connector_set_property(struct d
  }
  
  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 -555,7 +556,7 @@@ nouveau_connector_get_modes(struct drm_
         */
        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 -586,9 +587,9 @@@ nouveau_connector_mode_valid(struct drm
  
        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;
                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 -730,7 +731,7 @@@ nouveau_connector_create_lvds(struct dr
        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);
  
index 5c468a4fef9a43a5408d5310a6b3af592bccb1bf,a2544ffd02cc8ecedea168563e166876dce9bf0f..147e59c4015148e4b645648346b2e959370d3dcf
@@@ -376,15 -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);
        }
  }
@@@ -916,6 -913,9 +916,9 @@@ int nouveau_ioctl_getparam(struct drm_d
        case NOUVEAU_GETPARAM_VM_VRAM_BASE:
                getparam->value = dev_priv->vm_vram_base;
                break;
+       case NOUVEAU_GETPARAM_PTIMER_TIME:
+               getparam->value = dev_priv->engine.timer.read(dev);
+               break;
        case NOUVEAU_GETPARAM_GRAPH_UNITS:
                /* NV40 and NV50 versions are quite different, but register
                 * address is the same. User is supposed to know the card