From patchwork Tue Jun 4 17:32:20 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: 10975841 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 E1BF014B6 for ; Tue, 4 Jun 2019 17:34:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CADFA287ED for ; Tue, 4 Jun 2019 17:34:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BEC69287F3; Tue, 4 Jun 2019 17:34:04 +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 6F225287ED for ; Tue, 4 Jun 2019 17:34:04 +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=FzxZWLkAUXPVDEPgvamBWnSCQkmpk6DoP7Kg6LiOK+4=; b=n7BRLdqJ6DTMAk BJdB3SJChtEbX7btHoMNm87Cs84aSiprJsQjkx0IURKlRUqdOYXEXs+U3DMtml8+XdW+ucvEfc7Q4 wpxcyRMVrigNF4UeOXZnjcfG1f/MgpEbspGi1MPzXJhXeAM9xvZMm+2iFEd4hfqrZl1bl1+o4nQRw duLNexdH3IGxexrIV8f41zhMnkBu3I8aO6hFNKrNvUZAQx1FXZ3VlGrdLQvMb4BjIh+o5WvWu1fPN NJX2hZ14+sq4Mi6vo+euJUV6cPIw4yqPFF4xTKZeug3r+0Kzy3kuoJHPS/373j5tQhXdFGJQrl9l/ SSt6om7yJ+Hd9dlnNvYw==; 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 1hYDJv-0001tW-Fy; Tue, 04 Jun 2019 17:33:59 +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 1hYDJr-0001o5-Cw; Tue, 04 Jun 2019 17:33:57 +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 11759AE03; Tue, 4 Jun 2019 17:33:54 +0000 (UTC) From: Nicolas Saenz Julienne To: stefan.wahren@i2se.com, Eric Anholt , Florian Fainelli , Ray Jui , Scott Branden , bcm-kernel-feedback-list@broadcom.com Subject: [PATCH 1/4] clk: bcm2835: remove pllb Date: Tue, 4 Jun 2019 19:32:20 +0200 Message-Id: <20190604173223.4229-2-nsaenzjulienne@suse.de> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190604173223.4229-1-nsaenzjulienne@suse.de> References: <20190604173223.4229-1-nsaenzjulienne@suse.de> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190604_103355_818987_1C2D9361 X-CRM114-Status: GOOD ( 11.60 ) 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 controls this pll, we should use the firmware interface to access it. Signed-off-by: Nicolas Saenz Julienne Acked-by: Eric Anholt --- drivers/clk/bcm/clk-bcm2835.c | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 770bb01f523e..ccb0319fc2e9 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -1651,31 +1651,6 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { .fixed_divider = 1, .flags = CLK_SET_RATE_PARENT), - /* PLLB is used for the ARM's clock. */ - [BCM2835_PLLB] = REGISTER_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, - - .ana = &bcm2835_ana_default, - - .min_rate = 600000000u, - .max_rate = 3000000000u, - .max_fb_rate = BCM2835_MAX_FB_RATE), - [BCM2835_PLLB_ARM] = REGISTER_PLL_DIV( - .name = "pllb_arm", - .source_pll = "pllb", - .cm_reg = CM_PLLB, - .a2w_reg = A2W_PLLB_ARM, - .load_mask = CM_PLLB_LOADARM, - .hold_mask = CM_PLLB_HOLDARM, - .fixed_divider = 1, - .flags = CLK_SET_RATE_PARENT), - /* * PLLC is the core PLL, used to drive the core VPU clock. * From patchwork Tue Jun 4 17:32:22 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: 10975851 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 331662D47 for ; Tue, 4 Jun 2019 17:36:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1D3AA28610 for ; Tue, 4 Jun 2019 17:36:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 115BC284F1; Tue, 4 Jun 2019 17:36: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=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 5DED628415 for ; Tue, 4 Jun 2019 17:36:56 +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=HCk+nMG5d41/y8pBtG+4Gn5UUbdr7fp5cGV2bCuvI5M=; b=P5pkAmqYIDSovC BDLKGbWhZ6Dxolqy7YRp4g9jkhQh6Q5iC24IgWDlmG+U6Op4fCilsxoTsYOA7xnIFJ6F85fPvxhZM e04PoX3rHggPCzam+opDyNQLKYK/IdvEzE9i8pQdFaUsEigv4wOa7DNc+eLO0MeD41RLx4SJhtY0K GmJKAdhkJI7W8l12lR85NINP5+UAtyh70ph5QxfkIc7yeQwG8WjoztDGShiY/Jo9G9D8DtvNs8wgj y1yY5jb2TtW+n9BD7zJfKLIBJ/8C++Ad0zdD36+RyHEGkUttexZxnoW2sJ2jm8KoNs7r/cleYgcu9 MUkBUMR/ppGe1X0FdBzQ==; 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 1hYDMi-0004oF-M8; Tue, 04 Jun 2019 17:36:52 +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 1hYDMd-0004nO-Rp; Tue, 04 Jun 2019 17:36:50 +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 901AFAE03; Tue, 4 Jun 2019 17:36:46 +0000 (UTC) From: Nicolas Saenz Julienne To: stefan.wahren@i2se.com, linux-kernel@vger.kernel.org Subject: [PATCH 2/4] clk: bcm283x: add driver interfacing with Raspberry Pi's firmware Date: Tue, 4 Jun 2019 19:32:22 +0200 Message-Id: <20190604173223.4229-3-nsaenzjulienne@suse.de> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190604173223.4229-1-nsaenzjulienne@suse.de> References: <20190604173223.4229-1-nsaenzjulienne@suse.de> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190604_103648_193750_4CEE0343 X-CRM114-Status: GOOD ( 19.36 ) 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, viresh.kumar@linaro.org, mturquette@baylibre.com, linux-pm@vger.kernel.org, rjw@rjwysocki.net, 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 clock's frequencies. This is specially useful in order to change the CPU clock (pllb_arm) which is 'owned' by the firmware and we're unable to scale using the register interface. Signed-off-by: Nicolas Saenz Julienne --- Changes since RFC: - Moved firmware interface into own driver - Use of_find_compatible_node() - Remove error message on rpi_firmware_get() failure - Ratelimit messages on set_rate() failure - Use __le32 on firmware interface definition drivers/clk/bcm/Makefile | 1 + drivers/clk/bcm/clk-raspberrypi.c | 316 ++++++++++++++++++++++++++++++ 2 files changed, 317 insertions(+) create mode 100644 drivers/clk/bcm/clk-raspberrypi.c diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile index 002661d39128..07abe92df9d1 100644 --- a/drivers/clk/bcm/Makefile +++ b/drivers/clk/bcm/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835-aux.o +obj-$(CONFIG_ARCH_BCM2835) += clk-raspberrypi.o obj-$(CONFIG_ARCH_BCM_53573) += clk-bcm53573-ilp.o obj-$(CONFIG_CLK_BCM_CYGNUS) += clk-cygnus.o obj-$(CONFIG_CLK_BCM_HR2) += clk-hr2.o diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c new file mode 100644 index 000000000000..485c00288414 --- /dev/null +++ b/drivers/clk/bcm/clk-raspberrypi.c @@ -0,0 +1,316 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 Nicolas Saenz Julienne + */ + +#include +#include +#include +#include +#include + +#include + +#define RPI_FIRMWARE_ARM_CLK_ID 0x000000003 + +#define RPI_FIRMWARE_STATE_ENABLE_BIT 0x1 +#define RPI_FIRMWARE_STATE_WAIT_BIT 0x2 + +/* + * Even though the firmware interface alters 'pllb' the frequencies are + * provided as per 'pllb_arm'. We need to scale before passing them trough. + */ +#define RPI_FIRMWARE_PLLB_ARM_DIV_RATE 2 + +#define A2W_PLL_FRAC_BITS 20 + +struct raspberrypi_clk { + struct device *dev; + struct rpi_firmware *firmware; + + unsigned long min_rate; + unsigned long max_rate; + + struct clk_hw pllb; + struct clk_hw *pllb_arm; + struct clk_lookup *pllb_arm_lookup; +}; + +/* + * 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 raspberrypi_firmware_prop { + __le32 id; + __le32 val; + __le32 disable_turbo; +} __packed; + +static int raspberrypi_clock_property(struct rpi_firmware *firmware, u32 tag, + u32 clk, u32 *val) +{ + struct raspberrypi_firmware_prop msg = { + .id = clk, + .val = *val, + .disable_turbo = 1, + }; + int ret; + + ret = rpi_firmware_property(firmware, tag, &msg, sizeof(msg)); + if (ret) + return ret; + + *val = msg.val; + + return 0; +} + +static int raspberrypi_fw_pll_is_on(struct clk_hw *hw) +{ + struct raspberrypi_clk *rpi = container_of(hw, struct raspberrypi_clk, + pllb); + u32 val = 0; + int ret; + + ret = raspberrypi_clock_property(rpi->firmware, + RPI_FIRMWARE_GET_CLOCK_STATE, + RPI_FIRMWARE_ARM_CLK_ID, &val); + if (ret) + return 0; + + return !!(val & RPI_FIRMWARE_STATE_ENABLE_BIT); +} + + +static unsigned long raspberrypi_fw_pll_get_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct raspberrypi_clk *rpi = container_of(hw, struct raspberrypi_clk, + pllb); + u32 val = 0; + int ret; + + ret = raspberrypi_clock_property(rpi->firmware, + RPI_FIRMWARE_GET_CLOCK_RATE, + RPI_FIRMWARE_ARM_CLK_ID, + &val); + if (ret) + return ret; + + return val * RPI_FIRMWARE_PLLB_ARM_DIV_RATE; +} + +static int raspberrypi_fw_pll_on(struct clk_hw *hw) +{ + struct raspberrypi_clk *rpi = container_of(hw, struct raspberrypi_clk, + pllb); + u32 val; + int ret; + + val = RPI_FIRMWARE_STATE_ENABLE_BIT | RPI_FIRMWARE_STATE_WAIT_BIT; + + ret = raspberrypi_clock_property(rpi->firmware, + RPI_FIRMWARE_SET_CLOCK_STATE, + RPI_FIRMWARE_ARM_CLK_ID, &val); + if (ret) + return ret; + + return 0; +} + +static int raspberrypi_fw_pll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct raspberrypi_clk *rpi = container_of(hw, struct raspberrypi_clk, + pllb); + u32 new_rate = rate / RPI_FIRMWARE_PLLB_ARM_DIV_RATE; + int ret; + + ret = raspberrypi_clock_property(rpi->firmware, + RPI_FIRMWARE_SET_CLOCK_RATE, + RPI_FIRMWARE_ARM_CLK_ID, + &new_rate); + if (ret) + dev_err_ratelimited(rpi->dev, "Failed to change %s frequency: %d", + clk_hw_get_name(hw), ret); + + return ret; +} + +/* + * Sadly there is no firmware rate rounding interface. We borred it from + * clk-bcm2835. + */ +static long raspberrypi_pll_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + struct raspberrypi_clk *rpi = container_of(hw, struct raspberrypi_clk, + pllb); + u64 div, final_rate; + u32 ndiv, fdiv; + + rate = clamp(rate, rpi->min_rate, rpi->max_rate); + + div = (u64)rate << A2W_PLL_FRAC_BITS; + do_div(div, *parent_rate); + + ndiv = div >> A2W_PLL_FRAC_BITS; + fdiv = div & ((1 << A2W_PLL_FRAC_BITS) - 1); + + /* We can't use rate directly as it would overflow */ + final_rate = ((u64)*parent_rate * ((ndiv << A2W_PLL_FRAC_BITS) + fdiv)); + + return final_rate >> A2W_PLL_FRAC_BITS; +} + +static void raspberrypi_fw_pll_off(struct clk_hw *hw) +{ + struct raspberrypi_clk *rpi = container_of(hw, struct raspberrypi_clk, + pllb); + u32 val = RPI_FIRMWARE_STATE_WAIT_BIT; + + raspberrypi_clock_property(rpi->firmware, + RPI_FIRMWARE_SET_CLOCK_STATE, + RPI_FIRMWARE_ARM_CLK_ID, &val); +} + +static const struct clk_ops raspberrypi_firmware_pll_clk_ops = { + .is_prepared = raspberrypi_fw_pll_is_on, + .prepare = raspberrypi_fw_pll_on, + .unprepare = raspberrypi_fw_pll_off, + .recalc_rate = raspberrypi_fw_pll_get_rate, + .set_rate = raspberrypi_fw_pll_set_rate, + .round_rate = raspberrypi_pll_round_rate, +}; + +static int raspberrypi_register_pllb(struct raspberrypi_clk *rpi) +{ + u32 min_rate = 0, max_rate = 0; + struct clk_init_data init; + int ret; + + /* Get min & max rates set by the firmware */ + ret = raspberrypi_clock_property(rpi->firmware, + RPI_FIRMWARE_GET_MIN_CLOCK_RATE, + RPI_FIRMWARE_ARM_CLK_ID, + &min_rate); + if (ret) { + dev_err(rpi->dev, "Failed to get %s min freq: %d\n", + init.name, ret); + return ret; + } + + ret = raspberrypi_clock_property(rpi->firmware, + RPI_FIRMWARE_GET_MAX_CLOCK_RATE, + RPI_FIRMWARE_ARM_CLK_ID, + &max_rate); + if (ret) { + dev_err(rpi->dev, "Failed to get %s max freq: %d\n", + init.name, ret); + return ret; + } + + dev_info(rpi->dev, "CPU frequency range: min %u, max %u\n", + min_rate, max_rate); + + rpi->min_rate = min_rate * RPI_FIRMWARE_PLLB_ARM_DIV_RATE; + rpi->max_rate = max_rate * RPI_FIRMWARE_PLLB_ARM_DIV_RATE; + + memset(&init, 0, sizeof(init)); + + /* All of the PLLs derive from the external oscillator. */ + init.parent_names = (const char *[]){ "osc" }; + init.num_parents = 1; + init.name = "pllb"; + init.ops = &raspberrypi_firmware_pll_clk_ops; + init.flags = CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED; + + rpi->pllb.init = &init; + + return devm_clk_hw_register(rpi->dev, &rpi->pllb); +} + +static int raspberrypi_register_pllb_arm(struct raspberrypi_clk *rpi) +{ + rpi->pllb_arm = clk_hw_register_fixed_factor(rpi->dev, + "pllb_arm", "pllb", + CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, + 1, 2); + if (IS_ERR(rpi->pllb_arm)) { + dev_err(rpi->dev, "Failed to initialize pllb_arm\n"); + return PTR_ERR(rpi->pllb_arm); + } + + rpi->pllb_arm_lookup = clkdev_hw_create(rpi->pllb_arm, NULL, "cpu0"); + if (!rpi->pllb_arm_lookup) { + dev_err(rpi->dev, "Failed to initialize pllb_arm_lookup\n"); + clk_hw_unregister_fixed_factor(rpi->pllb_arm); + return -ENOMEM; + } + + return 0; +} + +static int raspberrypi_clk_probe(struct platform_device *pdev) +{ + struct device_node *firmware_node; + struct device *dev = &pdev->dev; + struct rpi_firmware *firmware; + struct raspberrypi_clk *rpi; + int ret; + + firmware_node = of_find_compatible_node(NULL, NULL, + "raspberrypi,bcm2835-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) + return -EPROBE_DEFER; + + rpi = devm_kzalloc(dev, sizeof(*rpi), GFP_KERNEL); + if (!rpi) + return -ENOMEM; + + rpi->dev = dev; + rpi->firmware = firmware; + + ret = raspberrypi_register_pllb(rpi); + if (ret) { + dev_err(dev, "Failed to initialize pllb, %d\n", ret); + return ret; + } + + ret = raspberrypi_register_pllb_arm(rpi); + if (ret) { + dev_err(dev, "Failed to initialize pllb_arm, %d\n", ret); + return ret; + } + + return 0; +} + +static struct platform_driver raspberrypi_clk_driver = { + .driver = { + .name = "raspberrypi-clk", + }, + .probe = raspberrypi_clk_probe, +}; +builtin_platform_driver(raspberrypi_clk_driver); + +MODULE_AUTHOR("Nicolas Saenz Julienne "); +MODULE_DESCRIPTION("Raspberry Pi firmware clock driver"); +MODULE_LICENSE("GPLv2"); From patchwork Tue Jun 4 17:32:23 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: 10975853 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 CF09617D2 for ; Tue, 4 Jun 2019 17:37:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B9D3828415 for ; Tue, 4 Jun 2019 17:37:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id ADED2284F1; Tue, 4 Jun 2019 17:37:02 +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 5D96928415 for ; Tue, 4 Jun 2019 17:37:02 +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=VW6Wvl4L7GtzMFnX2pU49sdROWh+v7/NsIi5RFHIQgk=; b=iB/QEEharimTVz 70rAmXB2MZX+r+rNVjItC62ZgmsgyJ4tVWCEN0bJy+CX1vtUBXVg9bh9GrKFqfjBRae2peSSeNZ2Y LS7+fnLfMOSePWcW3p0JggcdkgLXe1DGUIp7sgXJqbxx5gFBVPJKKgzV80gXmh/f61G4HAYaQRMDc 0YfA3LY3QL2hyGSbbSJ/YgubBYG7DizcR6XsHnB/k+kFJSSnYOzSG4vex4kBzMqc8uL2A5Yl3ooAl Ox1akkwB6YlpVzFtYYbzzdWoxvfv+Dvq40TQQIfm0zLx5nP+P+2gvs99SNV0YcLW7fLD30CLpLQM2 qpqzwDMz90vO7nDihbpw==; 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 1hYDMr-00050R-6R; Tue, 04 Jun 2019 17:37:01 +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 1hYDMm-0004sY-47; Tue, 04 Jun 2019 17:36:58 +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 C4F50AE03; Tue, 4 Jun 2019 17:36:54 +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: [PATCH 3/4] clk: bcm2835: register Raspberry Pi's firmware clk device Date: Tue, 4 Jun 2019 19:32:23 +0200 Message-Id: <20190604173223.4229-4-nsaenzjulienne@suse.de> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190604173223.4229-1-nsaenzjulienne@suse.de> References: <20190604173223.4229-1-nsaenzjulienne@suse.de> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190604_103656_835360_14B38479 X-CRM114-Status: GOOD ( 13.25 ) 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 Registers clk-raspberrypi as a platform device as part of the driver's probe sequence. Signed-off-by: Nicolas Saenz Julienne --- drivers/clk/bcm/clk-bcm2835.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index ccb0319fc2e9..6f370e6bafed 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -2098,6 +2098,7 @@ static int bcm2835_mark_sdc_parent_critical(struct clk *sdc) static int bcm2835_clk_probe(struct platform_device *pdev) { + struct platform_device *rpi_fw_clk; struct device *dev = &pdev->dev; struct clk_hw **hws; struct bcm2835_cprman *cprman; @@ -2150,8 +2151,18 @@ static int bcm2835_clk_probe(struct platform_device *pdev) if (ret) return ret; - return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, - &cprman->onecell); + ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, + &cprman->onecell); + if (ret) + return ret; + + rpi_fw_clk = platform_device_register_data(NULL, "raspberrypi-clk", -1, + NULL, 0); + ret = PTR_ERR_OR_ZERO(rpi_fw_clk); + if (ret) + dev_err(dev, "Failed to create platform device, %d\n", ret); + + return ret; } static const struct of_device_id bcm2835_clk_of_match[] = { From patchwork Tue Jun 4 17:32:25 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: 10975863 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 3942017D2 for ; Tue, 4 Jun 2019 17:40:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2593927CEA for ; Tue, 4 Jun 2019 17:40:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1954528433; Tue, 4 Jun 2019 17:40:19 +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 A601B27CEA for ; Tue, 4 Jun 2019 17:40:18 +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=J/DJoe8mtQ5uk0aX1NMah1qAUxBwr/lzzqRDd9LuVp8=; b=V0U7jXpN47gNs2 kjrsWGCvvnkiJ/1d2JCf7hSZZPEBbn5jGPgvfOjiXVZkvlJvNOF3cyhei/6/yd2rTTkiog2AdnMlY X+n5YAjORD8oU3qyKHwdz7PcRv/IyTMeXUA0w3x/wrYho6wP+ps4TIMmAp4/x4d07+f3s5vsQTmiv BIR3ouqWsmiCv/Mc4BvsL2eGu5qNfBzh0XVUFOdTr+m3W96A1vxDIWXVXEltkht00ERGPGhoTALw/ guetuIu71BM1IiCgZBSECxe8yQhKQe6npwCDShOcXfFFltQyJQBfvDNCAy3w9xqypSPPNdm4seeTq 7Z+8eR3eOx/k1Az5zKhQ==; 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 1hYDPy-0006va-N0; Tue, 04 Jun 2019 17:40:14 +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 1hYDPv-0006v7-QC; Tue, 04 Jun 2019 17:40:13 +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 72B2CAE05; Tue, 4 Jun 2019 17:40:10 +0000 (UTC) From: Nicolas Saenz Julienne To: stefan.wahren@i2se.com, "Rafael J. Wysocki" , Viresh Kumar Subject: [PATCH 4/4] cpufreq: add driver for Raspbery Pi Date: Tue, 4 Jun 2019 19:32:25 +0200 Message-Id: <20190604173223.4229-5-nsaenzjulienne@suse.de> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190604173223.4229-1-nsaenzjulienne@suse.de> References: <20190604173223.4229-1-nsaenzjulienne@suse.de> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190604_104012_152387_D9BF35E0 X-CRM114-Status: GOOD ( 16.90 ) 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 --- Changes since RFC: - Alphabetically ordered relevant stuff - Updated Kconfig to select firmware interface - Correctly unref clk_dev after use - Remove all opps on failure - Remove use of dev_pm_opp_set_sharing_cpus() drivers/cpufreq/Kconfig.arm | 8 +++ drivers/cpufreq/Makefile | 1 + drivers/cpufreq/raspberrypi-cpufreq.c | 84 +++++++++++++++++++++++++++ 3 files changed, 93 insertions(+) create mode 100644 drivers/cpufreq/raspberrypi-cpufreq.c diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index f8129edc145e..556d432cc826 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm @@ -133,6 +133,14 @@ config ARM_QCOM_CPUFREQ_HW The driver implements the cpufreq interface for this HW engine. Say Y if you want to support CPUFreq HW. +config ARM_RASPBERRYPI_CPUFREQ + tristate "Raspberry Pi cpufreq support" + select RASPBERRYPI_FIRMWARE + help + This adds the CPUFreq driver for Raspberry Pi + + If in doubt, say N. + config ARM_S3C_CPUFREQ bool help diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index 689b26c6f949..121c1acb66c0 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile @@ -64,6 +64,7 @@ obj-$(CONFIG_ARM_PXA2xx_CPUFREQ) += pxa2xx-cpufreq.o obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o obj-$(CONFIG_ARM_QCOM_CPUFREQ_HW) += qcom-cpufreq-hw.o obj-$(CONFIG_ARM_QCOM_CPUFREQ_KRYO) += qcom-cpufreq-kryo.o +obj-$(CONFIG_ARM_RASPBERRYPI_CPUFREQ) += raspberrypi-cpufreq.o obj-$(CONFIG_ARM_S3C2410_CPUFREQ) += s3c2410-cpufreq.o obj-$(CONFIG_ARM_S3C2412_CPUFREQ) += s3c2412-cpufreq.o obj-$(CONFIG_ARM_S3C2416_CPUFREQ) += s3c2416-cpufreq.o diff --git a/drivers/cpufreq/raspberrypi-cpufreq.c b/drivers/cpufreq/raspberrypi-cpufreq.c new file mode 100644 index 000000000000..2b3a195a9d37 --- /dev/null +++ b/drivers/cpufreq/raspberrypi-cpufreq.c @@ -0,0 +1,84 @@ +// 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" }, + { .compatible = "raspberrypi,2-model-b" }, + { /* sentinel */ } +}; + +static int __init raspberrypi_cpufreq_driver_init(void) +{ + struct platform_device *pdev; + struct device *cpu_dev; + unsigned long min, max; + unsigned long rate; + struct clk *clk; + 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