]> bbs.cooldavid.org Git - net-next-2.6.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

drivers/gpu/drm/nouveau/nouveau_bios.c
drivers/gpu/drm/nouveau/nouveau_connector.c
drivers/gpu/drm/nouveau/nouveau_crtc.h
drivers/gpu/drm/nouveau/nouveau_drv.c
drivers/gpu/drm/nouveau/nouveau_mem.c
drivers/gpu/drm/nouveau/nouveau_state.c
drivers/gpu/drm/nouveau/nv04_cursor.c
drivers/gpu/drm/nouveau/nv50_cursor.c
drivers/gpu/drm/nouveau/nv50_sor.c
include/drm/nouveau_drm.h

index 745ff3788e9d96a8b170a7ae8a8c6ff468bbc130..9ba2deaadcc7d38b833ff63fc99f4b76cc144ac1 100644 (file)
@@ -2827,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.
@@ -5553,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:
@@ -5642,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;
@@ -6225,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)
 {
@@ -6259,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;
                }
index 266b0ff441af37b75ee555360bdcd68ce1cd881f..149ed224c3cb48c86c56e2f4b9bb18a599190d10 100644 (file)
@@ -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);
 
index 49fa7b2d257e8e739391720ffaf66e8eea86ee45..cb1ce2a0916257ecbbe8ea72949baa8a80b32c56 100644 (file)
@@ -40,6 +40,8 @@ struct nouveau_crtc {
        int sharpness;
        int last_dpms;
 
+       int cursor_saved_x, cursor_saved_y;
+
        struct {
                int cpp;
                bool blanked;
index c6079e36669d9f43893db8ad88623dbb70b6147c..273770432298b72ae5687505e156fe5b03e0e4e4 100644 (file)
@@ -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);
index 775a7017af6437da7c149dfda2a04d172704fdb2..c1fd42b0dad19cb18e34463548c8ff4b60093747 100644 (file)
@@ -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));
index 5c468a4fef9a43a5408d5310a6b3af592bccb1bf..147e59c4015148e4b645648346b2e959370d3dcf 100644 (file)
@@ -916,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:
+               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
index 89a91b9d8b258d54e24c2b3725727824c7a18df0..aaf3de3bc816c5e0d9e1d34fcd4847fa2fa3e5db 100644 (file)
@@ -20,6 +20,7 @@ nv04_cursor_hide(struct nouveau_crtc *nv_crtc, bool update)
 static void
 nv04_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y)
 {
+       nv_crtc->cursor_saved_x = x; nv_crtc->cursor_saved_y = y;
        NVWriteRAMDAC(nv_crtc->base.dev, nv_crtc->index,
                      NV_PRAMDAC_CU_START_POS,
                      XLATE(y, 0, NV_PRAMDAC_CU_START_POS_Y) |
index 753e723adb3afb9e0dc733d4ef416a4468b3aacc..03ad7ab14f0960e1729674cd637a15ff325ae169 100644 (file)
@@ -107,6 +107,7 @@ nv50_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y)
 {
        struct drm_device *dev = nv_crtc->base.dev;
 
+       nv_crtc->cursor_saved_x = x; nv_crtc->cursor_saved_y = y;
        nv_wr32(dev, NV50_PDISPLAY_CURSOR_USER_POS(nv_crtc->index),
                ((y & 0xFFFF) << 16) | (x & 0xFFFF));
        /* Needed to make the cursor move. */
index b11eaf9c5c7cd0575eec63e20d7217b7c8fd49c1..812778db76ac185b5943a8257ae401ff82f27202 100644 (file)
@@ -274,7 +274,6 @@ static const struct drm_encoder_funcs nv50_sor_encoder_funcs = {
 int
 nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_encoder *nv_encoder = NULL;
        struct drm_encoder *encoder;
        bool dum;
@@ -324,11 +323,7 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
                int or = nv_encoder->or, link = !(entry->dpconf.sor.link & 1);
                uint32_t tmp;
 
-               if (dev_priv->chipset < 0x90 ||
-                   dev_priv->chipset == 0x92 || dev_priv->chipset == 0xa0)
-                       tmp = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_C(or));
-               else
-                       tmp = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_C(or));
+               tmp = nv_rd32(dev, 0x61c700 + (or * 0x800));
 
                switch ((tmp & 0x00000f00) >> 8) {
                case 8:
index a6a9f4af5ebd8257d92dcd592551b6fb05f91931..fe917dee723a7357f44c285626189ae7acd5e863 100644 (file)
@@ -79,6 +79,7 @@ struct drm_nouveau_gpuobj_free {
 #define NOUVEAU_GETPARAM_CHIPSET_ID      11
 #define NOUVEAU_GETPARAM_VM_VRAM_BASE    12
 #define NOUVEAU_GETPARAM_GRAPH_UNITS     13
+#define NOUVEAU_GETPARAM_PTIMER_TIME     14
 struct drm_nouveau_getparam {
        uint64_t param;
        uint64_t value;