diff options
-rw-r--r-- | drivers/gpu/drm/radeon/r300.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r300d.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_drv.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_kms.c | 39 | ||||
-rw-r--r-- | include/drm/radeon_drm.h | 1 |
6 files changed, 41 insertions, 14 deletions
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 36b4f7b48d6a..23fee54c3b75 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 0c036c60d9df..1f519a5ffb8c 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 140eaceab279..a835d95021d1 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 18225f21ee0f..be5cb4f28c29 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 b2686334d46b..28a53e4a925f 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); diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h index 10f8b53bdd40..e95a86b8b689 100644 --- a/include/drm/radeon_drm.h +++ b/include/drm/radeon_drm.h @@ -906,6 +906,7 @@ struct drm_radeon_cs { #define RADEON_INFO_ACCEL_WORKING2 0x05 #define RADEON_INFO_TILING_CONFIG 0x06 #define RADEON_INFO_WANT_HYPERZ 0x07 +#define RADEON_INFO_WANT_CMASK 0x08 /* get access to CMASK on r300 */ struct drm_radeon_info { uint32_t request; |