From patchwork Fri Dec 23 17:49:17 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 9487631 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 901FC601C0 for ; Fri, 23 Dec 2016 17:49:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 84D072522B for ; Fri, 23 Dec 2016 17:49:45 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 79ABD26212; Fri, 23 Dec 2016 17:49:45 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 004F32522B for ; Fri, 23 Dec 2016 17:49:44 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 35AA06E116; Fri, 23 Dec 2016 17:49:37 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wj0-x243.google.com (mail-wj0-x243.google.com [IPv6:2a00:1450:400c:c01::243]) by gabe.freedesktop.org (Postfix) with ESMTPS id 65E5A6E112 for ; Fri, 23 Dec 2016 17:49:26 +0000 (UTC) Received: by mail-wj0-x243.google.com with SMTP id j10so41199126wjb.3 for ; Fri, 23 Dec 2016 09:49:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=kGKfLTPMjFMtzQ3B0DHdRdJQ11hIbT9ZatMDOLZQgxw=; b=FGyCA0AUCw/LZbCiOQ69MkjNFNcWr9wfCGiNatf4Q00wJyF3XzMGoyaWSIJ1v8f5Am RWoHze5HYA8wTdNAn2WI7+KNnzyORHn8MHjpXNXpuSTMAh6eh5JOPM3pZhG2hEGbAtnY mSbzsg1f7HJ0JrHnYopMRjdkvKezUKpJAtz9Rtk45LiVQX2u1ogs98yU04OkqchVoXyX /733yqh2ux0gNLT5THfvwFkFwLVarFU20ubAG5VCrz4G90EEM/Jl7f+c4p7DM8piZZ2b ivTXnB30rHG7rbCqqL0mpeA7gBjJWN0w7pfb+JEQWqz3lqw50TB0WMsKnI7pcIT8w0IL q/2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=kGKfLTPMjFMtzQ3B0DHdRdJQ11hIbT9ZatMDOLZQgxw=; b=URl72SnPXtZfTIkte5K29WXAHaeW2EX7lhr/F4hjRgv/k+uc8NjUG2i0547gTrZ3YB zhJATFG+i0Qyul0f9XWGPqHohQr7kb+x8B2sRUNLkkU+5ZTMRu5sWHy6JAjUDaWasbcd 9Ll49IcSWm8uZFumlcMj3Wwl/fmUIDpnTRdtx7et351hjKRXHGX0nmxUdGiu3IEDmqGO kqmZ5yVCH+KEPF+FZ+5UxHZTb7pV4R0AF8oAoMqNd9yR92le5UaS8/A6sDjE/t9Jqomq 6a/XvPNSX7fSJF1ioTPnhCkI9nrjG2RwamCHUnkDK6mgHbenIWRDCIukTLte9z42jNAO +PXA== X-Gm-Message-State: AIkVDXJS9b1zdXTnwTchx0NQ9azZynJ+WCAxTANDBJMvenPrxpFcS2tncU2NDIcElo8Fpw== X-Received: by 10.194.82.8 with SMTP id e8mr14138164wjy.97.1482515363985; Fri, 23 Dec 2016 09:49:23 -0800 (PST) Received: from localhost (port-7589.pppoe.wtnet.de. [84.46.29.194]) by smtp.gmail.com with ESMTPSA id k11sm37971633wmf.24.2016.12.23.09.49.23 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 23 Dec 2016 09:49:23 -0800 (PST) From: Thierry Reding To: dri-devel@lists.freedesktop.org Subject: [PATCH libdrm 3/3] xf86drm: Add platform and host1x bus support Date: Fri, 23 Dec 2016 18:49:17 +0100 Message-Id: <20161223174917.29267-4-thierry.reding@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20161223174917.29267-1-thierry.reding@gmail.com> References: <20161223174917.29267-1-thierry.reding@gmail.com> X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Thierry Reding ARM SoCs usually have their DRM/KMS devices on the platform bus, so add support for that to enable these devices to be used with the drmDevice infrastructure. NVIDIA Tegra SoCs have an additional level in the hierarchy and DRM/KMS devices can also be on the host1x bus. This is mostly equivalent to the platform bus. Signed-off-by: Thierry Reding --- Note that we could probably get away with treating host1x as platform bus. However, they are technically two different busses in the kernel and hence we may want to make use of that differentiation later on. xf86drm.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ xf86drm.h | 24 ++++++++- 2 files changed, 186 insertions(+), 2 deletions(-) diff --git a/xf86drm.c b/xf86drm.c index f0171c34c958..69887accb3cb 100644 --- a/xf86drm.c +++ b/xf86drm.c @@ -2905,6 +2905,12 @@ static int drmParseSubsystemType(int maj, int min) if (strncmp(name, "/usb", 4) == 0) return DRM_BUS_USB; + if (strncmp(name, "/platform", 9) == 0) + return DRM_BUS_PLATFORM; + + if (strncmp(name, "/host1x", 7) == 0) + return DRM_BUS_HOST1X; + return -EINVAL; #elif defined(__OpenBSD__) return DRM_BUS_PCI; @@ -2995,6 +3001,12 @@ static int drmCompareBusInfo(drmDevicePtr a, drmDevicePtr b) case DRM_BUS_USB: return memcmp(a->businfo.usb, b->businfo.usb, sizeof(drmUsbBusInfo)); + case DRM_BUS_PLATFORM: + return memcmp(a->businfo.platform, b->businfo.platform, sizeof(drmPlatformBusInfo)); + + case DRM_BUS_HOST1X: + return memcmp(a->businfo.host1x, b->businfo.host1x, sizeof(drmHost1xBusInfo)); + default: break; } @@ -3357,6 +3369,128 @@ free_device: return ret; } +static int drmParsePlatformBusInfo(int maj, int min, drmPlatformBusInfoPtr info) +{ + char path[PATH_MAX + 1], *name; + + snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device", maj, min); + + name = sysfs_uevent_get(path, "OF_FULLNAME"); + strcpy(info->fullname, name); + free(name); + + return 0; +} + +static int drmParsePlatformDeviceInfo(int maj, int min, + drmPlatformDeviceInfoPtr info) +{ + /* XXX fill in platform device info */ + + return 0; +} + +static int drmProcessPlatformDevice(drmDevicePtr *device, + const char *node, int node_type, + int maj, int min, bool fetch_deviceinfo, + uint32_t flags) +{ + drmDevicePtr dev; + char *ptr; + int ret; + + dev = drmDeviceAlloc(node_type, node, sizeof(drmPlatformBusInfo), + sizeof(drmPlatformDeviceInfo), &ptr); + if (!dev) + return -ENOMEM; + + dev->bustype = DRM_BUS_PLATFORM; + + dev->businfo.platform = (drmPlatformBusInfoPtr)ptr; + + ret = drmParsePlatformBusInfo(maj, min, dev->businfo.platform); + if (ret < 0) + goto free_device; + + if (fetch_deviceinfo) { + ptr += sizeof(drmPlatformBusInfo); + dev->deviceinfo.platform = (drmPlatformDeviceInfoPtr)ptr; + + ret = drmParsePlatformDeviceInfo(maj, min, dev->deviceinfo.platform); + if (ret < 0) + goto free_device; + } + + *device = dev; + + return 0; + +free_device: + free(dev); + return ret; +} + +static int drmParseHost1xBusInfo(int maj, int min, drmHost1xBusInfoPtr info) +{ + char path[PATH_MAX + 1], *name; + + snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device", maj, min); + + name = sysfs_uevent_get(path, "OF_FULLNAME"); + strcpy(info->fullname, name); + free(name); + + return 0; +} + +static int drmParseHost1xDeviceInfo(int maj, int min, + drmHost1xDeviceInfoPtr info) +{ + /* XXX fill in host1x device info */ + + return 0; +} + +static int drmProcessHost1xDevice(drmDevicePtr *device, + const char *node, int node_type, + int maj, int min, bool fetch_deviceinfo, + uint32_t flags) +{ + drmDevicePtr dev; + char *ptr; + int ret; + + dev = drmDeviceAlloc(node_type, node, sizeof(drmHost1xBusInfo), + sizeof(drmHost1xDeviceInfo), &ptr); + if (!dev) + return -ENOMEM; + + dev->bustype = DRM_BUS_HOST1X; + + dev->businfo.host1x = (drmHost1xBusInfoPtr)ptr; + + ret = drmParseHost1xBusInfo(maj, min, dev->businfo.host1x); + if (ret < 0) + goto free_device; + + if (fetch_deviceinfo) { + ptr += sizeof(drmHost1xBusInfo); + dev->deviceinfo.host1x = (drmHost1xDeviceInfoPtr)ptr; + + ret = drmParseHost1xDeviceInfo(maj, min, dev->deviceinfo.host1x); + if (ret < 0) + goto free_device; + } + + *device = dev; + + return 0; + +free_device: + free(dev); + return ret; +} + /* Consider devices located on the same bus as duplicate and fold the respective * entries into a single one. * @@ -3536,6 +3670,20 @@ int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device) break; + case DRM_BUS_PLATFORM: + ret = drmProcessPlatformDevice(&d, node, node_type, maj, min, true, flags); + if (ret) + goto free_devices; + + break; + + case DRM_BUS_HOST1X: + ret = drmProcessHost1xDevice(&d, node, node_type, maj, min, true, flags); + if (ret) + goto free_devices; + + break; + default: continue; } @@ -3676,6 +3824,22 @@ int drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_devices) break; + case DRM_BUS_PLATFORM: + ret = drmProcessPlatformDevice(&device, node, node_type, maj, min, + devices != NULL, flags); + if (ret) + goto free_devices; + + break; + + case DRM_BUS_HOST1X: + ret = drmProcessHost1xDevice(&device, node, node_type, maj, min, + devices != NULL, flags); + if (ret) + goto free_devices; + + break; + default: continue; } diff --git a/xf86drm.h b/xf86drm.h index 65d5321950fc..eeb19e5e187e 100644 --- a/xf86drm.h +++ b/xf86drm.h @@ -766,8 +766,10 @@ extern int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle); extern char *drmGetPrimaryDeviceNameFromFd(int fd); extern char *drmGetRenderDeviceNameFromFd(int fd); -#define DRM_BUS_PCI 0 -#define DRM_BUS_USB 1 +#define DRM_BUS_PCI 0 +#define DRM_BUS_USB 1 +#define DRM_BUS_PLATFORM 2 +#define DRM_BUS_HOST1X 3 typedef struct _drmPciBusInfo { uint16_t domain; @@ -794,6 +796,20 @@ typedef struct _drmUsbDeviceInfo { uint16_t product; } drmUsbDeviceInfo, *drmUsbDeviceInfoPtr; +typedef struct _drmPlatformBusInfo { + char fullname[512]; +} drmPlatformBusInfo, *drmPlatformBusInfoPtr; + +typedef struct _drmPlatformDeviceInfo { +} drmPlatformDeviceInfo, *drmPlatformDeviceInfoPtr; + +typedef struct _drmHost1xBusInfo { + char fullname[512]; +} drmHost1xBusInfo, *drmHost1xBusInfoPtr; + +typedef struct _drmHost1xDeviceInfo { +} drmHost1xDeviceInfo, *drmHost1xDeviceInfoPtr; + typedef struct _drmDevice { char **nodes; /* DRM_NODE_MAX sized array */ int available_nodes; /* DRM_NODE_* bitmask */ @@ -801,10 +817,14 @@ typedef struct _drmDevice { union { drmPciBusInfoPtr pci; drmUsbBusInfoPtr usb; + drmPlatformBusInfoPtr platform; + drmHost1xBusInfoPtr host1x; } businfo; union { drmPciDeviceInfoPtr pci; drmUsbDeviceInfoPtr usb; + drmPlatformDeviceInfoPtr platform; + drmHost1xDeviceInfoPtr host1x; } deviceinfo; } drmDevice, *drmDevicePtr;