From dd1f33f83cbbb9917e13f194fadda4f7066ea98a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 14 May 2008 22:35:32 +1000 Subject: ati_pcigart: fill out 40-bit gart table support properly Thanks to Alex for supplying this info. --- linux-core/ati_pcigart.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'linux-core') diff --git a/linux-core/ati_pcigart.c b/linux-core/ati_pcigart.c index beaa4424..34081d4f 100644 --- a/linux-core/ati_pcigart.c +++ b/linux-core/ati_pcigart.c @@ -34,6 +34,8 @@ #include "drmP.h" # define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ +# define ATI_PCIGART_PAGE_MASK (~(ATI_PCIGART_PAGE_SIZE-1)) + static int drm_ati_alloc_pcigart_table(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info) { @@ -148,18 +150,23 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga bus_address = 0; goto done; } - page_base = (u32) entry->busaddr[i]; for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { switch(gart_info->gart_reg_if) { case DRM_ATI_GART_IGP: + page_base = (u32) entry->busaddr[i] & ATI_PCIGART_PAGE_MASK; + page_base |= (upper_32_bits(entry->busaddr[i]) & 0xff) << 4; *pci_gart = cpu_to_le32((page_base) | 0xc); break; case DRM_ATI_GART_PCIE: + page_base = (u32)(entry->busaddr[i] & ATI_PCIGART_PAGE_MASK); + page_base >>= 8; + page_base |= (upper_32_bits(entry->busaddr[i]) & 0xff) << 24; *pci_gart = cpu_to_le32((page_base >> 8) | 0xc); break; default: case DRM_ATI_GART_PCI: + page_base = (u32) entry->busaddr[i]; *pci_gart = cpu_to_le32(page_base); break; } -- cgit v1.2.3 From bc0836e12a9790f1cc83f8bc29bc05043c4bc840 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 14 May 2008 22:42:21 +1000 Subject: ati_pcigart: fixup properly this version might even work --- linux-core/ati_pcigart.c | 21 ++++++++++-------- linux-core/drm_object.c | 57 +++++++++++++++++++++++++++++------------------- linux-core/drm_objects.h | 6 +++-- 3 files changed, 51 insertions(+), 33 deletions(-) (limited to 'linux-core') diff --git a/linux-core/ati_pcigart.c b/linux-core/ati_pcigart.c index 34081d4f..f7752b5e 100644 --- a/linux-core/ati_pcigart.c +++ b/linux-core/ati_pcigart.c @@ -36,6 +36,9 @@ # define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ # define ATI_PCIGART_PAGE_MASK (~(ATI_PCIGART_PAGE_SIZE-1)) +#define ATI_PCIE_WRITE 0x4 +#define ATI_PCIE_READ 0x8 + static int drm_ati_alloc_pcigart_table(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info) { @@ -105,6 +108,7 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga dma_addr_t bus_address = 0; int i, j, ret = 0; int max_pages; + dma_addr_t entry_addr; if (!entry) { DRM_ERROR("no scatter/gather memory!\n"); @@ -151,27 +155,26 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga goto done; } + entry_addr = entry->busaddr[i]; for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { + page_base = (u32) entry_addr & ATI_PCIGART_PAGE_MASK; switch(gart_info->gart_reg_if) { case DRM_ATI_GART_IGP: - page_base = (u32) entry->busaddr[i] & ATI_PCIGART_PAGE_MASK; - page_base |= (upper_32_bits(entry->busaddr[i]) & 0xff) << 4; - *pci_gart = cpu_to_le32((page_base) | 0xc); + page_base |= (upper_32_bits(entry_addr) & 0xff) << 4; + page_base |= ATI_PCIE_READ | ATI_PCIE_WRITE; break; case DRM_ATI_GART_PCIE: - page_base = (u32)(entry->busaddr[i] & ATI_PCIGART_PAGE_MASK); page_base >>= 8; - page_base |= (upper_32_bits(entry->busaddr[i]) & 0xff) << 24; - *pci_gart = cpu_to_le32((page_base >> 8) | 0xc); + page_base |= (upper_32_bits(entry_addr) & 0xff) << 24; + page_base |= 0xc; break; default: case DRM_ATI_GART_PCI: - page_base = (u32) entry->busaddr[i]; - *pci_gart = cpu_to_le32(page_base); break; } + *pci_gart = cpu_to_le32(page_base); pci_gart++; - page_base += ATI_PCIGART_PAGE_SIZE; + entry_addr += ATI_PCIGART_PAGE_SIZE; } } diff --git a/linux-core/drm_object.c b/linux-core/drm_object.c index 2994b716..10924cf5 100644 --- a/linux-core/drm_object.c +++ b/linux-core/drm_object.c @@ -39,7 +39,7 @@ int drm_add_user_object(struct drm_file *priv, struct drm_user_object *item, DRM_ASSERT_LOCKED(&dev->struct_mutex); /* The refcount will be bumped to 1 when we add the ref object below. */ - atomic_set(&item->refcount, 0); + kref_init(&item->refcount); item->shareable = shareable; item->owner = priv; @@ -83,16 +83,20 @@ struct drm_user_object *drm_lookup_user_object(struct drm_file *priv, uint32_t k } EXPORT_SYMBOL(drm_lookup_user_object); -static void drm_deref_user_object(struct drm_file *priv, struct drm_user_object *item) +static void drm_user_object_free(struct kref *kref) { - struct drm_device *dev = priv->minor->dev; + struct drm_user_object *item = container_of(kref, struct drm_user_object, refcount); int ret; + struct drm_device *dev = item->owner->minor->dev; - if (atomic_dec_and_test(&item->refcount)) { - ret = drm_ht_remove_item(&dev->object_hash, &item->hash); - BUG_ON(ret); - item->remove(priv, item); - } + ret = drm_ht_remove_item(&dev->object_hash, &item->hash); + BUG_ON(ret); + item->remove(item->owner, item); +} + +static void drm_deref_user_object(struct drm_user_object *item) +{ + kref_put(&item->refcount, drm_user_object_free); } static int drm_object_ref_action(struct drm_file *priv, struct drm_user_object *ro, @@ -102,7 +106,7 @@ static int drm_object_ref_action(struct drm_file *priv, struct drm_user_object * switch (action) { case _DRM_REF_USE: - atomic_inc(&ro->refcount); + kref_get(&ro->refcount); break; default: if (!ro->ref_struct_locked) { @@ -146,7 +150,7 @@ int drm_add_ref_object(struct drm_file *priv, struct drm_user_object *referenced if (NULL != (item = drm_lookup_ref_object(priv, referenced_object, ref_action))) { - atomic_inc(&item->refcount); + kref_get(&item->refcount); return drm_object_ref_action(priv, referenced_object, ref_action); } @@ -157,8 +161,10 @@ int drm_add_ref_object(struct drm_file *priv, struct drm_user_object *referenced return -ENOMEM; } - atomic_set(&item->refcount, 1); + kref_init(&item->refcount); + kref_get(&item->refcount); item->hash.key = (unsigned long)referenced_object; + item->owner = priv; ret = drm_ht_insert_item(ht, &item->hash); item->unref_action = ref_action; @@ -205,27 +211,34 @@ static void drm_remove_other_references(struct drm_file *priv, } } -void drm_remove_ref_object(struct drm_file *priv, struct drm_ref_object *item) +void drm_object_ref_free(struct kref *kref) { - int ret; + struct drm_ref_object *item = container_of(kref, struct drm_ref_object, refcount); struct drm_user_object *user_object = (struct drm_user_object *) item->hash.key; + struct drm_file *priv = item->owner; struct drm_open_hash *ht = &priv->refd_object_hash[item->unref_action]; + int ret; + + ret = drm_ht_remove_item(ht, &item->hash); + BUG_ON(ret); + list_del_init(&item->list); + if (item->unref_action == _DRM_REF_USE) + drm_remove_other_references(priv, user_object); + drm_ctl_free(item, sizeof(*item), DRM_MEM_OBJECTS); +} + +void drm_remove_ref_object(struct drm_file *priv, struct drm_ref_object *item) +{ + struct drm_user_object *user_object = (struct drm_user_object *) item->hash.key; enum drm_ref_type unref_action; DRM_ASSERT_LOCKED(&priv->minor->dev->struct_mutex); unref_action = item->unref_action; - if (atomic_dec_and_test(&item->refcount)) { - ret = drm_ht_remove_item(ht, &item->hash); - BUG_ON(ret); - list_del_init(&item->list); - if (unref_action == _DRM_REF_USE) - drm_remove_other_references(priv, user_object); - drm_ctl_free(item, sizeof(*item), DRM_MEM_OBJECTS); - } + kref_put(&item->refcount, drm_object_ref_free); switch (unref_action) { case _DRM_REF_USE: - drm_deref_user_object(priv, user_object); + drm_deref_user_object(user_object); break; default: BUG_ON(!user_object->unref); diff --git a/linux-core/drm_objects.h b/linux-core/drm_objects.h index 770fbc56..427a9170 100644 --- a/linux-core/drm_objects.h +++ b/linux-core/drm_objects.h @@ -65,7 +65,8 @@ struct drm_user_object { struct drm_hash_item hash; struct list_head list; enum drm_object_type type; - atomic_t refcount; + struct kref refcount; + int shareable; struct drm_file *owner; void (*ref_struct_locked) (struct drm_file *priv, @@ -86,8 +87,9 @@ struct drm_user_object { struct drm_ref_object { struct drm_hash_item hash; struct list_head list; - atomic_t refcount; + struct kref refcount; enum drm_ref_type unref_action; + struct drm_file *owner; }; /** -- cgit v1.2.3 From 2712cdeec319d73187a6cccb06522a4125eef619 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 14 May 2008 22:43:28 +1000 Subject: Revert "ati_pcigart: fixup properly this version might even work" This reverts commit bc0836e12a9790f1cc83f8bc29bc05043c4bc840. tree has some kref hacks in it - oops --- linux-core/ati_pcigart.c | 21 ++++++++---------- linux-core/drm_object.c | 57 +++++++++++++++++++----------------------------- linux-core/drm_objects.h | 6 ++--- 3 files changed, 33 insertions(+), 51 deletions(-) (limited to 'linux-core') diff --git a/linux-core/ati_pcigart.c b/linux-core/ati_pcigart.c index f7752b5e..34081d4f 100644 --- a/linux-core/ati_pcigart.c +++ b/linux-core/ati_pcigart.c @@ -36,9 +36,6 @@ # define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ # define ATI_PCIGART_PAGE_MASK (~(ATI_PCIGART_PAGE_SIZE-1)) -#define ATI_PCIE_WRITE 0x4 -#define ATI_PCIE_READ 0x8 - static int drm_ati_alloc_pcigart_table(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info) { @@ -108,7 +105,6 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga dma_addr_t bus_address = 0; int i, j, ret = 0; int max_pages; - dma_addr_t entry_addr; if (!entry) { DRM_ERROR("no scatter/gather memory!\n"); @@ -155,26 +151,27 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga goto done; } - entry_addr = entry->busaddr[i]; for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { - page_base = (u32) entry_addr & ATI_PCIGART_PAGE_MASK; switch(gart_info->gart_reg_if) { case DRM_ATI_GART_IGP: - page_base |= (upper_32_bits(entry_addr) & 0xff) << 4; - page_base |= ATI_PCIE_READ | ATI_PCIE_WRITE; + page_base = (u32) entry->busaddr[i] & ATI_PCIGART_PAGE_MASK; + page_base |= (upper_32_bits(entry->busaddr[i]) & 0xff) << 4; + *pci_gart = cpu_to_le32((page_base) | 0xc); break; case DRM_ATI_GART_PCIE: + page_base = (u32)(entry->busaddr[i] & ATI_PCIGART_PAGE_MASK); page_base >>= 8; - page_base |= (upper_32_bits(entry_addr) & 0xff) << 24; - page_base |= 0xc; + page_base |= (upper_32_bits(entry->busaddr[i]) & 0xff) << 24; + *pci_gart = cpu_to_le32((page_base >> 8) | 0xc); break; default: case DRM_ATI_GART_PCI: + page_base = (u32) entry->busaddr[i]; + *pci_gart = cpu_to_le32(page_base); break; } - *pci_gart = cpu_to_le32(page_base); pci_gart++; - entry_addr += ATI_PCIGART_PAGE_SIZE; + page_base += ATI_PCIGART_PAGE_SIZE; } } diff --git a/linux-core/drm_object.c b/linux-core/drm_object.c index 10924cf5..2994b716 100644 --- a/linux-core/drm_object.c +++ b/linux-core/drm_object.c @@ -39,7 +39,7 @@ int drm_add_user_object(struct drm_file *priv, struct drm_user_object *item, DRM_ASSERT_LOCKED(&dev->struct_mutex); /* The refcount will be bumped to 1 when we add the ref object below. */ - kref_init(&item->refcount); + atomic_set(&item->refcount, 0); item->shareable = shareable; item->owner = priv; @@ -83,20 +83,16 @@ struct drm_user_object *drm_lookup_user_object(struct drm_file *priv, uint32_t k } EXPORT_SYMBOL(drm_lookup_user_object); -static void drm_user_object_free(struct kref *kref) +static void drm_deref_user_object(struct drm_file *priv, struct drm_user_object *item) { - struct drm_user_object *item = container_of(kref, struct drm_user_object, refcount); + struct drm_device *dev = priv->minor->dev; int ret; - struct drm_device *dev = item->owner->minor->dev; - - ret = drm_ht_remove_item(&dev->object_hash, &item->hash); - BUG_ON(ret); - item->remove(item->owner, item); -} -static void drm_deref_user_object(struct drm_user_object *item) -{ - kref_put(&item->refcount, drm_user_object_free); + if (atomic_dec_and_test(&item->refcount)) { + ret = drm_ht_remove_item(&dev->object_hash, &item->hash); + BUG_ON(ret); + item->remove(priv, item); + } } static int drm_object_ref_action(struct drm_file *priv, struct drm_user_object *ro, @@ -106,7 +102,7 @@ static int drm_object_ref_action(struct drm_file *priv, struct drm_user_object * switch (action) { case _DRM_REF_USE: - kref_get(&ro->refcount); + atomic_inc(&ro->refcount); break; default: if (!ro->ref_struct_locked) { @@ -150,7 +146,7 @@ int drm_add_ref_object(struct drm_file *priv, struct drm_user_object *referenced if (NULL != (item = drm_lookup_ref_object(priv, referenced_object, ref_action))) { - kref_get(&item->refcount); + atomic_inc(&item->refcount); return drm_object_ref_action(priv, referenced_object, ref_action); } @@ -161,10 +157,8 @@ int drm_add_ref_object(struct drm_file *priv, struct drm_user_object *referenced return -ENOMEM; } - kref_init(&item->refcount); - kref_get(&item->refcount); + atomic_set(&item->refcount, 1); item->hash.key = (unsigned long)referenced_object; - item->owner = priv; ret = drm_ht_insert_item(ht, &item->hash); item->unref_action = ref_action; @@ -211,34 +205,27 @@ static void drm_remove_other_references(struct drm_file *priv, } } -void drm_object_ref_free(struct kref *kref) -{ - struct drm_ref_object *item = container_of(kref, struct drm_ref_object, refcount); - struct drm_user_object *user_object = (struct drm_user_object *) item->hash.key; - struct drm_file *priv = item->owner; - struct drm_open_hash *ht = &priv->refd_object_hash[item->unref_action]; - int ret; - - ret = drm_ht_remove_item(ht, &item->hash); - BUG_ON(ret); - list_del_init(&item->list); - if (item->unref_action == _DRM_REF_USE) - drm_remove_other_references(priv, user_object); - drm_ctl_free(item, sizeof(*item), DRM_MEM_OBJECTS); -} - void drm_remove_ref_object(struct drm_file *priv, struct drm_ref_object *item) { + int ret; struct drm_user_object *user_object = (struct drm_user_object *) item->hash.key; + struct drm_open_hash *ht = &priv->refd_object_hash[item->unref_action]; enum drm_ref_type unref_action; DRM_ASSERT_LOCKED(&priv->minor->dev->struct_mutex); unref_action = item->unref_action; - kref_put(&item->refcount, drm_object_ref_free); + if (atomic_dec_and_test(&item->refcount)) { + ret = drm_ht_remove_item(ht, &item->hash); + BUG_ON(ret); + list_del_init(&item->list); + if (unref_action == _DRM_REF_USE) + drm_remove_other_references(priv, user_object); + drm_ctl_free(item, sizeof(*item), DRM_MEM_OBJECTS); + } switch (unref_action) { case _DRM_REF_USE: - drm_deref_user_object(user_object); + drm_deref_user_object(priv, user_object); break; default: BUG_ON(!user_object->unref); diff --git a/linux-core/drm_objects.h b/linux-core/drm_objects.h index 427a9170..770fbc56 100644 --- a/linux-core/drm_objects.h +++ b/linux-core/drm_objects.h @@ -65,8 +65,7 @@ struct drm_user_object { struct drm_hash_item hash; struct list_head list; enum drm_object_type type; - struct kref refcount; - + atomic_t refcount; int shareable; struct drm_file *owner; void (*ref_struct_locked) (struct drm_file *priv, @@ -87,9 +86,8 @@ struct drm_user_object { struct drm_ref_object { struct drm_hash_item hash; struct list_head list; - struct kref refcount; + atomic_t refcount; enum drm_ref_type unref_action; - struct drm_file *owner; }; /** -- cgit v1.2.3 From 4c6ec02eb8b1a5723f1a00dc420740d440a9ee0d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 14 May 2008 22:44:22 +1000 Subject: ati_pcigart: stop working in the evenings you mess up too often --- linux-core/ati_pcigart.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'linux-core') diff --git a/linux-core/ati_pcigart.c b/linux-core/ati_pcigart.c index 34081d4f..f7752b5e 100644 --- a/linux-core/ati_pcigart.c +++ b/linux-core/ati_pcigart.c @@ -36,6 +36,9 @@ # define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ # define ATI_PCIGART_PAGE_MASK (~(ATI_PCIGART_PAGE_SIZE-1)) +#define ATI_PCIE_WRITE 0x4 +#define ATI_PCIE_READ 0x8 + static int drm_ati_alloc_pcigart_table(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info) { @@ -105,6 +108,7 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga dma_addr_t bus_address = 0; int i, j, ret = 0; int max_pages; + dma_addr_t entry_addr; if (!entry) { DRM_ERROR("no scatter/gather memory!\n"); @@ -151,27 +155,26 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga goto done; } + entry_addr = entry->busaddr[i]; for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { + page_base = (u32) entry_addr & ATI_PCIGART_PAGE_MASK; switch(gart_info->gart_reg_if) { case DRM_ATI_GART_IGP: - page_base = (u32) entry->busaddr[i] & ATI_PCIGART_PAGE_MASK; - page_base |= (upper_32_bits(entry->busaddr[i]) & 0xff) << 4; - *pci_gart = cpu_to_le32((page_base) | 0xc); + page_base |= (upper_32_bits(entry_addr) & 0xff) << 4; + page_base |= ATI_PCIE_READ | ATI_PCIE_WRITE; break; case DRM_ATI_GART_PCIE: - page_base = (u32)(entry->busaddr[i] & ATI_PCIGART_PAGE_MASK); page_base >>= 8; - page_base |= (upper_32_bits(entry->busaddr[i]) & 0xff) << 24; - *pci_gart = cpu_to_le32((page_base >> 8) | 0xc); + page_base |= (upper_32_bits(entry_addr) & 0xff) << 24; + page_base |= 0xc; break; default: case DRM_ATI_GART_PCI: - page_base = (u32) entry->busaddr[i]; - *pci_gart = cpu_to_le32(page_base); break; } + *pci_gart = cpu_to_le32(page_base); pci_gart++; - page_base += ATI_PCIGART_PAGE_SIZE; + entry_addr += ATI_PCIGART_PAGE_SIZE; } } -- cgit v1.2.3 From a09c0bbe11004a020d0fac47f7517db55fb91754 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 14 May 2008 22:48:12 +1000 Subject: ati_pcigart: oops wrong way around not that it actually mattered --- linux-core/ati_pcigart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux-core') diff --git a/linux-core/ati_pcigart.c b/linux-core/ati_pcigart.c index f7752b5e..09251ac3 100644 --- a/linux-core/ati_pcigart.c +++ b/linux-core/ati_pcigart.c @@ -161,12 +161,12 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga switch(gart_info->gart_reg_if) { case DRM_ATI_GART_IGP: page_base |= (upper_32_bits(entry_addr) & 0xff) << 4; - page_base |= ATI_PCIE_READ | ATI_PCIE_WRITE; + page_base |= 0xc; break; case DRM_ATI_GART_PCIE: page_base >>= 8; page_base |= (upper_32_bits(entry_addr) & 0xff) << 24; - page_base |= 0xc; + page_base |= ATI_PCIE_READ | ATI_PCIE_WRITE; break; default: case DRM_ATI_GART_PCI: -- cgit v1.2.3 From 5b86823fa36513f521412a38c240cb18f02dcc9a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 28 May 2008 11:12:57 +1000 Subject: radeon: split microcode out into a separate header file. --- linux-core/radeon_microcode.h | 1 + 1 file changed, 1 insertion(+) create mode 120000 linux-core/radeon_microcode.h (limited to 'linux-core') diff --git a/linux-core/radeon_microcode.h b/linux-core/radeon_microcode.h new file mode 120000 index 00000000..709fff30 --- /dev/null +++ b/linux-core/radeon_microcode.h @@ -0,0 +1 @@ +../shared-core/radeon_microcode.h \ No newline at end of file -- cgit v1.2.3