From patchwork Tue Aug 31 13:54:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 505408 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.8 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,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 BA755C4320A for ; Tue, 31 Aug 2021 13:57:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A37546103D for ; Tue, 31 Aug 2021 13:57:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232153AbhHaN55 (ORCPT ); Tue, 31 Aug 2021 09:57:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58174 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229668AbhHaN5z (ORCPT ); Tue, 31 Aug 2021 09:57:55 -0400 Received: from mail-lf1-x12c.google.com (mail-lf1-x12c.google.com [IPv6:2a00:1450:4864:20::12c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 42245C0613D9; Tue, 31 Aug 2021 06:57:00 -0700 (PDT) Received: by mail-lf1-x12c.google.com with SMTP id bq28so38703419lfb.7; Tue, 31 Aug 2021 06:57:00 -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=kl0Y7hWnImbF0EBJlhQD+X5wimgI5lPFl9LYh/wR6RI=; b=jtMZgopVU3iUlt7/gbnIjj8Xg95dxw2fXMZuUFG/y18xFl0072FeWtOMsE0ErQV96A p7qbizqpKh4JIrCB5TsTOBmkgSA9Irn/CcLM8srykauJM/sNZ4RlymgQ15BKi4osg+oq 0wLMUHs8z6zXPyaULDENsLRrMDQGD7LMcyPM4uJJCOeSjPxWS4GUfa6ItyXnBoKmzp8Q cWMi4UfaSdBT6Hb59DIV8VYjOhfc7gscgFG0BZGJpOsKW44VbGSdozz+cXAduMv3FK9h 9Bg3ath8Bng8ya9GtvP0o1xr6+tiaziQVztV6KmD8SdbTo6PitryshmGXZpPrB3nvdRR iJ0w== 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=kl0Y7hWnImbF0EBJlhQD+X5wimgI5lPFl9LYh/wR6RI=; b=ayYqpGsno6z7LyA4pCdZknJlmoUn8eqH7lz4WmtxPRD0SH29bqMhE6vmjOrjdCOGLt zXpQsIClULYx1q4IwAAuftxY7R9CTYyQ8oGrHA4TFZ3Yk2h35DaK2dahlZf1grW5fprW KbgrFM86fVvnbaNfMNLzHrEJgOf4iW3NaPQhe+92bvINFmXiWOj9IGL/OaxPxtRU2x6W 0SVXBUwQVczI0dyP/f5R8yHyEipXOB2zM2weI6cr7szRo1mUZ/WCpYba/owkrgERZz6/ SZVKA3zCiHUeTY0eAIYkcxGTHBVgYknCL8r8qczhwkVBwesipMgXTDobdG1gJS84gGBj vdGg== X-Gm-Message-State: AOAM5300+fWOi1zDb7hY3Lsn6BhF2Pu1zCUOvQTAiEB8Oy/l9pWthyqK Z1h5AkxvgNXVbARMYkTLTP4= X-Google-Smtp-Source: ABdhPJwdicbVV/JUyy7fJmDZVKPtcggwkAXPQjWC9eGJOcSkCifYWZoDyK0Yrv9lOBxSQBg8lK/k2w== X-Received: by 2002:a05:6512:ad3:: with SMTP id n19mr1674841lfu.297.1630418218675; Tue, 31 Aug 2021 06:56:58 -0700 (PDT) Received: from localhost.localdomain (46-138-26-37.dynamic.spd-mgts.ru. [46.138.26.37]) by smtp.gmail.com with ESMTPSA id x4sm2203622ljm.98.2021.08.31.06.56.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 31 Aug 2021 06:56:58 -0700 (PDT) From: Dmitry Osipenko To: Thierry Reding , Jonathan Hunter , Ulf Hansson , "Rafael J. Wysocki" , Kevin Hilman , Viresh Kumar , Stephen Boyd , Nishanth Menon Cc: linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-pm@vger.kernel.org Subject: [PATCH v10 1/8] opp: Add dev_pm_opp_get_current() Date: Tue, 31 Aug 2021 16:54:43 +0300 Message-Id: <20210831135450.26070-2-digetx@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210831135450.26070-1-digetx@gmail.com> References: <20210831135450.26070-1-digetx@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Add dev_pm_opp_get_current() helper that returns OPP corresponding to the current clock rate of a device. Signed-off-by: Dmitry Osipenko --- drivers/opp/core.c | 43 +++++++++++++++++++++++++++++++++++++++--- include/linux/pm_opp.h | 6 ++++++ 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 04b4691a8aac..dde8a5cc948c 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -939,7 +939,7 @@ static int _set_required_opps(struct device *dev, return ret; } -static void _find_current_opp(struct device *dev, struct opp_table *opp_table) +static struct dev_pm_opp *_find_current_opp(struct opp_table *opp_table) { struct dev_pm_opp *opp = ERR_PTR(-ENODEV); unsigned long freq; @@ -949,6 +949,18 @@ static void _find_current_opp(struct device *dev, struct opp_table *opp_table) opp = _find_freq_ceil(opp_table, &freq); } + return opp; +} + +static void _find_and_set_current_opp(struct opp_table *opp_table) +{ + struct dev_pm_opp *opp; + + if (opp_table->current_opp) + return; + + opp = _find_current_opp(opp_table); + /* * Unable to find the current OPP ? Pick the first from the list since * it is in ascending order, otherwise rest of the code will need to @@ -1002,8 +1014,7 @@ static int _set_opp(struct device *dev, struct opp_table *opp_table, return _disable_opp_table(dev, opp_table); /* Find the currently set OPP if we don't know already */ - if (unlikely(!opp_table->current_opp)) - _find_current_opp(dev, opp_table); + _find_and_set_current_opp(opp_table); old_opp = opp_table->current_opp; @@ -2931,3 +2942,29 @@ int dev_pm_opp_sync_regulators(struct device *dev) return ret; } EXPORT_SYMBOL_GPL(dev_pm_opp_sync_regulators); + +/** + * dev_pm_opp_get_current() - Get current OPP + * @dev: device for which we do this operation + * + * Get current OPP of a device based on current clock rate or by other means. + * + * Return: pointer to 'struct dev_pm_opp' on success and errorno otherwise. + */ +struct dev_pm_opp *dev_pm_opp_get_current(struct device *dev) +{ + struct opp_table *opp_table; + struct dev_pm_opp *opp; + + opp_table = _find_opp_table(dev); + if (IS_ERR(opp_table)) + return ERR_CAST(opp_table); + + opp = _find_current_opp(opp_table); + + /* Drop reference taken by _find_opp_table() */ + dev_pm_opp_put_opp_table(opp_table); + + return opp; +} +EXPORT_SYMBOL_GPL(dev_pm_opp_get_current); diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index 84150a22fd7c..c8091977efb8 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -168,6 +168,7 @@ int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask) void dev_pm_opp_remove_table(struct device *dev); void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask); int dev_pm_opp_sync_regulators(struct device *dev); +struct dev_pm_opp *dev_pm_opp_get_current(struct device *dev); #else static inline struct opp_table *dev_pm_opp_get_opp_table(struct device *dev) { @@ -434,6 +435,11 @@ static inline int dev_pm_opp_sync_regulators(struct device *dev) return -EOPNOTSUPP; } +static inline struct dev_pm_opp *dev_pm_opp_get_current(struct device *dev) +{ + return ERR_PTR(-EOPNOTSUPP); +} + #endif /* CONFIG_PM_OPP */ #if defined(CONFIG_PM_OPP) && defined(CONFIG_OF) From patchwork Tue Aug 31 13:54:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 504843 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.8 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,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 25F2FC19F38 for ; Tue, 31 Aug 2021 13:57:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F3EB561056 for ; Tue, 31 Aug 2021 13:57:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231634AbhHaN55 (ORCPT ); Tue, 31 Aug 2021 09:57:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58178 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232400AbhHaN54 (ORCPT ); Tue, 31 Aug 2021 09:57:56 -0400 Received: from mail-lj1-x229.google.com (mail-lj1-x229.google.com [IPv6:2a00:1450:4864:20::229]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EAE59C061575; Tue, 31 Aug 2021 06:57:00 -0700 (PDT) Received: by mail-lj1-x229.google.com with SMTP id g14so3788389ljk.5; Tue, 31 Aug 2021 06:57:00 -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=b0/cqGavEHwgsYtk4vTJO+BDi1z8O7toXfeYU/faT8s=; b=fhwxuRbSDKX/TZ2i6TzSrxfeiG763DDq9XWavBnavi1jgPfM7KavrpOghI7hIPNTiL ZDzwm6WBycm5e4C4tltQ3ofeWPSMqphDZkTKHxkRSV8xmsdaU6a8nxbR4Q8ZwYA4Xj6L CREmgJ4ERebr3FOduMDSNkl5vjvTJjL/KScW2KeqkjAo7g7YIoep3Ew5cq9WfQm3zi0n xCjdHrXU3sEzQM8J9UbcTsfGztvi31HE/pC0sqkHZyKhCYc5XrybVCGWysQZihUst7TW KoH3A95F4IZrQrazVIzNBRuix99RbIKOMtjOpao0OLPsygMyI0H9eP/5w7YfO+/fBBbd lzHw== 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=b0/cqGavEHwgsYtk4vTJO+BDi1z8O7toXfeYU/faT8s=; b=MiSJzC4nX3OxHL7e5JbBnClUpctwczOEjnVrSYRi+tb17OwZtNi4NVLd2lWlZbdiab Deo3b5uEbyFC/D4D7zWgDnjbOMu2YdRKx2sQj8XIcwmo3IcwSFp6oW+WZm1T9m+ysbxR sgH4vpY2Sm/iHotnjexQUciZDRxu8qU1auDNG2paJWIkGPSHgXXVIJrM/UqvB9dt3b44 8DzvvNVpmFdvR7nj0g9njvGuoUTYx58GPLDGSYekLx5cCwJpv0R9YNdzf1IwANh5noNh uPuyXzoUQ925S64mLG2vO7Qd7HBOkkFzEI8f0Ll584rSynQF8XzA0nqUlSCAr0gVOLLY Soow== X-Gm-Message-State: AOAM5331hTddZ7fHaKmxag+ySLKGrciIo3XhAw8dA65QRhqFBQx7mNtF VSvgGKUK2FctUuUXuC/O8Gc= X-Google-Smtp-Source: ABdhPJymsO0TUupAbW3s5AjqlceExa694368OtSMKsTx+2Ovkae7LbJU2Gn+zzlQcybuJZV6cdMvmw== X-Received: by 2002:a2e:8881:: with SMTP id k1mr25360627lji.443.1630418219389; Tue, 31 Aug 2021 06:56:59 -0700 (PDT) Received: from localhost.localdomain (46-138-26-37.dynamic.spd-mgts.ru. [46.138.26.37]) by smtp.gmail.com with ESMTPSA id x4sm2203622ljm.98.2021.08.31.06.56.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 31 Aug 2021 06:56:59 -0700 (PDT) From: Dmitry Osipenko To: Thierry Reding , Jonathan Hunter , Ulf Hansson , "Rafael J. Wysocki" , Kevin Hilman , Viresh Kumar , Stephen Boyd , Nishanth Menon Cc: linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-pm@vger.kernel.org Subject: [PATCH v10 2/8] opp: Allow dev_pm_opp_set_clkname() to replace released clock Date: Tue, 31 Aug 2021 16:54:44 +0300 Message-Id: <20210831135450.26070-3-digetx@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210831135450.26070-1-digetx@gmail.com> References: <20210831135450.26070-1-digetx@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The opp_table->clk is set to error once clock is released by dev_pm_opp_put_clkname(). This doesn't allow to set clock again, until OPP table is re-created from scratch. Check opp_table->clk for both NULL and ERR_PTR to allow the clock's replacement. Signed-off-by: Dmitry Osipenko --- drivers/opp/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index dde8a5cc948c..602e502d092e 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -2146,7 +2146,7 @@ struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char *name) } /* clk shouldn't be initialized at this point */ - if (WARN_ON(opp_table->clk)) { + if (WARN_ON(!IS_ERR_OR_NULL(opp_table->clk))) { ret = -EBUSY; goto err; } From patchwork Tue Aug 31 13:54:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 505407 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.8 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,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 0A9FBC432BE for ; Tue, 31 Aug 2021 13:57:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E5DA561027 for ; Tue, 31 Aug 2021 13:57:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232617AbhHaN57 (ORCPT ); Tue, 31 Aug 2021 09:57:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58184 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230406AbhHaN55 (ORCPT ); Tue, 31 Aug 2021 09:57:57 -0400 Received: from mail-lf1-x136.google.com (mail-lf1-x136.google.com [IPv6:2a00:1450:4864:20::136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CBAA7C0613D9; Tue, 31 Aug 2021 06:57:01 -0700 (PDT) Received: by mail-lf1-x136.google.com with SMTP id g13so38678241lfj.12; Tue, 31 Aug 2021 06:57:01 -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=Hgtc73wlzCPnDSrqZMFKdeSGLWZ/vHH3cfFR111Xa/s=; b=irnCEBugj9h5KB1fYkP9OvMOkrJp63BMzspkE3SIn6OkBb9KaSEzQAbQ0BAYE73ciH pHUAfquaR4slUFDj6gB0OqxIxsm9XSqPy49d+bdol3VK8435+ffiV+GM5ZL+fkYjPrmW mBb53w4VxpN9zV31qYYnzILN3oTaIAA1FqO6IaRD10aYLkVRevjGL6uxrt6hw+f012bL xwyYx1l9j7OkKoA1Or4G6TJTuli+FEtW7GO9PfOEernLjVayZO26JxQcjTXTABGSJA4H oJPlWFzvsnasQu7cUKNSxA70jV7o+MaVY0uzOBTrT7UUQm4a1xG1m2/VHDwfjBFQXa6z XJkg== 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=Hgtc73wlzCPnDSrqZMFKdeSGLWZ/vHH3cfFR111Xa/s=; b=VJLmzNYgjb3WeHvjTizw39vN3fRM6BETs1ZRhYZS3P+zAY1C3Rz+9+tjwWBGq5r2JF XafjpR8rGHpR36QoZu50lrkOi6q1aWRPhp4oJ9rOMh/Kvmhw0CMQhv0M+8KcaSUKkpki qBpP1ebZeQB2hweXTgmijrWBZuzxsH6EU0z6M9qtXiDB5WzvRiKBnJZu8xDV4332ncA+ LMi0KW8QGioFq53mIPBR9r0HV+lTnj0TBVxrjlUrxMN8MeIpRkn1vKN2fvOervn4Bl65 GticKGMEM8VgVFFgfUbgxgTbFHXyFkSnHfuHte/vF9RFNCEw1fflSwcEou7tA377b5/C TogQ== X-Gm-Message-State: AOAM533S4Ki8Qtq4CvQ0PdkGE97VdLwdBB+o2hi9iUEk31h1Sf51Jz4e TC6GbKjtjSMyjoG8IWlYajQ= X-Google-Smtp-Source: ABdhPJwBxEAKZykniE6gECVoOUXIP0Uxwd71uV46hgknj7vXpR/Ih5V3Mns3w7BORSlEuE5R8NVqrw== X-Received: by 2002:a19:4955:: with SMTP id l21mr22326210lfj.5.1630418220155; Tue, 31 Aug 2021 06:57:00 -0700 (PDT) Received: from localhost.localdomain (46-138-26-37.dynamic.spd-mgts.ru. [46.138.26.37]) by smtp.gmail.com with ESMTPSA id x4sm2203622ljm.98.2021.08.31.06.56.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 31 Aug 2021 06:56:59 -0700 (PDT) From: Dmitry Osipenko To: Thierry Reding , Jonathan Hunter , Ulf Hansson , "Rafael J. Wysocki" , Kevin Hilman , Viresh Kumar , Stephen Boyd , Nishanth Menon Cc: linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-pm@vger.kernel.org Subject: [PATCH v10 3/8] opp: Change type of dev_pm_opp_attach_genpd(names) argument Date: Tue, 31 Aug 2021 16:54:45 +0300 Message-Id: <20210831135450.26070-4-digetx@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210831135450.26070-1-digetx@gmail.com> References: <20210831135450.26070-1-digetx@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Elements of the 'names' array are not changed by the code, constify them for consistency. Signed-off-by: Dmitry Osipenko --- drivers/opp/core.c | 6 +++--- include/linux/pm_opp.h | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 602e502d092e..d4e706a8b70d 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -2359,12 +2359,12 @@ static void _opp_detach_genpd(struct opp_table *opp_table) * "required-opps" are added in DT. */ struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, - const char **names, struct device ***virt_devs) + const char * const *names, struct device ***virt_devs) { struct opp_table *opp_table; struct device *virt_dev; int index = 0, ret = -EINVAL; - const char **name = names; + const char * const *name = names; opp_table = _add_opp_table(dev, false); if (IS_ERR(opp_table)) @@ -2468,7 +2468,7 @@ static void devm_pm_opp_detach_genpd(void *data) * * Return: 0 on success and errorno otherwise. */ -int devm_pm_opp_attach_genpd(struct device *dev, const char **names, +int devm_pm_opp_attach_genpd(struct device *dev, const char * const *names, struct device ***virt_devs) { struct opp_table *opp_table; diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index c8091977efb8..37d5d71e0835 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -156,9 +156,9 @@ int devm_pm_opp_set_clkname(struct device *dev, const char *name); struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)(struct dev_pm_set_opp_data *data)); void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table); int devm_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)(struct dev_pm_set_opp_data *data)); -struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char **names, struct device ***virt_devs); +struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char * const *names, struct device ***virt_devs); void dev_pm_opp_detach_genpd(struct opp_table *opp_table); -int devm_pm_opp_attach_genpd(struct device *dev, const char **names, struct device ***virt_devs); +int devm_pm_opp_attach_genpd(struct device *dev, const char * const *names, struct device ***virt_devs); struct dev_pm_opp *dev_pm_opp_xlate_required_opp(struct opp_table *src_table, struct opp_table *dst_table, struct dev_pm_opp *src_opp); int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate); int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq); @@ -377,7 +377,7 @@ static inline int devm_pm_opp_set_clkname(struct device *dev, const char *name) return -EOPNOTSUPP; } -static inline struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char **names, struct device ***virt_devs) +static inline struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char * const *names, struct device ***virt_devs) { return ERR_PTR(-EOPNOTSUPP); } @@ -385,7 +385,7 @@ static inline struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, cons static inline void dev_pm_opp_detach_genpd(struct opp_table *opp_table) {} static inline int devm_pm_opp_attach_genpd(struct device *dev, - const char **names, + const char * const *names, struct device ***virt_devs) { return -EOPNOTSUPP; From patchwork Tue Aug 31 13:54:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 504842 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.8 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, USER_AGENT_GIT autolearn=ham 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 1F274C43214 for ; Tue, 31 Aug 2021 13:57:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0513C60241 for ; Tue, 31 Aug 2021 13:57:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233345AbhHaN6A (ORCPT ); Tue, 31 Aug 2021 09:58:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58190 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232438AbhHaN56 (ORCPT ); Tue, 31 Aug 2021 09:57:58 -0400 Received: from mail-lf1-x132.google.com (mail-lf1-x132.google.com [IPv6:2a00:1450:4864:20::132]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 92860C061575; Tue, 31 Aug 2021 06:57:02 -0700 (PDT) Received: by mail-lf1-x132.google.com with SMTP id bq28so38703686lfb.7; Tue, 31 Aug 2021 06:57:02 -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=M8U7E16VGX8CxKkJRXCHT93F41HSxSE0YgI66q/OlMI=; b=jfP90AL86PGMD5r1wct+KNrS0wk4s/vxOz/gFD1rlQz6X4QVQ67JsPeYYLQ5KncpKu 4VhFKk9yhGadsKkFnCK8EiDb65DEt9DotWqwW/PdY0t/KJdpYRawWj4HVZAHy8A58IjZ MuVkEX2aLxpkz9goRJ31cdlyh4+6dG/IHJikT3c76Ylsr4GP8WVMtwXobzrwqbX6uVP6 yc/vR5jnmMshbp29vXPvmjBZwwHn+tSjMtENT9lWzHS6rSe5euFvdMQP9MFngHHm7cER /sHuWBTMgYHOWURSrpg15xqNmq2rKmTnEDZydu/FbzLrz6wdu74c1r4mSmql0zmEQNqd 8exA== 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=M8U7E16VGX8CxKkJRXCHT93F41HSxSE0YgI66q/OlMI=; b=LytY4quNE6DBuBxRNmt8FFv+O3NNyWliIpZ1jbHH7FDXXHAQzr6LDvfCZDCKj/3GzN xtdUbuXpYLiyYMk7nW6UshfqSkdbmPvAWfXg3IkribG4zxOstlKEb0qSEZkEYdBKKPsw S/VpugnrClfNAobPwoCxKRLCqgbCgRLn/wGjjuwFjjFpE83WQ92rJJdhiX8QIQu7VEGK lUUhltwbg6X4sRm+Lx+0CLUmP5P1tVcx51UW1py5ClY7D9+3Mp5MbK6TxyzE+YqWZZDg YZLks9LHRRNJDFEWRe86v2CAeRUP6cWz5rq8fJiprdWtn8u0lLvmlAE09dOLlBSTZ0Co 3xsw== X-Gm-Message-State: AOAM531qYwU3HNuBXZzW8mZPBEWIpTVhLDwU76z0uDdky5eLFokpJKdS LUR7VrWAWJ00ODI+Funh3y4= X-Google-Smtp-Source: ABdhPJyAIg2ZdcBcD2CNj1TGt7NfKafvr1Os4cITSLpy4xasOOF/6eyPlw16ekZJg5RjiiYB3YeVaQ== X-Received: by 2002:a05:6512:2602:: with SMTP id bt2mr21109410lfb.47.1630418220975; Tue, 31 Aug 2021 06:57:00 -0700 (PDT) Received: from localhost.localdomain (46-138-26-37.dynamic.spd-mgts.ru. [46.138.26.37]) by smtp.gmail.com with ESMTPSA id x4sm2203622ljm.98.2021.08.31.06.57.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 31 Aug 2021 06:57:00 -0700 (PDT) From: Dmitry Osipenko To: Thierry Reding , Jonathan Hunter , Ulf Hansson , "Rafael J. Wysocki" , Kevin Hilman , Viresh Kumar , Stephen Boyd , Nishanth Menon Cc: linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-pm@vger.kernel.org Subject: [PATCH v10 4/8] PM: domains: Add dev_get_performance_state() callback Date: Tue, 31 Aug 2021 16:54:46 +0300 Message-Id: <20210831135450.26070-5-digetx@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210831135450.26070-1-digetx@gmail.com> References: <20210831135450.26070-1-digetx@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Add optional dev_get_performance_state() callback that retrieves performance state of a device attached to a power domain. The new callback returns performance states of the given device, which should be read out from hardware. GENPD core assumes that initially performance state of all devices is zero and consumer device driver is responsible for management of the performance state. GENPD core now manages performance state across RPM suspend/resume of consumer devices by dropping and restoring the state, this allowed to move a part of performance management code into GENPD core out of consumer drivers. The part that hasn't been moved to GENPD core yet is the initialization of the performance state. Hardware may be preprogrammed to a specific performance state which isn't zero initially, hence the PD's performance state is inconsistent with hardware at the init time. This requires each consumer driver to explicitly sync the state. For some platforms this is a boilerplate code replicated by each driver. The new callback allows GENPD core to initialize the performance state, allowing to remove the remaining boilerplate code from consumer drivers. Now, when consumer device is resumed for the first time, the performance state is either already set by GENPD core or it will be set in accordance to the hardware state that was retrieved using the new callback when device was attached to a power domain. Still, consumer drivers are free to override the initial performance state configured by GENPD, if necessary. Signed-off-by: Dmitry Osipenko --- drivers/base/power/domain.c | 90 +++++++++++++++++++++++++++++++------ include/linux/pm_domain.h | 2 + 2 files changed, 79 insertions(+), 13 deletions(-) diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 5db704f02e71..598528abce01 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -2644,12 +2644,85 @@ static void genpd_dev_pm_sync(struct device *dev) genpd_queue_power_off_work(pd); } +static int genpd_dev_get_current_performance_state(struct device *dev, + struct device *base_dev, + unsigned int index, + bool *state_default, + bool *suspended) +{ + struct generic_pm_domain *pd = dev_to_genpd(dev); + int ret; + + ret = of_get_required_opp_performance_state(dev->of_node, index); + if (ret < 0 && ret != -ENODEV && ret != -EOPNOTSUPP) { + dev_err(dev, "failed to get required performance state for power-domain %s: %d\n", + pd->name, ret); + + return ret; + } else if (ret >= 0) { + *state_default = true; + + return ret; + } + + if (pd->dev_get_performance_state) { + ret = pd->dev_get_performance_state(pd, base_dev); + if (ret >= 0) + *suspended = pm_runtime_status_suspended(base_dev); + else + dev_err(dev, "failed to get performance state of %s for power-domain %s: %d\n", + dev_name(base_dev), pd->name, ret); + + return ret; + } + + return 0; +} + +static int genpd_dev_initialize_performance_state(struct device *dev, + struct device *base_dev, + unsigned int index) +{ + struct generic_pm_domain *pd = dev_to_genpd(dev); + bool state_default = false, suspended = false; + int pstate, err; + + pstate = genpd_dev_get_current_performance_state(dev, base_dev, index, + &state_default, + &suspended); + if (pstate <= 0) + return pstate; + + /* + * If device is suspended, then performance state will be applied + * on RPM-resume. This prevents potential extra power consumption + * if device won't be resumed soon. + * + * If device is known to be active at the moment, then the performance + * state should be updated immediately to sync state with hardware. + */ + if (suspended) { + dev_gpd_data(dev)->rpm_pstate = pstate; + } else { + err = dev_pm_genpd_set_performance_state(dev, pstate); + if (err) { + dev_err(dev, "failed to set performance state for power-domain %s: %d\n", + pd->name, err); + return err; + } + + if (state_default) + dev_gpd_data(dev)->default_pstate = pstate; + } + + return 0; +} + static int __genpd_dev_pm_attach(struct device *dev, struct device *base_dev, unsigned int index, bool power_on) { struct of_phandle_args pd_args; struct generic_pm_domain *pd; - int pstate; int ret; ret = of_parse_phandle_with_args(dev->of_node, "power-domains", @@ -2693,22 +2766,13 @@ static int __genpd_dev_pm_attach(struct device *dev, struct device *base_dev, return -EPROBE_DEFER; } - /* Set the default performance state */ - pstate = of_get_required_opp_performance_state(dev->of_node, index); - if (pstate < 0 && pstate != -ENODEV && pstate != -EOPNOTSUPP) { - ret = pstate; + ret = genpd_dev_initialize_performance_state(dev, base_dev, index); + if (ret) goto err; - } else if (pstate > 0) { - ret = dev_pm_genpd_set_performance_state(dev, pstate); - if (ret) - goto err; - dev_gpd_data(dev)->default_pstate = pstate; - } + return 1; err: - dev_err(dev, "failed to set required performance state for power-domain %s: %d\n", - pd->name, ret); genpd_remove_device(pd, dev); return ret; } diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 67017c9390c8..0a4dd4986f34 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -133,6 +133,8 @@ struct generic_pm_domain { struct dev_pm_opp *opp); int (*set_performance_state)(struct generic_pm_domain *genpd, unsigned int state); + int (*dev_get_performance_state)(struct generic_pm_domain *genpd, + struct device *dev); struct gpd_dev_ops dev_ops; s64 max_off_time_ns; /* Maximum allowed "suspended" time. */ ktime_t next_wakeup; /* Maintained by the domain governor */ From patchwork Tue Aug 31 13:54:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 505406 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.8 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,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 13760C04FE3 for ; Tue, 31 Aug 2021 13:57:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EDB6D6102A for ; Tue, 31 Aug 2021 13:57:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232870AbhHaN6C (ORCPT ); Tue, 31 Aug 2021 09:58:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58196 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231927AbhHaN56 (ORCPT ); Tue, 31 Aug 2021 09:57:58 -0400 Received: from mail-lj1-x230.google.com (mail-lj1-x230.google.com [IPv6:2a00:1450:4864:20::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 530ADC061760; Tue, 31 Aug 2021 06:57:03 -0700 (PDT) Received: by mail-lj1-x230.google.com with SMTP id s3so31957133ljp.11; Tue, 31 Aug 2021 06:57:03 -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=vxZLlezmdlBfmORUY8VTkoehAmXrLhditoSKpgYm74c=; b=OZPnxXBlgfpSfDwpyOGpPsulhCcuNiZlp1iz33kdT3xK7b7zcbBtyMPlh24brwFYqq RVPU8xGYktiVAHJpeSaMRpnNB6uqFsgvu9uV30h2oJvHQxj99JNL5w1T8aDTEd410jNh k1OoezMZTytNJqfPG8hUW4I1w0gCZWfn8jp9DsX7thlnyCShKVQjjXguWLGOl1PKZMaN g7lPtiEXzFXmZMa8uh8VfBTSepIzcO5g855XacQFJFHZ3tdjIeTO1gbBvYk0xKBNvt2q NZSABJ+G/Wm083zu/2w9bLEaayacvkN/+04KQFvTGdPf77c/mkRqIPr8Nvx30NrD3wkE NgGw== 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=vxZLlezmdlBfmORUY8VTkoehAmXrLhditoSKpgYm74c=; b=AI03kaALkM+BMKZN7/f3OBEtY7/YqwN8z8FeqoaDarQkThDOxLgTnRyt0nT7PjmGMf mJLlMQTHJK1XiHjSpG3KlvUbrH4J3M5bHbY6+L0Zb5KqJ5OH0f2Pj9iSJqfm3IpraAGO 1FTv9ju/9pEEwEPm5TP/Q5avWo+Vu6Y8xxcjiN3/psbBqapsgo2V8+DTtDdQJDx/BtGE /qA6MuWNVqG3RGLnqsZ0wdy7M8uHxz6pYWJkgGrRa1D21laFW55JEoab1mWT6ZBUNzOc T5RaspEt1CWX8vKsKLKArdSGiZ9nEDNBS80LOVIti7C1DUKa1/m6KsE6kMiz/M6wdXtQ bkkA== X-Gm-Message-State: AOAM531Dd4hyP3ihSmtGtGqjYw84VXjeDmIXRmvCozTAtJWBcoq5MoP3 8dQQuNFn/0uIUxD4OkVJo/U= X-Google-Smtp-Source: ABdhPJxvLGSM2G1hi+P/eh8bjV7Otd9EPzCwKJnTc/HtDoTKHWQ5+JHmhCz1QWrHHodLfgqdqAuYhQ== X-Received: by 2002:a05:651c:50e:: with SMTP id o14mr26038356ljp.351.1630418221715; Tue, 31 Aug 2021 06:57:01 -0700 (PDT) Received: from localhost.localdomain (46-138-26-37.dynamic.spd-mgts.ru. [46.138.26.37]) by smtp.gmail.com with ESMTPSA id x4sm2203622ljm.98.2021.08.31.06.57.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 31 Aug 2021 06:57:01 -0700 (PDT) From: Dmitry Osipenko To: Thierry Reding , Jonathan Hunter , Ulf Hansson , "Rafael J. Wysocki" , Kevin Hilman , Viresh Kumar , Stephen Boyd , Nishanth Menon Cc: linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-pm@vger.kernel.org Subject: [PATCH v10 5/8] soc/tegra: pmc: Implement dev_get_performance_state() callback Date: Tue, 31 Aug 2021 16:54:47 +0300 Message-Id: <20210831135450.26070-6-digetx@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210831135450.26070-1-digetx@gmail.com> References: <20210831135450.26070-1-digetx@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Implement dev_get_performance_state() callback of the power domains to pre-initialize theirs performance (voltage) state in accordance to the clock rate of attached devices. Signed-off-by: Dmitry Osipenko --- drivers/soc/tegra/pmc.c | 101 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 50091c4ec948..98015a6cdd1d 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -505,6 +506,104 @@ static void tegra_pmc_scratch_writel(struct tegra_pmc *pmc, u32 value, writel(value, pmc->scratch + offset); } +static const char * const tegra_pd_no_perf_compats[] = { + "nvidia,tegra20-sclk", + "nvidia,tegra30-sclk", + "nvidia,tegra30-pllc", + "nvidia,tegra30-plle", + "nvidia,tegra30-pllm", + "nvidia,tegra20-dc", + "nvidia,tegra30-dc", + "nvidia,tegra20-emc", + "nvidia,tegra30-emc", + NULL, +}; + +static int +tegra_pmc_pd_dev_get_performance_state(struct generic_pm_domain *genpd, + struct device *dev) +{ + struct opp_table *hw_opp_table, *clk_opp_table; + struct dev_pm_opp *opp; + u32 hw_version; + int ret; + + /* + * The EMC devices are a special case because we have a protection + * from non-EMC drivers getting clock handle before EMC driver is + * fully initialized. The goal of the protection is to prevent + * devfreq driver from getting failures if it will try to change + * EMC clock rate until clock is fully initialized. The EMC drivers + * will initialize the performance state by themselves. + * + * Display controller also is a special case because only controller + * driver could get the clock rate based on configuration of internal + * divider. + * + * Clock driver uses its own state syncing. + */ + if (of_device_compatible_match(dev->of_node, tegra_pd_no_perf_compats)) + return 0; + + if (of_machine_is_compatible("nvidia,tegra20")) + hw_version = BIT(tegra_sku_info.soc_process_id); + else + hw_version = BIT(tegra_sku_info.soc_speedo_id); + + hw_opp_table = dev_pm_opp_set_supported_hw(dev, &hw_version, 1); + if (IS_ERR(hw_opp_table)) { + dev_err(dev, "failed to set OPP supported HW: %pe\n", + hw_opp_table); + return PTR_ERR(hw_opp_table); + } + + /* + * Older device-trees don't have OPPs, meanwhile drivers use + * dev_pm_opp_set_rate() and it requires OPP table to be set + * up using dev_pm_opp_set_clkname(). + * + * The devm_tegra_core_dev_init_opp_table() is a common helper + * that sets up OPP table for Tegra drivers and it sets the clk + * for compatibility with older device-tress. GR3D driver uses that + * helper, it also uses devm_pm_opp_attach_genpd() to manually attach + * power domains, which now holds the reference to OPP table that + * already has clk set up implicitly by OPP core for a newly created + * table using dev_pm_opp_of_add_table() invoked below. + * + * Hence we need to explicitly set/put the clk, otherwise + * further dev_pm_opp_set_clkname() will fail with -EBUSY. + */ + clk_opp_table = dev_pm_opp_set_clkname(dev, NULL); + if (IS_ERR(clk_opp_table)) { + dev_err(dev, "failed to set OPP clk: %pe\n", clk_opp_table); + ret = PTR_ERR(clk_opp_table); + goto put_hw; + } + + ret = dev_pm_opp_of_add_table(dev); + if (ret) { + dev_err(dev, "failed to add OPP table: %d\n", ret); + goto put_clk; + } + + opp = dev_pm_opp_get_current(dev); + if (IS_ERR(opp)) { + dev_err(dev, "failed to get current OPP: %pe\n", opp); + ret = PTR_ERR(opp); + } else { + ret = dev_pm_opp_get_required_pstate(opp, 0); + dev_pm_opp_put(opp); + } + + dev_pm_opp_of_remove_table(dev); +put_clk: + dev_pm_opp_put_clkname(clk_opp_table); +put_hw: + dev_pm_opp_put_supported_hw(hw_opp_table); + + return ret; +} + /* * TODO Figure out a way to call this with the struct tegra_pmc * passed in. * This currently doesn't work because readx_poll_timeout() can only operate @@ -1237,6 +1336,7 @@ static int tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np) pg->id = id; pg->genpd.name = np->name; + pg->genpd.dev_get_performance_state = tegra_pmc_pd_dev_get_performance_state; pg->genpd.power_off = tegra_genpd_power_off; pg->genpd.power_on = tegra_genpd_power_on; pg->pmc = pmc; @@ -1355,6 +1455,7 @@ static int tegra_pmc_core_pd_add(struct tegra_pmc *pmc, struct device_node *np) genpd->name = np->name; genpd->set_performance_state = tegra_pmc_core_pd_set_performance_state; genpd->opp_to_performance_state = tegra_pmc_core_pd_opp_to_performance_state; + genpd->dev_get_performance_state = tegra_pmc_pd_dev_get_performance_state; err = devm_pm_opp_set_regulators(pmc->dev, &rname, 1); if (err) From patchwork Tue Aug 31 13:54:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 504840 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.8 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,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 D64D0C4320E for ; Tue, 31 Aug 2021 13:57:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BD5B361027 for ; Tue, 31 Aug 2021 13:57:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234673AbhHaN6G (ORCPT ); Tue, 31 Aug 2021 09:58:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58200 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233092AbhHaN57 (ORCPT ); Tue, 31 Aug 2021 09:57:59 -0400 Received: from mail-lj1-x22c.google.com (mail-lj1-x22c.google.com [IPv6:2a00:1450:4864:20::22c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0E2E4C061575; Tue, 31 Aug 2021 06:57:04 -0700 (PDT) Received: by mail-lj1-x22c.google.com with SMTP id q21so31912137ljj.6; Tue, 31 Aug 2021 06:57:03 -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=wojn7XneOlcjLQTZlMLpcmbGjIOEPaqexo+f2WGyphI=; b=qVsfZiyMnP/5jTRQoTxF8dWulzxsSz94iH5tlFNvaAII+VNdg99R2f+8EvePPIchr9 3ywfK1DPyQcya2uCzEeS5a/YcPsGvQJ67NRGMwUvUWSBFa4Mfd8cjmufzpjdVx86LXhx c0qVUwC+5FSifqSa8tIYTbx/PVEQtZ5GER1m63etxy6oiWpHoll47BeO3uEPo73sH1NO Rqr76tF7ykOUhOPcGW7RTeWtY1jSjMXx9+9vxF4P5/gvTNPgexO34XwXj+g54oQ7qhSw dFnv1iBzDgb+jWRGO3dRzTDiRSWoEsIITlgj67SiuG4FQWTQ2djRmoetBsTqwctmuV2B VT6g== 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=wojn7XneOlcjLQTZlMLpcmbGjIOEPaqexo+f2WGyphI=; b=UW0hcFO7CEf0K5LT32MfMa10RJjxZXtLJlxwO1DqVb686UKw6CeltJYrKDmP+d0cRQ 7g5OgFT/rdntpBujuE5xxWMTybkDLv5Cz3MSxZY0j4K/vW4mxWbJ3whIIjpEyFgStRIQ fYH/YwwjgPBLtUPpy5FnRc2niMczRGWWXhE43bxzT0fAXCH7Q7fIr3LjYIQW/svyBOrI OaYEtNpKmyHX5fq8/O2KgO5/v41+VasX+8vDma0lWSfRXhew97OudNN2Eqb/xEgiA1sD K08bYP4gI/rYStJQphGjGncZQGth/8kOkyPvmQeNRWGKRmL5RA3SScfysDkPHbdIHLYD OYNg== X-Gm-Message-State: AOAM53239xRa0Hu5UlDBVwaWKygJY5luqaH2GWrTaPf0FMui7chPZg5r 9t7i20QaUNyoqW/mVwiwD/4= X-Google-Smtp-Source: ABdhPJwPfoUBTBafkRF0UF0+sV9ZaSTJMquVbN7nqg6nVS6mcP8N12osVFg3TeM3zfO9rR3ZtbNHrQ== X-Received: by 2002:a2e:7801:: with SMTP id t1mr25099487ljc.192.1630418222483; Tue, 31 Aug 2021 06:57:02 -0700 (PDT) Received: from localhost.localdomain (46-138-26-37.dynamic.spd-mgts.ru. [46.138.26.37]) by smtp.gmail.com with ESMTPSA id x4sm2203622ljm.98.2021.08.31.06.57.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 31 Aug 2021 06:57:02 -0700 (PDT) From: Dmitry Osipenko To: Thierry Reding , Jonathan Hunter , Ulf Hansson , "Rafael J. Wysocki" , Kevin Hilman , Viresh Kumar , Stephen Boyd , Nishanth Menon Cc: linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-pm@vger.kernel.org Subject: [PATCH v10 6/8] soc/tegra: Add devm_tegra_core_dev_init_opp_table_simple() Date: Tue, 31 Aug 2021 16:54:48 +0300 Message-Id: <20210831135450.26070-7-digetx@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210831135450.26070-1-digetx@gmail.com> References: <20210831135450.26070-1-digetx@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Only couple drivers need to get the -ENODEV error code and explicitly initialize the performance state. Add new helper that allows to avoid the extra boilerplate code in majority of drivers. Signed-off-by: Dmitry Osipenko --- include/soc/tegra/common.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/soc/tegra/common.h b/include/soc/tegra/common.h index af41ad80ec21..265ad90e45a2 100644 --- a/include/soc/tegra/common.h +++ b/include/soc/tegra/common.h @@ -39,4 +39,17 @@ devm_tegra_core_dev_init_opp_table(struct device *dev, } #endif +static inline int +devm_tegra_core_dev_init_opp_table_simple(struct device *dev) +{ + struct tegra_core_opp_params params = {}; + int err; + + err = devm_tegra_core_dev_init_opp_table(dev, ¶ms); + if (err != -ENODEV) + return err; + + return 0; +} + #endif /* __SOC_TEGRA_COMMON_H__ */ From patchwork Tue Aug 31 13:54:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 504841 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.8 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,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 7C868C4320E for ; Tue, 31 Aug 2021 13:57:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6A1FA61027 for ; Tue, 31 Aug 2021 13:57:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232518AbhHaN6E (ORCPT ); Tue, 31 Aug 2021 09:58:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58204 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233134AbhHaN6A (ORCPT ); Tue, 31 Aug 2021 09:58:00 -0400 Received: from mail-lj1-x233.google.com (mail-lj1-x233.google.com [IPv6:2a00:1450:4864:20::233]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D7AA1C061764; Tue, 31 Aug 2021 06:57:04 -0700 (PDT) Received: by mail-lj1-x233.google.com with SMTP id q21so31912231ljj.6; Tue, 31 Aug 2021 06:57:04 -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=yDP03amDwCEY6IiivIbDG+60+C+xV/Pv6sR1LEywSYo=; b=joFzU8WPJH8DP0+WGdlyT4Tgw7vhOJ+mTQaTb1LSEO1z/dKqhZO6LNqV3eIsxqrNqh jTvvIgRsSURHHRi6MwKtud6Ry7//fDmPl+/gmwgA4Fm1/oqYMWECk13igVwEFbXCOATM F6qQc0iqXyR1Wn9B90gaZg6xHFDBkLXhZEgharG0yWgA3OUh3l8JkhnaRzFg2mvKQiok j3jQecttboUU0IlWM/uDxP4owTEAo7CvjXRM22byBE0ERMvJpCFeipwbK511NI0l6TVr tO2TCvS+XlSfWqdKdLLuB5DTjNYeof1Yco55xnCisM1bPc9BOEeuhpU1oISJrnRBPCxH Fy/g== 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=yDP03amDwCEY6IiivIbDG+60+C+xV/Pv6sR1LEywSYo=; b=Q2moyPsO1sGu1FjXHKB/Nb6mPvlMXD/eMuCKVJPtA38aoWXuY++fbe2eTRvbdXD4bX 7pvgpj9DsucO8Z9wnKkl6AALOE+zna9QJLRvd77mVkYwib1r774C2mRDBc1kdrgqdmpa b2fm06EMZCiGjY6TyWOSZIU8cmu/tqzMPZ9aU5n6MqEguBGwtuPD1w3+V76MKUthapPk 2qBanUthZvemkRt3N/1Hsd6eXSbSvqPbOcwhlZWQoTHUGbZ4xaDaQgRpI7fJkT8XYAgt cmIAjx3QIGC+KtwVvBvW/NCPSC3F2WmKt+p87EARYWZB1zks4T4lk6uLYrO0BP6+dox5 VRgw== X-Gm-Message-State: AOAM533pinGYoUMGVQdW6rWHWTwWt82a+06sBHZNfs8fdGUCaOfHbWiq 61VcWCMNZMIdteh0esULL9c= X-Google-Smtp-Source: ABdhPJzoJ/gElLf6N9bO/NPqrNrysTQIFQEktX7rML2l2ShYORbg+kuDiamYRjl7HTQxP53SL3aKbg== X-Received: by 2002:a2e:a363:: with SMTP id i3mr24868111ljn.56.1630418223330; Tue, 31 Aug 2021 06:57:03 -0700 (PDT) Received: from localhost.localdomain (46-138-26-37.dynamic.spd-mgts.ru. [46.138.26.37]) by smtp.gmail.com with ESMTPSA id x4sm2203622ljm.98.2021.08.31.06.57.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 31 Aug 2021 06:57:02 -0700 (PDT) From: Dmitry Osipenko To: Thierry Reding , Jonathan Hunter , Ulf Hansson , "Rafael J. Wysocki" , Kevin Hilman , Viresh Kumar , Stephen Boyd , Nishanth Menon Cc: linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-pm@vger.kernel.org Subject: [PATCH v10 7/8] gpu: host1x: Add host1x_channel_stop() Date: Tue, 31 Aug 2021 16:54:49 +0300 Message-Id: <20210831135450.26070-8-digetx@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210831135450.26070-1-digetx@gmail.com> References: <20210831135450.26070-1-digetx@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Add host1x_channel_stop() which waits till channel becomes idle and then stops the channel hardware. This is needed for supporting suspend/resume by host1x drivers since the hardware state is lost after power-gating, thus the channel needs to be stopped before client enters into suspend. Tested-by: Peter Geis # Ouya T30 Tested-by: Paul Fertser # PAZ00 T20 Tested-by: Nicolas Chauvet # PAZ00 T20 and TK1 T124 Tested-by: Matt Merhar # Ouya T30 Signed-off-by: Dmitry Osipenko --- drivers/gpu/host1x/channel.c | 8 ++++++++ include/linux/host1x.h | 1 + 2 files changed, 9 insertions(+) diff --git a/drivers/gpu/host1x/channel.c b/drivers/gpu/host1x/channel.c index 4cd212bb570d..2a9a3a8d5931 100644 --- a/drivers/gpu/host1x/channel.c +++ b/drivers/gpu/host1x/channel.c @@ -75,6 +75,14 @@ struct host1x_channel *host1x_channel_get_index(struct host1x *host, return ch; } +void host1x_channel_stop(struct host1x_channel *channel) +{ + struct host1x *host = dev_get_drvdata(channel->dev->parent); + + host1x_hw_cdma_stop(host, &channel->cdma); +} +EXPORT_SYMBOL(host1x_channel_stop); + static void release_channel(struct kref *kref) { struct host1x_channel *channel = diff --git a/include/linux/host1x.h b/include/linux/host1x.h index 7bccf589aba7..66473b5be0af 100644 --- a/include/linux/host1x.h +++ b/include/linux/host1x.h @@ -181,6 +181,7 @@ struct host1x_job; struct host1x_channel *host1x_channel_request(struct host1x_client *client); struct host1x_channel *host1x_channel_get(struct host1x_channel *channel); +void host1x_channel_stop(struct host1x_channel *channel); void host1x_channel_put(struct host1x_channel *channel); int host1x_job_submit(struct host1x_job *job); From patchwork Tue Aug 31 13:54:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 505405 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.8 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,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 C4301C4320A for ; Tue, 31 Aug 2021 13:57:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B0A0561056 for ; Tue, 31 Aug 2021 13:57:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233405AbhHaN6F (ORCPT ); Tue, 31 Aug 2021 09:58:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58210 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233354AbhHaN6B (ORCPT ); Tue, 31 Aug 2021 09:58:01 -0400 Received: from mail-lj1-x232.google.com (mail-lj1-x232.google.com [IPv6:2a00:1450:4864:20::232]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E8F2AC0613D9; Tue, 31 Aug 2021 06:57:05 -0700 (PDT) Received: by mail-lj1-x232.google.com with SMTP id i28so31976771ljm.7; Tue, 31 Aug 2021 06:57:05 -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=2xnbiR8WOpQFvteKUmC+0aA2JAMzFJwrKrlTihtzzZw=; b=g8uoSOyBMmMRJ1ETJv2IbO2p8/TB3n5jd/TW/+2+cunZpXF/zc/tG4uYnUy0+kiRfa pR2dVaZKukDQ1woB81MJJ9Qo9pgzqqBGGiGyhG18wcSQuFJR2/CuscY5vIOGFDrZZgom t0vgcCHXD9IsM4UZysoEFT3jqa1HqzcF2ZPkVHFYZQClQ34b2VR1AjWH6qBIV4eNe0aa 5SnJ0tHAaeoK7R7HtF6R6pP0R8NuLyatPoGCjmeL7ezCEQZZZOdHQNU2i7kEdycgoWiH xEbU9saJ0EQL4H9pwf+h3oKxefRpoWAv1H0RaYyoAmZA2m4NJncbWJVNcmpWX8EF+BT6 5NXg== 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=2xnbiR8WOpQFvteKUmC+0aA2JAMzFJwrKrlTihtzzZw=; b=I6dhnyls8II/ZXfKGTzSaiM6z+yJ5u+TEeQT6Qpw/fJXg7PSwiOs3QLXWdcqCWFtCC AnZjeQHkLrusLQGPKD5XUeY/jw6ictpi0kg/uuxqIsBC/FTArXJMa/oYBse+ILbwL4oM f7/0MLMTssz8L0cZGVq7o9KuSLMAzMcvmd+dY3Zg/hkvTezquVVDhnGxcULuAAPX71vn u4YTXR/ny4+Bwp+WZGzXPz0L1jNG2UrI+TrVOahvhBObH1ChpqGbqzxpyzbq4NMoR3Qe gPtALNaNid9aGpR7uEXxfAY+zfWOIRT67HChiGELYtfhICTmJ03dWkEl4+iQQic3w/wb yKuQ== X-Gm-Message-State: AOAM533c6dz9xF6hTdvXOuyUrQfsc6QjSHyEPZ42SPSvFIcLJagnOKbS n/YC2ujJbhI+UJQZsGehN1uo5eDqnqU= X-Google-Smtp-Source: ABdhPJwODV2YJrUgbirl/FeCm5CKQ45o9qIqWoRe9rw4kFWLWCazBRDK/fnlvwp2QmFy/sXstis4EQ== X-Received: by 2002:a05:651c:88d:: with SMTP id d13mr26075563ljq.238.1630418224276; Tue, 31 Aug 2021 06:57:04 -0700 (PDT) Received: from localhost.localdomain (46-138-26-37.dynamic.spd-mgts.ru. [46.138.26.37]) by smtp.gmail.com with ESMTPSA id x4sm2203622ljm.98.2021.08.31.06.57.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 31 Aug 2021 06:57:03 -0700 (PDT) From: Dmitry Osipenko To: Thierry Reding , Jonathan Hunter , Ulf Hansson , "Rafael J. Wysocki" , Kevin Hilman , Viresh Kumar , Stephen Boyd , Nishanth Menon Cc: linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-pm@vger.kernel.org Subject: [PATCH v10 8/8] drm/tegra: gr3d: Support generic power domain and runtime PM Date: Tue, 31 Aug 2021 16:54:50 +0300 Message-Id: <20210831135450.26070-9-digetx@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210831135450.26070-1-digetx@gmail.com> References: <20210831135450.26070-1-digetx@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Add power management and support generic power domains. Tested-by: Peter Geis # Ouya T30 Tested-by: Paul Fertser # PAZ00 T20 Tested-by: Nicolas Chauvet # PAZ00 T20 and TK1 T124 Tested-by: Matt Merhar # Ouya T30 Signed-off-by: Dmitry Osipenko --- drivers/gpu/drm/tegra/gr3d.c | 384 ++++++++++++++++++++++++++++++----- 1 file changed, 330 insertions(+), 54 deletions(-) diff --git a/drivers/gpu/drm/tegra/gr3d.c b/drivers/gpu/drm/tegra/gr3d.c index 24442ade0da3..545eb4005a96 100644 --- a/drivers/gpu/drm/tegra/gr3d.c +++ b/drivers/gpu/drm/tegra/gr3d.c @@ -5,32 +5,47 @@ */ #include +#include #include #include #include #include #include +#include +#include +#include #include +#include #include #include "drm.h" #include "gem.h" #include "gr3d.h" +enum { + RST_MC, + RST_GR3D, + RST_MC2, + RST_GR3D2, + RST_GR3D_MAX, +}; + struct gr3d_soc { unsigned int version; + unsigned int num_clocks; + unsigned int num_resets; }; struct gr3d { struct tegra_drm_client client; struct host1x_channel *channel; - struct clk *clk_secondary; - struct clk *clk; - struct reset_control *rst_secondary; - struct reset_control *rst; const struct gr3d_soc *soc; + struct clk_bulk_data *clocks; + unsigned int nclocks; + struct reset_control_bulk_data resets[RST_GR3D_MAX]; + unsigned int nresets; DECLARE_BITMAP(addr_regs, GR3D_NUM_REGS); }; @@ -109,16 +124,24 @@ static int gr3d_open_channel(struct tegra_drm_client *client, struct tegra_drm_context *context) { struct gr3d *gr3d = to_gr3d(client); + int err; context->channel = host1x_channel_get(gr3d->channel); if (!context->channel) return -ENOMEM; + err = pm_runtime_resume_and_get(client->base.dev); + if (err) { + host1x_channel_put(context->channel); + return err; + } + return 0; } static void gr3d_close_channel(struct tegra_drm_context *context) { + pm_runtime_put_sync(context->client->base.dev); host1x_channel_put(context->channel); } @@ -155,14 +178,20 @@ static const struct tegra_drm_client_ops gr3d_ops = { static const struct gr3d_soc tegra20_gr3d_soc = { .version = 0x20, + .num_clocks = 1, + .num_resets = 2, }; static const struct gr3d_soc tegra30_gr3d_soc = { .version = 0x30, + .num_clocks = 2, + .num_resets = 4, }; static const struct gr3d_soc tegra114_gr3d_soc = { .version = 0x35, + .num_clocks = 1, + .num_resets = 2, }; static const struct of_device_id tegra_gr3d_match[] = { @@ -278,9 +307,211 @@ static const u32 gr3d_addr_regs[] = { GR3D_GLOBAL_SAMP23SURFADDR(15), }; +static int gr3d_power_up_legacy_domain(struct device *dev, const char *name, + unsigned int id) +{ + struct gr3d *gr3d = dev_get_drvdata(dev); + struct reset_control *reset; + struct clk *clk; + unsigned int i; + int err; + + /* + * Tegra20 device-tree doesn't specify 3d clock name and there is only + * one clock for Tegra20. Tegra30+ device-trees always specified names + * for the clocks. + */ + if (gr3d->nclocks == 1) { + if (id == TEGRA_POWERGATE_3D1) + return 0; + + clk = gr3d->clocks[0].clk; + } else { + for (i = 0; i < gr3d->nclocks; i++) { + if (WARN_ON(!gr3d->clocks[i].id)) + continue; + + if (!strcmp(gr3d->clocks[i].id, name)) { + clk = gr3d->clocks[i].clk; + break; + } + } + + if (WARN_ON(i == gr3d->nclocks)) + return -EINVAL; + } + + /* + * We use array of resets, which includes MC resets, and MC + * reset shouldn't be asserted while hardware is gated because + * MC flushing will fail for gated hardware. Hence for legacy + * PD we request the individual reset separately. + */ + reset = reset_control_get_exclusive_released(dev, name); + if (IS_ERR(reset)) + return PTR_ERR(reset); + + err = reset_control_acquire(reset); + if (err) { + dev_err(dev, "failed to acquire %s reset: %d\n", name, err); + } else { + err = tegra_powergate_sequence_power_up(id, clk, reset); + reset_control_release(reset); + } + + reset_control_put(reset); + if (err) + return err; + + /* + * tegra_powergate_sequence_power_up() leaves clocks enabled + * while GENPD not, hence keep clock-enable balanced. + */ + clk_disable_unprepare(clk); + + return 0; +} + +static void gr3d_del_link(void *link) +{ + device_link_del(link); +} + +static int gr3d_init_power(struct device *dev, struct gr3d *gr3d) +{ + static const char * const opp_genpd_names[] = { "3d0", "3d1", NULL }; + const u32 link_flags = DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME; + struct device **opp_virt_devs, *pd_dev; + struct device_link *link; + unsigned int i; + int err; + + err = of_count_phandle_with_args(dev->of_node, "power-domains", + "#power-domain-cells"); + if (err < 0) { + if (err != -ENOENT) + return err; + + /* + * Older device-trees don't use GENPD. In this case we should + * toggle power domain manually. + */ + err = gr3d_power_up_legacy_domain(dev, "3d", + TEGRA_POWERGATE_3D); + if (err) + return err; + + err = gr3d_power_up_legacy_domain(dev, "3d2", + TEGRA_POWERGATE_3D1); + if (err) + return err; + + return 0; + } + + /* + * The PM domain core automatically attaches a single power domain, + * otherwise it skips attaching completely. We have a single domain + * on Tegra20 and two domains on Tegra30+. + */ + if (dev->pm_domain) + return 0; + + err = devm_pm_opp_attach_genpd(dev, opp_genpd_names, &opp_virt_devs); + if (err) + return err; + + for (i = 0; opp_genpd_names[i]; i++) { + pd_dev = opp_virt_devs[i]; + if (!pd_dev) { + dev_err(dev, "failed to get %s power domain\n", + opp_genpd_names[i]); + return -EINVAL; + } + + link = device_link_add(dev, pd_dev, link_flags); + if (!link) { + dev_err(dev, "failed to link to %s\n", dev_name(pd_dev)); + return -EINVAL; + } + + err = devm_add_action_or_reset(dev, gr3d_del_link, link); + if (err) + return err; + } + + return 0; +} + +static int gr3d_set_opp(struct dev_pm_set_opp_data *data) +{ + struct gr3d *gr3d = dev_get_drvdata(data->dev); + unsigned int i; + int err; + + for (i = 0; i < gr3d->nclocks; i++) { + err = clk_set_rate(gr3d->clocks[i].clk, data->new_opp.rate); + if (err) { + dev_err(data->dev, "failed to set %s rate to %lu: %d\n", + gr3d->clocks[i].id, data->new_opp.rate, err); + goto restore; + } + } + + return 0; + +restore: + while (i--) + clk_set_rate(gr3d->clocks[i].clk, data->old_opp.rate); + + return err; +} + +static int gr3d_get_clocks(struct device *dev, struct gr3d *gr3d) +{ + int err; + + err = devm_clk_bulk_get_all(dev, &gr3d->clocks); + if (err < 0) { + dev_err(dev, "failed to get clock: %d\n", err); + return err; + } + gr3d->nclocks = err; + + if (gr3d->nclocks != gr3d->soc->num_clocks) { + dev_err(dev, "invalid number of clocks: %u\n", gr3d->nclocks); + return -ENOENT; + } + + return 0; +} + +static int gr3d_get_resets(struct device *dev, struct gr3d *gr3d) +{ + int err; + + gr3d->resets[RST_MC].id = "mc"; + gr3d->resets[RST_MC2].id = "mc2"; + gr3d->resets[RST_GR3D].id = "3d"; + gr3d->resets[RST_GR3D2].id = "3d2"; + gr3d->nresets = gr3d->soc->num_resets; + + err = devm_reset_control_bulk_get_optional_exclusive_released( + dev, gr3d->nresets, gr3d->resets); + if (err) { + dev_err(dev, "failed to get reset: %d\n", err); + return err; + } + + if (WARN_ON(!gr3d->resets[RST_GR3D].rstc) || + WARN_ON(!gr3d->resets[RST_GR3D2].rstc && gr3d->nresets == 4)) + return -ENOENT; + + return 0; +} + static int gr3d_probe(struct platform_device *pdev) { - struct device_node *np = pdev->dev.of_node; struct host1x_syncpt **syncpts; struct gr3d *gr3d; unsigned int i; @@ -290,56 +521,33 @@ static int gr3d_probe(struct platform_device *pdev) if (!gr3d) return -ENOMEM; + platform_set_drvdata(pdev, gr3d); + gr3d->soc = of_device_get_match_data(&pdev->dev); syncpts = devm_kzalloc(&pdev->dev, sizeof(*syncpts), GFP_KERNEL); if (!syncpts) return -ENOMEM; - gr3d->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(gr3d->clk)) { - dev_err(&pdev->dev, "cannot get clock\n"); - return PTR_ERR(gr3d->clk); - } - - gr3d->rst = devm_reset_control_get(&pdev->dev, "3d"); - if (IS_ERR(gr3d->rst)) { - dev_err(&pdev->dev, "cannot get reset\n"); - return PTR_ERR(gr3d->rst); - } + err = gr3d_get_clocks(&pdev->dev, gr3d); + if (err) + return err; - if (of_device_is_compatible(np, "nvidia,tegra30-gr3d")) { - gr3d->clk_secondary = devm_clk_get(&pdev->dev, "3d2"); - if (IS_ERR(gr3d->clk_secondary)) { - dev_err(&pdev->dev, "cannot get secondary clock\n"); - return PTR_ERR(gr3d->clk_secondary); - } + err = gr3d_get_resets(&pdev->dev, gr3d); + if (err) + return err; - gr3d->rst_secondary = devm_reset_control_get(&pdev->dev, - "3d2"); - if (IS_ERR(gr3d->rst_secondary)) { - dev_err(&pdev->dev, "cannot get secondary reset\n"); - return PTR_ERR(gr3d->rst_secondary); - } - } + err = gr3d_init_power(&pdev->dev, gr3d); + if (err) + return err; - err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_3D, gr3d->clk, - gr3d->rst); - if (err < 0) { - dev_err(&pdev->dev, "failed to power up 3D unit\n"); + err = devm_pm_opp_register_set_opp_helper(&pdev->dev, gr3d_set_opp); + if (err) return err; - } - if (gr3d->clk_secondary) { - err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_3D1, - gr3d->clk_secondary, - gr3d->rst_secondary); - if (err < 0) { - dev_err(&pdev->dev, - "failed to power up secondary 3D unit\n"); - return err; - } - } + err = devm_tegra_core_dev_init_opp_table_simple(&pdev->dev); + if (err) + return err; INIT_LIST_HEAD(&gr3d->client.base.list); gr3d->client.base.ops = &gr3d_client_ops; @@ -352,20 +560,28 @@ static int gr3d_probe(struct platform_device *pdev) gr3d->client.version = gr3d->soc->version; gr3d->client.ops = &gr3d_ops; + pm_runtime_enable(&pdev->dev); + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_set_autosuspend_delay(&pdev->dev, 200); + err = host1x_client_register(&gr3d->client.base); if (err < 0) { dev_err(&pdev->dev, "failed to register host1x client: %d\n", err); - return err; + goto disable_rpm; } /* initialize address register map */ for (i = 0; i < ARRAY_SIZE(gr3d_addr_regs); i++) set_bit(gr3d_addr_regs[i], gr3d->addr_regs); - platform_set_drvdata(pdev, gr3d); - return 0; + +disable_rpm: + pm_runtime_dont_use_autosuspend(&pdev->dev); + pm_runtime_disable(&pdev->dev); + + return err; } static int gr3d_remove(struct platform_device *pdev) @@ -380,23 +596,83 @@ static int gr3d_remove(struct platform_device *pdev) return err; } - if (gr3d->clk_secondary) { - reset_control_assert(gr3d->rst_secondary); - tegra_powergate_power_off(TEGRA_POWERGATE_3D1); - clk_disable_unprepare(gr3d->clk_secondary); + pm_runtime_dont_use_autosuspend(&pdev->dev); + pm_runtime_disable(&pdev->dev); + + return 0; +} + +static int __maybe_unused gr3d_runtime_suspend(struct device *dev) +{ + struct gr3d *gr3d = dev_get_drvdata(dev); + int err; + + host1x_channel_stop(gr3d->channel); + + err = reset_control_bulk_assert(gr3d->nresets, gr3d->resets); + if (err) { + dev_err(dev, "failed to assert reset: %d\n", err); + return err; + } + + usleep_range(10, 20); + + /* + * Older device-trees don't specify MC resets and power-gating can't + * be done safely in that case. Hence we will keep the power ungated + * for older DTBs. For newer DTBs, GENPD will perform the power-gating. + */ + + clk_bulk_disable_unprepare(gr3d->nclocks, gr3d->clocks); + reset_control_bulk_release(gr3d->nresets, gr3d->resets); + + return 0; +} + +static int __maybe_unused gr3d_runtime_resume(struct device *dev) +{ + struct gr3d *gr3d = dev_get_drvdata(dev); + int err; + + err = reset_control_bulk_acquire(gr3d->nresets, gr3d->resets); + if (err) { + dev_err(dev, "failed to acquire reset: %d\n", err); + return err; + } + + err = clk_bulk_prepare_enable(gr3d->nclocks, gr3d->clocks); + if (err) { + dev_err(dev, "failed to enable clock: %d\n", err); + goto release_reset; } - reset_control_assert(gr3d->rst); - tegra_powergate_power_off(TEGRA_POWERGATE_3D); - clk_disable_unprepare(gr3d->clk); + err = reset_control_bulk_deassert(gr3d->nresets, gr3d->resets); + if (err) { + dev_err(dev, "failed to deassert reset: %d\n", err); + goto disable_clk; + } return 0; + +disable_clk: + clk_bulk_disable_unprepare(gr3d->nclocks, gr3d->clocks); +release_reset: + reset_control_bulk_release(gr3d->nresets, gr3d->resets); + + return err; } +static const struct dev_pm_ops tegra_gr3d_pm = { + SET_RUNTIME_PM_OPS(gr3d_runtime_suspend, gr3d_runtime_resume, NULL) + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) +}; + struct platform_driver tegra_gr3d_driver = { .driver = { .name = "tegra-gr3d", .of_match_table = tegra_gr3d_match, + .pm = &tegra_gr3d_pm, }, .probe = gr3d_probe, .remove = gr3d_remove,