From patchwork Mon Jan 22 18:04:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Crouse X-Patchwork-Id: 10178991 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 3AE34601D5 for ; Mon, 22 Jan 2018 18:04:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2EC3C27FA1 for ; Mon, 22 Jan 2018 18:04:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 23124283C5; Mon, 22 Jan 2018 18:04:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 32F3927FA1 for ; Mon, 22 Jan 2018 18:04:29 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id EBBC06E293; Mon, 22 Jan 2018 18:04:24 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from smtp.codeaurora.org (smtp.codeaurora.org [198.145.29.96]) by gabe.freedesktop.org (Postfix) with ESMTPS id 57C996E284; Mon, 22 Jan 2018 18:04:20 +0000 (UTC) Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 43C4760328; Mon, 22 Jan 2018 18:04:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1516644260; bh=otSHmfkpEMFjD+k1adMD4XP5bMd83yW4wjAvyRtgHYY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=g32kV0O09482rF8pqAjmdJ58ENK0glSA/R2f5aOB08KBt0p9DAhtJ5gjEgE4+40Yj GZ4qQXNBvI+iqrrCLjxCyqk2nK7hSN4DgaLtKqBCEX5AZYPCFKcgYkah+BO4TmWg7P J1mzZx5IhXSKKN5xhXVakRUv2BHVsvInJ7Dhb+YI= Received: from jcrouse-lnx.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: jcrouse@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 0F63860398; Mon, 22 Jan 2018 18:04:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1516644259; bh=otSHmfkpEMFjD+k1adMD4XP5bMd83yW4wjAvyRtgHYY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TNatcJUH0LQl+QlLuiYiFbEgNRO4VTgcr19LsM1S9aCkxgvX2yQw0TzZNojiYq2EN +6SXdQIwS+nk+3nd4t7htprcm4jif174bwt+7tYmj3pAYX0HHNeJtG3JUroRptTUhe M9Rkc/KEFGBQV1DeIiF1abpHLEI6ix6jTrPZ2VkM= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 0F63860398 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=jcrouse@codeaurora.org From: Jordan Crouse To: freedreno@lists.freedesktop.org, dri-devel@lists.freedesktop.org Subject: [PATCH 1/5] drm/msm/adreno: Make microcode loading target specific Date: Mon, 22 Jan 2018 11:04:09 -0700 Message-Id: <1516644253-31546-2-git-send-email-jcrouse@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1516644253-31546-1-git-send-email-jcrouse@codeaurora.org> References: <1516644253-31546-1-git-send-email-jcrouse@codeaurora.org> Cc: Jordan Crouse , linux-arm-msm@vger.kernel.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Move microcode loading to be target specific. While this results in a bit more code duplication (especially between A3XX/A4XX) this gives us more flexibility for newer targets that don't need to keep an extra copy of the firmware data around in memory. Signed-off-by: Jordan Crouse --- drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 83 ++++++++++++++++++++++----------- drivers/gpu/drm/msm/adreno/a3xx_gpu.h | 2 + drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 69 ++++++++++++++++++++------- drivers/gpu/drm/msm/adreno/a4xx_gpu.h | 2 + drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 24 +++++++--- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 30 ------------ drivers/gpu/drm/msm/adreno/adreno_gpu.h | 3 -- 7 files changed, 127 insertions(+), 86 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c index 4baef27..fbc2d11 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c @@ -69,11 +69,58 @@ static bool a3xx_me_init(struct msm_gpu *gpu) return a3xx_idle(gpu); } -static int a3xx_hw_init(struct msm_gpu *gpu) +static int a3xx_ucode_init(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); struct a3xx_gpu *a3xx_gpu = to_a3xx_gpu(adreno_gpu); + const struct firmware *fw; uint32_t *ptr, len; + int i; + + if (!a3xx_gpu->pm4) { + fw = adreno_request_fw(adreno_gpu, adreno_gpu->info->pm4fw); + if (IS_ERR(fw)) + return PTR_ERR(fw); + + a3xx_gpu->pm4 = fw; + } + + if (!a3xx_gpu->pfp) { + fw = adreno_request_fw(adreno_gpu, adreno_gpu->info->pfpfw); + if (IS_ERR(fw)) + return PTR_ERR(fw); + + a3xx_gpu->pfp = fw; + } + + /* Load PM4: */ + ptr = (uint32_t *)(a3xx_gpu->pm4->data); + len = a3xx_gpu->pm4->size / 4; + DBG("loading PM4 ucode version: %x", ptr[1]); + + gpu_write(gpu, REG_AXXX_CP_DEBUG, + AXXX_CP_DEBUG_DYNAMIC_CLK_DISABLE | + AXXX_CP_DEBUG_MIU_128BIT_WRITE_ENABLE); + gpu_write(gpu, REG_AXXX_CP_ME_RAM_WADDR, 0); + for (i = 1; i < len; i++) + gpu_write(gpu, REG_AXXX_CP_ME_RAM_DATA, ptr[i]); + + /* Load PFP: */ + ptr = (uint32_t *)(a3xx_gpu->pfp->data); + len = a3xx_gpu->pfp->size / 4; + DBG("loading PFP ucode version: %x", ptr[5]); + + gpu_write(gpu, REG_A3XX_CP_PFP_UCODE_ADDR, 0); + for (i = 1; i < len; i++) + gpu_write(gpu, REG_A3XX_CP_PFP_UCODE_DATA, ptr[i]); + + return 0; +} + +static int a3xx_hw_init(struct msm_gpu *gpu) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a3xx_gpu *a3xx_gpu = to_a3xx_gpu(adreno_gpu); int i, ret; DBG("%s", gpu->name); @@ -225,6 +272,10 @@ static int a3xx_hw_init(struct msm_gpu *gpu) if (ret) return ret; + ret = a3xx_ucode_init(gpu); + if (ret) + return ret; + /* setup access protection: */ gpu_write(gpu, REG_A3XX_CP_PROTECT_CTRL, 0x00000007); @@ -249,33 +300,6 @@ static int a3xx_hw_init(struct msm_gpu *gpu) /* VBIF registers */ gpu_write(gpu, REG_A3XX_CP_PROTECT(12), 0x6b00c000); - /* NOTE: PM4/micro-engine firmware registers look to be the same - * for a2xx and a3xx.. we could possibly push that part down to - * adreno_gpu base class. Or push both PM4 and PFP but - * parameterize the pfp ucode addr/data registers.. - */ - - /* Load PM4: */ - ptr = (uint32_t *)(adreno_gpu->pm4->data); - len = adreno_gpu->pm4->size / 4; - DBG("loading PM4 ucode version: %x", ptr[1]); - - gpu_write(gpu, REG_AXXX_CP_DEBUG, - AXXX_CP_DEBUG_DYNAMIC_CLK_DISABLE | - AXXX_CP_DEBUG_MIU_128BIT_WRITE_ENABLE); - gpu_write(gpu, REG_AXXX_CP_ME_RAM_WADDR, 0); - for (i = 1; i < len; i++) - gpu_write(gpu, REG_AXXX_CP_ME_RAM_DATA, ptr[i]); - - /* Load PFP: */ - ptr = (uint32_t *)(adreno_gpu->pfp->data); - len = adreno_gpu->pfp->size / 4; - DBG("loading PFP ucode version: %x", ptr[5]); - - gpu_write(gpu, REG_A3XX_CP_PFP_UCODE_ADDR, 0); - for (i = 1; i < len; i++) - gpu_write(gpu, REG_A3XX_CP_PFP_UCODE_DATA, ptr[i]); - /* CP ROQ queue sizes (bytes) - RB:16, ST:16, IB1:32, IB2:64 */ if (adreno_is_a305(adreno_gpu) || adreno_is_a306(adreno_gpu) || adreno_is_a320(adreno_gpu)) { @@ -326,6 +350,9 @@ static void a3xx_destroy(struct msm_gpu *gpu) DBG("%s", gpu->name); + release_firmware(a3xx_gpu->pm4); + release_firmware(a3xx_gpu->pfp); + adreno_gpu_cleanup(adreno_gpu); #ifdef CONFIG_MSM_OCMEM diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.h b/drivers/gpu/drm/msm/adreno/a3xx_gpu.h index ab60dc9..e4fcc0d 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.h @@ -32,6 +32,8 @@ struct a3xx_gpu { /* if OCMEM is used for GMEM: */ uint32_t ocmem_base; void *ocmem_hdl; + + const struct firmware *pm4, *pfp; }; #define to_a3xx_gpu(x) container_of(x, struct a3xx_gpu, base) diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c index 8199a4b..7d0a858 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c @@ -141,12 +141,55 @@ static bool a4xx_me_init(struct msm_gpu *gpu) return a4xx_idle(gpu); } -static int a4xx_hw_init(struct msm_gpu *gpu) +static int a4xx_ucode_init(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); struct a4xx_gpu *a4xx_gpu = to_a4xx_gpu(adreno_gpu); + const struct firmware *fw; uint32_t *ptr, len; - int i, ret; + int i; + + if (!a4xx_gpu->pm4) { + fw = adreno_request_fw(adreno_gpu, adreno_gpu->info->pm4fw); + if (IS_ERR(fw)) + return PTR_ERR(fw); + + a4xx_gpu->pm4 = fw; + } + + if (!a4xx_gpu->pfp) { + fw = adreno_request_fw(adreno_gpu, adreno_gpu->info->pfpfw); + if (IS_ERR(fw)) + return PTR_ERR(fw); + + a4xx_gpu->pfp = fw; + } + + /* Load PM4: */ + ptr = (uint32_t *)(a4xx_gpu->pm4->data); + len = a4xx_gpu->pm4->size / 4; + DBG("loading PM4 ucode version: %u", ptr[0]); + gpu_write(gpu, REG_A4XX_CP_ME_RAM_WADDR, 0); + for (i = 1; i < len; i++) + gpu_write(gpu, REG_A4XX_CP_ME_RAM_DATA, ptr[i]); + + /* Load PFP: */ + ptr = (uint32_t *)(a4xx_gpu->pfp->data); + len = a4xx_gpu->pfp->size / 4; + DBG("loading PFP ucode version: %u", ptr[0]); + + gpu_write(gpu, REG_A4XX_CP_PFP_UCODE_ADDR, 0); + for (i = 1; i < len; i++) + gpu_write(gpu, REG_A4XX_CP_PFP_UCODE_DATA, ptr[i]); + + return 0; +} + +static int a4xx_hw_init(struct msm_gpu *gpu) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a4xx_gpu *a4xx_gpu = to_a4xx_gpu(adreno_gpu); + int ret; if (adreno_is_a420(adreno_gpu)) { gpu_write(gpu, REG_A4XX_VBIF_ABIT_SORT, 0x0001001F); @@ -273,22 +316,9 @@ static int a4xx_hw_init(struct msm_gpu *gpu) if (ret) return ret; - /* Load PM4: */ - ptr = (uint32_t *)(adreno_gpu->pm4->data); - len = adreno_gpu->pm4->size / 4; - DBG("loading PM4 ucode version: %u", ptr[0]); - gpu_write(gpu, REG_A4XX_CP_ME_RAM_WADDR, 0); - for (i = 1; i < len; i++) - gpu_write(gpu, REG_A4XX_CP_ME_RAM_DATA, ptr[i]); - - /* Load PFP: */ - ptr = (uint32_t *)(adreno_gpu->pfp->data); - len = adreno_gpu->pfp->size / 4; - DBG("loading PFP ucode version: %u", ptr[0]); - - gpu_write(gpu, REG_A4XX_CP_PFP_UCODE_ADDR, 0); - for (i = 1; i < len; i++) - gpu_write(gpu, REG_A4XX_CP_PFP_UCODE_DATA, ptr[i]); + ret = a4xx_ucode_init(gpu); + if (ret) + return ret; /* clear ME_HALT to start micro engine */ gpu_write(gpu, REG_A4XX_CP_ME_CNTL, 0); @@ -324,6 +354,9 @@ static void a4xx_destroy(struct msm_gpu *gpu) DBG("%s", gpu->name); + release_firmware(a4xx_gpu->pm4); + release_firmware(a4xx_gpu->pfp); + adreno_gpu_cleanup(adreno_gpu); #ifdef CONFIG_MSM_OCMEM diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.h b/drivers/gpu/drm/msm/adreno/a4xx_gpu.h index f757184..2c80af7 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.h @@ -27,6 +27,8 @@ struct a4xx_gpu { /* if OCMEM is used for GMEM: */ uint32_t ocmem_base; void *ocmem_hdl; + + const struct firmware *pm4, *pfp; }; #define to_a4xx_gpu(x) container_of(x, struct a4xx_gpu, base) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 7e09d44..e8e726e 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -434,20 +434,30 @@ static int a5xx_preempt_start(struct msm_gpu *gpu) static struct drm_gem_object *a5xx_ucode_load_bo(struct msm_gpu *gpu, - const struct firmware *fw, u64 *iova) + const char *fwname, u64 *iova) { + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + const struct firmware *fw; struct drm_gem_object *bo; void *ptr; + fw = adreno_request_fw(adreno_gpu, fwname); + if (IS_ERR(fw)) + return ERR_CAST(fw); + ptr = msm_gem_kernel_new_locked(gpu->dev, fw->size - 4, MSM_BO_UNCACHED | MSM_BO_GPU_READONLY, gpu->aspace, &bo, iova); - if (IS_ERR(ptr)) - return ERR_CAST(ptr); + if (IS_ERR(ptr)) { + bo = ERR_CAST(ptr); + goto out; + } memcpy(ptr, &fw->data[4], fw->size - 4); msm_gem_put_vaddr(bo); +out: + release_firmware(fw); return bo; } @@ -458,8 +468,8 @@ static int a5xx_ucode_init(struct msm_gpu *gpu) int ret; if (!a5xx_gpu->pm4_bo) { - a5xx_gpu->pm4_bo = a5xx_ucode_load_bo(gpu, adreno_gpu->pm4, - &a5xx_gpu->pm4_iova); + a5xx_gpu->pm4_bo = a5xx_ucode_load_bo(gpu, + adreno_gpu->info->pm4fw, &a5xx_gpu->pm4_iova); if (IS_ERR(a5xx_gpu->pm4_bo)) { ret = PTR_ERR(a5xx_gpu->pm4_bo); @@ -471,8 +481,8 @@ static int a5xx_ucode_init(struct msm_gpu *gpu) } if (!a5xx_gpu->pfp_bo) { - a5xx_gpu->pfp_bo = a5xx_ucode_load_bo(gpu, adreno_gpu->pfp, - &a5xx_gpu->pfp_iova); + a5xx_gpu->pfp_bo = a5xx_ucode_load_bo(gpu, + adreno_gpu->info->pfpfw, &a5xx_gpu->pfp_iova); if (IS_ERR(a5xx_gpu->pfp_bo)) { ret = PTR_ERR(a5xx_gpu->pfp_bo); diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index de63ff2..9253550 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -138,29 +138,6 @@ int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value) return ERR_PTR(-ENOENT); } -static int adreno_load_fw(struct adreno_gpu *adreno_gpu) -{ - const struct firmware *fw; - - if (adreno_gpu->pm4) - return 0; - - fw = adreno_request_fw(adreno_gpu, adreno_gpu->info->pm4fw); - if (IS_ERR(fw)) - return PTR_ERR(fw); - adreno_gpu->pm4 = fw; - - fw = adreno_request_fw(adreno_gpu, adreno_gpu->info->pfpfw); - if (IS_ERR(fw)) { - release_firmware(adreno_gpu->pm4); - adreno_gpu->pm4 = NULL; - return PTR_ERR(fw); - } - adreno_gpu->pfp = fw; - - return 0; -} - int adreno_hw_init(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); @@ -168,10 +145,6 @@ int adreno_hw_init(struct msm_gpu *gpu) DBG("%s", gpu->name); - ret = adreno_load_fw(adreno_gpu); - if (ret) - return ret; - for (i = 0; i < gpu->nr_rings; i++) { struct msm_ringbuffer *ring = gpu->rb[i]; @@ -569,8 +542,5 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu) { - release_firmware(adreno_gpu->pm4); - release_firmware(adreno_gpu->pfp); - msm_gpu_cleanup(&adreno_gpu->base); } diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index 8d3d0a9..bfdaaf2 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -114,9 +114,6 @@ struct adreno_gpu { FW_LOCATION_HELPER, } fwloc; - /* firmware: */ - const struct firmware *pm4, *pfp; - /* * Register offsets are different between some GPUs. * GPU specific offsets will be exported by GPU specific