From patchwork Wed Sep 18 14:22:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Zimmermann X-Patchwork-Id: 11150453 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B09DB1745 for ; Wed, 18 Sep 2019 14:23:23 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 98DEC2067B for ; Wed, 18 Sep 2019 14:23:23 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 98DEC2067B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.de Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D94216F3BC; Wed, 18 Sep 2019 14:23:15 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mx1.suse.de (mx2.suse.de [195.135.220.15]) by gabe.freedesktop.org (Postfix) with ESMTPS id 482306F3B8 for ; Wed, 18 Sep 2019 14:23:14 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 04ADEB673; Wed, 18 Sep 2019 14:23:11 +0000 (UTC) From: Thomas Zimmermann To: airlied@linux.ie, daniel@ffwll.ch, kraxel@redhat.com, sam@ravnborg.org, yc_chen@aspeedtech.com, corbet@lwn.net Subject: [PATCH 01/11] drm/vram: Add struct drm_vram_buffer to VRAM helpers Date: Wed, 18 Sep 2019 16:22:57 +0200 Message-Id: <20190918142307.27127-2-tzimmermann@suse.de> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190918142307.27127-1-tzimmermann@suse.de> References: <20190918142307.27127-1-tzimmermann@suse.de> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Zimmermann , dri-devel@lists.freedesktop.org, linux-doc@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Drivers with dedicated video memory occasionally need to reserve a memory area for a specific purpose, such as cursor images or sprites. Using GEM VRAM buffer objects can be problematic. For small buffers, GEM VRAM buffer objects are inefficient as they are aligned to page boundaries. And they cannot easily be placed at specific memory offsets. This can lead to memory fragmentation and is a problem for hardware with only a small amount of memory. The data structure struct drm_vram_buffer manages an area of video memory. In contrast to GEM VRAM buffer objects, the memory is of static size and dedicated to a single purpose. The area can be of any size and places at an arbitrary offset. A single buffer can hold multiple frames. A use case is in ast's and mgag200's cursor handling. Each driver reserves a small amount of dedicated video memory (<=32 KiB) that holds a double-buffered cursor image. The image is in a HW-specific, non-standard format. With a VRAM buffer, the dedicated memory can be of an optimal size and located at the high end of video memory. The remaining video memory is available for the framebuffer's GEM VRAM buffer objects. Signed-off-by: Thomas Zimmermann --- Documentation/gpu/drm-mm.rst | 19 +- drivers/gpu/drm/drm_vram_helper_common.c | 259 ++++++++++++++++++++++- include/drm/drm_vram_helper.h | 64 ++++++ 3 files changed, 335 insertions(+), 7 deletions(-) create mode 100644 include/drm/drm_vram_helper.h diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst index 99d56015e077..eac12bd0ea3f 100644 --- a/Documentation/gpu/drm-mm.rst +++ b/Documentation/gpu/drm-mm.rst @@ -379,15 +379,12 @@ GEM CMA Helper Functions Reference .. kernel-doc:: drivers/gpu/drm/drm_gem_cma_helper.c :export: -VRAM Helper Function Reference -============================== +VRAM Helper Library +=================== .. kernel-doc:: drivers/gpu/drm/drm_vram_helper_common.c :doc: overview -.. kernel-doc:: include/drm/drm_gem_vram_helper.h - :internal: - GEM VRAM Helper Functions Reference ----------------------------------- @@ -400,6 +397,18 @@ GEM VRAM Helper Functions Reference .. kernel-doc:: drivers/gpu/drm/drm_gem_vram_helper.c :export: +VRAM Buffer Function Reference +------------------------------ + +.. kernel-doc:: drivers/gpu/drm/drm_vram_helper_common.c + :doc: vbuf overview + +.. kernel-doc:: include/drm/drm_vram_helper.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_vram_helper_common.c + :export: + GEM TTM Helper Functions Reference ----------------------------------- diff --git a/drivers/gpu/drm/drm_vram_helper_common.c b/drivers/gpu/drm/drm_vram_helper_common.c index 2000d9b33fd5..ec55fa374edc 100644 --- a/drivers/gpu/drm/drm_vram_helper_common.c +++ b/drivers/gpu/drm/drm_vram_helper_common.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later +#include #include /** @@ -8,9 +9,11 @@ * This library provides &struct drm_gem_vram_object (GEM VRAM), a GEM * buffer object that is backed by video RAM. It can be used for * framebuffer devices with dedicated memory. The video RAM is managed - * by &struct drm_vram_mm (VRAM MM). + * by &struct drm_vram_mm (VRAM MM). For very simple use cases, + * &struct drm_vram_buffer provides management of memory buffers with + * static size. * - * With the GEM interface userspace applications create, manage and destroy + * With the GEM interface, userspace applications create, manage and destroy * graphics buffers, such as an on-screen framebuffer. GEM does not provide * an implementation of these interfaces. It's up to the DRM driver to * provide an implementation that suits the hardware. If the hardware device @@ -88,7 +91,259 @@ * drm_gem_vram_kmap(). It (optionally) maps the buffer into kernel address * space and returns the memory address. Use drm_gem_vram_kunmap() to * release the mapping. + * + * Occasionally, it is easier and more efficient to dedicate a memory + * buffer to certain functionality and not bother with GEM. One example is + * hardware cursor support. Such buffers are typically small or have uncommon + * pixel formats, such as a small color palette or a reduced number of bits + * per pixel. DRM GEM objects and framebuffers can often not be used directly + * with such functionality, as an additional dithering step is required. + * Maintaining such buffers with GEM objects can lead to memory fragmentation, + * which is a problem for devices with only a small amount of VRAM. + * + * The data structure &struct drm_vram_buffer and its helpers provide memory + * management for these use cases. Each instance of &struct drm_vram_buffer + * handles a dedicated area of VRAM. It offers double buffering (or more) + * and access to the current front and back buffer. + * + * For example, assume a hardware cursor with 64 x 64 pixels and 2 bytes per + * pixel. Storing this cursor's image requires 8 KiB of VRAM. The VRAM buffer + * could manage this memory as shown below. + * + * .. code-block:: c + * + * static const struct drm_vram_buffer_funcs funcs = { + * .update = do_update, // see below + * .set_base = do_set_base, // see below + * }; + * + * struct drm_vram_buffer vbuf; + * + * drm_vram_buffer_init(&vbuf, 0x0ul, 16 * 1024 * 1024, 0, 2, + * &funcs); + * + * A call to drm_vram_buffer_init() initializes the VRAM buffer. The + * cursor-image buffer is located at VRAM address 0x0. It is 16 KiB in + * size to allow for double buffering. The implementation auto-detects the + * frame size (i.e., the size of each individual sub-buffer) from the number + * of frames, which is 2. Finally there's a structure of call-back functions, + * which are explained below. The rest of VRAM memory can be managed with + * other memory managers, such as other VRAM buffers or GEM VRAM helpers. + * + * A call to drm_vram_buffer_cleanup() releases the VRAM buffer. + * + * .. code-block:: c + * + * drm_vram_buffer_cleanup(&vbuf); + * + * Displaying a VRAM buffer is a two-step process. The first step fills the + * current back buffer, the second step swaps buffers and sends the new front + * buffer's offset to the display's scanout engine. The first step should be + * performed in the cursor plane's &struct drm_plane_helper_funcs.prepare_fb() + * callback, the second step should be located in the plane's + * &struct drm_plane_helper_funcs.atomic_update() callback. + * + * .. code-block:: c + * + * int prepare_fb(struct drm_plane *plane, + * struct drm_plane_state *new_state) + * { + * int width = new_state->fb->width; + * int height = new_state->fb->height; + * void *src = ...; // memory buffer of new_state->fb + * + * drm_vram_buffer_update(&vbuf, src, width, height); + * } + * + * void atomic_update(struct drm_plane *plane, + * struct drm_plane_state *old_state) + * { + * drm_vram_buffer_swap(&vbuf); + * } + * + * The call to drm_vram_buffer_update() looks up the next available back + * buffer and gives its address to the VRAM buffer's + * &struct drm_vram_buffer_funcs.update() callback; together with the other + * arguments. After a successful call the back buffer is ready for displaying. + * This is done by the call to drm_vram_buffer_swap(). + * + * The implementation of do_update() and do_set_base() looks something like + * shown below. + * + * .. code-block:: c + * + * int do_update(struct drm_vram_buffer *vbuf, void *dst, void *src, + * unsigned int width, unsigned int height) + * { + * unsigned int x, y; + * unsigned int i = 0; + * + * for (y = 0; y < height; ++y) { + * for (x = 0; x < width; ++x, ++i) { + * dst[i] = convert_to_cursor_format(src[i]); + * } + * } + * return 0; + * } + * + * void do_set_base(struct vram_buffer *vbuf, u64 addr) + * { + * // write addr to device registers and enable HW cursor + * } + * + * The implementation of do_update() does the format conversion and sets up + * the destination buffer (i.e., the VRAM buffer's current back-buffer frame). + * The implementation if do_set_base() writes the back buffer's address to + * the device and hence makes it the new front buffer. */ MODULE_DESCRIPTION("DRM VRAM memory-management helpers"); MODULE_LICENSE("GPL"); + +/* + * Helpers for dedicated VRAM buffers + */ + +/** + * DOC: vbuf overview + * + * A VRAM buffer manage an area of video memory that has been dedicated + * to a specific functionality. Typical use cases are hardware cursors and + * sprites. + */ + +/** + * drm_vram_buffer_init - Initializes a VRAM buffer + * @vbuf: The VRAM-buffer instance to initialize + * @base: The managed memory's base address + * @size: The managed memory's size in bytes + * @frame_size: The size of each individual sub-buffer + * @nframes: The number of sub buffers + * @funcs: Hardware-specific call-back functions + * Returns: 0 on success, or a negative error code otherwise. + */ +int drm_vram_buffer_init(struct drm_vram_buffer *vbuf, + resource_size_t base, resource_size_t size, + unsigned int frame_size, unsigned int nframes, + const struct drm_vram_buffer_funcs *funcs) +{ + void *mem; + + /* try to auto-detect 0-value arguments */ + if (!frame_size && !nframes) { + frame_size = size; + nframes = 1; + } else if (!frame_size) { + frame_size = size / nframes; + if (!frame_size) + return -EINVAL; + } else if (!nframes) { + nframes = size / frame_size; + if (!nframes) + return -EINVAL; + } else if (frame_size * nframes > size) { + return -ENOMEM; + } + + mem = ioremap(base, size); + if (!mem) + return -ENOMEM; + + vbuf->funcs = funcs; + vbuf->mem_base = base; + vbuf->mem_size = size; + vbuf->mem = mem; + vbuf->frame_size = frame_size; + vbuf->nframes = nframes; + vbuf->next_index = 0; + + return 0; +} +EXPORT_SYMBOL(drm_vram_buffer_init); + +/** + * drm_vram_buffer_cleanup - Releases a VRAM buffer + * @vbuf: The VRAM buffer to release + */ +void drm_vram_buffer_cleanup(struct drm_vram_buffer *vbuf) +{ + iounmap(vbuf->mem); +} +EXPORT_SYMBOL(drm_vram_buffer_cleanup); + +/** + * drm_vram_buffer_update - Updates the current back buffer + * @vbuf: The VRAM buffer + * @src: The source buffer + * @width: The source buffer's width in pixel + * @height: The source buffer's height in scanlines + * Returns: 0 on success, or a negative error code otherwise + */ +int drm_vram_buffer_update(struct drm_vram_buffer *vbuf, void *src, + unsigned int width, unsigned int height) +{ + unsigned long off; + void *dst; + int ret; + + if (!vbuf->funcs->update) + return 0; + + off = vbuf->frame_size * vbuf->next_index; + dst = &vbuf->mem[off]; + + ret = vbuf->funcs->update(vbuf, dst, src, width, height); + if (ret) + return ret; + + return 0; +} +EXPORT_SYMBOL(drm_vram_buffer_update); + +/** + * drm_vram_buffer_swap - Replaces the current front buffer wih the back buffer + * @vbuf: The VRAM buffer + */ +void drm_vram_buffer_swap(struct drm_vram_buffer *vbuf) +{ + if (vbuf->funcs->set_base) { + unsigned long off = vbuf->frame_size * vbuf->next_index; + u64 addr = vbuf->mem_base + off; + + vbuf->funcs->set_base(vbuf, addr); + } + + vbuf->next_index = (vbuf->next_index + 1) % vbuf->nframes; +} +EXPORT_SYMBOL(drm_vram_buffer_swap); + +/** + * drm_vram_buffer_get - Returns the current back buffer + * @vbuf: The VRAM buffer + * Returns: The address of the current back buffer + * in kernel address space + */ +void *drm_vram_buffer_get(struct drm_vram_buffer *vbuf) +{ + unsigned long off = vbuf->frame_size * vbuf->next_index; + + return &vbuf->mem[off]; +} +EXPORT_SYMBOL(drm_vram_buffer_get); + +/** + * drm_vram_buffer_get_current - Returns the current front buffer + * @vbuf: The VRAM buffer + * Returns: The address of the current front buffer + * in kernel address space + */ +void *drm_vram_buffer_get_current(struct drm_vram_buffer *vbuf) +{ + unsigned int cur_index; + unsigned long off; + + cur_index = vbuf->next_index + (vbuf->nframes - 1) % vbuf->nframes; + off = vbuf->frame_size * vbuf->next_index; + return &vbuf->mem[off]; +} +EXPORT_SYMBOL(drm_vram_buffer_get_current); diff --git a/include/drm/drm_vram_helper.h b/include/drm/drm_vram_helper.h new file mode 100644 index 000000000000..6b5c2381543b --- /dev/null +++ b/include/drm/drm_vram_helper.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef DRM_VRAM_HELPER_H +#define DRM_VRAM_HELPER_H + +#include + +/* + * DRM VRAM dedicated memory + */ + +struct drm_vram_buffer_funcs; + +/** + * struct drm_vram_buffer - Manages a dedicated area of video RAM + * @funcs: Call-back functions + * @mem_base: The base address of the managed memory + * @mem_size: The size of the managed memory + * @mem: Mapping of the VRAM buffer's memory into kernel address space + * @frame_size: The size of each individual frame + * @nframes: The number of frames + * @next_index: The index of the next frame (i.e., the current back buffer) + * + * The data structure &struct vram_buffer manages a dedicated area of video + * RAM. + */ +struct drm_vram_buffer { + const struct drm_vram_buffer_funcs *funcs; + + resource_size_t mem_base; + resource_size_t mem_size; + + u8 *mem; + + unsigned int frame_size; + unsigned int nframes; + unsigned int next_index; +}; + +/** + * struct drm_vram_buffer_funcs - Call-back functions for + * &struct drm_vram_buffer + * @update: Updates the current back buffer from a source buffer + * @set_base: Sets the current back buffer as the new front buffer + * used by hardware + */ +struct drm_vram_buffer_funcs { + int (*update)(struct drm_vram_buffer *vbuf, void *dst, void *src, + unsigned int width, unsigned int height); + void (*set_base)(struct drm_vram_buffer *vbuf, u64 address); +}; + +int drm_vram_buffer_init(struct drm_vram_buffer *vbuf, + resource_size_t base, resource_size_t size, + unsigned int frame_size, unsigned int nframes, + const struct drm_vram_buffer_funcs *funcs); +void drm_vram_buffer_cleanup(struct drm_vram_buffer *vbuf); +int drm_vram_buffer_update(struct drm_vram_buffer *vbuf, void *src, + unsigned int width, unsigned int height); +void drm_vram_buffer_swap(struct drm_vram_buffer *vbuf); +void *drm_vram_buffer_get(struct drm_vram_buffer *vbuf); +void *drm_vram_buffer_get_current(struct drm_vram_buffer *vbuf); + +#endif From patchwork Wed Sep 18 14:22:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Zimmermann X-Patchwork-Id: 11150457 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 723B616B1 for ; Wed, 18 Sep 2019 14:23:27 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5ABBB2067B for ; Wed, 18 Sep 2019 14:23:27 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5ABBB2067B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.de Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D0A466F3BB; Wed, 18 Sep 2019 14:23:15 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mx1.suse.de (mx2.suse.de [195.135.220.15]) by gabe.freedesktop.org (Postfix) with ESMTPS id 4A92C6F3B9 for ; Wed, 18 Sep 2019 14:23:14 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 05A3DB679; Wed, 18 Sep 2019 14:23:11 +0000 (UTC) From: Thomas Zimmermann To: airlied@linux.ie, daniel@ffwll.ch, kraxel@redhat.com, sam@ravnborg.org, yc_chen@aspeedtech.com, corbet@lwn.net Subject: [PATCH 02/11] drm/ast: Don't call ast_show_cursor() from ast_cursor_move() Date: Wed, 18 Sep 2019 16:22:58 +0200 Message-Id: <20190918142307.27127-3-tzimmermann@suse.de> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190918142307.27127-1-tzimmermann@suse.de> References: <20190918142307.27127-1-tzimmermann@suse.de> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Zimmermann , dri-devel@lists.freedesktop.org, linux-doc@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Separating the cursor's move() function from the show() function in preparation of further rework of the cursor update code. 'Showing' the cursor from within the move() function is required to updates the cursor position. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/ast/ast_mode.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 6caa6ebfeaa8..a4cbf2d5ee0a 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -1236,6 +1236,7 @@ static int ast_cursor_move(struct drm_crtc *crtc, struct ast_private *ast = crtc->dev->dev_private; int x_offset, y_offset; u8 *sig; + u8 jreg; sig = drm_gem_vram_kmap(drm_gem_vram_of_gem(ast->cursor_cache), false, NULL); @@ -1262,7 +1263,9 @@ static int ast_cursor_move(struct drm_crtc *crtc, ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc7, ((y >> 8) & 0x07)); /* dummy write to fire HWC */ - ast_show_cursor(crtc); + jreg = 0x02 | + 0x01; /* enable ARGB4444 cursor */ + ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, 0xfc, jreg); return 0; } From patchwork Wed Sep 18 14:22:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Zimmermann X-Patchwork-Id: 11150455 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 95D01195A for ; Wed, 18 Sep 2019 14:23:25 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7D5D82067B for ; Wed, 18 Sep 2019 14:23:25 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7D5D82067B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.de Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id EF11A6F3C4; Wed, 18 Sep 2019 14:23:15 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mx1.suse.de (mx2.suse.de [195.135.220.15]) by gabe.freedesktop.org (Postfix) with ESMTPS id 4D64F6F3BB for ; Wed, 18 Sep 2019 14:23:14 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 05273B675; Wed, 18 Sep 2019 14:23:11 +0000 (UTC) From: Thomas Zimmermann To: airlied@linux.ie, daniel@ffwll.ch, kraxel@redhat.com, sam@ravnborg.org, yc_chen@aspeedtech.com, corbet@lwn.net Subject: [PATCH 03/11] drm/ast: Move cursor update code to ast_show_cursor() Date: Wed, 18 Sep 2019 16:22:59 +0200 Message-Id: <20190918142307.27127-4-tzimmermann@suse.de> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190918142307.27127-1-tzimmermann@suse.de> References: <20190918142307.27127-1-tzimmermann@suse.de> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Zimmermann , dri-devel@lists.freedesktop.org, linux-doc@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" A call to ast's show-cursor function now receives the cursor image and updates the buffer. The change splits off image update and base-address update into separate functions. The will help with the upcoming change to VRAM buffers. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/ast/ast_mode.c | 120 +++++++++++++++++++-------------- 1 file changed, 69 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index a4cbf2d5ee0a..1294f0612fd5 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -1064,23 +1064,6 @@ static void ast_i2c_destroy(struct ast_i2c_chan *i2c) kfree(i2c); } -static void ast_show_cursor(struct drm_crtc *crtc) -{ - struct ast_private *ast = crtc->dev->dev_private; - u8 jreg; - - jreg = 0x2; - /* enable ARGB cursor */ - jreg |= 1; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, 0xfc, jreg); -} - -static void ast_hide_cursor(struct drm_crtc *crtc) -{ - struct ast_private *ast = crtc->dev->dev_private; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, 0xfc, 0x00); -} - static u32 copy_cursor_image(u8 *src, u8 *dst, int width, int height) { union { @@ -1137,6 +1120,72 @@ static u32 copy_cursor_image(u8 *src, u8 *dst, int width, int height) return csum; } +static int ast_cursor_update(void *dst, void *src, unsigned int width, + unsigned int height) +{ + u32 csum; + + /* do data transfer to cursor cache */ + csum = copy_cursor_image(src, dst, width, height); + + /* write checksum + signature */ + dst += AST_HWC_SIZE; + writel(csum, dst); + writel(width, dst + AST_HWC_SIGNATURE_SizeX); + writel(height, dst + AST_HWC_SIGNATURE_SizeY); + writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTX); + writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTY); + + return 0; +} + +static void ast_cursor_set_base(struct ast_private *ast, u64 address) +{ + u8 addr0 = (address >> 3) & 0xff; + u8 addr1 = (address >> 11) & 0xff; + u8 addr2 = (address >> 19) & 0xff; + + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc8, addr0); + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc9, addr1); + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xca, addr2); +} + +static int ast_show_cursor(struct drm_crtc *crtc, void *dst, void *src, + unsigned int width, unsigned int height, + u64 dst_gpu) +{ + struct ast_private *ast = crtc->dev->dev_private; + struct ast_crtc *ast_crtc = to_ast_crtc(crtc); + int ret; + u8 jreg; + + dst += (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE)*ast->next_cursor; + + ret = ast_cursor_update(dst, src, width, height); + if (ret) + return ret; + ast_cursor_set_base(ast, dst_gpu); + + ast->next_cursor = (ast->next_cursor + 1) % AST_DEFAULT_HWC_NUM; + + ast_crtc->offset_x = AST_MAX_HWC_WIDTH - width; + ast_crtc->offset_y = AST_MAX_HWC_WIDTH - height; + + jreg = 0x2; + /* enable ARGB cursor */ + jreg |= 1; + ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, 0xfc, jreg); + + return 0; +} + +static void ast_hide_cursor(struct drm_crtc *crtc) +{ + struct ast_private *ast = crtc->dev->dev_private; + + ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, 0xfc, 0x00); +} + static int ast_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, uint32_t handle, @@ -1144,12 +1193,9 @@ static int ast_cursor_set(struct drm_crtc *crtc, uint32_t height) { struct ast_private *ast = crtc->dev->dev_private; - struct ast_crtc *ast_crtc = to_ast_crtc(crtc); struct drm_gem_object *obj; struct drm_gem_vram_object *gbo; s64 dst_gpu; - u64 gpu_addr; - u32 csum; int ret; u8 *src, *dst; @@ -1185,37 +1231,9 @@ static int ast_cursor_set(struct drm_crtc *crtc, goto err_drm_gem_vram_vunmap; } - dst += (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE)*ast->next_cursor; - - /* do data transfer to cursor cache */ - csum = copy_cursor_image(src, dst, width, height); - - /* write checksum + signature */ - { - struct drm_gem_vram_object *dst_gbo = - drm_gem_vram_of_gem(ast->cursor_cache); - u8 *dst = drm_gem_vram_kmap(dst_gbo, false, NULL); - dst += (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE)*ast->next_cursor + AST_HWC_SIZE; - writel(csum, dst); - writel(width, dst + AST_HWC_SIGNATURE_SizeX); - writel(height, dst + AST_HWC_SIGNATURE_SizeY); - writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTX); - writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTY); - - /* set pattern offset */ - gpu_addr = (u64)dst_gpu; - gpu_addr += (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE)*ast->next_cursor; - gpu_addr >>= 3; - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc8, gpu_addr & 0xff); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc9, (gpu_addr >> 8) & 0xff); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xca, (gpu_addr >> 16) & 0xff); - } - ast_crtc->offset_x = AST_MAX_HWC_WIDTH - width; - ast_crtc->offset_y = AST_MAX_HWC_WIDTH - height; - - ast->next_cursor = (ast->next_cursor + 1) % AST_DEFAULT_HWC_NUM; - - ast_show_cursor(crtc); + ret = ast_show_cursor(crtc, dst, src, width, height, dst_gpu); + if (ret) + goto err_drm_gem_vram_kunmap; drm_gem_vram_vunmap(gbo, src); drm_gem_object_put_unlocked(obj); From patchwork Wed Sep 18 14:23:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Zimmermann X-Patchwork-Id: 11150451 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E69511745 for ; Wed, 18 Sep 2019 14:23:20 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id CF34721920 for ; Wed, 18 Sep 2019 14:23:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CF34721920 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.de Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6C0316F3B8; Wed, 18 Sep 2019 14:23:16 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mx1.suse.de (mx2.suse.de [195.135.220.15]) by gabe.freedesktop.org (Postfix) with ESMTPS id 4DEFC6F3BC for ; Wed, 18 Sep 2019 14:23:14 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 052FEB676; Wed, 18 Sep 2019 14:23:11 +0000 (UTC) From: Thomas Zimmermann To: airlied@linux.ie, daniel@ffwll.ch, kraxel@redhat.com, sam@ravnborg.org, yc_chen@aspeedtech.com, corbet@lwn.net Subject: [PATCH 04/11] drm/ast: Reserve space for double-buffered cursor image Date: Wed, 18 Sep 2019 16:23:00 +0200 Message-Id: <20190918142307.27127-5-tzimmermann@suse.de> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190918142307.27127-1-tzimmermann@suse.de> References: <20190918142307.27127-1-tzimmermann@suse.de> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Zimmermann , dri-devel@lists.freedesktop.org, linux-doc@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" With the patch, we reserve 2x 16 KiB at the high end of video memory, with each frame aligned to an 8-byte boundary. The remaining memory is available for GEM VRAM buffer objects. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/ast/ast_ttm.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_ttm.c b/drivers/gpu/drm/ast/ast_ttm.c index fad34106083a..8e6a1d8917d0 100644 --- a/drivers/gpu/drm/ast/ast_ttm.c +++ b/drivers/gpu/drm/ast/ast_ttm.c @@ -35,13 +35,20 @@ int ast_mm_init(struct ast_private *ast) { + unsigned long cursor_size; struct drm_vram_mm *vmm; int ret; struct drm_device *dev = ast->dev; - vmm = drm_vram_helper_alloc_mm( - dev, pci_resource_start(dev->pdev, 0), - ast->vram_size); + /* At the high end of video memory, we reserve space for + * two cursor images. The cursor plane uses this memory to + * store a double-buffered image of the current cursor. + */ + cursor_size = roundup((AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE), + PAGE_SIZE) * AST_DEFAULT_HWC_NUM; + + vmm = drm_vram_helper_alloc_mm(dev, pci_resource_start(dev->pdev, 0), + ast->vram_size - cursor_size); if (IS_ERR(vmm)) { ret = PTR_ERR(vmm); DRM_ERROR("Error initializing VRAM MM; %d\n", ret); From patchwork Wed Sep 18 14:23:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Zimmermann X-Patchwork-Id: 11150463 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E8F55195A for ; Wed, 18 Sep 2019 14:23:30 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D198021920 for ; Wed, 18 Sep 2019 14:23:30 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D198021920 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.de Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 349286F3C1; Wed, 18 Sep 2019 14:23:20 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mx1.suse.de (mx2.suse.de [195.135.220.15]) by gabe.freedesktop.org (Postfix) with ESMTPS id ECB7C6F3C2 for ; Wed, 18 Sep 2019 14:23:15 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id D5C65B67D; Wed, 18 Sep 2019 14:23:12 +0000 (UTC) From: Thomas Zimmermann To: airlied@linux.ie, daniel@ffwll.ch, kraxel@redhat.com, sam@ravnborg.org, yc_chen@aspeedtech.com, corbet@lwn.net Subject: [PATCH 05/11] drm/ast: Store cursor in reserved memory area Date: Wed, 18 Sep 2019 16:23:01 +0200 Message-Id: <20190918142307.27127-6-tzimmermann@suse.de> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190918142307.27127-1-tzimmermann@suse.de> References: <20190918142307.27127-1-tzimmermann@suse.de> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Zimmermann , dri-devel@lists.freedesktop.org, linux-doc@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" An instance of struct drm_vram_buffer maintains the memory area at the high end of video memory. The VRAM buffer replaces the GEM-based buffers and ast's buffer swapping. Two frames provide double buffering; with each frame aligned to 8 bytes, as required by the hardware. The full cursor update is currently performed in ast_show_cursor(). After conversing the ast driver to atomic mode setting, The update of the cursor's back buffer can be performed in the cursor plane's implementation of prepare_fb(). The swap operation can be performed in the cursor plane's implementation of atomic_update(). Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/ast/ast_drv.h | 5 +- drivers/gpu/drm/ast/ast_mode.c | 103 ++++++++++++--------------------- 2 files changed, 41 insertions(+), 67 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 244cc7c382af..d459ede43384 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -39,6 +39,7 @@ #include #include #include +#include #define DRIVER_AUTHOR "Dave Airlie" @@ -97,8 +98,8 @@ struct ast_private { int fb_mtrr; - struct drm_gem_object *cursor_cache; - int next_cursor; + struct drm_vram_buffer cursor; + bool support_wide_screen; enum { ast_use_p2a, diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 1294f0612fd5..5a55ee587df0 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -51,6 +51,8 @@ static int ast_cursor_set(struct drm_crtc *crtc, static int ast_cursor_move(struct drm_crtc *crtc, int x, int y); +static const struct drm_vram_buffer_funcs ast_cursor_vram_buffer_funcs; + static inline void ast_load_palette_index(struct ast_private *ast, u8 index, u8 red, u8 green, u8 blue) @@ -883,50 +885,26 @@ static int ast_connector_init(struct drm_device *dev) static int ast_cursor_init(struct drm_device *dev) { struct ast_private *ast = dev->dev_private; - int size; + unsigned long base = pci_resource_start(dev->pdev, 0) + + dev->vram_mm->vram_size; + unsigned long size = ast->vram_size - dev->vram_mm->vram_size; + unsigned long frame_size = size / AST_DEFAULT_HWC_NUM; int ret; - struct drm_gem_object *obj; - struct drm_gem_vram_object *gbo; - s64 gpu_addr; - void *base; - size = (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE) * AST_DEFAULT_HWC_NUM; - - ret = ast_gem_create(dev, size, true, &obj); + ret = drm_vram_buffer_init(&ast->cursor, base, size, frame_size, + AST_DEFAULT_HWC_NUM, + &ast_cursor_vram_buffer_funcs); if (ret) return ret; - gbo = drm_gem_vram_of_gem(obj); - ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM); - if (ret) - goto fail; - gpu_addr = drm_gem_vram_offset(gbo); - if (gpu_addr < 0) { - drm_gem_vram_unpin(gbo); - ret = (int)gpu_addr; - goto fail; - } - - /* kmap the object */ - base = drm_gem_vram_kmap(gbo, true, NULL); - if (IS_ERR(base)) { - ret = PTR_ERR(base); - goto fail; - } - ast->cursor_cache = obj; return 0; -fail: - return ret; } static void ast_cursor_fini(struct drm_device *dev) { struct ast_private *ast = dev->dev_private; - struct drm_gem_vram_object *gbo = - drm_gem_vram_of_gem(ast->cursor_cache); - drm_gem_vram_kunmap(gbo); - drm_gem_vram_unpin(gbo); - drm_gem_object_put_unlocked(ast->cursor_cache); + + drm_vram_buffer_cleanup(&ast->cursor); } int ast_mode_init(struct drm_device *dev) @@ -1120,8 +1098,10 @@ static u32 copy_cursor_image(u8 *src, u8 *dst, int width, int height) return csum; } -static int ast_cursor_update(void *dst, void *src, unsigned int width, - unsigned int height) +static int ast_cursor_vram_buffer_update(struct drm_vram_buffer *vbuf, + void *dst, void *src, + unsigned int width, + unsigned int height) { u32 csum; @@ -1139,8 +1119,12 @@ static int ast_cursor_update(void *dst, void *src, unsigned int width, return 0; } -static void ast_cursor_set_base(struct ast_private *ast, u64 address) +static void ast_cursor_vram_buffer_set_base(struct drm_vram_buffer *vbuf, + u64 address) { + struct ast_private *ast = container_of(vbuf, struct ast_private, + cursor); + u8 addr0 = (address >> 3) & 0xff; u8 addr1 = (address >> 11) & 0xff; u8 addr2 = (address >> 19) & 0xff; @@ -1150,23 +1134,23 @@ static void ast_cursor_set_base(struct ast_private *ast, u64 address) ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xca, addr2); } -static int ast_show_cursor(struct drm_crtc *crtc, void *dst, void *src, - unsigned int width, unsigned int height, - u64 dst_gpu) +static const struct drm_vram_buffer_funcs ast_cursor_vram_buffer_funcs = { + .update = ast_cursor_vram_buffer_update, + .set_base = ast_cursor_vram_buffer_set_base +}; + +static int ast_show_cursor(struct drm_crtc *crtc, void *src, + unsigned int width, unsigned int height) { struct ast_private *ast = crtc->dev->dev_private; struct ast_crtc *ast_crtc = to_ast_crtc(crtc); int ret; u8 jreg; - dst += (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE)*ast->next_cursor; - - ret = ast_cursor_update(dst, src, width, height); + ret = drm_vram_buffer_update(&ast->cursor, src, width, height); if (ret) return ret; - ast_cursor_set_base(ast, dst_gpu); - - ast->next_cursor = (ast->next_cursor + 1) % AST_DEFAULT_HWC_NUM; + drm_vram_buffer_swap(&ast->cursor); ast_crtc->offset_x = AST_MAX_HWC_WIDTH - width; ast_crtc->offset_y = AST_MAX_HWC_WIDTH - height; @@ -1192,12 +1176,10 @@ static int ast_cursor_set(struct drm_crtc *crtc, uint32_t width, uint32_t height) { - struct ast_private *ast = crtc->dev->dev_private; struct drm_gem_object *obj; struct drm_gem_vram_object *gbo; - s64 dst_gpu; int ret; - u8 *src, *dst; + u8 *src; if (!handle) { ast_hide_cursor(crtc); @@ -1219,21 +1201,9 @@ static int ast_cursor_set(struct drm_crtc *crtc, goto err_drm_gem_object_put_unlocked; } - dst = drm_gem_vram_kmap(drm_gem_vram_of_gem(ast->cursor_cache), - false, NULL); - if (IS_ERR(dst)) { - ret = PTR_ERR(dst); - goto err_drm_gem_vram_vunmap; - } - dst_gpu = drm_gem_vram_offset(drm_gem_vram_of_gem(ast->cursor_cache)); - if (dst_gpu < 0) { - ret = (int)dst_gpu; - goto err_drm_gem_vram_vunmap; - } - - ret = ast_show_cursor(crtc, dst, src, width, height, dst_gpu); + ret = ast_show_cursor(crtc, src, width, height); if (ret) - goto err_drm_gem_vram_kunmap; + goto err_drm_gem_vram_vunmap; drm_gem_vram_vunmap(gbo, src); drm_gem_object_put_unlocked(obj); @@ -1256,9 +1226,12 @@ static int ast_cursor_move(struct drm_crtc *crtc, u8 *sig; u8 jreg; - sig = drm_gem_vram_kmap(drm_gem_vram_of_gem(ast->cursor_cache), - false, NULL); - sig += (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE)*ast->next_cursor + AST_HWC_SIZE; + /* FIXME: If the cursor position is a required part of the + * signature, this code updates the wrong frame. If + * not, what is the purpose of this code? + */ + sig = drm_vram_buffer_get(&ast->cursor); + sig += AST_HWC_SIZE; writel(x, sig + AST_HWC_SIGNATURE_X); writel(y, sig + AST_HWC_SIGNATURE_Y); From patchwork Wed Sep 18 14:23:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Zimmermann X-Patchwork-Id: 11150467 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CDF3E1745 for ; Wed, 18 Sep 2019 14:23:32 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B608921920 for ; Wed, 18 Sep 2019 14:23:32 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B608921920 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.de Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1400C6F410; Wed, 18 Sep 2019 14:23:21 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mx1.suse.de (mx2.suse.de [195.135.220.15]) by gabe.freedesktop.org (Postfix) with ESMTPS id EC8446F3C1 for ; Wed, 18 Sep 2019 14:23:15 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id D5D6CB67E; Wed, 18 Sep 2019 14:23:12 +0000 (UTC) From: Thomas Zimmermann To: airlied@linux.ie, daniel@ffwll.ch, kraxel@redhat.com, sam@ravnborg.org, yc_chen@aspeedtech.com, corbet@lwn.net Subject: [PATCH 06/11] drm/mgag200: Rename cursor functions to use mgag200_ prefix Date: Wed, 18 Sep 2019 16:23:02 +0200 Message-Id: <20190918142307.27127-7-tzimmermann@suse.de> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190918142307.27127-1-tzimmermann@suse.de> References: <20190918142307.27127-1-tzimmermann@suse.de> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Zimmermann , dri-devel@lists.freedesktop.org, linux-doc@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Although the driver source code is fairly inconsistent wrt naming, the prefix should be mgag200. Rename cursor functions accordingly. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/mgag200/mgag200_cursor.c | 20 ++++++++------------ drivers/gpu/drm/mgag200/mgag200_drv.h | 6 +++--- drivers/gpu/drm/mgag200/mgag200_mode.c | 4 ++-- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_cursor.c b/drivers/gpu/drm/mgag200/mgag200_cursor.c index 89f61573a497..648357ad9a4b 100644 --- a/drivers/gpu/drm/mgag200/mgag200_cursor.c +++ b/drivers/gpu/drm/mgag200/mgag200_cursor.c @@ -12,11 +12,10 @@ static bool warn_transparent = true; static bool warn_palette = true; -/* - Hide the cursor off screen. We can't disable the cursor hardware because it - takes too long to re-activate and causes momentary corruption -*/ -static void mga_hide_cursor(struct mga_device *mdev) +/* Hide the cursor off screen. We can't disable the cursor hardware because it + * takes too long to re-activate and causes momentary corruption + */ +static void mgag200_hide_cursor(struct mga_device *mdev) { WREG8(MGA_CURPOSXL, 0); WREG8(MGA_CURPOSXH, 0); @@ -25,11 +24,8 @@ static void mga_hide_cursor(struct mga_device *mdev) mdev->cursor.pixels_current = NULL; } -int mga_crtc_cursor_set(struct drm_crtc *crtc, - struct drm_file *file_priv, - uint32_t handle, - uint32_t width, - uint32_t height) +int mgag200_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, + uint32_t handle, uint32_t width, uint32_t height) { struct drm_device *dev = crtc->dev; struct mga_device *mdev = (struct mga_device *)dev->dev_private; @@ -66,7 +62,7 @@ int mga_crtc_cursor_set(struct drm_crtc *crtc, } if (!handle || !file_priv) { - mga_hide_cursor(mdev); + mgag200_hide_cursor(mdev); return 0; } @@ -224,7 +220,7 @@ int mga_crtc_cursor_set(struct drm_crtc *crtc, return ret; } -int mga_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) +int mgag200_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) { struct mga_device *mdev = (struct mga_device *)crtc->dev->dev_private; /* Our origin is at (64,64) */ diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index 37c003ed57c0..5244e3fa4203 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -203,8 +203,8 @@ int mgag200_mm_init(struct mga_device *mdev); void mgag200_mm_fini(struct mga_device *mdev); int mgag200_mmap(struct file *filp, struct vm_area_struct *vma); -int mga_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, - uint32_t handle, uint32_t width, uint32_t height); -int mga_crtc_cursor_move(struct drm_crtc *crtc, int x, int y); +int mgag200_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, + uint32_t handle, uint32_t width, uint32_t height); +int mgag200_crtc_cursor_move(struct drm_crtc *crtc, int x, int y); #endif /* __MGAG200_DRV_H__ */ diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 68226556044b..0cf5608c3644 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -1413,8 +1413,8 @@ static void mga_crtc_disable(struct drm_crtc *crtc) /* These provide the minimum set of functions required to handle a CRTC */ static const struct drm_crtc_funcs mga_crtc_funcs = { - .cursor_set = mga_crtc_cursor_set, - .cursor_move = mga_crtc_cursor_move, + .cursor_set = mgag200_crtc_cursor_set, + .cursor_move = mgag200_crtc_cursor_move, .gamma_set = mga_crtc_gamma_set, .set_config = drm_crtc_helper_set_config, .destroy = mga_crtc_destroy, From patchwork Wed Sep 18 14:23:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Zimmermann X-Patchwork-Id: 11150461 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CE4391745 for ; Wed, 18 Sep 2019 14:23:30 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id DF28C21920 for ; Wed, 18 Sep 2019 14:23:29 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org DF28C21920 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.de Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id DD7EF6F3C0; Wed, 18 Sep 2019 14:23:19 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mx1.suse.de (mx2.suse.de [195.135.220.15]) by gabe.freedesktop.org (Postfix) with ESMTPS id 0B8AE6F410 for ; Wed, 18 Sep 2019 14:23:16 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 18B1DB682; Wed, 18 Sep 2019 14:23:13 +0000 (UTC) From: Thomas Zimmermann To: airlied@linux.ie, daniel@ffwll.ch, kraxel@redhat.com, sam@ravnborg.org, yc_chen@aspeedtech.com, corbet@lwn.net Subject: [PATCH 07/11] drm/mgag200: Add init and fini functions for cursor handling Date: Wed, 18 Sep 2019 16:23:03 +0200 Message-Id: <20190918142307.27127-8-tzimmermann@suse.de> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190918142307.27127-1-tzimmermann@suse.de> References: <20190918142307.27127-1-tzimmermann@suse.de> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Zimmermann , dri-devel@lists.freedesktop.org, linux-doc@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Moving the cursor initialization and cleanup into separate functions makes the overall code slightly more readable. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/mgag200/mgag200_cursor.c | 28 ++++++++++++++++++++++++ drivers/gpu/drm/mgag200/mgag200_drv.h | 2 ++ drivers/gpu/drm/mgag200/mgag200_main.c | 18 +++++---------- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_cursor.c b/drivers/gpu/drm/mgag200/mgag200_cursor.c index 648357ad9a4b..c6a7ad11ca72 100644 --- a/drivers/gpu/drm/mgag200/mgag200_cursor.c +++ b/drivers/gpu/drm/mgag200/mgag200_cursor.c @@ -24,6 +24,34 @@ static void mgag200_hide_cursor(struct mga_device *mdev) mdev->cursor.pixels_current = NULL; } +int mgag200_cursor_init(struct mga_device *mdev) +{ + struct drm_device *dev = mdev->dev; + + /* + * Make small buffers to store a hardware cursor (double + * buffered icon updates) + */ + mdev->cursor.pixels_1 = drm_gem_vram_create(dev, &dev->vram_mm->bdev, + roundup(48*64, PAGE_SIZE), + 0, 0); + mdev->cursor.pixels_2 = drm_gem_vram_create(dev, &dev->vram_mm->bdev, + roundup(48*64, PAGE_SIZE), + 0, 0); + if (IS_ERR(mdev->cursor.pixels_2) || IS_ERR(mdev->cursor.pixels_1)) { + mdev->cursor.pixels_1 = NULL; + mdev->cursor.pixels_2 = NULL; + dev_warn(&dev->pdev->dev, + "Could not allocate space for cursors. Not doing hardware cursors.\n"); + } + mdev->cursor.pixels_current = NULL; + + return 0; +} + +void mgag200_cursor_fini(struct mga_device *mdev) +{ } + int mgag200_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, uint32_t handle, uint32_t width, uint32_t height) { diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index 5244e3fa4203..01243fa6397c 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -203,6 +203,8 @@ int mgag200_mm_init(struct mga_device *mdev); void mgag200_mm_fini(struct mga_device *mdev); int mgag200_mmap(struct file *filp, struct vm_area_struct *vma); +int mgag200_cursor_init(struct mga_device *mdev); +void mgag200_cursor_fini(struct mga_device *mdev); int mgag200_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, uint32_t handle, uint32_t width, uint32_t height); int mgag200_crtc_cursor_move(struct drm_crtc *crtc, int x, int y); diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c index a9773334dedf..2b59280777a5 100644 --- a/drivers/gpu/drm/mgag200/mgag200_main.c +++ b/drivers/gpu/drm/mgag200/mgag200_main.c @@ -171,20 +171,10 @@ int mgag200_driver_load(struct drm_device *dev, unsigned long flags) goto err_modeset; } - /* Make small buffers to store a hardware cursor (double buffered icon updates) */ - mdev->cursor.pixels_1 = drm_gem_vram_create(dev, &dev->vram_mm->bdev, - roundup(48*64, PAGE_SIZE), - 0, 0); - mdev->cursor.pixels_2 = drm_gem_vram_create(dev, &dev->vram_mm->bdev, - roundup(48*64, PAGE_SIZE), - 0, 0); - if (IS_ERR(mdev->cursor.pixels_2) || IS_ERR(mdev->cursor.pixels_1)) { - mdev->cursor.pixels_1 = NULL; - mdev->cursor.pixels_2 = NULL; + r = mgag200_cursor_init(mdev); + if (r) dev_warn(&dev->pdev->dev, - "Could not allocate space for cursors. Not doing hardware cursors.\n"); - } - mdev->cursor.pixels_current = NULL; + "Could not initialize cursors. Not doing hardware cursors.\n"); r = drm_fbdev_generic_setup(mdev->dev, 0); if (r) @@ -194,6 +184,7 @@ int mgag200_driver_load(struct drm_device *dev, unsigned long flags) err_modeset: drm_mode_config_cleanup(dev); + mgag200_cursor_fini(mdev); mgag200_mm_fini(mdev); err_mm: dev->dev_private = NULL; @@ -209,6 +200,7 @@ void mgag200_driver_unload(struct drm_device *dev) return; mgag200_modeset_fini(mdev); drm_mode_config_cleanup(dev); + mgag200_cursor_fini(mdev); mgag200_mm_fini(mdev); dev->dev_private = NULL; } From patchwork Wed Sep 18 14:23:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Zimmermann X-Patchwork-Id: 11150477 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D500A16B1 for ; Wed, 18 Sep 2019 14:23:38 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id BD9F621928 for ; Wed, 18 Sep 2019 14:23:38 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org BD9F621928 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.de Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E36F36F58F; Wed, 18 Sep 2019 14:23:35 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mx1.suse.de (mx2.suse.de [195.135.220.15]) by gabe.freedesktop.org (Postfix) with ESMTPS id 0FCB56F4B4 for ; Wed, 18 Sep 2019 14:23:16 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 8FAD7B686; Wed, 18 Sep 2019 14:23:13 +0000 (UTC) From: Thomas Zimmermann To: airlied@linux.ie, daniel@ffwll.ch, kraxel@redhat.com, sam@ravnborg.org, yc_chen@aspeedtech.com, corbet@lwn.net Subject: [PATCH 08/11] drm/mgag200: Add separate move-cursor function Date: Wed, 18 Sep 2019 16:23:04 +0200 Message-Id: <20190918142307.27127-9-tzimmermann@suse.de> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190918142307.27127-1-tzimmermann@suse.de> References: <20190918142307.27127-1-tzimmermann@suse.de> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Zimmermann , dri-devel@lists.freedesktop.org, linux-doc@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Adding mgag200_move_cursor() makes the cursor code more consistent and will become handy when we move to universal cursor planes. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/mgag200/mgag200_cursor.c | 29 ++++++++++++++++-------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_cursor.c b/drivers/gpu/drm/mgag200/mgag200_cursor.c index c6a7ad11ca72..aabacdd3e401 100644 --- a/drivers/gpu/drm/mgag200/mgag200_cursor.c +++ b/drivers/gpu/drm/mgag200/mgag200_cursor.c @@ -24,6 +24,24 @@ static void mgag200_hide_cursor(struct mga_device *mdev) mdev->cursor.pixels_current = NULL; } +static void mgag200_move_cursor(struct mga_device *mdev, int x, int y) +{ + if (WARN_ON(x <= 0)) + return; + if (WARN_ON(y <= 0)) + return; + if (WARN_ON(x & ~0xffff)) + return; + if (WARN_ON(y & ~0xffff)) + return; + + WREG8(MGA_CURPOSXL, x & 0xff); + WREG8(MGA_CURPOSXH, (x>>8) & 0xff); + + WREG8(MGA_CURPOSYL, y & 0xff); + WREG8(MGA_CURPOSYH, (y>>8) & 0xff); +} + int mgag200_cursor_init(struct mga_device *mdev) { struct drm_device *dev = mdev->dev; @@ -251,19 +269,12 @@ int mgag200_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, int mgag200_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) { struct mga_device *mdev = (struct mga_device *)crtc->dev->dev_private; + /* Our origin is at (64,64) */ x += 64; y += 64; - BUG_ON(x <= 0); - BUG_ON(y <= 0); - BUG_ON(x & ~0xffff); - BUG_ON(y & ~0xffff); + mgag200_move_cursor(mdev, x, y); - WREG8(MGA_CURPOSXL, x & 0xff); - WREG8(MGA_CURPOSXH, (x>>8) & 0xff); - - WREG8(MGA_CURPOSYL, y & 0xff); - WREG8(MGA_CURPOSYH, (y>>8) & 0xff); return 0; } From patchwork Wed Sep 18 14:23:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Zimmermann X-Patchwork-Id: 11150471 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CD4DA16B1 for ; Wed, 18 Sep 2019 14:23:34 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B586921925 for ; Wed, 18 Sep 2019 14:23:34 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B586921925 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.de Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1AA4A6F4B4; Wed, 18 Sep 2019 14:23:21 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mx1.suse.de (mx2.suse.de [195.135.220.15]) by gabe.freedesktop.org (Postfix) with ESMTPS id 159AF6F4CB for ; Wed, 18 Sep 2019 14:23:16 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 24F28B688; Wed, 18 Sep 2019 14:23:14 +0000 (UTC) From: Thomas Zimmermann To: airlied@linux.ie, daniel@ffwll.ch, kraxel@redhat.com, sam@ravnborg.org, yc_chen@aspeedtech.com, corbet@lwn.net Subject: [PATCH 09/11] drm/mgag200: Move cursor-image update to mgag200_show_cursor() Date: Wed, 18 Sep 2019 16:23:05 +0200 Message-Id: <20190918142307.27127-10-tzimmermann@suse.de> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190918142307.27127-1-tzimmermann@suse.de> References: <20190918142307.27127-1-tzimmermann@suse.de> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Zimmermann , dri-devel@lists.freedesktop.org, linux-doc@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" This separates the management of buffer objects from updating the hardware cursor buffer. While doing this, we can further split the image-update code into code for writing the buffer, setting the base scan-out address, and enabling the cursor. The first two operations are in dedicated functions update() and set_base(). This simplifies the conversion to a VRAM buffer. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/mgag200/mgag200_cursor.c | 221 +++++++++++++---------- 1 file changed, 126 insertions(+), 95 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_cursor.c b/drivers/gpu/drm/mgag200/mgag200_cursor.c index aabacdd3e401..ab3dfe6bdd92 100644 --- a/drivers/gpu/drm/mgag200/mgag200_cursor.c +++ b/drivers/gpu/drm/mgag200/mgag200_cursor.c @@ -12,6 +12,128 @@ static bool warn_transparent = true; static bool warn_palette = true; +static int mgag200_cursor_update(struct mga_device *mdev, void *dst, void *src, + unsigned int width, unsigned int height) +{ + struct drm_device *dev = mdev->dev; + unsigned int i, row, col; + uint32_t colour_set[16]; + uint32_t *next_space = &colour_set[0]; + uint32_t *palette_iter; + uint32_t this_colour; + bool found = false; + int colour_count = 0; + u8 reg_index; + u8 this_row[48]; + + memset(&colour_set[0], 0, sizeof(uint32_t)*16); + /* width*height*4 = 16384 */ + for (i = 0; i < 16384; i += 4) { + this_colour = ioread32(src + i); + /* No transparency */ + if (this_colour>>24 != 0xff && + this_colour>>24 != 0x0) { + if (warn_transparent) { + dev_info(&dev->pdev->dev, "Video card doesn't support cursors with partial transparency.\n"); + dev_info(&dev->pdev->dev, "Not enabling hardware cursor.\n"); + warn_transparent = false; /* Only tell the user once. */ + } + return -EINVAL; + } + /* Don't need to store transparent pixels as colours */ + if (this_colour>>24 == 0x0) + continue; + found = false; + for (palette_iter = &colour_set[0]; palette_iter != next_space; palette_iter++) { + if (*palette_iter == this_colour) { + found = true; + break; + } + } + if (found) + continue; + /* We only support 4bit paletted cursors */ + if (colour_count >= 16) { + if (warn_palette) { + dev_info(&dev->pdev->dev, "Video card only supports cursors with up to 16 colours.\n"); + dev_info(&dev->pdev->dev, "Not enabling hardware cursor.\n"); + warn_palette = false; /* Only tell the user once. */ + } + return -EINVAL; + } + *next_space = this_colour; + next_space++; + colour_count++; + } + + /* Program colours from cursor icon into palette */ + for (i = 0; i < colour_count; i++) { + if (i <= 2) + reg_index = 0x8 + i*0x4; + else + reg_index = 0x60 + i*0x3; + WREG_DAC(reg_index, colour_set[i] & 0xff); + WREG_DAC(reg_index+1, colour_set[i]>>8 & 0xff); + WREG_DAC(reg_index+2, colour_set[i]>>16 & 0xff); + if (WARN_ON((colour_set[i]>>24 & 0xff) != 0xff)) + return -EINVAL; + } + + /* now write colour indices into hardware cursor buffer */ + for (row = 0; row < 64; row++) { + memset(&this_row[0], 0, 48); + for (col = 0; col < 64; col++) { + this_colour = ioread32(src + 4*(col + 64*row)); + /* write transparent pixels */ + if (this_colour>>24 == 0x0) { + this_row[47 - col/8] |= 0x80>>(col%8); + continue; + } + + /* write colour index here */ + for (i = 0; i < colour_count; i++) { + if (colour_set[i] == this_colour) { + if (col % 2) + this_row[col/2] |= i<<4; + else + this_row[col/2] |= i; + break; + } + } + } + memcpy_toio(dst + row*48, &this_row[0], 48); + } + + return 0; +} + +static void mgag200_cursor_set_base(struct mga_device *mdev, u64 address) +{ + u8 addrl = (address >> 10) & 0xff; + u8 addrh = (address >> 18) & 0x3f; + + /* Program gpu address of cursor buffer */ + WREG_DAC(MGA1064_CURSOR_BASE_ADR_LOW, addrl); + WREG_DAC(MGA1064_CURSOR_BASE_ADR_HI, addrh); +} + +static int mgag200_show_cursor(struct mga_device *mdev, void *dst, void *src, + unsigned int width, unsigned int height, + u64 dst_gpu) +{ + int ret; + + ret = mgag200_cursor_update(mdev, dst, src, width, height); + if (ret) + return ret; + mgag200_cursor_set_base(mdev, dst_gpu); + + /* Adjust cursor control register to turn on the cursor */ + WREG_DAC(MGA1064_CURSOR_CTL, 4); /* 16-colour palletized cursor mode */ + + return 0; +} + /* Hide the cursor off screen. We can't disable the cursor hardware because it * takes too long to re-activate and causes momentary corruption */ @@ -81,19 +203,10 @@ int mgag200_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, struct drm_gem_vram_object *pixels_next; struct drm_gem_object *obj; struct drm_gem_vram_object *gbo = NULL; - int ret = 0; + int ret; u8 *src, *dst; - unsigned int i, row, col; - uint32_t colour_set[16]; - uint32_t *next_space = &colour_set[0]; - uint32_t *palette_iter; - uint32_t this_colour; - bool found = false; - int colour_count = 0; s64 gpu_addr; u64 dst_gpu; - u8 reg_index; - u8 this_row[48]; if (!pixels_1 || !pixels_2) { WREG8(MGA_CURPOSXL, 0); @@ -158,91 +271,9 @@ int mgag200_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, } dst_gpu = (u64)gpu_addr; - memset(&colour_set[0], 0, sizeof(uint32_t)*16); - /* width*height*4 = 16384 */ - for (i = 0; i < 16384; i += 4) { - this_colour = ioread32(src + i); - /* No transparency */ - if (this_colour>>24 != 0xff && - this_colour>>24 != 0x0) { - if (warn_transparent) { - dev_info(&dev->pdev->dev, "Video card doesn't support cursors with partial transparency.\n"); - dev_info(&dev->pdev->dev, "Not enabling hardware cursor.\n"); - warn_transparent = false; /* Only tell the user once. */ - } - ret = -EINVAL; - goto err_drm_gem_vram_kunmap_dst; - } - /* Don't need to store transparent pixels as colours */ - if (this_colour>>24 == 0x0) - continue; - found = false; - for (palette_iter = &colour_set[0]; palette_iter != next_space; palette_iter++) { - if (*palette_iter == this_colour) { - found = true; - break; - } - } - if (found) - continue; - /* We only support 4bit paletted cursors */ - if (colour_count >= 16) { - if (warn_palette) { - dev_info(&dev->pdev->dev, "Video card only supports cursors with up to 16 colours.\n"); - dev_info(&dev->pdev->dev, "Not enabling hardware cursor.\n"); - warn_palette = false; /* Only tell the user once. */ - } - ret = -EINVAL; - goto err_drm_gem_vram_kunmap_dst; - } - *next_space = this_colour; - next_space++; - colour_count++; - } - - /* Program colours from cursor icon into palette */ - for (i = 0; i < colour_count; i++) { - if (i <= 2) - reg_index = 0x8 + i*0x4; - else - reg_index = 0x60 + i*0x3; - WREG_DAC(reg_index, colour_set[i] & 0xff); - WREG_DAC(reg_index+1, colour_set[i]>>8 & 0xff); - WREG_DAC(reg_index+2, colour_set[i]>>16 & 0xff); - BUG_ON((colour_set[i]>>24 & 0xff) != 0xff); - } - - /* now write colour indices into hardware cursor buffer */ - for (row = 0; row < 64; row++) { - memset(&this_row[0], 0, 48); - for (col = 0; col < 64; col++) { - this_colour = ioread32(src + 4*(col + 64*row)); - /* write transparent pixels */ - if (this_colour>>24 == 0x0) { - this_row[47 - col/8] |= 0x80>>(col%8); - continue; - } - - /* write colour index here */ - for (i = 0; i < colour_count; i++) { - if (colour_set[i] == this_colour) { - if (col % 2) - this_row[col/2] |= i<<4; - else - this_row[col/2] |= i; - break; - } - } - } - memcpy_toio(dst + row*48, &this_row[0], 48); - } - - /* Program gpu address of cursor buffer */ - WREG_DAC(MGA1064_CURSOR_BASE_ADR_LOW, (u8)((dst_gpu>>10) & 0xff)); - WREG_DAC(MGA1064_CURSOR_BASE_ADR_HI, (u8)((dst_gpu>>18) & 0x3f)); - - /* Adjust cursor control register to turn on the cursor */ - WREG_DAC(MGA1064_CURSOR_CTL, 4); /* 16-colour palletized cursor mode */ + ret = mgag200_show_cursor(mdev, dst, src, width, height, dst_gpu); + if (ret) + goto err_drm_gem_vram_kunmap_dst; /* Now update internal buffer pointers */ if (pixels_current) From patchwork Wed Sep 18 14:23:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Zimmermann X-Patchwork-Id: 11150479 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 937D216B1 for ; Wed, 18 Sep 2019 14:23:40 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7BD7A2196E for ; Wed, 18 Sep 2019 14:23:40 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7BD7A2196E Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.de Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1C4546F596; Wed, 18 Sep 2019 14:23:36 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mx1.suse.de (mx2.suse.de [195.135.220.15]) by gabe.freedesktop.org (Postfix) with ESMTPS id F39496F3C5 for ; Wed, 18 Sep 2019 14:23:15 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 6B8CBB687; Wed, 18 Sep 2019 14:23:14 +0000 (UTC) From: Thomas Zimmermann To: airlied@linux.ie, daniel@ffwll.ch, kraxel@redhat.com, sam@ravnborg.org, yc_chen@aspeedtech.com, corbet@lwn.net Subject: [PATCH 10/11] drm/mgag200: Reserve video memory for cursor plane Date: Wed, 18 Sep 2019 16:23:06 +0200 Message-Id: <20190918142307.27127-11-tzimmermann@suse.de> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190918142307.27127-1-tzimmermann@suse.de> References: <20190918142307.27127-1-tzimmermann@suse.de> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Zimmermann , dri-devel@lists.freedesktop.org, linux-doc@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" The double-buffered cursor image is currently stored in video memory by creating two BOs and pinning them to VRAM. The exact location is chosen by VRAM helpers. Since the driver has no control over BO placement, pinned cursor BOs can conflict with framebuffer BOs and prevent the primary plane from displaying its framebuffer. As a first step to solving this problem, we reserve dedicated space at the high end of the video memory for the cursor images. As the amount of video memory now differs from the amount of available framebuffer memory, size tests are performed against the VRAM helper's framebuffer limits. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/mgag200/mgag200_main.c | 2 +- drivers/gpu/drm/mgag200/mgag200_mode.c | 2 +- drivers/gpu/drm/mgag200/mgag200_ttm.c | 15 ++++++++++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c index 2b59280777a5..4b8686e9a276 100644 --- a/drivers/gpu/drm/mgag200/mgag200_main.c +++ b/drivers/gpu/drm/mgag200/mgag200_main.c @@ -159,7 +159,7 @@ int mgag200_driver_load(struct drm_device *dev, unsigned long flags) drm_mode_config_init(dev); dev->mode_config.funcs = (void *)&mga_mode_funcs; - if (IS_G200_SE(mdev) && mdev->mc.vram_size < (2048*1024)) + if (IS_G200_SE(mdev) && dev->vram_mm->vram_size < (2048*1024)) dev->mode_config.preferred_depth = 16; else dev->mode_config.preferred_depth = 32; diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 0cf5608c3644..2ac66a2270bb 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -1629,7 +1629,7 @@ static enum drm_mode_status mga_vga_mode_valid(struct drm_connector *connector, bpp = connector->cmdline_mode.bpp; } - if ((mode->hdisplay * mode->vdisplay * (bpp/8)) > mdev->mc.vram_size) { + if ((mode->hdisplay * mode->vdisplay * (bpp/8)) > dev->vram_mm->vram_size) { if (connector->cmdline_mode.specified) connector->cmdline_mode.specified = false; return MODE_BAD; diff --git a/drivers/gpu/drm/mgag200/mgag200_ttm.c b/drivers/gpu/drm/mgag200/mgag200_ttm.c index 69c81ebf3745..1df8504c6cab 100644 --- a/drivers/gpu/drm/mgag200/mgag200_ttm.c +++ b/drivers/gpu/drm/mgag200/mgag200_ttm.c @@ -32,12 +32,25 @@ int mgag200_mm_init(struct mga_device *mdev) { + unsigned long cursor_framesize, cursor_nframes, cursor_size; + unsigned long framebuffer_size; struct drm_vram_mm *vmm; int ret; struct drm_device *dev = mdev->dev; + /* At the high end of video memory, we reserve space for + * two cursor images. The cursor plane uses this memory to + * store a double-buffered image of the current cursor. + */ + + cursor_framesize = roundup(64 * 48, 1024); + cursor_nframes = 2; + cursor_size = roundup(cursor_framesize * cursor_nframes, PAGE_SIZE); + + framebuffer_size = (mdev->mc.vram_size - cursor_size) & PAGE_MASK; + vmm = drm_vram_helper_alloc_mm(dev, pci_resource_start(dev->pdev, 0), - mdev->mc.vram_size); + framebuffer_size); if (IS_ERR(vmm)) { ret = PTR_ERR(vmm); DRM_ERROR("Error initializing VRAM MM; %d\n", ret); From patchwork Wed Sep 18 14:23:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Zimmermann X-Patchwork-Id: 11150475 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 436F7195A for ; Wed, 18 Sep 2019 14:23:37 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8AB1F21925 for ; Wed, 18 Sep 2019 14:23:36 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8AB1F21925 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.de Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B12906F4D5; Wed, 18 Sep 2019 14:23:21 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mx1.suse.de (mx2.suse.de [195.135.220.15]) by gabe.freedesktop.org (Postfix) with ESMTPS id 85B426F3C0 for ; Wed, 18 Sep 2019 14:23:16 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 1670CB689; Wed, 18 Sep 2019 14:23:15 +0000 (UTC) From: Thomas Zimmermann To: airlied@linux.ie, daniel@ffwll.ch, kraxel@redhat.com, sam@ravnborg.org, yc_chen@aspeedtech.com, corbet@lwn.net Subject: [PATCH 11/11] drm/mgag200: Implement cursor buffer with struct drm_vram_buffer Date: Wed, 18 Sep 2019 16:23:07 +0200 Message-Id: <20190918142307.27127-12-tzimmermann@suse.de> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190918142307.27127-1-tzimmermann@suse.de> References: <20190918142307.27127-1-tzimmermann@suse.de> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Zimmermann , dri-devel@lists.freedesktop.org, linux-doc@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" The new VRAM buffer replaces all GEM buffer objects that contained cursor images. The buffer maintains the previously reserved memory at the high end of video RAM. The update() and set_base() now serve as callbacks for the VRAM buffer. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/mgag200/mgag200_cursor.c | 124 +++++++---------------- drivers/gpu/drm/mgag200/mgag200_drv.h | 16 +-- 2 files changed, 38 insertions(+), 102 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_cursor.c b/drivers/gpu/drm/mgag200/mgag200_cursor.c index ab3dfe6bdd92..650013e488c2 100644 --- a/drivers/gpu/drm/mgag200/mgag200_cursor.c +++ b/drivers/gpu/drm/mgag200/mgag200_cursor.c @@ -12,9 +12,12 @@ static bool warn_transparent = true; static bool warn_palette = true; -static int mgag200_cursor_update(struct mga_device *mdev, void *dst, void *src, - unsigned int width, unsigned int height) +static int mgag200_cursor_vram_buffer_update(struct drm_vram_buffer *vbuf, + void *dst, void *src, + unsigned int width, + unsigned int height) { + struct mga_device *mdev = container_of(vbuf, struct mga_device, cursor); struct drm_device *dev = mdev->dev; unsigned int i, row, col; uint32_t colour_set[16]; @@ -107,8 +110,10 @@ static int mgag200_cursor_update(struct mga_device *mdev, void *dst, void *src, return 0; } -static void mgag200_cursor_set_base(struct mga_device *mdev, u64 address) +static void mgag200_cursor_vram_buffer_set_base(struct drm_vram_buffer *vbuf, + u64 address) { + struct mga_device *mdev = container_of(vbuf, struct mga_device, cursor); u8 addrl = (address >> 10) & 0xff; u8 addrh = (address >> 18) & 0x3f; @@ -117,16 +122,20 @@ static void mgag200_cursor_set_base(struct mga_device *mdev, u64 address) WREG_DAC(MGA1064_CURSOR_BASE_ADR_HI, addrh); } -static int mgag200_show_cursor(struct mga_device *mdev, void *dst, void *src, - unsigned int width, unsigned int height, - u64 dst_gpu) +static const struct drm_vram_buffer_funcs mgag200_cursor_vram_buffer_funcs = { + .update = mgag200_cursor_vram_buffer_update, + .set_base = mgag200_cursor_vram_buffer_set_base +}; + +static int mgag200_show_cursor(struct mga_device *mdev, void *src, + unsigned int width, unsigned int height) { int ret; - ret = mgag200_cursor_update(mdev, dst, src, width, height); + ret = drm_vram_buffer_update(&mdev->cursor, src, width, height); if (ret) return ret; - mgag200_cursor_set_base(mdev, dst_gpu); + drm_vram_buffer_swap(&mdev->cursor); /* Adjust cursor control register to turn on the cursor */ WREG_DAC(MGA1064_CURSOR_CTL, 4); /* 16-colour palletized cursor mode */ @@ -141,9 +150,6 @@ static void mgag200_hide_cursor(struct mga_device *mdev) { WREG8(MGA_CURPOSXL, 0); WREG8(MGA_CURPOSXH, 0); - if (mdev->cursor.pixels_current) - drm_gem_vram_unpin(mdev->cursor.pixels_current); - mdev->cursor.pixels_current = NULL; } static void mgag200_move_cursor(struct mga_device *mdev, int x, int y) @@ -167,58 +173,39 @@ static void mgag200_move_cursor(struct mga_device *mdev, int x, int y) int mgag200_cursor_init(struct mga_device *mdev) { struct drm_device *dev = mdev->dev; + unsigned long base, frame_size, nframes, size; + int ret; - /* - * Make small buffers to store a hardware cursor (double - * buffered icon updates) - */ - mdev->cursor.pixels_1 = drm_gem_vram_create(dev, &dev->vram_mm->bdev, - roundup(48*64, PAGE_SIZE), - 0, 0); - mdev->cursor.pixels_2 = drm_gem_vram_create(dev, &dev->vram_mm->bdev, - roundup(48*64, PAGE_SIZE), - 0, 0); - if (IS_ERR(mdev->cursor.pixels_2) || IS_ERR(mdev->cursor.pixels_1)) { - mdev->cursor.pixels_1 = NULL; - mdev->cursor.pixels_2 = NULL; - dev_warn(&dev->pdev->dev, - "Could not allocate space for cursors. Not doing hardware cursors.\n"); - } - mdev->cursor.pixels_current = NULL; + base = mdev->mc.vram_base + dev->vram_mm->vram_size; + frame_size = roundup(64 * 48, 1024); + nframes = 2; + size = roundup(frame_size * nframes, PAGE_SIZE); + + ret = drm_vram_buffer_init(&mdev->cursor, base, size, frame_size, + nframes, &mgag200_cursor_vram_buffer_funcs); + if (ret) + return ret; return 0; } void mgag200_cursor_fini(struct mga_device *mdev) -{ } +{ + drm_vram_buffer_cleanup(&mdev->cursor); +} int mgag200_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, uint32_t handle, uint32_t width, uint32_t height) { struct drm_device *dev = crtc->dev; struct mga_device *mdev = (struct mga_device *)dev->dev_private; - struct drm_gem_vram_object *pixels_1 = mdev->cursor.pixels_1; - struct drm_gem_vram_object *pixels_2 = mdev->cursor.pixels_2; - struct drm_gem_vram_object *pixels_current = mdev->cursor.pixels_current; - struct drm_gem_vram_object *pixels_next; struct drm_gem_object *obj; struct drm_gem_vram_object *gbo = NULL; int ret; - u8 *src, *dst; - s64 gpu_addr; - u64 dst_gpu; + u8 *src; - if (!pixels_1 || !pixels_2) { - WREG8(MGA_CURPOSXL, 0); - WREG8(MGA_CURPOSXH, 0); + if (!mdev->cursor.mem) return -ENOTSUPP; /* Didn't allocate space for cursors */ - } - - if (WARN_ON(pixels_current && - pixels_1 != pixels_current && - pixels_2 != pixels_current)) { - return -ENOTSUPP; /* inconsistent state */ - } if (!handle || !file_priv) { mgag200_hide_cursor(mdev); @@ -226,16 +213,10 @@ int mgag200_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, } if (width != 64 || height != 64) { - WREG8(MGA_CURPOSXL, 0); - WREG8(MGA_CURPOSXH, 0); + mgag200_hide_cursor(mdev); return -EINVAL; } - if (pixels_current == pixels_1) - pixels_next = pixels_2; - else - pixels_next = pixels_1; - obj = drm_gem_object_lookup(file_priv, handle); if (!obj) return -ENOENT; @@ -248,48 +229,15 @@ int mgag200_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, goto err_drm_gem_object_put_unlocked; } - /* Pin and map up-coming buffer to write colour indices */ - ret = drm_gem_vram_pin(pixels_next, DRM_GEM_VRAM_PL_FLAG_VRAM); - if (ret) { - dev_err(&dev->pdev->dev, - "failed to pin cursor buffer: %d\n", ret); - goto err_drm_gem_vram_vunmap; - } - dst = drm_gem_vram_kmap(pixels_next, true, NULL); - if (IS_ERR(dst)) { - ret = PTR_ERR(dst); - dev_err(&dev->pdev->dev, - "failed to kmap cursor updates: %d\n", ret); - goto err_drm_gem_vram_unpin_dst; - } - gpu_addr = drm_gem_vram_offset(pixels_next); - if (gpu_addr < 0) { - ret = (int)gpu_addr; - dev_err(&dev->pdev->dev, - "failed to get cursor scanout address: %d\n", ret); - goto err_drm_gem_vram_kunmap_dst; - } - dst_gpu = (u64)gpu_addr; - - ret = mgag200_show_cursor(mdev, dst, src, width, height, dst_gpu); + ret = mgag200_show_cursor(mdev, src, width, height); if (ret) - goto err_drm_gem_vram_kunmap_dst; - - /* Now update internal buffer pointers */ - if (pixels_current) - drm_gem_vram_unpin(pixels_current); - mdev->cursor.pixels_current = pixels_next; + goto err_drm_gem_vram_vunmap; - drm_gem_vram_kunmap(pixels_next); drm_gem_vram_vunmap(gbo, src); drm_gem_object_put_unlocked(obj); return 0; -err_drm_gem_vram_kunmap_dst: - drm_gem_vram_kunmap(pixels_next); -err_drm_gem_vram_unpin_dst: - drm_gem_vram_unpin(pixels_next); err_drm_gem_vram_vunmap: drm_gem_vram_vunmap(gbo, src); err_drm_gem_object_put_unlocked: diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index 01243fa6397c..7ced98d61c22 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -19,6 +19,7 @@ #include #include #include +#include #include "mgag200_reg.h" @@ -128,19 +129,6 @@ struct mga_connector { struct mga_i2c_chan *i2c; }; -struct mga_cursor { - /* - We have to have 2 buffers for the cursor to avoid occasional - corruption while switching cursor icons. - If either of these is NULL, then don't do hardware cursors, and - fall back to software. - */ - struct drm_gem_vram_object *pixels_1; - struct drm_gem_vram_object *pixels_2; - /* The currently displayed icon, this points to one of pixels_1, or pixels_2 */ - struct drm_gem_vram_object *pixels_current; -}; - struct mga_mc { resource_size_t vram_size; resource_size_t vram_base; @@ -171,7 +159,7 @@ struct mga_device { struct mga_mc mc; struct mga_mode_info mode_info; - struct mga_cursor cursor; + struct drm_vram_buffer cursor; bool suspended; int num_crtc;