linux-mips.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jonas Gorski <jonas.gorski@gmail.com>
To: linux-clk@vger.kernel.org, devicetree@vger.kernel.org,
	linux-mips@vger.kernel.org
Cc: Michael Turquette <mturquette@baylibre.com>,
	Stephen Boyd <sboyd@kernel.org>, Rob Herring <robh+dt@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Florian Fainelli <f.fainelli@gmail.com>,
	bcm-kernel-feedback-list@broadcom.com,
	Kevin Cernekee <cernekee@gmail.com>,
	Ralf Baechle <ralf@linux-mips.org>,
	Paul Burton <paul.burton@mips.com>,
	James Hogan <jhogan@kernel.org>
Subject: [PATCH 2/3] clk: add BCM63XX gated clock controller driver
Date: Thu,  2 May 2019 14:26:56 +0200	[thread overview]
Message-ID: <20190502122657.15577-3-jonas.gorski@gmail.com> (raw)
In-Reply-To: <20190502122657.15577-1-jonas.gorski@gmail.com>

Add a driver for the gated clock controller found on MIPS based BCM63XX
SoCs.

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
 drivers/clk/bcm/Kconfig            |   8 ++
 drivers/clk/bcm/Makefile           |   1 +
 drivers/clk/bcm/clk-bcm63xx-gate.c | 246 +++++++++++++++++++++++++++++++++++++
 3 files changed, 255 insertions(+)
 create mode 100644 drivers/clk/bcm/clk-bcm63xx-gate.c

diff --git a/drivers/clk/bcm/Kconfig b/drivers/clk/bcm/Kconfig
index 4c4bd85f707c..144e724815c6 100644
--- a/drivers/clk/bcm/Kconfig
+++ b/drivers/clk/bcm/Kconfig
@@ -7,6 +7,14 @@ config CLK_BCM_63XX
 	  Enable common clock framework support for Broadcom BCM63xx DSL SoCs
 	  based on the ARM architecture
 
+config CLK_BCM_63XX_GATE
+	bool "Broadcom BCM63xx gated clock support"
+	depends on BMIPS_GENERIC || COMPILE_TEST
+	default BMIPS_GENERIC
+	help
+	  Enable common clock framework support for Broadcom BCM63xx DSL SoCs
+	  based on the MIPS architecture
+
 config CLK_BCM_KONA
 	bool "Broadcom Kona CCU clock support"
 	depends on ARCH_BCM_MOBILE || COMPILE_TEST
diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile
index 002661d39128..3d925493db7f 100644
--- a/drivers/clk/bcm/Makefile
+++ b/drivers/clk/bcm/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_CLK_BCM_63XX)	+= clk-bcm63xx.o
+obj-$(CONFIG_CLK_BCM_63XX_GATE)	+= clk-bcm63xx-gate.o
 obj-$(CONFIG_CLK_BCM_KONA)	+= clk-kona.o
 obj-$(CONFIG_CLK_BCM_KONA)	+= clk-kona-setup.o
 obj-$(CONFIG_CLK_BCM_KONA)	+= clk-bcm281xx.o
diff --git a/drivers/clk/bcm/clk-bcm63xx-gate.c b/drivers/clk/bcm/clk-bcm63xx-gate.c
new file mode 100644
index 000000000000..4fd10645a192
--- /dev/null
+++ b/drivers/clk/bcm/clk-bcm63xx-gate.c
@@ -0,0 +1,246 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <linux/clk-provider.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+struct clk_bcm63xx_table_entry {
+	const char * const name;
+	u8 bit;
+	unsigned long flags;
+};
+
+struct clk_bcm63xx_hw {
+	void __iomem *regs;
+	spinlock_t lock;
+
+	struct clk_hw_onecell_data data;
+};
+
+const struct clk_bcm63xx_table_entry bcm3368_clocks[] = {
+	{ .name = "mac", .bit = 3, },
+	{ .name = "tc", .bit = 5, },
+	{ .name = "us_top", .bit = 6, },
+	{ .name = "ds_top", .bit = 7, },
+	{ .name = "acm", .bit = 8, },
+	{ .name = "spi", .bit = 9, },
+	{ .name = "usbs", .bit = 10, },
+	{ .name = "bmu", .bit = 11, },
+	{ .name = "pcm", .bit = 12, },
+	{ .name = "ntp", .bit = 13, },
+	{ .name = "acp_b", .bit = 14, },
+	{ .name = "acp_a", .bit = 15, },
+	{ .name = "emusb", .bit = 17, },
+	{ .name = "enet0", .bit = 18, },
+	{ .name = "enet1", .bit = 19, },
+	{ .name = "usbsu", .bit = 20, },
+	{ .name = "ephy", .bit = 21, },
+	{ },
+};
+
+const struct clk_bcm63xx_table_entry bcm6328_clocks[] = {
+	{ .name = "phy_mips", .bit = 0, },
+	{ .name = "adsl_qproc", .bit = 1, },
+	{ .name = "adsl_afe", .bit = 2, },
+	{ .name = "adsl", .bit = 3, },
+	{ .name = "mips", .bit = 4, .flags = CLK_IS_CRITICAL, },
+	{ .name = "sar", .bit = 5, },
+	{ .name = "pcm", .bit = 6, },
+	{ .name = "usbd", .bit = 7, },
+	{ .name = "usbh", .bit = 8, },
+	{ .name = "hsspi", .bit = 9, },
+	{ .name = "pcie", .bit = 10, },
+	{ .name = "robosw", .bit = 11, },
+	{ },
+};
+
+const struct clk_bcm63xx_table_entry bcm6358_clocks[] = {
+	{ .name = "enet", .bit = 4, },
+	{ .name = "adslphy", .bit = 5, },
+	{ .name = "pcm", .bit = 8, },
+	{ .name = "spi", .bit = 9, },
+	{ .name = "usbs", .bit = 10, },
+	{ .name = "sar", .bit = 11, },
+	{ .name = "emusb", .bit = 17, },
+	{ .name = "enet0", .bit = 18, },
+	{ .name = "enet1", .bit = 19, },
+	{ .name = "usbsu", .bit = 20, },
+	{ .name = "ephy", .bit = 21, },
+	{ },
+};
+
+const struct clk_bcm63xx_table_entry bcm6362_clocks[] = {
+	{ .name = "adsl_qproc", .bit = 1, },
+	{ .name = "adsl_afe", .bit = 2, },
+	{ .name = "adsl", .bit = 3, },
+	{ .name = "mips", .bit = 4, .flags = CLK_IS_CRITICAL, },
+	{ .name = "wlan_ocp", .bit = 5, },
+	{ .name = "swpkt_usb", .bit = 7, },
+	{ .name = "swpkt_sar", .bit = 8, },
+	{ .name = "sar", .bit = 9, },
+	{ .name = "robosw", .bit = 10, },
+	{ .name = "pcm", .bit = 11, },
+	{ .name = "usbd", .bit = 12, },
+	{ .name = "usbh", .bit = 13, },
+	{ .name = "ipsec", .bit = 14, },
+	{ .name = "spi", .bit = 15, },
+	{ .name = "hsspi", .bit = 16, },
+	{ .name = "pcie", .bit = 17, },
+	{ .name = "fap", .bit = 18, },
+	{ .name = "phymips", .bit = 19, },
+	{ .name = "nand", .bit = 20, },
+	{ },
+};
+
+const struct clk_bcm63xx_table_entry bcm6368_clocks[] = {
+	{ .name = "vdsl_qproc", .bit = 2, },
+	{ .name = "vdsl_afe", .bit = 3, },
+	{ .name = "vdsl_bonding", .bit = 4, },
+	{ .name = "vdsl", .bit = 5, },
+	{ .name = "phymips", .bit = 6, },
+	{ .name = "swpkt_usb", .bit = 7, },
+	{ .name = "swpkt_sar", .bit = 8, },
+	{ .name = "spi", .bit = 9, },
+	{ .name = "usbd", .bit = 10, },
+	{ .name = "sar", .bit = 11, },
+	{ .name = "robosw", .bit = 12, },
+	{ .name = "utopia", .bit = 13, },
+	{ .name = "pcm", .bit = 14, },
+	{ .name = "usbh", .bit = 15, },
+	{ .name = "disable_gless", .bit = 16, },
+	{ .name = "nand", .bit = 17, },
+	{ .name = "ipsec", .bit = 18, },
+	{ },
+};
+
+const struct clk_bcm63xx_table_entry bcm63268_clocks[] = {
+	{ .name = "disable_gless", .bit = 0, },
+	{ .name = "vdsl_qproc", .bit = 1, },
+	{ .name = "vdsl_afe", .bit = 2, },
+	{ .name = "vdsl", .bit = 3, },
+	{ .name = "mips", .bit = 4, .flags = CLK_IS_CRITICAL, },
+	{ .name = "wlan_ocp", .bit = 5, },
+	{ .name = "dect", .bit = 6, },
+	{ .name = "fap0", .bit = 7, },
+	{ .name = "fap1", .bit = 8, },
+	{ .name = "sar", .bit = 9, },
+	{ .name = "robosw", .bit = 10, },
+	{ .name = "pcm", .bit = 11, },
+	{ .name = "usbd", .bit = 12, },
+	{ .name = "usbh", .bit = 13, },
+	{ .name = "ipsec", .bit = 14, },
+	{ .name = "spi", .bit = 15, },
+	{ .name = "hsspi", .bit = 16, },
+	{ .name = "pcie", .bit = 17, },
+	{ .name = "phymips", .bit = 18, },
+	{ .name = "gmac", .bit = 19, },
+	{ .name = "nand", .bit = 20, },
+	{ .name = "tbus", .bit = 27, },
+	{ .name = "robosw250", .bit = 31, },
+	{ },
+};
+
+static int clk_bcm63xx_probe(struct platform_device *pdev)
+{
+	const struct clk_bcm63xx_table_entry *entry, *table;
+	struct clk_bcm63xx_hw *hw;
+	struct resource *r;
+	u8 maxbit = 0;
+	int i, ret;
+
+	table = of_device_get_match_data(&pdev->dev);
+	if (!table)
+		return -EINVAL;
+
+	for (entry = table; entry->name; entry++)
+		maxbit = max_t(u8, maxbit, entry->bit);
+
+	hw = devm_kzalloc(&pdev->dev, struct_size(hw, data.hws, maxbit),
+			  GFP_KERNEL);
+	if (!hw)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, hw);
+
+	spin_lock_init(&hw->lock);
+
+	hw->data.num = maxbit;
+	for (i = 0; i < maxbit; i++)
+		hw->data.hws[i] = ERR_PTR(-ENODEV);
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	hw->regs = devm_ioremap_resource(&pdev->dev, r);
+	if (IS_ERR(hw->regs))
+		return PTR_ERR(hw->regs);
+
+	for (entry = table; entry->name; entry++) {
+		struct clk_hw *clk;
+
+		clk = clk_hw_register_gate(&pdev->dev, entry->name, NULL,
+					   entry->flags, hw->regs, entry->bit,
+					   CLK_GATE_BIG_ENDIAN, &hw->lock);
+		if (IS_ERR(clk)) {
+			ret = PTR_ERR(clk);
+			goto out_err;
+		}
+
+		hw->data.hws[entry->bit] = clk;
+	}
+
+	ret = of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get,
+				     &hw->data);
+	if (!ret)
+		return 0;
+out_err:
+	for (i = 0; i < hw->data.num; i++) {
+		if (!IS_ERR(hw->data.hws[i]))
+			clk_hw_unregister_gate(hw->data.hws[i]);
+	}
+
+	return ret;
+}
+
+static int clk_bcm63xx_remove(struct platform_device *pdev)
+{
+	struct clk_bcm63xx_hw *hw = platform_get_drvdata(pdev);
+	int i;
+
+	of_clk_del_provider(pdev->dev.of_node);
+
+	for (i = 0; i < hw->data.num; i++) {
+		if (!IS_ERR(hw->data.hws[i]))
+			clk_hw_unregister_gate(hw->data.hws[i]);
+	}
+
+	return 0;
+}
+
+static const struct of_device_id clk_bcm63xx_dt_ids[] = {
+	{ .compatible = "brcm,bcm3368-clocks", .data = &bcm3368_clocks, },
+	{ .compatible = "brcm,bcm6328-clocks", .data = &bcm6328_clocks, },
+	{ .compatible = "brcm,bcm6358-clocks", .data = &bcm6358_clocks, },
+	{ .compatible = "brcm,bcm6362-clocks", .data = &bcm6362_clocks, },
+	{ .compatible = "brcm,bcm6368-clocks", .data = &bcm6368_clocks, },
+	{ .compatible = "brcm,bcm63268-clocks", .data = &bcm63268_clocks, },
+	{ },
+};
+
+MODULE_DEVICE_TABLE(of, clk_bcm63xx_dt_ids);
+
+static struct platform_driver clk_bcm63xx = {
+	.probe = clk_bcm63xx_probe,
+	.remove = clk_bcm63xx_remove,
+	.driver = {
+		.name = "bcm63xx-clock",
+		.of_match_table = of_match_ptr(clk_bcm63xx_dt_ids),
+	},
+};
+
+builtin_platform_driver(clk_bcm63xx);
+
+MODULE_AUTHOR("Jonas Gorski <jonas.gorski@gmail.com>");
+MODULE_DESCRIPTION("BCM63XX (MIPS) gated clock controller driver");
+MODULE_LICENSE("GPL");
-- 
2.13.2


  parent reply	other threads:[~2019-05-02 12:27 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-02 12:26 [PATCH 0/3] MIPS: BMIPS: add support for gated clock controller Jonas Gorski
2019-05-02 12:26 ` [PATCH 1/3] devicetree: document the BCM63XX gated clock bindings Jonas Gorski
2019-05-03  1:44   ` Florian Fainelli
2019-05-03  9:47     ` Jonas Gorski
2019-05-03 14:36   ` Philippe Mathieu-Daudé
2019-05-05 18:57     ` Jonas Gorski
2019-05-05 23:26       ` Philippe Mathieu-Daudé
2019-05-14 20:33   ` Rob Herring
2019-06-27 20:36   ` Stephen Boyd
2019-05-02 12:26 ` Jonas Gorski [this message]
2019-05-03  1:46   ` [PATCH 2/3] clk: add BCM63XX gated clock controller driver Florian Fainelli
2019-05-03 14:13   ` Philippe Mathieu-Daudé
2019-06-27 20:43   ` Stephen Boyd
2019-05-02 12:26 ` [PATCH 3/3] MIPS: BMIPS: add clock controller nodes Jonas Gorski
2019-05-03  1:47   ` Florian Fainelli
2019-05-03 14:36   ` Philippe Mathieu-Daudé
2019-07-22 21:22   ` Paul Burton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190502122657.15577-3-jonas.gorski@gmail.com \
    --to=jonas.gorski@gmail.com \
    --cc=bcm-kernel-feedback-list@broadcom.com \
    --cc=cernekee@gmail.com \
    --cc=devicetree@vger.kernel.org \
    --cc=f.fainelli@gmail.com \
    --cc=jhogan@kernel.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-mips@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=mturquette@baylibre.com \
    --cc=paul.burton@mips.com \
    --cc=ralf@linux-mips.org \
    --cc=robh+dt@kernel.org \
    --cc=sboyd@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).