From patchwork Wed Jan 25 21:36:55 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergei Shtylyov X-Patchwork-Id: 9538261 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 4F5B1604A7 for ; Thu, 26 Jan 2017 00:42:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3FAC31FF1E for ; Thu, 26 Jan 2017 00:42:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3488427E33; Thu, 26 Jan 2017 00:42:57 +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_SIGNED, 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 6BD781FF1E for ; Thu, 26 Jan 2017 00:42:56 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 68AAC6EAA0; Thu, 26 Jan 2017 00:42:34 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-lf0-x22b.google.com (mail-lf0-x22b.google.com [IPv6:2a00:1450:4010:c07::22b]) by gabe.freedesktop.org (Postfix) with ESMTPS id 95E9889DDF for ; Wed, 25 Jan 2017 21:36:58 +0000 (UTC) Received: by mail-lf0-x22b.google.com with SMTP id z134so136070826lff.3 for ; Wed, 25 Jan 2017 13:36:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cogentembedded-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:organization:user-agent :in-reply-to:references:mime-version:content-transfer-encoding; bh=qKAWbMjLYhHxm8XDwh/ptMxmn7HjPJ2J1Uh5ImMMJXc=; b=zw9sbuh+bHFQRez9Gw4tEcsxqRbFoXl0jFVTTFMLEXWX2Q15ahnjvzmknwAljJ7nPU Og2oWYKsTs1khnFkze0q6Fo8ysgr2Pdp9B+/nRyj7RMdOk7JFyHr8D76Q2vS9T4YDMBC jIYEJsQveN+drv6t6Xhn4zM2MbXUn0Y1GI69ikp5k59RoTK3PJxuIKxPezV/Zfj0UBDu wvv+WeHYJ/OFL1WQHVnjLeK9ntgTQSn4vjuM3CLQMUNpv7i1vbH4fNrk609d2vrKgYEv 4K7NhdxFzNMiKqPfcCqWgv4xmLEPFzXcPJvnih26u8HlptinNVK21p+CoC7+zEzYSIJ/ UJYA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:organization :user-agent:in-reply-to:references:mime-version :content-transfer-encoding; bh=qKAWbMjLYhHxm8XDwh/ptMxmn7HjPJ2J1Uh5ImMMJXc=; b=YPflEk9etlQq4fFSZmhdaoppKMkCFzUbtFKRetDq4JSY25KfqQ6UNWrCWyClbbwZlB AAemrpx+XWdETo2uPM1Z+/vTG+5DMWMs2FrvDlSZtcPIHyhpzhqi03UznA1+mByU8ICp cqdYbN5YBHz0RxTerExF/LEPVhnvdn9Q2CnPhDWz613fui0uzQyS4/qSWI/TIFRm76Ln O46DfoeoJFOsReBNiOIo0yqpJkUjprg+O9MUiFMD4yWjSf7bsizJdPfPkGgDVjqiDVRa p1f92BEPgQWe9D7s6rsPe9ekScn/F5yJI53FOdBWhYomK6+RoDNd3zOtynQCHfvvhbos 0PSg== X-Gm-Message-State: AIkVDXLsNs87qKw2uhz67vEejnwfiTVxpuTGYGy0cZT3FM1c3x88sNciZ+OEhIuBfAdgZQ== X-Received: by 10.46.72.1 with SMTP id v1mr15618157lja.12.1485380216844; Wed, 25 Jan 2017 13:36:56 -0800 (PST) Received: from wasted.cogentembedded.com ([31.173.85.38]) by smtp.gmail.com with ESMTPSA id u126sm8671565lja.25.2017.01.25.13.36.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 25 Jan 2017 13:36:56 -0800 (PST) From: Sergei Shtylyov To: laurent.pinchart@ideasonboard.com, airlied@linux.ie, dri-devel@lists.freedesktop.org, daniel.vetter@intel.com, jani.nikula@linux.intel.com, seanpaul@chromium.org Subject: [PATCH v3 2/3] drm: Connect live source to framebuffers Date: Thu, 26 Jan 2017 00:36:55 +0300 Message-ID: <4381980.kUHGeUXACq@wasted.cogentembedded.com> Organization: Cogent Embedded Inc. User-Agent: KMail/4.14.10 (Linux/4.8.13-100.fc23.x86_64; KDE/4.14.20; x86_64; ; ) In-Reply-To: <1542778.dcWpka5Jpx@wasted.cogentembedded.com> References: <1542778.dcWpka5Jpx@wasted.cogentembedded.com> MIME-Version: 1.0 X-Mailman-Approved-At: Thu, 26 Jan 2017 00:42:12 +0000 Cc: linux-renesas-soc@vger.kernel.org, linux-kernel@vger.kernel.org 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: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Laurent Pinchart Introduce a new live source flag for framebuffers. When a framebuffer is created with that flag set, a live source is associated with the framebuffer instead of buffer objects. The framebuffer can then be used with a plane to connect it with the live source. [Sergei: ported to the modern kernel.] Signed-off-by: Laurent Pinchart Signed-off-by: Sergei Shtylyov --- Changes in version 3: - ported the patch to the modern kernel; - added my signoff. drivers/gpu/drm/drm_framebuffer.c | 134 ++++++++++++++++++++++++++++++-------- include/uapi/drm/drm_mode.h | 7 + 2 files changed, 113 insertions(+), 28 deletions(-) Index: linux/drivers/gpu/drm/drm_framebuffer.c =================================================================== --- linux.orig/drivers/gpu/drm/drm_framebuffer.c +++ linux/drivers/gpu/drm/drm_framebuffer.c @@ -126,34 +126,18 @@ int drm_mode_addfb(struct drm_device *de return 0; } -static int framebuffer_check(const struct drm_mode_fb_cmd2 *r) +static int framebuffer_check_buffers(const struct drm_mode_fb_cmd2 *r, + int hsub, int vsub) { - const struct drm_format_info *info; - int i; + int num_planes, i; + unsigned int cpp; - info = __drm_format_info(r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN); - if (!info) { - struct drm_format_name_buf format_name; - DRM_DEBUG_KMS("bad framebuffer format %s\n", - drm_get_format_name(r->pixel_format, - &format_name)); - return -EINVAL; - } - - if (r->width == 0 || r->width % info->hsub) { - DRM_DEBUG_KMS("bad framebuffer width %u\n", r->width); - return -EINVAL; - } - - if (r->height == 0 || r->height % info->vsub) { - DRM_DEBUG_KMS("bad framebuffer height %u\n", r->height); - return -EINVAL; - } + num_planes = drm_format_num_planes(r->pixel_format); + cpp = drm_format_plane_cpp(r->pixel_format, 0); - for (i = 0; i < info->num_planes; i++) { - unsigned int width = r->width / (i != 0 ? info->hsub : 1); - unsigned int height = r->height / (i != 0 ? info->vsub : 1); - unsigned int cpp = info->cpp[i]; + for (i = 0; i < num_planes; i++) { + unsigned int width = r->width / (i != 0 ? hsub : 1); + unsigned int height = r->height / (i != 0 ? vsub : 1); if (!r->handles[i]) { DRM_DEBUG_KMS("no buffer object handle for plane %d\n", i); @@ -203,7 +187,7 @@ static int framebuffer_check(const struc } } - for (i = info->num_planes; i < 4; i++) { + for (i = num_planes; i < 4; i++) { if (r->modifier[i]) { DRM_DEBUG_KMS("non-zero modifier for unused plane %d\n", i); return -EINVAL; @@ -232,6 +216,99 @@ static int framebuffer_check(const struc return 0; } +static int framebuffer_check_sources(struct drm_device *dev, + const struct drm_mode_fb_cmd2 *r) +{ + struct drm_mode_object *obj; + struct drm_live_source *src; + unsigned int cpp; + unsigned int i; + + /* + * Ensure that userspace has zeroed unused handles, pitches, offsets and + * modifiers to allow future API extensions. + */ + if (r->offsets[0] || r->modifier[0]) + return -EINVAL; + + for (i = 1; i < ARRAY_SIZE(r->handles); ++i) { + if (r->handles[i] || r->pitches[i] || + r->offsets[i] || r->modifier[i]) + return -EINVAL; + } + + /* Validate width, height and pitch. */ + cpp = drm_format_plane_cpp(r->pixel_format, 0); + + if ((uint64_t) r->width * cpp > UINT_MAX) + return -ERANGE; + + if ((uint64_t) r->height * r->pitches[0] > UINT_MAX) + return -ERANGE; + + if (r->pitches[0] != r->width * cpp) { + DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[0], i); + return -EINVAL; + } + + /* + * Find the live source and check whether it supports the requested + * pixel format. + */ + + obj = drm_mode_object_find(dev, r->handles[0], + DRM_MODE_OBJECT_LIVE_SOURCE); + if (!obj) { + DRM_DEBUG_KMS("bad framebuffer source ID %u\n", r->handles[0]); + return -EINVAL; + } + + src = obj_to_live_source(obj); + + for (i = 0; i < src->format_count; i++) { + if (r->pixel_format == src->format_types[i]) + break; + } + + if (i == src->format_count) { + DRM_DEBUG_KMS("bad framebuffer pixel format 0x%08x for source %u\n", + r->pixel_format, r->handles[0]); + return -EINVAL; + } + + return 0; +} + +static int framebuffer_check(struct drm_device *dev, + const struct drm_mode_fb_cmd2 *r) +{ + const struct drm_format_info *info; + + info = __drm_format_info(r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN); + if (!info) { + struct drm_format_name_buf format_name; + DRM_DEBUG_KMS("bad framebuffer format %s\n", + drm_get_format_name(r->pixel_format, + &format_name)); + return -EINVAL; + } + + if (r->width == 0 || r->width % info->hsub) { + DRM_DEBUG_KMS("bad framebuffer width %u\n", r->width); + return -EINVAL; + } + + if (r->height == 0 || r->height % info->vsub) { + DRM_DEBUG_KMS("bad framebuffer height %u\n", r->height); + return -EINVAL; + } + + if (r->flags & DRM_MODE_FB_LIVE_SOURCE) + return framebuffer_check_sources(dev, r); + else + return framebuffer_check_buffers(r, info->hsub, info->vsub); +} + struct drm_framebuffer * drm_internal_framebuffer_create(struct drm_device *dev, const struct drm_mode_fb_cmd2 *r, @@ -241,7 +318,8 @@ drm_internal_framebuffer_create(struct d struct drm_framebuffer *fb; int ret; - if (r->flags & ~(DRM_MODE_FB_INTERLACED | DRM_MODE_FB_MODIFIERS)) { + if (r->flags & ~(DRM_MODE_FB_INTERLACED | DRM_MODE_FB_MODIFIERS | + DRM_MODE_FB_LIVE_SOURCE)) { DRM_DEBUG_KMS("bad framebuffer flags 0x%08x\n", r->flags); return ERR_PTR(-EINVAL); } @@ -263,7 +341,7 @@ drm_internal_framebuffer_create(struct d return ERR_PTR(-EINVAL); } - ret = framebuffer_check(r); + ret = framebuffer_check(dev, r); if (ret) return ERR_PTR(ret); Index: linux/include/uapi/drm/drm_mode.h =================================================================== --- linux.orig/include/uapi/drm/drm_mode.h +++ linux/include/uapi/drm/drm_mode.h @@ -405,6 +405,7 @@ struct drm_mode_fb_cmd { #define DRM_MODE_FB_INTERLACED (1<<0) /* for interlaced framebuffers */ #define DRM_MODE_FB_MODIFIERS (1<<1) /* enables ->modifer[] */ +#define DRM_MODE_FB_LIVE_SOURCE (1<<2) /* connected to a live source */ struct drm_mode_fb_cmd2 { __u32 fb_id; @@ -436,6 +437,12 @@ struct drm_mode_fb_cmd2 { * Thus all combinations of different data layouts for * multi plane formats must be enumerated as separate * modifiers. + * + * If the DRM_MODE_FB_LIVE_SOURCE flag is set the frame buffer input + * comes from a live source instead of from memory. The handles[0] + * field contains the ID of the connected live source object. All other + * handles and all pitches, offsets and modifiers are then ignored by + * the kernel and must be set to zero by applications. */ __u32 handles[4]; __u32 pitches[4]; /* pitch for each plane */