From patchwork Thu Jul 22 22:21:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 484706 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 673DBC4320A for ; Thu, 22 Jul 2021 22:17:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4E6FA60EB2 for ; Thu, 22 Jul 2021 22:17:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232434AbhGVVhN (ORCPT ); Thu, 22 Jul 2021 17:37:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41144 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232360AbhGVVhJ (ORCPT ); Thu, 22 Jul 2021 17:37:09 -0400 Received: from mail-pj1-x102f.google.com (mail-pj1-x102f.google.com [IPv6:2607:f8b0:4864:20::102f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 551BBC061760; Thu, 22 Jul 2021 15:17:43 -0700 (PDT) Received: by mail-pj1-x102f.google.com with SMTP id hg12-20020a17090b300cb02901736d9d2218so1262151pjb.1; Thu, 22 Jul 2021 15:17:43 -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 :mime-version:content-transfer-encoding; bh=KOj4T9MSF9gxvN5EZKSnYxLTf4ljzXVKQMqxx38M28M=; b=mZpAQSjCV17+qaPbtXgZ5eEFb+4CO3M2Zx+OEKYxNd3R2OoEEQbQCVKLAGL915e+Fw nphREHgjFC/Y0ansvqtf8IvbsvF81wZDNgneD/fCzVA9dCrWN7gD/8n49NWPzNtCyZh2 dpghLZPzhXGiVaNQ13SagcquVJUiXr0yX9Zx+YVmSSjPpzdszRxd3wQlwlM8KMcDD3w6 gNAfZvx1a3tiEFyEc7C+zOXVFvYnqRALFfbxbtQ+FlzMszf6iHaIq/6/h6sNNrh3Azjt NfWtvlMPWZEV28YJZZNiUSQ+QN77u+vds9QT6qooRciqpmPkyPtIoQ2I0m2XNQp24ecq o/bw== 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:mime-version:content-transfer-encoding; bh=KOj4T9MSF9gxvN5EZKSnYxLTf4ljzXVKQMqxx38M28M=; b=arL/0Hfyi9Ub9i8j7Dax5vwwK9kQCZxB1519qsU7+LkImfut5uBu199BzQkjFLCs62 C1XlvMqXDaN+2pcx8u4gXQs0SpdjLt9dP3wXqhAmHOzsMMxjqp+ulIsqyyccPVIuAZvJ lHmBflIi9rFLV7PW8PUoL9rNWd4W21PjgWpzCFwIReknEW8g9hW4sl5FeDeNmlPkVn+/ UG2eBkEQhkM3kkZVmZLt146b/r0080mZxyt0M9vtcpMmozS93kpxsajderX519jv/sY7 M0VADZicu5CN/t6RiU73tFvuq4zZ6fnnOoOQI1untSN1S+a1442A1JUuYlbFfnIyoFUD wHbw== X-Gm-Message-State: AOAM532mgvIvKCLGiW+TpN6NSzmAOI2DOtI/Q0eOkzyaOsQoErydCoer +VyWHy0qsZHmKYkUXzjXP9g= X-Google-Smtp-Source: ABdhPJx2WIFTxyaXEUhhk1qZC8990wqgTFa2FVN74TE5kE5mlZXFOp3f1jTam5iWhE0nQFO228llJg== X-Received: by 2002:a17:90a:55c8:: with SMTP id o8mr10814843pjm.223.1626992262883; Thu, 22 Jul 2021 15:17:42 -0700 (PDT) Received: from localhost (c-73-25-156-94.hsd1.or.comcast.net. [73.25.156.94]) by smtp.gmail.com with ESMTPSA id 5sm35794307pgv.25.2021.07.22.15.17.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Jul 2021 15:17:41 -0700 (PDT) From: Rob Clark To: dri-devel@lists.freedesktop.org Cc: Rob Clark , Rob Clark , Sean Paul , David Airlie , Daniel Vetter , Jordan Crouse , Jonathan Marek , Akhil P Oommen , Sai Prakash Ranjan , Sharat Masetty , Douglas Anderson , linux-kernel@vger.kernel.org (open list), linux-arm-msm@vger.kernel.org (open list:DRM DRIVER FOR MSM ADRENO GPU), freedreno@lists.freedesktop.org (open list:DRM DRIVER FOR MSM ADRENO GPU) Subject: [PATCH 1/3] drm/msm: Split out devfreq handling Date: Thu, 22 Jul 2021 15:21:39 -0700 Message-Id: <20210722222145.1759900-2-robdclark@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210722222145.1759900-1-robdclark@gmail.com> References: <20210722222145.1759900-1-robdclark@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org From: Rob Clark Before we start adding more cleverness, split it into it's own file. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 4 +- drivers/gpu/drm/msm/msm_gpu.c | 116 +--------------------- drivers/gpu/drm/msm/msm_gpu.h | 18 ++-- drivers/gpu/drm/msm/msm_gpu_devfreq.c | 133 ++++++++++++++++++++++++++ 5 files changed, 151 insertions(+), 121 deletions(-) create mode 100644 drivers/gpu/drm/msm/msm_gpu_devfreq.c diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 2c00aa70b708..904535eda0c4 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -90,6 +90,7 @@ msm-y := \ msm_gem_submit.o \ msm_gem_vma.o \ msm_gpu.o \ + msm_gpu_devfreq.o \ msm_iommu.o \ msm_perf.o \ msm_rd.o \ diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index a7df02298479..55ea136b8933 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1477,7 +1477,7 @@ static int a6xx_pm_resume(struct msm_gpu *gpu) if (ret) return ret; - msm_gpu_resume_devfreq(gpu); + msm_devfreq_resume(gpu); a6xx_llc_activate(a6xx_gpu); @@ -1494,7 +1494,7 @@ static int a6xx_pm_suspend(struct msm_gpu *gpu) a6xx_llc_deactivate(a6xx_gpu); - devfreq_suspend_device(gpu->devfreq.devfreq); + msm_devfreq_suspend(gpu); ret = a6xx_gmu_stop(a6xx_gpu); if (ret) diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index c4e202f0366c..70d8610b1b73 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -13,8 +13,6 @@ #include #include -#include -#include #include #include @@ -22,106 +20,6 @@ * Power Management: */ -static int msm_devfreq_target(struct device *dev, unsigned long *freq, - u32 flags) -{ - struct msm_gpu *gpu = dev_to_gpu(dev); - struct dev_pm_opp *opp; - - opp = devfreq_recommended_opp(dev, freq, flags); - - if (IS_ERR(opp)) - return PTR_ERR(opp); - - trace_msm_gpu_freq_change(dev_pm_opp_get_freq(opp)); - - if (gpu->funcs->gpu_set_freq) - gpu->funcs->gpu_set_freq(gpu, opp); - else - clk_set_rate(gpu->core_clk, *freq); - - dev_pm_opp_put(opp); - - return 0; -} - -static int msm_devfreq_get_dev_status(struct device *dev, - struct devfreq_dev_status *status) -{ - struct msm_gpu *gpu = dev_to_gpu(dev); - ktime_t time; - - if (gpu->funcs->gpu_get_freq) - status->current_frequency = gpu->funcs->gpu_get_freq(gpu); - else - status->current_frequency = clk_get_rate(gpu->core_clk); - - status->busy_time = gpu->funcs->gpu_busy(gpu); - - time = ktime_get(); - status->total_time = ktime_us_delta(time, gpu->devfreq.time); - gpu->devfreq.time = time; - - return 0; -} - -static int msm_devfreq_get_cur_freq(struct device *dev, unsigned long *freq) -{ - struct msm_gpu *gpu = dev_to_gpu(dev); - - if (gpu->funcs->gpu_get_freq) - *freq = gpu->funcs->gpu_get_freq(gpu); - else - *freq = clk_get_rate(gpu->core_clk); - - return 0; -} - -static struct devfreq_dev_profile msm_devfreq_profile = { - .polling_ms = 10, - .target = msm_devfreq_target, - .get_dev_status = msm_devfreq_get_dev_status, - .get_cur_freq = msm_devfreq_get_cur_freq, -}; - -static void msm_devfreq_init(struct msm_gpu *gpu) -{ - /* We need target support to do devfreq */ - if (!gpu->funcs->gpu_busy) - return; - - msm_devfreq_profile.initial_freq = gpu->fast_rate; - - /* - * Don't set the freq_table or max_state and let devfreq build the table - * from OPP - * After a deferred probe, these may have be left to non-zero values, - * so set them back to zero before creating the devfreq device - */ - msm_devfreq_profile.freq_table = NULL; - msm_devfreq_profile.max_state = 0; - - gpu->devfreq.devfreq = devm_devfreq_add_device(&gpu->pdev->dev, - &msm_devfreq_profile, DEVFREQ_GOV_SIMPLE_ONDEMAND, - NULL); - - if (IS_ERR(gpu->devfreq.devfreq)) { - DRM_DEV_ERROR(&gpu->pdev->dev, "Couldn't initialize GPU devfreq\n"); - gpu->devfreq.devfreq = NULL; - return; - } - - devfreq_suspend_device(gpu->devfreq.devfreq); - - gpu->cooling = of_devfreq_cooling_register(gpu->pdev->dev.of_node, - gpu->devfreq.devfreq); - if (IS_ERR(gpu->cooling)) { - DRM_DEV_ERROR(&gpu->pdev->dev, - "Couldn't register GPU cooling device\n"); - gpu->cooling = NULL; - } -} - static int enable_pwrrail(struct msm_gpu *gpu) { struct drm_device *dev = gpu->dev; @@ -196,14 +94,6 @@ static int disable_axi(struct msm_gpu *gpu) return 0; } -void msm_gpu_resume_devfreq(struct msm_gpu *gpu) -{ - gpu->devfreq.busy_cycles = 0; - gpu->devfreq.time = ktime_get(); - - devfreq_resume_device(gpu->devfreq.devfreq); -} - int msm_gpu_pm_resume(struct msm_gpu *gpu) { int ret; @@ -223,7 +113,7 @@ int msm_gpu_pm_resume(struct msm_gpu *gpu) if (ret) return ret; - msm_gpu_resume_devfreq(gpu); + msm_devfreq_resume(gpu); gpu->needs_hw_init = true; @@ -237,7 +127,7 @@ int msm_gpu_pm_suspend(struct msm_gpu *gpu) DBG("%s", gpu->name); trace_msm_gpu_suspend(0); - devfreq_suspend_device(gpu->devfreq.devfreq); + msm_devfreq_suspend(gpu); ret = disable_axi(gpu); if (ret) @@ -1082,5 +972,5 @@ void msm_gpu_cleanup(struct msm_gpu *gpu) kthread_destroy_worker(gpu->worker); } - devfreq_cooling_unregister(gpu->cooling); + msm_devfreq_cleanup(gpu); } diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 090cb89fa238..ada15e28f251 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -80,6 +80,12 @@ struct msm_gpu_fault_info { const char *block; }; +struct msm_gpu_devfreq { + struct devfreq *devfreq; + u64 busy_cycles; + ktime_t time; +}; + struct msm_gpu { const char *name; struct drm_device *dev; @@ -151,11 +157,7 @@ struct msm_gpu { struct drm_gem_object *memptrs_bo; - struct { - struct devfreq *devfreq; - u64 busy_cycles; - ktime_t time; - } devfreq; + struct msm_gpu_devfreq devfreq; uint32_t suspend_count; @@ -377,7 +379,11 @@ static inline void gpu_write64(struct msm_gpu *gpu, u32 lo, u32 hi, u64 val) int msm_gpu_pm_suspend(struct msm_gpu *gpu); int msm_gpu_pm_resume(struct msm_gpu *gpu); -void msm_gpu_resume_devfreq(struct msm_gpu *gpu); + +void msm_devfreq_init(struct msm_gpu *gpu); +void msm_devfreq_cleanup(struct msm_gpu *gpu); +void msm_devfreq_resume(struct msm_gpu *gpu); +void msm_devfreq_suspend(struct msm_gpu *gpu); int msm_gpu_hw_init(struct msm_gpu *gpu); diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c b/drivers/gpu/drm/msm/msm_gpu_devfreq.c new file mode 100644 index 000000000000..3bcea0baddab --- /dev/null +++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2013 Red Hat + * Author: Rob Clark + */ + +#include "msm_gpu.h" +#include "msm_gpu_trace.h" + +#include +#include + +/* + * Power Management: + */ + +static int msm_devfreq_target(struct device *dev, unsigned long *freq, + u32 flags) +{ + struct msm_gpu *gpu = dev_to_gpu(dev); + struct dev_pm_opp *opp; + + opp = devfreq_recommended_opp(dev, freq, flags); + + if (IS_ERR(opp)) + return PTR_ERR(opp); + + trace_msm_gpu_freq_change(dev_pm_opp_get_freq(opp)); + + if (gpu->funcs->gpu_set_freq) + gpu->funcs->gpu_set_freq(gpu, opp); + else + clk_set_rate(gpu->core_clk, *freq); + + dev_pm_opp_put(opp); + + return 0; +} + +static int msm_devfreq_get_dev_status(struct device *dev, + struct devfreq_dev_status *status) +{ + struct msm_gpu *gpu = dev_to_gpu(dev); + ktime_t time; + + if (gpu->funcs->gpu_get_freq) + status->current_frequency = gpu->funcs->gpu_get_freq(gpu); + else + status->current_frequency = clk_get_rate(gpu->core_clk); + + status->busy_time = gpu->funcs->gpu_busy(gpu); + + time = ktime_get(); + status->total_time = ktime_us_delta(time, gpu->devfreq.time); + gpu->devfreq.time = time; + + return 0; +} + +static int msm_devfreq_get_cur_freq(struct device *dev, unsigned long *freq) +{ + struct msm_gpu *gpu = dev_to_gpu(dev); + + if (gpu->funcs->gpu_get_freq) + *freq = gpu->funcs->gpu_get_freq(gpu); + else + *freq = clk_get_rate(gpu->core_clk); + + return 0; +} + +static struct devfreq_dev_profile msm_devfreq_profile = { + .polling_ms = 10, + .target = msm_devfreq_target, + .get_dev_status = msm_devfreq_get_dev_status, + .get_cur_freq = msm_devfreq_get_cur_freq, +}; + +void msm_devfreq_init(struct msm_gpu *gpu) +{ + /* We need target support to do devfreq */ + if (!gpu->funcs->gpu_busy) + return; + + msm_devfreq_profile.initial_freq = gpu->fast_rate; + + /* + * Don't set the freq_table or max_state and let devfreq build the table + * from OPP + * After a deferred probe, these may have be left to non-zero values, + * so set them back to zero before creating the devfreq device + */ + msm_devfreq_profile.freq_table = NULL; + msm_devfreq_profile.max_state = 0; + + gpu->devfreq.devfreq = devm_devfreq_add_device(&gpu->pdev->dev, + &msm_devfreq_profile, DEVFREQ_GOV_SIMPLE_ONDEMAND, + NULL); + + if (IS_ERR(gpu->devfreq.devfreq)) { + DRM_DEV_ERROR(&gpu->pdev->dev, "Couldn't initialize GPU devfreq\n"); + gpu->devfreq.devfreq = NULL; + return; + } + + devfreq_suspend_device(gpu->devfreq.devfreq); + + gpu->cooling = of_devfreq_cooling_register(gpu->pdev->dev.of_node, + gpu->devfreq.devfreq); + if (IS_ERR(gpu->cooling)) { + DRM_DEV_ERROR(&gpu->pdev->dev, + "Couldn't register GPU cooling device\n"); + gpu->cooling = NULL; + } +} + +void msm_devfreq_cleanup(struct msm_gpu *gpu) +{ + devfreq_cooling_unregister(gpu->cooling); +} + +void msm_devfreq_resume(struct msm_gpu *gpu) +{ + gpu->devfreq.busy_cycles = 0; + gpu->devfreq.time = ktime_get(); + + devfreq_resume_device(gpu->devfreq.devfreq); +} + +void msm_devfreq_suspend(struct msm_gpu *gpu) +{ + devfreq_suspend_device(gpu->devfreq.devfreq); +} From patchwork Thu Jul 22 22:21:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 483966 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C6ECFC4320E for ; Thu, 22 Jul 2021 22:17:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B06EA60EB0 for ; Thu, 22 Jul 2021 22:17:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232458AbhGVVhO (ORCPT ); Thu, 22 Jul 2021 17:37:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41156 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232426AbhGVVhL (ORCPT ); Thu, 22 Jul 2021 17:37:11 -0400 Received: from mail-pl1-x635.google.com (mail-pl1-x635.google.com [IPv6:2607:f8b0:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2D282C061575; Thu, 22 Jul 2021 15:17:45 -0700 (PDT) Received: by mail-pl1-x635.google.com with SMTP id e14so944409plh.8; Thu, 22 Jul 2021 15:17:45 -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 :mime-version:content-transfer-encoding; bh=8PbuIDLJSwDZoHRmQDtVVH8v7wrAjGN8POl6WAu5zOM=; b=SNpsbNBiLKHHFRQTP5JWRERPIA10ErY3XlI+V8RrayabzM9kXncvCEVClGWSAFG/rw 0H0ZMkV/xtYjWs1ylY6DkKGZBYFRGrF8JHkcLLL7RGBZTShJPxS7VAAkWKwLcrFEMd5E jfScfcf1jJHeCwad258NJOmFklVGTv8zpuSAib1gnfM7NuQfuABFMyh3chceJdSfHbr9 lu062tTXh9ntjt16QzfH7WKmcd/N906vaLnr/TyjsxMWzX2/QTkbHAxVa4fG4MYpYy6C nliAMGxLyWWlQ14OZegS32EZGdYvtv7wbinETTtYvupbfTaAE8zWqSkcmUcM4gsSRCvk cbAg== 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:mime-version:content-transfer-encoding; bh=8PbuIDLJSwDZoHRmQDtVVH8v7wrAjGN8POl6WAu5zOM=; b=juMUxaimFKI/Kq6Fx8Vc1cNc208P295G334eGrOHAOHJ751vgBcGpSmn0Gq3H8tTex 80m1RlKJ6X9e4F+8EQGdSbKx5FCksxtjOPIEpoKd5X/55OcNuu5mZpSQzg2NisGFLU7d SRD/Cs62cFcGX+9n36xYUue4PcAW/vVmyEdMlMU5PLm+7+GjD3Ni74FVtwj0ifeNY88C 4iznx7odqLKCLdL6mKHqbHg01RedJzUtEUXKJY0Ees/jyPZFHneheEvJLNZQ2quFwM2n lSEJfmzielslheEmiO8833LEPdP0cUnas6MxLWj35PZUpt9cmG0Nz/glwj4hpBpFYNPT /n1A== X-Gm-Message-State: AOAM533Iau+wvKXkhqL1j7Y+k1GiHIoK9ebi8rJ92u0bqxn6Vh9U1+pg VkregFsFhT7Ne8SflF6AYs0= X-Google-Smtp-Source: ABdhPJzDw2jN1R+e7X9KNvqHxtRZDBRDujIR0CDelIocfLSDYbR3ug0aI+S90A9NQH5xZzCaLv1hyg== X-Received: by 2002:a17:90a:7789:: with SMTP id v9mr1806135pjk.159.1626992264754; Thu, 22 Jul 2021 15:17:44 -0700 (PDT) Received: from localhost (c-73-25-156-94.hsd1.or.comcast.net. [73.25.156.94]) by smtp.gmail.com with ESMTPSA id m34sm35739282pgb.85.2021.07.22.15.17.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Jul 2021 15:17:44 -0700 (PDT) From: Rob Clark To: dri-devel@lists.freedesktop.org Cc: Rob Clark , Rob Clark , Sean Paul , David Airlie , Daniel Vetter , linux-arm-msm@vger.kernel.org (open list:DRM DRIVER FOR MSM ADRENO GPU), freedreno@lists.freedesktop.org (open list:DRM DRIVER FOR MSM ADRENO GPU), linux-kernel@vger.kernel.org (open list) Subject: [PATCH 2/3] drm/msm: Split out get_freq() helper Date: Thu, 22 Jul 2021 15:21:40 -0700 Message-Id: <20210722222145.1759900-3-robdclark@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210722222145.1759900-1-robdclark@gmail.com> References: <20210722222145.1759900-1-robdclark@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org From: Rob Clark In the next patch, it grows a bit more, so lets not duplicate the logic in multiple places. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gpu_devfreq.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c b/drivers/gpu/drm/msm/msm_gpu_devfreq.c index 3bcea0baddab..2e24a97be624 100644 --- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c +++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c @@ -37,17 +37,21 @@ static int msm_devfreq_target(struct device *dev, unsigned long *freq, return 0; } +static unsigned long get_freq(struct msm_gpu *gpu) +{ + if (gpu->funcs->gpu_get_freq) + return gpu->funcs->gpu_get_freq(gpu); + + return clk_get_rate(gpu->core_clk); +} + static int msm_devfreq_get_dev_status(struct device *dev, struct devfreq_dev_status *status) { struct msm_gpu *gpu = dev_to_gpu(dev); ktime_t time; - if (gpu->funcs->gpu_get_freq) - status->current_frequency = gpu->funcs->gpu_get_freq(gpu); - else - status->current_frequency = clk_get_rate(gpu->core_clk); - + status->current_frequency = get_freq(gpu); status->busy_time = gpu->funcs->gpu_busy(gpu); time = ktime_get(); @@ -59,12 +63,7 @@ static int msm_devfreq_get_dev_status(struct device *dev, static int msm_devfreq_get_cur_freq(struct device *dev, unsigned long *freq) { - struct msm_gpu *gpu = dev_to_gpu(dev); - - if (gpu->funcs->gpu_get_freq) - *freq = gpu->funcs->gpu_get_freq(gpu); - else - *freq = clk_get_rate(gpu->core_clk); + *freq = get_freq(dev_to_gpu(dev)); return 0; } From patchwork Thu Jul 22 22:21:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 484705 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 33477C432BE for ; Thu, 22 Jul 2021 22:17:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1B13E60EB2 for ; Thu, 22 Jul 2021 22:17:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232513AbhGVVhQ (ORCPT ); Thu, 22 Jul 2021 17:37:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41146 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232431AbhGVVhO (ORCPT ); Thu, 22 Jul 2021 17:37:14 -0400 Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 55CA9C061575; Thu, 22 Jul 2021 15:17:48 -0700 (PDT) Received: by mail-pj1-x102c.google.com with SMTP id ds11-20020a17090b08cbb0290172f971883bso6299092pjb.1; Thu, 22 Jul 2021 15:17:48 -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 :mime-version:content-transfer-encoding; bh=e+4yPSI4Sw52ZnxaUpGPC1NtBGa97BfMQZfa8dht1vc=; b=ebId3pQafrdJYrg5tLuaZQHdo1QsTXSkY+0KtXY1FpWofozX4wfj2bTQui7qcPtgUh Esg9UvUZcuUDC7DNrxQLgZJS5nqtjgx/CsFPe/klY+nG0eAw4KDAjsDAZXBbAg4Pu1Fb I8xZ+LbLu8Fju+P+yKf0+cTYd1QNtekC3Vbvg2yDNHshs0PAiN1Ii9LUNAse9rt+RIHr +z9X2TpxRKPBSo/TlC9s6jT917MWl150wkdEeAukH79ySaVz5cLtU54K8urEK2m/by1k faVAm3mOyRZ47hBUiUBLFByDHWJCjhCmCRjELzQy0UgMeoiuZ90tcEf8Jak1oFDxaArD WztA== 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:mime-version:content-transfer-encoding; bh=e+4yPSI4Sw52ZnxaUpGPC1NtBGa97BfMQZfa8dht1vc=; b=brjc7UQlDtt3LdyOMZPppjCvJcDgcWMWTVetQ92D/nCEeZ+EA+kPoTKu38VORiITu+ rIwRHjhyIROePeiELIZ0fJWzgCQMtNExp4bwca7vJPo4s/EuFcSBAK3cJQV3dBHj+3wr qWwcPhD9CcEFY0ABs1niXBIGETWt8o0MIcZ4Kc5bmVSSX6fPYG6CqD/8pjU/9QGT3Toj 102MA8b5rMrb1nh5Y9gGJqNoG1o8zADh/q5SLleM6f9h6QUAvpgeaiY0Qirr6EkeMdrE updwNRKLbl/bGI8oGORbzXJ6DwtAzv/J7Yykoxtx5jsspVhyBnrEuOrwjeeSmzOiODN1 lgPw== X-Gm-Message-State: AOAM531cUEiuZ+/62baBTgtsZuRt2EsIF8Y4Ngm1dWK3/TGlVsp0Y+xr AwNlGGRvlQlfx6DJtgXZIrk= X-Google-Smtp-Source: ABdhPJxQuPnhfr+lsj16reAJBxco2WCHD35phGKUb5+VmUZIahKiyZz6hFYSKJKG4OIKeePCz6RS7A== X-Received: by 2002:a62:1c14:0:b029:34a:70f5:40da with SMTP id c20-20020a621c140000b029034a70f540damr1799546pfc.37.1626992267863; Thu, 22 Jul 2021 15:17:47 -0700 (PDT) Received: from localhost (c-73-25-156-94.hsd1.or.comcast.net. [73.25.156.94]) by smtp.gmail.com with ESMTPSA id 85sm31841316pfz.76.2021.07.22.15.17.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Jul 2021 15:17:46 -0700 (PDT) From: Rob Clark To: dri-devel@lists.freedesktop.org Cc: Rob Clark , Rob Clark , Sean Paul , David Airlie , Daniel Vetter , linux-arm-msm@vger.kernel.org (open list:DRM DRIVER FOR MSM ADRENO GPU), freedreno@lists.freedesktop.org (open list:DRM DRIVER FOR MSM ADRENO GPU), linux-kernel@vger.kernel.org (open list) Subject: [PATCH 3/3] drm/msm: Devfreq tuning Date: Thu, 22 Jul 2021 15:21:41 -0700 Message-Id: <20210722222145.1759900-4-robdclark@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210722222145.1759900-1-robdclark@gmail.com> References: <20210722222145.1759900-1-robdclark@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org From: Rob Clark This adds a few things to try and make frequency scaling better match the workload: 1) Longer polling interval to avoid whip-lashing between too-high and too-low frequencies in certain workloads, like mobile games which throttle themselves to 30fps. Previously our polling interval was short enough to let things ramp down to minimum freq in the "off" frame, but long enough to not react quickly enough when rendering started on the next frame, leading to uneven frame times. (Ie. rather than a consistent 33ms it would alternate between 16/33/48ms.) 2) Awareness of when the GPU is active vs idle. Since we know when the GPU is active vs idle, we can clamp the frequency down to the minimum while it is idle. (If it is idle for long enough, then the autosuspend delay will eventually kick in and power down the GPU.) Since devfreq has no knowledge of powered-but-idle, this takes a small bit of trickery to maintain a "fake" frequency while idle. This, combined with the longer polling period allows devfreq to arrive at a reasonable "active" frequency, while still clamping to minimum freq when idle to reduce power draw. 3) Boost. Because simple_ondemand needs to see a certain threshold of busyness to ramp up, we could end up needing multiple polling cycles before it reacts appropriately on interactive workloads (ex. scrolling a web page after reading for some time), on top of the already lengthened polling interval, when we see a idle to active transition after a period of idle time we boost the frequency that we return to. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gpu.c | 8 +++ drivers/gpu/drm/msm/msm_gpu.h | 9 ++++ drivers/gpu/drm/msm/msm_gpu_devfreq.c | 73 ++++++++++++++++++++++++++- 3 files changed, 89 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 70d8610b1b73..68d2df590054 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -667,6 +667,10 @@ static void retire_submit(struct msm_gpu *gpu, struct msm_ringbuffer *ring, list_del(&submit->node); spin_unlock(&ring->submit_lock); + /* Update devfreq on transition from active->idle: */ + if (atomic_dec_return(&gpu->active_submits) == 0) + msm_devfreq_idle(gpu); + msm_gem_submit_put(submit); } @@ -747,6 +751,10 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) list_add_tail(&submit->node, &ring->submits); spin_unlock(&ring->submit_lock); + /* Update devfreq on transition from idle->active: */ + if (atomic_inc_return(&gpu->active_submits) == 1) + msm_devfreq_active(gpu); + gpu->funcs->submit(gpu, submit); priv->lastctx = submit->queue->ctx; diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index ada15e28f251..e14edda3d778 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -84,6 +84,10 @@ struct msm_gpu_devfreq { struct devfreq *devfreq; u64 busy_cycles; ktime_t time; + + /* Time and freq of last transition to idle: */ + ktime_t idle_time; + unsigned long idle_freq; }; struct msm_gpu { @@ -115,6 +119,9 @@ struct msm_gpu { */ struct list_head active_list; + /* number of in-flight submits: */ + atomic_t active_submits; + /* does gpu need hw_init? */ bool needs_hw_init; @@ -384,6 +391,8 @@ void msm_devfreq_init(struct msm_gpu *gpu); void msm_devfreq_cleanup(struct msm_gpu *gpu); void msm_devfreq_resume(struct msm_gpu *gpu); void msm_devfreq_suspend(struct msm_gpu *gpu); +void msm_devfreq_active(struct msm_gpu *gpu); +void msm_devfreq_idle(struct msm_gpu *gpu); int msm_gpu_hw_init(struct msm_gpu *gpu); diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c b/drivers/gpu/drm/msm/msm_gpu_devfreq.c index 2e24a97be624..0a1ee20296a2 100644 --- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c +++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c @@ -22,6 +22,15 @@ static int msm_devfreq_target(struct device *dev, unsigned long *freq, opp = devfreq_recommended_opp(dev, freq, flags); + /* + * If the GPU is idle, devfreq is not aware, so just ignore + * it's requests + */ + if (gpu->devfreq.idle_freq) { + gpu->devfreq.idle_freq = *freq; + return 0; + } + if (IS_ERR(opp)) return PTR_ERR(opp); @@ -39,6 +48,9 @@ static int msm_devfreq_target(struct device *dev, unsigned long *freq, static unsigned long get_freq(struct msm_gpu *gpu) { + if (gpu->devfreq.idle_freq) + return gpu->devfreq.idle_freq; + if (gpu->funcs->gpu_get_freq) return gpu->funcs->gpu_get_freq(gpu); @@ -69,7 +81,8 @@ static int msm_devfreq_get_cur_freq(struct device *dev, unsigned long *freq) } static struct devfreq_dev_profile msm_devfreq_profile = { - .polling_ms = 10, + .timer = DEVFREQ_TIMER_DELAYED, + .polling_ms = 50, .target = msm_devfreq_target, .get_dev_status = msm_devfreq_get_dev_status, .get_cur_freq = msm_devfreq_get_cur_freq, @@ -130,3 +143,61 @@ void msm_devfreq_suspend(struct msm_gpu *gpu) { devfreq_suspend_device(gpu->devfreq.devfreq); } + +void msm_devfreq_active(struct msm_gpu *gpu) +{ + struct msm_gpu_devfreq *df = &gpu->devfreq; + struct devfreq_dev_status status; + unsigned int idle_time; + unsigned long target_freq = df->idle_freq; + + /* + * Hold devfreq lock to synchronize with get_dev_status()/ + * target() callbacks + */ + mutex_lock(&df->devfreq->lock); + + idle_time = ktime_to_ms(ktime_sub(ktime_get(), df->idle_time)); + + /* + * If we've been idle for a significant fraction of a polling + * interval, then we won't meet the threshold of busyness for + * the governor to ramp up the freq.. so give some boost + */ + if (idle_time > msm_devfreq_profile.polling_ms/2) { + target_freq *= 2; + } + + df->idle_freq = 0; + + msm_devfreq_target(&gpu->pdev->dev, &target_freq, 0); + + /* + * Reset the polling interval so we aren't inconsistent + * about freq vs busy/total cycles + */ + msm_devfreq_get_dev_status(&gpu->pdev->dev, &status); + + mutex_unlock(&df->devfreq->lock); +} + +void msm_devfreq_idle(struct msm_gpu *gpu) +{ + struct msm_gpu_devfreq *df = &gpu->devfreq; + unsigned long idle_freq, target_freq = 0; + + /* + * Hold devfreq lock to synchronize with get_dev_status()/ + * target() callbacks + */ + mutex_lock(&df->devfreq->lock); + + idle_freq = get_freq(gpu); + + msm_devfreq_target(&gpu->pdev->dev, &target_freq, 0); + + df->idle_time = ktime_get(); + df->idle_freq = idle_freq; + + mutex_unlock(&df->devfreq->lock); +}