From patchwork Tue Apr 5 19:33:35 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 688651 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p35JYhdk005729 for ; Tue, 5 Apr 2011 19:35:03 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id EC4BC9ED95 for ; Tue, 5 Apr 2011 12:34:42 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from cloud01.chad-versace.us (184-106-247-128.static.cloud-ips.com [184.106.247.128]) by gabe.freedesktop.org (Postfix) with ESMTP id 134019E852 for ; Tue, 5 Apr 2011 12:33:46 -0700 (PDT) Received: from localhost.localdomain (unknown [67.208.96.87]) by cloud01.chad-versace.us (Postfix) with ESMTPSA id E89C01D406B; Tue, 5 Apr 2011 19:34:33 +0000 (UTC) From: Ben Widawsky To: intel-gfx@lists.freedesktop.org Date: Tue, 5 Apr 2011 12:33:35 -0700 Message-Id: <1302032017-1771-2-git-send-email-ben@bwidawsk.net> X-Mailer: git-send-email 1.7.3.4 In-Reply-To: <1302032017-1771-1-git-send-email-ben@bwidawsk.net> References: <1302032017-1771-1-git-send-email-ben@bwidawsk.net> Subject: [Intel-gfx] [intel-gpu-tools] [PATCH 1/3] intel-gpu-tools add ioctl interface usage X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Tue, 05 Apr 2011 19:35:25 +0000 (UTC) Added the mechnanism to communicate with the i915 IOCTL interface, and removed the existing forcewake code, as it is not reliable. Modified gpu_top to take a flag -i, to use the IOCTL interface. Previous gpu_top behavior with no args is maintained from previous version. Signed-off-by: Ben Widawsky --- lib/intel_gpu_tools.h | 58 +++++++++++++++++++++++++++++++++++++++++++++++- lib/intel_mmio.c | 18 +++++++++++++++ tools/intel_gpu_top.c | 45 +++++++++++-------------------------- 3 files changed, 88 insertions(+), 33 deletions(-) diff --git a/lib/intel_gpu_tools.h b/lib/intel_gpu_tools.h index acee657..b45d6f9 100644 --- a/lib/intel_gpu_tools.h +++ b/lib/intel_gpu_tools.h @@ -26,29 +26,83 @@ */ #include +#include +#include +#include #include +#include #include #include "intel_chipset.h" #include "intel_reg.h" +#include "i915_drm.h" #define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0])) extern void *mmio; +extern int mmio_fd; +extern int use_ioctl_mmio; void intel_get_mmio(struct pci_device *pci_dev); +#define INREG(reg) \ + (use_ioctl_mmio ? INREG_IOCTL(reg) : INREG_PCI(reg)) + +#define OUTREG(reg, val) \ + (use_ioctl_mmio ? OUTREG_IOCTL(reg, val) : OUTREG_PCI(reg, val)) + static inline uint32_t -INREG(uint32_t reg) +INREG_PCI(uint32_t reg) { return *(volatile uint32_t *)((volatile char *)mmio + reg); } +/* + * Try to read a register using the i915 IOCTL interface. The operations should + * not fall back to the normal pci mmio method to avoid confusion. IOCTL usage + * should be explicitly specified. + */ +static inline uint32_t +INREG_IOCTL(uint32_t reg) +{ + int err; + struct drm_intel_read_reg reg_read = { + .offset = reg, + .size = 0 + }; + + assert(mmio_fd >= 0); + err = ioctl(mmio_fd, DRM_IOCTL_I915_READ_REGISTER, ®_read); + if (err) + fprintf(stderr, "read 0x%08x fail %s\n", reg, strerror(err)); + return (uint32_t)reg_read.value; +} + static inline void -OUTREG(uint32_t reg, uint32_t val) +OUTREG_PCI(uint32_t reg, uint32_t val) { *(volatile uint32_t *)((volatile char *)mmio + reg) = val; } +/* + * See INREG_IOCTL() + */ + +static inline void +OUTREG_IOCTL(uint32_t reg, uint32_t val) +{ + int err; + struct drm_intel_write_reg reg_write = { + .offset = reg, + .size = 4, + .value = (uint64_t)val + }; + + assert(mmio_fd >= 0); + err = ioctl(mmio_fd, DRM_IOCTL_I915_WRITE_REGISTER, ®_write); + if (err) + fprintf(stderr, "write 0x%08x fail %s\n", reg, strerror(err)); +} + struct pci_device *intel_get_pci_device(void); uint32_t intel_get_drm_devid(int fd); diff --git a/lib/intel_mmio.c b/lib/intel_mmio.c index 0228a87..a98c9c7 100644 --- a/lib/intel_mmio.c +++ b/lib/intel_mmio.c @@ -40,6 +40,9 @@ #include "intel_gpu_tools.h" void *mmio; +int mmio_fd = -1; +/* ioctls are not default */ +int use_ioctl_mmio = 0; void intel_map_file(char *file) @@ -60,6 +63,9 @@ intel_map_file(char *file) strerror(errno)); exit(1); } + + mmio_fd = fd; + close(fd); } @@ -87,5 +93,17 @@ intel_get_mmio(struct pci_device *pci_dev) strerror(err)); exit(1); } + + if (!use_ioctl_mmio) + return; + + /* XXX: this is major lame, we need to have the device file match the + * pci_dev, any good way to do that? */ + mmio_fd = drm_open_any(); + if (mmio_fd == -1) { + fprintf(stderr, "Couldn't get an fd for gen6 device\n"); + exit(1); + } + } diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c index e9fbf43..b8ade4a 100644 --- a/tools/intel_gpu_top.c +++ b/tools/intel_gpu_top.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include "intel_gpu_tools.h" #include "instdone.h" @@ -297,33 +298,6 @@ struct ring { int idle; }; -static void gen6_force_wake_get(void) -{ - int count; - - if (!IS_GEN6(devid)) - return; - - /* This will probably have undesirable side-effects upon the system. */ - count = 0; - while (count++ < 50 && (INREG(FORCEWAKE_ACK) & 1)) - usleep(10); - - OUTREG(FORCEWAKE, 1); - - count = 0; - while (count++ < 50 && (INREG(FORCEWAKE_ACK) & 1) == 0) - usleep(10); -} - -static void gen6_force_wake_put(void) -{ - if (!IS_GEN6(devid)) - return; - - OUTREG(FORCEWAKE, 0); -} - static uint32_t ring_read(struct ring *ring, uint32_t reg) { return INREG(ring->mmio + reg); @@ -331,9 +305,7 @@ static uint32_t ring_read(struct ring *ring, uint32_t reg) static void ring_init(struct ring *ring) { - gen6_force_wake_get(); ring->size = (((ring_read(ring, RING_LEN) & RING_NR_PAGES) >> 12) + 1) * 4096; - gen6_force_wake_put(); } static void ring_reset(struct ring *ring) @@ -348,10 +320,8 @@ static void ring_sample(struct ring *ring) if (!ring->size) return; - gen6_force_wake_get(); ring->head = ring_read(ring, RING_HEAD) & HEAD_ADDR; ring->tail = ring_read(ring, RING_TAIL) & TAIL_ADDR; - gen6_force_wake_put(); if (ring->tail == ring->head) ring->idle++; @@ -397,11 +367,24 @@ int main(int argc, char **argv) }; int i; + if (argc == 2) { + if ((strlen(argv[1]) == 2) && + !strncmp(argv[1], "-i", 2)) { + printf("using ioctl mmio access\n"); + use_ioctl_mmio = 1; + } + } + pci_dev = intel_get_pci_device(); devid = pci_dev->device_id; intel_get_mmio(pci_dev); init_instdone_definitions(devid); + if (IS_GEN6(devid) && !use_ioctl_mmio) + fprintf(stderr, "using ioctl for mmio " + " read/write is recommended (%s -i)\n", + argv[0]); + for (i = 0; i < num_instdone_bits; i++) { top_bits[i].bit = &instdone_bits[i]; top_bits[i].count = 0;