From patchwork Fri Apr 5 21:18:46 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jerome Glisse X-Patchwork-Id: 2400551 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork2.kernel.org (Postfix) with ESMTP id DE5CEDF2E5 for ; Fri, 5 Apr 2013 21:17:56 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 99299E683B for ; Fri, 5 Apr 2013 14:17:56 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-da0-f53.google.com (mail-da0-f53.google.com [209.85.210.53]) by gabe.freedesktop.org (Postfix) with ESMTP id 18DCFE6843 for ; Fri, 5 Apr 2013 14:17:34 -0700 (PDT) Received: by mail-da0-f53.google.com with SMTP id n34so1751335dal.12 for ; Fri, 05 Apr 2013 14:17:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer; bh=t0S+4mg2UMosblpKOY6DjPSNGmSrUN7qNNSMwo9cK8g=; b=jyfk7C4CaX3uUzYYVRPCL0/SPCb20yQ6q4NW1R12mfHcDxiW71qeJI88E91sE41aMQ m8DQ9DobP9pYQZSxidpG6ZCi9eBXrU1mlH0j89J28UpRc3joiRf5e9mfnau8scpHz/TK dqaB5JnmAq10AhZYnpESVbrGTFrYBzDaNcCG2QezxL8sfi5cNEjYbpTRHuXA7DdbhkO2 4yJGgwc4qBO3w7/55D5NxaHxe5Z1FBas05OnadF7mySx5PmFIej0hqDsI+neRRoRUKvb li9rk/AWpr5SkNjQkZACmrrp/fW1zdJsETQKsJ46LSCS9IXEBLDr4sP2Y8LMPhUN2Ctz 1CDw== X-Received: by 10.68.1.231 with SMTP id 7mr16451886pbp.124.1365196653854; Fri, 05 Apr 2013 14:17:33 -0700 (PDT) Received: from homer.boston.devel.redhat.com ([66.187.233.206]) by mx.google.com with ESMTPS id gd4sm5543383pbd.35.2013.04.05.14.17.31 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Fri, 05 Apr 2013 14:17:33 -0700 (PDT) From: j.glisse@gmail.com To: dri-devel@lists.freedesktop.org Subject: [PATCH] drm/radeon: add si tile mode array query v2 Date: Fri, 5 Apr 2013 17:18:46 -0400 Message-Id: <1365196726-20960-1-git-send-email-j.glisse@gmail.com> X-Mailer: git-send-email 1.8.1.4 Cc: Jerome Glisse X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org From: Jerome Glisse Allow userspace to query for the tile mode array so userspace can properly compute surface pitch and alignment requirement depending on tiling. v2: Make strict aliasing safer by casting to char when copying Signed-off-by: Jerome Glisse --- drivers/gpu/drm/radeon/radeon.h | 1 + drivers/gpu/drm/radeon/radeon_drv.c | 3 +- drivers/gpu/drm/radeon/radeon_kms.c | 158 +++++++++++++++++++----------------- drivers/gpu/drm/radeon/si.c | 2 + include/uapi/drm/radeon_drm.h | 20 +++++ 5 files changed, 109 insertions(+), 75 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 8263af3..961659e 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1443,6 +1443,7 @@ struct si_asic { unsigned multi_gpu_tile_size; unsigned tile_config; + uint32_t tile_mode_array[32]; }; union radeon_asic_config { diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 66a7f0f..1e48ab6 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -71,9 +71,10 @@ * 2.28.0 - r600-eg: Add MEM_WRITE packet support * 2.29.0 - R500 FP16 color clear registers * 2.30.0 - fix for FMASK texturing + * 2.31.0 - Add SI tiling mode array query */ #define KMS_DRIVER_MAJOR 2 -#define KMS_DRIVER_MINOR 30 +#define KMS_DRIVER_MINOR 31 #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); diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index c75cb2c..63e28e0 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -176,80 +176,65 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) struct radeon_device *rdev = dev->dev_private; struct drm_radeon_info *info = data; struct radeon_mode_info *minfo = &rdev->mode_info; - uint32_t value, *value_ptr; - uint64_t value64, *value_ptr64; + uint32_t *value, value_tmp, *value_ptr, value_size; + uint64_t value64; struct drm_crtc *crtc; int i, found; - /* TIMESTAMP is a 64-bit value, needs special handling. */ - if (info->request == RADEON_INFO_TIMESTAMP) { - if (rdev->family >= CHIP_R600) { - value_ptr64 = (uint64_t*)((unsigned long)info->value); - value64 = radeon_get_gpu_clock_counter(rdev); - - if (DRM_COPY_TO_USER(value_ptr64, &value64, sizeof(value64))) { - DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__); - return -EFAULT; - } - return 0; - } else { - DRM_DEBUG_KMS("timestamp is r6xx+ only!\n"); - return -EINVAL; - } - } - value_ptr = (uint32_t *)((unsigned long)info->value); - if (DRM_COPY_FROM_USER(&value, value_ptr, sizeof(value))) { - DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__); - return -EFAULT; - } + value = &value_tmp; + value_size = sizeof(uint32_t); switch (info->request) { case RADEON_INFO_DEVICE_ID: - value = dev->pci_device; + *value = dev->pci_device; break; case RADEON_INFO_NUM_GB_PIPES: - value = rdev->num_gb_pipes; + *value = rdev->num_gb_pipes; break; case RADEON_INFO_NUM_Z_PIPES: - value = rdev->num_z_pipes; + *value = rdev->num_z_pipes; break; case RADEON_INFO_ACCEL_WORKING: /* xf86-video-ati 6.13.0 relies on this being false for evergreen */ if ((rdev->family >= CHIP_CEDAR) && (rdev->family <= CHIP_HEMLOCK)) - value = false; + *value = false; else - value = rdev->accel_working; + *value = rdev->accel_working; break; case RADEON_INFO_CRTC_FROM_ID: + if (DRM_COPY_FROM_USER(value, value_ptr, sizeof(uint32_t))) { + DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__); + return -EFAULT; + } for (i = 0, found = 0; i < rdev->num_crtc; i++) { crtc = (struct drm_crtc *)minfo->crtcs[i]; - if (crtc && crtc->base.id == value) { + if (crtc && crtc->base.id == *value) { struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - value = radeon_crtc->crtc_id; + *value = radeon_crtc->crtc_id; found = 1; break; } } if (!found) { - DRM_DEBUG_KMS("unknown crtc id %d\n", value); + DRM_DEBUG_KMS("unknown crtc id %d\n", *value); return -EINVAL; } break; case RADEON_INFO_ACCEL_WORKING2: - value = rdev->accel_working; + *value = rdev->accel_working; break; case RADEON_INFO_TILING_CONFIG: if (rdev->family >= CHIP_TAHITI) - value = rdev->config.si.tile_config; + *value = rdev->config.si.tile_config; else if (rdev->family >= CHIP_CAYMAN) - value = rdev->config.cayman.tile_config; + *value = rdev->config.cayman.tile_config; else if (rdev->family >= CHIP_CEDAR) - value = rdev->config.evergreen.tile_config; + *value = rdev->config.evergreen.tile_config; else if (rdev->family >= CHIP_RV770) - value = rdev->config.rv770.tile_config; + *value = rdev->config.rv770.tile_config; else if (rdev->family >= CHIP_R600) - value = rdev->config.r600.tile_config; + *value = rdev->config.r600.tile_config; else { DRM_DEBUG_KMS("tiling config is r6xx+ only!\n"); return -EINVAL; @@ -262,73 +247,81 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) * * When returning, the value is 1 if filp owns hyper-z access, * 0 otherwise. */ - if (value >= 2) { - DRM_DEBUG_KMS("WANT_HYPERZ: invalid value %d\n", value); + if (DRM_COPY_FROM_USER(value, value_ptr, sizeof(uint32_t))) { + DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__); + return -EFAULT; + } + if (*value >= 2) { + DRM_DEBUG_KMS("WANT_HYPERZ: invalid value %d\n", *value); return -EINVAL; } - radeon_set_filp_rights(dev, &rdev->hyperz_filp, filp, &value); + 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); + if (DRM_COPY_FROM_USER(value, value_ptr, sizeof(uint32_t))) { + DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__); + return -EFAULT; + } + if (*value >= 2) { + DRM_DEBUG_KMS("WANT_CMASK: invalid value %d\n", *value); return -EINVAL; } - radeon_set_filp_rights(dev, &rdev->cmask_filp, filp, &value); + radeon_set_filp_rights(dev, &rdev->cmask_filp, filp, value); break; case RADEON_INFO_CLOCK_CRYSTAL_FREQ: /* return clock value in KHz */ if (rdev->asic->get_xclk) - value = radeon_get_xclk(rdev) * 10; + *value = radeon_get_xclk(rdev) * 10; else - value = rdev->clock.spll.reference_freq * 10; + *value = rdev->clock.spll.reference_freq * 10; break; case RADEON_INFO_NUM_BACKENDS: if (rdev->family >= CHIP_TAHITI) - value = rdev->config.si.max_backends_per_se * + *value = rdev->config.si.max_backends_per_se * rdev->config.si.max_shader_engines; else if (rdev->family >= CHIP_CAYMAN) - value = rdev->config.cayman.max_backends_per_se * + *value = rdev->config.cayman.max_backends_per_se * rdev->config.cayman.max_shader_engines; else if (rdev->family >= CHIP_CEDAR) - value = rdev->config.evergreen.max_backends; + *value = rdev->config.evergreen.max_backends; else if (rdev->family >= CHIP_RV770) - value = rdev->config.rv770.max_backends; + *value = rdev->config.rv770.max_backends; else if (rdev->family >= CHIP_R600) - value = rdev->config.r600.max_backends; + *value = rdev->config.r600.max_backends; else { return -EINVAL; } break; case RADEON_INFO_NUM_TILE_PIPES: if (rdev->family >= CHIP_TAHITI) - value = rdev->config.si.max_tile_pipes; + *value = rdev->config.si.max_tile_pipes; else if (rdev->family >= CHIP_CAYMAN) - value = rdev->config.cayman.max_tile_pipes; + *value = rdev->config.cayman.max_tile_pipes; else if (rdev->family >= CHIP_CEDAR) - value = rdev->config.evergreen.max_tile_pipes; + *value = rdev->config.evergreen.max_tile_pipes; else if (rdev->family >= CHIP_RV770) - value = rdev->config.rv770.max_tile_pipes; + *value = rdev->config.rv770.max_tile_pipes; else if (rdev->family >= CHIP_R600) - value = rdev->config.r600.max_tile_pipes; + *value = rdev->config.r600.max_tile_pipes; else { return -EINVAL; } break; case RADEON_INFO_FUSION_GART_WORKING: - value = 1; + *value = 1; break; case RADEON_INFO_BACKEND_MAP: if (rdev->family >= CHIP_TAHITI) - value = rdev->config.si.backend_map; + *value = rdev->config.si.backend_map; else if (rdev->family >= CHIP_CAYMAN) - value = rdev->config.cayman.backend_map; + *value = rdev->config.cayman.backend_map; else if (rdev->family >= CHIP_CEDAR) - value = rdev->config.evergreen.backend_map; + *value = rdev->config.evergreen.backend_map; else if (rdev->family >= CHIP_RV770) - value = rdev->config.rv770.backend_map; + *value = rdev->config.rv770.backend_map; else if (rdev->family >= CHIP_R600) - value = rdev->config.r600.backend_map; + *value = rdev->config.r600.backend_map; else { return -EINVAL; } @@ -337,50 +330,67 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) /* this is where we report if vm is supported or not */ if (rdev->family < CHIP_CAYMAN) return -EINVAL; - value = RADEON_VA_RESERVED_SIZE; + *value = RADEON_VA_RESERVED_SIZE; break; case RADEON_INFO_IB_VM_MAX_SIZE: /* this is where we report if vm is supported or not */ if (rdev->family < CHIP_CAYMAN) return -EINVAL; - value = RADEON_IB_VM_MAX_SIZE; + *value = RADEON_IB_VM_MAX_SIZE; break; case RADEON_INFO_MAX_PIPES: if (rdev->family >= CHIP_TAHITI) - value = rdev->config.si.max_cu_per_sh; + *value = rdev->config.si.max_cu_per_sh; else if (rdev->family >= CHIP_CAYMAN) - value = rdev->config.cayman.max_pipes_per_simd; + *value = rdev->config.cayman.max_pipes_per_simd; else if (rdev->family >= CHIP_CEDAR) - value = rdev->config.evergreen.max_pipes; + *value = rdev->config.evergreen.max_pipes; else if (rdev->family >= CHIP_RV770) - value = rdev->config.rv770.max_pipes; + *value = rdev->config.rv770.max_pipes; else if (rdev->family >= CHIP_R600) - value = rdev->config.r600.max_pipes; + *value = rdev->config.r600.max_pipes; else { return -EINVAL; } break; + case RADEON_INFO_TIMESTAMP: + if (rdev->family < CHIP_R600) { + DRM_DEBUG_KMS("timestamp is r6xx+ only!\n"); + return -EINVAL; + } + value = (uint32_t*)&value64; + value_size = sizeof(uint64_t); + value64 = radeon_get_gpu_clock_counter(rdev); + break; case RADEON_INFO_MAX_SE: if (rdev->family >= CHIP_TAHITI) - value = rdev->config.si.max_shader_engines; + *value = rdev->config.si.max_shader_engines; else if (rdev->family >= CHIP_CAYMAN) - value = rdev->config.cayman.max_shader_engines; + *value = rdev->config.cayman.max_shader_engines; else if (rdev->family >= CHIP_CEDAR) - value = rdev->config.evergreen.num_ses; + *value = rdev->config.evergreen.num_ses; else - value = 1; + *value = 1; break; case RADEON_INFO_MAX_SH_PER_SE: if (rdev->family >= CHIP_TAHITI) - value = rdev->config.si.max_sh_per_se; + *value = rdev->config.si.max_sh_per_se; else return -EINVAL; break; + case RADEON_INFO_SI_TILE_MODE_ARRAY: + if (rdev->family < CHIP_TAHITI) { + DRM_DEBUG_KMS("tile mode array is si only!\n"); + return -EINVAL; + } + value = rdev->config.si.tile_mode_array; + value_size = sizeof(uint32_t)*32; + break; default: DRM_DEBUG_KMS("Invalid request %d\n", info->request); return -EINVAL; } - if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) { + if (DRM_COPY_TO_USER(value_ptr, (char*)value, value_size)) { DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__); return -EFAULT; } diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index bafbe32..c96bd93 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -1211,6 +1211,7 @@ static void si_tiling_mode_table_init(struct radeon_device *rdev) gb_tile_moden = 0; break; } + rdev->config.si.tile_mode_array[reg_offset] = gb_tile_moden; WREG32(GB_TILE_MODE0 + (reg_offset * 4), gb_tile_moden); } } else if ((rdev->family == CHIP_VERDE) || @@ -1451,6 +1452,7 @@ static void si_tiling_mode_table_init(struct radeon_device *rdev) gb_tile_moden = 0; break; } + rdev->config.si.tile_mode_array[reg_offset] = gb_tile_moden; WREG32(GB_TILE_MODE0 + (reg_offset * 4), gb_tile_moden); } } else diff --git a/include/uapi/drm/radeon_drm.h b/include/uapi/drm/radeon_drm.h index eeda917..db5049c 100644 --- a/include/uapi/drm/radeon_drm.h +++ b/include/uapi/drm/radeon_drm.h @@ -972,6 +972,8 @@ struct drm_radeon_cs { #define RADEON_INFO_MAX_SE 0x12 /* max SH per SE */ #define RADEON_INFO_MAX_SH_PER_SE 0x13 +/* SI tile mode array */ +#define RADEON_INFO_SI_TILE_MODE_ARRAY 0x14 struct drm_radeon_info { uint32_t request; @@ -979,4 +981,22 @@ struct drm_radeon_info { uint64_t value; }; +/* Those correspond to the tile index to use, this is to explicitly state + * the API that is implicitly defined by the tile mode array. + */ +#define SI_TILE_MODE_COLOR_LINEAR_ALIGNED 8 +#define SI_TILE_MODE_COLOR_1D 13 +#define SI_TILE_MODE_COLOR_1D_SCANOUT 9 +#define SI_TILE_MODE_COLOR_2D_8BPP 14 +#define SI_TILE_MODE_COLOR_2D_16BPP 15 +#define SI_TILE_MODE_COLOR_2D_32BPP 16 +#define SI_TILE_MODE_COLOR_2D_64BPP 17 +#define SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP 11 +#define SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP 12 +#define SI_TILE_MODE_DEPTH_STENCIL_1D 4 +#define SI_TILE_MODE_DEPTH_STENCIL_2D 0 +#define SI_TILE_MODE_DEPTH_STENCIL_2D_2AA 3 +#define SI_TILE_MODE_DEPTH_STENCIL_2D_4AA 3 +#define SI_TILE_MODE_DEPTH_STENCIL_2D_8AA 2 + #endif