From patchwork Mon Feb 24 09:06:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 11399687 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id ADBE292A for ; Mon, 24 Feb 2020 09:19:18 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8406B20828 for ; Mon, 24 Feb 2020 09:19:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="bJSSx19o"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=cerno.tech header.i=@cerno.tech header.b="g5yDTxoj"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="Srvnlj1K" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8406B20828 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=cerno.tech Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org 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=AUMP+W4zcT1NQfjtR+NcCJOE7Og8YFAZqg4jikfMSjo=; b=bJSSx19ooH4e9e QLMBs8gDizlAkOUJI4wCSlze7JMavNVNztsvLKlvKbwHAZDCLIjeOwohV082/uqiFh2GcjLgnjzCY eWo5IUXlMjTt1AquEpBo9OGtBRSScY3GQUWW02FkgJ4irf+Gxt0Y9zjyE1OnOYgv2/JFKqdwZxr3x XKpsYuLhxU2HFeif3SclQsXKLoEBp34kMFCrcawiByoU59SHfkQ/Cd+qepd6cVpm0v9tL98bF/xHG UyihmIiC40MjcBUkl/sJCS0LpGGMkihAyCVON2UzHAqvbrB006j+eLCOx0dp2bGoWbsmEJnGnBTJE CEmfKoWE4OgIBdij0CHQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1j69tU-00025M-Ru; Mon, 24 Feb 2020 09:19:16 +0000 Received: from wnew3-smtp.messagingengine.com ([64.147.123.17]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1j69jw-0001fQ-G2; Mon, 24 Feb 2020 09:09:28 +0000 Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailnew.west.internal (Postfix) with ESMTP id C34CF60E; Mon, 24 Feb 2020 04:09:21 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute3.internal (MEProxy); Mon, 24 Feb 2020 04:09:22 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cerno.tech; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm2; bh=DwriZRHRN7fN7 mhHrJdEKvtb3nQZcEd0mgRQMVSwm/Y=; b=g5yDTxoj8S6kyr6YkHEMf6zhkqMYw X/hsZAJnTYpW/02DOjvTpoXhDxSJjJ+9R38OQaJoDjKW2BqbbHt0zjYFEg10Uf1H oCSnPOAEDiLQVu0HnrjbAVaGznXipSJHjuuPdPmDsDuPsi5fyIEgY2t/ZQrz1NKY n4UX8M1ShIHmhvdd40MuhmtB9PM/H32vkIC7TQkSdsky7WSGlwDhcJx+6KQij5pQ TfIEWojkAMLSIUWokAf+5xqMhHTUaItIEFczm+1g9eDpTW3Ln5aWxO9SA/shWmvF 1IihAxnEI67NS82Olc6EyO05AvG2HNtkdCkPAWHE3GFYjm46IICi7xcmw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm2; bh=DwriZRHRN7fN7mhHrJdEKvtb3nQZcEd0mgRQMVSwm/Y=; b=Srvnlj1K Kxj/m1XJXkyCSWasG+E6ij6xxmoBO4dsmBDqqeZxYQMSKC1m0a8nuO11TO5cpAX9 ZVh0ujUsk+R18ueIUCH/3IR/Ky3oQ9IFeyWKlq8Q4M4+nGC0oyX9slRROQ1mDx7P CUEQhAkS6fyfrt/adZul1NavZhNV3MQqC+MggvYwQu5VfmMr5VYFBRhmUYxLDy+O 8haSarBhdGp67sY/BZecMg2rEqqPqNvcc2PwRlOw6zRgezyQY32jVYqxM55/w5Pr vGbp/zYNxOmJCbFG4A2tb2SbnssJg7PApEW3WlwuybPzOz0yZKBNReJFP59hWM/d 60hJy8Fdph/pPw== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedugedrledtucetufdoteggodetrfdotffvucfrrh hofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgenuceurghi lhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurh ephffvufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpeforgigihhmvgcutfhi phgrrhguuceomhgrgihimhgvsegtvghrnhhordhtvggthheqnecukfhppeeltddrkeelrd eikedrjeeinecuvehluhhsthgvrhfuihiivgepudejnecurfgrrhgrmhepmhgrihhlfhhr ohhmpehmrgigihhmvgestggvrhhnohdrthgvtghh X-ME-Proxy: Received: from localhost (lfbn-tou-1-1502-76.w90-89.abo.wanadoo.fr [90.89.68.76]) by mail.messagingengine.com (Postfix) with ESMTPA id 0D5743280064; Mon, 24 Feb 2020 04:09:20 -0500 (EST) From: Maxime Ripard To: Nicolas Saenz Julienne , Eric Anholt Subject: [PATCH 22/89] clk: bcm: rpi: Discover the firmware clocks Date: Mon, 24 Feb 2020 10:06:24 +0100 Message-Id: X-Mailer: git-send-email 2.24.1 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200224_010925_184821_4D602981 X-CRM114-Status: GOOD ( 14.16 ) X-Spam-Score: -0.9 (/) X-Spam-Report: SpamAssassin version 3.4.3 on bombadil.infradead.org summary: Content analysis details: (-0.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at https://www.dnswl.org/, low trust [64.147.123.17 listed in list.dnswl.org] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches SPF record 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Tim Gover , Dave Stevenson , Stephen Boyd , Michael Turquette , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-clk@vger.kernel.org, bcm-kernel-feedback-list@broadcom.com, linux-rpi-kernel@lists.infradead.org, Phil Elwell , linux-arm-kernel@lists.infradead.org, Maxime Ripard Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org The firmware has an interface to discover the clocks it exposes. Let's use it to discover, register the clocks in the clocks framework and then expose them through the device tree for consumers to use them. Cc: Michael Turquette Cc: Stephen Boyd Cc: linux-clk@vger.kernel.org Signed-off-by: Maxime Ripard Reported-by: kbuild test robot Reported-by: kbuild test robot --- drivers/clk/bcm/clk-raspberrypi.c | 105 +++++++++++++++++++--- include/soc/bcm2835/raspberrypi-firmware.h | 5 +- 2 files changed, 98 insertions(+), 12 deletions(-) diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c index 3f21888a3e3e..bf6a1e2dc099 100644 --- a/drivers/clk/bcm/clk-raspberrypi.c +++ b/drivers/clk/bcm/clk-raspberrypi.c @@ -285,6 +285,95 @@ static struct clk_hw *raspberrypi_register_pllb_arm(struct raspberrypi_clk *rpi) return &raspberrypi_clk_pllb_arm.hw; } +static long raspberrypi_fw_dumb_round_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long *parent_rate) +{ + return rate; +} + +static const struct clk_ops raspberrypi_firmware_clk_ops = { + .is_prepared = raspberrypi_fw_is_prepared, + .recalc_rate = raspberrypi_fw_get_rate, + .round_rate = raspberrypi_fw_dumb_round_rate, + .set_rate = raspberrypi_fw_set_rate, +}; + +static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi, + unsigned int parent, + unsigned int id) +{ + struct raspberrypi_clk_data *data; + struct clk_init_data init = {}; + int ret; + + if (id == RPI_FIRMWARE_ARM_CLK_ID) { + struct clk_hw *hw; + + hw = raspberrypi_register_pllb(rpi); + if (IS_ERR(hw)) { + dev_err(rpi->dev, "Failed to initialize pllb, %ld\n", + PTR_ERR(hw)); + return hw; + } + + hw = raspberrypi_register_pllb_arm(rpi); + if (IS_ERR(hw)) + return hw; + + return hw; + } + + data = devm_kzalloc(rpi->dev, sizeof(data), GFP_KERNEL); + if (!data) + return ERR_PTR(-ENOMEM); + data->rpi = rpi; + data->id = id; + + init.name = devm_kasprintf(rpi->dev, GFP_KERNEL, "fw-clk-%u", id); + init.ops = &raspberrypi_firmware_clk_ops; + init.flags = CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED; + + data->hw.init = &init; + + ret = devm_clk_hw_register(rpi->dev, &data->hw); + if (ret) + return ERR_PTR(ret); + + return &data->hw; +} + +static int raspberrypi_discover_clocks(struct raspberrypi_clk *rpi, + struct clk_hw_onecell_data *data) +{ + struct rpi_firmware_get_clocks_response *clks; + size_t clks_size = NUM_FW_CLKS * sizeof(*clks); + int ret; + + clks = devm_kzalloc(rpi->dev, clks_size, GFP_KERNEL); + if (!clks) + return -ENOMEM; + + ret = rpi_firmware_property(rpi->firmware, RPI_FIRMWARE_GET_CLOCKS, + clks, clks_size); + if (ret) + return ret; + + while (clks->id) { + struct clk_hw *hw; + + hw = raspberrypi_clk_register(rpi, clks->parent, clks->id); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + data->hws[clks->id] = hw; + data->num = clks->id + 1; + clks++; + } + + return 0; +} + static int raspberrypi_clk_probe(struct platform_device *pdev) { struct clk_hw_onecell_data *clk_data; @@ -292,7 +381,7 @@ static int raspberrypi_clk_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct rpi_firmware *firmware; struct raspberrypi_clk *rpi; - struct clk_hw *hw; + int ret; firmware_node = of_parse_phandle(dev->of_node, "raspberrypi,firmware", 0); if (!firmware_node) { @@ -317,17 +406,9 @@ static int raspberrypi_clk_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - hw = raspberrypi_register_pllb(rpi); - if (IS_ERR(hw)) { - dev_err(dev, "Failed to initialize pllb, %ld\n", PTR_ERR(hw)); - return PTR_ERR(hw); - } - - hw = raspberrypi_register_pllb_arm(rpi); - if (IS_ERR(hw)) - return PTR_ERR(hw); - clk_data->hws[RPI_FIRMWARE_ARM_CLK_ID] = hw; - clk_data->num = RPI_FIRMWARE_ARM_CLK_ID + 1; + ret = raspberrypi_discover_clocks(rpi, clk_data); + if (ret) + return ret; ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data); diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h index 7800e12ee042..e5b7a41bba6b 100644 --- a/include/soc/bcm2835/raspberrypi-firmware.h +++ b/include/soc/bcm2835/raspberrypi-firmware.h @@ -135,6 +135,11 @@ enum rpi_firmware_property_tag { RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, }; +struct rpi_firmware_get_clocks_response { + __le32 parent; + __le32 id; +}; + #if IS_ENABLED(CONFIG_RASPBERRYPI_FIRMWARE) int rpi_firmware_property(struct rpi_firmware *fw, u32 tag, void *data, size_t len);