diff options
Diffstat (limited to 'drivers/clk')
61 files changed, 1889 insertions, 221 deletions
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 81cdb4eaca07..2dc12bf75b1b 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -283,6 +283,13 @@ config COMMON_CLK_STM32H7 ---help--- Support for stm32h7 SoC family clocks +config COMMON_CLK_BD718XX + tristate "Clock driver for ROHM BD718x7 PMIC" + depends on MFD_ROHM_BD718XX + help + This driver supports ROHM BD71837 and ROHM BD71847 + PMICs clock gates. + source "drivers/clk/actions/Kconfig" source "drivers/clk/bcm/Kconfig" source "drivers/clk/hisilicon/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 72be7a38cff1..a47430b387db 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -21,6 +21,7 @@ endif obj-$(CONFIG_MACH_ASM9260) += clk-asm9260.o obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o obj-$(CONFIG_ARCH_AXXIA) += clk-axm5516.o +obj-$(CONFIG_COMMON_CLK_BD718XX) += clk-bd718x7.o obj-$(CONFIG_COMMON_CLK_CDCE706) += clk-cdce706.o obj-$(CONFIG_COMMON_CLK_CDCE925) += clk-cdce925.o obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o diff --git a/drivers/clk/bcm/clk-bcm2835-aux.c b/drivers/clk/bcm/clk-bcm2835-aux.c index f225ad29b110..2a2c7569336a 100644 --- a/drivers/clk/bcm/clk-bcm2835-aux.c +++ b/drivers/clk/bcm/clk-bcm2835-aux.c @@ -1,15 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2015 Broadcom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/clk.h> @@ -79,4 +70,4 @@ builtin_platform_driver(bcm2835_aux_clk_driver); MODULE_AUTHOR("Eric Anholt <eric@anholt.net>"); MODULE_DESCRIPTION("BCM2835 auxiliary peripheral clock driver"); -MODULE_LICENSE("GPL v2"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 7bef0666ae7e..9fcae932e082 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -1,17 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2010,2015 Broadcom * Copyright (C) 2012 Stephen Warren - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ /** @@ -2206,4 +2196,4 @@ builtin_platform_driver(bcm2835_clk_driver); MODULE_AUTHOR("Eric Anholt <eric@anholt.net>"); MODULE_DESCRIPTION("BCM2835 clock driver"); -MODULE_LICENSE("GPL v2"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/clk-axm5516.c b/drivers/clk/clk-axm5516.c index 5d7ae333257e..98e0c9ba7b61 100644 --- a/drivers/clk/clk-axm5516.c +++ b/drivers/clk/clk-axm5516.c @@ -311,7 +311,6 @@ static struct axxia_divclk clk_per_div = { "clk_sm1_pll" }, .num_parents = 1, - .flags = CLK_IS_BASIC, .ops = &axxia_divclk_ops, }, .reg = 0x1000c, @@ -326,7 +325,6 @@ static struct axxia_divclk clk_mmc_div = { "clk_sm1_pll" }, .num_parents = 1, - .flags = CLK_IS_BASIC, .ops = &axxia_divclk_ops, }, .reg = 0x1000c, diff --git a/drivers/clk/clk-bd718x7.c b/drivers/clk/clk-bd718x7.c new file mode 100644 index 000000000000..60422c72d142 --- /dev/null +++ b/drivers/clk/clk-bd718x7.c @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 ROHM Semiconductors + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/err.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/mfd/rohm-bd718x7.h> +#include <linux/clk-provider.h> +#include <linux/clkdev.h> +#include <linux/regmap.h> + +struct bd718xx_clk { + struct clk_hw hw; + u8 reg; + u8 mask; + struct platform_device *pdev; + struct bd718xx *mfd; +}; + +static int bd71837_clk_set(struct clk_hw *hw, int status) +{ + struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw); + + return regmap_update_bits(c->mfd->regmap, c->reg, c->mask, status); +} + +static void bd71837_clk_disable(struct clk_hw *hw) +{ + int rv; + struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw); + + rv = bd71837_clk_set(hw, 0); + if (rv) + dev_dbg(&c->pdev->dev, "Failed to disable 32K clk (%d)\n", rv); +} + +static int bd71837_clk_enable(struct clk_hw *hw) +{ + return bd71837_clk_set(hw, 1); +} + +static int bd71837_clk_is_enabled(struct clk_hw *hw) +{ + int enabled; + int rval; + struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw); + + rval = regmap_read(c->mfd->regmap, c->reg, &enabled); + + if (rval) + return rval; + + return enabled & c->mask; +} + +static const struct clk_ops bd71837_clk_ops = { + .prepare = &bd71837_clk_enable, + .unprepare = &bd71837_clk_disable, + .is_prepared = &bd71837_clk_is_enabled, +}; + +static int bd71837_clk_probe(struct platform_device *pdev) +{ + struct bd718xx_clk *c; + int rval = -ENOMEM; + const char *parent_clk; + struct device *parent = pdev->dev.parent; + struct bd718xx *mfd = dev_get_drvdata(parent); + struct clk_init_data init = { + .name = "bd718xx-32k-out", + .ops = &bd71837_clk_ops, + }; + + c = devm_kzalloc(&pdev->dev, sizeof(*c), GFP_KERNEL); + if (!c) + return -ENOMEM; + + init.num_parents = 1; + parent_clk = of_clk_get_parent_name(parent->of_node, 0); + + init.parent_names = &parent_clk; + if (!parent_clk) { + dev_err(&pdev->dev, "No parent clk found\n"); + return -EINVAL; + } + + c->reg = BD718XX_REG_OUT32K; + c->mask = BD718XX_OUT32K_EN; + c->mfd = mfd; + c->pdev = pdev; + c->hw.init = &init; + + of_property_read_string_index(parent->of_node, + "clock-output-names", 0, &init.name); + + rval = devm_clk_hw_register(&pdev->dev, &c->hw); + if (rval) { + dev_err(&pdev->dev, "failed to register 32K clk"); + return rval; + } + rval = devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_simple_get, + &c->hw); + if (rval) + dev_err(&pdev->dev, "adding clk provider failed\n"); + + return rval; +} + +static struct platform_driver bd71837_clk = { + .driver = { + .name = "bd718xx-clk", + }, + .probe = bd71837_clk_probe, +}; + +module_platform_driver(bd71837_clk); + +MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>"); +MODULE_DESCRIPTION("BD71837 chip clk driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/clk-bulk.c b/drivers/clk/clk-bulk.c index 6a7118d4250a..06499568cf07 100644 --- a/drivers/clk/clk-bulk.c +++ b/drivers/clk/clk-bulk.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright 2017 NXP * * Dong Aisheng <aisheng.dong@nxp.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <linux/clk.h> diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c index 00269de2f390..46604214bba0 100644 --- a/drivers/clk/clk-composite.c +++ b/drivers/clk/clk-composite.c @@ -1,17 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2013 NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <linux/clk.h> diff --git a/drivers/clk/clk-conf.c b/drivers/clk/clk-conf.c index 49819b546134..2ef819606c41 100644 --- a/drivers/clk/clk-conf.c +++ b/drivers/clk/clk-conf.c @@ -1,10 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2014 Samsung Electronics Co., Ltd. * Sylwester Nawrocki <s.nawrocki@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/clk.h> diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c index 12c87457eca1..c9a86156ced8 100644 --- a/drivers/clk/clk-devres.c +++ b/drivers/clk/clk-devres.c @@ -1,9 +1,4 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - +// SPDX-License-Identifier: GPL-2.0 #include <linux/clk.h> #include <linux/device.h> #include <linux/export.h> diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index b6234a5da12d..e5a17265cfaf 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> * Copyright (C) 2011 Richard Zhao, Linaro <richard.zhao@linaro.org> * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * * Adjustable divider clock implementation */ diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c index ef0ca9414f37..739e19dcacfa 100644 --- a/drivers/clk/clk-fixed-factor.c +++ b/drivers/clk/clk-fixed-factor.c @@ -1,11 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Standard functionality for the common clock API. */ #include <linux/module.h> #include <linux/clk-provider.h> diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c index 6d6475c32ee5..00ef4f5e53fe 100644 --- a/drivers/clk/clk-fixed-rate.c +++ b/drivers/clk/clk-fixed-rate.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2010-2011 Canonical Ltd <jeremy.kerr@canonical.com> * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * * Fixed rate clock implementation */ diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c index fdf625fb10fa..830f1361ff79 100644 --- a/drivers/clk/clk-fractional-divider.c +++ b/drivers/clk/clk-fractional-divider.c @@ -1,10 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2014 Intel Corporation * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * * Adjustable fractional divider clock implementation. * Output rate = (m / n) * parent_rate. * Uses rational best approximation algorithm. diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c index dd82485e09a1..f05823cd9b21 100644 --- a/drivers/clk/clk-gate.c +++ b/drivers/clk/clk-gate.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2010-2011 Canonical Ltd <jeremy.kerr@canonical.com> * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * * Gated clock implementation */ diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c index 6a43ce420492..25eed3e0251f 100644 --- a/drivers/clk/clk-gpio.c +++ b/drivers/clk/clk-gpio.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2013 - 2014 Texas Instruments Incorporated - http://www.ti.com * @@ -5,10 +6,6 @@ * Jyri Sarha <jsarha@ti.com> * Sergej Sawazki <ce3a@gmx.de> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * * Gpio controlled clock implementation */ diff --git a/drivers/clk/clk-hi655x.c b/drivers/clk/clk-hi655x.c index 403a0188634a..a0de3315df2e 100644 --- a/drivers/clk/clk-hi655x.c +++ b/drivers/clk/clk-hi655x.c @@ -107,8 +107,8 @@ static int hi655x_clk_probe(struct platform_device *pdev) if (ret) return ret; - return of_clk_add_hw_provider(parent->of_node, of_clk_hw_simple_get, - &hi655x_clk->clk_hw); + return devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_simple_get, + &hi655x_clk->clk_hw); } static struct platform_driver hi655x_clk_driver = { diff --git a/drivers/clk/clk-multiplier.c b/drivers/clk/clk-multiplier.c index dc037c957acd..3c86f859c199 100644 --- a/drivers/clk/clk-multiplier.c +++ b/drivers/clk/clk-multiplier.c @@ -1,9 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2015 Maxime Ripard <maxime.ripard@free-electrons.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/bitops.h> diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c index 1628b93655ed..2ad2df2e8909 100644 --- a/drivers/clk/clk-mux.c +++ b/drivers/clk/clk-mux.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> * Copyright (C) 2011 Richard Zhao, Linaro <richard.zhao@linaro.org> * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * * Simple multiplexer clock implementation */ diff --git a/drivers/clk/clk-nomadik.c b/drivers/clk/clk-nomadik.c index 84a24875c629..a95aa96f4a68 100644 --- a/drivers/clk/clk-nomadik.c +++ b/drivers/clk/clk-nomadik.c @@ -455,7 +455,7 @@ static const char * const src_clk_names[] = { "RNGCCLK ", }; -static int nomadik_src_clk_show(struct seq_file *s, void *what) +static int nomadik_src_clk_debugfs_show(struct seq_file *s, void *what) { int i; u32 src_pcksr0 = readl(src_base + SRC_PCKSR0); @@ -479,17 +479,7 @@ static int nomadik_src_clk_show(struct seq_file *s, void *what) return 0; } -static int nomadik_src_clk_open(struct inode *inode, struct file *file) -{ - return single_open(file, nomadik_src_clk_show, NULL); -} - -static const struct file_operations nomadik_src_clk_debugfs_ops = { - .open = nomadik_src_clk_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(nomadik_src_clk_debugfs); static int __init nomadik_src_clk_init_debugfs(void) { @@ -499,7 +489,7 @@ static int __init nomadik_src_clk_init_debugfs(void) src_pcksr0_boot = readl(src_base + SRC_PCKSR0); src_pcksr1_boot = readl(src_base + SRC_PCKSR1); debugfs_create_file("nomadik-src-clk", S_IFREG | S_IRUGO, - NULL, NULL, &nomadik_src_clk_debugfs_ops); + NULL, NULL, &nomadik_src_clk_debugfs_fops); return 0; } device_initcall(nomadik_src_clk_init_debugfs); diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c index 4c30b6e799ed..5baa9e051110 100644 --- a/drivers/clk/clk-qoriq.c +++ b/drivers/clk/clk-qoriq.c @@ -1418,12 +1418,23 @@ err: CLK_OF_DECLARE(qoriq_clockgen_1, "fsl,qoriq-clockgen-1.0", clockgen_init); CLK_OF_DECLARE(qoriq_clockgen_2, "fsl,qoriq-clockgen-2.0", clockgen_init); +CLK_OF_DECLARE(qoriq_clockgen_b4420, "fsl,b4420-clockgen", clockgen_init); +CLK_OF_DECLARE(qoriq_clockgen_b4860, "fsl,b4860-clockgen", clockgen_init); CLK_OF_DECLARE(qoriq_clockgen_ls1012a, "fsl,ls1012a-clockgen", clockgen_init); CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen", clockgen_init); CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen", clockgen_init); CLK_OF_DECLARE(qoriq_clockgen_ls1046a, "fsl,ls1046a-clockgen", clockgen_init); CLK_OF_DECLARE(qoriq_clockgen_ls1088a, "fsl,ls1088a-clockgen", clockgen_init); CLK_OF_DECLARE(qoriq_clockgen_ls2080a, "fsl,ls2080a-clockgen", clockgen_init); +CLK_OF_DECLARE(qoriq_clockgen_p2041, "fsl,p2041-clockgen", clockgen_init); +CLK_OF_DECLARE(qoriq_clockgen_p3041, "fsl,p3041-clockgen", clockgen_init); +CLK_OF_DECLARE(qoriq_clockgen_p4080, "fsl,p4080-clockgen", clockgen_init); +CLK_OF_DECLARE(qoriq_clockgen_p5020, "fsl,p5020-clockgen", clockgen_init); +CLK_OF_DECLARE(qoriq_clockgen_p5040, "fsl,p5040-clockgen", clockgen_init); +CLK_OF_DECLARE(qoriq_clockgen_t1023, "fsl,t1023-clockgen", clockgen_init); +CLK_OF_DECLARE(qoriq_clockgen_t1040, "fsl,t1040-clockgen", clockgen_init); +CLK_OF_DECLARE(qoriq_clockgen_t2080, "fsl,t2080-clockgen", clockgen_init); +CLK_OF_DECLARE(qoriq_clockgen_t4240, "fsl,t4240-clockgen", clockgen_init); /* Legacy nodes */ CLK_OF_DECLARE(qoriq_sysclk_1, "fsl,qoriq-sysclk-1.0", sysclk_init); diff --git a/drivers/clk/clk-rk808.c b/drivers/clk/clk-rk808.c index 6461f2820a5b..8d90bdf5b946 100644 --- a/drivers/clk/clk-rk808.c +++ b/drivers/clk/clk-rk808.c @@ -138,23 +138,12 @@ static int rk808_clkout_probe(struct platform_device *pdev) if (ret) return ret; - return of_clk_add_hw_provider(node, of_clk_rk808_get, rk808_clkout); -} - -static int rk808_clkout_remove(struct platform_device *pdev) -{ - struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); - struct i2c_client *client = rk808->i2c; - struct device_node *node = client->dev.of_node; - - of_clk_del_provider(node); - - return 0; + return devm_of_clk_add_hw_provider(&pdev->dev, of_clk_rk808_get, + rk808_clkout); } static struct platform_driver rk808_clkout_driver = { .probe = rk808_clkout_probe, - .remove = rk808_clkout_remove, .driver = { .name = "rk808-clkout", }, diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c index 4f48342bc280..6a31f7f434ce 100644 --- a/drivers/clk/clk-stm32mp1.c +++ b/drivers/clk/clk-stm32mp1.c @@ -2015,7 +2015,7 @@ static int stm32_register_hw_clk(struct device *dev, void __iomem *base, spinlock_t *lock, const struct clock_config *cfg) { - static struct clk_hw **hws; + struct clk_hw **hws; struct clk_hw *hw = ERR_PTR(-ENOENT); hws = clk_data->hws; diff --git a/drivers/clk/clk-twl6040.c b/drivers/clk/clk-twl6040.c index 25dfe050ae9f..ea846f77750b 100644 --- a/drivers/clk/clk-twl6040.c +++ b/drivers/clk/clk-twl6040.c @@ -108,9 +108,8 @@ static int twl6040_pdmclk_probe(struct platform_device *pdev) platform_set_drvdata(pdev, clkdata); - return of_clk_add_hw_provider(pdev->dev.parent->of_node, - of_clk_hw_simple_get, - &clkdata->pdmclk_hw); + return devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_simple_get, + &clkdata->pdmclk_hw); } static struct platform_driver twl6040_pdmclk_driver = { diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index af011974d4ec..75d13c0eff12 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2010-2011 Canonical Ltd <jeremy.kerr@canonical.com> * Copyright (C) 2011-2012 Linaro Ltd <mturquette@linaro.org> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * * Standard functionality for the common clock API. See Documentation/driver-api/clk.rst */ @@ -3893,6 +3890,39 @@ static void devm_of_clk_release_provider(struct device *dev, void *res) of_clk_del_provider(*(struct device_node **)res); } +/* + * We allow a child device to use its parent device as the clock provider node + * for cases like MFD sub-devices where the child device driver wants to use + * devm_*() APIs but not list the device in DT as a sub-node. + */ +static struct device_node *get_clk_provider_node(struct device *dev) +{ + struct device_node *np, *parent_np; + + np = dev->of_node; + parent_np = dev->parent ? dev->parent->of_node : NULL; + + if (!of_find_property(np, "#clock-cells", NULL)) + if (of_find_property(parent_np, "#clock-cells", NULL)) + np = parent_np; + + return np; +} + +/** + * devm_of_clk_add_hw_provider() - Managed clk provider node registration + * @dev: Device acting as the clock provider (used for DT node and lifetime) + * @get: callback for decoding clk_hw + * @data: context pointer for @get callback + * + * Registers clock provider for given device's node. If the device has no DT + * node or if the device node lacks of clock provider information (#clock-cells) + * then the parent device's node is scanned for this information. If parent node + * has the #clock-cells then it is used in registration. Provider is + * automatically released at device exit. + * + * Return: 0 on success or an errno on failure. + */ int devm_of_clk_add_hw_provider(struct device *dev, struct clk_hw *(*get)(struct of_phandle_args *clkspec, void *data), @@ -3906,7 +3936,7 @@ int devm_of_clk_add_hw_provider(struct device *dev, if (!ptr) return -ENOMEM; - np = dev->of_node; + np = get_clk_provider_node(dev); ret = of_clk_add_hw_provider(np, get, data); if (!ret) { *ptr = np; @@ -3950,12 +3980,17 @@ static int devm_clk_provider_match(struct device *dev, void *res, void *data) return *np == data; } +/** + * devm_of_clk_del_provider() - Remove clock provider registered using devm + * @dev: Device to whose lifetime the clock provider was bound + */ void devm_of_clk_del_provider(struct device *dev) { int ret; + struct device_node *np = get_clk_provider_node(dev); ret = devres_release(dev, devm_of_clk_release_provider, - devm_clk_provider_match, dev->of_node); + devm_clk_provider_match, np); WARN_ON(ret); } diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h index 70c0ba6336c1..b02f5e604e69 100644 --- a/drivers/clk/clk.h +++ b/drivers/clk/clk.h @@ -1,12 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* - * linux/drivers/clk/clk.h - * * Copyright (C) 2013 Samsung Electronics Co., Ltd. * Sylwester Nawrocki <s.nawrocki@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ struct clk_hw; diff --git a/drivers/clk/h8300/clk-h8s2678.c b/drivers/clk/h8300/clk-h8s2678.c index b68045d8b921..c7ae653c8a16 100644 --- a/drivers/clk/h8300/clk-h8s2678.c +++ b/drivers/clk/h8300/clk-h8s2678.c @@ -117,7 +117,7 @@ static void __init h8s2678_pll_clk_setup(struct device_node *node) parent_name = of_clk_get_parent_name(node, 0); init.name = clk_name; init.ops = &pll_ops; - init.flags = CLK_IS_BASIC; + init.flags = 0; init.parent_names = &parent_name; init.num_parents = 1; pll_clock->hw.init = &init; diff --git a/drivers/clk/hisilicon/clk-hi3620.c b/drivers/clk/hisilicon/clk-hi3620.c index 77072c7778b9..2eda9bdf6d03 100644 --- a/drivers/clk/hisilicon/clk-hi3620.c +++ b/drivers/clk/hisilicon/clk-hi3620.c @@ -435,7 +435,7 @@ static struct clk *hisi_register_clk_mmc(struct hisi_mmc_clock *mmc_clk, init.name = mmc_clk->name; init.ops = &clk_mmc_ops; - init.flags = mmc_clk->flags | CLK_IS_BASIC; + init.flags = mmc_clk->flags; init.parent_names = (mmc_clk->parent_name ? &mmc_clk->parent_name : NULL); init.num_parents = (mmc_clk->parent_name ? 1 : 0); mclk->hw.init = &init; diff --git a/drivers/clk/hisilicon/clk-hisi-phase.c b/drivers/clk/hisilicon/clk-hisi-phase.c index 5bce9297b78b..5fdc267bb2da 100644 --- a/drivers/clk/hisilicon/clk-hisi-phase.c +++ b/drivers/clk/hisilicon/clk-hisi-phase.c @@ -103,7 +103,7 @@ struct clk *clk_register_hisi_phase(struct device *dev, init.name = clks->name; init.ops = &clk_phase_ops; - init.flags = clks->flags | CLK_IS_BASIC; + init.flags = clks->flags; init.parent_names = clks->parent_names ? &clks->parent_names : NULL; init.num_parents = clks->parent_names ? 1 : 0; diff --git a/drivers/clk/hisilicon/clk-hix5hd2.c b/drivers/clk/hisilicon/clk-hix5hd2.c index 9584f0c32dda..659bd5f493b8 100644 --- a/drivers/clk/hisilicon/clk-hix5hd2.c +++ b/drivers/clk/hisilicon/clk-hix5hd2.c @@ -274,7 +274,7 @@ hix5hd2_clk_register_complex(struct hix5hd2_complex_clock *clks, int nums, else init.ops = &clk_complex_ops; - init.flags = CLK_IS_BASIC; + init.flags = 0; init.parent_names = (clks[i].parent_name ? &clks[i].parent_name : NULL); init.num_parents = (clks[i].parent_name ? 1 : 0); diff --git a/drivers/clk/hisilicon/clkgate-separated.c b/drivers/clk/hisilicon/clkgate-separated.c index f36bdef91831..ae84884dc749 100644 --- a/drivers/clk/hisilicon/clkgate-separated.c +++ b/drivers/clk/hisilicon/clkgate-separated.c @@ -110,7 +110,7 @@ struct clk *hisi_register_clkgate_sep(struct device *dev, const char *name, init.name = name; init.ops = &clkgate_separated_ops; - init.flags = flags | CLK_IS_BASIC; + init.flags = flags; init.parent_names = (parent_name ? &parent_name : NULL); init.num_parents = (parent_name ? 1 : 0); diff --git a/drivers/clk/imgtec/clk-boston.c b/drivers/clk/imgtec/clk-boston.c index 15af423cc0c9..dddda45127a8 100644 --- a/drivers/clk/imgtec/clk-boston.c +++ b/drivers/clk/imgtec/clk-boston.c @@ -73,27 +73,40 @@ static void __init clk_boston_setup(struct device_node *np) hw = clk_hw_register_fixed_rate(NULL, "input", NULL, 0, in_freq); if (IS_ERR(hw)) { pr_err("failed to register input clock: %ld\n", PTR_ERR(hw)); - return; + goto fail_input; } onecell->hws[BOSTON_CLK_INPUT] = hw; hw = clk_hw_register_fixed_rate(NULL, "sys", "input", 0, sys_freq); if (IS_ERR(hw)) { pr_err("failed to register sys clock: %ld\n", PTR_ERR(hw)); - return; + goto fail_sys; } onecell->hws[BOSTON_CLK_SYS] = hw; hw = clk_hw_register_fixed_rate(NULL, "cpu", "input", 0, cpu_freq); if (IS_ERR(hw)) { pr_err("failed to register cpu clock: %ld\n", PTR_ERR(hw)); - return; + goto fail_cpu; } onecell->hws[BOSTON_CLK_CPU] = hw; err = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, onecell); - if (err) + if (err) { pr_err("failed to add DT provider: %d\n", err); + goto fail_clk_add; + } + + return; + +fail_clk_add: + clk_hw_unregister_fixed_rate(onecell->hws[BOSTON_CLK_CPU]); +fail_cpu: + clk_hw_unregister_fixed_rate(onecell->hws[BOSTON_CLK_SYS]); +fail_sys: + clk_hw_unregister_fixed_rate(onecell->hws[BOSTON_CLK_INPUT]); +fail_input: + kfree(onecell); } /* diff --git a/drivers/clk/loongson1/clk.c b/drivers/clk/loongson1/clk.c index cfcfd143fccb..983ce9f6edbb 100644 --- a/drivers/clk/loongson1/clk.c +++ b/drivers/clk/loongson1/clk.c @@ -10,6 +10,8 @@ #include <linux/clk-provider.h> #include <linux/slab.h> +#include "clk.h" + struct clk_hw *__init clk_hw_register_pll(struct device *dev, const char *name, const char *parent_name, @@ -27,9 +29,9 @@ struct clk_hw *__init clk_hw_register_pll(struct device *dev, init.name = name; init.ops = ops; - init.flags = flags | CLK_IS_BASIC; - init.parent_names = (parent_name ? &parent_name : NULL); - init.num_parents = (parent_name ? 1 : 0); + init.flags = flags; + init.parent_names = parent_name ? &parent_name : NULL; + init.num_parents = parent_name ? 1 : 0; hw->init = &init; /* register the clock */ diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index 3dd1dab92223..53edade25a1d 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -178,6 +178,29 @@ config COMMON_CLK_MT7622_AUDSYS This driver supports MediaTek MT7622 AUDSYS clocks providing to audio consumers such as I2S and TDM. +config COMMON_CLK_MT7629 + bool "Clock driver for MediaTek MT7629" + depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST + select COMMON_CLK_MEDIATEK + default ARCH_MEDIATEK && ARM + ---help--- + This driver supports MediaTek MT7629 basic clocks and clocks + required for various periperals found on MediaTek. + +config COMMON_CLK_MT7629_ETHSYS + bool "Clock driver for MediaTek MT7629 ETHSYS" + depends on COMMON_CLK_MT7629 + ---help--- + This driver add support for clocks for Ethernet and SGMII + required on MediaTek MT7629 SoC. + +config COMMON_CLK_MT7629_HIFSYS + bool "Clock driver for MediaTek MT7629 HIFSYS" + depends on COMMON_CLK_MT7629 + ---help--- + This driver supports MediaTek MT7629 HIFSYS clocks providing + to PCI-E and USB. + config COMMON_CLK_MT8135 bool "Clock driver for MediaTek MT8135" depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index 844b55d2770d..ee4410ff43ab 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -26,5 +26,8 @@ obj-$(CONFIG_COMMON_CLK_MT7622) += clk-mt7622.o obj-$(CONFIG_COMMON_CLK_MT7622_ETHSYS) += clk-mt7622-eth.o obj-$(CONFIG_COMMON_CLK_MT7622_HIFSYS) += clk-mt7622-hif.o obj-$(CONFIG_COMMON_CLK_MT7622_AUDSYS) += clk-mt7622-aud.o +obj-$(CONFIG_COMMON_CLK_MT7629) += clk-mt7629.o +obj-$(CONFIG_COMMON_CLK_MT7629_ETHSYS) += clk-mt7629-eth.o +obj-$(CONFIG_COMMON_CLK_MT7629_HIFSYS) += clk-mt7629-hif.o obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o obj-$(CONFIG_COMMON_CLK_MT8173) += clk-mt8173.o diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c index 16e56772d280..6c7eaa21e662 100644 --- a/drivers/clk/mediatek/clk-cpumux.c +++ b/drivers/clk/mediatek/clk-cpumux.c @@ -53,7 +53,7 @@ static const struct clk_ops clk_cpumux_ops = { .set_parent = clk_cpumux_set_parent, }; -static struct clk __init * +static struct clk * mtk_clk_register_cpumux(const struct mtk_composite *mux, struct regmap *regmap) { @@ -84,9 +84,9 @@ mtk_clk_register_cpumux(const struct mtk_composite *mux, return clk; } -int __init mtk_clk_register_cpumuxes(struct device_node *node, - const struct mtk_composite *clks, int num, - struct clk_onecell_data *clk_data) +int mtk_clk_register_cpumuxes(struct device_node *node, + const struct mtk_composite *clks, int num, + struct clk_onecell_data *clk_data) { int i; struct clk *clk; diff --git a/drivers/clk/mediatek/clk-mt7622.c b/drivers/clk/mediatek/clk-mt7622.c index 92f7e32770c6..a8aecef1ba89 100644 --- a/drivers/clk/mediatek/clk-mt7622.c +++ b/drivers/clk/mediatek/clk-mt7622.c @@ -513,7 +513,7 @@ static const struct mtk_gate peri_clks[] = { GATE_PERI1(CLK_PERI_IRTX_PD, "peri_irtx_pd", "irtx_sel", 2), }; -static struct mtk_composite infra_muxes[] __initdata = { +static struct mtk_composite infra_muxes[] = { MUX(CLK_INFRA_MUX1_SEL, "infra_mux1_sel", infra_mux1_parents, 0x000, 2, 2), }; @@ -652,7 +652,7 @@ static int mtk_topckgen_init(struct platform_device *pdev) return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); } -static int __init mtk_infrasys_init(struct platform_device *pdev) +static int mtk_infrasys_init(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; struct clk_onecell_data *clk_data; diff --git a/drivers/clk/mediatek/clk-mt7629-eth.c b/drivers/clk/mediatek/clk-mt7629-eth.c new file mode 100644 index 000000000000..88279d0ea1a7 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt7629-eth.c @@ -0,0 +1,159 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 MediaTek Inc. + * Author: Wenzhen Yu <Wenzhen Yu@mediatek.com> + * Ryder Lee <ryder.lee@mediatek.com> + */ + +#include <linux/clk-provider.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> + +#include "clk-mtk.h" +#include "clk-gate.h" + +#include <dt-bindings/clock/mt7629-clk.h> + +#define GATE_ETH(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = ð_cg_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_no_setclr_inv, \ + } + +static const struct mtk_gate_regs eth_cg_regs = { + .set_ofs = 0x30, + .clr_ofs = 0x30, + .sta_ofs = 0x30, +}; + +static const struct mtk_gate eth_clks[] = { + GATE_ETH(CLK_ETH_FE_EN, "eth_fe_en", "eth2pll", 6), + GATE_ETH(CLK_ETH_GP2_EN, "eth_gp2_en", "txclk_src_pre", 7), + GATE_ETH(CLK_ETH_GP1_EN, "eth_gp1_en", "txclk_src_pre", 8), + GATE_ETH(CLK_ETH_GP0_EN, "eth_gp0_en", "txclk_src_pre", 9), + GATE_ETH(CLK_ETH_ESW_EN, "eth_esw_en", "eth_500m", 16), +}; + +static const struct mtk_gate_regs sgmii_cg_regs = { + .set_ofs = 0xE4, + .clr_ofs = 0xE4, + .sta_ofs = 0xE4, +}; + +#define GATE_SGMII(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &sgmii_cg_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_no_setclr_inv, \ + } + +static const struct mtk_gate sgmii_clks[2][4] = { + { + GATE_SGMII(CLK_SGMII_TX_EN, "sgmii_tx_en", + "ssusb_tx250m", 2), + GATE_SGMII(CLK_SGMII_RX_EN, "sgmii_rx_en", + "ssusb_eq_rx250m", 3), + GATE_SGMII(CLK_SGMII_CDR_REF, "sgmii_cdr_ref", + "ssusb_cdr_ref", 4), + GATE_SGMII(CLK_SGMII_CDR_FB, "sgmii_cdr_fb", + "ssusb_cdr_fb", 5), + }, { + GATE_SGMII(CLK_SGMII_TX_EN, "sgmii_tx_en1", + "ssusb_tx250m", 2), + GATE_SGMII(CLK_SGMII_RX_EN, "sgmii_rx_en1", + "ssusb_eq_rx250m", 3), + GATE_SGMII(CLK_SGMII_CDR_REF, "sgmii_cdr_ref1", + "ssusb_cdr_ref", 4), + GATE_SGMII(CLK_SGMII_CDR_FB, "sgmii_cdr_fb1", + "ssusb_cdr_fb", 5), + } +}; + +static int clk_mt7629_ethsys_init(struct platform_device *pdev) +{ + struct clk_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + int r; + + clk_data = mtk_alloc_clk_data(CLK_ETH_NR_CLK); + + mtk_clk_register_gates(node, eth_clks, CLK_ETH_NR_CLK, clk_data); + + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); + if (r) + dev_err(&pdev->dev, + "could not register clock provider: %s: %d\n", + pdev->name, r); + + mtk_register_reset_controller(node, 1, 0x34); + + return r; +} + +static int clk_mt7629_sgmiisys_init(struct platform_device *pdev) +{ + struct clk_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + static int id; + int r; + + clk_data = mtk_alloc_clk_data(CLK_SGMII_NR_CLK); + + mtk_clk_register_gates(node, sgmii_clks[id++], CLK_SGMII_NR_CLK, + clk_data); + + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); + if (r) + dev_err(&pdev->dev, + "could not register clock provider: %s: %d\n", + pdev->name, r); + + return r; +} + +static const struct of_device_id of_match_clk_mt7629_eth[] = { + { + .compatible = "mediatek,mt7629-ethsys", + .data = clk_mt7629_ethsys_init, + }, { + .compatible = "mediatek,mt7629-sgmiisys", + .data = clk_mt7629_sgmiisys_init, + }, { + /* sentinel */ + } +}; + +static int clk_mt7629_eth_probe(struct platform_device *pdev) +{ + int (*clk_init)(struct platform_device *); + int r; + + clk_init = of_device_get_match_data(&pdev->dev); + if (!clk_init) + return -EINVAL; + + r = clk_init(pdev); + if (r) + dev_err(&pdev->dev, + "could not register clock provider: %s: %d\n", + pdev->name, r); + + return r; +} + +static struct platform_driver clk_mt7629_eth_drv = { + .probe = clk_mt7629_eth_probe, + .driver = { + .name = "clk-mt7629-eth", + .of_match_table = of_match_clk_mt7629_eth, + }, +}; + +builtin_platform_driver(clk_mt7629_eth_drv); diff --git a/drivers/clk/mediatek/clk-mt7629-hif.c b/drivers/clk/mediatek/clk-mt7629-hif.c new file mode 100644 index 000000000000..5c5b37207afb --- /dev/null +++ b/drivers/clk/mediatek/clk-mt7629-hif.c @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 MediaTek Inc. + * Author: Wenzhen Yu <Wenzhen Yu@mediatek.com> + * Ryder Lee <ryder.lee@mediatek.com> + */ + +#include <linux/clk-provider.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> + +#include "clk-mtk.h" +#include "clk-gate.h" + +#include <dt-bindings/clock/mt7629-clk.h> + +#define GATE_PCIE(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &pcie_cg_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_no_setclr_inv, \ + } + +#define GATE_SSUSB(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ssusb_cg_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_no_setclr_inv, \ + } + +static const struct mtk_gate_regs pcie_cg_regs = { + .set_ofs = 0x30, + .clr_ofs = 0x30, + .sta_ofs = 0x30, +}; + +static const struct mtk_gate_regs ssusb_cg_regs = { + .set_ofs = 0x30, + .clr_ofs = 0x30, + .sta_ofs = 0x30, +}; + +static const struct mtk_gate ssusb_clks[] = { + GATE_SSUSB(CLK_SSUSB_U2_PHY_1P_EN, "ssusb_u2_phy_1p", + "to_u2_phy_1p", 0), + GATE_SSUSB(CLK_SSUSB_U2_PHY_EN, "ssusb_u2_phy_en", "to_u2_phy", 1), + GATE_SSUSB(CLK_SSUSB_REF_EN, "ssusb_ref_en", "to_usb3_ref", 5), + GATE_SSUSB(CLK_SSUSB_SYS_EN, "ssusb_sys_en", "to_usb3_sys", 6), + GATE_SSUSB(CLK_SSUSB_MCU_EN, "ssusb_mcu_en", "to_usb3_mcu", 7), + GATE_SSUSB(CLK_SSUSB_DMA_EN, "ssusb_dma_en", "to_usb3_dma", 8), +}; + +static const struct mtk_gate pcie_clks[] = { + GATE_PCIE(CLK_PCIE_P1_AUX_EN, "pcie_p1_aux_en", "p1_1mhz", 12), + GATE_PCIE(CLK_PCIE_P1_OBFF_EN, "pcie_p1_obff_en", "free_run_4mhz", 13), + GATE_PCIE(CLK_PCIE_P1_AHB_EN, "pcie_p1_ahb_en", "from_top_ahb", 14), + GATE_PCIE(CLK_PCIE_P1_AXI_EN, "pcie_p1_axi_en", "from_top_axi", 15), + GATE_PCIE(CLK_PCIE_P1_MAC_EN, "pcie_p1_mac_en", "pcie1_mac_en", 16), + GATE_PCIE(CLK_PCIE_P1_PIPE_EN, "pcie_p1_pipe_en", "pcie1_pipe_en", 17), + GATE_PCIE(CLK_PCIE_P0_AUX_EN, "pcie_p0_aux_en", "p0_1mhz", 18), + GATE_PCIE(CLK_PCIE_P0_OBFF_EN, "pcie_p0_obff_en", "free_run_4mhz", 19), + GATE_PCIE(CLK_PCIE_P0_AHB_EN, "pcie_p0_ahb_en", "from_top_ahb", 20), + GATE_PCIE(CLK_PCIE_P0_AXI_EN, "pcie_p0_axi_en", "from_top_axi", 21), + GATE_PCIE(CLK_PCIE_P0_MAC_EN, "pcie_p0_mac_en", "pcie0_mac_en", 22), + GATE_PCIE(CLK_PCIE_P0_PIPE_EN, "pcie_p0_pipe_en", "pcie0_pipe_en", 23), +}; + +static int clk_mt7629_ssusbsys_init(struct platform_device *pdev) +{ + struct clk_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + int r; + + clk_data = mtk_alloc_clk_data(CLK_SSUSB_NR_CLK); + + mtk_clk_register_gates(node, ssusb_clks, ARRAY_SIZE(ssusb_clks), + clk_data); + + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); + if (r) + dev_err(&pdev->dev, + "could not register clock provider: %s: %d\n", + pdev->name, r); + + mtk_register_reset_controller(node, 1, 0x34); + + return r; +} + +static int clk_mt7629_pciesys_init(struct platform_device *pdev) +{ + struct clk_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + int r; + + clk_data = mtk_alloc_clk_data(CLK_PCIE_NR_CLK); + + mtk_clk_register_gates(node, pcie_clks, ARRAY_SIZE(pcie_clks), + clk_data); + + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); + if (r) + dev_err(&pdev->dev, + "could not register clock provider: %s: %d\n", + pdev->name, r); + + mtk_register_reset_controller(node, 1, 0x34); + + return r; +} + +static const struct of_device_id of_match_clk_mt7629_hif[] = { + { + .compatible = "mediatek,mt7629-pciesys", + .data = clk_mt7629_pciesys_init, + }, { + .compatible = "mediatek,mt7629-ssusbsys", + .data = clk_mt7629_ssusbsys_init, + }, { + /* sentinel */ + } +}; + +static int clk_mt7629_hif_probe(struct platform_device *pdev) +{ + int (*clk_init)(struct platform_device *); + int r; + + clk_init = of_device_get_match_data(&pdev->dev); + if (!clk_init) + return -EINVAL; + + r = clk_init(pdev); + if (r) + dev_err(&pdev->dev, + "could not register clock provider: %s: %d\n", + pdev->name, r); + + return r; +} + +static struct platform_driver clk_mt7629_hif_drv = { + .probe = clk_mt7629_hif_probe, + .driver = { + .name = "clk-mt7629-hif", + .of_match_table = of_match_clk_mt7629_hif, + }, +}; + +builtin_platform_driver(clk_mt7629_hif_drv); diff --git a/drivers/clk/mediatek/clk-mt7629.c b/drivers/clk/mediatek/clk-mt7629.c new file mode 100644 index 000000000000..d6233994af5a --- /dev/null +++ b/drivers/clk/mediatek/clk-mt7629.c @@ -0,0 +1,723 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 MediaTek Inc. + * Author: Wenzhen Yu <Wenzhen Yu@mediatek.com> + * Ryder Lee <ryder.lee@mediatek.com> + */ + +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> + +#include "clk-mtk.h" +#include "clk-gate.h" +#include "clk-cpumux.h" + +#include <dt-bindings/clock/mt7629-clk.h> + +#define MT7629_PLL_FMAX (2500UL * MHZ) +#define CON0_MT7629_RST_BAR BIT(24) + +#define PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \ + _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, \ + _pcw_shift, _div_table, _parent_name) { \ + .id = _id, \ + .name = _name, \ + .reg = _reg, \ + .pwr_reg = _pwr_reg, \ + .en_mask = _en_mask, \ + .flags = _flags, \ + .rst_bar_mask = CON0_MT7629_RST_BAR, \ + .fmax = MT7629_PLL_FMAX, \ + .pcwbits = _pcwbits, \ + .pd_reg = _pd_reg, \ + .pd_shift = _pd_shift, \ + .tuner_reg = _tuner_reg, \ + .pcw_reg = _pcw_reg, \ + .pcw_shift = _pcw_shift, \ + .div_table = _div_table, \ + .parent_name = _parent_name, \ + } + +#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \ + _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, \ + _pcw_shift) \ + PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \ + _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift, \ + NULL, "clk20m") + +#define GATE_APMIXED(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &apmixed_cg_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_no_setclr_inv, \ + } + +#define GATE_INFRA(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &infra_cg_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +#define GATE_PERI0(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &peri0_cg_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +#define GATE_PERI1(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &peri1_cg_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +static DEFINE_SPINLOCK(mt7629_clk_lock); + +static const char * const axi_parents[] = { + "clkxtal", + "syspll1_d2", + "syspll_d5", + "syspll1_d4", + "univpll_d5", + "univpll2_d2", + "univpll_d7", + "dmpll_ck" +}; + +static const char * const mem_parents[] = { + "clkxtal", + "dmpll_ck" +}; + +static const char * const ddrphycfg_parents[] = { + "clkxtal", + "syspll1_d8" +}; + +static const char * const eth_parents[] = { + "clkxtal", + "syspll1_d2", + "univpll1_d2", + "syspll1_d4", + "univpll_d5", + "sgmiipll_d2", + "univpll_d7", + "dmpll_ck" +}; + +static const char * const pwm_parents[] = { + "clkxtal", + "univpll2_d4" +}; + +static const char * const f10m_ref_parents[] = { + "clkxtal", + "sgmiipll_d2" +}; + +static const char * const nfi_infra_parents[] = { + "clkxtal", + "clkxtal", + "clkxtal", + "clkxtal", + "clkxtal", + "clkxtal", + "univpll2_d8", + "univpll3_d4", + "syspll1_d8", + "univpll1_d8", + "syspll4_d2", + "syspll2_d4", + "univpll2_d4", + "univpll3_d2", + "syspll1_d4", + "syspll_d7" +}; + +static const char * const flash_parents[] = { + "clkxtal", + "univpll_d80_d4", + "syspll2_d8", + "syspll3_d4", + "univpll3_d4", + "univpll1_d8", + "syspll2_d4", + "univpll2_d4" +}; + +static const char * const uart_parents[] = { + "clkxtal", + "univpll2_d8" +}; + +static const char * const spi0_parents[] = { + "clkxtal", + "syspll3_d2", + "clkxtal", + "syspll2_d4", + "syspll4_d2", + "univpll2_d4", + "univpll1_d8", + "clkxtal" +}; + +static const char * const spi1_parents[] = { + "clkxtal", + "syspll3_d2", + "clkxtal", + "syspll4_d4", + "syspll4_d2", + "univpll2_d4", + "univpll1_d8", + "clkxtal" +}; + +static const char * const msdc30_0_parents[] = { + "clkxtal", + "univpll2_d16", + "univ48m" +}; + +static const char * const msdc30_1_parents[] = { + "clkxtal", + "univpll2_d16", + "univ48m", + "syspll2_d4", + "univpll2_d4", + "syspll_d7", + "syspll2_d2", + "univpll2_d2" +}; + +static const char * const ap2wbmcu_parents[] = { + "clkxtal", + "syspll1_d2", + "univ48m", + "syspll1_d8", + "univpll2_d4", + "syspll_d7", + "syspll2_d2", + "univpll2_d2" +}; + +static const char * const audio_parents[] = { + "clkxtal", + "syspll3_d4", + "syspll4_d4", + "syspll1_d16" +}; + +static const char * const aud_intbus_parents[] = { + "clkxtal", + "syspll1_d4", + "syspll4_d2", + "dmpll_d4" +}; + +static const char * const pmicspi_parents[] = { + "clkxtal", + "syspll1_d8", + "syspll3_d4", + "syspll1_d16", + "univpll3_d4", + "clkxtal", + "univpll2_d4", + "dmpll_d8" +}; + +static const char * const scp_parents[] = { + "clkxtal", + "syspll1_d8", + "univpll2_d2", + "univpll2_d4" +}; + +static const char * const atb_parents[] = { + "clkxtal", + "syspll1_d2", + "syspll_d5" +}; + +static const char * const hif_parents[] = { + "clkxtal", + "syspll1_d2", + "univpll1_d2", + "syspll1_d4", + "univpll_d5", + "clk_null", + "univpll_d7" +}; + +static const char * const sata_parents[] = { + "clkxtal", + "univpll2_d4" +}; + +static const char * const usb20_parents[] = { + "clkxtal", + "univpll3_d4", + "syspll1_d8" +}; + +static const char * const aud1_parents[] = { + "clkxtal" +}; + +static const char * const irrx_parents[] = { + "clkxtal", + "syspll4_d16" +}; + +static const char * const crypto_parents[] = { + "clkxtal", + "univpll_d3", + "univpll1_d2", + "syspll1_d2", + "univpll_d5", + "syspll_d5", + "univpll2_d2", + "syspll_d2" +}; + +static const char * const gpt10m_parents[] = { + "clkxtal", + "clkxtal_d4" +}; + +static const char * const peribus_ck_parents[] = { + "syspll1_d8", + "syspll1_d4" +}; + +static const char * const infra_mux1_parents[] = { + "clkxtal", + "armpll", + "main_core_en", + "armpll" +}; + +static const struct mtk_gate_regs apmixed_cg_regs = { + .set_ofs = 0x8, + .clr_ofs = 0x8, + .sta_ofs = 0x8, +}; + +static const struct mtk_gate_regs infra_cg_regs = { + .set_ofs = 0x40, + .clr_ofs = 0x44, + .sta_ofs = 0x48, +}; + +static const struct mtk_gate_regs peri0_cg_regs = { + .set_ofs = 0x8, + .clr_ofs = 0x10, + .sta_ofs = 0x18, +}; + +static const struct mtk_gate_regs peri1_cg_regs = { + .set_ofs = 0xC, + .clr_ofs = 0x14, + .sta_ofs = 0x1C, +}; + +static const struct mtk_pll_data plls[] = { + PLL(CLK_APMIXED_ARMPLL, "armpll", 0x0200, 0x020C, 0x00000001, + 0, 21, 0x0204, 24, 0, 0x0204, 0), + PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x0210, 0x021C, 0x00000001, + HAVE_RST_BAR, 21, 0x0214, 24, 0, 0x0214, 0), + PLL(CLK_APMIXED_UNIV2PLL, "univ2pll", 0x0220, 0x022C, 0x00000001, + HAVE_RST_BAR, 7, 0x0224, 24, 0, 0x0224, 14), + PLL(CLK_APMIXED_ETH1PLL, "eth1pll", 0x0300, 0x0310, 0x00000001, + 0, 21, 0x0300, 1, 0, 0x0304, 0), + PLL(CLK_APMIXED_ETH2PLL, "eth2pll", 0x0314, 0x0320, 0x00000001, + 0, 21, 0x0314, 1, 0, 0x0318, 0), + PLL(CLK_APMIXED_SGMIPLL, "sgmipll", 0x0358, 0x0368, 0x00000001, + 0, 21, 0x0358, 1, 0, 0x035C, 0), +}; + +static const struct mtk_gate apmixed_clks[] = { + GATE_APMIXED(CLK_APMIXED_MAIN_CORE_EN, "main_core_en", "mainpll", 5), +}; + +static const struct mtk_gate infra_clks[] = { + GATE_INFRA(CLK_INFRA_DBGCLK_PD, "infra_dbgclk_pd", "hd_faxi", 0), + GATE_INFRA(CLK_INFRA_TRNG_PD, "infra_trng_pd", "hd_faxi", 2), + GATE_INFRA(CLK_INFRA_DEVAPC_PD, "infra_devapc_pd", "hd_faxi", 4), + GATE_INFRA(CLK_INFRA_APXGPT_PD, "infra_apxgpt_pd", "infrao_10m", 18), + GATE_INFRA(CLK_INFRA_SEJ_PD, "infra_sej_pd", "infrao_10m", 19), +}; + +static const struct mtk_fixed_clk top_fixed_clks[] = { + FIXED_CLK(CLK_TOP_TO_U2_PHY, "to_u2_phy", "clkxtal", + 31250000), + FIXED_CLK(CLK_TOP_TO_U2_PHY_1P, "to_u2_phy_1p", "clkxtal", + 31250000), + FIXED_CLK(CLK_TOP_PCIE0_PIPE_EN, "pcie0_pipe_en", "clkxtal", + 125000000), + FIXED_CLK(CLK_TOP_PCIE1_PIPE_EN, "pcie1_pipe_en", "clkxtal", + 125000000), + FIXED_CLK(CLK_TOP_SSUSB_TX250M, "ssusb_tx250m", "clkxtal", + 250000000), + FIXED_CLK(CLK_TOP_SSUSB_EQ_RX250M, "ssusb_eq_rx250m", "clkxtal", + 250000000), + FIXED_CLK(CLK_TOP_SSUSB_CDR_REF, "ssusb_cdr_ref", "clkxtal", + 33333333), + FIXED_CLK(CLK_TOP_SSUSB_CDR_FB, "ssusb_cdr_fb", "clkxtal", + 50000000), + FIXED_CLK(CLK_TOP_SATA_ASIC, "sata_asic", "clkxtal", + 50000000), + FIXED_CLK(CLK_TOP_SATA_RBC, "sata_rbc", "clkxtal", + 50000000), +}; + +static const struct mtk_fixed_factor top_divs[] = { + FACTOR(CLK_TOP_TO_USB3_SYS, "to_usb3_sys", "eth1pll", 1, 4), + FACTOR(CLK_TOP_P1_1MHZ, "p1_1mhz", "eth1pll", 1, 500), + FACTOR(CLK_TOP_4MHZ, "free_run_4mhz", "eth1pll", 1, 125), + FACTOR(CLK_TOP_P0_1MHZ, "p0_1mhz", "eth1pll", 1, 500), + FACTOR(CLK_TOP_ETH_500M, "eth_500m", "eth1pll", 1, 1), + FACTOR(CLK_TOP_TXCLK_SRC_PRE, "txclk_src_pre", "sgmiipll_d2", 1, 1), + FACTOR(CLK_TOP_RTC, "rtc", "clkxtal", 1, 1024), + FACTOR(CLK_TOP_PWM_QTR_26M, "pwm_qtr_26m", "clkxtal", 1, 1), + FACTOR(CLK_TOP_CPUM_TCK_IN, "cpum_tck_in", "cpum_tck", 1, 1), + FACTOR(CLK_TOP_TO_USB3_DA_TOP, "to_usb3_da_top", "clkxtal", 1, 1), + FACTOR(CLK_TOP_MEMPLL, "mempll", "clkxtal", 32, 1), + FACTOR(CLK_TOP_DMPLL, "dmpll_ck", "mempll", 1, 1), + FACTOR(CLK_TOP_DMPLL_D4, "dmpll_d4", "mempll", 1, 4), + FACTOR(CLK_TOP_DMPLL_D8, "dmpll_d8", "mempll", 1, 8), + FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "mainpll", 1, 2), + FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "mainpll", 1, 4), + FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "mainpll", 1, 8), + FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "mainpll", 1, 16), + FACTOR(CLK_TOP_SYSPLL1_D16, "syspll1_d16", "mainpll", 1, 32), + FACTOR(CLK_TOP_SYSPLL2_D2, "syspll2_d2", "mainpll", 1, 6), + FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "mainpll", 1, 12), + FACTOR(CLK_TOP_SYSPLL2_D8, "syspll2_d8", "mainpll", 1, 24), + FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll", 1, 5), + FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "mainpll", 1, 10), + FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "mainpll", 1, 20), + FACTOR(CLK_TOP_SYSPLL_D7, "syspll_d7", "mainpll", 1, 7), + FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "mainpll", 1, 14), + FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "mainpll", 1, 28), + FACTOR(CLK_TOP_SYSPLL4_D16, "syspll4_d16", "mainpll", 1, 112), + FACTOR(CLK_TOP_UNIVPLL, "univpll", "univ2pll", 1, 2), + FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll", 1, 4), + FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll", 1, 8), + FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll", 1, 16), + FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll", 1, 3), + FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll", 1, 6), + FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll", 1, 12), + FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll", 1, 24), + FACTOR(CLK_TOP_UNIVPLL2_D16, "univpll2_d16", "univpll", 1, 48), + FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5), + FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2", "univpll", 1, 10), + FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4", "univpll", 1, 20), + FACTOR(CLK_TOP_UNIVPLL3_D16, "univpll3_d16", "univpll", 1, 80), + FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll", 1, 7), + FACTOR(CLK_TOP_UNIVPLL_D80_D4, "univpll_d80_d4", "univpll", 1, 320), + FACTOR(CLK_TOP_UNIV48M, "univ48m", "univpll", 1, 25), + FACTOR(CLK_TOP_SGMIIPLL_D2, "sgmiipll_d2", "sgmipll", 1, 2), + FACTOR(CLK_TOP_CLKXTAL_D4, "clkxtal_d4", "clkxtal", 1, 4), + FACTOR(CLK_TOP_HD_FAXI, "hd_faxi", "axi_sel", 1, 1), + FACTOR(CLK_TOP_FAXI, "faxi", "axi_sel", 1, 1), + FACTOR(CLK_TOP_F_FAUD_INTBUS, "f_faud_intbus", "aud_intbus_sel", 1, 1), + FACTOR(CLK_TOP_AP2WBHIF_HCLK, "ap2wbhif_hclk", "syspll1_d8", 1, 1), + FACTOR(CLK_TOP_10M_INFRAO, "infrao_10m", "gpt10m_sel", 1, 1), + FACTOR(CLK_TOP_MSDC30_1, "msdc30_1", "msdc30_1_sel", 1, 1), + FACTOR(CLK_TOP_SPI, "spi", "spi0_sel", 1, 1), + FACTOR(CLK_TOP_SF, "sf", "nfi_infra_sel", 1, 1), + FACTOR(CLK_TOP_FLASH, "flash", "flash_sel", 1, 1), + FACTOR(CLK_TOP_TO_USB3_REF, "to_usb3_ref", "sata_sel", 1, 4), + FACTOR(CLK_TOP_TO_USB3_MCU, "to_usb3_mcu", "axi_sel", 1, 1), + FACTOR(CLK_TOP_TO_USB3_DMA, "to_usb3_dma", "hif_sel", 1, 1), + FACTOR(CLK_TOP_FROM_TOP_AHB, "from_top_ahb", "axi_sel", 1, 1), + FACTOR(CLK_TOP_FROM_TOP_AXI, "from_top_axi", "hif_sel", 1, 1), + FACTOR(CLK_TOP_PCIE1_MAC_EN, "pcie1_mac_en", "sata_sel", 1, 1), + FACTOR(CLK_TOP_PCIE0_MAC_EN, "pcie0_mac_en", "sata_sel", 1, 1), +}; + +static const struct mtk_gate peri_clks[] = { + /* PERI0 */ + GATE_PERI0(CLK_PERI_PWM1_PD, "peri_pwm1_pd", "pwm_qtr_26m", 2), + GATE_PERI0(CLK_PERI_PWM2_PD, "peri_pwm2_pd", "pwm_qtr_26m", 3), + GATE_PERI0(CLK_PERI_PWM3_PD, "peri_pwm3_pd", "pwm_qtr_26m", 4), + GATE_PERI0(CLK_PERI_PWM4_PD, "peri_pwm4_pd", "pwm_qtr_26m", 5), + GATE_PERI0(CLK_PERI_PWM5_PD, "peri_pwm5_pd", "pwm_qtr_26m", 6), + GATE_PERI0(CLK_PERI_PWM6_PD, "peri_pwm6_pd", "pwm_qtr_26m", 7), + GATE_PERI0(CLK_PERI_PWM7_PD, "peri_pwm7_pd", "pwm_qtr_26m", 8), + GATE_PERI0(CLK_PERI_PWM_PD, "peri_pwm_pd", "pwm_qtr_26m", 9), + GATE_PERI0(CLK_PERI_AP_DMA_PD, "peri_ap_dma_pd", "faxi", 12), + GATE_PERI0(CLK_PERI_MSDC30_1_PD, "peri_msdc30_1", "msdc30_1", 14), + GATE_PERI0(CLK_PERI_UART0_PD, "peri_uart0_pd", "faxi", 17), + GATE_PERI0(CLK_PERI_UART1_PD, "peri_uart1_pd", "faxi", 18), + GATE_PERI0(CLK_PERI_UART2_PD, "peri_uart2_pd", "faxi", 19), + GATE_PERI0(CLK_PERI_UART3_PD, "peri_uart3_pd", "faxi", 20), + GATE_PERI0(CLK_PERI_BTIF_PD, "peri_btif_pd", "faxi", 22), + GATE_PERI0(CLK_PERI_I2C0_PD, "peri_i2c0_pd", "faxi", 23), + GATE_PERI0(CLK_PERI_SPI0_PD, "peri_spi0_pd", "spi", 28), + GATE_PERI0(CLK_PERI_SNFI_PD, "peri_snfi_pd", "sf", 29), + GATE_PERI0(CLK_PERI_NFI_PD, "peri_nfi_pd", "faxi", 30), + GATE_PERI0(CLK_PERI_NFIECC_PD, "peri_nfiecc_pd", "faxi", 31), + /* PERI1 */ + GATE_PERI1(CLK_PERI_FLASH_PD, "peri_flash_pd", "flash", 1), +}; + +static struct mtk_composite infra_muxes[] = { + /* INFRA_TOPCKGEN_CKMUXSEL */ + MUX(CLK_INFRA_MUX1_SEL, "infra_mux1_sel", infra_mux1_parents, 0x000, + 2, 2), +}; + +static struct mtk_composite top_muxes[] = { + /* CLK_CFG_0 */ + MUX_GATE(CLK_TOP_AXI_SEL, "axi_sel", axi_parents, + 0x040, 0, 3, 7), + MUX_GATE(CLK_TOP_MEM_SEL, "mem_sel", mem_parents, + 0x040, 8, 1, 15), + MUX_GATE(CLK_TOP_DDRPHYCFG_SEL, "ddrphycfg_sel", ddrphycfg_parents, + 0x040, 16, 1, 23), + MUX_GATE(CLK_TOP_ETH_SEL, "eth_sel", eth_parents, + 0x040, 24, 3, 31), + /* CLK_CFG_1 */ + MUX_GATE(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents, + 0x050, 0, 2, 7), + MUX_GATE(CLK_TOP_F10M_REF_SEL, "f10m_ref_sel", f10m_ref_parents, + 0x050, 8, 1, 15), + MUX_GATE(CLK_TOP_NFI_INFRA_SEL, "nfi_infra_sel", nfi_infra_parents, + 0x050, 16, 4, 23), + MUX_GATE(CLK_TOP_FLASH_SEL, "flash_sel", flash_parents, + 0x050, 24, 3, 31), + /* CLK_CFG_2 */ + MUX_GATE(CLK_TOP_UART_SEL, "uart_sel", uart_parents, + 0x060, 0, 1, 7), + MUX_GATE(CLK_TOP_SPI0_SEL, "spi0_sel", spi0_parents, + 0x060, 8, 3, 15), + MUX_GATE(CLK_TOP_SPI1_SEL, "spi1_sel", spi1_parents, + 0x060, 16, 3, 23), + MUX_GATE(CLK_TOP_MSDC50_0_SEL, "msdc50_0_sel", uart_parents, + 0x060, 24, 3, 31), + /* CLK_CFG_3 */ + MUX_GATE(CLK_TOP_MSDC30_0_SEL, "msdc30_0_sel", msdc30_0_parents, + 0x070, 0, 3, 7), + MUX_GATE(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_1_parents, + 0x070, 8, 3, 15), + MUX_GATE(CLK_TOP_AP2WBMCU_SEL, "ap2wbmcu_sel", ap2wbmcu_parents, + 0x070, 16, 3, 23), + MUX_GATE(CLK_TOP_AP2WBHIF_SEL, "ap2wbhif_sel", ap2wbmcu_parents, + 0x070, 24, 3, 31), + /* CLK_CFG_4 */ + MUX_GATE(CLK_TOP_AUDIO_SEL, "audio_sel", audio_parents, + 0x080, 0, 2, 7), + MUX_GATE(CLK_TOP_AUD_INTBUS_SEL, "aud_intbus_sel", aud_intbus_parents, + 0x080, 8, 2, 15), + MUX_GATE(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents, + 0x080, 16, 3, 23), + MUX_GATE(CLK_TOP_SCP_SEL, "scp_sel", scp_parents, + 0x080, 24, 2, 31), + /* CLK_CFG_5 */ + MUX_GATE(CLK_TOP_ATB_SEL, "atb_sel", atb_parents, + 0x090, 0, 2, 7), + MUX_GATE(CLK_TOP_HIF_SEL, "hif_sel", hif_parents, + 0x090, 8, 3, 15), + MUX_GATE(CLK_TOP_SATA_SEL, "sata_sel", sata_parents, + 0x090, 16, 1, 23), + MUX_GATE(CLK_TOP_U2_SEL, "usb20_sel", usb20_parents, + 0x090, 24, 2, 31), + /* CLK_CFG_6 */ + MUX_GATE(CLK_TOP_AUD1_SEL, "aud1_sel", aud1_parents, + 0x0A0, 0, 1, 7), + MUX_GATE(CLK_TOP_AUD2_SEL, "aud2_sel", aud1_parents, + 0x0A0, 8, 1, 15), + MUX_GATE(CLK_TOP_IRRX_SEL, "irrx_sel", irrx_parents, + 0x0A0, 16, 1, 23), + MUX_GATE(CLK_TOP_IRTX_SEL, "irtx_sel", irrx_parents, + 0x0A0, 24, 1, 31), + /* CLK_CFG_7 */ + MUX_GATE(CLK_TOP_SATA_MCU_SEL, "sata_mcu_sel", scp_parents, + 0x0B0, 0, 2, 7), + MUX_GATE(CLK_TOP_PCIE0_MCU_SEL, "pcie0_mcu_sel", scp_parents, + 0x0B0, 8, 2, 15), + MUX_GATE(CLK_TOP_PCIE1_MCU_SEL, "pcie1_mcu_sel", scp_parents, + 0x0B0, 16, 2, 23), + MUX_GATE(CLK_TOP_SSUSB_MCU_SEL, "ssusb_mcu_sel", scp_parents, + 0x0B0, 24, 2, 31), + /* CLK_CFG_8 */ + MUX_GATE(CLK_TOP_CRYPTO_SEL, "crypto_sel", crypto_parents, + 0x0C0, 0, 3, 7), + MUX_GATE(CLK_TOP_SGMII_REF_1_SEL, "sgmii_ref_1_sel", f10m_ref_parents, + 0x0C0, 8, 1, 15), + MUX_GATE(CLK_TOP_10M_SEL, "gpt10m_sel", gpt10m_parents, + 0x0C0, 16, 1, 23), +}; + +static struct mtk_composite peri_muxes[] = { + /* PERI_GLOBALCON_CKSEL */ + MUX(CLK_PERIBUS_SEL, "peribus_ck_sel", peribus_ck_parents, 0x05C, 0, 1), +}; + +static int mtk_topckgen_init(struct platform_device *pdev) +{ + struct clk_onecell_data *clk_data; + void __iomem *base; + struct device_node *node = pdev->dev.of_node; + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK); + + mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), + clk_data); + + mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), + clk_data); + + mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), + base, &mt7629_clk_lock, clk_data); + + clk_prepare_enable(clk_data->clks[CLK_TOP_AXI_SEL]); + clk_prepare_enable(clk_data->clks[CLK_TOP_MEM_SEL]); + clk_prepare_enable(clk_data->clks[CLK_TOP_DDRPHYCFG_SEL]); + + return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); +} + +static int mtk_infrasys_init(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + struct clk_onecell_data *clk_data; + int r; + + clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK); + + mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks), + clk_data); + + mtk_clk_register_cpumuxes(node, infra_muxes, ARRAY_SIZE(infra_muxes), + clk_data); + + r = of_clk_add_provider(node, of_clk_src_onecell_get, + clk_data); + if (r) + return r; + + return 0; +} + +static int mtk_pericfg_init(struct platform_device *pdev) +{ + struct clk_onecell_data *clk_data; + void __iomem *base; + int r; + struct device_node *node = pdev->dev.of_node; + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK); + + mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks), + clk_data); + + mtk_clk_register_composites(peri_muxes, ARRAY_SIZE(peri_muxes), base, + &mt7629_clk_lock, clk_data); + + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); + if (r) + return r; + + clk_prepare_enable(clk_data->clks[CLK_PERI_UART0_PD]); + + return 0; +} + +static int mtk_apmixedsys_init(struct platform_device *pdev) +{ + struct clk_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + + clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK); + if (!clk_data) + return -ENOMEM; + + mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), + clk_data); + + mtk_clk_register_gates(node, apmixed_clks, + ARRAY_SIZE(apmixed_clks), clk_data); + + clk_prepare_enable(clk_data->clks[CLK_APMIXED_ARMPLL]); + clk_prepare_enable(clk_data->clks[CLK_APMIXED_MAIN_CORE_EN]); + + return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); +} + + +static const struct of_device_id of_match_clk_mt7629[] = { + { + .compatible = "mediatek,mt7629-apmixedsys", + .data = mtk_apmixedsys_init, + }, { + .compatible = "mediatek,mt7629-infracfg", + .data = mtk_infrasys_init, + }, { + .compatible = "mediatek,mt7629-topckgen", + .data = mtk_topckgen_init, + }, { + .compatible = "mediatek,mt7629-pericfg", + .data = mtk_pericfg_init, + }, { + /* sentinel */ + } +}; + +static int clk_mt7629_probe(struct platform_device *pdev) +{ + int (*clk_init)(struct platform_device *); + int r; + + clk_init = of_device_get_match_data(&pdev->dev); + if (!clk_init) + return -EINVAL; + + r = clk_init(pdev); + if (r) + dev_err(&pdev->dev, + "could not register clock provider: %s: %d\n", + pdev->name, r); + + return r; +} + +static struct platform_driver clk_mt7629_drv = { + .probe = clk_mt7629_probe, + .driver = { + .name = "clk-mt7629", + .of_match_table = of_match_clk_mt7629, + }, +}; + +static int clk_mt7629_init(void) +{ + return platform_driver_register(&clk_mt7629_drv); +} + +arch_initcall(clk_mt7629_init); diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index a611531df115..1b1ba54e33dd 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -9,16 +9,17 @@ config QCOM_GDSC config QCOM_RPMCC bool -config COMMON_CLK_QCOM +menuconfig COMMON_CLK_QCOM tristate "Support for Qualcomm's clock controllers" depends on OF depends on ARCH_QCOM || COMPILE_TEST select REGMAP_MMIO select RESET_CONTROLLER +if COMMON_CLK_QCOM + config QCOM_A53PLL tristate "MSM8916 A53 PLL" - depends on COMMON_CLK_QCOM default ARCH_QCOM help Support for the A53 PLL on MSM8916 devices. It provides @@ -28,7 +29,6 @@ config QCOM_A53PLL config QCOM_CLK_APCS_MSM8916 tristate "MSM8916 APCS Clock Controller" - depends on COMMON_CLK_QCOM depends on QCOM_APCS_IPC || COMPILE_TEST default ARCH_QCOM help @@ -39,7 +39,7 @@ config QCOM_CLK_APCS_MSM8916 config QCOM_CLK_RPM tristate "RPM based Clock Controller" - depends on COMMON_CLK_QCOM && MFD_QCOM_RPM + depends on MFD_QCOM_RPM select QCOM_RPMCC help The RPM (Resource Power Manager) is a dedicated hardware engine for @@ -52,7 +52,7 @@ config QCOM_CLK_RPM config QCOM_CLK_SMD_RPM tristate "RPM over SMD based Clock Controller" - depends on COMMON_CLK_QCOM && QCOM_SMD_RPM + depends on QCOM_SMD_RPM select QCOM_RPMCC help The RPM (Resource Power Manager) is a dedicated hardware engine for @@ -65,7 +65,7 @@ config QCOM_CLK_SMD_RPM config QCOM_CLK_RPMH tristate "RPMh Clock Driver" - depends on COMMON_CLK_QCOM && QCOM_RPMH + depends on QCOM_RPMH help RPMh manages shared resources on some Qualcomm Technologies, Inc. SoCs. It accepts requests from other hardware subsystems via RSC. @@ -75,7 +75,6 @@ config QCOM_CLK_RPMH config APQ_GCC_8084 tristate "APQ8084 Global Clock Controller" select QCOM_GDSC - depends on COMMON_CLK_QCOM help Support for the global clock controller on apq8084 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -85,7 +84,6 @@ config APQ_MMCC_8084 tristate "APQ8084 Multimedia Clock Controller" select APQ_GCC_8084 select QCOM_GDSC - depends on COMMON_CLK_QCOM help Support for the multimedia clock controller on apq8084 devices. Say Y if you want to support multimedia devices such as display, @@ -93,7 +91,6 @@ config APQ_MMCC_8084 config IPQ_GCC_4019 tristate "IPQ4019 Global Clock Controller" - depends on COMMON_CLK_QCOM help Support for the global clock controller on ipq4019 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -101,7 +98,6 @@ config IPQ_GCC_4019 config IPQ_GCC_806X tristate "IPQ806x Global Clock Controller" - depends on COMMON_CLK_QCOM help Support for the global clock controller on ipq806x devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -110,7 +106,6 @@ config IPQ_GCC_806X config IPQ_LCC_806X tristate "IPQ806x LPASS Clock Controller" select IPQ_GCC_806X - depends on COMMON_CLK_QCOM help Support for the LPASS clock controller on ipq806x devices. Say Y if you want to use audio devices such as i2s, pcm, @@ -118,7 +113,6 @@ config IPQ_LCC_806X config IPQ_GCC_8074 tristate "IPQ8074 Global Clock Controller" - depends on COMMON_CLK_QCOM help Support for global clock controller on ipq8074 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -127,7 +121,6 @@ config IPQ_GCC_8074 config MSM_GCC_8660 tristate "MSM8660 Global Clock Controller" - depends on COMMON_CLK_QCOM help Support for the global clock controller on msm8660 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -136,7 +129,6 @@ config MSM_GCC_8660 config MSM_GCC_8916 tristate "MSM8916 Global Clock Controller" select QCOM_GDSC - depends on COMMON_CLK_QCOM help Support for the global clock controller on msm8916 devices. Say Y if you want to use devices such as UART, SPI i2c, USB, @@ -144,7 +136,6 @@ config MSM_GCC_8916 config MSM_GCC_8960 tristate "APQ8064/MSM8960 Global Clock Controller" - depends on COMMON_CLK_QCOM help Support for the global clock controller on apq8064/msm8960 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -153,7 +144,6 @@ config MSM_GCC_8960 config MSM_LCC_8960 tristate "APQ8064/MSM8960 LPASS Clock Controller" select MSM_GCC_8960 - depends on COMMON_CLK_QCOM help Support for the LPASS clock controller on apq8064/msm8960 devices. Say Y if you want to use audio devices such as i2s, pcm, @@ -161,7 +151,6 @@ config MSM_LCC_8960 config MDM_GCC_9615 tristate "MDM9615 Global Clock Controller" - depends on COMMON_CLK_QCOM help Support for the global clock controller on mdm9615 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -170,7 +159,6 @@ config MDM_GCC_9615 config MDM_LCC_9615 tristate "MDM9615 LPASS Clock Controller" select MDM_GCC_9615 - depends on COMMON_CLK_QCOM help Support for the LPASS clock controller on mdm9615 devices. Say Y if you want to use audio devices such as i2s, pcm, @@ -179,7 +167,6 @@ config MDM_LCC_9615 config MSM_MMCC_8960 tristate "MSM8960 Multimedia Clock Controller" select MSM_GCC_8960 - depends on COMMON_CLK_QCOM help Support for the multimedia clock controller on msm8960 devices. Say Y if you want to support multimedia devices such as display, @@ -188,7 +175,6 @@ config MSM_MMCC_8960 config MSM_GCC_8974 tristate "MSM8974 Global Clock Controller" select QCOM_GDSC - depends on COMMON_CLK_QCOM help Support for the global clock controller on msm8974 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -198,7 +184,6 @@ config MSM_MMCC_8974 tristate "MSM8974 Multimedia Clock Controller" select MSM_GCC_8974 select QCOM_GDSC - depends on COMMON_CLK_QCOM help Support for the multimedia clock controller on msm8974 devices. Say Y if you want to support multimedia devices such as display, @@ -206,7 +191,6 @@ config MSM_MMCC_8974 config MSM_GCC_8994 tristate "MSM8994 Global Clock Controller" - depends on COMMON_CLK_QCOM help Support for the global clock controller on msm8994 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -215,7 +199,6 @@ config MSM_GCC_8994 config MSM_GCC_8996 tristate "MSM8996 Global Clock Controller" select QCOM_GDSC - depends on COMMON_CLK_QCOM help Support for the global clock controller on msm8996 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -225,7 +208,6 @@ config MSM_MMCC_8996 tristate "MSM8996 Multimedia Clock Controller" select MSM_GCC_8996 select QCOM_GDSC - depends on COMMON_CLK_QCOM help Support for the multimedia clock controller on msm8996 devices. Say Y if you want to support multimedia devices such as display, @@ -233,7 +215,6 @@ config MSM_MMCC_8996 config MSM_GCC_8998 tristate "MSM8998 Global Clock Controller" - depends on COMMON_CLK_QCOM help Support for the global clock controller on msm8998 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -241,7 +222,6 @@ config MSM_GCC_8998 config QCS_GCC_404 tristate "QCS404 Global Clock Controller" - depends on COMMON_CLK_QCOM help Support for the global clock controller on QCS404 devices. Say Y if you want to use multimedia devices or peripheral @@ -249,7 +229,6 @@ config QCS_GCC_404 config SDM_CAMCC_845 tristate "SDM845 Camera Clock Controller" - depends on COMMON_CLK_QCOM select SDM_GCC_845 help Support for the camera clock controller on SDM845 devices. @@ -258,7 +237,6 @@ config SDM_CAMCC_845 config SDM_GCC_660 tristate "SDM660 Global Clock Controller" select QCOM_GDSC - depends on COMMON_CLK_QCOM help Support for the global clock controller on SDM660 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -267,15 +245,21 @@ config SDM_GCC_660 config SDM_GCC_845 tristate "SDM845 Global Clock Controller" select QCOM_GDSC - depends on COMMON_CLK_QCOM help Support for the global clock controller on SDM845 devices. Say Y if you want to use peripheral devices such as UART, SPI, i2C, USB, UFS, SDDC, PCIe, etc. +config SDM_GPUCC_845 + tristate "SDM845 Graphics Clock Controller" + select SDM_GCC_845 + help + Support for the graphics clock controller on SDM845 devices. + Say Y if you want to support graphics controller devices and + functionality such as 3D graphics. + config SDM_VIDEOCC_845 tristate "SDM845 Video Clock Controller" - depends on COMMON_CLK_QCOM select SDM_GCC_845 select QCOM_GDSC help @@ -286,16 +270,23 @@ config SDM_VIDEOCC_845 config SDM_DISPCC_845 tristate "SDM845 Display Clock Controller" select SDM_GCC_845 - depends on COMMON_CLK_QCOM help Support for the display clock controller on Qualcomm Technologies, Inc SDM845 devices. Say Y if you want to support display devices and functionality such as splash screen. +config SDM_LPASSCC_845 + tristate "SDM845 Low Power Audio Subsystem (LPAAS) Clock Controller" + select SDM_GCC_845 + help + Support for the LPASS clock controller on SDM845 devices. + Say Y if you want to use the LPASS branch clocks of the LPASS clock + controller to reset the LPASS subsystem. + config SPMI_PMIC_CLKDIV tristate "SPMI PMIC clkdiv Support" - depends on (COMMON_CLK_QCOM && SPMI) || COMPILE_TEST + depends on SPMI || COMPILE_TEST help This driver supports the clkdiv functionality on the Qualcomm Technologies, Inc. SPMI PMIC. It configures the frequency of @@ -304,7 +295,6 @@ config SPMI_PMIC_CLKDIV config QCOM_HFPLL tristate "High-Frequency PLL (HFPLL) Clock Controller" - depends on COMMON_CLK_QCOM help Support for the high-frequency PLLs present on Qualcomm devices. Say Y if you want to support CPU frequency scaling on devices @@ -312,7 +302,6 @@ config QCOM_HFPLL config KPSS_XCC tristate "KPSS Clock Controller" - depends on COMMON_CLK_QCOM help Support for the Krait ACC and GCC clock controllers. Say Y if you want to support CPU frequency scaling on devices such @@ -320,8 +309,10 @@ config KPSS_XCC config KRAITCC tristate "Krait Clock Controller" - depends on COMMON_CLK_QCOM && ARM + depends on ARM select KRAIT_CLOCKS help Support for the Krait CPU clocks on Qualcomm devices. Say Y if you want to support CPU frequency scaling. + +endif diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 981882e16189..ee8d0698e370 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -46,6 +46,8 @@ obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o obj-$(CONFIG_SDM_GCC_660) += gcc-sdm660.o obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o +obj-$(CONFIG_SDM_GPUCC_845) += gpucc-sdm845.o +obj-$(CONFIG_SDM_LPASSCC_845) += lpasscc-sdm845.o obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o diff --git a/drivers/clk/qcom/apcs-msm8916.c b/drivers/clk/qcom/apcs-msm8916.c index b1cc8dbcd327..a6c89a310b18 100644 --- a/drivers/clk/qcom/apcs-msm8916.c +++ b/drivers/clk/qcom/apcs-msm8916.c @@ -96,8 +96,8 @@ static int qcom_apcs_msm8916_clk_probe(struct platform_device *pdev) goto err; } - ret = of_clk_add_hw_provider(parent->of_node, of_clk_hw_simple_get, - &a53cc->clkr.hw); + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, + &a53cc->clkr.hw); if (ret) { dev_err(dev, "failed to add clock provider: %d\n", ret); goto err; @@ -115,10 +115,8 @@ err: static int qcom_apcs_msm8916_clk_remove(struct platform_device *pdev) { struct clk_regmap_mux_div *a53cc = platform_get_drvdata(pdev); - struct device *parent = pdev->dev.parent; clk_notifier_unregister(a53cc->pclk, &a53cc->clk_nb); - of_clk_del_provider(parent->of_node); return 0; } diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c index 850c02a52248..d3aadaeb2903 100644 --- a/drivers/clk/qcom/clk-smd-rpm.c +++ b/drivers/clk/qcom/clk-smd-rpm.c @@ -611,10 +611,55 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8996 = { .num_clks = ARRAY_SIZE(msm8996_clks), }; +/* QCS404 */ +DEFINE_CLK_SMD_RPM_QDSS(qcs404, qdss_clk, qdss_a_clk, QCOM_SMD_RPM_MISC_CLK, 1); + +DEFINE_CLK_SMD_RPM(qcs404, pnoc_clk, pnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0); +DEFINE_CLK_SMD_RPM(qcs404, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1); + +DEFINE_CLK_SMD_RPM(qcs404, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0); +DEFINE_CLK_SMD_RPM(qcs404, bimc_gpu_clk, bimc_gpu_a_clk, QCOM_SMD_RPM_MEM_CLK, 2); + +DEFINE_CLK_SMD_RPM(qcs404, qpic_clk, qpic_a_clk, QCOM_SMD_RPM_QPIC_CLK, 0); +DEFINE_CLK_SMD_RPM(qcs404, ce1_clk, ce1_a_clk, QCOM_SMD_RPM_CE_CLK, 0); + +DEFINE_CLK_SMD_RPM_XO_BUFFER(qcs404, rf_clk1, rf_clk1_a, 4); +DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(qcs404, rf_clk1_pin, rf_clk1_a_pin, 4); + +DEFINE_CLK_SMD_RPM_XO_BUFFER(qcs404, ln_bb_clk, ln_bb_a_clk, 8); +DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(qcs404, ln_bb_clk_pin, ln_bb_clk_a_pin, 8); + +static struct clk_smd_rpm *qcs404_clks[] = { + [RPM_SMD_QDSS_CLK] = &qcs404_qdss_clk, + [RPM_SMD_QDSS_A_CLK] = &qcs404_qdss_a_clk, + [RPM_SMD_PNOC_CLK] = &qcs404_pnoc_clk, + [RPM_SMD_PNOC_A_CLK] = &qcs404_pnoc_a_clk, + [RPM_SMD_SNOC_CLK] = &qcs404_snoc_clk, + [RPM_SMD_SNOC_A_CLK] = &qcs404_snoc_a_clk, + [RPM_SMD_BIMC_CLK] = &qcs404_bimc_clk, + [RPM_SMD_BIMC_A_CLK] = &qcs404_bimc_a_clk, + [RPM_SMD_BIMC_GPU_CLK] = &qcs404_bimc_gpu_clk, + [RPM_SMD_BIMC_GPU_A_CLK] = &qcs404_bimc_gpu_a_clk, + [RPM_SMD_QPIC_CLK] = &qcs404_qpic_clk, + [RPM_SMD_QPIC_CLK_A] = &qcs404_qpic_a_clk, + [RPM_SMD_CE1_CLK] = &qcs404_ce1_clk, + [RPM_SMD_CE1_A_CLK] = &qcs404_ce1_a_clk, + [RPM_SMD_RF_CLK1] = &qcs404_rf_clk1, + [RPM_SMD_RF_CLK1_A] = &qcs404_rf_clk1_a, + [RPM_SMD_LN_BB_CLK] = &qcs404_ln_bb_clk, + [RPM_SMD_LN_BB_A_CLK] = &qcs404_ln_bb_a_clk, +}; + +static const struct rpm_smd_clk_desc rpm_clk_qcs404 = { + .clks = qcs404_clks, + .num_clks = ARRAY_SIZE(qcs404_clks), +}; + static const struct of_device_id rpm_smd_clk_match_table[] = { { .compatible = "qcom,rpmcc-msm8916", .data = &rpm_clk_msm8916 }, { .compatible = "qcom,rpmcc-msm8974", .data = &rpm_clk_msm8974 }, { .compatible = "qcom,rpmcc-msm8996", .data = &rpm_clk_msm8996 }, + { .compatible = "qcom,rpmcc-qcs404", .data = &rpm_clk_qcs404 }, { } }; MODULE_DEVICE_TABLE(of, rpm_smd_clk_match_table); diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index db9b2471ac40..0a48ed56833b 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -191,6 +191,22 @@ int qcom_cc_register_sleep_clk(struct device *dev) } EXPORT_SYMBOL_GPL(qcom_cc_register_sleep_clk); +/* Drop 'protected-clocks' from the list of clocks to register */ +static void qcom_cc_drop_protected(struct device *dev, struct qcom_cc *cc) +{ + struct device_node *np = dev->of_node; + struct property *prop; + const __be32 *p; + u32 i; + + of_property_for_each_u32(np, "protected-clocks", prop, p, i) { + if (i >= cc->num_rclks) + continue; + + cc->rclks[i] = NULL; + } +} + static struct clk_hw *qcom_cc_clk_hw_get(struct of_phandle_args *clkspec, void *data) { @@ -251,6 +267,8 @@ int qcom_cc_really_probe(struct platform_device *pdev, cc->rclks = rclks; cc->num_rclks = num_clks; + qcom_cc_drop_protected(dev, cc); + for (i = 0; i < num_clks; i++) { if (!rclks[i]) continue; diff --git a/drivers/clk/qcom/gcc-msm8916.c b/drivers/clk/qcom/gcc-msm8916.c index ac2b0aa1e8b5..7d9647cc29f9 100644 --- a/drivers/clk/qcom/gcc-msm8916.c +++ b/drivers/clk/qcom/gcc-msm8916.c @@ -544,7 +544,11 @@ static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = { }; static const struct freq_tbl ftbl_gcc_blsp1_qup1_6_spi_apps_clk[] = { + F(100000, P_XO, 16, 2, 24), + F(250000, P_XO, 16, 5, 24), + F(500000, P_XO, 8, 5, 24), F(960000, P_XO, 10, 1, 2), + F(1000000, P_XO, 4, 5, 24), F(4800000, P_XO, 4, 0, 0), F(9600000, P_XO, 2, 0, 0), F(16000000, P_GPLL0, 10, 1, 5), diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c index f133b7f5652f..c782e62dd98b 100644 --- a/drivers/clk/qcom/gcc-sdm845.c +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -3153,6 +3153,37 @@ static struct clk_branch gcc_cpuss_gnoc_clk = { }, }; +/* TODO: Remove after DTS updated to protect these */ +#ifdef CONFIG_SDM_LPASSCC_845 +static struct clk_branch gcc_lpass_q6_axi_clk = { + .halt_reg = 0x47000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x47000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_lpass_q6_axi_clk", + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_lpass_sway_clk = { + .halt_reg = 0x47008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x47008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_lpass_sway_clk", + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; +#endif + static struct gdsc pcie_0_gdsc = { .gdscr = 0x6b004, .pd = { @@ -3453,6 +3484,10 @@ static struct clk_regmap *gcc_sdm845_clocks[] = { [GCC_QSPI_CORE_CLK_SRC] = &gcc_qspi_core_clk_src.clkr, [GCC_QSPI_CORE_CLK] = &gcc_qspi_core_clk.clkr, [GCC_QSPI_CNOC_PERIPH_AHB_CLK] = &gcc_qspi_cnoc_periph_ahb_clk.clkr, +#ifdef CONFIG_SDM_LPASSCC_845 + [GCC_LPASS_Q6_AXI_CLK] = &gcc_lpass_q6_axi_clk.clkr, + [GCC_LPASS_SWAY_CLK] = &gcc_lpass_sway_clk.clkr, +#endif }; static const struct qcom_reset_map gcc_sdm845_resets[] = { diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index a077133c7ce3..dd63aa36b092 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -350,8 +350,10 @@ static int gdsc_init(struct gdsc *sc) else gdsc_clear_mem_on(sc); - sc->pd.power_off = gdsc_disable; - sc->pd.power_on = gdsc_enable; + if (!sc->pd.power_off) + sc->pd.power_off = gdsc_disable; + if (!sc->pd.power_on) + sc->pd.power_on = gdsc_enable; pm_genpd_init(&sc->pd, NULL, !on); return 0; diff --git a/drivers/clk/qcom/gpucc-sdm845.c b/drivers/clk/qcom/gpucc-sdm845.c new file mode 100644 index 000000000000..e40efba1bf7d --- /dev/null +++ b/drivers/clk/qcom/gpucc-sdm845.c @@ -0,0 +1,252 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include <linux/clk-provider.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include <dt-bindings/clock/qcom,gpucc-sdm845.h> + +#include "common.h" +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "gdsc.h" + +#define CX_GMU_CBCR_SLEEP_MASK 0xf +#define CX_GMU_CBCR_SLEEP_SHIFT 4 +#define CX_GMU_CBCR_WAKE_MASK 0xf +#define CX_GMU_CBCR_WAKE_SHIFT 8 +#define CLK_DIS_WAIT_SHIFT 12 +#define CLK_DIS_WAIT_MASK (0xf << CLK_DIS_WAIT_SHIFT) + +enum { + P_BI_TCXO, + P_CORE_BI_PLL_TEST_SE, + P_GPLL0_OUT_MAIN, + P_GPLL0_OUT_MAIN_DIV, + P_GPU_CC_PLL1_OUT_EVEN, + P_GPU_CC_PLL1_OUT_MAIN, + P_GPU_CC_PLL1_OUT_ODD, +}; + +static const struct parent_map gpu_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL1_OUT_MAIN, 3 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gpu_cc_parent_names_0[] = { + "bi_tcxo", + "gpu_cc_pll1", + "gcc_gpu_gpll0_clk_src", + "gcc_gpu_gpll0_div_clk_src", + "core_bi_pll_test_se", +}; + +static const struct alpha_pll_config gpu_cc_pll1_config = { + .l = 0x1a, + .alpha = 0xaab, +}; + +static struct clk_alpha_pll gpu_cc_pll1 = { + .offset = 0x100, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_pll1", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0), + F(500000000, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_gmu_clk_src = { + .cmd_rcgr = 0x1120, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_0, + .freq_tbl = ftbl_gpu_cc_gmu_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpu_cc_gmu_clk_src", + .parent_names = gpu_cc_parent_names_0, + .num_parents = 5, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_branch gpu_cc_cx_gmu_clk = { + .halt_reg = 0x1098, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1098, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_cx_gmu_clk", + .parent_names = (const char *[]){ + "gpu_cc_gmu_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cxo_clk = { + .halt_reg = 0x109c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x109c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_cxo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc gpu_cx_gdsc = { + .gdscr = 0x106c, + .gds_hw_ctrl = 0x1540, + .pd = { + .name = "gpu_cx_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +/* + * On SDM845 the GPU GX domain is *almost* entirely controlled by the GMU + * running in the CX domain so the CPU doesn't need to know anything about the + * GX domain EXCEPT.... + * + * Hardware constraints dictate that the GX be powered down before the CX. If + * the GMU crashes it could leave the GX on. In order to successfully bring back + * the device the CPU needs to disable the GX headswitch. There being no sane + * way to reach in and touch that register from deep inside the GPU driver we + * need to set up the infrastructure to be able to ensure that the GPU can + * ensure that the GX is off during this super special case. We do this by + * defining a GX gdsc with a dummy enable function and a "default" disable + * function. + * + * This allows us to attach with genpd_dev_pm_attach_by_name() in the GPU + * driver. During power up, nothing will happen from the CPU (and the GMU will + * power up normally but during power down this will ensure that the GX domain + * is *really* off - this gives us a semi standard way of doing what we need. + */ +static int gx_gdsc_enable(struct generic_pm_domain *domain) +{ + /* Do nothing but give genpd the impression that we were successful */ + return 0; +} + +static struct gdsc gpu_gx_gdsc = { + .gdscr = 0x100c, + .clamp_io_ctrl = 0x1508, + .pd = { + .name = "gpu_gx_gdsc", + .power_on = gx_gdsc_enable, + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = CLAMP_IO | AON_RESET | POLL_CFG_GDSCR, +}; + +static struct clk_regmap *gpu_cc_sdm845_clocks[] = { + [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr, + [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr, + [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr, + [GPU_CC_PLL1] = &gpu_cc_pll1.clkr, +}; + +static struct gdsc *gpu_cc_sdm845_gdscs[] = { + [GPU_CX_GDSC] = &gpu_cx_gdsc, + [GPU_GX_GDSC] = &gpu_gx_gdsc, +}; + +static const struct regmap_config gpu_cc_sdm845_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x8008, + .fast_io = true, +}; + +static const struct qcom_cc_desc gpu_cc_sdm845_desc = { + .config = &gpu_cc_sdm845_regmap_config, + .clks = gpu_cc_sdm845_clocks, + .num_clks = ARRAY_SIZE(gpu_cc_sdm845_clocks), + .gdscs = gpu_cc_sdm845_gdscs, + .num_gdscs = ARRAY_SIZE(gpu_cc_sdm845_gdscs), +}; + +static const struct of_device_id gpu_cc_sdm845_match_table[] = { + { .compatible = "qcom,sdm845-gpucc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gpu_cc_sdm845_match_table); + +static int gpu_cc_sdm845_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + unsigned int value, mask; + + regmap = qcom_cc_map(pdev, &gpu_cc_sdm845_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + clk_fabia_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); + + /* + * Configure gpu_cc_cx_gmu_clk with recommended + * wakeup/sleep settings + */ + mask = CX_GMU_CBCR_WAKE_MASK << CX_GMU_CBCR_WAKE_SHIFT; + mask |= CX_GMU_CBCR_SLEEP_MASK << CX_GMU_CBCR_SLEEP_SHIFT; + value = 0xf << CX_GMU_CBCR_WAKE_SHIFT | 0xf << CX_GMU_CBCR_SLEEP_SHIFT; + regmap_update_bits(regmap, 0x1098, mask, value); + + /* Configure clk_dis_wait for gpu_cx_gdsc */ + regmap_update_bits(regmap, 0x106c, CLK_DIS_WAIT_MASK, + 8 << CLK_DIS_WAIT_SHIFT); + + return qcom_cc_really_probe(pdev, &gpu_cc_sdm845_desc, regmap); +} + +static struct platform_driver gpu_cc_sdm845_driver = { + .probe = gpu_cc_sdm845_probe, + .driver = { + .name = "sdm845-gpucc", + .of_match_table = gpu_cc_sdm845_match_table, + }, +}; + +static int __init gpu_cc_sdm845_init(void) +{ + return platform_driver_register(&gpu_cc_sdm845_driver); +} +subsys_initcall(gpu_cc_sdm845_init); + +static void __exit gpu_cc_sdm845_exit(void) +{ + platform_driver_unregister(&gpu_cc_sdm845_driver); +} +module_exit(gpu_cc_sdm845_exit); + +MODULE_DESCRIPTION("QTI GPUCC SDM845 Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/lpasscc-sdm845.c b/drivers/clk/qcom/lpasscc-sdm845.c new file mode 100644 index 000000000000..e246b99dfbc6 --- /dev/null +++ b/drivers/clk/qcom/lpasscc-sdm845.c @@ -0,0 +1,179 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include <linux/platform_device.h> +#include <linux/module.h> +#include <linux/of_address.h> +#include <linux/regmap.h> + +#include <dt-bindings/clock/qcom,lpass-sdm845.h> + +#include "clk-regmap.h" +#include "clk-branch.h" +#include "common.h" + +static struct clk_branch lpass_q6ss_ahbm_aon_clk = { + .halt_reg = 0x12000, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x12000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "lpass_q6ss_ahbm_aon_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch lpass_q6ss_ahbs_aon_clk = { + .halt_reg = 0x1f000, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x1f000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "lpass_q6ss_ahbs_aon_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch lpass_qdsp6ss_core_clk = { + .halt_reg = 0x20, + /* CLK_OFF would not toggle until LPASS is out of reset */ + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x20, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "lpass_qdsp6ss_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch lpass_qdsp6ss_xo_clk = { + .halt_reg = 0x38, + /* CLK_OFF would not toggle until LPASS is out of reset */ + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x38, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "lpass_qdsp6ss_xo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch lpass_qdsp6ss_sleep_clk = { + .halt_reg = 0x3c, + /* CLK_OFF would not toggle until LPASS is out of reset */ + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x3c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "lpass_qdsp6ss_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct regmap_config lpass_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .fast_io = true, +}; + +static struct clk_regmap *lpass_cc_sdm845_clocks[] = { + [LPASS_Q6SS_AHBM_AON_CLK] = &lpass_q6ss_ahbm_aon_clk.clkr, + [LPASS_Q6SS_AHBS_AON_CLK] = &lpass_q6ss_ahbs_aon_clk.clkr, +}; + +static const struct qcom_cc_desc lpass_cc_sdm845_desc = { + .config = &lpass_regmap_config, + .clks = lpass_cc_sdm845_clocks, + .num_clks = ARRAY_SIZE(lpass_cc_sdm845_clocks), +}; + +static struct clk_regmap *lpass_qdsp6ss_sdm845_clocks[] = { + [LPASS_QDSP6SS_XO_CLK] = &lpass_qdsp6ss_xo_clk.clkr, + [LPASS_QDSP6SS_SLEEP_CLK] = &lpass_qdsp6ss_sleep_clk.clkr, + [LPASS_QDSP6SS_CORE_CLK] = &lpass_qdsp6ss_core_clk.clkr, +}; + +static const struct qcom_cc_desc lpass_qdsp6ss_sdm845_desc = { + .config = &lpass_regmap_config, + .clks = lpass_qdsp6ss_sdm845_clocks, + .num_clks = ARRAY_SIZE(lpass_qdsp6ss_sdm845_clocks), +}; + +static int lpass_clocks_sdm845_probe(struct platform_device *pdev, int index, + const struct qcom_cc_desc *desc) +{ + struct regmap *regmap; + struct resource *res; + void __iomem *base; + + res = platform_get_resource(pdev, IORESOURCE_MEM, index); + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + regmap = devm_regmap_init_mmio(&pdev->dev, base, desc->config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + return qcom_cc_really_probe(pdev, desc, regmap); +} + +static int lpass_cc_sdm845_probe(struct platform_device *pdev) +{ + const struct qcom_cc_desc *desc; + int ret; + + lpass_regmap_config.name = "cc"; + desc = &lpass_cc_sdm845_desc; + + ret = lpass_clocks_sdm845_probe(pdev, 0, desc); + if (ret) + return ret; + + lpass_regmap_config.name = "qdsp6ss"; + desc = &lpass_qdsp6ss_sdm845_desc; + + return lpass_clocks_sdm845_probe(pdev, 1, desc); +} + +static const struct of_device_id lpass_cc_sdm845_match_table[] = { + { .compatible = "qcom,sdm845-lpasscc" }, + { } +}; +MODULE_DEVICE_TABLE(of, lpass_cc_sdm845_match_table); + +static struct platform_driver lpass_cc_sdm845_driver = { + .probe = lpass_cc_sdm845_probe, + .driver = { + .name = "sdm845-lpasscc", + .of_match_table = lpass_cc_sdm845_match_table, + }, +}; + +static int __init lpass_cc_sdm845_init(void) +{ + return platform_driver_register(&lpass_cc_sdm845_driver); +} +subsys_initcall(lpass_cc_sdm845_init); + +static void __exit lpass_cc_sdm845_exit(void) +{ + platform_driver_unregister(&lpass_cc_sdm845_driver); +} +module_exit(lpass_cc_sdm845_exit); + +MODULE_DESCRIPTION("QTI LPASS_CC SDM845 Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/renesas/clk-div6.c b/drivers/clk/renesas/clk-div6.c index 57c934164306..e98a9f5b3c90 100644 --- a/drivers/clk/renesas/clk-div6.c +++ b/drivers/clk/renesas/clk-div6.c @@ -274,7 +274,7 @@ struct clk * __init cpg_div6_register(const char *name, /* Register the clock. */ init.name = name; init.ops = &cpg_div6_clock_ops; - init.flags = CLK_IS_BASIC; + init.flags = 0; init.parent_names = parent_names; init.num_parents = valid_parents; diff --git a/drivers/clk/renesas/clk-mstp.c b/drivers/clk/renesas/clk-mstp.c index 1c1768c2cc82..2ba6105937e3 100644 --- a/drivers/clk/renesas/clk-mstp.c +++ b/drivers/clk/renesas/clk-mstp.c @@ -158,7 +158,7 @@ static struct clk * __init cpg_mstp_clock_register(const char *name, init.name = name; init.ops = &cpg_mstp_clock_ops; - init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; + init.flags = CLK_SET_RATE_PARENT; /* INTC-SYS is the module clock of the GIC, and must not be disabled */ if (!strcmp(name, "intc-sys")) { pr_debug("MSTP %s setting CLK_IS_CRITICAL\n", name); diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c index 6d2b56891559..658cb11b6f55 100644 --- a/drivers/clk/renesas/r9a06g032-clocks.c +++ b/drivers/clk/renesas/r9a06g032-clocks.c @@ -424,7 +424,7 @@ r9a06g032_register_gate(struct r9a06g032_priv *clocks, init.name = desc->name; init.ops = &r9a06g032_clk_gate_ops; - init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; + init.flags = CLK_SET_RATE_PARENT; init.parent_names = parent_name ? &parent_name : NULL; init.num_parents = parent_name ? 1 : 0; @@ -595,7 +595,7 @@ r9a06g032_register_div(struct r9a06g032_priv *clocks, init.name = desc->name; init.ops = &r9a06g032_clk_div_ops; - init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; + init.flags = CLK_SET_RATE_PARENT; init.parent_names = parent_name ? &parent_name : NULL; init.num_parents = parent_name ? 1 : 0; @@ -683,7 +683,7 @@ r9a06g032_register_bitsel(struct r9a06g032_priv *clocks, init.name = desc->name; init.ops = &clk_bitselect_ops; - init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; + init.flags = CLK_SET_RATE_PARENT; init.parent_names = names; init.num_parents = 2; @@ -777,7 +777,7 @@ r9a06g032_register_dualgate(struct r9a06g032_priv *clocks, init.name = desc->name; init.ops = &r9a06g032_clk_dualgate_ops; - init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; + init.flags = CLK_SET_RATE_PARENT; init.parent_names = &parent_name; init.num_parents = 1; g->hw.init = &init; diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index 4ba38f98cc7b..48e003c69cd1 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -368,7 +368,7 @@ static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core, init.name = core->name; init.ops = &cpg_sd_clock_ops; - init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; + init.flags = CLK_SET_RATE_PARENT; init.parent_names = &parent_name; init.num_parents = 1; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index f7bb817420b4..30df0dc853f0 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -412,7 +412,7 @@ static void __init cpg_mssr_register_mod_clk(const struct mssr_mod_clk *mod, init.name = mod->name; init.ops = &cpg_mstp_clock_ops; - init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; + init.flags = CLK_SET_RATE_PARENT; for (i = 0; i < info->num_crit_mod_clks; i++) if (id == info->crit_mod_clks[i]) { dev_dbg(dev, "MSTP %s setting CLK_IS_CRITICAL\n", diff --git a/drivers/clk/samsung/clk-s3c2410-dclk.c b/drivers/clk/samsung/clk-s3c2410-dclk.c index 0d92f3e5e3d9..82f8ae22fd34 100644 --- a/drivers/clk/samsung/clk-s3c2410-dclk.c +++ b/drivers/clk/samsung/clk-s3c2410-dclk.c @@ -105,7 +105,7 @@ static struct clk_hw *s3c24xx_register_clkout(struct device *dev, init.name = name; init.ops = &s3c24xx_clkout_ops; - init.flags = CLK_IS_BASIC; + init.flags = 0; init.parent_names = parent_names; init.num_parents = num_parents; diff --git a/drivers/clk/st/clk-flexgen.c b/drivers/clk/st/clk-flexgen.c index 918ba3164da9..ca8d5350f94e 100644 --- a/drivers/clk/st/clk-flexgen.c +++ b/drivers/clk/st/clk-flexgen.c @@ -210,7 +210,7 @@ static struct clk *clk_register_flexgen(const char *name, init.name = name; init.ops = &flexgen_ops; - init.flags = CLK_IS_BASIC | CLK_GET_RATE_NOCACHE | flexgen_flags; + init.flags = CLK_GET_RATE_NOCACHE | flexgen_flags; init.parent_names = parent_names; init.num_parents = num_parents; diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c index cfa000007622..946ceb14dbf7 100644 --- a/drivers/clk/st/clkgen-fsyn.c +++ b/drivers/clk/st/clkgen-fsyn.c @@ -404,7 +404,7 @@ static struct clk * __init st_clk_register_quadfs_pll( init.name = name; init.ops = quadfs->pll_ops; - init.flags = CLK_IS_BASIC | CLK_GET_RATE_NOCACHE; + init.flags = CLK_GET_RATE_NOCACHE; init.parent_names = &parent_name; init.num_parents = 1; @@ -843,7 +843,7 @@ static struct clk * __init st_clk_register_quadfs_fsynth( init.name = name; init.ops = &st_quadfs_ops; - init.flags = flags | CLK_GET_RATE_NOCACHE | CLK_IS_BASIC; + init.flags = flags | CLK_GET_RATE_NOCACHE; init.parent_names = &parent_name; init.num_parents = 1; diff --git a/drivers/clk/st/clkgen-pll.c b/drivers/clk/st/clkgen-pll.c index 7a7106dc80bf..6930348ce843 100644 --- a/drivers/clk/st/clkgen-pll.c +++ b/drivers/clk/st/clkgen-pll.c @@ -613,7 +613,7 @@ static struct clk * __init clkgen_pll_register(const char *parent_name, init.name = clk_name; init.ops = pll_data->ops; - init.flags = pll_flags | CLK_IS_BASIC | CLK_GET_RATE_NOCACHE; + init.flags = pll_flags | CLK_GET_RATE_NOCACHE; init.parent_names = &parent_name; init.num_parents = 1; diff --git a/drivers/clk/tegra/clk-dfll.c b/drivers/clk/tegra/clk-dfll.c index ebb0e1b6bf01..609e363dabf8 100644 --- a/drivers/clk/tegra/clk-dfll.c +++ b/drivers/clk/tegra/clk-dfll.c @@ -1184,17 +1184,7 @@ static int attr_registers_show(struct seq_file *s, void *data) return 0; } -static int attr_registers_open(struct inode *inode, struct file *file) -{ - return single_open(file, attr_registers_show, inode->i_private); -} - -static const struct file_operations attr_registers_fops = { - .open = attr_registers_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(attr_registers); static void dfll_debug_init(struct tegra_dfll *td) { diff --git a/drivers/clk/versatile/clk-sp810.c b/drivers/clk/versatile/clk-sp810.c index 1fe1e8d970cf..c2b6bb814742 100644 --- a/drivers/clk/versatile/clk-sp810.c +++ b/drivers/clk/versatile/clk-sp810.c @@ -111,7 +111,7 @@ static void __init clk_sp810_of_setup(struct device_node *node) init.name = name; init.ops = &clk_sp810_timerclken_ops; - init.flags = CLK_IS_BASIC; + init.flags = 0; init.parent_names = parent_names; init.num_parents = num; |