From patchwork Mon May 20 10:47:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Saenz Julienne X-Patchwork-Id: 10950853 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E55F517E0 for ; Mon, 20 May 2019 10:47:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D1FED28696 for ; Mon, 20 May 2019 10:47:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C651C287C1; Mon, 20 May 2019 10:47:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 74F8B28696 for ; Mon, 20 May 2019 10:47:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=mCxOTBzfHiuI6M9SXyyXOf+XH7MBXY1qnAA81jU5/m0=; b=D3Aef2ajh2vhul fEZDER32Bo3ORDdFHibIIBPrVuwNX7EMDB0dCpIo7aG3kOS4Rn9lA8EPjoHSHImB3sTWHNA/OQTpC X5KfeyTEEg+sQ/4YLM5X6s69+V2DrONBm2BP6+nPEpPR1b5Oa/PyRigWFJPtY/suEiqHqYRnRSu4V Bhv3vTXcqeu0JsTg7OV2xoPalCT27Y1xHuOBjtbz11KI/y20fRes6c8ne8rxy1yJJlluY2nv+Duc3 bxUHhrrMvl5cHy1DnIhtdZJcXnKUGNhkXVhVD95dBQ0Xt3130hv9kzgM/ilJ5/OMF9dO/Zb2UYyzY krS502X50ub9ZGHWyNmw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hSfpf-0000km-Rd; Mon, 20 May 2019 10:47:51 +0000 Received: from mx2.suse.de ([195.135.220.15] helo=mx1.suse.de) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hSfpU-0000QN-4t; Mon, 20 May 2019 10:47:43 +0000 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 91BADAFD2; Mon, 20 May 2019 10:47:35 +0000 (UTC) From: Nicolas Saenz Julienne To: stefan.wahren@i2se.com, Florian Fainelli , Ray Jui , Scott Branden , bcm-kernel-feedback-list@broadcom.com, Eric Anholt Subject: [RFC v2 1/5] clk: bcm2835: set CLK_GET_RATE_NOCACHE on CPU clocks Date: Mon, 20 May 2019 12:47:03 +0200 Message-Id: <20190520104708.11980-2-nsaenzjulienne@suse.de> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190520104708.11980-1-nsaenzjulienne@suse.de> References: <20190520104708.11980-1-nsaenzjulienne@suse.de> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190520_034740_330997_CE1AC184 X-CRM114-Status: GOOD ( 12.88 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-arm-kernel@lists.infradead.org, ptesarik@suse.com, sboyd@kernel.org, viresh.kumar@linaro.org, mturquette@baylibre.com, linux-pm@vger.kernel.org, rjw@rjwysocki.net, linux-kernel@vger.kernel.org, Nicolas Saenz Julienne , linux-rpi-kernel@lists.infradead.org, linux-clk@vger.kernel.org, mbrugger@suse.de, ssuloev@orpaltech.com Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Raspberry Pi's firmware is responsible for updating the cpu clocks and pll. This makes sure we get the right rates anytime. Signed-off-by: Nicolas Saenz Julienne Acked-by: Stefan Wahren --- drivers/clk/bcm/clk-bcm2835.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 770bb01f523e..c2772dfb155a 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -411,6 +411,7 @@ struct bcm2835_pll_data { u32 reference_enable_mask; /* Bit in CM_LOCK to indicate when the PLL has locked. */ u32 lock_mask; + u32 flags; const struct bcm2835_pll_ana_bits *ana; @@ -1299,7 +1300,7 @@ static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman, init.num_parents = 1; init.name = data->name; init.ops = &bcm2835_pll_clk_ops; - init.flags = CLK_IGNORE_UNUSED; + init.flags = data->flags | CLK_IGNORE_UNUSED; pll = kzalloc(sizeof(*pll), GFP_KERNEL); if (!pll) @@ -1660,6 +1661,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { .ana_reg_base = A2W_PLLB_ANA0, .reference_enable_mask = A2W_XOSC_CTRL_PLLB_ENABLE, .lock_mask = CM_LOCK_FLOCKB, + .flags = CLK_GET_RATE_NOCACHE, .ana = &bcm2835_ana_default, @@ -1674,7 +1676,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { .load_mask = CM_PLLB_LOADARM, .hold_mask = CM_PLLB_HOLDARM, .fixed_divider = 1, - .flags = CLK_SET_RATE_PARENT), + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE), /* * PLLC is the core PLL, used to drive the core VPU clock. From patchwork Mon May 20 10:47:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Saenz Julienne X-Patchwork-Id: 10950861 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A3FFE6C5 for ; Mon, 20 May 2019 10:48:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 91FEB28696 for ; Mon, 20 May 2019 10:48:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 85D96287C1; Mon, 20 May 2019 10:48:11 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 226F628696 for ; Mon, 20 May 2019 10:48:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=WJepoRGqb8R1GxqTTyDco/daeRLDO0ddDjJSZuojYCU=; b=QQF8XwT/8YEpty 72K9/4euwcKlwxsGwKga5AcVzEszvNuJPw7pCNWd472OD6U5t9R5Xak8vE96bRSHBS+tBAK+0Hxs8 RtZK+TbBwDjZ5lpHqqj7AqYlEhyNJoD5RNlgVnarugUQctRzqxqS1dws7TmSKlAlMkMvR1ibHZOka Y+X5uQHpnflYZ0VyqdTqWOwqqb0S/tLjlmp5ClPyFyi/MUwoYYD3Vk97Er5ZjgiSdMs39TmOnbMD7 YJDrGQwp3IyOz8qQUHBFhrOLil6fCM63HnyK8DiDFuvih7avX/6GF2WrU/T2UmrCCYZSvlmgbh09c V0PPv6j5RQIEzvxMkQYw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hSfpr-00010w-Mi; Mon, 20 May 2019 10:48:03 +0000 Received: from mx2.suse.de ([195.135.220.15] helo=mx1.suse.de) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hSfpU-0000RA-4x; Mon, 20 May 2019 10:47:43 +0000 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id AD1E1AFD3; Mon, 20 May 2019 10:47:36 +0000 (UTC) From: Nicolas Saenz Julienne To: stefan.wahren@i2se.com, Florian Fainelli , Ray Jui , Scott Branden , bcm-kernel-feedback-list@broadcom.com, Eric Anholt Subject: [RFC v2 2/5] clk: bcm2835: set pllb_arm divisor as readonly Date: Mon, 20 May 2019 12:47:04 +0200 Message-Id: <20190520104708.11980-3-nsaenzjulienne@suse.de> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190520104708.11980-1-nsaenzjulienne@suse.de> References: <20190520104708.11980-1-nsaenzjulienne@suse.de> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190520_034740_424459_F0147EEF X-CRM114-Status: GOOD ( 13.05 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-arm-kernel@lists.infradead.org, ptesarik@suse.com, sboyd@kernel.org, viresh.kumar@linaro.org, mturquette@baylibre.com, linux-pm@vger.kernel.org, rjw@rjwysocki.net, linux-kernel@vger.kernel.org, Nicolas Saenz Julienne , linux-rpi-kernel@lists.infradead.org, linux-clk@vger.kernel.org, mbrugger@suse.de, ssuloev@orpaltech.com Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP This divisor is controlled by the firmware, we don't want the clock subsystem to update it inadvertently. Signed-off-by: Nicolas Saenz Julienne Acked-by: Stefan Wahren --- drivers/clk/bcm/clk-bcm2835.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index c2772dfb155a..5aea110672f3 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -465,6 +465,7 @@ struct bcm2835_pll_divider_data { u32 hold_mask; u32 fixed_divider; u32 flags; + u32 div_flags; }; struct bcm2835_clock_data { @@ -1349,7 +1350,7 @@ bcm2835_register_pll_divider(struct bcm2835_cprman *cprman, divider->div.reg = cprman->regs + data->a2w_reg; divider->div.shift = A2W_PLL_DIV_SHIFT; divider->div.width = A2W_PLL_DIV_BITS; - divider->div.flags = CLK_DIVIDER_MAX_AT_ZERO; + divider->div.flags = data->div_flags | CLK_DIVIDER_MAX_AT_ZERO; divider->div.lock = &cprman->regs_lock; divider->div.hw.init = &init; divider->div.table = NULL; @@ -1676,7 +1677,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { .load_mask = CM_PLLB_LOADARM, .hold_mask = CM_PLLB_HOLDARM, .fixed_divider = 1, - .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE), + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, + .div_flags = CLK_DIVIDER_READ_ONLY), /* * PLLC is the core PLL, used to drive the core VPU clock. From patchwork Mon May 20 10:47:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Saenz Julienne X-Patchwork-Id: 10950867 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9FC8E1390 for ; Mon, 20 May 2019 10:48:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8C2A4287C1 for ; Mon, 20 May 2019 10:48:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7CD80287C3; Mon, 20 May 2019 10:48:47 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id AEA3F287C1 for ; Mon, 20 May 2019 10:48:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Jsaa7IJJck4dSwwFib7cbHLCKAX6nYSFAp2K4kRz4VA=; b=VCVyziUz1/ugaA /4q451r9xnbofmWXxyvSjZle7hOAHDWQe36SpRf6+K2gd7LrnruRkYEHO/pJXOsKwcKmSdIdstWsh Gi3BaMtcV8y6S6U85drLBX9O/zG6EaDUtk8L8QwZPgaRqXvGV6viWum3I0WGnxWbHNYATtSWgRrpI ce/WAUuMG+1UdPfbwd04BFmc4zxK3ndNDkbLDZsF5F16R4mZwdSM1SgeTW4EleJJNdg0GaEuDKyb8 WsBv6WE6SwkVgq156AlKeQ/tlJE49z51NL0NR8n2qVqYkR5SSAP+BmEM8VHOkqUlT6/dAmqf8uv+h F5qsugoTgxoW4+LybS/w==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hSfqS-0001iD-Lg; Mon, 20 May 2019 10:48:40 +0000 Received: from mx2.suse.de ([195.135.220.15] helo=mx1.suse.de) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hSfpU-0000Ss-QI; Mon, 20 May 2019 10:47:44 +0000 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 040B5AFD4; Mon, 20 May 2019 10:47:38 +0000 (UTC) From: Nicolas Saenz Julienne To: stefan.wahren@i2se.com, Florian Fainelli , Ray Jui , Scott Branden , bcm-kernel-feedback-list@broadcom.com, Eric Anholt Subject: [RFC v2 3/5] clk: bcm2835: use firmware interface to update pllb Date: Mon, 20 May 2019 12:47:05 +0200 Message-Id: <20190520104708.11980-4-nsaenzjulienne@suse.de> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190520104708.11980-1-nsaenzjulienne@suse.de> References: <20190520104708.11980-1-nsaenzjulienne@suse.de> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190520_034741_154891_835F86F9 X-CRM114-Status: GOOD ( 23.69 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-arm-kernel@lists.infradead.org, ptesarik@suse.com, sboyd@kernel.org, viresh.kumar@linaro.org, mturquette@baylibre.com, linux-pm@vger.kernel.org, rjw@rjwysocki.net, linux-kernel@vger.kernel.org, Nicolas Saenz Julienne , linux-rpi-kernel@lists.infradead.org, linux-clk@vger.kernel.org, mbrugger@suse.de, ssuloev@orpaltech.com Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Raspberry Pi's firmware, which runs in a dedicated processor, keeps track of the board's temperature and voltage. It's resposible for scaling the CPU frequency whenever it deems the device reached an unsafe state. On top of that the firmware provides an interface which allows Linux to to query the clock's state or change it's frequency. Being the sole user of the bcm2835 clock driver, this integrates the firmware interface into the clock driver and adds a first user: the CPU pll, also known as 'pllb'. Signed-off-by: Nicolas Saenz Julienne --- drivers/clk/bcm/clk-bcm2835.c | 274 ++++++++++++++++++++++++++++++++-- 1 file changed, 259 insertions(+), 15 deletions(-) diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 5aea110672f3..ce5b16f3704e 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -35,6 +35,7 @@ #include #include #include +#include #define CM_PASSWORD 0x5a000000 @@ -289,6 +290,30 @@ #define LOCK_TIMEOUT_NS 100000000 #define BCM2835_MAX_FB_RATE 1750000000u +#define RPI_FIRMWARE_ARM_CLK_ID 0x000000003 +#define RPI_FIRMWARE_STATE_ENABLE_BIT 0x1 +#define RPI_FIRMWARE_STATE_WAIT_BIT 0x2 + +/* + * Structure of the message passed to Raspberry Pi's firmware in order to + * change clock rates. The 'disable_turbo' option is only available to the ARM + * clock (pllb) which we enable by default as turbo mode will alter multiple + * clocks at once. + * + * Even though we're able to access the clock registers directly we're bound to + * use the firmware interface as the firmware ultimately takes care of + * mitigating overheating/undervoltage situations and we would be changing + * frequencies behind his back. + * + * For more information on the firmware interface check: + * https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface + */ +struct bcm2835_firmware_prop { + u32 id; + u32 val; + u32 disable_turbo; +} __packed; + /* * Names of clocks used within the driver that need to be replaced * with an external parent's name. This array is in the order that @@ -316,6 +341,8 @@ struct bcm2835_cprman { */ const char *real_parent_names[ARRAY_SIZE(cprman_parent_names)]; + struct rpi_firmware *firmware; + /* Must be last */ struct clk_hw_onecell_data onecell; }; @@ -424,6 +451,23 @@ struct bcm2835_pll_data { unsigned long max_fb_rate; }; +struct bcm2835_fw_pll_data { + const char *name; + int firmware_clk_id; + u32 flags; + + unsigned long min_rate; + unsigned long max_rate; + + /* + * The rate provided to the firmware interface might not always match + * the clock subsystem's. For instance, in the case of the ARM cpu + * clock, even though the firmware ultimately edits 'pllb' it takes the + * expected 'pllb_arm' rate as it's input. + */ + unsigned int rate_rescale; +}; + struct bcm2835_pll_ana_bits { u32 mask0; u32 set0; @@ -505,6 +549,7 @@ struct bcm2835_pll { struct clk_hw hw; struct bcm2835_cprman *cprman; const struct bcm2835_pll_data *data; + const struct bcm2835_fw_pll_data *fw_data; }; static int bcm2835_pll_is_on(struct clk_hw *hw) @@ -517,6 +562,41 @@ static int bcm2835_pll_is_on(struct clk_hw *hw) A2W_PLL_CTRL_PRST_DISABLE; } +static int raspberrypi_clock_property(struct rpi_firmware *firmware, u32 tag, + u32 clk, u32 *val) +{ + int ret; + struct bcm2835_firmware_prop msg = { + .id = clk, + .val = *val, + .disable_turbo = 1, + }; + + ret = rpi_firmware_property(firmware, tag, &msg, sizeof(msg)); + if (ret) + return ret; + + *val = msg.val; + + return 0; +} + +static int bcm2835_fw_pll_is_on(struct clk_hw *hw) +{ + struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw); + struct bcm2835_cprman *cprman = pll->cprman; + u32 val = 0; + int ret; + + ret = raspberrypi_clock_property(cprman->firmware, + RPI_FIRMWARE_GET_CLOCK_STATE, + pll->fw_data->firmware_clk_id, &val); + if (ret) + return 0; + + return !!(val & RPI_FIRMWARE_STATE_ENABLE_BIT); +} + static void bcm2835_pll_choose_ndiv_and_fdiv(unsigned long rate, unsigned long parent_rate, u32 *ndiv, u32 *fdiv) @@ -547,16 +627,37 @@ static long bcm2835_pll_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate) { struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw); - const struct bcm2835_pll_data *data = pll->data; u32 ndiv, fdiv; - rate = clamp(rate, data->min_rate, data->max_rate); + if (pll->data) + rate = clamp(rate, pll->data->min_rate, pll->data->max_rate); + else + rate = clamp(rate, pll->fw_data->min_rate, + pll->fw_data->max_rate); bcm2835_pll_choose_ndiv_and_fdiv(rate, *parent_rate, &ndiv, &fdiv); return bcm2835_pll_rate_from_divisors(*parent_rate, ndiv, fdiv, 1); } +static unsigned long bcm2835_fw_pll_get_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw); + struct bcm2835_cprman *cprman = pll->cprman; + u32 val = 0; + int ret; + + ret = raspberrypi_clock_property(cprman->firmware, + RPI_FIRMWARE_GET_CLOCK_RATE, + pll->fw_data->firmware_clk_id, + &val); + if (ret) + return ret; + + return val * pll->fw_data->rate_rescale; +} + static unsigned long bcm2835_pll_get_rate(struct clk_hw *hw, unsigned long parent_rate) { @@ -584,6 +685,35 @@ static unsigned long bcm2835_pll_get_rate(struct clk_hw *hw, return bcm2835_pll_rate_from_divisors(parent_rate, ndiv, fdiv, pdiv); } +static int bcm2835_fw_pll_on(struct clk_hw *hw) +{ + struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw); + struct bcm2835_cprman *cprman = pll->cprman; + u32 val; + int ret; + + val = RPI_FIRMWARE_STATE_ENABLE_BIT | RPI_FIRMWARE_STATE_WAIT_BIT; + + ret = raspberrypi_clock_property(cprman->firmware, + RPI_FIRMWARE_SET_CLOCK_STATE, + pll->fw_data->firmware_clk_id, &val); + if (ret) + return ret; + + return 0; +} + +static void bcm2835_fw_pll_off(struct clk_hw *hw) +{ + struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw); + struct bcm2835_cprman *cprman = pll->cprman; + u32 val = RPI_FIRMWARE_STATE_WAIT_BIT; + + raspberrypi_clock_property(cprman->firmware, + RPI_FIRMWARE_SET_CLOCK_STATE, + pll->fw_data->firmware_clk_id, &val); +} + static void bcm2835_pll_off(struct clk_hw *hw) { struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw); @@ -651,6 +781,25 @@ bcm2835_pll_write_ana(struct bcm2835_cprman *cprman, u32 ana_reg_base, u32 *ana) cprman_write(cprman, ana_reg_base + i * 4, ana[i]); } +static int bcm2835_fw_pll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw); + u32 new_rate = rate / pll->fw_data->rate_rescale; + struct bcm2835_cprman *cprman = pll->cprman; + int ret; + + ret = raspberrypi_clock_property(cprman->firmware, + RPI_FIRMWARE_SET_CLOCK_RATE, + pll->fw_data->firmware_clk_id, + &new_rate); + if (ret) + dev_err(cprman->dev, "Failed to change %s frequency: %d", + clk_hw_get_name(hw), ret); + + return ret; +} + static int bcm2835_pll_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { @@ -759,6 +908,15 @@ static const struct clk_ops bcm2835_pll_clk_ops = { .debug_init = bcm2835_pll_debug_init, }; +static const struct clk_ops bcm2835_firmware_pll_clk_ops = { + .is_prepared = bcm2835_fw_pll_is_on, + .prepare = bcm2835_fw_pll_on, + .unprepare = bcm2835_fw_pll_off, + .recalc_rate = bcm2835_fw_pll_get_rate, + .set_rate = bcm2835_fw_pll_set_rate, + .round_rate = bcm2835_pll_round_rate, +}; + struct bcm2835_pll_divider { struct clk_divider div; struct bcm2835_cprman *cprman; @@ -1287,6 +1445,83 @@ static const struct clk_ops bcm2835_vpu_clock_clk_ops = { .debug_init = bcm2835_clock_debug_init, }; +static int bcm2835_firmware_get_min_max_rates(struct bcm2835_cprman *cprman, + struct bcm2835_fw_pll_data *data) +{ + u32 min_rate = 0, max_rate = 0; + int ret; + + ret = raspberrypi_clock_property(cprman->firmware, + RPI_FIRMWARE_GET_MIN_CLOCK_RATE, + data->firmware_clk_id, + &min_rate); + if (ret) { + dev_err(cprman->dev, "Failed to get %s min freq: %d\n", + data->name, ret); + return ret; + } + + ret = raspberrypi_clock_property(cprman->firmware, + RPI_FIRMWARE_GET_MAX_CLOCK_RATE, + data->firmware_clk_id, + &max_rate); + if (ret) { + dev_err(cprman->dev, "Failed to get %s max freq: %d\n", + data->name, ret); + return ret; + } + + data->min_rate = min_rate * data->rate_rescale; + data->max_rate = max_rate * data->rate_rescale; + + dev_info(cprman->dev, "min %lu, max %lu\n", data->min_rate, data->max_rate); + return 0; +} + +static struct clk_hw *bcm2835_register_fw_pll(struct bcm2835_cprman *cprman, + const struct bcm2835_fw_pll_data *data) +{ + struct bcm2835_fw_pll_data *fw_data; + struct clk_init_data init; + struct bcm2835_pll *pll; + int ret; + + memset(&init, 0, sizeof(init)); + + /* All of the PLLs derive from the external oscillator. */ + init.parent_names = &cprman->real_parent_names[0]; + init.num_parents = 1; + init.name = data->name; + init.ops = &bcm2835_firmware_pll_clk_ops; + init.flags = data->flags | CLK_IGNORE_UNUSED; + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) + return NULL; + + /* + * As the max and min rate values are firmware dependent we need a non + * constant version of struct bcm2835_fw_pll_data. + */ + fw_data = devm_kmemdup(cprman->dev, data, sizeof(*data), + GFP_KERNEL); + if (!fw_data) + return NULL; + + ret = bcm2835_firmware_get_min_max_rates(cprman, fw_data); + if (ret) + return NULL; + + pll->cprman = cprman; + pll->hw.init = &init; + pll->fw_data = fw_data; + + ret = devm_clk_hw_register(cprman->dev, &pll->hw); + if (ret) + return NULL; + return &pll->hw; +} + static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman, const struct bcm2835_pll_data *data) { @@ -1462,6 +1697,9 @@ struct bcm2835_clk_desc { #define REGISTER_PLL(...) _REGISTER(&bcm2835_register_pll, \ &(struct bcm2835_pll_data) \ {__VA_ARGS__}) +#define REGISTER_FW_PLL(...) _REGISTER(&bcm2835_register_fw_pll, \ + &(struct bcm2835_fw_pll_data) \ + {__VA_ARGS__}) #define REGISTER_PLL_DIV(...) _REGISTER(&bcm2835_register_pll_divider, \ &(struct bcm2835_pll_divider_data) \ {__VA_ARGS__}) @@ -1654,21 +1892,11 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { .flags = CLK_SET_RATE_PARENT), /* PLLB is used for the ARM's clock. */ - [BCM2835_PLLB] = REGISTER_PLL( + [BCM2835_PLLB] = REGISTER_FW_PLL( .name = "pllb", - .cm_ctrl_reg = CM_PLLB, - .a2w_ctrl_reg = A2W_PLLB_CTRL, - .frac_reg = A2W_PLLB_FRAC, - .ana_reg_base = A2W_PLLB_ANA0, - .reference_enable_mask = A2W_XOSC_CTRL_PLLB_ENABLE, - .lock_mask = CM_LOCK_FLOCKB, .flags = CLK_GET_RATE_NOCACHE, - - .ana = &bcm2835_ana_default, - - .min_rate = 600000000u, - .max_rate = 3000000000u, - .max_fb_rate = BCM2835_MAX_FB_RATE), + .rate_rescale = 2, + .firmware_clk_id = RPI_FIRMWARE_ARM_CLK_ID), [BCM2835_PLLB_ARM] = REGISTER_PLL_DIV( .name = "pllb_arm", .source_pll = "pllb", @@ -2133,9 +2361,24 @@ static int bcm2835_clk_probe(struct platform_device *pdev) struct resource *res; const struct bcm2835_clk_desc *desc; const size_t asize = ARRAY_SIZE(clk_desc_array); + struct device_node *firmware_node; + struct rpi_firmware *firmware; size_t i; int ret; + firmware_node = of_find_node_by_name(NULL, "firmware"); + if (!firmware_node) { + dev_err(dev, "Missing firmware node\n"); + return -ENOENT; + } + + firmware = rpi_firmware_get(firmware_node); + of_node_put(firmware_node); + if (!firmware) { + dev_err(dev, "Can't get raspberrypi's firmware\n"); + return -EPROBE_DEFER; + } + cprman = devm_kzalloc(dev, struct_size(cprman, onecell.hws, asize), GFP_KERNEL); @@ -2144,6 +2387,7 @@ static int bcm2835_clk_probe(struct platform_device *pdev) spin_lock_init(&cprman->regs_lock); cprman->dev = dev; + cprman->firmware = firmware; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); cprman->regs = devm_ioremap_resource(dev, res); if (IS_ERR(cprman->regs)) From patchwork Mon May 20 10:47:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Saenz Julienne X-Patchwork-Id: 10950839 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9B4171390 for ; Mon, 20 May 2019 10:47:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8B28F28696 for ; Mon, 20 May 2019 10:47:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7F247287C1; Mon, 20 May 2019 10:47:51 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 35EF228696 for ; Mon, 20 May 2019 10:47:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=EOdPHGbRRFm3mbA3UHxcWvVDjdQHI+AYe+uXY8FV9ZQ=; b=asSAWTKQDMMLCE pvcx6BcMQ72dIrs29DsYPEFrjD/LK6KuTjiUzVGC8+OfsBcDmDcF6AuiQcbiKpspaMcCBeo0Drc9g XdAFm3aCiU5dHtm3QJn+9cGChrURgfXBawtqIsZWNrufNhZ9sYPEhiBz2rs3+1iVPP+rXRWHttCXz kbybySMU1iZQ365zqjXMJm9ho5M0p+Xh1kiTRH+j6ftFC4xlP9JUDTUk5+t992ZdXJwYe/SmUr1an 3mGmKgpLZ5niiIqEAAICNC00i/iolPInP4sRkeMUvL2nI8edOcKNxP7UW+MoBylOaW7ai26JVhwqo YBDA5T2ZazrZejgVSezw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hSfpZ-0000bQ-ET; Mon, 20 May 2019 10:47:45 +0000 Received: from mx2.suse.de ([195.135.220.15] helo=mx1.suse.de) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hSfpU-0000Uc-N0; Mon, 20 May 2019 10:47:43 +0000 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 601ADAFD6; Mon, 20 May 2019 10:47:39 +0000 (UTC) From: Nicolas Saenz Julienne To: stefan.wahren@i2se.com, Rob Herring , Mark Rutland , Florian Fainelli , Ray Jui , Scott Branden , bcm-kernel-feedback-list@broadcom.com Subject: [RFC v2 4/5] dts: bcm2837: add per-cpu clock devices Date: Mon, 20 May 2019 12:47:06 +0200 Message-Id: <20190520104708.11980-5-nsaenzjulienne@suse.de> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190520104708.11980-1-nsaenzjulienne@suse.de> References: <20190520104708.11980-1-nsaenzjulienne@suse.de> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190520_034740_905970_0DAB40BA X-CRM114-Status: GOOD ( 10.31 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, ptesarik@suse.com, sboyd@kernel.org, viresh.kumar@linaro.org, mturquette@baylibre.com, linux-pm@vger.kernel.org, rjw@rjwysocki.net, linux-kernel@vger.kernel.org, eric@anholt.net, linux-rpi-kernel@lists.infradead.org, Nicolas Saenz Julienne , linux-clk@vger.kernel.org, mbrugger@suse.de, ssuloev@orpaltech.com Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP The four CPUs share a same clock source called pllb_arm. The clock can be scaled through the raspberrypi firmware interface. Signed-off-by: Nicolas Saenz Julienne --- arch/arm/boot/dts/bcm2837.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm/boot/dts/bcm2837.dtsi b/arch/arm/boot/dts/bcm2837.dtsi index beb6c502dadc..a8fea6696b42 100644 --- a/arch/arm/boot/dts/bcm2837.dtsi +++ b/arch/arm/boot/dts/bcm2837.dtsi @@ -44,6 +44,8 @@ reg = <0>; enable-method = "spin-table"; cpu-release-addr = <0x0 0x000000d8>; + clocks = <&clocks BCM2835_PLLB_ARM>; + clock-names = "pllb_arm"; }; cpu1: cpu@1 { @@ -52,6 +54,8 @@ reg = <1>; enable-method = "spin-table"; cpu-release-addr = <0x0 0x000000e0>; + clocks = <&clocks BCM2835_PLLB_ARM>; + clock-names = "pllb_arm"; }; cpu2: cpu@2 { @@ -60,6 +64,8 @@ reg = <2>; enable-method = "spin-table"; cpu-release-addr = <0x0 0x000000e8>; + clocks = <&clocks BCM2835_PLLB_ARM>; + clock-names = "pllb_arm"; }; cpu3: cpu@3 { @@ -68,6 +74,8 @@ reg = <3>; enable-method = "spin-table"; cpu-release-addr = <0x0 0x000000f0>; + clocks = <&clocks BCM2835_PLLB_ARM>; + clock-names = "pllb_arm"; }; }; }; From patchwork Mon May 20 10:47:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Saenz Julienne X-Patchwork-Id: 10950863 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 62B5B6C5 for ; Mon, 20 May 2019 10:48:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4FDC728696 for ; Mon, 20 May 2019 10:48:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4398B287C1; Mon, 20 May 2019 10:48:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D0CD228696 for ; Mon, 20 May 2019 10:48:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=eh77ocaw6plrOjh96IKAaKW+h+pkhVWC5r17wbPgiKc=; b=E+11Xc5VyuHkOK KNvEiag9Qd+TXRVhl4pmvAHIfF2kTVyp7TPVTYLRi+yOU1KfGqwXeZMT4tM/I+5f9irpRnfE6YnRW HcJA2DsLU53PnP6GCnY00UZGu012z5ZqB9/ygJrC0HmLVgHVsqJQ1/s6gYHQEAC3H6j4vNSK4IEI5 TeatkFa/7pXAvsH3cBmNzrpcz/s1fnzdZmrd5bBiyRqxCjg28iEruBnA0HWlSIGhhzcREErIjost7 kH9caXSy8nrKD43aXK8Pv8nyFKdtCDdWdDhQxKFQ9khH514WmpToAZ8rsGcFL+kxDptYd5F26Vz/W PIEg1jQf0t1s/JZhssMQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hSfqD-0001NE-4W; Mon, 20 May 2019 10:48:25 +0000 Received: from mx2.suse.de ([195.135.220.15] helo=mx1.suse.de) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hSfpY-0000Zp-A9; Mon, 20 May 2019 10:47:46 +0000 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id B410AAFDD; Mon, 20 May 2019 10:47:40 +0000 (UTC) From: Nicolas Saenz Julienne To: stefan.wahren@i2se.com, "Rafael J. Wysocki" , Viresh Kumar Subject: [RFC v2 5/5] cpufreq: add driver for Raspbery Pi Date: Mon, 20 May 2019 12:47:07 +0200 Message-Id: <20190520104708.11980-6-nsaenzjulienne@suse.de> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190520104708.11980-1-nsaenzjulienne@suse.de> References: <20190520104708.11980-1-nsaenzjulienne@suse.de> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190520_034744_646126_3F81186C X-CRM114-Status: GOOD ( 15.99 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-arm-kernel@lists.infradead.org, f.fainelli@gmail.com, ptesarik@suse.com, sboyd@kernel.org, mturquette@baylibre.com, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, eric@anholt.net, bcm-kernel-feedback-list@broadcom.com, linux-rpi-kernel@lists.infradead.org, Nicolas Saenz Julienne , linux-clk@vger.kernel.org, mbrugger@suse.de, ssuloev@orpaltech.com Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Raspberry Pi's firmware offers and interface though which update it's performance requirements. It allows us to request for specific runtime frequencies, which the firmware might or might not respect, depending on the firmware configuration and thermals. As the maximum and minimum frequencies are configurable in the firmware there is no way to know in advance their values. So the Raspberry Pi cpufreq driver queries them, builds an opp frequency table to then launch cpufreq-dt. Signed-off-by: Nicolas Saenz Julienne --- drivers/cpufreq/Kconfig.arm | 8 +++ drivers/cpufreq/Makefile | 1 + drivers/cpufreq/raspberrypi-cpufreq.c | 83 +++++++++++++++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 drivers/cpufreq/raspberrypi-cpufreq.c diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index 179a1d302f48..f6eba7ae50d0 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm @@ -308,3 +308,11 @@ config ARM_PXA2xx_CPUFREQ This add the CPUFreq driver support for Intel PXA2xx SOCs. If in doubt, say N. + +config ARM_RASPBERRYPI_CPUFREQ + tristate "Raspberry Pi cpufreq support" + depends on RASPBERRYPI_FIRMWARE || COMPILE_TEST + help + This adds the CPUFreq driver for Raspberry Pi + + If in doubt, say N. diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index 689b26c6f949..02678e9b2ff5 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile @@ -84,6 +84,7 @@ obj-$(CONFIG_ARM_TEGRA124_CPUFREQ) += tegra124-cpufreq.o obj-$(CONFIG_ARM_TEGRA186_CPUFREQ) += tegra186-cpufreq.o obj-$(CONFIG_ARM_TI_CPUFREQ) += ti-cpufreq.o obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ) += vexpress-spc-cpufreq.o +obj-$(CONFIG_ARM_RASPBERRYPI_CPUFREQ) += raspberrypi-cpufreq.o ################################################################################## diff --git a/drivers/cpufreq/raspberrypi-cpufreq.c b/drivers/cpufreq/raspberrypi-cpufreq.c new file mode 100644 index 000000000000..a85988867d56 --- /dev/null +++ b/drivers/cpufreq/raspberrypi-cpufreq.c @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Raspberry Pi cpufreq driver + * + * Copyright (C) 2019, Nicolas Saenz Julienne + */ + +#include +#include +#include +#include +#include +#include +#include + +static const struct of_device_id machines[] __initconst = { + { .compatible = "raspberrypi,3-model-b-plus" }, + { .compatible = "raspberrypi,3-model-b" }, + { /* sentinel */ } +}; + +static int __init raspberrypi_cpufreq_driver_init(void) +{ + struct platform_device *pdev; + struct device *cpu_dev; + struct clk *clk; + long min, max; + long rate; + int ret; + + if (!of_match_node(machines, of_root)) + return -ENODEV; + + cpu_dev = get_cpu_device(0); + if (!cpu_dev) { + pr_err("Cannot get CPU for cpufreq driver\n"); + return -ENODEV; + } + + clk = clk_get(cpu_dev, 0); + if (IS_ERR(clk)) { + dev_err(cpu_dev, "Cannot get clock for CPU0\n"); + return PTR_ERR(clk); + } + + /* + * The max and min frequencies are configurable in the Raspberry Pi + * firmware, so we query them at runtime + */ + min = clk_round_rate(clk, 0); + max = clk_round_rate(clk, ULONG_MAX); + clk_put(clk); + + for (rate = min; rate < max; rate += 100000000) { + ret = dev_pm_opp_add(cpu_dev, rate, 0); + if (ret) + goto remove_opp; + } + + ret = dev_pm_opp_add(cpu_dev, max, 0); + if (ret) + goto remove_opp; + + pdev = platform_device_register_data(NULL, "cpufreq-dt", -1, NULL, 0); + ret = PTR_ERR_OR_ZERO(pdev); + if (ret) { + dev_err(cpu_dev, "Failed to create platform device, %d\n", ret); + goto remove_opp; + } + + return 0; + +remove_opp: + dev_pm_opp_remove_all_dynamic(cpu_dev); + + return ret; +} + +late_initcall(raspberrypi_cpufreq_driver_init); + +MODULE_AUTHOR("Nicolas Saenz Julienne