summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorMarek Olšák <maraeo@gmail.com>2011-01-05 05:46:48 +0100
committerDave Airlie <airlied@redhat.com>2011-01-06 13:00:45 +1000
commit9eba4a93ce520a627e876b0d1851d4f78a701c2b (patch)
treea0dbb86c2105b4ff89af724b835d0c40fbf59368 /drivers/gpu/drm
parent2f299d5de02da3ffb1f9e1a05c91dcd1173ebd3c (diff)
downloadlinux-3.10-9eba4a93ce520a627e876b0d1851d4f78a701c2b.tar.gz
linux-3.10-9eba4a93ce520a627e876b0d1851d4f78a701c2b.tar.bz2
linux-3.10-9eba4a93ce520a627e876b0d1851d4f78a701c2b.zip
drm/radeon/kms: manage r300 CMASK RAM access and allow CMASK clear
The CMASK RAM is for colorbuffer compression (used in conjunction with MSAA). Only one user (filp) can access it. The CMASK RAM access is managed in the same way as Hyper-Z, but there is a separate ioctl, because an app that uses MSAA does not necessarily have to use zbuffering. Signed-off-by: Marek Olšák <maraeo@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/radeon/r300.c9
-rw-r--r--drivers/gpu/drm/radeon/r300d.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon.h3
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_kms.c39
5 files changed, 40 insertions, 14 deletions
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index 36b4f7b48d6..23fee54c3b7 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -745,6 +745,11 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
break;
case 0x4E00:
/* RB3D_CCTL */
+ if ((idx_value & (1 << 10)) && /* CMASK_ENABLE */
+ p->rdev->cmask_filp != p->filp) {
+ DRM_ERROR("Invalid RB3D_CCTL: Cannot enable CMASK.\n");
+ return -EINVAL;
+ }
track->num_cb = ((idx_value >> 5) & 0x3) + 1;
break;
case 0x4E38:
@@ -1206,6 +1211,10 @@ static int r300_packet3_check(struct radeon_cs_parser *p,
if (p->rdev->hyperz_filp != p->filp)
return -EINVAL;
break;
+ case PACKET3_3D_CLEAR_CMASK:
+ if (p->rdev->cmask_filp != p->filp)
+ return -EINVAL;
+ break;
case PACKET3_NOP:
break;
default:
diff --git a/drivers/gpu/drm/radeon/r300d.h b/drivers/gpu/drm/radeon/r300d.h
index 0c036c60d9d..1f519a5ffb8 100644
--- a/drivers/gpu/drm/radeon/r300d.h
+++ b/drivers/gpu/drm/radeon/r300d.h
@@ -54,6 +54,7 @@
#define PACKET3_3D_DRAW_IMMD_2 0x35
#define PACKET3_3D_DRAW_INDX_2 0x36
#define PACKET3_3D_CLEAR_HIZ 0x37
+#define PACKET3_3D_CLEAR_CMASK 0x38
#define PACKET3_BITBLT_MULTI 0x9B
#define PACKET0(reg, n) (CP_PACKET0 | \
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 140eaceab27..a835d95021d 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1168,8 +1168,9 @@ struct radeon_device {
uint8_t audio_category_code;
struct notifier_block acpi_nb;
- /* only one userspace can use Hyperz features at a time */
+ /* only one userspace can use Hyperz features or CMASK at a time */
struct drm_file *hyperz_filp;
+ struct drm_file *cmask_filp;
/* i2c buses */
struct radeon_i2c_chan *i2c_bus[RADEON_MAX_I2C_BUS];
};
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 18225f21ee0..be5cb4f28c2 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -48,7 +48,7 @@
* - 2.5.0 - add get accel 2 to work around ddx breakage for evergreen
* - 2.6.0 - add tiling config query (r6xx+), add initial HiZ support (r300->r500)
* 2.7.0 - fixups for r600 2D tiling support. (no external ABI change), add eg dyn gpr regs
- * 2.8.0 - pageflip support, r500 US_FORMAT regs. r500 ARGB2101010 colorbuf
+ * 2.8.0 - pageflip support, r500 US_FORMAT regs. r500 ARGB2101010 colorbuf, r300->r500 CMASK
*/
#define KMS_DRIVER_MAJOR 2
#define KMS_DRIVER_MINOR 8
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index b2686334d46..28a53e4a925 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -96,9 +96,27 @@ out:
return r;
}
+static void radeon_set_filp_rights(struct drm_device *dev,
+ struct drm_file **owner,
+ struct drm_file *applier,
+ uint32_t *value)
+{
+ mutex_lock(&dev->struct_mutex);
+ if (*value == 1) {
+ /* wants rights */
+ if (!*owner)
+ *owner = applier;
+ } else if (*value == 0) {
+ /* revokes rights */
+ if (*owner == applier)
+ *owner = NULL;
+ }
+ *value = *owner == applier ? 1 : 0;
+ mutex_unlock(&dev->struct_mutex);
+}
/*
- * Userspace get informations ioctl
+ * Userspace get information ioctl
*/
int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
{
@@ -173,18 +191,15 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
DRM_DEBUG_KMS("WANT_HYPERZ: invalid value %d\n", value);
return -EINVAL;
}
- mutex_lock(&dev->struct_mutex);
- if (value == 1) {
- /* wants hyper-z */
- if (!rdev->hyperz_filp)
- rdev->hyperz_filp = filp;
- } else if (value == 0) {
- /* revokes hyper-z */
- if (rdev->hyperz_filp == filp)
- rdev->hyperz_filp = NULL;
+ radeon_set_filp_rights(dev, &rdev->hyperz_filp, filp, &value);
+ break;
+ case RADEON_INFO_WANT_CMASK:
+ /* The same logic as Hyper-Z. */
+ if (value >= 2) {
+ DRM_DEBUG_KMS("WANT_CMASK: invalid value %d\n", value);
+ return -EINVAL;
}
- value = rdev->hyperz_filp == filp ? 1 : 0;
- mutex_unlock(&dev->struct_mutex);
+ radeon_set_filp_rights(dev, &rdev->cmask_filp, filp, &value);
break;
default:
DRM_DEBUG_KMS("Invalid request %d\n", info->request);