From patchwork Thu Mar 14 09:50:21 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Inki Dae X-Patchwork-Id: 2268781 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork1.kernel.org (Postfix) with ESMTP id 408D83FCF6 for ; Thu, 14 Mar 2013 09:50:55 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1D51DE613F for ; Thu, 14 Mar 2013 02:50:55 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mailout2.samsung.com (mailout2.samsung.com [203.254.224.25]) by gabe.freedesktop.org (Postfix) with ESMTP id AED2AE673F for ; Thu, 14 Mar 2013 02:50:23 -0700 (PDT) Received: from epcpsbgr5.samsung.com (u145.gpu120.samsung.co.kr [203.254.230.145]) by mailout2.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MJN00G0P9ZW2T40@mailout2.samsung.com> for dri-devel@lists.freedesktop.org; Thu, 14 Mar 2013 18:50:22 +0900 (KST) Received: from epcpsbgm1.samsung.com ( [203.254.230.46]) by epcpsbgr5.samsung.com (EPCPMTA) with SMTP id B9.7D.12250.E5D91415; Thu, 14 Mar 2013 18:50:22 +0900 (KST) X-AuditID: cbfee691-b7f5f6d000002fda-5d-51419d5e7ee5 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id D8.63.17838.D5D91415; Thu, 14 Mar 2013 18:50:21 +0900 (KST) Received: from daeinki-desktop.10.32.193.11 ([10.90.8.53]) by mmp1.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0MJN00CCF9ZXRJ20@mmp1.samsung.com> for dri-devel@lists.freedesktop.org; Thu, 14 Mar 2013 18:50:21 +0900 (KST) From: Inki Dae To: airlied@linux.ie, dri-devel@lists.freedesktop.org Subject: [PATCH v2 5/7] drm/exynos: Deal with g2d buffer info more efficiently Date: Thu, 14 Mar 2013 18:50:21 +0900 Message-id: <1363254621-11829-1-git-send-email-inki.dae@samsung.com> X-Mailer: git-send-email 1.7.4.1 In-reply-to: <1363165452-7516-1-git-send-email-inki.dae@samsung.com> References: <1363165452-7516-1-git-send-email-inki.dae@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrKLMWRmVeSWpSXmKPExsVy+t8zPd24uY6BBs8/slpc+fqezYHR4373 caYAxigum5TUnMyy1CJ9uwSujI+3dzEXHHOuaJy0l7GBscO0i5GTQ0LARGLigy/MELaYxIV7 69m6GLk4hASWMUosO3uNDaboy5Z57BCJRYwSNz63sEI465gkpk2azwRSxSagKjFxxX2wDhEB U4mOSUtZQIqYBboZJZ4/+AvUwcEhLOAn0bBVGaSGBaj+9LaXzCBhXgEXifNXbCCWKUgsuPcW bAwnUHjr5CvsILaQgLPE7curmEBGSghcZ5PY920TG8QcAYlvkw+xgMyREJCV2HQA6htJiYMr brBMYBRewMiwilE0tSC5oDgpvchUrzgxt7g0L10vOT93EyMkCCfuYLx/wPoQYzLQuInMUqLJ +cAgziuJNzQ2M7IwNTE1NjK3NCNNWEmcV73FOlBIID2xJDU7NbUgtSi+qDQntfgQIxMHp1QD o9yNgrscoRcYJ1jsyHBb5mfzvD4vfIn5ajf11p9SnO+e5Bh8faHzzCZCp0R61vWN7ltLhV9F dczx0uUtiOpPD9x6q6Sw5UxJWNxlkQwpn+DZv+QrNoqo/btRe0ySPZvtv8XGgNZnp+JKrhR3 e21btvXH9Ovc03apKM10WfCfv7pnQ0+u355tSizFGYmGWsxFxYkAZCFUA1gCAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrEIsWRmVeSWpSXmKPExsVy+t9jAd3YuY6BBh8fm1hc+fqezYHR4373 caYAxqgGRpuM1MSU1CKF1Lzk/JTMvHRbJe/geOd4UzMDQ11DSwtzJYW8xNxUWyUXnwBdt8wc oLFKCmWJOaVAoYDE4mIlfTtME0JD3HQtYBojdH1DguB6jAzQQMI6xoyPt3cxFxxzrmictJex gbHDtIuRk0NCwETiy5Z57BC2mMSFe+vZuhi5OIQEFjFK3PjcwgrhrGOSmDZpPhNIFZuAqsTE FffZQGwRAVOJjklLWUCKmAW6GSWeP/gL1MHBISzgJ9GwVRmkhgWo/vS2l8wgYV4BF4nzV2wg lilILLj3FmwMJ1B46+QrYEcICThL3L68imkCI+8CRoZVjKKpBckFxUnpuYZ6xYm5xaV56XrJ +bmbGMEh/kxqB+PKBotDjAIcjEo8vAf6HQKFWBPLiitzDzFKcDArifB6ejkGCvGmJFZWpRbl xxeV5qQWH2JMBjpqIrOUaHI+MP7ySuINjU3MjCyNzIxNzI2NSRNWEuc90GodKCSQnliSmp2a WpBaBLOFiYNTqoHxMKtvjc3Wy91nnma3lEUGyvfpl/x7WyY51fNP+PNIpgNip97wKU49su+J 1c8s5y6R3/P+9fgssdvSJbTn4M0TSTrifyz1fW3Klu/TYb3R7S9ukdb2d6n1nQm/FpWFLLZz Uj+VqdmwNXzZr+nXreK4zjTynTz+jOWyld29UqNTRvYvJCemvehTYinOSDTUYi4qTgQA+du5 y7UCAAA= DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected Cc: kyungmin.park@samsung.com, sw0312.kim@samsung.com, YoungJun Cho X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org From: YoungJun Cho This patch adds g2d_buf_info structure and buffer relevant variables moves into the g2d_buf_info to manage g2d buffer information more efficiently. Changelog v2: - Fix merge conflict. Signed-off-by: YoungJun Cho Signed-off-by: Inki Dae Signed-off-by: Kyungmin Park --- drivers/gpu/drm/exynos/exynos_drm_g2d.c | 160 ++++++++++++++++++++++++------- 1 files changed, 123 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index 7c1aac3..1a022dc 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -96,8 +96,6 @@ #define G2D_CMDLIST_POOL_SIZE (G2D_CMDLIST_SIZE * G2D_CMDLIST_NUM) #define G2D_CMDLIST_DATA_NUM (G2D_CMDLIST_SIZE / sizeof(u32) - 2) -#define MAX_BUF_ADDR_NR 6 - /* maximum buffer pool size of userptr is 64MB as default */ #define MAX_POOL (64 * 1024 * 1024) @@ -106,6 +104,17 @@ enum { BUF_TYPE_USERPTR, }; +enum g2d_reg_type { + REG_TYPE_NONE = -1, + REG_TYPE_SRC, + REG_TYPE_SRC_PLANE2, + REG_TYPE_DST, + REG_TYPE_DST_PLANE2, + REG_TYPE_PAT, + REG_TYPE_MSK, + MAX_REG_TYPE_NR +}; + /* cmdlist data structure */ struct g2d_cmdlist { u32 head; @@ -113,6 +122,22 @@ struct g2d_cmdlist { u32 last; /* last data offset */ }; +/* + * A structure of buffer information + * + * @map_nr: manages the number of mapped buffers + * @reg_types: stores regitster type in the order of requested command + * @handles: stores buffer handle in its reg_type position + * @types: stores buffer type in its reg_type position + * + */ +struct g2d_buf_info { + unsigned int map_nr; + enum g2d_reg_type reg_types[MAX_REG_TYPE_NR]; + unsigned long handles[MAX_REG_TYPE_NR]; + unsigned int types[MAX_REG_TYPE_NR]; +}; + struct drm_exynos_pending_g2d_event { struct drm_pending_event base; struct drm_exynos_g2d_event event; @@ -134,10 +159,8 @@ struct g2d_cmdlist_userptr { struct g2d_cmdlist_node { struct list_head list; struct g2d_cmdlist *cmdlist; - unsigned int map_nr; - unsigned long handles[MAX_BUF_ADDR_NR]; - unsigned int buf_type[MAX_BUF_ADDR_NR]; dma_addr_t dma_addr; + struct g2d_buf_info buf_info; struct drm_exynos_pending_g2d_event *event; }; @@ -187,6 +210,7 @@ static int g2d_init_cmdlist(struct g2d_data *g2d) struct exynos_drm_subdrv *subdrv = &g2d->subdrv; int nr; int ret; + struct g2d_buf_info *buf_info; init_dma_attrs(&g2d->cmdlist_dma_attrs); dma_set_attr(DMA_ATTR_WRITE_COMBINE, &g2d->cmdlist_dma_attrs); @@ -208,11 +232,17 @@ static int g2d_init_cmdlist(struct g2d_data *g2d) } for (nr = 0; nr < G2D_CMDLIST_NUM; nr++) { + unsigned int i; + node[nr].cmdlist = g2d->cmdlist_pool_virt + nr * G2D_CMDLIST_SIZE; node[nr].dma_addr = g2d->cmdlist_pool + nr * G2D_CMDLIST_SIZE; + buf_info = &node[nr].buf_info; + for (i = 0; i < MAX_REG_TYPE_NR; i++) + buf_info->reg_types[i] = REG_TYPE_NONE; + list_add_tail(&node[nr].list, &g2d->free_cmdlist); } @@ -507,36 +537,80 @@ static void g2d_userptr_free_all(struct drm_device *drm_dev, g2d->current_pool = 0; } +static enum g2d_reg_type g2d_get_reg_type(int reg_offset) +{ + enum g2d_reg_type reg_type; + + switch (reg_offset) { + case G2D_SRC_BASE_ADDR: + reg_type = REG_TYPE_SRC; + break; + case G2D_SRC_PLANE2_BASE_ADDR: + reg_type = REG_TYPE_SRC_PLANE2; + break; + case G2D_DST_BASE_ADDR: + reg_type = REG_TYPE_DST; + break; + case G2D_DST_PLANE2_BASE_ADDR: + reg_type = REG_TYPE_DST_PLANE2; + break; + case G2D_PAT_BASE_ADDR: + reg_type = REG_TYPE_PAT; + break; + case G2D_MSK_BASE_ADDR: + reg_type = REG_TYPE_MSK; + break; + default: + reg_type = REG_TYPE_NONE; + DRM_ERROR("Unknown register offset![%d]\n", reg_offset); + break; + }; + + return reg_type; +} + static int g2d_map_cmdlist_gem(struct g2d_data *g2d, struct g2d_cmdlist_node *node, struct drm_device *drm_dev, struct drm_file *file) { struct g2d_cmdlist *cmdlist = node->cmdlist; + struct g2d_buf_info *buf_info = &node->buf_info; int offset; + int ret; int i; - for (i = 0; i < node->map_nr; i++) { + for (i = 0; i < buf_info->map_nr; i++) { + enum g2d_reg_type reg_type; + int reg_pos; unsigned long handle; dma_addr_t *addr; - offset = cmdlist->last - (i * 2 + 1); - handle = cmdlist->data[offset]; + reg_pos = cmdlist->last - 2 * (i + 1); + + offset = cmdlist->data[reg_pos]; + handle = cmdlist->data[reg_pos + 1]; + + reg_type = g2d_get_reg_type(offset); + if (reg_type == REG_TYPE_NONE) { + ret = -EFAULT; + goto err; + } - if (node->buf_type[i] == BUF_TYPE_GEM) { + if (buf_info->types[reg_type] == BUF_TYPE_GEM) { addr = exynos_drm_gem_get_dma_addr(drm_dev, handle, file); if (IS_ERR(addr)) { - node->map_nr = i; - return -EFAULT; + ret = -EFAULT; + goto err; } } else { struct drm_exynos_g2d_userptr g2d_userptr; if (copy_from_user(&g2d_userptr, (void __user *)handle, sizeof(struct drm_exynos_g2d_userptr))) { - node->map_nr = i; - return -EFAULT; + ret = -EFAULT; + goto err; } addr = g2d_userptr_get_dma_addr(drm_dev, @@ -545,16 +619,21 @@ static int g2d_map_cmdlist_gem(struct g2d_data *g2d, file, &handle); if (IS_ERR(addr)) { - node->map_nr = i; - return -EFAULT; + ret = -EFAULT; + goto err; } } - cmdlist->data[offset] = *addr; - node->handles[i] = handle; + cmdlist->data[reg_pos + 1] = *addr; + buf_info->reg_types[i] = reg_type; + buf_info->handles[reg_type] = handle; } return 0; + +err: + buf_info->map_nr = i; + return ret; } static void g2d_unmap_cmdlist_gem(struct g2d_data *g2d, @@ -562,23 +641,30 @@ static void g2d_unmap_cmdlist_gem(struct g2d_data *g2d, struct drm_file *filp) { struct exynos_drm_subdrv *subdrv = &g2d->subdrv; + struct g2d_buf_info *buf_info = &node->buf_info; int i; - for (i = 0; i < node->map_nr; i++) { - unsigned long handle = node->handles[i]; + for (i = 0; i < buf_info->map_nr; i++) { + enum g2d_reg_type reg_type; + unsigned long handle; + + reg_type = buf_info->reg_types[i]; - if (node->buf_type[i] == BUF_TYPE_GEM) + handle = buf_info->handles[reg_type]; + + if (buf_info->types[reg_type] == BUF_TYPE_GEM) exynos_drm_gem_put_dma_addr(subdrv->drm_dev, handle, filp); else g2d_userptr_put_dma_addr(subdrv->drm_dev, handle, false); - node->handles[i] = 0; - node->buf_type[i] = 0; + buf_info->reg_types[i] = REG_TYPE_NONE; + buf_info->handles[reg_type] = 0; + buf_info->types[reg_type] = 0; } - node->map_nr = 0; + buf_info->map_nr = 0; } static void g2d_dma_start(struct g2d_data *g2d, @@ -721,20 +807,12 @@ static int g2d_check_reg_offset(struct device *dev, int i; for (i = 0; i < nr; i++) { - index = cmdlist->last - 2 * (i + 1); + struct g2d_buf_info *buf_info = &node->buf_info; + enum g2d_reg_type reg_type; - if (for_addr) { - /* check userptr buffer type. */ - reg_offset = (cmdlist->data[index] & - ~0x7fffffff) >> 31; - if (reg_offset) { - node->buf_type[i] = BUF_TYPE_USERPTR; - cmdlist->data[index] &= ~G2D_BUF_USERPTR; - } - } + index = cmdlist->last - 2 * (i + 1); reg_offset = cmdlist->data[index] & ~0xfffff000; - if (reg_offset < G2D_VALID_START || reg_offset > G2D_VALID_END) goto err; if (reg_offset % 4) @@ -750,8 +828,16 @@ static int g2d_check_reg_offset(struct device *dev, if (!for_addr) goto err; - if (node->buf_type[i] != BUF_TYPE_USERPTR) - node->buf_type[i] = BUF_TYPE_GEM; + reg_type = g2d_get_reg_type(reg_offset); + if (reg_type == REG_TYPE_NONE) + goto err; + + /* check userptr buffer type. */ + if ((cmdlist->data[index] & ~0x7fffffff) >> 31) { + buf_info->types[reg_type] = BUF_TYPE_USERPTR; + cmdlist->data[index] &= ~G2D_BUF_USERPTR; + } else + buf_info->types[reg_type] = BUF_TYPE_GEM; break; default: if (for_addr) @@ -898,7 +984,7 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data, if (ret < 0) goto err_free_event; - node->map_nr = req->cmd_buf_nr; + node->buf_info.map_nr = req->cmd_buf_nr; if (req->cmd_buf_nr) { struct drm_exynos_g2d_cmd *cmd_buf;