Merge tag 'v2.6.35-rc6' into drm-radeon-next
authorDave Airlie <airlied@redhat.com>
Mon, 2 Aug 2010 00:05:18 +0000 (10:05 +1000)
committerDave Airlie <airlied@redhat.com>
Mon, 2 Aug 2010 00:05:24 +0000 (10:05 +1000)
Need this to avoid conflicts with future radeon fixes

78 files changed:
drivers/gpu/drm/Kconfig
drivers/gpu/drm/Makefile
drivers/gpu/drm/drm_bufs.c
drivers/gpu/drm/drm_crtc.c
drivers/gpu/drm/drm_crtc_helper.c
drivers/gpu/drm/drm_drv.c
drivers/gpu/drm/drm_edid.c
drivers/gpu/drm/drm_gem.c
drivers/gpu/drm/drm_info.c
drivers/gpu/drm/drm_ioctl.c
drivers/gpu/drm/drm_irq.c
drivers/gpu/drm/drm_mm.c
drivers/gpu/drm/drm_pci.c
drivers/gpu/drm/drm_platform.c [new file with mode: 0644]
drivers/gpu/drm/drm_stub.c
drivers/gpu/drm/drm_sysfs.c
drivers/gpu/drm/drm_trace.h [new file with mode: 0644]
drivers/gpu/drm/drm_trace_points.c [new file with mode: 0644]
drivers/gpu/drm/drm_vm.c
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_trace.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/mga/mga_dma.c
drivers/gpu/drm/nouveau/Kconfig
drivers/gpu/drm/nouveau/nouveau_bo.c
drivers/gpu/drm/nouveau/nouveau_channel.c
drivers/gpu/drm/nouveau/nouveau_drv.c
drivers/gpu/drm/nouveau/nouveau_mem.c
drivers/gpu/drm/nouveau/nv20_graph.c
drivers/gpu/drm/nouveau/nv40_graph.c
drivers/gpu/drm/nouveau/nv50_instmem.c
drivers/gpu/drm/radeon/Makefile
drivers/gpu/drm/radeon/atom.c
drivers/gpu/drm/radeon/atom.h
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/evergreen_reg.h
drivers/gpu/drm/radeon/evergreend.h
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r300.c
drivers/gpu/drm/radeon/r420.c
drivers/gpu/drm/radeon/r500_reg.h
drivers/gpu/drm/radeon/r520.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600_audio.c
drivers/gpu/drm/radeon/r600_cs.c
drivers/gpu/drm/radeon/r600_hdmi.c
drivers/gpu/drm/radeon/r600d.h
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_acpi.c [new file with mode: 0644]
drivers/gpu/drm/radeon/radeon_asic.h
drivers/gpu/drm/radeon/radeon_atombios.c
drivers/gpu/drm/radeon/radeon_bios.c
drivers/gpu/drm/radeon/radeon_combios.c
drivers/gpu/drm/radeon/radeon_cp.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/radeon/radeon_drv.c
drivers/gpu/drm/radeon/radeon_kms.c
drivers/gpu/drm/radeon/radeon_object.c
drivers/gpu/drm/radeon/radeon_pm.c
drivers/gpu/drm/radeon/rs400.c
drivers/gpu/drm/radeon/rs600.c
drivers/gpu/drm/radeon/rs690.c
drivers/gpu/drm/radeon/rv515.c
drivers/gpu/drm/radeon/rv770.c
drivers/gpu/drm/radeon/rv770d.h
drivers/gpu/drm/savage/savage_bci.c
drivers/gpu/drm/ttm/ttm_bo.c
drivers/gpu/drm/ttm/ttm_bo_util.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
include/drm/drmP.h
include/drm/drm_crtc_helper.h
include/drm/drm_mm.h
include/drm/drm_mode.h
include/drm/radeon_drm.h

index 88910e5a2c77275654e8b431d96a93b07e438685..4cab0c6397e34654086f57433e1de471d1d87b30 100644 (file)
@@ -6,7 +6,7 @@
 #
 menuconfig DRM
        tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
-       depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG && MMU
+       depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU
        select I2C
        select I2C_ALGOBIT
        select SLOW_WORK
@@ -17,7 +17,7 @@ menuconfig DRM
          These modules provide support for synchronization, security, and
          DMA transfers. Please see <http://dri.sourceforge.net/> for more
          details.  You should also select and configure AGP
-         (/dev/agpgart) support.
+         (/dev/agpgart) support if it is available for your platform.
 
 config DRM_KMS_HELPER
        tristate
@@ -61,6 +61,7 @@ config DRM_RADEON
         select DRM_KMS_HELPER
         select DRM_TTM
        select POWER_SUPPLY
+       select HWMON
        help
          Choose this option if you have an ATI Radeon graphics card.  There
          are both PCI and AGP versions.  You don't need to choose this to
@@ -130,7 +131,7 @@ endchoice
 
 config DRM_MGA
        tristate "Matrox g200/g400"
-       depends on DRM
+       depends on DRM && PCI
        select FW_LOADER
        help
          Choose this option if you have a Matrox G200, G400 or G450 graphics
@@ -148,14 +149,14 @@ config DRM_SIS
 
 config DRM_VIA
        tristate "Via unichrome video cards"
-       depends on DRM
+       depends on DRM && PCI
        help
          Choose this option if you have a Via unichrome or compatible video
          chipset. If M is selected the module will be called via.
 
 config DRM_SAVAGE
        tristate "Savage video cards"
-       depends on DRM
+       depends on DRM && PCI
        help
          Choose this option if you have a Savage3D/4/SuperSavage/Pro/Twister
          chipset. If M is selected the module will be called savage.
index abe3f446ca48efe06d7896d00b4c347a2e6daead..df8f923228656c095f7c57d770aa8b0e7af2abc0 100644 (file)
@@ -9,9 +9,10 @@ drm-y       := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \
                drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \
                drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
                drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
-               drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \
+               drm_platform.o drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \
                drm_crtc.o drm_modes.o drm_edid.o \
-               drm_info.o drm_debugfs.o drm_encoder_slave.o
+               drm_info.o drm_debugfs.o drm_encoder_slave.o \
+               drm_trace_points.o
 
 drm-$(CONFIG_COMPAT) += drm_ioc32.o
 
@@ -19,6 +20,8 @@ drm_kms_helper-y := drm_fb_helper.o drm_crtc_helper.o drm_dp_i2c_helper.o
 
 obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
 
+CFLAGS_drm_trace_points.o := -I$(src)
+
 obj-$(CONFIG_DRM)      += drm.o
 obj-$(CONFIG_DRM_TTM)  += ttm/
 obj-$(CONFIG_DRM_TDFX) += tdfx/
index 2092e7bb788f90302ff226c69a383c1a6a5aea67..a5c9ce93bbcba1cf4d7390cfa3f7fe1c1e504078 100644 (file)
 #include <asm/shmparam.h>
 #include "drmP.h"
 
-resource_size_t drm_get_resource_start(struct drm_device *dev, unsigned int resource)
-{
-       return pci_resource_start(dev->pdev, resource);
-}
-EXPORT_SYMBOL(drm_get_resource_start);
-
-resource_size_t drm_get_resource_len(struct drm_device *dev, unsigned int resource)
-{
-       return pci_resource_len(dev->pdev, resource);
-}
-
-EXPORT_SYMBOL(drm_get_resource_len);
-
 static struct drm_map_list *drm_find_matching_map(struct drm_device *dev,
                                                  struct drm_local_map *map)
 {
@@ -189,7 +176,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset,
        switch (map->type) {
        case _DRM_REGISTERS:
        case _DRM_FRAME_BUFFER:
-#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__)
+#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__) && !defined(__arm__)
                if (map->offset + (map->size-1) < map->offset ||
                    map->offset < virt_to_phys(high_memory)) {
                        kfree(map);
index 57cea01c4ffb25cb62b7b46007853c506a5c15a3..4c68f76993d8eee831717b7939ccd8af1c59d76b 100644 (file)
@@ -80,6 +80,7 @@ static struct drm_prop_enum_list drm_dithering_mode_enum_list[] =
 {
        { DRM_MODE_DITHERING_OFF, "Off" },
        { DRM_MODE_DITHERING_ON, "On" },
+       { DRM_MODE_DITHERING_AUTO, "Automatic" },
 };
 
 /*
@@ -1126,7 +1127,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
                if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
                        list_for_each_entry(crtc, &dev->mode_config.crtc_list,
                                            head) {
-                               DRM_DEBUG_KMS("CRTC ID is %d\n", crtc->base.id);
+                               DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
                                if (put_user(crtc->base.id, crtc_id + copied)) {
                                        ret = -EFAULT;
                                        goto out;
@@ -1154,8 +1155,8 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
                        list_for_each_entry(encoder,
                                            &dev->mode_config.encoder_list,
                                            head) {
-                               DRM_DEBUG_KMS("ENCODER ID is %d\n",
-                                         encoder->base.id);
+                               DRM_DEBUG_KMS("[ENCODER:%d:%s]\n", encoder->base.id,
+                                               drm_get_encoder_name(encoder));
                                if (put_user(encoder->base.id, encoder_id +
                                             copied)) {
                                        ret = -EFAULT;
@@ -1185,8 +1186,9 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
                        list_for_each_entry(connector,
                                            &dev->mode_config.connector_list,
                                            head) {
-                               DRM_DEBUG_KMS("CONNECTOR ID is %d\n",
-                                         connector->base.id);
+                               DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
+                                       connector->base.id,
+                                       drm_get_connector_name(connector));
                                if (put_user(connector->base.id,
                                             connector_id + copied)) {
                                        ret = -EFAULT;
@@ -1209,7 +1211,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
        }
        card_res->count_connectors = connector_count;
 
-       DRM_DEBUG_KMS("Counted %d %d %d\n", card_res->count_crtcs,
+       DRM_DEBUG_KMS("CRTC[%d] CONNECTORS[%d] ENCODERS[%d]\n", card_res->count_crtcs,
                  card_res->count_connectors, card_res->count_encoders);
 
 out:
@@ -1312,7 +1314,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
 
        memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
 
-       DRM_DEBUG_KMS("connector id %d:\n", out_resp->connector_id);
+       DRM_DEBUG_KMS("[CONNECTOR:%d:?]\n", out_resp->connector_id);
 
        mutex_lock(&dev->mode_config.mutex);
 
@@ -1493,6 +1495,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
                goto out;
        }
        crtc = obj_to_crtc(obj);
+       DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
 
        if (crtc_req->mode_valid) {
                /* If we have a mode we need a framebuffer. */
@@ -1569,6 +1572,9 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
                                goto out;
                        }
                        connector = obj_to_connector(obj);
+                       DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
+                                       connector->base.id,
+                                       drm_get_connector_name(connector));
 
                        connector_set[i] = connector;
                }
@@ -1684,6 +1690,7 @@ int drm_mode_addfb(struct drm_device *dev,
 
        r->fb_id = fb->base.id;
        list_add(&fb->filp_head, &file_priv->fbs);
+       DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
 
 out:
        mutex_unlock(&dev->mode_config.mutex);
@@ -2610,6 +2617,15 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
                goto out;
        crtc = obj_to_crtc(obj);
 
+       if (crtc->fb == NULL) {
+               /* The framebuffer is currently unbound, presumably
+                * due to a hotplug event, that userspace has not
+                * yet discovered.
+                */
+               ret = -EBUSY;
+               goto out;
+       }
+
        if (crtc->funcs->page_flip == NULL)
                goto out;
 
index 9b2a54117c91c0a306c41c7eb437b641bbd58b31..11fe9c870d17f5ce07e06786878f99cf40c50307 100644 (file)
@@ -86,7 +86,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
        int count = 0;
        int mode_flags = 0;
 
-       DRM_DEBUG_KMS("%s\n", drm_get_connector_name(connector));
+       DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
+                       drm_get_connector_name(connector));
        /* set all modes to the unverified state */
        list_for_each_entry_safe(mode, t, &connector->modes, head)
                mode->status = MODE_UNVERIFIED;
@@ -102,8 +103,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
                connector->status = connector->funcs->detect(connector);
 
        if (connector->status == connector_status_disconnected) {
-               DRM_DEBUG_KMS("%s is disconnected\n",
-                         drm_get_connector_name(connector));
+               DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
+                       connector->base.id, drm_get_connector_name(connector));
                drm_mode_connector_update_edid_property(connector, NULL);
                goto prune;
        }
@@ -141,8 +142,8 @@ prune:
 
        drm_mode_sort(&connector->modes);
 
-       DRM_DEBUG_KMS("Probed modes for %s\n",
-                               drm_get_connector_name(connector));
+       DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id,
+                       drm_get_connector_name(connector));
        list_for_each_entry_safe(mode, t, &connector->modes, head) {
                mode->vrefresh = drm_mode_vrefresh(mode);
 
@@ -201,6 +202,17 @@ bool drm_helper_crtc_in_use(struct drm_crtc *crtc)
 }
 EXPORT_SYMBOL(drm_helper_crtc_in_use);
 
+static void
+drm_encoder_disable(struct drm_encoder *encoder)
+{
+       struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
+
+       if (encoder_funcs->disable)
+               (*encoder_funcs->disable)(encoder);
+       else
+               (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
+}
+
 /**
  * drm_helper_disable_unused_functions - disable unused objects
  * @dev: DRM device
@@ -215,7 +227,6 @@ void drm_helper_disable_unused_functions(struct drm_device *dev)
 {
        struct drm_encoder *encoder;
        struct drm_connector *connector;
-       struct drm_encoder_helper_funcs *encoder_funcs;
        struct drm_crtc *crtc;
 
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
@@ -226,12 +237,8 @@ void drm_helper_disable_unused_functions(struct drm_device *dev)
        }
 
        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-               encoder_funcs = encoder->helper_private;
                if (!drm_helper_encoder_in_use(encoder)) {
-                       if (encoder_funcs->disable)
-                               (*encoder_funcs->disable)(encoder);
-                       else
-                               (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
+                       drm_encoder_disable(encoder);
                        /* disconnector encoder from any connector */
                        encoder->crtc = NULL;
                }
@@ -241,7 +248,10 @@ void drm_helper_disable_unused_functions(struct drm_device *dev)
                struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
                crtc->enabled = drm_helper_crtc_in_use(crtc);
                if (!crtc->enabled) {
-                       crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
+                       if (crtc_funcs->disable)
+                               (*crtc_funcs->disable)(crtc);
+                       else
+                               (*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF);
                        crtc->fb = NULL;
                }
        }
@@ -292,11 +302,11 @@ drm_crtc_prepare_encoders(struct drm_device *dev)
                encoder_funcs = encoder->helper_private;
                /* Disable unused encoders */
                if (encoder->crtc == NULL)
-                       (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
+                       drm_encoder_disable(encoder);
                /* Disable encoders whose CRTC is about to change */
                if (encoder_funcs->get_crtc &&
                    encoder->crtc != (*encoder_funcs->get_crtc)(encoder))
-                       (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
+                       drm_encoder_disable(encoder);
        }
 }
 
@@ -365,6 +375,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
        if (!(ret = crtc_funcs->mode_fixup(crtc, mode, adjusted_mode))) {
                goto done;
        }
+       DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
 
        /* Prepare the encoders and CRTCs before setting the mode. */
        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
@@ -392,8 +403,9 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
                if (encoder->crtc != crtc)
                        continue;
 
-               DRM_DEBUG("%s: set mode %s %x\n", drm_get_encoder_name(encoder),
-                        mode->name, mode->base.id);
+               DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%d:%s]\n",
+                       encoder->base.id, drm_get_encoder_name(encoder),
+                       mode->base.id, mode->name);
                encoder_funcs = encoder->helper_private;
                encoder_funcs->mode_set(encoder, mode, adjusted_mode);
        }
@@ -469,10 +481,15 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 
        crtc_funcs = set->crtc->helper_private;
 
-       DRM_DEBUG_KMS("crtc: %p %d fb: %p connectors: %p num_connectors:"
-                       " %d (x, y) (%i, %i)\n",
-                 set->crtc, set->crtc->base.id, set->fb, set->connectors,
-                 (int)set->num_connectors, set->x, set->y);
+       if (set->fb) {
+               DRM_DEBUG_KMS("[CRTC:%d] [FB:%d] #connectors=%d (x y) (%i %i)\n",
+                               set->crtc->base.id, set->fb->base.id,
+                               (int)set->num_connectors, set->x, set->y);
+       } else {
+               DRM_DEBUG_KMS("[CRTC:%d] [NOFB] #connectors=%d (x y) (%i %i)\n",
+                               set->crtc->base.id, (int)set->num_connectors,
+                               set->x, set->y);
+       }
 
        dev = set->crtc->dev;
 
@@ -601,8 +618,14 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
                        mode_changed = true;
                        connector->encoder->crtc = new_crtc;
                }
-               DRM_DEBUG_KMS("setting connector %d crtc to %p\n",
-                         connector->base.id, new_crtc);
+               if (new_crtc) {
+                       DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n",
+                               connector->base.id, drm_get_connector_name(connector),
+                               new_crtc->base.id);
+               } else {
+                       DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n",
+                               connector->base.id, drm_get_connector_name(connector));
+               }
        }
 
        /* mode_set_base is not a required function */
@@ -620,8 +643,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
                        if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
                                                      set->x, set->y,
                                                      old_fb)) {
-                               DRM_ERROR("failed to set mode on crtc %p\n",
-                                         set->crtc);
+                               DRM_ERROR("failed to set mode on [CRTC:%d]\n",
+                                         set->crtc->base.id);
                                ret = -EINVAL;
                                goto fail;
                        }
index 4a66201edaec0ea89ccc9d791a67f29d2ea58245..510bc87d98f6f991e93e31d74affe90fd9986792 100644 (file)
@@ -243,47 +243,20 @@ int drm_lastclose(struct drm_device * dev)
  *
  * Initializes an array of drm_device structures, and attempts to
  * initialize all available devices, using consecutive minors, registering the
- * stubs and initializing the AGP device.
+ * stubs and initializing the device.
  *
  * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and
  * after the initialization for driver customization.
  */
 int drm_init(struct drm_driver *driver)
 {
-       struct pci_dev *pdev = NULL;
-       const struct pci_device_id *pid;
-       int i;
-
        DRM_DEBUG("\n");
-
        INIT_LIST_HEAD(&driver->device_list);
 
-       if (driver->driver_features & DRIVER_MODESET)
-               return pci_register_driver(&driver->pci_driver);
-
-       /* If not using KMS, fall back to stealth mode manual scanning. */
-       for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) {
-               pid = &driver->pci_driver.id_table[i];
-
-               /* Loop around setting up a DRM device for each PCI device
-                * matching our ID and device class.  If we had the internal
-                * function that pci_get_subsys and pci_get_class used, we'd
-                * be able to just pass pid in instead of doing a two-stage
-                * thing.
-                */
-               pdev = NULL;
-               while ((pdev =
-                       pci_get_subsys(pid->vendor, pid->device, pid->subvendor,
-                                      pid->subdevice, pdev)) != NULL) {
-                       if ((pdev->class & pid->class_mask) != pid->class)
-                               continue;
-
-                       /* stealth mode requires a manual probe */
-                       pci_dev_get(pdev);
-                       drm_get_dev(pdev, pid, driver);
-               }
-       }
-       return 0;
+       if (driver->driver_features & DRIVER_USE_PLATFORM_DEVICE)
+               return drm_platform_init(driver);
+       else
+               return drm_pci_init(driver);
 }
 
 EXPORT_SYMBOL(drm_init);
index c1981861bbbdb418ab58f9c9400e6c41a9430216..83d8072066cb80b809b1eb0f9791b834cd0e7329 100644 (file)
@@ -282,7 +282,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
        return block;
 
 carp:
-       dev_warn(&connector->dev->pdev->dev, "%s: EDID block %d invalid.\n",
+       dev_warn(connector->dev->dev, "%s: EDID block %d invalid.\n",
                 drm_get_connector_name(connector), j);
 
 out:
@@ -1626,7 +1626,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
                return 0;
        }
        if (!drm_edid_is_valid(edid)) {
-               dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n",
+               dev_warn(connector->dev->dev, "%s: EDID invalid.\n",
                         drm_get_connector_name(connector));
                return 0;
        }
index 33dad3fa60439e0b39daca428f8b062ddfca8276..8601b72b6f26694def3cc4329158b9c27f770c7a 100644 (file)
  * We make up offsets for buffer objects so we can recognize them at
  * mmap time.
  */
+
+/* pgoff in mmap is an unsigned long, so we need to make sure that
+ * the faked up offset will fit
+ */
+
+#if BITS_PER_LONG == 64
 #define DRM_FILE_PAGE_OFFSET_START ((0xFFFFFFFFUL >> PAGE_SHIFT) + 1)
 #define DRM_FILE_PAGE_OFFSET_SIZE ((0xFFFFFFFFUL >> PAGE_SHIFT) * 16)
+#else
+#define DRM_FILE_PAGE_OFFSET_START ((0xFFFFFFFUL >> PAGE_SHIFT) + 1)
+#define DRM_FILE_PAGE_OFFSET_SIZE ((0xFFFFFFFUL >> PAGE_SHIFT) * 16)
+#endif
 
 /**
  * Initialize the GEM device fields
index f0f6c6b93f3a235a4a667bcac27a56f5667b4562..2ef2c78272434dcb6b32dc17fd96e34dd7a8d959 100644 (file)
@@ -51,13 +51,24 @@ int drm_name_info(struct seq_file *m, void *data)
        if (!master)
                return 0;
 
-       if (master->unique) {
-               seq_printf(m, "%s %s %s\n",
-                          dev->driver->pci_driver.name,
-                          pci_name(dev->pdev), master->unique);
+       if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE)) {
+               if (master->unique) {
+                       seq_printf(m, "%s %s %s\n",
+                                       dev->driver->platform_device->name,
+                                       dev_name(dev->dev), master->unique);
+               } else {
+                       seq_printf(m, "%s\n",
+                               dev->driver->platform_device->name);
+               }
        } else {
-               seq_printf(m, "%s %s\n", dev->driver->pci_driver.name,
-                          pci_name(dev->pdev));
+               if (master->unique) {
+                       seq_printf(m, "%s %s %s\n",
+                               dev->driver->pci_driver.name,
+                               dev_name(dev->dev), master->unique);
+               } else {
+                       seq_printf(m, "%s %s\n", dev->driver->pci_driver.name,
+                               dev_name(dev->dev));
+               }
        }
 
        return 0;
index 9b9ff46c2378b8601661e8dacbd176f7e40d979d..76d3d18056dd881a7c7f16b40050e4b4f56de359 100644 (file)
@@ -132,32 +132,57 @@ static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv)
        struct drm_master *master = file_priv->master;
        int len;
 
-       if (master->unique != NULL)
-               return -EBUSY;
-
-       master->unique_len = 40;
-       master->unique_size = master->unique_len;
-       master->unique = kmalloc(master->unique_size, GFP_KERNEL);
-       if (master->unique == NULL)
-               return -ENOMEM;
+       if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE)) {
+               master->unique_len = 10 + strlen(dev->platformdev->name);
+               master->unique = kmalloc(master->unique_len + 1, GFP_KERNEL);
+
+               if (master->unique == NULL)
+                       return -ENOMEM;
+
+               len = snprintf(master->unique, master->unique_len,
+                       "platform:%s", dev->platformdev->name);
+
+               if (len > master->unique_len)
+                       DRM_ERROR("Unique buffer overflowed\n");
+
+               dev->devname =
+                       kmalloc(strlen(dev->platformdev->name) +
+                               master->unique_len + 2, GFP_KERNEL);
+
+               if (dev->devname == NULL)
+                       return -ENOMEM;
+
+               sprintf(dev->devname, "%s@%s", dev->platformdev->name,
+                       master->unique);
+
+       } else {
+               master->unique_len = 40;
+               master->unique_size = master->unique_len;
+               master->unique = kmalloc(master->unique_size, GFP_KERNEL);
+               if (master->unique == NULL)
+                       return -ENOMEM;
+
+               len = snprintf(master->unique, master->unique_len,
+                       "pci:%04x:%02x:%02x.%d",
+                       drm_get_pci_domain(dev),
+                       dev->pdev->bus->number,
+                       PCI_SLOT(dev->pdev->devfn),
+                       PCI_FUNC(dev->pdev->devfn));
+               if (len >= master->unique_len)
+                       DRM_ERROR("buffer overflow");
+               else
+                       master->unique_len = len;
 
-       len = snprintf(master->unique, master->unique_len, "pci:%04x:%02x:%02x.%d",
-                      drm_get_pci_domain(dev),
-                      dev->pdev->bus->number,
-                      PCI_SLOT(dev->pdev->devfn),
-                      PCI_FUNC(dev->pdev->devfn));
-       if (len >= master->unique_len)
-               DRM_ERROR("buffer overflow");
-       else
-               master->unique_len = len;
+               dev->devname =
+                       kmalloc(strlen(dev->driver->pci_driver.name) +
+                               master->unique_len + 2, GFP_KERNEL);
 
-       dev->devname = kmalloc(strlen(dev->driver->pci_driver.name) +
-                              master->unique_len + 2, GFP_KERNEL);
-       if (dev->devname == NULL)
-               return -ENOMEM;
+               if (dev->devname == NULL)
+                       return -ENOMEM;
 
-       sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
-               master->unique);
+               sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
+                       master->unique);
+       }
 
        return 0;
 }
index a263b7070fc6f81b227d77a3befbd11b6efc8be0..9d3a5030b6e1dfcfbf522a783d24f14816c7b813 100644 (file)
@@ -34,6 +34,7 @@
  */
 
 #include "drmP.h"
+#include "drm_trace.h"
 
 #include <linux/interrupt.h>   /* For task queue support */
 #include <linux/slab.h>
@@ -57,6 +58,9 @@ int drm_irq_by_busid(struct drm_device *dev, void *data,
 {
        struct drm_irq_busid *p = data;
 
+       if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE))
+               return -EINVAL;
+
        if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
                return -EINVAL;
 
@@ -211,7 +215,7 @@ int drm_irq_install(struct drm_device *dev)
        if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
                return -EINVAL;
 
-       if (dev->pdev->irq == 0)
+       if (drm_dev_to_irq(dev) == 0)
                return -EINVAL;
 
        mutex_lock(&dev->struct_mutex);
@@ -229,7 +233,7 @@ int drm_irq_install(struct drm_device *dev)
        dev->irq_enabled = 1;
        mutex_unlock(&dev->struct_mutex);
 
-       DRM_DEBUG("irq=%d\n", dev->pdev->irq);
+       DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev));
 
        /* Before installing handler */
        dev->driver->irq_preinstall(dev);
@@ -302,14 +306,14 @@ int drm_irq_uninstall(struct drm_device * dev)
        if (!irq_enabled)
                return -EINVAL;
 
-       DRM_DEBUG("irq=%d\n", dev->pdev->irq);
+       DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev));
 
        if (!drm_core_check_feature(dev, DRIVER_MODESET))
                vga_client_register(dev->pdev, NULL, NULL, NULL);
 
        dev->driver->irq_uninstall(dev);
 
-       free_irq(dev->pdev->irq, dev);
+       free_irq(drm_dev_to_irq(dev), dev);
 
        return 0;
 }
@@ -341,7 +345,7 @@ int drm_control(struct drm_device *dev, void *data,
                if (drm_core_check_feature(dev, DRIVER_MODESET))
                        return 0;
                if (dev->if_version < DRM_IF_VERSION(1, 2) &&
-                   ctl->irq != dev->pdev->irq)
+                   ctl->irq != drm_dev_to_irq(dev))
                        return -EINVAL;
                return drm_irq_install(dev);
        case DRM_UNINST_HANDLER:
@@ -587,6 +591,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
                return -ENOMEM;
 
        e->pipe = pipe;
+       e->base.pid = current->pid;
        e->event.base.type = DRM_EVENT_VBLANK;
        e->event.base.length = sizeof e->event;
        e->event.user_data = vblwait->request.signal;
@@ -614,6 +619,9 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
        DRM_DEBUG("event on vblank count %d, current %d, crtc %d\n",
                  vblwait->request.sequence, seq, pipe);
 
+       trace_drm_vblank_event_queued(current->pid, pipe,
+                                     vblwait->request.sequence);
+
        e->event.sequence = vblwait->request.sequence;
        if ((seq - vblwait->request.sequence) <= (1 << 23)) {
                e->event.tv_sec = now.tv_sec;
@@ -621,6 +629,8 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
                drm_vblank_put(dev, e->pipe);
                list_add_tail(&e->base.link, &e->base.file_priv->event_list);
                wake_up_interruptible(&e->base.file_priv->event_wait);
+               trace_drm_vblank_event_delivered(current->pid, pipe,
+                                                vblwait->request.sequence);
        } else {
                list_add_tail(&e->base.link, &dev->vblank_event_list);
        }
@@ -651,7 +661,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
        int ret = 0;
        unsigned int flags, seq, crtc;
 
-       if ((!dev->pdev->irq) || (!dev->irq_enabled))
+       if ((!drm_dev_to_irq(dev)) || (!dev->irq_enabled))
                return -EINVAL;
 
        if (vblwait->request.type & _DRM_VBLANK_SIGNAL)
@@ -751,9 +761,13 @@ void drm_handle_vblank_events(struct drm_device *dev, int crtc)
                drm_vblank_put(dev, e->pipe);
                list_move_tail(&e->base.link, &e->base.file_priv->event_list);
                wake_up_interruptible(&e->base.file_priv->event_wait);
+               trace_drm_vblank_event_delivered(e->base.pid, e->pipe,
+                                                e->event.sequence);
        }
 
        spin_unlock_irqrestore(&dev->event_lock, flags);
+
+       trace_drm_vblank_event(crtc, seq);
 }
 
 /**
index 2ac074c8f5d2e546d40ff53fa3fe54c83547773d..da99edc50888f2168c510054305e1c847e1fbefb 100644 (file)
 
 #define MM_UNUSED_TARGET 4
 
-unsigned long drm_mm_tail_space(struct drm_mm *mm)
-{
-       struct list_head *tail_node;
-       struct drm_mm_node *entry;
-
-       tail_node = mm->ml_entry.prev;
-       entry = list_entry(tail_node, struct drm_mm_node, ml_entry);
-       if (!entry->free)
-               return 0;
-
-       return entry->size;
-}
-
-int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size)
-{
-       struct list_head *tail_node;
-       struct drm_mm_node *entry;
-
-       tail_node = mm->ml_entry.prev;
-       entry = list_entry(tail_node, struct drm_mm_node, ml_entry);
-       if (!entry->free)
-               return -ENOMEM;
-
-       if (entry->size <= size)
-               return -ENOMEM;
-
-       entry->size -= size;
-       return 0;
-}
-
 static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic)
 {
        struct drm_mm_node *child;
 
        if (atomic)
-               child = kmalloc(sizeof(*child), GFP_ATOMIC);
+               child = kzalloc(sizeof(*child), GFP_ATOMIC);
        else
-               child = kmalloc(sizeof(*child), GFP_KERNEL);
+               child = kzalloc(sizeof(*child), GFP_KERNEL);
 
        if (unlikely(child == NULL)) {
                spin_lock(&mm->unused_lock);
@@ -94,8 +64,8 @@ static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic)
                else {
                        child =
                            list_entry(mm->unused_nodes.next,
-                                      struct drm_mm_node, fl_entry);
-                       list_del(&child->fl_entry);
+                                      struct drm_mm_node, free_stack);
+                       list_del(&child->free_stack);
                        --mm->num_unused;
                }
                spin_unlock(&mm->unused_lock);
@@ -115,7 +85,7 @@ int drm_mm_pre_get(struct drm_mm *mm)
        spin_lock(&mm->unused_lock);
        while (mm->num_unused < MM_UNUSED_TARGET) {
                spin_unlock(&mm->unused_lock);
-               node = kmalloc(sizeof(*node), GFP_KERNEL);
+               node = kzalloc(sizeof(*node), GFP_KERNEL);
                spin_lock(&mm->unused_lock);
 
                if (unlikely(node == NULL)) {
@@ -124,7 +94,7 @@ int drm_mm_pre_get(struct drm_mm *mm)
                        return ret;
                }
                ++mm->num_unused;
-               list_add_tail(&node->fl_entry, &mm->unused_nodes);
+               list_add_tail(&node->free_stack, &mm->unused_nodes);
        }
        spin_unlock(&mm->unused_lock);
        return 0;
@@ -146,27 +116,12 @@ static int drm_mm_create_tail_node(struct drm_mm *mm,
        child->start = start;
        child->mm = mm;
 
-       list_add_tail(&child->ml_entry, &mm->ml_entry);
-       list_add_tail(&child->fl_entry, &mm->fl_entry);
+       list_add_tail(&child->node_list, &mm->node_list);
+       list_add_tail(&child->free_stack, &mm->free_stack);
 
        return 0;
 }
 
-int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size, int atomic)
-{
-       struct list_head *tail_node;
-       struct drm_mm_node *entry;
-
-       tail_node = mm->ml_entry.prev;
-       entry = list_entry(tail_node, struct drm_mm_node, ml_entry);
-       if (!entry->free) {
-               return drm_mm_create_tail_node(mm, entry->start + entry->size,
-                                              size, atomic);
-       }
-       entry->size += size;
-       return 0;
-}
-
 static struct drm_mm_node *drm_mm_split_at_start(struct drm_mm_node *parent,
                                                 unsigned long size,
                                                 int atomic)
@@ -177,15 +132,14 @@ static struct drm_mm_node *drm_mm_split_at_start(struct drm_mm_node *parent,
        if (unlikely(child == NULL))
                return NULL;
 
-       INIT_LIST_HEAD(&child->fl_entry);
+       INIT_LIST_HEAD(&child->free_stack);
 
-       child->free = 0;
        child->size = size;
        child->start = parent->start;
        child->mm = parent->mm;
 
-       list_add_tail(&child->ml_entry, &parent->ml_entry);
-       INIT_LIST_HEAD(&child->fl_entry);
+       list_add_tail(&child->node_list, &parent->node_list);
+       INIT_LIST_HEAD(&child->free_stack);
 
        parent->size -= size;
        parent->start += size;
@@ -213,7 +167,7 @@ struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node,
        }
 
        if (node->size == size) {
-               list_del_init(&node->fl_entry);
+               list_del_init(&node->free_stack);
                node->free = 0;
        } else {
                node = drm_mm_split_at_start(node, size, atomic);
@@ -251,7 +205,7 @@ struct drm_mm_node *drm_mm_get_block_range_generic(struct drm_mm_node *node,
        }
 
        if (node->size == size) {
-               list_del_init(&node->fl_entry);
+               list_del_init(&node->free_stack);
                node->free = 0;
        } else {
                node = drm_mm_split_at_start(node, size, atomic);
@@ -273,16 +227,19 @@ void drm_mm_put_block(struct drm_mm_node *cur)
 {
 
        struct drm_mm *mm = cur->mm;
-       struct list_head *cur_head = &cur->ml_entry;
-       struct list_head *root_head = &mm->ml_entry;
+       struct list_head *cur_head = &cur->node_list;
+       struct list_head *root_head = &mm->node_list;
        struct drm_mm_node *prev_node = NULL;
        struct drm_mm_node *next_node;
 
        int merged = 0;
 
+       BUG_ON(cur->scanned_block || cur->scanned_prev_free
+                                 || cur->scanned_next_free);
+
        if (cur_head->prev != root_head) {
                prev_node =
-                   list_entry(cur_head->prev, struct drm_mm_node, ml_entry);
+                   list_entry(cur_head->prev, struct drm_mm_node, node_list);
                if (prev_node->free) {
                        prev_node->size += cur->size;
                        merged = 1;
@@ -290,15 +247,15 @@ void drm_mm_put_block(struct drm_mm_node *cur)
        }
        if (cur_head->next != root_head) {
                next_node =
-                   list_entry(cur_head->next, struct drm_mm_node, ml_entry);
+                   list_entry(cur_head->next, struct drm_mm_node, node_list);
                if (next_node->free) {
                        if (merged) {
                                prev_node->size += next_node->size;
-                               list_del(&next_node->ml_entry);
-                               list_del(&next_node->fl_entry);
+                               list_del(&next_node->node_list);
+                               list_del(&next_node->free_stack);
                                spin_lock(&mm->unused_lock);
                                if (mm->num_unused < MM_UNUSED_TARGET) {
-                                       list_add(&next_node->fl_entry,
+                                       list_add(&next_node->free_stack,
                                                 &mm->unused_nodes);
                                        ++mm->num_unused;
                                } else
@@ -313,12 +270,12 @@ void drm_mm_put_block(struct drm_mm_node *cur)
        }
        if (!merged) {
                cur->free = 1;
-               list_add(&cur->fl_entry, &mm->fl_entry);
+               list_add(&cur->free_stack, &mm->free_stack);
        } else {
-               list_del(&cur->ml_entry);
+               list_del(&cur->node_list);
                spin_lock(&mm->unused_lock);
                if (mm->num_unused < MM_UNUSED_TARGET) {
-                       list_add(&cur->fl_entry, &mm->unused_nodes);
+                       list_add(&cur->free_stack, &mm->unused_nodes);
                        ++mm->num_unused;
                } else
                        kfree(cur);
@@ -328,40 +285,50 @@ void drm_mm_put_block(struct drm_mm_node *cur)
 
 EXPORT_SYMBOL(drm_mm_put_block);
 
+static int check_free_mm_node(struct drm_mm_node *entry, unsigned long size,
+                             unsigned alignment)
+{
+       unsigned wasted = 0;
+
+       if (entry->size < size)
+               return 0;
+
+       if (alignment) {
+               register unsigned tmp = entry->start % alignment;
+               if (tmp)
+                       wasted = alignment - tmp;
+       }
+
+       if (entry->size >= size + wasted) {
+               return 1;
+       }
+
+       return 0;
+}
+
 struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm,
                                       unsigned long size,
                                       unsigned alignment, int best_match)
 {
-       struct list_head *list;
-       const struct list_head *free_stack = &mm->fl_entry;
        struct drm_mm_node *entry;
        struct drm_mm_node *best;
        unsigned long best_size;
-       unsigned wasted;
+
+       BUG_ON(mm->scanned_blocks);
 
        best = NULL;
        best_size = ~0UL;
 
-       list_for_each(list, free_stack) {
-               entry = list_entry(list, struct drm_mm_node, fl_entry);
-               wasted = 0;
-
-               if (entry->size < size)
+       list_for_each_entry(entry, &mm->free_stack, free_stack) {
+               if (!check_free_mm_node(entry, size, alignment))
                        continue;
 
-               if (alignment) {
-                       register unsigned tmp = entry->start % alignment;
-                       if (tmp)
-                               wasted += alignment - tmp;
-               }
+               if (!best_match)
+                       return entry;
 
-               if (entry->size >= size + wasted) {
-                       if (!best_match)
-                               return entry;
-                       if (entry->size < best_size) {
-                               best = entry;
-                               best_size = entry->size;
-                       }
+               if (entry->size < best_size) {
+                       best = entry;
+                       best_size = entry->size;
                }
        }
 
@@ -376,43 +343,28 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm,
                                                unsigned long end,
                                                int best_match)
 {
-       struct list_head *list;
-       const struct list_head *free_stack = &mm->fl_entry;
        struct drm_mm_node *entry;
        struct drm_mm_node *best;
        unsigned long best_size;
-       unsigned wasted;
+
+       BUG_ON(mm->scanned_blocks);
 
        best = NULL;
        best_size = ~0UL;
 
-       list_for_each(list, free_stack) {
-               entry = list_entry(list, struct drm_mm_node, fl_entry);
-               wasted = 0;
-
-               if (entry->size < size)
-                       continue;
-
+       list_for_each_entry(entry, &mm->free_stack, free_stack) {
                if (entry->start > end || (entry->start+entry->size) < start)
                        continue;
 
-               if (entry->start < start)
-                       wasted += start - entry->start;
+               if (!check_free_mm_node(entry, size, alignment))
+                       continue;
 
-               if (alignment) {
-                       register unsigned tmp = (entry->start + wasted) % alignment;
-                       if (tmp)
-                               wasted += alignment - tmp;
-               }
+               if (!best_match)
+                       return entry;
 
-               if (entry->size >= size + wasted &&
-                   (entry->start + wasted + size) <= end) {
-                       if (!best_match)
-                               return entry;
-                       if (entry->size < best_size) {
-                               best = entry;
-                               best_size = entry->size;
-                       }
+               if (entry->size < best_size) {
+                       best = entry;
+                       best_size = entry->size;
                }
        }
 
@@ -420,9 +372,161 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm,
 }
 EXPORT_SYMBOL(drm_mm_search_free_in_range);
 
+/**
+ * Initializa lru scanning.
+ *
+ * This simply sets up the scanning routines with the parameters for the desired
+ * hole.
+ *
+ * Warning: As long as the scan list is non-empty, no other operations than
+ * adding/removing nodes to/from the scan list are allowed.
+ */
+void drm_mm_init_scan(struct drm_mm *mm, unsigned long size,
+                     unsigned alignment)
+{
+       mm->scan_alignment = alignment;
+       mm->scan_size = size;
+       mm->scanned_blocks = 0;
+       mm->scan_hit_start = 0;
+       mm->scan_hit_size = 0;
+}
+EXPORT_SYMBOL(drm_mm_init_scan);
+
+/**
+ * Add a node to the scan list that might be freed to make space for the desired
+ * hole.
+ *
+ * Returns non-zero, if a hole has been found, zero otherwise.
+ */
+int drm_mm_scan_add_block(struct drm_mm_node *node)
+{
+       struct drm_mm *mm = node->mm;
+       struct list_head *prev_free, *next_free;
+       struct drm_mm_node *prev_node, *next_node;
+
+       mm->scanned_blocks++;
+
+       prev_free = next_free = NULL;
+
+       BUG_ON(node->free);
+       node->scanned_block = 1;
+       node->free = 1;
+
+       if (node->node_list.prev != &mm->node_list) {
+               prev_node = list_entry(node->node_list.prev, struct drm_mm_node,
+                                      node_list);
+
+               if (prev_node->free) {
+                       list_del(&prev_node->node_list);
+
+                       node->start = prev_node->start;
+                       node->size += prev_node->size;
+
+                       prev_node->scanned_prev_free = 1;
+
+                       prev_free = &prev_node->free_stack;
+               }
+       }
+
+       if (node->node_list.next != &mm->node_list) {
+               next_node = list_entry(node->node_list.next, struct drm_mm_node,
+                                      node_list);
+
+               if (next_node->free) {
+                       list_del(&next_node->node_list);
+
+                       node->size += next_node->size;
+
+                       next_node->scanned_next_free = 1;
+
+                       next_free = &next_node->free_stack;
+               }
+       }
+
+       /* The free_stack list is not used for allocated objects, so these two
+        * pointers can be abused (as long as no allocations in this memory
+        * manager happens). */
+       node->free_stack.prev = prev_free;
+       node->free_stack.next = next_free;
+
+       if (check_free_mm_node(node, mm->scan_size, mm->scan_alignment)) {
+               mm->scan_hit_start = node->start;
+               mm->scan_hit_size = node->size;
+
+               return 1;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(drm_mm_scan_add_block);
+
+/**
+ * Remove a node from the scan list.
+ *
+ * Nodes _must_ be removed in the exact same order from the scan list as they
+ * have been added, otherwise the internal state of the memory manager will be
+ * corrupted.
+ *
+ * When the scan list is empty, the selected memory nodes can be freed. An
+ * immediatly following drm_mm_search_free with best_match = 0 will then return
+ * the just freed block (because its at the top of the free_stack list).
+ *
+ * Returns one if this block should be evicted, zero otherwise. Will always
+ * return zero when no hole has been found.
+ */
+int drm_mm_scan_remove_block(struct drm_mm_node *node)
+{
+       struct drm_mm *mm = node->mm;
+       struct drm_mm_node *prev_node, *next_node;
+
+       mm->scanned_blocks--;
+
+       BUG_ON(!node->scanned_block);
+       node->scanned_block = 0;
+       node->free = 0;
+
+       prev_node = list_entry(node->free_stack.prev, struct drm_mm_node,
+                              free_stack);
+       next_node = list_entry(node->free_stack.next, struct drm_mm_node,
+                              free_stack);
+
+       if (prev_node) {
+               BUG_ON(!prev_node->scanned_prev_free);
+               prev_node->scanned_prev_free = 0;
+
+               list_add_tail(&prev_node->node_list, &node->node_list);
+
+               node->start = prev_node->start + prev_node->size;
+               node->size -= prev_node->size;
+       }
+
+       if (next_node) {
+               BUG_ON(!next_node->scanned_next_free);
+               next_node->scanned_next_free = 0;
+
+               list_add(&next_node->node_list, &node->node_list);
+
+               node->size -= next_node->size;
+       }
+
+       INIT_LIST_HEAD(&node->free_stack);
+
+       /* Only need to check for containement because start&size for the
+        * complete resulting free block (not just the desired part) is
+        * stored. */
+       if (node->start >= mm->scan_hit_start &&
+           node->start + node->size
+                       <= mm->scan_hit_start + mm->scan_hit_size) {
+               return 1;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(drm_mm_scan_remove_block);
+
 int drm_mm_clean(struct drm_mm * mm)
 {
-       struct list_head *head = &mm->ml_entry;
+       struct list_head *head = &mm->node_list;
 
        return (head->next->next == head);
 }
@@ -430,10 +534,11 @@ EXPORT_SYMBOL(drm_mm_clean);
 
 int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size)
 {
-       INIT_LIST_HEAD(&mm->ml_entry);
-       INIT_LIST_HEAD(&mm->fl_entry);
+       INIT_LIST_HEAD(&mm->node_list);
+       INIT_LIST_HEAD(&mm->free_stack);
        INIT_LIST_HEAD(&mm->unused_nodes);
        mm->num_unused = 0;
+       mm->scanned_blocks = 0;
        spin_lock_init(&mm->unused_lock);
 
        return drm_mm_create_tail_node(mm, start, size, 0);
@@ -442,25 +547,25 @@ EXPORT_SYMBOL(drm_mm_init);
 
 void drm_mm_takedown(struct drm_mm * mm)
 {
-       struct list_head *bnode = mm->fl_entry.next;
+       struct list_head *bnode = mm->free_stack.next;
        struct drm_mm_node *entry;
        struct drm_mm_node *next;
 
-       entry = list_entry(bnode, struct drm_mm_node, fl_entry);
+       entry = list_entry(bnode, struct drm_mm_node, free_stack);
 
-       if (entry->ml_entry.next != &mm->ml_entry ||
-           entry->fl_entry.next != &mm->fl_entry) {
+       if (entry->node_list.next != &mm->node_list ||
+           entry->free_stack.next != &mm->free_stack) {
                DRM_ERROR("Memory manager not clean. Delaying takedown\n");
                return;
        }
 
-       list_del(&entry->fl_entry);
-       list_del(&entry->ml_entry);
+       list_del(&entry->free_stack);
+       list_del(&entry->node_list);
        kfree(entry);
 
        spin_lock(&mm->unused_lock);
-       list_for_each_entry_safe(entry, next, &mm->unused_nodes, fl_entry) {
-               list_del(&entry->fl_entry);
+       list_for_each_entry_safe(entry, next, &mm->unused_nodes, free_stack) {
+               list_del(&entry->free_stack);
                kfree(entry);
                --mm->num_unused;
        }
@@ -475,7 +580,7 @@ void drm_mm_debug_table(struct drm_mm *mm, const char *prefix)
        struct drm_mm_node *entry;
        int total_used = 0, total_free = 0, total = 0;
 
-       list_for_each_entry(entry, &mm->ml_entry, ml_entry) {
+       list_for_each_entry(entry, &mm->node_list, node_list) {
                printk(KERN_DEBUG "%s 0x%08lx-0x%08lx: %8ld: %s\n",
                        prefix, entry->start, entry->start + entry->size,
                        entry->size, entry->free ? "free" : "used");
@@ -496,7 +601,7 @@ int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm)
        struct drm_mm_node *entry;
        int total_used = 0, total_free = 0, total = 0;
 
-       list_for_each_entry(entry, &mm->ml_entry, ml_entry) {
+       list_for_each_entry(entry, &mm->node_list, node_list) {
                seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: %s\n", entry->start, entry->start + entry->size, entry->size, entry->free ? "free" : "used");
                total += entry->size;
                if (entry->free)
index 2ea9ad4a8d699847bb4e8a7d0f1e7dc58ace90e4..e20f78b542a756644a29693c8da5927dd72f5a7d 100644 (file)
@@ -124,4 +124,147 @@ void drm_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah)
 
 EXPORT_SYMBOL(drm_pci_free);
 
+#ifdef CONFIG_PCI
+/**
+ * Register.
+ *
+ * \param pdev - PCI device structure
+ * \param ent entry from the PCI ID table with device type flags
+ * \return zero on success or a negative number on failure.
+ *
+ * Attempt to gets inter module "drm" information. If we are first
+ * then register the character device and inter module information.
+ * Try and register, if we fail to register, backout previous work.
+ */
+int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
+                   struct drm_driver *driver)
+{
+       struct drm_device *dev;
+       int ret;
+
+       DRM_DEBUG("\n");
+
+       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+       if (!dev)
+               return -ENOMEM;
+
+       ret = pci_enable_device(pdev);
+       if (ret)
+               goto err_g1;
+
+       pci_set_master(pdev);
+
+       dev->pdev = pdev;
+       dev->dev = &pdev->dev;
+
+       dev->pci_device = pdev->device;
+       dev->pci_vendor = pdev->vendor;
+
+#ifdef __alpha__
+       dev->hose = pdev->sysdata;
+#endif
+
+       if ((ret = drm_fill_in_dev(dev, ent, driver))) {
+               printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
+               goto err_g2;
+       }
+
+       if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+               pci_set_drvdata(pdev, dev);
+               ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
+               if (ret)
+                       goto err_g2;
+       }
+
+       if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY)))
+               goto err_g3;
+
+       if (dev->driver->load) {
+               ret = dev->driver->load(dev, ent->driver_data);
+               if (ret)
+                       goto err_g4;
+       }
+
+       /* setup the grouping for the legacy output */
+       if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+               ret = drm_mode_group_init_legacy_group(dev,
+                                               &dev->primary->mode_group);
+               if (ret)
+                       goto err_g4;
+       }
+
+       list_add_tail(&dev->driver_item, &driver->device_list);
+
+       DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
+                driver->name, driver->major, driver->minor, driver->patchlevel,
+                driver->date, pci_name(pdev), dev->primary->index);
+
+       return 0;
+
+err_g4:
+       drm_put_minor(&dev->primary);
+err_g3:
+       if (drm_core_check_feature(dev, DRIVER_MODESET))
+               drm_put_minor(&dev->control);
+err_g2:
+       pci_disable_device(pdev);
+err_g1:
+       kfree(dev);
+       return ret;
+}
+EXPORT_SYMBOL(drm_get_pci_dev);
+
+/**
+ * PCI device initialization. Called via drm_init at module load time,
+ *
+ * \return zero on success or a negative number on failure.
+ *
+ * Initializes a drm_device structures,registering the
+ * stubs and initializing the AGP device.
+ *
+ * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and
+ * after the initialization for driver customization.
+ */
+int drm_pci_init(struct drm_driver *driver)
+{
+       struct pci_dev *pdev = NULL;
+       const struct pci_device_id *pid;
+       int i;
+
+       if (driver->driver_features & DRIVER_MODESET)
+               return pci_register_driver(&driver->pci_driver);
+
+       /* If not using KMS, fall back to stealth mode manual scanning. */
+       for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) {
+               pid = &driver->pci_driver.id_table[i];
+
+               /* Loop around setting up a DRM device for each PCI device
+                * matching our ID and device class.  If we had the internal
+                * function that pci_get_subsys and pci_get_class used, we'd
+                * be able to just pass pid in instead of doing a two-stage
+                * thing.
+                */
+               pdev = NULL;
+               while ((pdev =
+                       pci_get_subsys(pid->vendor, pid->device, pid->subvendor,
+                                      pid->subdevice, pdev)) != NULL) {
+                       if ((pdev->class & pid->class_mask) != pid->class)
+                               continue;
+
+                       /* stealth mode requires a manual probe */
+                       pci_dev_get(pdev);
+                       drm_get_pci_dev(pdev, pid, driver);
+               }
+       }
+       return 0;
+}
+
+#else
+
+int drm_pci_init(struct drm_driver *driver)
+{
+       return -1;
+}
+
+#endif
 /*@}*/
diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c
new file mode 100644 (file)
index 0000000..460e9a3
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Derived from drm_pci.c
+ *
+ * Copyright 2003 José Fonseca.
+ * Copyright 2003 Leif Delgass.
+ * Copyright (c) 2009, Code Aurora Forum.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+
+/**
+ * Register.
+ *
+ * \param platdev - Platform device struture
+ * \return zero on success or a negative number on failure.
+ *
+ * Attempt to gets inter module "drm" information. If we are first
+ * then register the character device and inter module information.
+ * Try and register, if we fail to register, backout previous work.
+ */
+
+int drm_get_platform_dev(struct platform_device *platdev,
+                        struct drm_driver *driver)
+{
+       struct drm_device *dev;
+       int ret;
+
+       DRM_DEBUG("\n");
+
+       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+       if (!dev)
+               return -ENOMEM;
+
+       dev->platformdev = platdev;
+       dev->dev = &platdev->dev;
+
+       ret = drm_fill_in_dev(dev, NULL, driver);
+
+       if (ret) {
+               printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
+               goto err_g1;
+       }
+
+       if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+               dev_set_drvdata(&platdev->dev, dev);
+               ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
+               if (ret)
+                       goto err_g1;
+       }
+
+       ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY);
+       if (ret)
+               goto err_g2;
+
+       if (dev->driver->load) {
+               ret = dev->driver->load(dev, 0);
+               if (ret)
+                       goto err_g3;
+       }
+
+       /* setup the grouping for the legacy output */
+       if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+               ret = drm_mode_group_init_legacy_group(dev,
+                               &dev->primary->mode_group);
+               if (ret)
+                       goto err_g3;
+       }
+
+       list_add_tail(&dev->driver_item, &driver->device_list);
+
+       DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
+                driver->name, driver->major, driver->minor, driver->patchlevel,
+                driver->date, dev->primary->index);
+
+       return 0;
+
+err_g3:
+       drm_put_minor(&dev->primary);
+err_g2:
+       if (drm_core_check_feature(dev, DRIVER_MODESET))
+               drm_put_minor(&dev->control);
+err_g1:
+       kfree(dev);
+       return ret;
+}
+EXPORT_SYMBOL(drm_get_platform_dev);
+
+/**
+ * Platform device initialization. Called via drm_init at module load time,
+ *
+ * \return zero on success or a negative number on failure.
+ *
+ * Initializes a drm_device structures,registering the
+ * stubs
+ *
+ * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and
+ * after the initialization for driver customization.
+ */
+
+int drm_platform_init(struct drm_driver *driver)
+{
+       return drm_get_platform_dev(driver->platform_device, driver);
+}
index a0c365f2e521a393ead336e55950ba8aa966c11e..63575e2fa882493461bf2b0aba217e4be15bcc01 100644 (file)
@@ -224,7 +224,7 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
        return 0;
 }
 
-static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev,
+int drm_fill_in_dev(struct drm_device *dev,
                           const struct pci_device_id *ent,
                           struct drm_driver *driver)
 {
@@ -245,14 +245,6 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev,
 
        idr_init(&dev->drw_idr);
 
-       dev->pdev = pdev;
-       dev->pci_device = pdev->device;
-       dev->pci_vendor = pdev->vendor;
-
-#ifdef __alpha__
-       dev->hose = pdev->sysdata;
-#endif
-
        if (drm_ht_create(&dev->map_hash, 12)) {
                return -ENOMEM;
        }
@@ -321,7 +313,7 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev,
  * create the proc init entry via proc_init(). This routines assigns
  * minor numbers to secondary heads of multi-headed cards
  */
-static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type)
+int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type)
 {
        struct drm_minor *new_minor;
        int ret;
@@ -387,83 +379,6 @@ err_idr:
        return ret;
 }
 
-/**
- * Register.
- *
- * \param pdev - PCI device structure
- * \param ent entry from the PCI ID table with device type flags
- * \return zero on success or a negative number on failure.
- *
- * Attempt to gets inter module "drm" information. If we are first
- * then register the character device and inter module information.
- * Try and register, if we fail to register, backout previous work.
- */
-int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
-               struct drm_driver *driver)
-{
-       struct drm_device *dev;
-       int ret;
-
-       DRM_DEBUG("\n");
-
-       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-       if (!dev)
-               return -ENOMEM;
-
-       ret = pci_enable_device(pdev);
-       if (ret)
-               goto err_g1;
-
-       pci_set_master(pdev);
-       if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) {
-               printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
-               goto err_g2;
-       }
-
-       if (drm_core_check_feature(dev, DRIVER_MODESET)) {
-               pci_set_drvdata(pdev, dev);
-               ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
-               if (ret)
-                       goto err_g2;
-       }
-
-       if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY)))
-               goto err_g3;
-
-       if (dev->driver->load) {
-               ret = dev->driver->load(dev, ent->driver_data);
-               if (ret)
-                       goto err_g4;
-       }
-
-        /* setup the grouping for the legacy output */
-       if (drm_core_check_feature(dev, DRIVER_MODESET)) {
-               ret = drm_mode_group_init_legacy_group(dev, &dev->primary->mode_group);
-               if (ret)
-                       goto err_g4;
-       }
-
-       list_add_tail(&dev->driver_item, &driver->device_list);
-
-       DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
-                driver->name, driver->major, driver->minor, driver->patchlevel,
-                driver->date, pci_name(pdev), dev->primary->index);
-
-       return 0;
-
-err_g4:
-       drm_put_minor(&dev->primary);
-err_g3:
-       if (drm_core_check_feature(dev, DRIVER_MODESET))
-               drm_put_minor(&dev->control);
-err_g2:
-       pci_disable_device(pdev);
-err_g1:
-       kfree(dev);
-       return ret;
-}
-EXPORT_SYMBOL(drm_get_dev);
-
 /**
  * Put a secondary minor number.
  *
index 101d381e9d86ced4967677d639753297df43ae77..86118a742231b42fd711f18b64deb182a8d60d3a 100644 (file)
@@ -489,7 +489,8 @@ int drm_sysfs_device_add(struct drm_minor *minor)
        int err;
        char *minor_str;
 
-       minor->kdev.parent = &minor->dev->pdev->dev;
+       minor->kdev.parent = minor->dev->dev;
+
        minor->kdev.class = drm_class;
        minor->kdev.release = drm_sysfs_device_release;
        minor->kdev.devt = minor->device;
diff --git a/drivers/gpu/drm/drm_trace.h b/drivers/gpu/drm/drm_trace.h
new file mode 100644 (file)
index 0000000..03ea964
--- /dev/null
@@ -0,0 +1,66 @@
+#if !defined(_DRM_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ)
+#define _DRM_TRACE_H_
+
+#include <linux/stringify.h>
+#include <linux/types.h>
+#include <linux/tracepoint.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM drm
+#define TRACE_SYSTEM_STRING __stringify(TRACE_SYSTEM)
+#define TRACE_INCLUDE_FILE drm_trace
+
+TRACE_EVENT(drm_vblank_event,
+           TP_PROTO(int crtc, unsigned int seq),
+           TP_ARGS(crtc, seq),
+           TP_STRUCT__entry(
+                   __field(int, crtc)
+                   __field(unsigned int, seq)
+                   ),
+           TP_fast_assign(
+                   __entry->crtc = crtc;
+                   __entry->seq = seq;
+                   ),
+           TP_printk("crtc=%d, seq=%d", __entry->crtc, __entry->seq)
+);
+
+TRACE_EVENT(drm_vblank_event_queued,
+           TP_PROTO(pid_t pid, int crtc, unsigned int seq),
+           TP_ARGS(pid, crtc, seq),
+           TP_STRUCT__entry(
+                   __field(pid_t, pid)
+                   __field(int, crtc)
+                   __field(unsigned int, seq)
+                   ),
+           TP_fast_assign(
+                   __entry->pid = pid;
+                   __entry->crtc = crtc;
+                   __entry->seq = seq;
+                   ),
+           TP_printk("pid=%d, crtc=%d, seq=%d", __entry->pid, __entry->crtc, \
+                     __entry->seq)
+);
+
+TRACE_EVENT(drm_vblank_event_delivered,
+           TP_PROTO(pid_t pid, int crtc, unsigned int seq),
+           TP_ARGS(pid, crtc, seq),
+           TP_STRUCT__entry(
+                   __field(pid_t, pid)
+                   __field(int, crtc)
+                   __field(unsigned int, seq)
+                   ),
+           TP_fast_assign(
+                   __entry->pid = pid;
+                   __entry->crtc = crtc;
+                   __entry->seq = seq;
+                   ),
+           TP_printk("pid=%d, crtc=%d, seq=%d", __entry->pid, __entry->crtc, \
+                     __entry->seq)
+);
+
+#endif /* _DRM_TRACE_H_ */
+
+/* This part must be outside protection */
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#include <trace/define_trace.h>
diff --git a/drivers/gpu/drm/drm_trace_points.c b/drivers/gpu/drm/drm_trace_points.c
new file mode 100644 (file)
index 0000000..0d0eb90
--- /dev/null
@@ -0,0 +1,4 @@
+#include "drmP.h"
+
+#define CREATE_TRACE_POINTS
+#include "drm_trace.h"
index c3b13fb41d0cd557dcf1bf2897d9a5b331356828..3778360eceea0cc44d2f2213090d5e1ed2e670f4 100644 (file)
@@ -61,7 +61,7 @@ static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma)
                tmp = pgprot_writecombine(tmp);
        else
                tmp = pgprot_noncached(tmp);
-#elif defined(__sparc__)
+#elif defined(__sparc__) || defined(__arm__)
        tmp = pgprot_noncached(tmp);
 #endif
        return tmp;
@@ -601,6 +601,7 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
        }
 
        switch (map->type) {
+#if !defined(__arm__)
        case _DRM_AGP:
                if (drm_core_has_AGP(dev) && dev->agp->cant_use_aperture) {
                        /*
@@ -615,20 +616,31 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
                        break;
                }
                /* fall through to _DRM_FRAME_BUFFER... */
+#endif
        case _DRM_FRAME_BUFFER:
        case _DRM_REGISTERS:
                offset = dev->driver->get_reg_ofs(dev);
                vma->vm_flags |= VM_IO; /* not in core dump */
                vma->vm_page_prot = drm_io_prot(map->type, vma);
+#if !defined(__arm__)
                if (io_remap_pfn_range(vma, vma->vm_start,
                                       (map->offset + offset) >> PAGE_SHIFT,
                                       vma->vm_end - vma->vm_start,
                                       vma->vm_page_prot))
                        return -EAGAIN;
+#else
+               if (remap_pfn_range(vma, vma->vm_start,
+                                       (map->offset + offset) >> PAGE_SHIFT,
+                                       vma->vm_end - vma->vm_start,
+                                       vma->vm_page_prot))
+                       return -EAGAIN;
+#endif
+
                DRM_DEBUG("   Type = %d; start = 0x%lx, end = 0x%lx,"
                          " offset = 0x%llx\n",
                          map->type,
                          vma->vm_start, vma->vm_end, (unsigned long long)(map->offset + offset));
+
                vma->vm_ops = &drm_vm_ops;
                break;
        case _DRM_CONSISTENT:
index f00c5ae9556ccb47358ce1f5267dd9cc5cb17a21..92898035845d606e134865b6d9348d187909b979 100644 (file)
@@ -34,6 +34,7 @@
 #include "i915_drm.h"
 #include "i915_drv.h"
 #include "i915_trace.h"
+#include <linux/pci.h>
 #include <linux/vgaarb.h>
 #include <linux/acpi.h>
 #include <linux/pnp.h>
@@ -1354,7 +1355,7 @@ static int i915_load_modeset_init(struct drm_device *dev,
        int fb_bar = IS_I9XX(dev) ? 2 : 0;
        int ret = 0;
 
-       dev->mode_config.fb_base = drm_get_resource_start(dev, fb_bar) &
+       dev->mode_config.fb_base = pci_resource_start(dev->pdev, fb_bar) &
                0xff000000;
 
        /* Basic memrange allocator for stolen space (aka vram) */
@@ -2063,8 +2064,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 
        /* Add register map (needed for suspend/resume) */
        mmio_bar = IS_I9XX(dev) ? 0 : 1;
-       base = drm_get_resource_start(dev, mmio_bar);
-       size = drm_get_resource_len(dev, mmio_bar);
+       base = pci_resource_start(dev->pdev, mmio_bar);
+       size = pci_resource_len(dev->pdev, mmio_bar);
 
        if (i915_get_bridge_dev(dev)) {
                ret = -EIO;
index 423dc90c1e20589e7669f1ba41880308af9fb044..65d3f3e8475b2e5a81bc0f3f14e20ad28b86dc6b 100644 (file)
@@ -413,7 +413,7 @@ int i965_reset(struct drm_device *dev, u8 flags)
 static int __devinit
 i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-       return drm_get_dev(pdev, ent, &driver);
+       return drm_get_pci_dev(pdev, ent, &driver);
 }
 
 static void
index 51bd301cf10d9002555177d95b28e86703145d67..15d2d93aaca997f551bd82cc6222a5963b9bd607 100644 (file)
@@ -2634,10 +2634,8 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
        if (free_space != NULL) {
                obj_priv->gtt_space = drm_mm_get_block(free_space, obj->size,
                                                       alignment);
-               if (obj_priv->gtt_space != NULL) {
-                       obj_priv->gtt_space->private = obj;
+               if (obj_priv->gtt_space != NULL)
                        obj_priv->gtt_offset = obj_priv->gtt_space->start;
-               }
        }
        if (obj_priv->gtt_space == NULL) {
                /* If the gtt is empty and we're still having trouble
index fab21760dd57857cef544f205c44766d08a923ff..fea97a21cc1435a67a95563e786cf41a4acc7858 100644 (file)
@@ -262,6 +262,42 @@ DEFINE_EVENT(i915_ring, i915_ring_wait_end,
            TP_ARGS(dev)
 );
 
+TRACE_EVENT(i915_flip_request,
+           TP_PROTO(int plane, struct drm_gem_object *obj),
+
+           TP_ARGS(plane, obj),
+
+           TP_STRUCT__entry(
+                   __field(int, plane)
+                   __field(struct drm_gem_object *, obj)
+                   ),
+
+           TP_fast_assign(
+                   __entry->plane = plane;
+                   __entry->obj = obj;
+                   ),
+
+           TP_printk("plane=%d, obj=%p", __entry->plane, __entry->obj)
+);
+
+TRACE_EVENT(i915_flip_complete,
+           TP_PROTO(int plane, struct drm_gem_object *obj),
+
+           TP_ARGS(plane, obj),
+
+           TP_STRUCT__entry(
+                   __field(int, plane)
+                   __field(struct drm_gem_object *, obj)
+                   ),
+
+           TP_fast_assign(
+                   __entry->plane = plane;
+                   __entry->obj = obj;
+                   ),
+
+           TP_printk("plane=%d, obj=%p", __entry->plane, __entry->obj)
+);
+
 #endif /* _I915_TRACE_H_ */
 
 /* This part must be outside protection */
index 68dcf36e2793f51fa42aeecb9b67037aa8515205..f879589bead10796c523f3ea1d79135a3105d1c9 100644 (file)
@@ -33,6 +33,7 @@
 #include "intel_drv.h"
 #include "i915_drm.h"
 #include "i915_drv.h"
+#include "i915_trace.h"
 #include "drm_dp_helper.h"
 
 #include "drm_crtc_helper.h"
@@ -4650,6 +4651,8 @@ static void do_intel_finish_page_flip(struct drm_device *dev,
            atomic_dec_and_test(&obj_priv->pending_flip))
                DRM_WAKEUP(&dev_priv->pending_flip_queue);
        schedule_work(&work->work);
+
+       trace_i915_flip_complete(intel_crtc->plane, work->pending_flip_obj);
 }
 
 void intel_finish_page_flip(struct drm_device *dev, int pipe)
@@ -4781,6 +4784,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 
        mutex_unlock(&dev->struct_mutex);
 
+       trace_i915_flip_request(intel_crtc->plane, obj);
+
        return 0;
 }
 
index 3c917fb3a60b85398d84d456d36093d02924525b..ccc129c328a41941cce5e33839bad1bae62ab513 100644 (file)
@@ -405,8 +405,8 @@ int mga_driver_load(struct drm_device * dev, unsigned long flags)
        dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT;
        dev_priv->chipset = flags;
 
-       dev_priv->mmio_base = drm_get_resource_start(dev, 1);
-       dev_priv->mmio_size = drm_get_resource_len(dev, 1);
+       dev_priv->mmio_base = pci_resource_start(dev->pdev, 1);
+       dev_priv->mmio_size = pci_resource_len(dev->pdev, 1);
 
        dev->counters += 3;
        dev->types[6] = _DRM_STAT_IRQ;
index 1175429da1029bf18feb23813aaa223cae651283..b6f5239c2efb07004d7caa084fbefd62aa1b742c 100644 (file)
@@ -1,6 +1,6 @@
 config DRM_NOUVEAU
        tristate "Nouveau (nVidia) cards"
-       depends on DRM
+       depends on DRM && PCI
         select FW_LOADER
        select DRM_KMS_HELPER
        select DRM_TTM
index 6f3c195223772bf9adc6884db52b24711fdb32a1..9f5ab4677758e7ea1013a515ef9ff3f57379a8d7 100644 (file)
@@ -783,7 +783,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
                break;
        case TTM_PL_VRAM:
                mem->bus.offset = mem->mm_node->start << PAGE_SHIFT;
-               mem->bus.base = drm_get_resource_start(dev, 1);
+               mem->bus.base = pci_resource_start(dev->pdev, 1);
                mem->bus.is_iomem = true;
                break;
        default:
index 1fc57ef58295091eef1e8ad979ad50b17c2fb9a4..06555c7cde509104e8ce87c3b1b51bc54f17711c 100644 (file)
@@ -62,7 +62,8 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan)
                 * VRAM.
                 */
                ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
-                                            drm_get_resource_start(dev, 1),
+                                            pci_resource_start(dev->pdev,
+                                            1),
                                             dev_priv->fb_available_size,
                                             NV_DMA_ACCESS_RO,
                                             NV_DMA_TARGET_PCI, &pushbuf);
index 273770432298b72ae5687505e156fe5b03e0e4e4..0fd8e10dbbdebe259539618562322f5eba48e02f 100644 (file)
@@ -132,7 +132,7 @@ static struct drm_driver driver;
 static int __devinit
 nouveau_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-       return drm_get_dev(pdev, ent, &driver);
+       return drm_get_pci_dev(pdev, ent, &driver);
 }
 
 static void
index c1fd42b0dad19cb18e34463548c8ff4b60093747..fb6b791506b2cf7ec0f243f48b3388dd2e728f48 100644 (file)
@@ -471,8 +471,9 @@ void nouveau_mem_close(struct drm_device *dev)
        }
 
        if (dev_priv->fb_mtrr) {
-               drm_mtrr_del(dev_priv->fb_mtrr, drm_get_resource_start(dev, 1),
-                            drm_get_resource_len(dev, 1), DRM_MTRR_WC);
+               drm_mtrr_del(dev_priv->fb_mtrr,
+                            pci_resource_start(dev->pdev, 1),
+                            pci_resource_len(dev->pdev, 1), DRM_MTRR_WC);
                dev_priv->fb_mtrr = 0;
        }
 }
@@ -633,7 +634,7 @@ nouveau_mem_init(struct drm_device *dev)
        struct ttm_bo_device *bdev = &dev_priv->ttm.bdev;
        int ret, dma_bits = 32;
 
-       dev_priv->fb_phys = drm_get_resource_start(dev, 1);
+       dev_priv->fb_phys = pci_resource_start(dev->pdev, 1);
        dev_priv->gart_info.type = NOUVEAU_GART_NONE;
 
        if (dev_priv->card_type >= NV_50 &&
@@ -665,8 +666,9 @@ nouveau_mem_init(struct drm_device *dev)
 
        dev_priv->fb_available_size = dev_priv->vram_size;
        dev_priv->fb_mappable_pages = dev_priv->fb_available_size;
-       if (dev_priv->fb_mappable_pages > drm_get_resource_len(dev, 1))
-               dev_priv->fb_mappable_pages = drm_get_resource_len(dev, 1);
+       if (dev_priv->fb_mappable_pages > pci_resource_len(dev->pdev, 1))
+               dev_priv->fb_mappable_pages =
+                       pci_resource_len(dev->pdev, 1);
        dev_priv->fb_mappable_pages >>= PAGE_SHIFT;
 
        /* remove reserved space at end of vram from available amount */
@@ -718,8 +720,8 @@ nouveau_mem_init(struct drm_device *dev)
                return ret;
        }
 
-       dev_priv->fb_mtrr = drm_mtrr_add(drm_get_resource_start(dev, 1),
-                                        drm_get_resource_len(dev, 1),
+       dev_priv->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 1),
+                                        pci_resource_len(dev->pdev, 1),
                                         DRM_MTRR_WC);
 
        return 0;
index d6fc0a82f03dd20ea8b7c21da48d75c98ebb0ad9..fe2349b115f0f3f8906c42baaae6774a7a8270ce 100644 (file)
@@ -616,7 +616,7 @@ nv20_graph_init(struct drm_device *dev)
        nv_wr32(dev, NV10_PGRAPH_SURFACE, tmp);
 
        /* begin RAM config */
-       vramsz = drm_get_resource_len(dev, 0) - 1;
+       vramsz = pci_resource_len(dev->pdev, 0) - 1;
        nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0));
        nv_wr32(dev, 0x4009A8, nv_rd32(dev, NV04_PFB_CFG1));
        nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0000);
@@ -717,7 +717,7 @@ nv30_graph_init(struct drm_device *dev)
        nv_wr32(dev, 0x0040075c             , 0x00000001);
 
        /* begin RAM config */
-       /* vramsz = drm_get_resource_len(dev, 0) - 1; */
+       /* vramsz = pci_resource_len(dev->pdev, 0) - 1; */
        nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0));
        nv_wr32(dev, 0x4009A8, nv_rd32(dev, NV04_PFB_CFG1));
        if (dev_priv->chipset != 0x34) {
index 704a25d04ac92c75a20fe4f019a808c91ccd7304..65b13b54c5ae0e478fc3dac2aa0deb2274775b4b 100644 (file)
@@ -367,7 +367,7 @@ nv40_graph_init(struct drm_device *dev)
                nv40_graph_set_region_tiling(dev, i, 0, 0, 0);
 
        /* begin RAM config */
-       vramsz = drm_get_resource_len(dev, 0) - 1;
+       vramsz = pci_resource_len(dev->pdev, 0) - 1;
        switch (dev_priv->chipset) {
        case 0x40:
                nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0));
index 5f21df31f3aa7f69beac46ff65dc11885a5f02bd..71c01b6e57319669cdaf995d1334c48375310ce8 100644 (file)
@@ -241,7 +241,7 @@ nv50_instmem_init(struct drm_device *dev)
                return ret;
        BAR0_WI32(priv->fb_bar->gpuobj, 0x00, 0x7fc00000);
        BAR0_WI32(priv->fb_bar->gpuobj, 0x04, 0x40000000 +
-                                             drm_get_resource_len(dev, 1) - 1);
+                                             pci_resource_len(dev->pdev, 1) - 1);
        BAR0_WI32(priv->fb_bar->gpuobj, 0x08, 0x40000000);
        BAR0_WI32(priv->fb_bar->gpuobj, 0x0c, 0x00000000);
        BAR0_WI32(priv->fb_bar->gpuobj, 0x10, 0x00000000);
index 84b1f2729d430deaddcf6e4241a1886339c0123b..aebe00875041448351bb129b7a131baab66f4e9e 100644 (file)
@@ -69,5 +69,6 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
 
 radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
 radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
+radeon-$(CONFIG_ACPI) += radeon_acpi.o
 
 obj-$(CONFIG_DRM_RADEON)+= radeon.o
index 1d569830ed99f0b278e5ae96de52971d020d7a8d..8e421f644a5435d44b6a0bc26f0edf3039b78c21 100644 (file)
@@ -108,12 +108,11 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base,
                        base++;
                        break;
                case ATOM_IIO_READ:
-                       temp = ctx->card->reg_read(ctx->card, CU16(base + 1));
+                       temp = ctx->card->ioreg_read(ctx->card, CU16(base + 1));
                        base += 3;
                        break;
                case ATOM_IIO_WRITE:
-                       (void)ctx->card->reg_read(ctx->card, CU16(base + 1));
-                       ctx->card->reg_write(ctx->card, CU16(base + 1), temp);
+                       ctx->card->ioreg_write(ctx->card, CU16(base + 1), temp);
                        base += 3;
                        break;
                case ATOM_IIO_CLEAR:
@@ -715,8 +714,8 @@ static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg)
                        cjiffies = jiffies;
                        if (time_after(cjiffies, ctx->last_jump_jiffies)) {
                                cjiffies -= ctx->last_jump_jiffies;
-                               if ((jiffies_to_msecs(cjiffies) > 1000)) {
-                                       DRM_ERROR("atombios stuck in loop for more than 1sec aborting\n");
+                               if ((jiffies_to_msecs(cjiffies) > 5000)) {
+                                       DRM_ERROR("atombios stuck in loop for more than 5secs aborting\n");
                                        ctx->abort = true;
                                }
                        } else {
index cd1b64ab5ca7c0c4b24e29bd4dd04e8b52387b16..a589a55b223e660576a9e393be36c371ed7f2f71 100644 (file)
@@ -113,6 +113,8 @@ struct card_info {
        struct drm_device *dev;
        void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
         uint32_t (* reg_read)(struct card_info *, uint32_t);          /*  filled by driver */
+       void (* ioreg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
+        uint32_t (* ioreg_read)(struct card_info *, uint32_t);          /*  filled by driver */
        void (* mc_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
         uint32_t (* mc_read)(struct card_info *, uint32_t);          /*  filled by driver */
        void (* pll_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
index 8c2d6478a2213d82637a4270b4215a676481896b..ec702345d70e545be2c2c80545d8d1c69a80f0ac 100644 (file)
@@ -669,56 +669,25 @@ static void atombios_crtc_set_dcpll(struct drm_crtc *crtc)
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
 
-static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
+static void atombios_crtc_program_pll(struct drm_crtc *crtc,
+                                     int crtc_id,
+                                     int pll_id,
+                                     u32 encoder_mode,
+                                     u32 encoder_id,
+                                     u32 clock,
+                                     u32 ref_div,
+                                     u32 fb_div,
+                                     u32 frac_fb_div,
+                                     u32 post_div)
 {
-       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
        struct drm_device *dev = crtc->dev;
        struct radeon_device *rdev = dev->dev_private;
-       struct drm_encoder *encoder = NULL;
-       struct radeon_encoder *radeon_encoder = NULL;
        u8 frev, crev;
-       int index;
+       int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
        union set_pixel_clock args;
-       u32 pll_clock = mode->clock;
-       u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
-       struct radeon_pll *pll;
-       u32 adjusted_clock;
-       int encoder_mode = 0;
 
        memset(&args, 0, sizeof(args));
 
-       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-               if (encoder->crtc == crtc) {
-                       radeon_encoder = to_radeon_encoder(encoder);
-                       encoder_mode = atombios_get_encoder_mode(encoder);
-                       break;
-               }
-       }
-
-       if (!radeon_encoder)
-               return;
-
-       switch (radeon_crtc->pll_id) {
-       case ATOM_PPLL1:
-               pll = &rdev->clock.p1pll;
-               break;
-       case ATOM_PPLL2:
-               pll = &rdev->clock.p2pll;
-               break;
-       case ATOM_DCPLL:
-       case ATOM_PPLL_INVALID:
-       default:
-               pll = &rdev->clock.dcpll;
-               break;
-       }
-
-       /* adjust pixel clock as needed */
-       adjusted_clock = atombios_adjust_pll(crtc, mode, pll);
-
-       radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
-                          &ref_div, &post_div);
-
-       index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
        if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
                                   &crev))
                return;
@@ -727,47 +696,49 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
        case 1:
                switch (crev) {
                case 1:
-                       args.v1.usPixelClock = cpu_to_le16(mode->clock / 10);
+                       if (clock == ATOM_DISABLE)
+                               return;
+                       args.v1.usPixelClock = cpu_to_le16(clock / 10);
                        args.v1.usRefDiv = cpu_to_le16(ref_div);
                        args.v1.usFbDiv = cpu_to_le16(fb_div);
                        args.v1.ucFracFbDiv = frac_fb_div;
                        args.v1.ucPostDiv = post_div;
-                       args.v1.ucPpll = radeon_crtc->pll_id;
-                       args.v1.ucCRTC = radeon_crtc->crtc_id;
+                       args.v1.ucPpll = pll_id;
+                       args.v1.ucCRTC = crtc_id;
                        args.v1.ucRefDivSrc = 1;
                        break;
                case 2:
-                       args.v2.usPixelClock = cpu_to_le16(mode->clock / 10);
+                       args.v2.usPixelClock = cpu_to_le16(clock / 10);
                        args.v2.usRefDiv = cpu_to_le16(ref_div);
                        args.v2.usFbDiv = cpu_to_le16(fb_div);
                        args.v2.ucFracFbDiv = frac_fb_div;
                        args.v2.ucPostDiv = post_div;
-                       args.v2.ucPpll = radeon_crtc->pll_id;
-                       args.v2.ucCRTC = radeon_crtc->crtc_id;
+                       args.v2.ucPpll = pll_id;
+                       args.v2.ucCRTC = crtc_id;
                        args.v2.ucRefDivSrc = 1;
                        break;
                case 3:
-                       args.v3.usPixelClock = cpu_to_le16(mode->clock / 10);
+                       args.v3.usPixelClock = cpu_to_le16(clock / 10);
                        args.v3.usRefDiv = cpu_to_le16(ref_div);
                        args.v3.usFbDiv = cpu_to_le16(fb_div);
                        args.v3.ucFracFbDiv = frac_fb_div;
                        args.v3.ucPostDiv = post_div;
-                       args.v3.ucPpll = radeon_crtc->pll_id;
-                       args.v3.ucMiscInfo = (radeon_crtc->pll_id << 2);
-                       args.v3.ucTransmitterId = radeon_encoder->encoder_id;
+                       args.v3.ucPpll = pll_id;
+                       args.v3.ucMiscInfo = (pll_id << 2);
+                       args.v3.ucTransmitterId = encoder_id;
                        args.v3.ucEncoderMode = encoder_mode;
                        break;
                case 5:
-                       args.v5.ucCRTC = radeon_crtc->crtc_id;
-                       args.v5.usPixelClock = cpu_to_le16(mode->clock / 10);
+                       args.v5.ucCRTC = crtc_id;
+                       args.v5.usPixelClock = cpu_to_le16(clock / 10);
                        args.v5.ucRefDiv = ref_div;
                        args.v5.usFbDiv = cpu_to_le16(fb_div);
                        args.v5.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
                        args.v5.ucPostDiv = post_div;
                        args.v5.ucMiscInfo = 0; /* HDMI depth, etc. */
-                       args.v5.ucTransmitterID = radeon_encoder->encoder_id;
+                       args.v5.ucTransmitterID = encoder_id;
                        args.v5.ucEncoderMode = encoder_mode;
-                       args.v5.ucPpll = radeon_crtc->pll_id;
+                       args.v5.ucPpll = pll_id;
                        break;
                default:
                        DRM_ERROR("Unknown table version %d %d\n", frev, crev);
@@ -782,6 +753,56 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
 
+static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
+{
+       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+       struct drm_device *dev = crtc->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct drm_encoder *encoder = NULL;
+       struct radeon_encoder *radeon_encoder = NULL;
+       u32 pll_clock = mode->clock;
+       u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
+       struct radeon_pll *pll;
+       u32 adjusted_clock;
+       int encoder_mode = 0;
+
+       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+               if (encoder->crtc == crtc) {
+                       radeon_encoder = to_radeon_encoder(encoder);
+                       encoder_mode = atombios_get_encoder_mode(encoder);
+                       break;
+               }
+       }
+
+       if (!radeon_encoder)
+               return;
+
+       switch (radeon_crtc->pll_id) {
+       case ATOM_PPLL1:
+               pll = &rdev->clock.p1pll;
+               break;
+       case ATOM_PPLL2:
+               pll = &rdev->clock.p2pll;
+               break;
+       case ATOM_DCPLL:
+       case ATOM_PPLL_INVALID:
+       default:
+               pll = &rdev->clock.dcpll;
+               break;
+       }
+
+       /* adjust pixel clock as needed */
+       adjusted_clock = atombios_adjust_pll(crtc, mode, pll);
+
+       radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
+                          &ref_div, &post_div);
+
+       atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
+                                 encoder_mode, radeon_encoder->encoder_id, mode->clock,
+                                 ref_div, fb_div, frac_fb_div, post_div);
+
+}
+
 static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y,
                                   struct drm_framebuffer *old_fb)
 {
@@ -841,6 +862,11 @@ static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y,
                return -EINVAL;
        }
 
+       if (tiling_flags & RADEON_TILING_MACRO)
+               fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1);
+       else if (tiling_flags & RADEON_TILING_MICRO)
+               fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1);
+
        switch (radeon_crtc->crtc_id) {
        case 0:
                WREG32(AVIVO_D1VGA_CONTROL, 0);
@@ -979,11 +1005,18 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y,
                return -EINVAL;
        }
 
-       if (tiling_flags & RADEON_TILING_MACRO)
-               fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE;
+       if (rdev->family >= CHIP_R600) {
+               if (tiling_flags & RADEON_TILING_MACRO)
+                       fb_format |= R600_D1GRPH_ARRAY_MODE_2D_TILED_THIN1;
+               else if (tiling_flags & RADEON_TILING_MICRO)
+                       fb_format |= R600_D1GRPH_ARRAY_MODE_1D_TILED_THIN1;
+       } else {
+               if (tiling_flags & RADEON_TILING_MACRO)
+                       fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE;
 
-       if (tiling_flags & RADEON_TILING_MICRO)
-               fb_format |= AVIVO_D1GRPH_TILED;
+               if (tiling_flags & RADEON_TILING_MICRO)
+                       fb_format |= AVIVO_D1GRPH_TILED;
+       }
 
        if (radeon_crtc->crtc_id == 0)
                WREG32(AVIVO_D1VGA_CONTROL, 0);
@@ -1191,6 +1224,24 @@ static void atombios_crtc_commit(struct drm_crtc *crtc)
        atombios_lock_crtc(crtc, ATOM_DISABLE);
 }
 
+static void atombios_crtc_disable(struct drm_crtc *crtc)
+{
+       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+       atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
+
+       switch (radeon_crtc->pll_id) {
+       case ATOM_PPLL1:
+       case ATOM_PPLL2:
+               /* disable the ppll */
+               atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
+                                         0, 0, ATOM_DISABLE, 0, 0, 0, 0);
+               break;
+       default:
+               break;
+       }
+       radeon_crtc->pll_id = -1;
+}
+
 static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
        .dpms = atombios_crtc_dpms,
        .mode_fixup = atombios_crtc_mode_fixup,
@@ -1199,6 +1250,7 @@ static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
        .prepare = atombios_crtc_prepare,
        .commit = atombios_crtc_commit,
        .load_lut = radeon_crtc_load_lut,
+       .disable = atombios_crtc_disable,
 };
 
 void radeon_atombios_init_crtc(struct drm_device *dev,
index 1caf625e472b607b92b2841f0dcf7fae44785cde..957d5067ad9cc1495984f909d724fbf64c8d8856 100644 (file)
 static void evergreen_gpu_init(struct radeon_device *rdev);
 void evergreen_fini(struct radeon_device *rdev);
 
+/* get temperature in millidegrees */
+u32 evergreen_get_temp(struct radeon_device *rdev)
+{
+       u32 temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >>
+               ASIC_T_SHIFT;
+       u32 actual_temp = 0;
+
+       if ((temp >> 10) & 1)
+               actual_temp = 0;
+       else if ((temp >> 9) & 1)
+               actual_temp = 255;
+       else
+               actual_temp = (temp >> 1) & 0xff;
+
+       return actual_temp * 1000;
+}
+
 void evergreen_pm_misc(struct radeon_device *rdev)
 {
        int req_ps_idx = rdev->pm.requested_power_state_index;
@@ -1115,6 +1132,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
                                                                 rdev->config.evergreen.max_backends) &
                                                                EVERGREEN_MAX_BACKENDS_MASK));
 
+       rdev->config.evergreen.tile_config = gb_addr_config;
        WREG32(GB_BACKEND_MAP, gb_backend_map);
        WREG32(GB_ADDR_CONFIG, gb_addr_config);
        WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
@@ -1334,8 +1352,8 @@ int evergreen_mc_init(struct radeon_device *rdev)
        }
        rdev->mc.vram_width = numchan * chansize;
        /* Could aper size report 0 ? */
-       rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
-       rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
+       rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
+       rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
        /* Setup GPU memory space */
        /* size in MB on evergreen */
        rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024;
index e028c1cd9d9b7732d8eeaf1c8773df35e13c93fa..2330f3a36fd5c44d02d8a2d96b057db56ef9f079 100644 (file)
 #       define EVERGREEN_GRPH_FORMAT_8B_BGRA1010102     5
 #       define EVERGREEN_GRPH_FORMAT_RGB111110          6
 #       define EVERGREEN_GRPH_FORMAT_BGR101111          7
+#       define EVERGREEN_GRPH_ARRAY_MODE(x)             (((x) & 0x7) << 20)
+#       define EVERGREEN_GRPH_ARRAY_LINEAR_GENERAL      0
+#       define EVERGREEN_GRPH_ARRAY_LINEAR_ALIGNED      1
+#       define EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1      2
+#       define EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1      4
 #define EVERGREEN_GRPH_SWAP_CONTROL                     0x680c
 #       define EVERGREEN_GRPH_ENDIAN_SWAP(x)            (((x) & 0x3) << 0)
 #       define EVERGREEN_GRPH_ENDIAN_NONE               0
index a1cd621780e21bc5fdd7251c397dfc362d3c5ec3..9b7532dd30f754d4ad2e3e02915006ae823538f2 100644 (file)
 #define                SE_DB_BUSY                                      (1 << 30)
 #define                SE_CB_BUSY                                      (1 << 31)
 
+#define        CG_MULT_THERMAL_STATUS                          0x740
+#define                ASIC_T(x)                               ((x) << 16)
+#define                ASIC_T_MASK                             0x7FF0000
+#define                ASIC_T_SHIFT                            16
+
 #define        HDP_HOST_PATH_CNTL                              0x2C00
 #define        HDP_NONSURFACE_BASE                             0x2C04
 #define        HDP_NONSURFACE_INFO                             0x2C08
index a89a15ab524d87d64f734b9475418b0538525dd2..e115583f84fb03dd48f9716694668a8268d54a60 100644 (file)
@@ -2295,8 +2295,8 @@ void r100_vram_init_sizes(struct radeon_device *rdev)
        u64 config_aper_size;
 
        /* work out accessible VRAM */
-       rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
-       rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
+       rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
+       rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
        rdev->mc.visible_vram_size = r100_get_accessible_vram(rdev);
        /* FIXME we don't use the second aperture yet when we could use it */
        if (rdev->mc.visible_vram_size > rdev->mc.aper_size)
@@ -2364,11 +2364,10 @@ void r100_mc_init(struct radeon_device *rdev)
  */
 void r100_pll_errata_after_index(struct radeon_device *rdev)
 {
-       if (!(rdev->pll_errata & CHIP_ERRATA_PLL_DUMMYREADS)) {
-               return;
+       if (rdev->pll_errata & CHIP_ERRATA_PLL_DUMMYREADS) {
+               (void)RREG32(RADEON_CLOCK_CNTL_DATA);
+               (void)RREG32(RADEON_CRTC_GEN_CNTL);
        }
-       (void)RREG32(RADEON_CLOCK_CNTL_DATA);
-       (void)RREG32(RADEON_CRTC_GEN_CNTL);
 }
 
 static void r100_pll_errata_after_data(struct radeon_device *rdev)
@@ -3809,6 +3808,31 @@ void r100_fini(struct radeon_device *rdev)
        rdev->bios = NULL;
 }
 
+/*
+ * Due to how kexec works, it can leave the hw fully initialised when it
+ * boots the new kernel. However doing our init sequence with the CP and
+ * WB stuff setup causes GPU hangs on the RN50 at least. So at startup
+ * do some quick sanity checks and restore sane values to avoid this
+ * problem.
+ */
+void r100_restore_sanity(struct radeon_device *rdev)
+{
+       u32 tmp;
+
+       tmp = RREG32(RADEON_CP_CSQ_CNTL);
+       if (tmp) {
+               WREG32(RADEON_CP_CSQ_CNTL, 0);
+       }
+       tmp = RREG32(RADEON_CP_RB_CNTL);
+       if (tmp) {
+               WREG32(RADEON_CP_RB_CNTL, 0);
+       }
+       tmp = RREG32(RADEON_SCRATCH_UMSK);
+       if (tmp) {
+               WREG32(RADEON_SCRATCH_UMSK, 0);
+       }
+}
+
 int r100_init(struct radeon_device *rdev)
 {
        int r;
@@ -3821,6 +3845,8 @@ int r100_init(struct radeon_device *rdev)
        radeon_scratch_init(rdev);
        /* Initialize surface registers */
        radeon_surface_init(rdev);
+       /* sanity check some register to avoid hangs like after kexec */
+       r100_restore_sanity(rdev);
        /* TODO: disable VGA need to use VGA request */
        /* BIOS*/
        if (!radeon_get_bios(rdev)) {
index 19a7ef7ee3448f867ec11ab4a0f57f9dfa047013..58eab5d473058fa51aca846452233e850cccca30 100644 (file)
@@ -1380,6 +1380,8 @@ int r300_init(struct radeon_device *rdev)
        /* Initialize surface registers */
        radeon_surface_init(rdev);
        /* TODO: disable VGA need to use VGA request */
+       /* restore some register to sane defaults */
+       r100_restore_sanity(rdev);
        /* BIOS*/
        if (!radeon_get_bios(rdev)) {
                if (ASIC_IS_AVIVO(rdev))
index e6c89142bb4d24323920636cf0e2499c5e17cf59..59f7bccc5be0a291dcf0fcfb9487080ea93d5693 100644 (file)
@@ -343,6 +343,8 @@ int r420_init(struct radeon_device *rdev)
        /* Initialize surface registers */
        radeon_surface_init(rdev);
        /* TODO: disable VGA need to use VGA request */
+       /* restore some register to sane defaults */
+       r100_restore_sanity(rdev);
        /* BIOS*/
        if (!radeon_get_bios(rdev)) {
                if (ASIC_IS_AVIVO(rdev))
index 93c9a2bbccf88b856eaf3c9a2cc6e0592cb7fb32..6ac1f604e29be8afd2eb7d16cd43ffd1c4817458 100644 (file)
 #       define AVIVO_D1GRPH_TILED                               (1 << 20)
 #       define AVIVO_D1GRPH_MACRO_ADDRESS_MODE                  (1 << 21)
 
+#       define R600_D1GRPH_ARRAY_MODE_LINEAR_GENERAL            (0 << 20)
+#       define R600_D1GRPH_ARRAY_MODE_LINEAR_ALIGNED            (1 << 20)
+#       define R600_D1GRPH_ARRAY_MODE_1D_TILED_THIN1            (2 << 20)
+#       define R600_D1GRPH_ARRAY_MODE_2D_TILED_THIN1            (4 << 20)
+
 /* The R7xx *_HIGH surface regs are backwards; the D1 regs are in the D2
  * block and vice versa.  This applies to GRPH, CUR, etc.
  */
index 694af7cc23ac1b3ce91b8abb71ca1d3fdbb58ae2..1458dee902dd6124db7c11d3c74911220c7648de 100644 (file)
@@ -231,6 +231,8 @@ int r520_init(struct radeon_device *rdev)
        radeon_scratch_init(rdev);
        /* Initialize surface registers */
        radeon_surface_init(rdev);
+       /* restore some register to sane defaults */
+       r100_restore_sanity(rdev);
        /* TODO: disable VGA need to use VGA request */
        /* BIOS*/
        if (!radeon_get_bios(rdev)) {
index e100f69faeec80a0c447ee186774a14ea95620c4..e1e59e1b318d4a2f6c7f2b0578d8aa1d6eaee936 100644 (file)
@@ -92,6 +92,21 @@ void r600_gpu_init(struct radeon_device *rdev);
 void r600_fini(struct radeon_device *rdev);
 void r600_irq_disable(struct radeon_device *rdev);
 
+/* get temperature in millidegrees */
+u32 rv6xx_get_temp(struct radeon_device *rdev)
+{
+       u32 temp = (RREG32(CG_THERMAL_STATUS) & ASIC_T_MASK) >>
+               ASIC_T_SHIFT;
+       u32 actual_temp = 0;
+
+       if ((temp >> 7) & 1)
+               actual_temp = 0;
+       else
+               actual_temp = (temp >> 1) & 0xff;
+
+       return actual_temp * 1000;
+}
+
 void r600_pm_get_dynpm_state(struct radeon_device *rdev)
 {
        int i;
@@ -1217,8 +1232,8 @@ int r600_mc_init(struct radeon_device *rdev)
        }
        rdev->mc.vram_width = numchan * chansize;
        /* Could aper size report 0 ? */
-       rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
-       rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
+       rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
+       rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
        /* Setup GPU memory space */
        rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
        rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
@@ -1609,7 +1624,7 @@ void r600_gpu_init(struct radeon_device *rdev)
                                                         r600_count_pipe_bits((cc_rb_backend_disable &
                                                                               R6XX_MAX_BACKENDS_MASK) >> 16)),
                                                        (cc_rb_backend_disable >> 16));
-
+       rdev->config.r600.tile_config = tiling_config;
        tiling_config |= BACKEND_MAP(backend_map);
        WREG32(GB_TILING_CONFIG, tiling_config);
        WREG32(DCP_TILING_CONFIG, tiling_config & 0xffff);
index 2b26553c352cdf6bd63495ae9f40b3f95a259030..631e1edc373a60b0dbc34b4bf71c39fa5b8e24e0 100644 (file)
@@ -160,6 +160,7 @@ static void r600_audio_engine_enable(struct radeon_device *rdev, bool enable)
 {
        DRM_INFO("%s audio support", enable ? "Enabling" : "Disabling");
        WREG32_P(R600_AUDIO_ENABLE, enable ? 0x81000000 : 0x0, ~0x81000000);
+       rdev->audio_enabled = enable;
 }
 
 /*
@@ -200,7 +201,8 @@ void r600_audio_enable_polling(struct drm_encoder *encoder)
                return;
 
        radeon_encoder->audio_polling_active = 1;
-       mod_timer(&rdev->audio_timer, jiffies + 1);
+       if (rdev->audio_enabled)
+               mod_timer(&rdev->audio_timer, jiffies + 1);
 }
 
 /*
@@ -266,7 +268,7 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock)
  */
 void r600_audio_fini(struct radeon_device *rdev)
 {
-       if (!radeon_audio || !r600_audio_chipset_supported(rdev))
+       if (!rdev->audio_enabled)
                return;
 
        del_timer(&rdev->audio_timer);
index 144c32d371362b0a167e1dc9bd95322ddc8614e7..c3ea212e0c3c28284271d64e617b3cebedc0e173 100644 (file)
@@ -25,6 +25,7 @@
  *          Alex Deucher
  *          Jerome Glisse
  */
+#include <linux/kernel.h>
 #include "drmP.h"
 #include "radeon.h"
 #include "r600d.h"
@@ -166,7 +167,7 @@ static void r600_cs_track_init(struct r600_cs_track *track)
 static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
 {
        struct r600_cs_track *track = p->track;
-       u32 bpe = 0, pitch, slice_tile_max, size, tmp, height;
+       u32 bpe = 0, pitch, slice_tile_max, size, tmp, height, pitch_align;
        volatile u32 *ib = p->ib->ptr;
 
        if (G_0280A0_TILE_MODE(track->cb_color_info[i])) {
@@ -180,56 +181,57 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
                        i, track->cb_color_info[i]);
                return -EINVAL;
        }
-       pitch = (G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1) << 3;
+       /* pitch is the number of 8x8 tiles per row */
+       pitch = G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1;
        slice_tile_max = G_028060_SLICE_TILE_MAX(track->cb_color_size[i]) + 1;
-       if (!pitch) {
-               dev_warn(p->dev, "%s:%d cb pitch (%d) for %d invalid (0x%08X)\n",
-                       __func__, __LINE__, pitch, i, track->cb_color_size[i]);
-               return -EINVAL;
-       }
-       height = size / (pitch * bpe);
+       height = size / (pitch * 8 * bpe);
        if (height > 8192)
                height = 8192;
+       if (height > 7)
+               height &= ~0x7;
        switch (G_0280A0_ARRAY_MODE(track->cb_color_info[i])) {
        case V_0280A0_ARRAY_LINEAR_GENERAL:
+               /* technically height & 0x7 */
+               break;
        case V_0280A0_ARRAY_LINEAR_ALIGNED:
-               if (pitch & 0x3f) {
-                       dev_warn(p->dev, "%s:%d cb pitch (%d x %d = %d) invalid\n",
-                               __func__, __LINE__, pitch, bpe, pitch * bpe);
+               pitch_align = max((u32)64, (u32)(track->group_size / bpe)) / 8;
+               if (!IS_ALIGNED(pitch, pitch_align)) {
+                       dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
+                                __func__, __LINE__, pitch);
                        return -EINVAL;
                }
-               if ((pitch * bpe) & (track->group_size - 1)) {
-                       dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
-                               __func__, __LINE__, pitch);
+               if (!IS_ALIGNED(height, 8)) {
+                       dev_warn(p->dev, "%s:%d cb height (%d) invalid\n",
+                                __func__, __LINE__, height);
                        return -EINVAL;
                }
                break;
        case V_0280A0_ARRAY_1D_TILED_THIN1:
-               if ((pitch * 8 * bpe * track->nsamples) & (track->group_size - 1)) {
+               pitch_align = max((u32)8, (u32)(track->group_size / (8 * bpe * track->nsamples))) / 8;
+               if (!IS_ALIGNED(pitch, pitch_align)) {
                        dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
-                               __func__, __LINE__, pitch);
+                                __func__, __LINE__, pitch);
+                       return -EINVAL;
+               }
+               if (!IS_ALIGNED(height, 8)) {
+                       dev_warn(p->dev, "%s:%d cb height (%d) invalid\n",
+                                __func__, __LINE__, height);
                        return -EINVAL;
                }
-               height &= ~0x7;
-               if (!height)
-                       height = 8;
                break;
        case V_0280A0_ARRAY_2D_TILED_THIN1:
-               if (pitch & ((8 * track->nbanks) - 1)) {
+               pitch_align = max((u32)track->nbanks,
+                                 (u32)(((track->group_size / 8) / (bpe * track->nsamples)) * track->nbanks));
+               if (!IS_ALIGNED(pitch, pitch_align)) {
                        dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
                                __func__, __LINE__, pitch);
                        return -EINVAL;
                }
-               tmp = pitch * 8 * bpe * track->nsamples;
-               tmp = tmp / track->nbanks;
-               if (tmp & (track->group_size - 1)) {
-                       dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
-                               __func__, __LINE__, pitch);
+               if (!IS_ALIGNED((height / 8), track->nbanks)) {
+                       dev_warn(p->dev, "%s:%d cb height (%d) invalid\n",
+                                __func__, __LINE__, height);
                        return -EINVAL;
                }
-               height &= ~((16 * track->npipes) - 1);
-               if (!height)
-                       height = 16 * track->npipes;
                break;
        default:
                dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__,
@@ -238,16 +240,20 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
                return -EINVAL;
        }
        /* check offset */
-       tmp = height * pitch;
+       tmp = height * pitch * 8 * bpe;
        if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) {
-               dev_warn(p->dev, "%s offset[%d] %d to big\n", __func__, i, track->cb_color_bo_offset[i]);
+               dev_warn(p->dev, "%s offset[%d] %d too big\n", __func__, i, track->cb_color_bo_offset[i]);
+               return -EINVAL;
+       }
+       if (!IS_ALIGNED(track->cb_color_bo_offset[i], track->group_size)) {
+               dev_warn(p->dev, "%s offset[%d] %d not aligned\n", __func__, i, track->cb_color_bo_offset[i]);
                return -EINVAL;
        }
        /* limit max tile */
-       tmp = (height * pitch) >> 6;
+       tmp = (height * pitch * 8) >> 6;
        if (tmp < slice_tile_max)
                slice_tile_max = tmp;
-       tmp = S_028060_PITCH_TILE_MAX((pitch >> 3) - 1) |
+       tmp = S_028060_PITCH_TILE_MAX(pitch - 1) |
                S_028060_SLICE_TILE_MAX(slice_tile_max - 1);
        ib[track->cb_color_size_idx[i]] = tmp;
        return 0;
@@ -289,7 +295,7 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
        /* Check depth buffer */
        if (G_028800_STENCIL_ENABLE(track->db_depth_control) ||
                G_028800_Z_ENABLE(track->db_depth_control)) {
-               u32 nviews, bpe, ntiles;
+               u32 nviews, bpe, ntiles, pitch, pitch_align, height, size;
                if (track->db_bo == NULL) {
                        dev_warn(p->dev, "z/stencil with no depth buffer\n");
                        return -EINVAL;
@@ -332,6 +338,51 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
                        }
                        ib[track->db_depth_size_idx] = S_028000_SLICE_TILE_MAX(tmp - 1) | (track->db_depth_size & 0x3FF);
                } else {
+                       size = radeon_bo_size(track->db_bo);
+                       pitch = G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1;
+                       height = size / (pitch * 8 * bpe);
+                       height &= ~0x7;
+                       if (!height)
+                               height = 8;
+
+                       switch (G_028010_ARRAY_MODE(track->db_depth_info)) {
+                       case V_028010_ARRAY_1D_TILED_THIN1:
+                               pitch_align = (max((u32)8, (u32)(track->group_size / (8 * bpe))) / 8);
+                               if (!IS_ALIGNED(pitch, pitch_align)) {
+                                       dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n",
+                                                __func__, __LINE__, pitch);
+                                       return -EINVAL;
+                               }
+                               if (!IS_ALIGNED(height, 8)) {
+                                       dev_warn(p->dev, "%s:%d db height (%d) invalid\n",
+                                                __func__, __LINE__, height);
+                                       return -EINVAL;
+                               }
+                               break;
+                       case V_028010_ARRAY_2D_TILED_THIN1:
+                               pitch_align = max((u32)track->nbanks,
+                                                 (u32)(((track->group_size / 8) / bpe) * track->nbanks));
+                               if (!IS_ALIGNED(pitch, pitch_align)) {
+                                       dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n",
+                                                __func__, __LINE__, pitch);
+                                       return -EINVAL;
+                               }
+                               if ((height / 8) & (track->nbanks - 1)) {
+                                       dev_warn(p->dev, "%s:%d db height (%d) invalid\n",
+                                                __func__, __LINE__, height);
+                                       return -EINVAL;
+                               }
+                               break;
+                       default:
+                               dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
+                                        G_028010_ARRAY_MODE(track->db_depth_info),
+                                        track->db_depth_info);
+                               return -EINVAL;
+                       }
+                       if (!IS_ALIGNED(track->db_offset, track->group_size)) {
+                               dev_warn(p->dev, "%s offset[%d] %d not aligned\n", __func__, i, track->db_offset);
+                               return -EINVAL;
+                       }
                        ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
                        nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1;
                        tmp = ntiles * bpe * 64 * nviews;
@@ -724,7 +775,25 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
                track->db_depth_control = radeon_get_ib_value(p, idx);
                break;
        case R_028010_DB_DEPTH_INFO:
-               track->db_depth_info = radeon_get_ib_value(p, idx);
+               if (r600_cs_packet_next_is_pkt3_nop(p)) {
+                       r = r600_cs_packet_next_reloc(p, &reloc);
+                       if (r) {
+                               dev_warn(p->dev, "bad SET_CONTEXT_REG "
+                                        "0x%04X\n", reg);
+                               return -EINVAL;
+                       }
+                       track->db_depth_info = radeon_get_ib_value(p, idx);
+                       ib[idx] &= C_028010_ARRAY_MODE;
+                       track->db_depth_info &= C_028010_ARRAY_MODE;
+                       if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
+                               ib[idx] |= S_028010_ARRAY_MODE(V_028010_ARRAY_2D_TILED_THIN1);
+                               track->db_depth_info |= S_028010_ARRAY_MODE(V_028010_ARRAY_2D_TILED_THIN1);
+                       } else {
+                               ib[idx] |= S_028010_ARRAY_MODE(V_028010_ARRAY_1D_TILED_THIN1);
+                               track->db_depth_info |= S_028010_ARRAY_MODE(V_028010_ARRAY_1D_TILED_THIN1);
+                       }
+               } else
+                       track->db_depth_info = radeon_get_ib_value(p, idx);
                break;
        case R_028004_DB_DEPTH_VIEW:
                track->db_depth_view = radeon_get_ib_value(p, idx);
@@ -757,8 +826,25 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
        case R_0280B4_CB_COLOR5_INFO:
        case R_0280B8_CB_COLOR6_INFO:
        case R_0280BC_CB_COLOR7_INFO:
-               tmp = (reg - R_0280A0_CB_COLOR0_INFO) / 4;
-               track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
+               if (r600_cs_packet_next_is_pkt3_nop(p)) {
+                       r = r600_cs_packet_next_reloc(p, &reloc);
+                       if (r) {
+                               dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
+                               return -EINVAL;
+                       }
+                       tmp = (reg - R_0280A0_CB_COLOR0_INFO) / 4;
+                       track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
+                       if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
+                               ib[idx] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_2D_TILED_THIN1);
+                               track->cb_color_info[tmp] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_2D_TILED_THIN1);
+                       } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
+                               ib[idx] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_1D_TILED_THIN1);
+                               track->cb_color_info[tmp] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_1D_TILED_THIN1);
+                       }
+               } else {
+                       tmp = (reg - R_0280A0_CB_COLOR0_INFO) / 4;
+                       track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
+               }
                break;
        case R_028060_CB_COLOR0_SIZE:
        case R_028064_CB_COLOR1_SIZE:
@@ -946,8 +1032,9 @@ static inline unsigned minify(unsigned size, unsigned levels)
 }
 
 static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels,
-                               unsigned w0, unsigned h0, unsigned d0, unsigned bpe,
-                               unsigned *l0_size, unsigned *mipmap_size)
+                             unsigned w0, unsigned h0, unsigned d0, unsigned bpe,
+                             unsigned pitch_align,
+                             unsigned *l0_size, unsigned *mipmap_size)
 {
        unsigned offset, i, level, face;
        unsigned width, height, depth, rowstride, size;
@@ -960,13 +1047,13 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels
                height = minify(h0, i);
                depth = minify(d0, i);
                for(face = 0; face < nfaces; face++) {
-                       rowstride = ((width * bpe) + 255) & ~255;
+                       rowstride = ALIGN((width * bpe), pitch_align);
                        size = height * rowstride * depth;
                        offset += size;
                        offset = (offset + 0x1f) & ~0x1f;
                }
        }
-       *l0_size = (((w0 * bpe) + 255) & ~255) * h0 * d0;
+       *l0_size = ALIGN((w0 * bpe), pitch_align) * h0 * d0;
        *mipmap_size = offset;
        if (!blevel)
                *mipmap_size -= *l0_size;
@@ -985,16 +1072,23 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels
  * the texture and mipmap bo object are big enough to cover this resource.
  */
 static inline int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 idx,
-                                               struct radeon_bo *texture,
-                                               struct radeon_bo *mipmap)
+                                             struct radeon_bo *texture,
+                                             struct radeon_bo *mipmap,
+                                             u32 tiling_flags)
 {
+       struct r600_cs_track *track = p->track;
        u32 nfaces, nlevels, blevel, w0, h0, d0, bpe = 0;
-       u32 word0, word1, l0_size, mipmap_size;
+       u32 word0, word1, l0_size, mipmap_size, pitch, pitch_align;
 
        /* on legacy kernel we don't perform advanced check */
        if (p->rdev == NULL)
                return 0;
+
        word0 = radeon_get_ib_value(p, idx + 0);
+       if (tiling_flags & RADEON_TILING_MACRO)
+               word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1);
+       else if (tiling_flags & RADEON_TILING_MICRO)
+               word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1);
        word1 = radeon_get_ib_value(p, idx + 1);
        w0 = G_038000_TEX_WIDTH(word0) + 1;
        h0 = G_038004_TEX_HEIGHT(word1) + 1;
@@ -1021,11 +1115,55 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 i
                         __func__, __LINE__, G_038004_DATA_FORMAT(word1));
                return -EINVAL;
        }
+
+       pitch = G_038000_PITCH(word0) + 1;
+       switch (G_038000_TILE_MODE(word0)) {
+       case V_038000_ARRAY_LINEAR_GENERAL:
+               pitch_align = 1;
+               /* XXX check height align */
+               break;
+       case V_038000_ARRAY_LINEAR_ALIGNED:
+               pitch_align = max((u32)64, (u32)(track->group_size / bpe)) / 8;
+               if (!IS_ALIGNED(pitch, pitch_align)) {
+                       dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n",
+                                __func__, __LINE__, pitch);
+                       return -EINVAL;
+               }
+               /* XXX check height align */
+               break;
+       case V_038000_ARRAY_1D_TILED_THIN1:
+               pitch_align = max((u32)8, (u32)(track->group_size / (8 * bpe))) / 8;
+               if (!IS_ALIGNED(pitch, pitch_align)) {
+                       dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n",
+                                __func__, __LINE__, pitch);
+                       return -EINVAL;
+               }
+               /* XXX check height align */
+               break;
+       case V_038000_ARRAY_2D_TILED_THIN1:
+               pitch_align = max((u32)track->nbanks,
+                                 (u32)(((track->group_size / 8) / bpe) * track->nbanks));
+               if (!IS_ALIGNED(pitch, pitch_align)) {
+                       dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n",
+                               __func__, __LINE__, pitch);
+                       return -EINVAL;
+               }
+               /* XXX check height align */
+               break;
+       default:
+               dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
+                        G_038000_TILE_MODE(word0), word0);
+               return -EINVAL;
+       }
+       /* XXX check offset align */
+
        word0 = radeon_get_ib_value(p, idx + 4);
        word1 = radeon_get_ib_value(p, idx + 5);
        blevel = G_038010_BASE_LEVEL(word0);
        nlevels = G_038014_LAST_LEVEL(word1);
-       r600_texture_size(nfaces, blevel, nlevels, w0, h0, d0, bpe, &l0_size, &mipmap_size);
+       r600_texture_size(nfaces, blevel, nlevels, w0, h0, d0, bpe,
+                         (pitch_align * bpe),
+                         &l0_size, &mipmap_size);
        /* using get ib will give us the offset into the texture bo */
        word0 = radeon_get_ib_value(p, idx + 2);
        if ((l0_size + word0) > radeon_bo_size(texture)) {
@@ -1239,6 +1377,10 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
                                        return -EINVAL;
                                }
                                ib[idx+1+(i*7)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+                               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
+                                       ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1);
+                               else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
+                                       ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1);
                                texture = reloc->robj;
                                /* tex mip base */
                                r = r600_cs_packet_next_reloc(p, &reloc);
@@ -1249,7 +1391,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
                                ib[idx+1+(i*7)+3] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
                                mipmap = reloc->robj;
                                r = r600_check_texture_resource(p,  idx+(i*7)+1,
-                                               texture, mipmap);
+                                                               texture, mipmap, reloc->lobj.tiling_flags);
                                if (r)
                                        return r;
                                break;
index 26b4bc9d89a574d048dfcfc190e5c11b2de341ee..e6a58ed48dcf255d70189306551d4bddc91db22e 100644 (file)
@@ -435,7 +435,8 @@ static int r600_hdmi_find_free_block(struct drm_device *dev)
                }
        }
 
-       if (rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690) {
+       if (rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690 ||
+           rdev->family == CHIP_RS740) {
                return free_blocks[0] ? R600_HDMI_BLOCK1 : 0;
        } else if (rdev->family >= CHIP_R600) {
                if (free_blocks[0])
@@ -466,7 +467,8 @@ static void r600_hdmi_assign_block(struct drm_encoder *encoder)
                if (ASIC_IS_DCE32(rdev))
                        radeon_encoder->hdmi_config_offset = dig->dig_encoder ?
                                R600_HDMI_CONFIG2 : R600_HDMI_CONFIG1;
-       } else if (rdev->family >= CHIP_R600) {
+       } else if (rdev->family >= CHIP_R600 || rdev->family == CHIP_RS600 ||
+                  rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) {
                radeon_encoder->hdmi_offset = r600_hdmi_find_free_block(dev);
        }
 }
index 59c1f8793e608df971466a9545ccc32c81e529fd..b7318ac4f84ab323f96e5f26d88eb280edfccc8a 100644 (file)
 #define        GRBM_SOFT_RESET                                 0x8020
 #define                SOFT_RESET_CP                                   (1<<0)
 
+#define        CG_THERMAL_STATUS                               0x7F4
+#define                ASIC_T(x)                               ((x) << 0)
+#define                ASIC_T_MASK                             0x1FF
+#define                ASIC_T_SHIFT                            0
+
 #define        HDP_HOST_PATH_CNTL                              0x2C00
 #define        HDP_NONSURFACE_BASE                             0x2C04
 #define        HDP_NONSURFACE_INFO                             0x2C08
 #define   S_038000_TILE_MODE(x)                        (((x) & 0xF) << 3)
 #define   G_038000_TILE_MODE(x)                        (((x) >> 3) & 0xF)
 #define   C_038000_TILE_MODE                           0xFFFFFF87
+#define     V_038000_ARRAY_LINEAR_GENERAL              0x00000000
+#define     V_038000_ARRAY_LINEAR_ALIGNED              0x00000001
+#define     V_038000_ARRAY_1D_TILED_THIN1              0x00000002
+#define     V_038000_ARRAY_2D_TILED_THIN1              0x00000004
 #define   S_038000_TILE_TYPE(x)                        (((x) & 0x1) << 7)
 #define   G_038000_TILE_TYPE(x)                        (((x) >> 7) & 0x1)
 #define   C_038000_TILE_TYPE                           0xFFFFFF7F
 #define   S_028010_ARRAY_MODE(x)                       (((x) & 0xF) << 15)
 #define   G_028010_ARRAY_MODE(x)                       (((x) >> 15) & 0xF)
 #define   C_028010_ARRAY_MODE                          0xFFF87FFF
+#define     V_028010_ARRAY_1D_TILED_THIN1              0x00000002
+#define     V_028010_ARRAY_2D_TILED_THIN1              0x00000004
 #define   S_028010_TILE_SURFACE_ENABLE(x)              (((x) & 0x1) << 25)
 #define   G_028010_TILE_SURFACE_ENABLE(x)              (((x) >> 25) & 0x1)
 #define   C_028010_TILE_SURFACE_ENABLE                 0xFDFFFFFF
index 2f94dc66c1836f4bf5d6814bb51b5730a13945ad..c84f9a311550ae7726709a8bd42258c5207e45cb 100644 (file)
@@ -178,6 +178,9 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev);
 void radeon_atombios_get_power_modes(struct radeon_device *rdev);
 void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level);
 void rs690_pm_info(struct radeon_device *rdev);
+extern u32 rv6xx_get_temp(struct radeon_device *rdev);
+extern u32 rv770_get_temp(struct radeon_device *rdev);
+extern u32 evergreen_get_temp(struct radeon_device *rdev);
 
 /*
  * Fences.
@@ -671,6 +674,13 @@ struct radeon_pm_profile {
        int dpms_on_cm_idx;
 };
 
+enum radeon_int_thermal_type {
+       THERMAL_TYPE_NONE,
+       THERMAL_TYPE_RV6XX,
+       THERMAL_TYPE_RV770,
+       THERMAL_TYPE_EVERGREEN,
+};
+
 struct radeon_voltage {
        enum radeon_voltage_type type;
        /* gpio voltage */
@@ -766,6 +776,9 @@ struct radeon_pm {
        enum radeon_pm_profile_type profile;
        int                     profile_index;
        struct radeon_pm_profile profiles[PM_PROFILE_MAX];
+       /* internal thermal controller on rv6xx+ */
+       enum radeon_int_thermal_type int_thermal_type;
+       struct device           *int_hwmon_dev;
 };
 
 
@@ -902,6 +915,7 @@ struct r600_asic {
        unsigned                tiling_nbanks;
        unsigned                tiling_npipes;
        unsigned                tiling_group_size;
+       unsigned                tile_config;
        struct r100_gpu_lockup  lockup;
 };
 
@@ -926,6 +940,7 @@ struct rv770_asic {
        unsigned                tiling_nbanks;
        unsigned                tiling_npipes;
        unsigned                tiling_group_size;
+       unsigned                tile_config;
        struct r100_gpu_lockup  lockup;
 };
 
@@ -951,6 +966,7 @@ struct evergreen_asic {
        unsigned tiling_nbanks;
        unsigned tiling_npipes;
        unsigned tiling_group_size;
+       unsigned tile_config;
 };
 
 union radeon_asic_config {
@@ -1033,6 +1049,9 @@ struct radeon_device {
        uint32_t                        pcie_reg_mask;
        radeon_rreg_t                   pciep_rreg;
        radeon_wreg_t                   pciep_wreg;
+       /* io port */
+       void __iomem                    *rio_mem;
+       resource_size_t                 rio_mem_size;
        struct radeon_clock             clock;
        struct radeon_mc                mc;
        struct radeon_gart              gart;
@@ -1069,6 +1088,7 @@ struct radeon_device {
        struct mutex vram_mutex;
 
        /* audio stuff */
+       bool                    audio_enabled;
        struct timer_list       audio_timer;
        int                     audio_channels;
        int                     audio_rate;
@@ -1114,6 +1134,26 @@ static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32
        }
 }
 
+static inline u32 r100_io_rreg(struct radeon_device *rdev, u32 reg)
+{
+       if (reg < rdev->rio_mem_size)
+               return ioread32(rdev->rio_mem + reg);
+       else {
+               iowrite32(reg, rdev->rio_mem + RADEON_MM_INDEX);
+               return ioread32(rdev->rio_mem + RADEON_MM_DATA);
+       }
+}
+
+static inline void r100_io_wreg(struct radeon_device *rdev, u32 reg, u32 v)
+{
+       if (reg < rdev->rio_mem_size)
+               iowrite32(v, rdev->rio_mem + reg);
+       else {
+               iowrite32(reg, rdev->rio_mem + RADEON_MM_INDEX);
+               iowrite32(v, rdev->rio_mem + RADEON_MM_DATA);
+       }
+}
+
 /*
  * Cast helper
  */
@@ -1152,6 +1192,8 @@ static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32
                WREG32_PLL(reg, tmp_);                          \
        } while (0)
 #define DREG32_SYS(sqf, rdev, reg) seq_printf((sqf), #reg " : 0x%08X\n", r100_mm_rreg((rdev), (reg)))
+#define RREG32_IO(reg) r100_io_rreg(rdev, (reg))
+#define WREG32_IO(reg, v) r100_io_wreg(rdev, (reg), (v))
 
 /*
  * Indirect registers accessor
@@ -1415,6 +1457,13 @@ extern void r700_cp_fini(struct radeon_device *rdev);
 extern void evergreen_disable_interrupt_state(struct radeon_device *rdev);
 extern int evergreen_irq_set(struct radeon_device *rdev);
 
+/* radeon_acpi.c */ 
+#if defined(CONFIG_ACPI) 
+extern int radeon_acpi_init(struct radeon_device *rdev); 
+#else 
+static inline int radeon_acpi_init(struct radeon_device *rdev) { return 0; } 
+#endif 
+
 /* evergreen */
 struct evergreen_mc_save {
        u32 vga_control[6];
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c
new file mode 100644 (file)
index 0000000..e366434
--- /dev/null
@@ -0,0 +1,67 @@
+#include <linux/pci.h>
+#include <linux/acpi.h>
+#include <linux/slab.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/acpi_bus.h>
+
+#include "drmP.h"
+#include "drm.h"
+#include "drm_sarea.h"
+#include "drm_crtc_helper.h"
+#include "radeon.h"
+
+#include <linux/vga_switcheroo.h>
+
+/* Call the ATIF method
+ *
+ * Note: currently we discard the output
+ */
+static int radeon_atif_call(acpi_handle handle)
+{
+       acpi_status status;
+       union acpi_object atif_arg_elements[2];
+       struct acpi_object_list atif_arg;
+       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
+
+       atif_arg.count = 2;
+       atif_arg.pointer = &atif_arg_elements[0];
+
+       atif_arg_elements[0].type = ACPI_TYPE_INTEGER;
+       atif_arg_elements[0].integer.value = 0;
+       atif_arg_elements[1].type = ACPI_TYPE_INTEGER;
+       atif_arg_elements[1].integer.value = 0;
+
+       status = acpi_evaluate_object(handle, "ATIF", &atif_arg, &buffer);
+
+       /* Fail only if calling the method fails and ATIF is supported */
+       if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+               printk(KERN_INFO "failed to evaluate ATIF got %s\n", acpi_format_exception(status));
+               kfree(buffer.pointer);
+               return 1;
+       }
+
+       kfree(buffer.pointer);
+       return 0;
+}
+
+/* Call all ACPI methods here */
+int radeon_acpi_init(struct radeon_device *rdev)
+{
+       acpi_handle handle;
+       int ret;
+
+       /* No need to proceed if we're sure that ATIF is not supported */
+       if (!ASIC_IS_AVIVO(rdev) || !rdev->bios)
+               return 0;
+
+       /* Get the device handle */
+       handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev);
+
+       /* Call the ATIF method */
+       ret = radeon_atif_call(handle);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
index c0bbaa64157a466efb81990431903dc8fbe2dc33..a5aff755f0d2e185dbdd4a1efd541dea5dae78fa 100644 (file)
@@ -113,6 +113,7 @@ void r100_wb_fini(struct radeon_device *rdev);
 int r100_wb_init(struct radeon_device *rdev);
 int r100_cp_reset(struct radeon_device *rdev);
 void r100_vga_render_disable(struct radeon_device *rdev);
+void r100_restore_sanity(struct radeon_device *rdev);
 int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
                                         struct radeon_cs_packet *pkt,
                                         struct radeon_bo *robj);
index 10673ae59cfa10ee8e408de3a9f84e54e2cab7ed..0a97aeb083ddd12bfeb9b542b9eaa6a1c2c7ed2c 100644 (file)
@@ -1789,14 +1789,22 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
                        }
 
                        /* add the i2c bus for thermal/fan chip */
-                       /* no support for internal controller yet */
                        if (controller->ucType > 0) {
-                               if ((controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) ||
-                                   (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) ||
-                                   (controller->ucType == ATOM_PP_THERMALCONTROLLER_EVERGREEN)) {
+                               if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) {
                                        DRM_INFO("Internal thermal controller %s fan control\n",
                                                 (controller->ucFanParameters &
                                                  ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
+                                       rdev->pm.int_thermal_type = THERMAL_TYPE_RV6XX;
+                               } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) {
+                                       DRM_INFO("Internal thermal controller %s fan control\n",
+                                                (controller->ucFanParameters &
+                                                 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
+                                       rdev->pm.int_thermal_type = THERMAL_TYPE_RV770;
+                               } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_EVERGREEN) {
+                                       DRM_INFO("Internal thermal controller %s fan control\n",
+                                                (controller->ucFanParameters &
+                                                 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
+                                       rdev->pm.int_thermal_type = THERMAL_TYPE_EVERGREEN;
                                } else if ((controller->ucType ==
                                            ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) ||
                                           (controller->ucType ==
index 2c92137399995f17d9df664c2ae28aa9ad8bbefa..654787ec43f4d33687f2c7dd0e0318c17be92dd6 100644 (file)
@@ -53,7 +53,7 @@ static bool igp_read_bios_from_vram(struct radeon_device *rdev)
                        return false;
 
        rdev->bios = NULL;
-       vram_base = drm_get_resource_start(rdev->ddev, 0);
+       vram_base = pci_resource_start(rdev->pdev, 0);
        bios = ioremap(vram_base, size);
        if (!bios) {
                return false;
index 2417d7b06fdb6dae3a6f486fad9a37a6e967b4ed..5e45cb27eb988cc5f38268adc86fef3ede1a59b2 100644 (file)
@@ -2941,9 +2941,8 @@ static void combios_write_ram_size(struct drm_device *dev)
                if (rev < 3) {
                        mem_cntl = RBIOS32(offset + 1);
                        mem_size = RBIOS16(offset + 5);
-                       if (((rdev->flags & RADEON_FAMILY_MASK) < CHIP_R200) &&
-                           ((dev->pdev->device != 0x515e)
-                            && (dev->pdev->device != 0x5969)))
+                       if ((rdev->family < CHIP_R200) &&
+                           !ASIC_IS_RN50(rdev))
                                WREG32(RADEON_MEM_CNTL, mem_cntl);
                }
        }
@@ -2954,10 +2953,8 @@ static void combios_write_ram_size(struct drm_device *dev)
                if (offset) {
                        rev = RBIOS8(offset - 1);
                        if (rev < 1) {
-                               if (((rdev->flags & RADEON_FAMILY_MASK) <
-                                    CHIP_R200)
-                                   && ((dev->pdev->device != 0x515e)
-                                       && (dev->pdev->device != 0x5969))) {
+                               if ((rdev->family < CHIP_R200)
+                                   && !ASIC_IS_RN50(rdev)) {
                                        int ram = 0;
                                        int mem_addr_mapping = 0;
 
index 2f042a3c0e62bb7bbe86fefa478109be033f1bb8..eb6b9eed7349264f29e5f498221b127942f51ec2 100644 (file)
@@ -2120,8 +2120,8 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
        else
                dev_priv->flags |= RADEON_IS_PCI;
 
-       ret = drm_addmap(dev, drm_get_resource_start(dev, 2),
-                        drm_get_resource_len(dev, 2), _DRM_REGISTERS,
+       ret = drm_addmap(dev, pci_resource_start(dev->pdev, 2),
+                        pci_resource_len(dev->pdev, 2), _DRM_REGISTERS,
                         _DRM_READ_ONLY | _DRM_DRIVER, &dev_priv->mmio);
        if (ret != 0)
                return ret;
@@ -2194,9 +2194,9 @@ int radeon_driver_firstopen(struct drm_device *dev)
 
        dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE;
 
-       dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0);
+       dev_priv->fb_aper_offset = pci_resource_start(dev->pdev, 0);
        ret = drm_addmap(dev, dev_priv->fb_aper_offset,
-                        drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER,
+                        pci_resource_len(dev->pdev, 0), _DRM_FRAME_BUFFER,
                         _DRM_WRITE_COMBINING, &map);
        if (ret != 0)
                return ret;
index dd279da90546ee03929b02b8bd7095683ef31caf..0fea894fc1271d428759b26fb8642a22b8394a71 100644 (file)
@@ -415,6 +415,22 @@ static uint32_t cail_reg_read(struct card_info *info, uint32_t reg)
        return r;
 }
 
+static void cail_ioreg_write(struct card_info *info, uint32_t reg, uint32_t val)
+{
+       struct radeon_device *rdev = info->dev->dev_private;
+
+       WREG32_IO(reg*4, val);
+}
+
+static uint32_t cail_ioreg_read(struct card_info *info, uint32_t reg)
+{
+       struct radeon_device *rdev = info->dev->dev_private;
+       uint32_t r;
+
+       r = RREG32_IO(reg*4);
+       return r;
+}
+
 int radeon_atombios_init(struct radeon_device *rdev)
 {
        struct card_info *atom_card_info =
@@ -427,6 +443,15 @@ int radeon_atombios_init(struct radeon_device *rdev)
        atom_card_info->dev = rdev->ddev;
        atom_card_info->reg_read = cail_reg_read;
        atom_card_info->reg_write = cail_reg_write;
+       /* needed for iio ops */
+       if (rdev->rio_mem) {
+               atom_card_info->ioreg_read = cail_ioreg_read;
+               atom_card_info->ioreg_write = cail_ioreg_write;
+       } else {
+               DRM_ERROR("Unable to find PCI I/O BAR; using MMIO for ATOM IIO\n");
+               atom_card_info->ioreg_read = cail_reg_read;
+               atom_card_info->ioreg_write = cail_reg_write;
+       }
        atom_card_info->mc_read = cail_mc_read;
        atom_card_info->mc_write = cail_mc_write;
        atom_card_info->pll_read = cail_pll_read;
@@ -573,7 +598,7 @@ int radeon_device_init(struct radeon_device *rdev,
                       struct pci_dev *pdev,
                       uint32_t flags)
 {
-       int r;
+       int r, i;
        int dma_bits;
 
        rdev->shutdown = false;
@@ -650,8 +675,8 @@ int radeon_device_init(struct radeon_device *rdev,
 
        /* Registers mapping */
        /* TODO: block userspace mapping of io register */
-       rdev->rmmio_base = drm_get_resource_start(rdev->ddev, 2);
-       rdev->rmmio_size = drm_get_resource_len(rdev->ddev, 2);
+       rdev->rmmio_base = pci_resource_start(rdev->pdev, 2);
+       rdev->rmmio_size = pci_resource_len(rdev->pdev, 2);
        rdev->rmmio = ioremap(rdev->rmmio_base, rdev->rmmio_size);
        if (rdev->rmmio == NULL) {
                return -ENOMEM;
@@ -659,6 +684,17 @@ int radeon_device_init(struct radeon_device *rdev,
        DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)rdev->rmmio_base);
        DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size);
 
+       /* io port mapping */
+       for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+               if (pci_resource_flags(rdev->pdev, i) & IORESOURCE_IO) {
+                       rdev->rio_mem_size = pci_resource_len(rdev->pdev, i);
+                       rdev->rio_mem = pci_iomap(rdev->pdev, i, rdev->rio_mem_size);
+                       break;
+               }
+       }
+       if (rdev->rio_mem == NULL)
+               DRM_ERROR("Unable to find PCI I/O BAR\n");
+
        /* if we have > 1 VGA cards, then disable the radeon VGA resources */
        /* this will fail for cards that aren't VGA class devices, just
         * ignore it */
@@ -701,6 +737,8 @@ void radeon_device_fini(struct radeon_device *rdev)
        destroy_workqueue(rdev->wq);
        vga_switcheroo_unregister_client(rdev->pdev);
        vga_client_register(rdev->pdev, NULL, NULL, NULL);
+       pci_iounmap(rdev->pdev, rdev->rio_mem);
+       rdev->rio_mem = NULL;
        iounmap(rdev->rmmio);
        rdev->rmmio = NULL;
 }
index 8154cdf796e4a752a0a33d6983852cabee7acf4a..a68728dbd41dd2db8e4b2d4d66b305f022e54f06 100644 (file)
@@ -558,15 +558,17 @@ static void radeon_compute_pll_legacy(struct radeon_pll *pll,
                                        current_freq = radeon_div(tmp, ref_div * post_div);
 
                                        if (pll->flags & RADEON_PLL_PREFER_CLOSEST_LOWER) {
-                                               error = freq - current_freq;
-                                               error = error < 0 ? 0xffffffff : error;
+                                               if (freq < current_freq)
+                                                       error = 0xffffffff;
+                                               else
+                                                       error = freq - current_freq;
                                        } else
                                                error = abs(current_freq - freq);
                                        vco_diff = abs(vco - best_vco);
 
                                        if ((best_vco == 0 && error < best_error) ||
                                            (best_vco != 0 &&
-                                            (error < best_error - 100 ||
+                                            ((best_error > 100 && error < best_error - 100) ||
                                              (abs(error - best_error) < 100 && vco_diff < best_vco_diff)))) {
                                                best_post_div = post_div;
                                                best_ref_div = ref_div;
index e166fe4d7c308f55ab451a710687a679dcf8720f..6f8a2e5728781acab115c2d014e4763b569354a2 100644 (file)
  * - 2.3.0 - add MSPOS + 3D texture + r500 VAP regs
  * - 2.4.0 - add crtc id query
  * - 2.5.0 - add get accel 2 to work around ddx breakage for evergreen
+ * - 2.6.0 - add tiling config query (r6xx+)
  */
 #define KMS_DRIVER_MAJOR       2
-#define KMS_DRIVER_MINOR       5
+#define KMS_DRIVER_MINOR       6
 #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);
@@ -238,7 +239,7 @@ static struct drm_driver kms_driver;
 static int __devinit
 radeon_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-       return drm_get_dev(pdev, ent, &kms_driver);
+       return drm_get_pci_dev(pdev, ent, &kms_driver);
 }
 
 static void
index ab389f89fa8df7fca6af0a3ca9197c0102dc39f4..8931c8e78101fbaa53343b8aeca47ed9e21b57c3 100644 (file)
@@ -49,7 +49,7 @@ int radeon_driver_unload_kms(struct drm_device *dev)
 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
 {
        struct radeon_device *rdev;
-       int r;
+       int r, acpi_status;
 
        rdev = kzalloc(sizeof(struct radeon_device), GFP_KERNEL);
        if (rdev == NULL) {
@@ -77,6 +77,12 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
                dev_err(&dev->pdev->dev, "Fatal error during GPU init\n");
                goto out;
        }
+
+       /* Call ACPI methods */
+       acpi_status = radeon_acpi_init(rdev);
+       if (acpi_status)
+               dev_err(&dev->pdev->dev, "Error during ACPI methods call\n");
+
        /* Again modeset_init should fail only on fatal error
         * otherwise it should provide enough functionalities
         * for shadowfb to run
@@ -142,6 +148,18 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
        case RADEON_INFO_ACCEL_WORKING2:
                value = rdev->accel_working;
                break;
+       case RADEON_INFO_TILING_CONFIG:
+               if (rdev->family >= CHIP_CEDAR)
+                       value = rdev->config.evergreen.tile_config;
+               else if (rdev->family >= CHIP_RV770)
+                       value = rdev->config.rv770.tile_config;
+               else if (rdev->family >= CHIP_R600)
+                       value = rdev->config.r600.tile_config;
+               else {
+                       DRM_DEBUG("tiling config is r6xx+ only!\n");
+                       return -EINVAL;
+               }
+               break;
        default:
                DRM_DEBUG("Invalid request %d\n", info->request);
                return -EINVAL;
index d5b9373ce06c16b9be8ee81b9f27d70b20947a19..0afd1e62347dcfb9670d20e13a818d8d7a99b59c 100644 (file)
@@ -110,6 +110,7 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj,
        bo->surface_reg = -1;
        INIT_LIST_HEAD(&bo->list);
 
+retry:
        radeon_ttm_placement_from_domain(bo, domain);
        /* Kernel allocation are uninterruptible */
        mutex_lock(&rdev->vram_mutex);
@@ -118,10 +119,15 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj,
                        &radeon_ttm_bo_destroy);
        mutex_unlock(&rdev->vram_mutex);
        if (unlikely(r != 0)) {
-               if (r != -ERESTARTSYS)
+               if (r != -ERESTARTSYS) {
+                       if (domain == RADEON_GEM_DOMAIN_VRAM) {
+                               domain |= RADEON_GEM_DOMAIN_GTT;
+                               goto retry;
+                       }
                        dev_err(rdev->dev,
                                "object_init failed for (%lu, 0x%08X)\n",
                                size, domain);
+               }
                return r;
        }
        *bo_ptr = bo;
@@ -321,6 +327,7 @@ int radeon_bo_list_validate(struct list_head *head)
 {
        struct radeon_bo_list *lobj;
        struct radeon_bo *bo;
+       u32 domain;
        int r;
 
        list_for_each_entry(lobj, head, list) {
@@ -333,17 +340,19 @@ int radeon_bo_list_validate(struct list_head *head)
        list_for_each_entry(lobj, head, list) {
                bo = lobj->bo;
                if (!bo->pin_count) {
-                       if (lobj->wdomain) {
-                               radeon_ttm_placement_from_domain(bo,
-                                                               lobj->wdomain);
-                       } else {
-                               radeon_ttm_placement_from_domain(bo,
-                                                               lobj->rdomain);
-                       }
+                       domain = lobj->wdomain ? lobj->wdomain : lobj->rdomain;
+                       
+               retry:
+                       radeon_ttm_placement_from_domain(bo, domain);
                        r = ttm_bo_validate(&bo->tbo, &bo->placement,
                                                true, false, false);
-                       if (unlikely(r))
+                       if (unlikely(r)) {
+                               if (r != -ERESTARTSYS && domain == RADEON_GEM_DOMAIN_VRAM) {
+                                       domain |= RADEON_GEM_DOMAIN_GTT;
+                                       goto retry;
+                               }
                                return r;
+                       }
                }
                lobj->gpu_offset = radeon_bo_gpu_offset(bo);
                lobj->tiling_flags = bo->tiling_flags;
index 115d26b762cc2b3db9301c86e66d97505f6fd291..ed66062ae9d0044601e843a2caa937559d361d78 100644 (file)
@@ -27,6 +27,8 @@
 #include <linux/acpi.h>
 #endif
 #include <linux/power_supply.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
 
 #define RADEON_IDLE_LOOP_MS 100
 #define RADEON_RECLOCK_DELAY_MS 200
@@ -423,6 +425,82 @@ fail:
 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);
 
+static ssize_t radeon_hwmon_show_temp(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;
+       u32 temp;
+
+       switch (rdev->pm.int_thermal_type) {
+       case THERMAL_TYPE_RV6XX:
+               temp = rv6xx_get_temp(rdev);
+               break;
+       case THERMAL_TYPE_RV770:
+               temp = rv770_get_temp(rdev);
+               break;
+       case THERMAL_TYPE_EVERGREEN:
+               temp = evergreen_get_temp(rdev);
+               break;
+       default:
+               temp = 0;
+               break;
+       }
+
+       return snprintf(buf, PAGE_SIZE, "%d\n", temp);
+}
+
+static ssize_t radeon_hwmon_show_name(struct device *dev,
+                                     struct device_attribute *attr,
+                                     char *buf)
+{
+       return sprintf(buf, "radeon\n");
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, radeon_hwmon_show_temp, NULL, 0);
+static SENSOR_DEVICE_ATTR(name, S_IRUGO, radeon_hwmon_show_name, NULL, 0);
+
+static struct attribute *hwmon_attributes[] = {
+       &sensor_dev_attr_temp1_input.dev_attr.attr,
+       &sensor_dev_attr_name.dev_attr.attr,
+       NULL
+};
+
+static const struct attribute_group hwmon_attrgroup = {
+       .attrs = hwmon_attributes,
+};
+
+static void radeon_hwmon_init(struct radeon_device *rdev)
+{
+       int err;
+
+       rdev->pm.int_hwmon_dev = NULL;
+
+       switch (rdev->pm.int_thermal_type) {
+       case THERMAL_TYPE_RV6XX:
+       case THERMAL_TYPE_RV770:
+       case THERMAL_TYPE_EVERGREEN:
+               rdev->pm.int_hwmon_dev = hwmon_device_register(rdev->dev);
+               dev_set_drvdata(rdev->pm.int_hwmon_dev, rdev->ddev);
+               err = sysfs_create_group(&rdev->pm.int_hwmon_dev->kobj,
+                                        &hwmon_attrgroup);
+               if (err)
+                       DRM_ERROR("Unable to create hwmon sysfs file: %d\n", err);
+               break;
+       default:
+               break;
+       }
+}
+
+static void radeon_hwmon_fini(struct radeon_device *rdev)
+{
+       if (rdev->pm.int_hwmon_dev) {
+               sysfs_remove_group(&rdev->pm.int_hwmon_dev->kobj, &hwmon_attrgroup);
+               hwmon_device_unregister(rdev->pm.int_hwmon_dev);
+       }
+}
+
 void radeon_pm_suspend(struct radeon_device *rdev)
 {
        bool flush_wq = false;
@@ -470,6 +548,7 @@ int radeon_pm_init(struct radeon_device *rdev)
        rdev->pm.dynpm_can_downclock = true;
        rdev->pm.current_sclk = rdev->clock.default_sclk;
        rdev->pm.current_mclk = rdev->clock.default_mclk;
+       rdev->pm.int_thermal_type = THERMAL_TYPE_NONE;
 
        if (rdev->bios) {
                if (rdev->is_atom_bios)
@@ -480,6 +559,8 @@ int radeon_pm_init(struct radeon_device *rdev)
                radeon_pm_init_profile(rdev);
        }
 
+       /* set up the internal thermal sensor if applicable */
+       radeon_hwmon_init(rdev);
        if (rdev->pm.num_power_states > 1) {
                /* where's the best place to put these? */
                ret = device_create_file(rdev->dev, &dev_attr_power_profile);
@@ -535,6 +616,7 @@ void radeon_pm_fini(struct radeon_device *rdev)
 #endif
        }
 
+       radeon_hwmon_fini(rdev);
        if (rdev->pm.i2c_bus)
                radeon_i2c_destroy(rdev->pm.i2c_bus);
 }
index f454c9a5e7f22269a9ffe0618d87f1a74e05f276..037b93a1b373172ed0f60291c95f47f725182bac 100644 (file)
@@ -483,6 +483,8 @@ int rs400_init(struct radeon_device *rdev)
        /* Initialize surface registers */
        radeon_surface_init(rdev);
        /* TODO: disable VGA need to use VGA request */
+       /* restore some register to sane defaults */
+       r100_restore_sanity(rdev);
        /* BIOS*/
        if (!radeon_get_bios(rdev)) {
                if (ASIC_IS_AVIVO(rdev))
index 6dc15ea8ba33ce088f273b17eea0f1fc42e537df..85cd911952c1715eb0165393bb842ed142bb51dd 100644 (file)
@@ -686,8 +686,8 @@ void rs600_mc_init(struct radeon_device *rdev)
 {
        u64 base;
 
-       rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
-       rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
+       rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
+       rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
        rdev->mc.vram_is_ddr = true;
        rdev->mc.vram_width = 128;
        rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE);
@@ -813,6 +813,13 @@ static int rs600_startup(struct radeon_device *rdev)
                dev_err(rdev->dev, "failled initializing IB (%d).\n", r);
                return r;
        }
+
+       r = r600_audio_init(rdev);
+       if (r) {
+               dev_err(rdev->dev, "failed initializing audio\n");
+               return r;
+       }
+
        return 0;
 }
 
@@ -839,6 +846,7 @@ int rs600_resume(struct radeon_device *rdev)
 
 int rs600_suspend(struct radeon_device *rdev)
 {
+       r600_audio_fini(rdev);
        r100_cp_disable(rdev);
        r100_wb_disable(rdev);
        rs600_irq_disable(rdev);
@@ -848,6 +856,7 @@ int rs600_suspend(struct radeon_device *rdev)
 
 void rs600_fini(struct radeon_device *rdev)
 {
+       r600_audio_fini(rdev);
        r100_cp_fini(rdev);
        r100_wb_fini(rdev);
        r100_ib_fini(rdev);
@@ -871,6 +880,8 @@ int rs600_init(struct radeon_device *rdev)
        radeon_scratch_init(rdev);
        /* Initialize surface registers */
        radeon_surface_init(rdev);
+       /* restore some register to sane defaults */
+       r100_restore_sanity(rdev);
        /* BIOS */
        if (!radeon_get_bios(rdev)) {
                if (ASIC_IS_AVIVO(rdev))
index ce4ecbe108163126c74fb14779eaf90dcf15ce41..f3a8c9344c64b27600bed94bbe9c81a7bfc9f6f7 100644 (file)
@@ -154,8 +154,8 @@ void rs690_mc_init(struct radeon_device *rdev)
        rdev->mc.vram_width = 128;
        rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE);
        rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
-       rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
-       rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
+       rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
+       rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
        rdev->mc.visible_vram_size = rdev->mc.aper_size;
        base = RREG32_MC(R_000100_MCCFG_FB_LOCATION);
        base = G_000100_MC_FB_START(base) << 16;
@@ -641,6 +641,13 @@ static int rs690_startup(struct radeon_device *rdev)
                dev_err(rdev->dev, "failled initializing IB (%d).\n", r);
                return r;
        }
+
+       r = r600_audio_init(rdev);
+       if (r) {
+               dev_err(rdev->dev, "failed initializing audio\n");
+               return r;
+       }
+
        return 0;
 }
 
@@ -667,6 +674,7 @@ int rs690_resume(struct radeon_device *rdev)
 
 int rs690_suspend(struct radeon_device *rdev)
 {
+       r600_audio_fini(rdev);
        r100_cp_disable(rdev);
        r100_wb_disable(rdev);
        rs600_irq_disable(rdev);
@@ -676,6 +684,7 @@ int rs690_suspend(struct radeon_device *rdev)
 
 void rs690_fini(struct radeon_device *rdev)
 {
+       r600_audio_fini(rdev);
        r100_cp_fini(rdev);
        r100_wb_fini(rdev);
        r100_ib_fini(rdev);
@@ -699,6 +708,8 @@ int rs690_init(struct radeon_device *rdev)
        radeon_scratch_init(rdev);
        /* Initialize surface registers */
        radeon_surface_init(rdev);
+       /* restore some register to sane defaults */
+       r100_restore_sanity(rdev);
        /* TODO: disable VGA need to use VGA request */
        /* BIOS*/
        if (!radeon_get_bios(rdev)) {
index 0c9c169a6852f453c6703901cd64dc2fb84699e9..b951b8790175eb5c82e76f21cbfb8a8e44411c6c 100644 (file)
@@ -469,6 +469,8 @@ int rv515_init(struct radeon_device *rdev)
        /* Initialize surface registers */
        radeon_surface_init(rdev);
        /* TODO: disable VGA need to use VGA request */
+       /* restore some register to sane defaults */
+       r100_restore_sanity(rdev);
        /* BIOS*/
        if (!radeon_get_bios(rdev)) {
                if (ASIC_IS_AVIVO(rdev))
index b7fd82064922342d420cacb56a7ece8a00964393..236fe66819222e0b7234cc6e9f8a2b9940dd0d59 100644 (file)
 static void rv770_gpu_init(struct radeon_device *rdev);
 void rv770_fini(struct radeon_device *rdev);
 
+/* get temperature in millidegrees */
+u32 rv770_get_temp(struct radeon_device *rdev)
+{
+       u32 temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >>
+               ASIC_T_SHIFT;
+       u32 actual_temp = 0;
+
+       if ((temp >> 9) & 1)
+               actual_temp = 0;
+       else
+               actual_temp = (temp >> 1) & 0xff;
+
+       return actual_temp * 1000;
+}
+
 void rv770_pm_misc(struct radeon_device *rdev)
 {
        int req_ps_idx = rdev->pm.requested_power_state_index;
@@ -659,8 +674,9 @@ static void rv770_gpu_init(struct radeon_device *rdev)
                                                                 r600_count_pipe_bits((cc_rb_backend_disable &
                                                                                       R7XX_MAX_BACKENDS_MASK) >> 16)),
                                                                (cc_rb_backend_disable >> 16));
-       gb_tiling_config |= BACKEND_MAP(backend_map);
 
+       rdev->config.rv770.tile_config = gb_tiling_config;
+       gb_tiling_config |= BACKEND_MAP(backend_map);
 
        WREG32(GB_TILING_CONFIG, gb_tiling_config);
        WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff));
@@ -919,8 +935,8 @@ int rv770_mc_init(struct radeon_device *rdev)
        }
        rdev->mc.vram_width = numchan * chansize;
        /* Could aper size report 0 ? */
-       rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
-       rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
+       rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
+       rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
        /* Setup GPU memory space */
        rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
        rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
index 9506f8cb99e0552a295bef5bd60dfba49bfaaee0..fd733f268e3d605b1deaad2da851c954ea183fbb 100644 (file)
 #define                GUI_ACTIVE                                      (1<<31)
 #define        GRBM_STATUS2                                    0x8014
 
+#define        CG_MULT_THERMAL_STATUS                          0x740
+#define                ASIC_T(x)                               ((x) << 16)
+#define                ASIC_T_MASK                             0x3FF0000
+#define                ASIC_T_SHIFT                            16
+
 #define        HDP_HOST_PATH_CNTL                              0x2C00
 #define        HDP_NONSURFACE_BASE                             0x2C04
 #define        HDP_NONSURFACE_INFO                             0x2C08
index 2d0c9ca484c519bd9797b2a1f7917abca015a33d..f576232846c3540c49f32ae88645076843bd0c30 100644 (file)
@@ -573,13 +573,13 @@ int savage_driver_firstopen(struct drm_device *dev)
        dev_priv->mtrr[2].handle = -1;
        if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
                fb_rsrc = 0;
-               fb_base = drm_get_resource_start(dev, 0);
+               fb_base = pci_resource_start(dev->pdev, 0);
                fb_size = SAVAGE_FB_SIZE_S3;
                mmio_base = fb_base + SAVAGE_FB_SIZE_S3;
                aper_rsrc = 0;
                aperture_base = fb_base + SAVAGE_APERTURE_OFFSET;
                /* this should always be true */
-               if (drm_get_resource_len(dev, 0) == 0x08000000) {
+               if (pci_resource_len(dev->pdev, 0) == 0x08000000) {
                        /* Don't make MMIO write-cobining! We need 3
                         * MTRRs. */
                        dev_priv->mtrr[0].base = fb_base;
@@ -599,18 +599,19 @@ int savage_driver_firstopen(struct drm_device *dev)
                                         dev_priv->mtrr[2].size, DRM_MTRR_WC);
                } else {
                        DRM_ERROR("strange pci_resource_len %08llx\n",
-                                 (unsigned long long)drm_get_resource_len(dev, 0));
+                                 (unsigned long long)
+                                 pci_resource_len(dev->pdev, 0));
                }
        } else if (dev_priv->chipset != S3_SUPERSAVAGE &&
                   dev_priv->chipset != S3_SAVAGE2000) {
-               mmio_base = drm_get_resource_start(dev, 0);
+               mmio_base = pci_resource_start(dev->pdev, 0);
                fb_rsrc = 1;
-               fb_base = drm_get_resource_start(dev, 1);
+               fb_base = pci_resource_start(dev->pdev, 1);
                fb_size = SAVAGE_FB_SIZE_S4;
                aper_rsrc = 1;
                aperture_base = fb_base + SAVAGE_APERTURE_OFFSET;
                /* this should always be true */
-               if (drm_get_resource_len(dev, 1) == 0x08000000) {
+               if (pci_resource_len(dev->pdev, 1) == 0x08000000) {
                        /* Can use one MTRR to cover both fb and
                         * aperture. */
                        dev_priv->mtrr[0].base = fb_base;
@@ -620,15 +621,16 @@ int savage_driver_firstopen(struct drm_device *dev)
                                         dev_priv->mtrr[0].size, DRM_MTRR_WC);
                } else {
                        DRM_ERROR("strange pci_resource_len %08llx\n",
-                                 (unsigned long long)drm_get_resource_len(dev, 1));
+                                 (unsigned long long)
+                                 pci_resource_len(dev->pdev, 1));
                }
        } else {
-               mmio_base = drm_get_resource_start(dev, 0);
+               mmio_base = pci_resource_start(dev->pdev, 0);
                fb_rsrc = 1;
-               fb_base = drm_get_resource_start(dev, 1);
-               fb_size = drm_get_resource_len(dev, 1);
+               fb_base = pci_resource_start(dev->pdev, 1);
+               fb_size = pci_resource_len(dev->pdev, 1);
                aper_rsrc = 2;
-               aperture_base = drm_get_resource_start(dev, 2);
+               aperture_base = pci_resource_start(dev->pdev, 2);
                /* Automatic MTRR setup will do the right thing. */
        }
 
index 555ebb12ace83dae496fbf41e357bc29c954542d..9763288c6b2d300f355f2bba367a405a7bd859f1 100644 (file)
@@ -476,7 +476,6 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all)
                        ++put_count;
                }
                if (bo->mem.mm_node) {
-                       bo->mem.mm_node->private = NULL;
                        drm_mm_put_block(bo->mem.mm_node);
                        bo->mem.mm_node = NULL;
                }
@@ -670,7 +669,6 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, bool interruptible,
                        printk(KERN_ERR TTM_PFX "Buffer eviction failed\n");
                spin_lock(&glob->lru_lock);
                if (evict_mem.mm_node) {
-                       evict_mem.mm_node->private = NULL;
                        drm_mm_put_block(evict_mem.mm_node);
                        evict_mem.mm_node = NULL;
                }
@@ -929,8 +927,6 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
                mem->mm_node = node;
                mem->mem_type = mem_type;
                mem->placement = cur_flags;
-               if (node)
-                       node->private = bo;
                return 0;
        }
 
@@ -973,7 +969,6 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
                                                interruptible, no_wait_reserve, no_wait_gpu);
                if (ret == 0 && mem->mm_node) {
                        mem->placement = cur_flags;
-                       mem->mm_node->private = bo;
                        return 0;
                }
                if (ret == -ERESTARTSYS)
@@ -1029,7 +1024,6 @@ int ttm_bo_move_buffer(struct ttm_buffer_object *bo,
 out_unlock:
        if (ret && mem.mm_node) {
                spin_lock(&glob->lru_lock);
-               mem.mm_node->private = NULL;
                drm_mm_put_block(mem.mm_node);
                spin_unlock(&glob->lru_lock);
        }
index 13012a1f1486c1bf4cad58608068f27b667b2335..7cffb3e0423249ec4f78f7c7cbdc72b6df921e50 100644 (file)
@@ -353,8 +353,6 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
        fbo->vm_node = NULL;
 
        fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj);
-       if (fbo->mem.mm_node)
-               fbo->mem.mm_node->private = (void *)fbo;
        kref_init(&fbo->list_kref);
        kref_init(&fbo->kref);
        fbo->destroy = &ttm_transfered_destroy;
index b793c8c9acb3162049fabe03b7cf43cfab1939fb..9dd395b90216b17c54598c9309502785a2684220 100644 (file)
@@ -764,7 +764,7 @@ static struct drm_driver driver = {
 
 static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-       return drm_get_dev(pdev, ent, &driver);
+       return drm_get_pci_dev(pdev, ent, &driver);
 }
 
 static int __init vmwgfx_init(void)
index c1b987158dfa20c19285e59533c40b2aa5ebb0b2..04b564bfc4a1f0084a9c6cd60e52af03ba930764 100644 (file)
@@ -9,6 +9,7 @@
 /*
  * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * Copyright (c) 2009-2010, Code Aurora Forum.
  * All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -48,6 +49,7 @@
 #include <linux/proc_fs.h>
 #include <linux/init.h>
 #include <linux/file.h>
+#include <linux/platform_device.h>
 #include <linux/pci.h>
 #include <linux/jiffies.h>
 #include <linux/smp_lock.h>    /* For (un)lock_kernel */
@@ -144,6 +146,7 @@ extern void drm_ut_debug_printk(unsigned int request_level,
 #define DRIVER_IRQ_VBL2    0x800
 #define DRIVER_GEM         0x1000
 #define DRIVER_MODESET     0x2000
+#define DRIVER_USE_PLATFORM_DEVICE  0x4000
 
 /***********************************************************************/
 /** \name Begin the DRM... */
@@ -403,6 +406,8 @@ struct drm_pending_event {
        struct drm_event *event;
        struct list_head link;
        struct drm_file *file_priv;
+       pid_t pid; /* pid of requester, no guarantee it's valid by the time
+                     we deliver the event, for tracing only */
        void (*destroy)(struct drm_pending_event *event);
 };
 
@@ -823,6 +828,7 @@ struct drm_driver {
        int num_ioctls;
        struct file_operations fops;
        struct pci_driver pci_driver;
+       struct platform_device *platform_device;
        /* List of devices hanging off this driver */
        struct list_head device_list;
 };
@@ -1015,12 +1021,16 @@ struct drm_device {
 
        struct drm_agp_head *agp;       /**< AGP data */
 
+       struct device *dev;             /**< Device structure */
        struct pci_dev *pdev;           /**< PCI device structure */
        int pci_vendor;                 /**< PCI vendor id */
        int pci_device;                 /**< PCI device id */
 #ifdef __alpha__
        struct pci_controller *hose;
 #endif
+
+       struct platform_device *platformdev; /**< Platform device struture */
+
        struct drm_sg_mem *sg;  /**< Scatter gather memory */
        int num_crtcs;                  /**< Number of CRTCs on this device */
        void *dev_private;              /**< device private data */
@@ -1060,17 +1070,21 @@ struct drm_device {
 
 };
 
-static inline int drm_dev_to_irq(struct drm_device *dev)
-{
-       return dev->pdev->irq;
-}
-
 static __inline__ int drm_core_check_feature(struct drm_device *dev,
                                             int feature)
 {
        return ((dev->driver->driver_features & feature) ? 1 : 0);
 }
 
+
+static inline int drm_dev_to_irq(struct drm_device *dev)
+{
+       if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE))
+               return platform_get_irq(dev->platformdev, 0);
+       else
+               return dev->pdev->irq;
+}
+
 #ifdef __alpha__
 #define drm_get_pci_domain(dev) dev->hose->index
 #else
@@ -1273,10 +1287,6 @@ extern int drm_freebufs(struct drm_device *dev, void *data,
 extern int drm_mapbufs(struct drm_device *dev, void *data,
                       struct drm_file *file_priv);
 extern int drm_order(unsigned long size);
-extern resource_size_t drm_get_resource_start(struct drm_device *dev,
-                                             unsigned int resource);
-extern resource_size_t drm_get_resource_len(struct drm_device *dev,
-                                           unsigned int resource);
 
                                /* DMA support (drm_dma.h) */
 extern int drm_dma_setup(struct drm_device *dev);
@@ -1351,8 +1361,11 @@ extern int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
 struct drm_master *drm_master_create(struct drm_minor *minor);
 extern struct drm_master *drm_master_get(struct drm_master *master);
 extern void drm_master_put(struct drm_master **master);
-extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
-                      struct drm_driver *driver);
+extern int drm_get_pci_dev(struct pci_dev *pdev,
+                          const struct pci_device_id *ent,
+                          struct drm_driver *driver);
+extern int drm_get_platform_dev(struct platform_device *pdev,
+                               struct drm_driver *driver);
 extern void drm_put_dev(struct drm_device *dev);
 extern int drm_put_minor(struct drm_minor **minor);
 extern unsigned int drm_debug;
@@ -1529,6 +1542,9 @@ static __inline__ struct drm_local_map *drm_core_findmap(struct drm_device *dev,
 
 static __inline__ int drm_device_is_agp(struct drm_device *dev)
 {
+       if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE))
+               return 0;
+
        if (dev->driver->device_is_agp != NULL) {
                int err = (*dev->driver->device_is_agp) (dev);
 
@@ -1542,7 +1558,10 @@ static __inline__ int drm_device_is_agp(struct drm_device *dev)
 
 static __inline__ int drm_device_is_pcie(struct drm_device *dev)
 {
-       return pci_find_capability(dev->pdev, PCI_CAP_ID_EXP);
+       if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE))
+               return 0;
+       else
+               return pci_find_capability(dev->pdev, PCI_CAP_ID_EXP);
 }
 
 static __inline__ void drm_core_dropmap(struct drm_local_map *map)
@@ -1550,6 +1569,21 @@ static __inline__ void drm_core_dropmap(struct drm_local_map *map)
 }
 
 #include "drm_mem_util.h"
+
+static inline void *drm_get_device(struct drm_device *dev)
+{
+       if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE))
+               return dev->platformdev;
+       else
+               return dev->pdev;
+}
+
+extern int drm_platform_init(struct drm_driver *driver);
+extern int drm_pci_init(struct drm_driver *driver);
+extern int drm_fill_in_dev(struct drm_device *dev,
+                          const struct pci_device_id *ent,
+                          struct drm_driver *driver);
+int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type);
 /*@}*/
 
 #endif                         /* __KERNEL__ */
index 1121f7799c6ff527838ec50052d51bc10b10e2e7..7e3c9766acbabc6dc8fb7086c3880f82000e4564 100644 (file)
@@ -63,6 +63,9 @@ struct drm_crtc_helper_funcs {
 
        /* reload the current crtc LUT */
        void (*load_lut)(struct drm_crtc *crtc);
+
+       /* disable crtc when not in use - more explicit than dpms off */
+       void (*disable)(struct drm_crtc *crtc);
 };
 
 struct drm_encoder_helper_funcs {
index 4c10be39a43bd94d7568fbb41bf3cc8d15fac95f..bf01531193d530640bbdedb69c86d49d14c81ea0 100644 (file)
 #endif
 
 struct drm_mm_node {
-       struct list_head fl_entry;
-       struct list_head ml_entry;
-       int free;
+       struct list_head free_stack;
+       struct list_head node_list;
+       unsigned free : 1;
+       unsigned scanned_block : 1;
+       unsigned scanned_prev_free : 1;
+       unsigned scanned_next_free : 1;
        unsigned long start;
        unsigned long size;
        struct drm_mm *mm;
-       void *private;
 };
 
 struct drm_mm {
-       struct list_head fl_entry;
-       struct list_head ml_entry;
+       /* List of free memory blocks, most recently freed ordered. */
+       struct list_head free_stack;
+       /* List of all memory nodes, ordered according to the (increasing) start
+        * address of the memory node. */
+       struct list_head node_list;
        struct list_head unused_nodes;
        int num_unused;
        spinlock_t unused_lock;
+       unsigned scan_alignment;
+       unsigned long scan_size;
+       unsigned long scan_hit_start;
+       unsigned scan_hit_size;
+       unsigned scanned_blocks;
 };
 
 /*
@@ -133,6 +143,11 @@ static inline struct drm_mm *drm_get_mm(struct drm_mm_node *block)
        return block->mm;
 }
 
+void drm_mm_init_scan(struct drm_mm *mm, unsigned long size,
+                     unsigned alignment);
+int drm_mm_scan_add_block(struct drm_mm_node *node);
+int drm_mm_scan_remove_block(struct drm_mm_node *node);
+
 extern void drm_mm_debug_table(struct drm_mm *mm, const char *prefix);
 #ifdef CONFIG_DEBUG_FS
 int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm);
index c5ba1636613c0baac637fb169b28a17fb6a08aa0..0fc7397c8f1f4c3f6f9ab454c5f66343c6b3b949 100644 (file)
@@ -74,6 +74,7 @@
 /* Dithering mode options */
 #define DRM_MODE_DITHERING_OFF 0
 #define DRM_MODE_DITHERING_ON  1
+#define DRM_MODE_DITHERING_AUTO 2
 
 /* Dirty info options */
 #define DRM_MODE_DIRTY_OFF      0
index 5347063e9d5a52b6896c135af389f6fcf8425ff3..ac5f0403d53722ea5cbf2118a486f76d371ee054 100644 (file)
@@ -904,6 +904,7 @@ struct drm_radeon_cs {
 #define RADEON_INFO_ACCEL_WORKING      0x03
 #define RADEON_INFO_CRTC_FROM_ID       0x04
 #define RADEON_INFO_ACCEL_WORKING2     0x05
+#define RADEON_INFO_TILING_CONFIG      0x06
 
 struct drm_radeon_info {
        uint32_t                request;