From patchwork Thu Aug 9 15:44:16 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alex Deucher X-Patchwork-Id: 1301401 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork1.kernel.org (Postfix) with ESMTP id 630A73FD8C for ; Thu, 9 Aug 2012 15:45:21 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 36077A0E88 for ; Thu, 9 Aug 2012 08:45:21 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-we0-f177.google.com (mail-we0-f177.google.com [74.125.82.177]) by gabe.freedesktop.org (Postfix) with ESMTP id 75BA0A0E84 for ; Thu, 9 Aug 2012 08:44:18 -0700 (PDT) Received: by weyr3 with SMTP id r3so416808wey.36 for ; Thu, 09 Aug 2012 08:44:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=4iiGqsPO4+bzItF11ul1zqC0PVWVThbaAxl6kGFoQe8=; b=uOxNsabzyp9hMapd767F/6x9WvOY+nal3PJ/fjnbVU5IWzqY2W37FbRFFruJrG9QLT RBjQ3uwMfjLzD2U0igz/jT6M2fgX/d5p50GfufpmKM0BMU1NNNmwBSoPtiraDx/wmVAn nBwC98bgNXx7VQZtBjQ3Pdk08ZnJNp5Rt79MB7XLGL41c7/CUEegY9mmQZ9ZVF7Et5oP gkyEsWM3zAj+NnnW06EeMQCAioq5Ar7L8OMnJNJ5eUpEePKobLPs+v+ubQOyK0Txc/U9 fnG4DmAOqCcFy7NMgCQgGZzpBWzDfVaBZ9QBmp1YXXWvUNyCkHsr1rPG8pFilbAaf1bZ TjYg== MIME-Version: 1.0 Received: by 10.180.92.9 with SMTP id ci9mr3848896wib.22.1344527056721; Thu, 09 Aug 2012 08:44:16 -0700 (PDT) Received: by 10.227.202.80 with HTTP; Thu, 9 Aug 2012 08:44:16 -0700 (PDT) In-Reply-To: References: <1344522857-3878-1-git-send-email-maraeo@gmail.com> <1344522857-3878-3-git-send-email-maraeo@gmail.com> Date: Thu, 9 Aug 2012 11:44:16 -0400 Message-ID: Subject: Re: [PATCH 3/3] drm/radeon/kms: implement timestamp userspace query From: Alex Deucher To: Jerome Glisse Cc: dri-devel@lists.freedesktop.org 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: , 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 On Thu, Aug 9, 2012 at 10:57 AM, Jerome Glisse wrote: > On Thu, Aug 9, 2012 at 10:34 AM, Marek Olšák wrote: >> Signed-off-by: Marek Olšák > > Some comment inline that need a v2 at least for version otherwise How about the attached updated patch? I'd like to get this series in the radeon drm-fixes pull. Alex > > Reviewed-by: Jerome Glisse > >> --- >> drivers/gpu/drm/radeon/r600.c | 12 +++++++++++ >> drivers/gpu/drm/radeon/r600d.h | 3 +++ >> drivers/gpu/drm/radeon/radeon.h | 1 + >> drivers/gpu/drm/radeon/radeon_asic.h | 2 ++ >> drivers/gpu/drm/radeon/radeon_device.c | 1 + >> drivers/gpu/drm/radeon/radeon_drv.c | 2 +- >> drivers/gpu/drm/radeon/radeon_kms.c | 35 ++++++++++++++++++++++++++------ >> drivers/gpu/drm/radeon/si.c | 11 ++++++++++ >> drivers/gpu/drm/radeon/sid.h | 3 +++ >> include/drm/radeon_drm.h | 2 ++ >> 10 files changed, 65 insertions(+), 7 deletions(-) >> >> diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c >> index 637280f..be0e320 100644 >> --- a/drivers/gpu/drm/radeon/r600.c >> +++ b/drivers/gpu/drm/radeon/r600.c >> @@ -3789,3 +3789,15 @@ static void r600_pcie_gen2_enable(struct radeon_device *rdev) >> WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); >> } >> } >> + >> +uint64_t r600_get_gpu_clock(struct radeon_device *rdev) >> +{ >> + uint64_t clock; >> + >> + mutex_lock(&rdev->gpu_clock_mutex); >> + WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1); >> + clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) | >> + ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32); > > I keep forgeting about c type rules but i think you want 32ULL > >> + mutex_unlock(&rdev->gpu_clock_mutex); >> + return clock; >> +} >> diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h >> index 4b116ae..fd328f4 100644 >> --- a/drivers/gpu/drm/radeon/r600d.h >> +++ b/drivers/gpu/drm/radeon/r600d.h >> @@ -602,6 +602,9 @@ >> #define RLC_HB_WPTR 0x3f1c >> #define RLC_HB_WPTR_LSB_ADDR 0x3f14 >> #define RLC_HB_WPTR_MSB_ADDR 0x3f18 >> +#define RLC_GPU_CLOCK_COUNT_LSB 0x3f38 >> +#define RLC_GPU_CLOCK_COUNT_MSB 0x3f3c >> +#define RLC_CAPTURE_GPU_CLOCK_COUNT 0x3f40 >> #define RLC_MC_CNTL 0x3f44 >> #define RLC_UCODE_CNTL 0x3f48 >> #define RLC_UCODE_ADDR 0x3f2c >> diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h >> index 5431af2..150097f 100644 >> --- a/drivers/gpu/drm/radeon/radeon.h >> +++ b/drivers/gpu/drm/radeon/radeon.h >> @@ -1533,6 +1533,7 @@ struct radeon_device { >> unsigned debugfs_count; >> /* virtual memory */ >> struct radeon_vm_manager vm_manager; >> + struct mutex gpu_clock_mutex; >> }; >> >> int radeon_device_init(struct radeon_device *rdev, >> diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h >> index f4af243..cbba387 100644 >> --- a/drivers/gpu/drm/radeon/radeon_asic.h >> +++ b/drivers/gpu/drm/radeon/radeon_asic.h >> @@ -371,6 +371,7 @@ void r600_kms_blit_copy(struct radeon_device *rdev, >> unsigned num_gpu_pages, >> struct radeon_sa_bo *vb); >> int r600_mc_wait_for_idle(struct radeon_device *rdev); >> +uint64_t r600_get_gpu_clock(struct radeon_device *rdev); >> >> /* >> * rv770,rv730,rv710,rv740 >> @@ -472,5 +473,6 @@ int si_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id); >> void si_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm); >> void si_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm); >> int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); >> +uint64_t si_get_gpu_clock(struct radeon_device *rdev); >> >> #endif >> diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c >> index 742af82..d2e2438 100644 >> --- a/drivers/gpu/drm/radeon/radeon_device.c >> +++ b/drivers/gpu/drm/radeon/radeon_device.c >> @@ -1009,6 +1009,7 @@ int radeon_device_init(struct radeon_device *rdev, >> atomic_set(&rdev->ih.lock, 0); >> mutex_init(&rdev->gem.mutex); >> mutex_init(&rdev->pm.mutex); >> + mutex_init(&rdev->gpu_clock_mutex); >> init_rwsem(&rdev->pm.mclk_lock); >> init_rwsem(&rdev->exclusive_lock); >> init_waitqueue_head(&rdev->irq.vblank_queue); >> diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c >> index a7f8ac0..f940806 100644 >> --- a/drivers/gpu/drm/radeon/radeon_drv.c >> +++ b/drivers/gpu/drm/radeon/radeon_drv.c >> @@ -60,7 +60,7 @@ >> * 2.16.0 - fix evergreen 2D tiled surface calculation >> * 2.17.0 - add STRMOUT_BASE_UPDATE for r7xx >> * 2.18.0 - r600-eg: allow "invalid" DB formats >> - * 2.19.0 - r600-eg: MSAA textures >> + * 2.19.0 - r600-eg: MSAA textures; r600-si: RADEON_INFO_TIMESTAMP query > > Given the failure that have been the streamout one, i would prefer to > also bump the version for timestamp ie 2.20.0 > >> */ >> #define KMS_DRIVER_MAJOR 2 >> #define KMS_DRIVER_MINOR 19 >> diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c >> index 1d73f16..414b4ac 100644 >> --- a/drivers/gpu/drm/radeon/radeon_kms.c >> +++ b/drivers/gpu/drm/radeon/radeon_kms.c >> @@ -29,6 +29,7 @@ >> #include "drm_sarea.h" >> #include "radeon.h" >> #include "radeon_drm.h" >> +#include "radeon_asic.h" >> >> #include >> #include >> @@ -167,17 +168,39 @@ static void radeon_set_filp_rights(struct drm_device *dev, >> 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; >> + struct drm_radeon_info *info = data; >> struct radeon_mode_info *minfo = &rdev->mode_info; >> - uint32_t *value_ptr; >> - uint32_t value; >> + uint32_t value, *value_ptr; >> + uint64_t value64, *value_ptr64; >> struct drm_crtc *crtc; >> int i, found; >> >> - info = data; >> + /* 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); >> + if (rdev->family >= CHIP_TAHITI) { >> + value64 = si_get_gpu_clock(rdev); >> + } else { >> + value64 = r600_get_gpu_clock(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))) >> + if (DRM_COPY_FROM_USER(&value, value_ptr, sizeof(value))) { >> + DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__); >> return -EFAULT; >> + } >> >> switch (info->request) { >> case RADEON_INFO_DEVICE_ID: >> @@ -337,7 +360,7 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) >> return -EINVAL; >> } >> if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) { >> - DRM_ERROR("copy_to_user\n"); >> + DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__); >> return -EFAULT; >> } >> return 0; >> diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c >> index c053f81..0f177d5 100644 >> --- a/drivers/gpu/drm/radeon/si.c >> +++ b/drivers/gpu/drm/radeon/si.c >> @@ -3960,3 +3960,14 @@ void si_fini(struct radeon_device *rdev) >> rdev->bios = NULL; >> } >> >> +uint64_t si_get_gpu_clock(struct radeon_device *rdev) >> +{ >> + uint64_t clock; >> + >> + mutex_lock(&rdev->gpu_clock_mutex); >> + WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1); >> + clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) | >> + ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32); >> + mutex_unlock(&rdev->gpu_clock_mutex); >> + return clock; >> +} >> diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h >> index 7869089..ef4815c 100644 >> --- a/drivers/gpu/drm/radeon/sid.h >> +++ b/drivers/gpu/drm/radeon/sid.h >> @@ -698,6 +698,9 @@ >> #define RLC_UCODE_ADDR 0xC32C >> #define RLC_UCODE_DATA 0xC330 >> >> +#define RLC_GPU_CLOCK_COUNT_LSB 0xC338 >> +#define RLC_GPU_CLOCK_COUNT_MSB 0xC33C >> +#define RLC_CAPTURE_GPU_CLOCK_COUNT 0xC340 >> #define RLC_MC_CNTL 0xC344 >> #define RLC_UCODE_CNTL 0xC348 >> >> diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h >> index 5805686..dc3a8cd 100644 >> --- a/include/drm/radeon_drm.h >> +++ b/include/drm/radeon_drm.h >> @@ -964,6 +964,8 @@ struct drm_radeon_cs { >> #define RADEON_INFO_IB_VM_MAX_SIZE 0x0f >> /* max pipes - needed for compute shaders */ >> #define RADEON_INFO_MAX_PIPES 0x10 >> +/* timestamp for GL_ARB_timer_query (OpenGL), returns the current GPU clock */ >> +#define RADEON_INFO_TIMESTAMP 0x11 >> >> struct drm_radeon_info { >> uint32_t request; >> -- >> 1.7.9.5 >> >> _______________________________________________ >> dri-devel mailing list >> dri-devel@lists.freedesktop.org >> http://lists.freedesktop.org/mailman/listinfo/dri-devel > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/dri-devel From 156c58ff876b8ee76f9a40ec00bf56d37197547b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Thu, 9 Aug 2012 16:34:17 +0200 Subject: [PATCH] drm/radeon/kms: implement timestamp userspace query (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Returns a snapshot of the GPU clock counter. Needed for certain OpenGL extensions. v2: agd5f - address Jerome's comments - add function documentation Signed-off-by: Marek Olšák Reviewed-by: Jerome Glisse Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/r600.c | 20 ++++++++++++++++++ drivers/gpu/drm/radeon/r600d.h | 3 ++ drivers/gpu/drm/radeon/radeon.h | 1 + drivers/gpu/drm/radeon/radeon_asic.h | 2 + drivers/gpu/drm/radeon/radeon_device.c | 1 + drivers/gpu/drm/radeon/radeon_drv.c | 3 +- drivers/gpu/drm/radeon/radeon_kms.c | 35 ++++++++++++++++++++++++++----- drivers/gpu/drm/radeon/si.c | 19 +++++++++++++++++ drivers/gpu/drm/radeon/sid.h | 3 ++ include/drm/radeon_drm.h | 2 + 10 files changed, 82 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 637280f..d79c639 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -3789,3 +3789,23 @@ static void r600_pcie_gen2_enable(struct radeon_device *rdev) WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); } } + +/** + * r600_get_gpu_clock - return GPU clock counter snapshot + * + * @rdev: radeon_device pointer + * + * Fetches a GPU clock counter snapshot (R6xx-cayman). + * Returns the 64 bit clock counter snapshot. + */ +uint64_t r600_get_gpu_clock(struct radeon_device *rdev) +{ + uint64_t clock; + + mutex_lock(&rdev->gpu_clock_mutex); + WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1); + clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) | + ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL); + mutex_unlock(&rdev->gpu_clock_mutex); + return clock; +} diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 4b116ae..fd328f4 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h @@ -602,6 +602,9 @@ #define RLC_HB_WPTR 0x3f1c #define RLC_HB_WPTR_LSB_ADDR 0x3f14 #define RLC_HB_WPTR_MSB_ADDR 0x3f18 +#define RLC_GPU_CLOCK_COUNT_LSB 0x3f38 +#define RLC_GPU_CLOCK_COUNT_MSB 0x3f3c +#define RLC_CAPTURE_GPU_CLOCK_COUNT 0x3f40 #define RLC_MC_CNTL 0x3f44 #define RLC_UCODE_CNTL 0x3f48 #define RLC_UCODE_ADDR 0x3f2c diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index b237a29..9930419 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1534,6 +1534,7 @@ struct radeon_device { unsigned debugfs_count; /* virtual memory */ struct radeon_vm_manager vm_manager; + struct mutex gpu_clock_mutex; }; int radeon_device_init(struct radeon_device *rdev, diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 0d445e7..18c38d1 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -368,6 +368,7 @@ void r600_kms_blit_copy(struct radeon_device *rdev, unsigned num_gpu_pages, struct radeon_sa_bo *vb); int r600_mc_wait_for_idle(struct radeon_device *rdev); +uint64_t r600_get_gpu_clock(struct radeon_device *rdev); /* * rv770,rv730,rv710,rv740 @@ -468,5 +469,6 @@ int si_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id); void si_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm); void si_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm); int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); +uint64_t si_get_gpu_clock(struct radeon_device *rdev); #endif diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 742af82..d2e2438 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -1009,6 +1009,7 @@ int radeon_device_init(struct radeon_device *rdev, atomic_set(&rdev->ih.lock, 0); mutex_init(&rdev->gem.mutex); mutex_init(&rdev->pm.mutex); + mutex_init(&rdev->gpu_clock_mutex); init_rwsem(&rdev->pm.mclk_lock); init_rwsem(&rdev->exclusive_lock); init_waitqueue_head(&rdev->irq.vblank_queue); diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index a7f8ac0..d7269f4 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -61,9 +61,10 @@ * 2.17.0 - add STRMOUT_BASE_UPDATE for r7xx * 2.18.0 - r600-eg: allow "invalid" DB formats * 2.19.0 - r600-eg: MSAA textures + * 2.20.0 - r600-si: RADEON_INFO_TIMESTAMP query */ #define KMS_DRIVER_MAJOR 2 -#define KMS_DRIVER_MINOR 19 +#define KMS_DRIVER_MINOR 20 #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 1d73f16..414b4ac 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -29,6 +29,7 @@ #include "drm_sarea.h" #include "radeon.h" #include "radeon_drm.h" +#include "radeon_asic.h" #include #include @@ -167,17 +168,39 @@ static void radeon_set_filp_rights(struct drm_device *dev, 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; + struct drm_radeon_info *info = data; struct radeon_mode_info *minfo = &rdev->mode_info; - uint32_t *value_ptr; - uint32_t value; + uint32_t value, *value_ptr; + uint64_t value64, *value_ptr64; struct drm_crtc *crtc; int i, found; - info = data; + /* 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); + if (rdev->family >= CHIP_TAHITI) { + value64 = si_get_gpu_clock(rdev); + } else { + value64 = r600_get_gpu_clock(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))) + if (DRM_COPY_FROM_USER(&value, value_ptr, sizeof(value))) { + DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__); return -EFAULT; + } switch (info->request) { case RADEON_INFO_DEVICE_ID: @@ -337,7 +360,7 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) return -EINVAL; } if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) { - DRM_ERROR("copy_to_user\n"); + DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__); return -EFAULT; } return 0; diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index c153a7f..0139e22 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -3968,3 +3968,22 @@ void si_fini(struct radeon_device *rdev) rdev->bios = NULL; } +/** + * si_get_gpu_clock - return GPU clock counter snapshot + * + * @rdev: radeon_device pointer + * + * Fetches a GPU clock counter snapshot (SI). + * Returns the 64 bit clock counter snapshot. + */ +uint64_t si_get_gpu_clock(struct radeon_device *rdev) +{ + uint64_t clock; + + mutex_lock(&rdev->gpu_clock_mutex); + WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1); + clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) | + ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL); + mutex_unlock(&rdev->gpu_clock_mutex); + return clock; +} diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index 7869089..ef4815c 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h @@ -698,6 +698,9 @@ #define RLC_UCODE_ADDR 0xC32C #define RLC_UCODE_DATA 0xC330 +#define RLC_GPU_CLOCK_COUNT_LSB 0xC338 +#define RLC_GPU_CLOCK_COUNT_MSB 0xC33C +#define RLC_CAPTURE_GPU_CLOCK_COUNT 0xC340 #define RLC_MC_CNTL 0xC344 #define RLC_UCODE_CNTL 0xC348 diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h index 5805686..dc3a8cd 100644 --- a/include/drm/radeon_drm.h +++ b/include/drm/radeon_drm.h @@ -964,6 +964,8 @@ struct drm_radeon_cs { #define RADEON_INFO_IB_VM_MAX_SIZE 0x0f /* max pipes - needed for compute shaders */ #define RADEON_INFO_MAX_PIPES 0x10 +/* timestamp for GL_ARB_timer_query (OpenGL), returns the current GPU clock */ +#define RADEON_INFO_TIMESTAMP 0x11 struct drm_radeon_info { uint32_t request; -- 1.7.7.5