From patchwork Fri May 18 09:28:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qiang Yu X-Patchwork-Id: 10414247 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id DE6C060365 for ; Mon, 21 May 2018 08:30:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CF2C3286F5 for ; Mon, 21 May 2018 08:30:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C3D82287C1; Mon, 21 May 2018 08:30:26 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.1 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 26BA3286F5 for ; Mon, 21 May 2018 08:30:26 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 22B416F044; Mon, 21 May 2018 08:22:16 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-pg0-x242.google.com (mail-pg0-x242.google.com [IPv6:2607:f8b0:400e:c05::242]) by gabe.freedesktop.org (Postfix) with ESMTPS id E03056ECCA for ; Fri, 18 May 2018 09:30:17 +0000 (UTC) Received: by mail-pg0-x242.google.com with SMTP id e1-v6so3081136pga.6 for ; Fri, 18 May 2018 02:30:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=EpMIvJQLq4hiAgLYZniLNx9/F1hAZDYXsJAmTPEplVA=; b=Af2GYZsqodAwsLM+FJySWzYIf7Cmt558BbJ1QpPN1immnFR+hF6yFAF5tiCJTC4arn C95XH9wlwET40/K3ZMHRxLaDvJbeoQbj1drbiymvkf9bbCAJwFFKIKDrjlgjznWVKwfR x+H3R4sK3u31SJb0oaMGSzWnmivKVyIO5LsmiLtHP+vJx+CPrWMvrzaIrofHtEy423Yr y2ocXN5PY7DrdPbQS8+zviQ3bxhOrvYAYfdL/MvfxHpmy87tjoAdXtAK6XISOUeTNgSg SCL4op2fbmptQaa4sU++kw5te/VwNrsrzDdbXDRhB07dSNTpqpFE+GxTV4E/W5Csdt60 eXcQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=EpMIvJQLq4hiAgLYZniLNx9/F1hAZDYXsJAmTPEplVA=; b=s/uSZj3TGa803OrTpXQvVRjtpSXujkDSWFNEF29a4I5uSIYn5XOZ/CK7z1aHeIk1YT vOOcjro5fjOmRaZUq1pkQudIvauNcH9hUuWYJM35VXzjthcr0Yes1m4m6zBfs9HZKZW6 hHRT1531Rdo2aocThg2SEznWJM8j2XHCB/axjzo/2IrglzDMnXRfpbZ/3vjtbXVo423m qsQCXolNLwqn2Bj1Iu+U4Q5ZaUdap6ewmLpjt6gfGhLqxSNPVBMghnW+hXenNt7ZaXln VZfPP42eMlLbAJywe73ITWjvl0f0/6ViYrACiUdjNEfWSTJKTuz+W3sohj45XcYox5eT y6GQ== X-Gm-Message-State: ALKqPwci9NFXW6GwpERLm0Dd8w3dE6vWxPVonwHumKLyB2RrtSJFFaKY O1OjsqqLIMtKwZzzSqJFjdeFIHaKsCg= X-Google-Smtp-Source: AB8JxZr9UUkdLxFt1IfyMqeq8j1MlSiDBZ6cKD4aOg3p1odsAqu7AHUOVgK2WJJV0BYSpRXNq/Xfmg== X-Received: by 2002:a63:384d:: with SMTP id h13-v6mr6851736pgn.209.1526635817258; Fri, 18 May 2018 02:30:17 -0700 (PDT) Received: from localhost.localdomain (210-140-84-216.jp-east.compute.idcfcloud.com. [210.140.84.216]) by smtp.gmail.com with ESMTPSA id h191-v6sm10543832pgc.11.2018.05.18.02.30.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 18 May 2018 02:30:16 -0700 (PDT) From: Qiang Yu To: dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org Subject: [PATCH RFC 12/24] drm/lima: add GP related functions Date: Fri, 18 May 2018 17:28:03 +0800 Message-Id: <20180518092815.25280-13-yuq825@gmail.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180518092815.25280-1-yuq825@gmail.com> References: <20180518092815.25280-1-yuq825@gmail.com> X-Mailman-Approved-At: Mon, 21 May 2018 08:18:10 +0000 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: Simon Shields , Marek Vasut , Connor Abbott , Neil Armstrong , Andrei Paulau <7134956@gmail.com>, Vasily Khoruzhick , Qiang Yu , Erico Nunes MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP GP is a processor for OpenGL vertex shader processing. Signed-off-by: Qiang Yu --- drivers/gpu/drm/lima/lima_gp.c | 293 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/lima/lima_gp.h | 34 ++++ 2 files changed, 327 insertions(+) create mode 100644 drivers/gpu/drm/lima/lima_gp.c create mode 100644 drivers/gpu/drm/lima/lima_gp.h diff --git a/drivers/gpu/drm/lima/lima_gp.c b/drivers/gpu/drm/lima/lima_gp.c new file mode 100644 index 000000000000..8fb49986418a --- /dev/null +++ b/drivers/gpu/drm/lima/lima_gp.c @@ -0,0 +1,293 @@ +/* + * Copyright (C) 2017-2018 Lima Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include + +#include + +#include "lima_device.h" +#include "lima_gp.h" +#include "lima_regs.h" + +#define gp_write(reg, data) writel(data, ip->iomem + LIMA_GP_##reg) +#define gp_read(reg) readl(ip->iomem + LIMA_GP_##reg) + +static irqreturn_t lima_gp_irq_handler(int irq, void *data) +{ + struct lima_ip *ip = data; + struct lima_device *dev = ip->dev; + struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_gp; + u32 state = gp_read(INT_STAT); + u32 status = gp_read(STATUS); + bool done = false; + + /* for shared irq case */ + if (!state) + return IRQ_NONE; + + if (state & LIMA_GP_IRQ_MASK_ERROR) { + dev_err(dev->dev, "gp error irq state=%x status=%x\n", + state, status); + + /* mask all interrupts before hard reset */ + gp_write(INT_MASK, 0); + + pipe->error = true; + done = true; + } + else { + bool valid = state & (LIMA_GP_IRQ_VS_END_CMD_LST | + LIMA_GP_IRQ_PLBU_END_CMD_LST); + bool active = status & (LIMA_GP_STATUS_VS_ACTIVE | + LIMA_GP_STATUS_PLBU_ACTIVE); + done = valid && !active; + } + + gp_write(INT_CLEAR, state); + + if (done) + lima_sched_pipe_task_done(pipe); + + return IRQ_HANDLED; +} + +static void lima_gp_soft_reset_async(struct lima_ip *ip) +{ + if (ip->data.async_reset) + return; + + gp_write(INT_MASK, 0); + gp_write(INT_CLEAR, LIMA_GP_IRQ_RESET_COMPLETED); + gp_write(CMD, LIMA_GP_CMD_SOFT_RESET); + ip->data.async_reset = true; +} + +static int lima_gp_soft_reset_async_wait(struct lima_ip *ip) +{ + struct lima_device *dev = ip->dev; + int timeout; + + if (!ip->data.async_reset) + return 0; + + for (timeout = 1000; timeout > 0; timeout--) { + if (gp_read(INT_RAWSTAT) & LIMA_GP_IRQ_RESET_COMPLETED) + break; + } + if (!timeout) { + dev_err(dev->dev, "gp soft reset time out\n"); + return -ETIMEDOUT; + } + + gp_write(INT_CLEAR, LIMA_GP_IRQ_MASK_ALL); + gp_write(INT_MASK, LIMA_GP_IRQ_MASK_USED); + + ip->data.async_reset = false; + return 0; +} + +static int lima_gp_task_validate(struct lima_sched_pipe *pipe, + struct lima_sched_task *task) +{ + struct drm_lima_gp_frame *frame = task->frame; + u32 *f = frame->frame; + (void)pipe; + + if (f[LIMA_GP_VSCL_START_ADDR >> 2] > + f[LIMA_GP_VSCL_END_ADDR >> 2] || + f[LIMA_GP_PLBUCL_START_ADDR >> 2] > + f[LIMA_GP_PLBUCL_END_ADDR >> 2] || + f[LIMA_GP_PLBU_ALLOC_START_ADDR >> 2] > + f[LIMA_GP_PLBU_ALLOC_END_ADDR >> 2]) + return -EINVAL; + + if (f[LIMA_GP_VSCL_START_ADDR >> 2] == + f[LIMA_GP_VSCL_END_ADDR >> 2] && + f[LIMA_GP_PLBUCL_START_ADDR >> 2] == + f[LIMA_GP_PLBUCL_END_ADDR >> 2]) + return -EINVAL; + + return 0; +} + +static void lima_gp_task_run(struct lima_sched_pipe *pipe, + struct lima_sched_task *task) +{ + struct lima_ip *ip = pipe->processor[0]; + struct drm_lima_gp_frame *frame = task->frame; + u32 *f = frame->frame; + u32 cmd = 0; + int i; + + if (f[LIMA_GP_VSCL_START_ADDR >> 2] != + f[LIMA_GP_VSCL_END_ADDR >> 2]) + cmd |= LIMA_GP_CMD_START_VS; + if (f[LIMA_GP_PLBUCL_START_ADDR >> 2] != + f[LIMA_GP_PLBUCL_END_ADDR >> 2]) + cmd |= LIMA_GP_CMD_START_PLBU; + + /* before any hw ops, wait last success task async soft reset */ + lima_gp_soft_reset_async_wait(ip); + + for (i = 0; i < LIMA_GP_FRAME_REG_NUM; i++) + writel(f[i], ip->iomem + LIMA_GP_VSCL_START_ADDR + i * 4); + + gp_write(CMD, LIMA_GP_CMD_UPDATE_PLBU_ALLOC); + gp_write(CMD, cmd); +} + +static int lima_gp_hard_reset(struct lima_ip *ip) +{ + struct lima_device *dev = ip->dev; + int timeout; + + gp_write(PERF_CNT_0_LIMIT, 0xC0FFE000); + gp_write(INT_MASK, 0); + gp_write(CMD, LIMA_GP_CMD_RESET); + for (timeout = 1000; timeout > 0; timeout--) { + gp_write(PERF_CNT_0_LIMIT, 0xC01A0000); + if (gp_read(PERF_CNT_0_LIMIT) == 0xC01A0000) + break; + } + if (!timeout) { + dev_err(dev->dev, "gp hard reset timeout\n"); + return -ETIMEDOUT; + } + + gp_write(PERF_CNT_0_LIMIT, 0); + gp_write(INT_CLEAR, LIMA_GP_IRQ_MASK_ALL); + gp_write(INT_MASK, LIMA_GP_IRQ_MASK_USED); + return 0; +} + +static void lima_gp_task_fini(struct lima_sched_pipe *pipe) +{ + lima_gp_soft_reset_async(pipe->processor[0]); +} + +static void lima_gp_task_error(struct lima_sched_pipe *pipe) +{ + lima_gp_hard_reset(pipe->processor[0]); +} + +static void lima_gp_task_mmu_error(struct lima_sched_pipe *pipe) +{ + lima_sched_pipe_task_done(pipe); +} + +static void lima_gp_print_version(struct lima_ip *ip) +{ + u32 version, major, minor; + char *name; + + version = gp_read(VERSION); + major = (version >> 8) & 0xFF; + minor = version & 0xFF; + switch (version >> 16) { + case 0xA07: + name = "mali200"; + break; + case 0xC07: + name = "mali300"; + break; + case 0xB07: + name = "mali400"; + break; + case 0xD07: + name = "mali450"; + break; + default: + name = "unknow"; + break; + } + dev_info(ip->dev->dev, "%s - %s version major %d minor %d\n", + lima_ip_name(ip), name, major, minor); +} + +static struct kmem_cache *lima_gp_task_slab = NULL; +static int lima_gp_task_slab_refcnt = 0; + +int lima_gp_init(struct lima_ip *ip) +{ + struct lima_device *dev = ip->dev; + int err; + + lima_gp_print_version(ip); + + ip->data.async_reset = false; + lima_gp_soft_reset_async(ip); + err = lima_gp_soft_reset_async_wait(ip); + if (err) + return err; + + err = devm_request_irq(dev->dev, ip->irq, lima_gp_irq_handler, 0, + lima_ip_name(ip), ip); + if (err) { + dev_err(dev->dev, "gp %s fail to request irq\n", + lima_ip_name(ip)); + return err; + } + + return 0; +} + +void lima_gp_fini(struct lima_ip *ip) +{ + +} + +int lima_gp_pipe_init(struct lima_device *dev) +{ + int frame_size = sizeof(struct drm_lima_gp_frame); + struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_gp; + + if (!lima_gp_task_slab) { + lima_gp_task_slab = kmem_cache_create( + "lima_gp_task", sizeof(struct lima_sched_task) + frame_size, + 0, SLAB_HWCACHE_ALIGN, NULL); + if (!lima_gp_task_slab) + return -ENOMEM; + } + lima_gp_task_slab_refcnt++; + + pipe->frame_size = frame_size; + pipe->task_slab = lima_gp_task_slab; + + pipe->task_validate = lima_gp_task_validate; + pipe->task_run = lima_gp_task_run; + pipe->task_fini = lima_gp_task_fini; + pipe->task_error = lima_gp_task_error; + pipe->task_mmu_error = lima_gp_task_mmu_error; + + return 0; +} + +void lima_gp_pipe_fini(struct lima_device *dev) +{ + if (!--lima_gp_task_slab_refcnt) { + kmem_cache_destroy(lima_gp_task_slab); + lima_gp_task_slab = NULL; + } +} diff --git a/drivers/gpu/drm/lima/lima_gp.h b/drivers/gpu/drm/lima/lima_gp.h new file mode 100644 index 000000000000..8354911e50ce --- /dev/null +++ b/drivers/gpu/drm/lima/lima_gp.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2017-2018 Lima Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef __LIMA_GP_H__ +#define __LIMA_GP_H__ + +struct lima_ip; +struct lima_device; + +int lima_gp_init(struct lima_ip *ip); +void lima_gp_fini(struct lima_ip *ip); + +int lima_gp_pipe_init(struct lima_device *dev); +void lima_gp_pipe_fini(struct lima_device *dev); + +#endif