diff options
Diffstat (limited to 'target/linux/bmips/patches-5.15/113-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch')
-rw-r--r-- | target/linux/bmips/patches-5.15/113-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch | 281 |
1 files changed, 0 insertions, 281 deletions
diff --git a/target/linux/bmips/patches-5.15/113-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch b/target/linux/bmips/patches-5.15/113-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch deleted file mode 100644 index 484647a6e1..0000000000 --- a/target/linux/bmips/patches-5.15/113-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch +++ /dev/null @@ -1,281 +0,0 @@ -From 3c8dd9d0937a19f3f20f28ba0b0b64f448d50dd4 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com> -Date: Thu, 25 Feb 2021 19:54:04 +0100 -Subject: [PATCH 4/4] clk: bcm: Add BCM63268 timer clock and reset driver -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add driver for BCM63268 timer clock and reset controller. - -Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> ---- - drivers/clk/bcm/Kconfig | 9 ++ - drivers/clk/bcm/Makefile | 1 + - drivers/clk/bcm/clk-bcm63268-timer.c | 232 +++++++++++++++++++++++++++ - 3 files changed, 242 insertions(+) - create mode 100644 drivers/clk/bcm/clk-bcm63268-timer.c - ---- a/drivers/clk/bcm/Kconfig -+++ b/drivers/clk/bcm/Kconfig -@@ -37,6 +37,15 @@ config CLK_BCM_63XX_GATE - Enable common clock framework support for Broadcom BCM63xx DSL SoCs - based on the MIPS architecture - -+config CLK_BCM63268_TIMER -+ bool "Broadcom BCM63268 timer clock and reset support" -+ depends on BMIPS_GENERIC || COMPILE_TEST -+ default BMIPS_GENERIC -+ select RESET_CONTROLLER -+ help -+ Enable timer clock and reset support for Broadcom BCM63268 DSL SoCs -+ based on the MIPS architecture. -+ - config CLK_BCM_KONA - bool "Broadcom Kona CCU clock support" - depends on ARCH_BCM_MOBILE || COMPILE_TEST ---- a/drivers/clk/bcm/Makefile -+++ b/drivers/clk/bcm/Makefile -@@ -1,6 +1,7 @@ - # 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_BCM63268_TIMER) += clk-bcm63268-timer.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 ---- /dev/null -+++ b/drivers/clk/bcm/clk-bcm63268-timer.c -@@ -0,0 +1,232 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * BCM63268 Timer Clock and Reset Controller Driver -+ * -+ * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com> -+ */ -+ -+#include <linux/clk-provider.h> -+#include <linux/delay.h> -+#include <linux/init.h> -+#include <linux/of.h> -+#include <linux/of_device.h> -+#include <linux/platform_device.h> -+#include <linux/reset-controller.h> -+ -+#include <dt-bindings/clock/bcm63268-clock.h> -+ -+#define BCM63268_TIMER_RESET_SLEEP_MIN_US 10000 -+#define BCM63268_TIMER_RESET_SLEEP_MAX_US 20000 -+ -+struct bcm63268_tclkrst_hw { -+ void __iomem *regs; -+ spinlock_t lock; -+ -+ struct reset_controller_dev rcdev; -+ struct clk_hw_onecell_data data; -+}; -+ -+struct bcm63268_tclk_table_entry { -+ const char * const name; -+ u8 bit; -+ unsigned long flags; -+}; -+ -+static const struct bcm63268_tclk_table_entry bcm63268_timer_clocks[] = { -+ { -+ .name = "ephy1", -+ .bit = BCM63268_TCLK_EPHY1, -+ }, { -+ .name = "ephy2", -+ .bit = BCM63268_TCLK_EPHY2, -+ }, { -+ .name = "ephy3", -+ .bit = BCM63268_TCLK_EPHY3, -+ }, { -+ .name = "gphy1", -+ .bit = BCM63268_TCLK_GPHY1, -+ }, { -+ .name = "dsl", -+ .bit = BCM63268_TCLK_DSL, -+ }, { -+ .name = "wakeon_ephy", -+ .bit = BCM63268_TCLK_WAKEON_EPHY, -+ }, { -+ .name = "wakeon_dsl", -+ .bit = BCM63268_TCLK_WAKEON_DSL, -+ }, { -+ .name = "fap1_pll", -+ .bit = BCM63268_TCLK_FAP1, -+ }, { -+ .name = "fap2_pll", -+ .bit = BCM63268_TCLK_FAP2, -+ }, { -+ .name = "uto_50", -+ .bit = BCM63268_TCLK_UTO_50, -+ }, { -+ .name = "uto_extin", -+ .bit = BCM63268_TCLK_UTO_EXTIN, -+ }, { -+ .name = "usb_ref", -+ .bit = BCM63268_TCLK_USB_REF, -+ }, { -+ /* sentinel */ -+ } -+}; -+ -+static inline struct bcm63268_tclkrst_hw * -+to_bcm63268_timer_reset(struct reset_controller_dev *rcdev) -+{ -+ return container_of(rcdev, struct bcm63268_tclkrst_hw, rcdev); -+} -+ -+static int bcm63268_timer_reset_update(struct reset_controller_dev *rcdev, -+ unsigned long id, bool assert) -+{ -+ struct bcm63268_tclkrst_hw *reset = to_bcm63268_timer_reset(rcdev); -+ unsigned long flags; -+ uint32_t val; -+ -+ spin_lock_irqsave(&reset->lock, flags); -+ val = __raw_readl(reset->regs); -+ if (assert) -+ val &= ~BIT(id); -+ else -+ val |= BIT(id); -+ __raw_writel(val, reset->regs); -+ spin_unlock_irqrestore(&reset->lock, flags); -+ -+ return 0; -+} -+ -+static int bcm63268_timer_reset_assert(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ return bcm63268_timer_reset_update(rcdev, id, true); -+} -+ -+static int bcm63268_timer_reset_deassert(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ return bcm63268_timer_reset_update(rcdev, id, false); -+} -+ -+static int bcm63268_timer_reset_reset(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ bcm63268_timer_reset_update(rcdev, id, true); -+ usleep_range(BCM63268_TIMER_RESET_SLEEP_MIN_US, -+ BCM63268_TIMER_RESET_SLEEP_MAX_US); -+ -+ bcm63268_timer_reset_update(rcdev, id, false); -+ /* -+ * Ensure component is taken out reset state by sleeping also after -+ * deasserting the reset. Otherwise, the component may not be ready -+ * for operation. -+ */ -+ usleep_range(BCM63268_TIMER_RESET_SLEEP_MIN_US, -+ BCM63268_TIMER_RESET_SLEEP_MAX_US); -+ -+ return 0; -+} -+ -+static int bcm63268_timer_reset_status(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ struct bcm63268_tclkrst_hw *reset = to_bcm63268_timer_reset(rcdev); -+ -+ return !(__raw_readl(reset->regs) & BIT(id)); -+} -+ -+static struct reset_control_ops bcm63268_timer_reset_ops = { -+ .assert = bcm63268_timer_reset_assert, -+ .deassert = bcm63268_timer_reset_deassert, -+ .reset = bcm63268_timer_reset_reset, -+ .status = bcm63268_timer_reset_status, -+}; -+ -+static int bcm63268_tclk_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ const struct bcm63268_tclk_table_entry *entry, *table; -+ struct bcm63268_tclkrst_hw *hw; -+ u8 maxbit = 0; -+ int i, ret; -+ -+ table = of_device_get_match_data(dev); -+ if (!table) -+ return -EINVAL; -+ -+ for (entry = table; entry->name; entry++) -+ maxbit = max_t(u8, maxbit, entry->bit); -+ maxbit++; -+ -+ 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); -+ -+ hw->regs = devm_platform_ioremap_resource(pdev, 0); -+ 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(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(dev->of_node, of_clk_hw_onecell_get, -+ &hw->data); -+ if (!ret) -+ return 0; -+ -+ hw->rcdev.of_node = dev->of_node; -+ hw->rcdev.ops = &bcm63268_timer_reset_ops; -+ -+ ret = devm_reset_controller_register(dev, &hw->rcdev); -+ if (ret) -+ dev_err(dev, "Failed to register reset controller\n"); -+ -+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 const struct of_device_id bcm63268_tclk_dt_ids[] = { -+ { -+ .compatible = "brcm,bcm63268-timer-clocks", -+ .data = &bcm63268_timer_clocks, -+ }, { -+ /* sentinel */ -+ } -+}; -+ -+static struct platform_driver bcm63268_tclk = { -+ .probe = bcm63268_tclk_probe, -+ .driver = { -+ .name = "bcm63268-timer-clock", -+ .of_match_table = bcm63268_tclk_dt_ids, -+ }, -+}; -+builtin_platform_driver(bcm63268_tclk); |