diff options
Diffstat (limited to 'drivers/clk')
59 files changed, 9246 insertions, 251 deletions
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index c3e3a02f7f1f..d2d3871e64c9 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -116,6 +116,12 @@ config COMMON_CLK_CDCE925 Given a target output frequency, the driver will set the PLL and divider to best approximate the desired output. +config COMMON_CLK_CS2000_CP + tristate "Clock driver for CS2000 Fractional-N Clock Synthesizer & Clock Multiplier" + depends on I2C + help + If you say yes here you get support for the CS2000 clock multiplier. + config COMMON_CLK_S2MPS11 tristate "Clock driver for S2MPS1X/S5M8767 MFD" depends on MFD_SEC_CORE diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 820714c72d36..0e0fdac2a599 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -21,6 +21,7 @@ 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_CDCE706) += clk-cdce706.o +obj-$(CONFIG_COMMON_CLK_CS2000_CP) += clk-cs2000-cp.o obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o @@ -42,6 +43,7 @@ obj-$(CONFIG_COMMON_CLK_SI514) += clk-si514.o obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o obj-$(CONFIG_COMMON_CLK_CDCE925) += clk-cdce925.o obj-$(CONFIG_ARCH_STM32) += clk-stm32f4.o +obj-$(CONFIG_ARCH_TANGOX) += clk-tango4.o obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o obj-$(CONFIG_ARCH_U300) += clk-u300.o obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o @@ -69,6 +71,7 @@ obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/ obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += shmobile/ +obj-$(CONFIG_ARCH_RENESAS) += shmobile/ obj-$(CONFIG_ARCH_SIRF) += sirf/ obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/ obj-$(CONFIG_PLAT_SPEAR) += spear/ diff --git a/drivers/clk/at91/clk-slow.c b/drivers/clk/at91/clk-slow.c index d0d5076a9b94..6f99a530ead6 100644 --- a/drivers/clk/at91/clk-slow.c +++ b/drivers/clk/at91/clk-slow.c @@ -10,7 +10,6 @@ * */ -#include <linux/clk.h> #include <linux/clk-provider.h> #include <linux/clkdev.h> #include <linux/slab.h> @@ -72,8 +71,6 @@ struct clk_sam9x5_slow { #define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw) -static struct clk *slow_clk; - static int clk_slow_osc_prepare(struct clk_hw *hw) { struct clk_slow_osc *osc = to_clk_slow_osc(hw); @@ -360,8 +357,6 @@ at91_clk_register_sam9x5_slow(void __iomem *sckcr, clk = clk_register(NULL, &slowck->hw); if (IS_ERR(clk)) kfree(slowck); - else - slow_clk = clk; return clk; } @@ -433,8 +428,6 @@ at91_clk_register_sam9260_slow(struct at91_pmc *pmc, clk = clk_register(NULL, &slowck->hw); if (IS_ERR(clk)) kfree(slowck); - else - slow_clk = clk; return clk; } @@ -462,25 +455,3 @@ void __init of_at91sam9260_clk_slow_setup(struct device_node *np, of_clk_add_provider(np, of_clk_src_simple_get, clk); } - -/* - * FIXME: All slow clk users are not properly claiming it (get + prepare + - * enable) before using it. - * If all users properly claiming this clock decide that they don't need it - * anymore (or are removed), it is disabled while faulty users are still - * requiring it, and the system hangs. - * Prevent this clock from being disabled until all users are properly - * requesting it. - * Once this is done we should remove this function and the slow_clk variable. - */ -static int __init of_at91_clk_slow_retain(void) -{ - if (!slow_clk) - return 0; - - __clk_get(slow_clk); - clk_prepare_enable(slow_clk); - - return 0; -} -arch_initcall(of_at91_clk_slow_retain); diff --git a/drivers/clk/bcm/Kconfig b/drivers/clk/bcm/Kconfig index 85260fb96b36..f2878459199a 100644 --- a/drivers/clk/bcm/Kconfig +++ b/drivers/clk/bcm/Kconfig @@ -1,3 +1,13 @@ +config CLK_BCM_63XX + bool "Broadcom BCM63xx clock support" + depends on ARCH_BCM_63XX || COMPILE_TEST + depends on COMMON_CLK + select COMMON_CLK_IPROC + default ARCH_BCM_63XX + help + Enable common clock framework support for Broadcom BCM63xx DSL SoCs + based on the ARM architecture + config CLK_BCM_KONA bool "Broadcom Kona CCU clock support" depends on ARCH_BCM_MOBILE || COMPILE_TEST diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile index 3fc95060d875..247c26750d8b 100644 --- a/drivers/clk/bcm/Makefile +++ b/drivers/clk/bcm/Makefile @@ -1,3 +1,4 @@ +obj-$(CONFIG_CLK_BCM_63XX) += clk-bcm63xx.o obj-$(CONFIG_CLK_BCM_KONA) += clk-kona.o obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o diff --git a/drivers/clk/bcm/clk-bcm63xx.c b/drivers/clk/bcm/clk-bcm63xx.c new file mode 100644 index 000000000000..fbc17ae5ff2b --- /dev/null +++ b/drivers/clk/bcm/clk-bcm63xx.c @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2015 Broadcom Corporation + * + * 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 version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include <linux/init.h> +#include <linux/clk-provider.h> +#include <linux/of.h> +#include "clk-iproc.h" + +static void __init bcm63138_armpll_init(struct device_node *node) +{ + iproc_armpll_setup(node); +} +CLK_OF_DECLARE(bcm63138_armpll, "brcm,bcm63138-armpll", bcm63138_armpll_init); diff --git a/drivers/clk/clk-cs2000-cp.c b/drivers/clk/clk-cs2000-cp.c new file mode 100644 index 000000000000..7379de8dc894 --- /dev/null +++ b/drivers/clk/clk-cs2000-cp.c @@ -0,0 +1,510 @@ +/* + * CS2000 -- CIRRUS LOGIC Fractional-N Clock Synthesizer & Clock Multiplier + * + * Copyright (C) 2015 Renesas Electronics Corporation + * Kuninori Morimoto <kuninori.morimoto.gx@renesas.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-provider.h> +#include <linux/delay.h> +#include <linux/clk.h> +#include <linux/i2c.h> +#include <linux/of_device.h> +#include <linux/module.h> + +#define CH_MAX 4 +#define RATIO_REG_SIZE 4 + +#define DEVICE_ID 0x1 +#define DEVICE_CTRL 0x2 +#define DEVICE_CFG1 0x3 +#define DEVICE_CFG2 0x4 +#define GLOBAL_CFG 0x5 +#define Ratio_Add(x, nth) (6 + (x * 4) + (nth)) +#define Ratio_Val(x, nth) ((x >> (24 - (8 * nth))) & 0xFF) +#define Val_Ratio(x, nth) ((x & 0xFF) << (24 - (8 * nth))) +#define FUNC_CFG1 0x16 +#define FUNC_CFG2 0x17 + +/* DEVICE_ID */ +#define REVISION_MASK (0x7) +#define REVISION_B2_B3 (0x4) +#define REVISION_C1 (0x6) + +/* DEVICE_CTRL */ +#define PLL_UNLOCK (1 << 7) + +/* DEVICE_CFG1 */ +#define RSEL(x) (((x) & 0x3) << 3) +#define RSEL_MASK RSEL(0x3) +#define ENDEV1 (0x1) + +/* GLOBAL_CFG */ +#define ENDEV2 (0x1) + +#define CH_SIZE_ERR(ch) ((ch < 0) || (ch >= CH_MAX)) +#define hw_to_priv(_hw) container_of(_hw, struct cs2000_priv, hw) +#define priv_to_client(priv) (priv->client) +#define priv_to_dev(priv) (&(priv_to_client(priv)->dev)) + +#define CLK_IN 0 +#define REF_CLK 1 +#define CLK_MAX 2 + +struct cs2000_priv { + struct clk_hw hw; + struct i2c_client *client; + struct clk *clk_in; + struct clk *ref_clk; + struct clk *clk_out; +}; + +static const struct of_device_id cs2000_of_match[] = { + { .compatible = "cirrus,cs2000-cp", }, + {}, +}; +MODULE_DEVICE_TABLE(of, cs2000_of_match); + +static const struct i2c_device_id cs2000_id[] = { + { "cs2000-cp", }, + {} +}; +MODULE_DEVICE_TABLE(i2c, cs2000_id); + +#define cs2000_read(priv, addr) \ + i2c_smbus_read_byte_data(priv_to_client(priv), addr) +#define cs2000_write(priv, addr, val) \ + i2c_smbus_write_byte_data(priv_to_client(priv), addr, val) + +static int cs2000_bset(struct cs2000_priv *priv, u8 addr, u8 mask, u8 val) +{ + s32 data; + + data = cs2000_read(priv, addr); + if (data < 0) + return data; + + data &= ~mask; + data |= (val & mask); + + return cs2000_write(priv, addr, data); +} + +static int cs2000_enable_dev_config(struct cs2000_priv *priv, bool enable) +{ + int ret; + + ret = cs2000_bset(priv, DEVICE_CFG1, ENDEV1, + enable ? ENDEV1 : 0); + if (ret < 0) + return ret; + + ret = cs2000_bset(priv, GLOBAL_CFG, ENDEV2, + enable ? ENDEV2 : 0); + if (ret < 0) + return ret; + + return 0; +} + +static int cs2000_clk_in_bound_rate(struct cs2000_priv *priv, + u32 rate_in) +{ + u32 val; + + if (rate_in >= 32000000 && rate_in < 56000000) + val = 0x0; + else if (rate_in >= 16000000 && rate_in < 28000000) + val = 0x1; + else if (rate_in >= 8000000 && rate_in < 14000000) + val = 0x2; + else + return -EINVAL; + + return cs2000_bset(priv, FUNC_CFG1, 0x3 << 3, val << 3); +} + +static int cs2000_wait_pll_lock(struct cs2000_priv *priv) +{ + struct device *dev = priv_to_dev(priv); + s32 val; + unsigned int i; + + for (i = 0; i < 256; i++) { + val = cs2000_read(priv, DEVICE_CTRL); + if (val < 0) + return val; + if (!(val & PLL_UNLOCK)) + return 0; + udelay(1); + } + + dev_err(dev, "pll lock failed\n"); + + return -ETIMEDOUT; +} + +static int cs2000_clk_out_enable(struct cs2000_priv *priv, bool enable) +{ + /* enable both AUX_OUT, CLK_OUT */ + return cs2000_write(priv, DEVICE_CTRL, enable ? 0 : 0x3); +} + +static u32 cs2000_rate_to_ratio(u32 rate_in, u32 rate_out) +{ + u64 ratio; + + /* + * ratio = rate_out / rate_in * 2^20 + * + * To avoid over flow, rate_out is u64. + * The result should be u32. + */ + ratio = (u64)rate_out << 20; + do_div(ratio, rate_in); + + return ratio; +} + +static unsigned long cs2000_ratio_to_rate(u32 ratio, u32 rate_in) +{ + u64 rate_out; + + /* + * ratio = rate_out / rate_in * 2^20 + * + * To avoid over flow, rate_out is u64. + * The result should be u32 or unsigned long. + */ + + rate_out = (u64)ratio * rate_in; + return rate_out >> 20; +} + +static int cs2000_ratio_set(struct cs2000_priv *priv, + int ch, u32 rate_in, u32 rate_out) +{ + u32 val; + unsigned int i; + int ret; + + if (CH_SIZE_ERR(ch)) + return -EINVAL; + + val = cs2000_rate_to_ratio(rate_in, rate_out); + for (i = 0; i < RATIO_REG_SIZE; i++) { + ret = cs2000_write(priv, + Ratio_Add(ch, i), + Ratio_Val(val, i)); + if (ret < 0) + return ret; + } + + return 0; +} + +static u32 cs2000_ratio_get(struct cs2000_priv *priv, int ch) +{ + s32 tmp; + u32 val; + unsigned int i; + + val = 0; + for (i = 0; i < RATIO_REG_SIZE; i++) { + tmp = cs2000_read(priv, Ratio_Add(ch, i)); + if (tmp < 0) + return 0; + + val |= Val_Ratio(tmp, i); + } + + return val; +} + +static int cs2000_ratio_select(struct cs2000_priv *priv, int ch) +{ + int ret; + + if (CH_SIZE_ERR(ch)) + return -EINVAL; + + /* + * FIXME + * + * this driver supports static ratio mode only at this point. + */ + ret = cs2000_bset(priv, DEVICE_CFG1, RSEL_MASK, RSEL(ch)); + if (ret < 0) + return ret; + + ret = cs2000_write(priv, DEVICE_CFG2, 0x0); + if (ret < 0) + return ret; + + return 0; +} + +static unsigned long cs2000_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct cs2000_priv *priv = hw_to_priv(hw); + int ch = 0; /* it uses ch0 only at this point */ + u32 ratio; + + ratio = cs2000_ratio_get(priv, ch); + + return cs2000_ratio_to_rate(ratio, parent_rate); +} + +static long cs2000_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + u32 ratio; + + ratio = cs2000_rate_to_ratio(*parent_rate, rate); + + return cs2000_ratio_to_rate(ratio, *parent_rate); +} + +static int __cs2000_set_rate(struct cs2000_priv *priv, int ch, + unsigned long rate, unsigned long parent_rate) + +{ + int ret; + + ret = cs2000_clk_in_bound_rate(priv, parent_rate); + if (ret < 0) + return ret; + + ret = cs2000_ratio_set(priv, ch, parent_rate, rate); + if (ret < 0) + return ret; + + ret = cs2000_ratio_select(priv, ch); + if (ret < 0) + return ret; + + return 0; +} + +static int cs2000_set_rate(struct clk_hw *hw, + unsigned long rate, unsigned long parent_rate) +{ + struct cs2000_priv *priv = hw_to_priv(hw); + int ch = 0; /* it uses ch0 only at this point */ + + return __cs2000_set_rate(priv, ch, rate, parent_rate); +} + +static int cs2000_enable(struct clk_hw *hw) +{ + struct cs2000_priv *priv = hw_to_priv(hw); + int ret; + + ret = cs2000_enable_dev_config(priv, true); + if (ret < 0) + return ret; + + ret = cs2000_clk_out_enable(priv, true); + if (ret < 0) + return ret; + + ret = cs2000_wait_pll_lock(priv); + if (ret < 0) + return ret; + + return ret; +} + +static void cs2000_disable(struct clk_hw *hw) +{ + struct cs2000_priv *priv = hw_to_priv(hw); + + cs2000_enable_dev_config(priv, false); + + cs2000_clk_out_enable(priv, false); +} + +static u8 cs2000_get_parent(struct clk_hw *hw) +{ + /* always return REF_CLK */ + return REF_CLK; +} + +static const struct clk_ops cs2000_ops = { + .get_parent = cs2000_get_parent, + .recalc_rate = cs2000_recalc_rate, + .round_rate = cs2000_round_rate, + .set_rate = cs2000_set_rate, + .prepare = cs2000_enable, + .unprepare = cs2000_disable, +}; + +static int cs2000_clk_get(struct cs2000_priv *priv) +{ + struct i2c_client *client = priv_to_client(priv); + struct device *dev = &client->dev; + struct clk *clk_in, *ref_clk; + + clk_in = devm_clk_get(dev, "clk_in"); + /* not yet provided */ + if (IS_ERR(clk_in)) + return -EPROBE_DEFER; + + ref_clk = devm_clk_get(dev, "ref_clk"); + /* not yet provided */ + if (IS_ERR(ref_clk)) + return -EPROBE_DEFER; + + priv->clk_in = clk_in; + priv->ref_clk = ref_clk; + + return 0; +} + +static int cs2000_clk_register(struct cs2000_priv *priv) +{ + struct device *dev = priv_to_dev(priv); + struct device_node *np = dev->of_node; + struct clk_init_data init; + const char *name = np->name; + struct clk *clk; + static const char *parent_names[CLK_MAX]; + int ch = 0; /* it uses ch0 only at this point */ + int rate; + int ret; + + of_property_read_string(np, "clock-output-names", &name); + + /* + * set default rate as 1/1. + * otherwise .set_rate which setup ratio + * is never called if user requests 1/1 rate + */ + rate = clk_get_rate(priv->ref_clk); + ret = __cs2000_set_rate(priv, ch, rate, rate); + if (ret < 0) + return ret; + + parent_names[CLK_IN] = __clk_get_name(priv->clk_in); + parent_names[REF_CLK] = __clk_get_name(priv->ref_clk); + + init.name = name; + init.ops = &cs2000_ops; + init.flags = CLK_SET_RATE_GATE; + init.parent_names = parent_names; + init.num_parents = ARRAY_SIZE(parent_names); + + priv->hw.init = &init; + + clk = clk_register(dev, &priv->hw); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + ret = of_clk_add_provider(np, of_clk_src_simple_get, clk); + if (ret < 0) { + clk_unregister(clk); + return ret; + } + + priv->clk_out = clk; + + return 0; +} + +static int cs2000_version_print(struct cs2000_priv *priv) +{ + struct i2c_client *client = priv_to_client(priv); + struct device *dev = &client->dev; + s32 val; + const char *revision; + + val = cs2000_read(priv, DEVICE_ID); + if (val < 0) + return val; + + /* CS2000 should be 0x0 */ + if (val >> 3) + return -EIO; + + switch (val & REVISION_MASK) { + case REVISION_B2_B3: + revision = "B2 / B3"; + break; + case REVISION_C1: + revision = "C1"; + break; + default: + return -EIO; + } + + dev_info(dev, "revision - %s\n", revision); + + return 0; +} + +static int cs2000_remove(struct i2c_client *client) +{ + struct cs2000_priv *priv = i2c_get_clientdata(client); + struct device *dev = &client->dev; + struct device_node *np = dev->of_node; + + of_clk_del_provider(np); + + clk_unregister(priv->clk_out); + + return 0; +} + +static int cs2000_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct cs2000_priv *priv; + struct device *dev = &client->dev; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->client = client; + i2c_set_clientdata(client, priv); + + ret = cs2000_clk_get(priv); + if (ret < 0) + return ret; + + ret = cs2000_clk_register(priv); + if (ret < 0) + return ret; + + ret = cs2000_version_print(priv); + if (ret < 0) + goto probe_err; + + return 0; + +probe_err: + cs2000_remove(client); + + return ret; +} + +static struct i2c_driver cs2000_driver = { + .driver = { + .name = "cs2000-cp", + .of_match_table = cs2000_of_match, + }, + .probe = cs2000_probe, + .remove = cs2000_remove, + .id_table = cs2000_id, +}; + +module_i2c_driver(cs2000_driver); + +MODULE_DESCRIPTION("CS2000-CP driver"); +MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index 3ace102a2a0a..ded3ff4b91b9 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -32,13 +32,14 @@ #define div_mask(width) ((1 << (width)) - 1) -static unsigned int _get_table_maxdiv(const struct clk_div_table *table) +static unsigned int _get_table_maxdiv(const struct clk_div_table *table, + u8 width) { - unsigned int maxdiv = 0; + unsigned int maxdiv = 0, mask = div_mask(width); const struct clk_div_table *clkt; for (clkt = table; clkt->div; clkt++) - if (clkt->div > maxdiv) + if (clkt->div > maxdiv && clkt->val <= mask) maxdiv = clkt->div; return maxdiv; } @@ -62,7 +63,7 @@ static unsigned int _get_maxdiv(const struct clk_div_table *table, u8 width, if (flags & CLK_DIVIDER_POWER_OF_TWO) return 1 << div_mask(width); if (table) - return _get_table_maxdiv(table); + return _get_table_maxdiv(table, width); return div_mask(width) + 1; } diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c index 10819e248414..335322dc403f 100644 --- a/drivers/clk/clk-gpio.c +++ b/drivers/clk/clk-gpio.c @@ -209,6 +209,8 @@ EXPORT_SYMBOL_GPL(clk_register_gpio_mux); struct clk_gpio_delayed_register_data { const char *gpio_name; + int num_parents; + const char **parent_names; struct device_node *node; struct mutex lock; struct clk *clk; @@ -222,8 +224,6 @@ static struct clk *of_clk_gpio_delayed_register_get( { struct clk_gpio_delayed_register_data *data = _data; struct clk *clk; - const char **parent_names; - int i, num_parents; int gpio; enum of_gpio_flags of_flags; @@ -248,26 +248,14 @@ static struct clk *of_clk_gpio_delayed_register_get( return ERR_PTR(gpio); } - num_parents = of_clk_get_parent_count(data->node); - - parent_names = kcalloc(num_parents, sizeof(char *), GFP_KERNEL); - if (!parent_names) { - clk = ERR_PTR(-ENOMEM); - goto out; - } - - for (i = 0; i < num_parents; i++) - parent_names[i] = of_clk_get_parent_name(data->node, i); - - clk = data->clk_register_get(data->node->name, parent_names, - num_parents, gpio, of_flags & OF_GPIO_ACTIVE_LOW); + clk = data->clk_register_get(data->node->name, data->parent_names, + data->num_parents, gpio, of_flags & OF_GPIO_ACTIVE_LOW); if (IS_ERR(clk)) goto out; data->clk = clk; out: mutex_unlock(&data->lock); - kfree(parent_names); return clk; } @@ -296,11 +284,24 @@ static void __init of_gpio_clk_setup(struct device_node *node, unsigned gpio, bool active_low)) { struct clk_gpio_delayed_register_data *data; + const char **parent_names; + int i, num_parents; data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) return; + num_parents = of_clk_get_parent_count(node); + + parent_names = kcalloc(num_parents, sizeof(char *), GFP_KERNEL); + if (!parent_names) + return; + + for (i = 0; i < num_parents; i++) + parent_names[i] = of_clk_get_parent_name(node, i); + + data->num_parents = num_parents; + data->parent_names = parent_names; data->node = node; data->gpio_name = gpio_name; data->clk_register_get = clk_register_get; diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c index 7129c86a79db..5ed03c8a8df9 100644 --- a/drivers/clk/clk-mux.c +++ b/drivers/clk/clk-mux.c @@ -71,10 +71,9 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index) u32 val; unsigned long flags = 0; - if (mux->table) + if (mux->table) { index = mux->table[index]; - - else { + } else { if (mux->flags & CLK_MUX_INDEX_BIT) index = 1 << index; diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c index 1ab0fb81c6a0..7bc1c4527ae4 100644 --- a/drivers/clk/clk-qoriq.c +++ b/drivers/clk/clk-qoriq.c @@ -778,8 +778,10 @@ static struct clk * __init create_one_cmux(struct clockgen *cg, int idx) */ clksel = (cg_in(cg, hwc->reg) & CLKSEL_MASK) >> CLKSEL_SHIFT; div = get_pll_div(cg, hwc, clksel); - if (!div) + if (!div) { + kfree(hwc); return NULL; + } pct80_rate = clk_get_rate(div->clk); pct80_rate *= 8; diff --git a/drivers/clk/clk-scpi.c b/drivers/clk/clk-scpi.c index 0b501a9fef92..cd0f2726f5e0 100644 --- a/drivers/clk/clk-scpi.c +++ b/drivers/clk/clk-scpi.c @@ -292,6 +292,7 @@ static int scpi_clocks_probe(struct platform_device *pdev) ret = scpi_clk_add(dev, child, match); if (ret) { scpi_clocks_remove(pdev); + of_node_put(child); return ret; } } diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c index e346b223199d..850316ac8831 100644 --- a/drivers/clk/clk-si5351.c +++ b/drivers/clk/clk-si5351.c @@ -1091,6 +1091,13 @@ static int si5351_clkout_set_rate(struct clk_hw *hw, unsigned long rate, si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num, SI5351_CLK_POWERDOWN, 0); + /* + * Do a pll soft reset on both plls, needed in some cases to get + * all outputs running. + */ + si5351_reg_write(hwdata->drvdata, SI5351_PLL_RESET, + SI5351_PLL_RESET_A | SI5351_PLL_RESET_B); + dev_dbg(&hwdata->drvdata->client->dev, "%s - %s: rdiv = %u, parent_rate = %lu, rate = %lu\n", __func__, clk_hw_get_name(hw), (1 << rdiv), diff --git a/drivers/clk/clk-tango4.c b/drivers/clk/clk-tango4.c new file mode 100644 index 000000000000..004ab7dfcfe3 --- /dev/null +++ b/drivers/clk/clk-tango4.c @@ -0,0 +1,61 @@ +#include <linux/kernel.h> +#include <linux/clk-provider.h> +#include <linux/of_address.h> +#include <linux/init.h> +#include <linux/io.h> + +static struct clk *out[2]; +static struct clk_onecell_data clk_data = { out, 2 }; + +#define SYSCLK_CTRL 0x20 +#define CPUCLK_CTRL 0x24 +#define LEGACY_DIV 0x3c + +#define PLL_N(val) (((val) >> 0) & 0x7f) +#define PLL_K(val) (((val) >> 13) & 0x7) +#define PLL_M(val) (((val) >> 16) & 0x7) +#define DIV_INDEX(val) (((val) >> 8) & 0xf) + +static void __init make_pll(int idx, const char *parent, void __iomem *base) +{ + char name[8]; + u32 val, mul, div; + + sprintf(name, "pll%d", idx); + val = readl_relaxed(base + idx*8); + mul = PLL_N(val) + 1; + div = (PLL_M(val) + 1) << PLL_K(val); + clk_register_fixed_factor(NULL, name, parent, 0, mul, div); +} + +static int __init get_div(void __iomem *base) +{ + u8 sysclk_tab[16] = { 2, 4, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4 }; + int idx = DIV_INDEX(readl_relaxed(base + LEGACY_DIV)); + + return sysclk_tab[idx]; +} + +static void __init tango4_clkgen_setup(struct device_node *np) +{ + int div, ret; + void __iomem *base = of_iomap(np, 0); + const char *parent = of_clk_get_parent_name(np, 0); + + if (!base) + panic("%s: invalid address\n", np->full_name); + + make_pll(0, parent, base); + make_pll(1, parent, base); + + out[0] = clk_register_divider(NULL, "cpuclk", "pll0", 0, + base + CPUCLK_CTRL, 8, 8, CLK_DIVIDER_ONE_BASED, NULL); + + div = readl_relaxed(base + SYSCLK_CTRL) & BIT(23) ? get_div(base) : 4; + out[1] = clk_register_fixed_factor(NULL, "sysclk", "pll1", 0, 1, div); + + ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); + if (IS_ERR(out[0]) || IS_ERR(out[1]) || ret < 0) + panic("%s: clk registration failed\n", np->full_name); +} +CLK_OF_DECLARE(tango4_clkgen, "sigma,tango4-clkgen", tango4_clkgen_setup); diff --git a/drivers/clk/clk-xgene.c b/drivers/clk/clk-xgene.c index 27c0da29eca3..10224b01b97c 100644 --- a/drivers/clk/clk-xgene.c +++ b/drivers/clk/clk-xgene.c @@ -351,7 +351,8 @@ static int xgene_clk_set_rate(struct clk_hw *hw, unsigned long rate, /* Set new divider */ data = xgene_clk_read(pclk->param.divider_reg + pclk->param.reg_divider_offset); - data &= ~((1 << pclk->param.reg_divider_width) - 1); + data &= ~((1 << pclk->param.reg_divider_width) - 1) + << pclk->param.reg_divider_shift; data |= divider; xgene_clk_write(data, pclk->param.divider_reg + pclk->param.reg_divider_offset); diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index f13c3f4228d4..9352a13395c8 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1944,7 +1944,7 @@ bool clk_is_match(const struct clk *p, const struct clk *q) if (p == q) return true; - /* true if clk->core pointers match. Avoid derefing garbage */ + /* true if clk->core pointers match. Avoid dereferencing garbage */ if (!IS_ERR_OR_NULL(p) && !IS_ERR_OR_NULL(q)) if (p->core == q->core) return true; @@ -2482,7 +2482,7 @@ struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id, struct clk *clk; /* This is to allow this function to be chained to others */ - if (!hw || IS_ERR(hw)) + if (IS_ERR_OR_NULL(hw)) return (struct clk *) hw; clk = kzalloc(sizeof(*clk), GFP_KERNEL); @@ -2806,10 +2806,9 @@ void __clk_put(struct clk *clk) * re-enter into the clk framework by calling any top-level clk APIs; * this will cause a nested prepare_lock mutex. * - * In all notification cases cases (pre, post and abort rate change) the - * original clock rate is passed to the callback via struct - * clk_notifier_data.old_rate and the new frequency is passed via struct - * clk_notifier_data.new_rate. + * In all notification cases (pre, post and abort rate change) the original + * clock rate is passed to the callback via struct clk_notifier_data.old_rate + * and the new frequency is passed via struct clk_notifier_data.new_rate. * * clk_notifier_register() must be called from non-atomic context. * Returns -EINVAL if called with null arguments, -ENOMEM upon @@ -3062,9 +3061,6 @@ const char *of_clk_get_parent_name(struct device_node *np, int index) int count; struct clk *clk; - if (index < 0) - return NULL; - rc = of_parse_phandle_with_args(np, "clocks", "#clock-cells", index, &clkspec); if (rc) @@ -3083,6 +3079,9 @@ const char *of_clk_get_parent_name(struct device_node *np, int index) } count++; } + /* We went off the end of 'clock-indices' without finding it */ + if (prop && !vp) + return NULL; if (of_property_read_string_index(clkspec.np, "clock-output-names", index, diff --git a/drivers/clk/imx/clk-pllv1.c b/drivers/clk/imx/clk-pllv1.c index 8564e4342c7d..82fe3662b5f6 100644 --- a/drivers/clk/imx/clk-pllv1.c +++ b/drivers/clk/imx/clk-pllv1.c @@ -52,7 +52,7 @@ static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct clk_pllv1 *pll = to_clk_pllv1(hw); - long long ll; + unsigned long long ull; int mfn_abs; unsigned int mfi, mfn, mfd, pd; u32 reg; @@ -94,16 +94,16 @@ static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw, rate = parent_rate * 2; rate /= pd + 1; - ll = (unsigned long long)rate * mfn_abs; + ull = (unsigned long long)rate * mfn_abs; - do_div(ll, mfd + 1); + do_div(ull, mfd + 1); if (mfn_is_negative(pll, mfn)) - ll = -ll; + ull = (rate * mfi) - ull; + else + ull = (rate * mfi) + ull; - ll = (rate * mfi) + ll; - - return ll; + return ull; } static struct clk_ops clk_pllv1_ops = { diff --git a/drivers/clk/imx/clk-pllv2.c b/drivers/clk/imx/clk-pllv2.c index b18f875eac6a..4aeda56ce372 100644 --- a/drivers/clk/imx/clk-pllv2.c +++ b/drivers/clk/imx/clk-pllv2.c @@ -79,7 +79,7 @@ static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate, { long mfi, mfn, mfd, pdf, ref_clk; unsigned long dbl; - s64 temp; + u64 temp; dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN; @@ -98,8 +98,9 @@ static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate, temp = (u64) ref_clk * abs(mfn); do_div(temp, mfd + 1); if (mfn < 0) - temp = -temp; - temp = (ref_clk * mfi) + temp; + temp = (ref_clk * mfi) - temp; + else + temp = (ref_clk * mfi) + temp; return temp; } @@ -126,7 +127,7 @@ static int __clk_pllv2_set_rate(unsigned long rate, unsigned long parent_rate, { u32 reg; long mfi, pdf, mfn, mfd = 999999; - s64 temp64; + u64 temp64; unsigned long quad_parent_rate; quad_parent_rate = 4 * parent_rate; diff --git a/drivers/clk/mmp/clk-mmp2.c b/drivers/clk/mmp/clk-mmp2.c index 09d2832fbd78..71fd29348f28 100644 --- a/drivers/clk/mmp/clk-mmp2.c +++ b/drivers/clk/mmp/clk-mmp2.c @@ -9,6 +9,7 @@ * warranty of any kind, whether express or implied. */ +#include <linux/clk.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/spinlock.h> diff --git a/drivers/clk/mmp/clk-pxa168.c b/drivers/clk/mmp/clk-pxa168.c index 93e967c0f972..75244915df05 100644 --- a/drivers/clk/mmp/clk-pxa168.c +++ b/drivers/clk/mmp/clk-pxa168.c @@ -9,6 +9,7 @@ * warranty of any kind, whether express or implied. */ +#include <linux/clk.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/spinlock.h> diff --git a/drivers/clk/mmp/clk-pxa910.c b/drivers/clk/mmp/clk-pxa910.c index 993abcdb32cc..37ba04ba1368 100644 --- a/drivers/clk/mmp/clk-pxa910.c +++ b/drivers/clk/mmp/clk-pxa910.c @@ -9,6 +9,7 @@ * warranty of any kind, whether express or implied. */ +#include <linux/clk.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/spinlock.h> diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index ee4c83aab4f4..b552eceec2be 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -106,3 +106,20 @@ config MSM_MMCC_8974 Support for the multimedia clock controller on msm8974 devices. Say Y if you want to support multimedia devices such as display, graphics, video encode/decode, camera, etc. + +config MSM_GCC_8996 + tristate "MSM8996 Global Clock Controller" + 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, + i2c, USB, UFS, SD/eMMC, PCIe, etc. + +config MSM_MMCC_8996 + tristate "MSM8996 Multimedia Clock Controller" + select MSM_GCC_8996 + 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, + graphics, video encode/decode, camera, etc. diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index fe6252349e55..dc4280b85db1 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_COMMON_CLK_QCOM) += clk-qcom.o clk-qcom-y += common.o clk-qcom-y += clk-regmap.o +clk-qcom-y += clk-alpha-pll.o clk-qcom-y += clk-pll.o clk-qcom-y += clk-rcg.o clk-qcom-y += clk-rcg2.o @@ -20,5 +21,7 @@ obj-$(CONFIG_MSM_GCC_8916) += gcc-msm8916.o obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o obj-$(CONFIG_MSM_LCC_8960) += lcc-msm8960.o obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o +obj-$(CONFIG_MSM_GCC_8996) += gcc-msm8996.o obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o +obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c new file mode 100644 index 000000000000..e6a03eaf7a93 --- /dev/null +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -0,0 +1,355 @@ +/* + * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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/kernel.h> +#include <linux/export.h> +#include <linux/clk-provider.h> +#include <linux/regmap.h> +#include <linux/delay.h> + +#include "clk-alpha-pll.h" + +#define PLL_MODE 0x00 +# define PLL_OUTCTRL BIT(0) +# define PLL_BYPASSNL BIT(1) +# define PLL_RESET_N BIT(2) +# define PLL_LOCK_COUNT_SHIFT 8 +# define PLL_LOCK_COUNT_MASK 0x3f +# define PLL_BIAS_COUNT_SHIFT 14 +# define PLL_BIAS_COUNT_MASK 0x3f +# define PLL_VOTE_FSM_ENA BIT(20) +# define PLL_VOTE_FSM_RESET BIT(21) +# define PLL_ACTIVE_FLAG BIT(30) +# define PLL_LOCK_DET BIT(31) + +#define PLL_L_VAL 0x04 +#define PLL_ALPHA_VAL 0x08 +#define PLL_ALPHA_VAL_U 0x0c + +#define PLL_USER_CTL 0x10 +# define PLL_POST_DIV_SHIFT 8 +# define PLL_POST_DIV_MASK 0xf +# define PLL_ALPHA_EN BIT(24) +# define PLL_VCO_SHIFT 20 +# define PLL_VCO_MASK 0x3 + +#define PLL_USER_CTL_U 0x14 + +#define PLL_CONFIG_CTL 0x18 +#define PLL_TEST_CTL 0x1c +#define PLL_TEST_CTL_U 0x20 +#define PLL_STATUS 0x24 + +/* + * Even though 40 bits are present, use only 32 for ease of calculation. + */ +#define ALPHA_REG_BITWIDTH 40 +#define ALPHA_BITWIDTH 32 + +#define to_clk_alpha_pll(_hw) container_of(to_clk_regmap(_hw), \ + struct clk_alpha_pll, clkr) + +#define to_clk_alpha_pll_postdiv(_hw) container_of(to_clk_regmap(_hw), \ + struct clk_alpha_pll_postdiv, clkr) + +static int wait_for_pll(struct clk_alpha_pll *pll) +{ + u32 val, mask, off; + int count; + int ret; + const char *name = clk_hw_get_name(&pll->clkr.hw); + + off = pll->offset; + ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val); + if (ret) + return ret; + + if (val & PLL_VOTE_FSM_ENA) + mask = PLL_ACTIVE_FLAG; + else + mask = PLL_LOCK_DET; + + /* Wait for pll to enable. */ + for (count = 100; count > 0; count--) { + ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val); + if (ret) + return ret; + if ((val & mask) == mask) + return 0; + + udelay(1); + } + + WARN(1, "%s didn't enable after voting for it!\n", name); + return -ETIMEDOUT; +} + +static int clk_alpha_pll_enable(struct clk_hw *hw) +{ + int ret; + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + u32 val, mask, off; + + off = pll->offset; + + mask = PLL_OUTCTRL | PLL_RESET_N | PLL_BYPASSNL; + ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val); + if (ret) + return ret; + + /* If in FSM mode, just vote for it */ + if (val & PLL_VOTE_FSM_ENA) { + ret = clk_enable_regmap(hw); + if (ret) + return ret; + return wait_for_pll(pll); + } + + /* Skip if already enabled */ + if ((val & mask) == mask) + return 0; + + ret = regmap_update_bits(pll->clkr.regmap, off + PLL_MODE, + PLL_BYPASSNL, PLL_BYPASSNL); + if (ret) + return ret; + + /* + * H/W requires a 5us delay between disabling the bypass and + * de-asserting the reset. + */ + mb(); + udelay(5); + + ret = regmap_update_bits(pll->clkr.regmap, off + PLL_MODE, + PLL_RESET_N, PLL_RESET_N); + if (ret) + return ret; + + ret = wait_for_pll(pll); + if (ret) + return ret; + + ret = regmap_update_bits(pll->clkr.regmap, off + PLL_MODE, + PLL_OUTCTRL, PLL_OUTCTRL); + + /* Ensure that the write above goes through before returning. */ + mb(); + return ret; +} + +static void clk_alpha_pll_disable(struct clk_hw *hw) +{ + int ret; + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + u32 val, mask, off; + + off = pll->offset; + + ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val); + if (ret) + return; + + /* If in FSM mode, just unvote it */ + if (val & PLL_VOTE_FSM_ENA) { + clk_disable_regmap(hw); + return; + } + + mask = PLL_OUTCTRL; + regmap_update_bits(pll->clkr.regmap, off + PLL_MODE, mask, 0); + + /* Delay of 2 output clock ticks required until output is disabled */ + mb(); + udelay(1); + + mask = PLL_RESET_N | PLL_BYPASSNL; + regmap_update_bits(pll->clkr.regmap, off + PLL_MODE, mask, 0); +} + +static unsigned long alpha_pll_calc_rate(u64 prate, u32 l, u32 a) +{ + return (prate * l) + ((prate * a) >> ALPHA_BITWIDTH); +} + +static unsigned long +alpha_pll_round_rate(unsigned long rate, unsigned long prate, u32 *l, u64 *a) +{ + u64 remainder; + u64 quotient; + + quotient = rate; + remainder = do_div(quotient, prate); + *l = quotient; + + if (!remainder) { + *a = 0; + return rate; + } + + /* Upper ALPHA_BITWIDTH bits of Alpha */ + quotient = remainder << ALPHA_BITWIDTH; + remainder = do_div(quotient, prate); + + if (remainder) + quotient++; + + *a = quotient; + return alpha_pll_calc_rate(prate, *l, *a); +} + +static const struct pll_vco * +alpha_pll_find_vco(const struct clk_alpha_pll *pll, unsigned long rate) +{ + const struct pll_vco *v = pll->vco_table; + const struct pll_vco *end = v + pll->num_vco; + + for (; v < end; v++) + if (rate >= v->min_freq && rate <= v->max_freq) + return v; + + return NULL; +} + +static unsigned long +clk_alpha_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + u32 l, low, high, ctl; + u64 a = 0, prate = parent_rate; + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + u32 off = pll->offset; + + regmap_read(pll->clkr.regmap, off + PLL_L_VAL, &l); + + regmap_read(pll->clkr.regmap, off + PLL_USER_CTL, &ctl); + if (ctl & PLL_ALPHA_EN) { + regmap_read(pll->clkr.regmap, off + PLL_ALPHA_VAL, &low); + regmap_read(pll->clkr.regmap, off + PLL_ALPHA_VAL_U, &high); + a = (u64)high << 32 | low; + a >>= ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH; + } + + return alpha_pll_calc_rate(prate, l, a); +} + +static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long prate) +{ + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + const struct pll_vco *vco; + u32 l, off = pll->offset; + u64 a; + + rate = alpha_pll_round_rate(rate, prate, &l, &a); + vco = alpha_pll_find_vco(pll, rate); + if (!vco) { + pr_err("alpha pll not in a valid vco range\n"); + return -EINVAL; + } + + a <<= (ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH); + + regmap_write(pll->clkr.regmap, off + PLL_L_VAL, l); + regmap_write(pll->clkr.regmap, off + PLL_ALPHA_VAL, a); + regmap_write(pll->clkr.regmap, off + PLL_ALPHA_VAL_U, a >> 32); + + regmap_update_bits(pll->clkr.regmap, off + PLL_USER_CTL, + PLL_VCO_MASK << PLL_VCO_SHIFT, + vco->val << PLL_VCO_SHIFT); + + regmap_update_bits(pll->clkr.regmap, off + PLL_USER_CTL, PLL_ALPHA_EN, + PLL_ALPHA_EN); + + return 0; +} + +static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + u32 l; + u64 a; + unsigned long min_freq, max_freq; + + rate = alpha_pll_round_rate(rate, *prate, &l, &a); + if (alpha_pll_find_vco(pll, rate)) + return rate; + + min_freq = pll->vco_table[0].min_freq; + max_freq = pll->vco_table[pll->num_vco - 1].max_freq; + + return clamp(rate, min_freq, max_freq); +} + +const struct clk_ops clk_alpha_pll_ops = { + .enable = clk_alpha_pll_enable, + .disable = clk_alpha_pll_disable, + .recalc_rate = clk_alpha_pll_recalc_rate, + .round_rate = clk_alpha_pll_round_rate, + .set_rate = clk_alpha_pll_set_rate, +}; +EXPORT_SYMBOL_GPL(clk_alpha_pll_ops); + +static unsigned long +clk_alpha_pll_postdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw); + u32 ctl; + + regmap_read(pll->clkr.regmap, pll->offset + PLL_USER_CTL, &ctl); + + ctl >>= PLL_POST_DIV_SHIFT; + ctl &= PLL_POST_DIV_MASK; + + return parent_rate >> fls(ctl); +} + +static const struct clk_div_table clk_alpha_div_table[] = { + { 0x0, 1 }, + { 0x1, 2 }, + { 0x3, 4 }, + { 0x7, 8 }, + { 0xf, 16 }, + { } +}; + +static long +clk_alpha_pll_postdiv_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw); + + return divider_round_rate(hw, rate, prate, clk_alpha_div_table, + pll->width, CLK_DIVIDER_POWER_OF_TWO); +} + +static int clk_alpha_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw); + int div; + + /* 16 -> 0xf, 8 -> 0x7, 4 -> 0x3, 2 -> 0x1, 1 -> 0x0 */ + div = DIV_ROUND_UP_ULL((u64)parent_rate, rate) - 1; + + return regmap_update_bits(pll->clkr.regmap, pll->offset + PLL_USER_CTL, + PLL_POST_DIV_MASK << PLL_POST_DIV_SHIFT, + div << PLL_POST_DIV_SHIFT); +} + +const struct clk_ops clk_alpha_pll_postdiv_ops = { + .recalc_rate = clk_alpha_pll_postdiv_recalc_rate, + .round_rate = clk_alpha_pll_postdiv_round_rate, + .set_rate = clk_alpha_pll_postdiv_set_rate, +}; +EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_ops); diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h new file mode 100644 index 000000000000..90ce2016e1a0 --- /dev/null +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + */ + +#ifndef __QCOM_CLK_ALPHA_PLL_H__ +#define __QCOM_CLK_ALPHA_PLL_H__ + +#include <linux/clk-provider.h> +#include "clk-regmap.h" + +struct pll_vco { + unsigned long min_freq; + unsigned long max_freq; + u32 val; +}; + +/** + * struct clk_alpha_pll - phase locked loop (PLL) + * @offset: base address of registers + * @vco_table: array of VCO settings + * @clkr: regmap clock handle + */ +struct clk_alpha_pll { + u32 offset; + + const struct pll_vco *vco_table; + size_t num_vco; + + struct clk_regmap clkr; +}; + +/** + * struct clk_alpha_pll_postdiv - phase locked loop (PLL) post-divider + * @offset: base address of registers + * @width: width of post-divider + * @clkr: regmap clock handle + */ +struct clk_alpha_pll_postdiv { + u32 offset; + u8 width; + + struct clk_regmap clkr; +}; + +extern const struct clk_ops clk_alpha_pll_ops; +extern const struct clk_ops clk_alpha_pll_postdiv_ops; + +#endif diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index 4b1e94bdf29e..b904c335cda4 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h @@ -178,5 +178,6 @@ extern const struct clk_ops clk_edp_pixel_ops; extern const struct clk_ops clk_byte_ops; extern const struct clk_ops clk_byte2_ops; extern const struct clk_ops clk_pixel_ops; +extern const struct clk_ops clk_gfx3d_ops; #endif diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index b544bb302f79..a071bba8018c 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -723,3 +723,90 @@ const struct clk_ops clk_pixel_ops = { .determine_rate = clk_pixel_determine_rate, }; EXPORT_SYMBOL_GPL(clk_pixel_ops); + +static int clk_gfx3d_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct clk_rate_request parent_req = { }; + struct clk_hw *p2, *p8, *p9, *xo; + unsigned long p9_rate; + int ret; + + xo = clk_hw_get_parent_by_index(hw, 0); + if (req->rate == clk_hw_get_rate(xo)) { + req->best_parent_hw = xo; + return 0; + } + + p9 = clk_hw_get_parent_by_index(hw, 2); + p2 = clk_hw_get_parent_by_index(hw, 3); + p8 = clk_hw_get_parent_by_index(hw, 4); + + /* PLL9 is a fixed rate PLL */ + p9_rate = clk_hw_get_rate(p9); + + parent_req.rate = req->rate = min(req->rate, p9_rate); + if (req->rate == p9_rate) { + req->rate = req->best_parent_rate = p9_rate; + req->best_parent_hw = p9; + return 0; + } + + if (req->best_parent_hw == p9) { + /* Are we going back to a previously used rate? */ + if (clk_hw_get_rate(p8) == req->rate) + req->best_parent_hw = p8; + else + req->best_parent_hw = p2; + } else if (req->best_parent_hw == p8) { + req->best_parent_hw = p2; + } else { + req->best_parent_hw = p8; + } + + ret = __clk_determine_rate(req->best_parent_hw, &parent_req); + if (ret) + return ret; + + req->rate = req->best_parent_rate = parent_req.rate; + + return 0; +} + +static int clk_gfx3d_set_rate_and_parent(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate, u8 index) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + u32 cfg; + int ret; + + /* Just mux it, we don't use the division or m/n hardware */ + cfg = rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT; + ret = regmap_write(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, cfg); + if (ret) + return ret; + + return update_config(rcg); +} + +static int clk_gfx3d_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + /* + * We should never get here; clk_gfx3d_determine_rate() should always + * make us use a different parent than what we're currently using, so + * clk_gfx3d_set_rate_and_parent() should always be called. + */ + return 0; +} + +const struct clk_ops clk_gfx3d_ops = { + .is_enabled = clk_rcg2_is_enabled, + .get_parent = clk_rcg2_get_parent, + .set_parent = clk_rcg2_set_parent, + .recalc_rate = clk_rcg2_recalc_rate, + .set_rate = clk_gfx3d_set_rate, + .set_rate_and_parent = clk_gfx3d_set_rate_and_parent, + .determine_rate = clk_gfx3d_determine_rate, +}; +EXPORT_SYMBOL_GPL(clk_gfx3d_ops); diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index 8fa477293ae0..c112ebaba70d 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -17,6 +17,7 @@ #include <linux/platform_device.h> #include <linux/clk-provider.h> #include <linux/reset-controller.h> +#include <linux/of.h> #include "common.h" #include "clk-rcg.h" @@ -88,6 +89,92 @@ static void qcom_cc_gdsc_unregister(void *data) gdsc_unregister(data); } +/* + * Backwards compatibility with old DTs. Register a pass-through factor 1/1 + * clock to translate 'path' clk into 'name' clk and regsiter the 'path' + * clk as a fixed rate clock if it isn't present. + */ +static int _qcom_cc_register_board_clk(struct device *dev, const char *path, + const char *name, unsigned long rate, + bool add_factor) +{ + struct device_node *node = NULL; + struct device_node *clocks_node; + struct clk_fixed_factor *factor; + struct clk_fixed_rate *fixed; + struct clk *clk; + struct clk_init_data init_data = { }; + + clocks_node = of_find_node_by_path("/clocks"); + if (clocks_node) + node = of_find_node_by_name(clocks_node, path); + of_node_put(clocks_node); + + if (!node) { + fixed = devm_kzalloc(dev, sizeof(*fixed), GFP_KERNEL); + if (!fixed) + return -EINVAL; + + fixed->fixed_rate = rate; + fixed->hw.init = &init_data; + + init_data.name = path; + init_data.flags = CLK_IS_ROOT; + init_data.ops = &clk_fixed_rate_ops; + + clk = devm_clk_register(dev, &fixed->hw); + if (IS_ERR(clk)) + return PTR_ERR(clk); + } + of_node_put(node); + + if (add_factor) { + factor = devm_kzalloc(dev, sizeof(*factor), GFP_KERNEL); + if (!factor) + return -EINVAL; + + factor->mult = factor->div = 1; + factor->hw.init = &init_data; + + init_data.name = name; + init_data.parent_names = &path; + init_data.num_parents = 1; + init_data.flags = 0; + init_data.ops = &clk_fixed_factor_ops; + + clk = devm_clk_register(dev, &factor->hw); + if (IS_ERR(clk)) + return PTR_ERR(clk); + } + + return 0; +} + +int qcom_cc_register_board_clk(struct device *dev, const char *path, + const char *name, unsigned long rate) +{ + bool add_factor = true; + struct device_node *node; + + /* The RPM clock driver will add the factor clock if present */ + if (IS_ENABLED(CONFIG_QCOM_RPMCC)) { + node = of_find_compatible_node(NULL, NULL, "qcom,rpmcc"); + if (of_device_is_available(node)) + add_factor = false; + of_node_put(node); + } + + return _qcom_cc_register_board_clk(dev, path, name, rate, add_factor); +} +EXPORT_SYMBOL_GPL(qcom_cc_register_board_clk); + +int qcom_cc_register_sleep_clk(struct device *dev) +{ + return _qcom_cc_register_board_clk(dev, "sleep_clk", "sleep_clk_src", + 32768, true); +} +EXPORT_SYMBOL_GPL(qcom_cc_register_sleep_clk); + int qcom_cc_really_probe(struct platform_device *pdev, const struct qcom_cc_desc *desc, struct regmap *regmap) { diff --git a/drivers/clk/qcom/common.h b/drivers/clk/qcom/common.h index 7c1fba3ebc03..ae9bdeb21f29 100644 --- a/drivers/clk/qcom/common.h +++ b/drivers/clk/qcom/common.h @@ -37,6 +37,10 @@ extern const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, extern int qcom_find_src_index(struct clk_hw *hw, const struct parent_map *map, u8 src); +extern int qcom_cc_register_board_clk(struct device *dev, const char *path, + const char *name, unsigned long rate); +extern int qcom_cc_register_sleep_clk(struct device *dev); + extern struct regmap *qcom_cc_map(struct platform_device *pdev, const struct qcom_cc_desc *desc); extern int qcom_cc_really_probe(struct platform_device *pdev, diff --git a/drivers/clk/qcom/gcc-apq8084.c b/drivers/clk/qcom/gcc-apq8084.c index 1567c3a79534..cf73e539e9f6 100644 --- a/drivers/clk/qcom/gcc-apq8084.c +++ b/drivers/clk/qcom/gcc-apq8084.c @@ -3587,6 +3587,7 @@ static const struct regmap_config gcc_apq8084_regmap_config = { .val_bits = 32, .max_register = 0x1fc0, .fast_io = true, + .val_format_endian = REGMAP_ENDIAN_LITTLE, }; static const struct qcom_cc_desc gcc_apq8084_desc = { @@ -3607,18 +3608,16 @@ MODULE_DEVICE_TABLE(of, gcc_apq8084_match_table); static int gcc_apq8084_probe(struct platform_device *pdev) { - struct clk *clk; + int ret; struct device *dev = &pdev->dev; - /* Temporary until RPM clocks supported */ - clk = clk_register_fixed_rate(dev, "xo", NULL, CLK_IS_ROOT, 19200000); - if (IS_ERR(clk)) - return PTR_ERR(clk); + ret = qcom_cc_register_board_clk(dev, "xo_board", "xo", 19200000); + if (ret) + return ret; - clk = clk_register_fixed_rate(dev, "sleep_clk_src", NULL, - CLK_IS_ROOT, 32768); - if (IS_ERR(clk)) - return PTR_ERR(clk); + ret = qcom_cc_register_sleep_clk(dev); + if (ret) + return ret; return qcom_cc_probe(pdev, &gcc_apq8084_desc); } diff --git a/drivers/clk/qcom/gcc-ipq806x.c b/drivers/clk/qcom/gcc-ipq806x.c index 16fc64c082a5..b692ae881d6a 100644 --- a/drivers/clk/qcom/gcc-ipq806x.c +++ b/drivers/clk/qcom/gcc-ipq806x.c @@ -3005,6 +3005,7 @@ static const struct regmap_config gcc_ipq806x_regmap_config = { .val_bits = 32, .max_register = 0x3e40, .fast_io = true, + .val_format_endian = REGMAP_ENDIAN_LITTLE, }; static const struct qcom_cc_desc gcc_ipq806x_desc = { @@ -3023,19 +3024,17 @@ MODULE_DEVICE_TABLE(of, gcc_ipq806x_match_table); static int gcc_ipq806x_probe(struct platform_device *pdev) { - struct clk *clk; struct device *dev = &pdev->dev; struct regmap *regmap; int ret; - /* Temporary until RPM clocks supported */ - clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 25000000); - if (IS_ERR(clk)) - return PTR_ERR(clk); + ret = qcom_cc_register_board_clk(dev, "cxo_board", "cxo", 19200000); + if (ret) + return ret; - clk = clk_register_fixed_rate(dev, "pxo", NULL, CLK_IS_ROOT, 25000000); - if (IS_ERR(clk)) - return PTR_ERR(clk); + ret = qcom_cc_register_board_clk(dev, "pxo_board", "pxo", 27000000); + if (ret) + return ret; ret = qcom_cc_probe(pdev, &gcc_ipq806x_desc); if (ret) diff --git a/drivers/clk/qcom/gcc-msm8660.c b/drivers/clk/qcom/gcc-msm8660.c index f110bb5a1df3..f6a2b14dfec4 100644 --- a/drivers/clk/qcom/gcc-msm8660.c +++ b/drivers/clk/qcom/gcc-msm8660.c @@ -2702,6 +2702,7 @@ static const struct regmap_config gcc_msm8660_regmap_config = { .val_bits = 32, .max_register = 0x363c, .fast_io = true, + .val_format_endian = REGMAP_ENDIAN_LITTLE, }; static const struct qcom_cc_desc gcc_msm8660_desc = { @@ -2720,17 +2721,16 @@ MODULE_DEVICE_TABLE(of, gcc_msm8660_match_table); static int gcc_msm8660_probe(struct platform_device *pdev) { - struct clk *clk; + int ret; struct device *dev = &pdev->dev; - /* Temporary until RPM clocks supported */ - clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 19200000); - if (IS_ERR(clk)) - return PTR_ERR(clk); + ret = qcom_cc_register_board_clk(dev, "cxo_board", "cxo", 19200000); + if (ret) + return ret; - clk = clk_register_fixed_rate(dev, "pxo", NULL, CLK_IS_ROOT, 27000000); - if (IS_ERR(clk)) - return PTR_ERR(clk); + ret = qcom_cc_register_board_clk(dev, "pxo_board", "pxo", 27000000); + if (ret) + return ret; return qcom_cc_probe(pdev, &gcc_msm8660_desc); } diff --git a/drivers/clk/qcom/gcc-msm8916.c b/drivers/clk/qcom/gcc-msm8916.c index d0a0313d6bef..e3bf09d7d0ef 100644 --- a/drivers/clk/qcom/gcc-msm8916.c +++ b/drivers/clk/qcom/gcc-msm8916.c @@ -3336,6 +3336,7 @@ static const struct regmap_config gcc_msm8916_regmap_config = { .val_bits = 32, .max_register = 0x80000, .fast_io = true, + .val_format_endian = REGMAP_ENDIAN_LITTLE, }; static const struct qcom_cc_desc gcc_msm8916_desc = { @@ -3356,18 +3357,16 @@ MODULE_DEVICE_TABLE(of, gcc_msm8916_match_table); static int gcc_msm8916_probe(struct platform_device *pdev) { - struct clk *clk; + int ret; struct device *dev = &pdev->dev; - /* Temporary until RPM clocks supported */ - clk = clk_register_fixed_rate(dev, "xo", NULL, CLK_IS_ROOT, 19200000); - if (IS_ERR(clk)) - return PTR_ERR(clk); + ret = qcom_cc_register_board_clk(dev, "xo_board", "xo", 19200000); + if (ret) + return ret; - clk = clk_register_fixed_rate(dev, "sleep_clk_src", NULL, - CLK_IS_ROOT, 32768); - if (IS_ERR(clk)) - return PTR_ERR(clk); + ret = qcom_cc_register_sleep_clk(dev); + if (ret) + return ret; return qcom_cc_probe(pdev, &gcc_msm8916_desc); } diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c index 66c18bc97857..f31111e32d44 100644 --- a/drivers/clk/qcom/gcc-msm8960.c +++ b/drivers/clk/qcom/gcc-msm8960.c @@ -3468,6 +3468,7 @@ static const struct regmap_config gcc_msm8960_regmap_config = { .val_bits = 32, .max_register = 0x3660, .fast_io = true, + .val_format_endian = REGMAP_ENDIAN_LITTLE, }; static const struct regmap_config gcc_apq8064_regmap_config = { @@ -3476,6 +3477,7 @@ static const struct regmap_config gcc_apq8064_regmap_config = { .val_bits = 32, .max_register = 0x3880, .fast_io = true, + .val_format_endian = REGMAP_ENDIAN_LITTLE, }; static const struct qcom_cc_desc gcc_msm8960_desc = { @@ -3503,7 +3505,6 @@ MODULE_DEVICE_TABLE(of, gcc_msm8960_match_table); static int gcc_msm8960_probe(struct platform_device *pdev) { - struct clk *clk; struct device *dev = &pdev->dev; const struct of_device_id *match; struct platform_device *tsens; @@ -3513,14 +3514,13 @@ static int gcc_msm8960_probe(struct platform_device *pdev) if (!match) return -EINVAL; - /* Temporary until RPM clocks supported */ - clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 19200000); - if (IS_ERR(clk)) - return PTR_ERR(clk); + ret = qcom_cc_register_board_clk(dev, "cxo_board", "cxo", 19200000); + if (ret) + return ret; - clk = clk_register_fixed_rate(dev, "pxo", NULL, CLK_IS_ROOT, 27000000); - if (IS_ERR(clk)) - return PTR_ERR(clk); + ret = qcom_cc_register_board_clk(dev, "pxo_board", "pxo", 27000000); + if (ret) + return ret; ret = qcom_cc_probe(pdev, match->data); if (ret) diff --git a/drivers/clk/qcom/gcc-msm8974.c b/drivers/clk/qcom/gcc-msm8974.c index 28abb8f8f293..df164d618e34 100644 --- a/drivers/clk/qcom/gcc-msm8974.c +++ b/drivers/clk/qcom/gcc-msm8974.c @@ -2680,6 +2680,7 @@ static const struct regmap_config gcc_msm8974_regmap_config = { .val_bits = 32, .max_register = 0x1fc0, .fast_io = true, + .val_format_endian = REGMAP_ENDIAN_LITTLE, }; static const struct qcom_cc_desc gcc_msm8974_desc = { @@ -2717,7 +2718,7 @@ static void msm8974_pro_clock_override(void) static int gcc_msm8974_probe(struct platform_device *pdev) { - struct clk *clk; + int ret; struct device *dev = &pdev->dev; bool pro; const struct of_device_id *id; @@ -2730,16 +2731,13 @@ static int gcc_msm8974_probe(struct platform_device *pdev) if (pro) msm8974_pro_clock_override(); - /* Temporary until RPM clocks supported */ - clk = clk_register_fixed_rate(dev, "xo", NULL, CLK_IS_ROOT, 19200000); - if (IS_ERR(clk)) - return PTR_ERR(clk); + ret = qcom_cc_register_board_clk(dev, "xo_board", "xo", 19200000); + if (ret) + return ret; - /* Should move to DT node? */ - clk = clk_register_fixed_rate(dev, "sleep_clk_src", NULL, - CLK_IS_ROOT, 32768); - if (IS_ERR(clk)) - return PTR_ERR(clk); + ret = qcom_cc_register_sleep_clk(dev); + if (ret) + return ret; return qcom_cc_probe(pdev, &gcc_msm8974_desc); } diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c new file mode 100644 index 000000000000..16d7c323db49 --- /dev/null +++ b/drivers/clk/qcom/gcc-msm8996.c @@ -0,0 +1,3422 @@ +/* + * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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/kernel.h> +#include <linux/bitops.h> +#include <linux/err.h> +#include <linux/platform_device.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/clk-provider.h> +#include <linux/regmap.h> +#include <linux/reset-controller.h> + +#include <dt-bindings/clock/qcom,gcc-msm8996.h> + +#include "common.h" +#include "clk-regmap.h" +#include "clk-alpha-pll.h" +#include "clk-rcg.h" +#include "clk-branch.h" +#include "reset.h" + +#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } + +enum { + P_XO, + P_GPLL0, + P_GPLL2, + P_GPLL3, + P_GPLL1, + P_GPLL2_EARLY, + P_GPLL0_EARLY_DIV, + P_SLEEP_CLK, + P_GPLL4, + P_AUD_REF_CLK, + P_GPLL1_EARLY_DIV +}; + +static const struct parent_map gcc_sleep_clk_map[] = { + { P_SLEEP_CLK, 5 } +}; + +static const char * const gcc_sleep_clk[] = { + "sleep_clk" +}; + +static const struct parent_map gcc_xo_gpll0_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 } +}; + +static const char * const gcc_xo_gpll0[] = { + "xo", + "gpll0" +}; + +static const struct parent_map gcc_xo_sleep_clk_map[] = { + { P_XO, 0 }, + { P_SLEEP_CLK, 5 } +}; + +static const char * const gcc_xo_sleep_clk[] = { + "xo", + "sleep_clk" +}; + +static const struct parent_map gcc_xo_gpll0_gpll0_early_div_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL0_EARLY_DIV, 6 } +}; + +static const char * const gcc_xo_gpll0_gpll0_early_div[] = { + "xo", + "gpll0", + "gpll0_early_div" +}; + +static const struct parent_map gcc_xo_gpll0_gpll4_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL4, 5 } +}; + +static const char * const gcc_xo_gpll0_gpll4[] = { + "xo", + "gpll0", + "gpll4" +}; + +static const struct parent_map gcc_xo_gpll0_aud_ref_clk_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_AUD_REF_CLK, 2 } +}; + +static const char * const gcc_xo_gpll0_aud_ref_clk[] = { + "xo", + "gpll0", + "aud_ref_clk" +}; + +static const struct parent_map gcc_xo_gpll0_sleep_clk_gpll0_early_div_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_SLEEP_CLK, 5 }, + { P_GPLL0_EARLY_DIV, 6 } +}; + +static const char * const gcc_xo_gpll0_sleep_clk_gpll0_early_div[] = { + "xo", + "gpll0", + "sleep_clk", + "gpll0_early_div" +}; + +static const struct parent_map gcc_xo_gpll0_gpll4_gpll0_early_div_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL4, 5 }, + { P_GPLL0_EARLY_DIV, 6 } +}; + +static const char * const gcc_xo_gpll0_gpll4_gpll0_early_div[] = { + "xo", + "gpll0", + "gpll4", + "gpll0_early_div" +}; + +static const struct parent_map gcc_xo_gpll0_gpll2_gpll3_gpll0_early_div_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL2, 2 }, + { P_GPLL3, 3 }, + { P_GPLL0_EARLY_DIV, 6 } +}; + +static const char * const gcc_xo_gpll0_gpll2_gpll3_gpll0_early_div[] = { + "xo", + "gpll0", + "gpll2", + "gpll3", + "gpll0_early_div" +}; + +static const struct parent_map gcc_xo_gpll0_gpll1_early_div_gpll1_gpll4_gpll0_early_div_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL1_EARLY_DIV, 3 }, + { P_GPLL1, 4 }, + { P_GPLL4, 5 }, + { P_GPLL0_EARLY_DIV, 6 } +}; + +static const char * const gcc_xo_gpll0_gpll1_early_div_gpll1_gpll4_gpll0_early_div[] = { + "xo", + "gpll0", + "gpll1_early_div", + "gpll1", + "gpll4", + "gpll0_early_div" +}; + +static const struct parent_map gcc_xo_gpll0_gpll2_gpll3_gpll1_gpll2_early_gpll0_early_div_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL2, 2 }, + { P_GPLL3, 3 }, + { P_GPLL1, 4 }, + { P_GPLL2_EARLY, 5 }, + { P_GPLL0_EARLY_DIV, 6 } +}; + +static const char * const gcc_xo_gpll0_gpll2_gpll3_gpll1_gpll2_early_gpll0_early_div[] = { + "xo", + "gpll0", + "gpll2", + "gpll3", + "gpll1", + "gpll2_early", + "gpll0_early_div" +}; + +static const struct parent_map gcc_xo_gpll0_gpll2_gpll3_gpll1_gpll4_gpll0_early_div_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL2, 2 }, + { P_GPLL3, 3 }, + { P_GPLL1, 4 }, + { P_GPLL4, 5 }, + { P_GPLL0_EARLY_DIV, 6 } +}; + +static const char * const gcc_xo_gpll0_gpll2_gpll3_gpll1_gpll4_gpll0_early_div[] = { + "xo", + "gpll0", + "gpll2", + "gpll3", + "gpll1", + "gpll4", + "gpll0_early_div" +}; + +static struct clk_fixed_factor xo = { + .mult = 1, + .div = 1, + .hw.init = &(struct clk_init_data){ + .name = "xo", + .parent_names = (const char *[]){ "xo_board" }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_alpha_pll gpll0_early = { + .offset = 0x00000, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpll0_early", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_fixed_factor gpll0_early_div = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "gpll0_early_div", + .parent_names = (const char *[]){ "gpll0_early" }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_alpha_pll_postdiv gpll0 = { + .offset = 0x00000, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll0", + .parent_names = (const char *[]){ "gpll0_early" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ops, + }, +}; + +static struct clk_alpha_pll gpll4_early = { + .offset = 0x77000, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gpll4_early", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv gpll4 = { + .offset = 0x77000, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll4", + .parent_names = (const char *[]){ "gpll4_early" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ops, + }, +}; + +static const struct freq_tbl ftbl_system_noc_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0_EARLY_DIV, 6, 0, 0), + F(100000000, P_GPLL0, 6, 0, 0), + F(150000000, P_GPLL0, 4, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + F(240000000, P_GPLL0, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 system_noc_clk_src = { + .cmd_rcgr = 0x0401c, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll2_gpll3_gpll1_gpll2_early_gpll0_early_div_map, + .freq_tbl = ftbl_system_noc_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "system_noc_clk_src", + .parent_names = gcc_xo_gpll0_gpll2_gpll3_gpll1_gpll2_early_gpll0_early_div, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_config_noc_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(37500000, P_GPLL0, 16, 0, 0), + F(75000000, P_GPLL0, 8, 0, 0), + { } +}; + +static struct clk_rcg2 config_noc_clk_src = { + .cmd_rcgr = 0x0500c, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_config_noc_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "config_noc_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_periph_noc_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(37500000, P_GPLL0, 16, 0, 0), + F(50000000, P_GPLL0, 12, 0, 0), + F(75000000, P_GPLL0, 8, 0, 0), + F(100000000, P_GPLL0, 6, 0, 0), + { } +}; + +static struct clk_rcg2 periph_noc_clk_src = { + .cmd_rcgr = 0x06014, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_periph_noc_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "periph_noc_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_usb30_master_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(120000000, P_GPLL0, 5, 0, 0), + F(150000000, P_GPLL0, 4, 0, 0), + { } +}; + +static struct clk_rcg2 usb30_master_clk_src = { + .cmd_rcgr = 0x0f014, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll0_early_div_map, + .freq_tbl = ftbl_usb30_master_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb30_master_clk_src", + .parent_names = gcc_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_usb30_mock_utmi_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 usb30_mock_utmi_clk_src = { + .cmd_rcgr = 0x0f028, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll0_early_div_map, + .freq_tbl = ftbl_usb30_mock_utmi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb30_mock_utmi_clk_src", + .parent_names = gcc_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_usb3_phy_aux_clk_src[] = { + F(1200000, P_XO, 16, 0, 0), + { } +}; + +static struct clk_rcg2 usb3_phy_aux_clk_src = { + .cmd_rcgr = 0x5000c, + .hid_width = 5, + .parent_map = gcc_xo_sleep_clk_map, + .freq_tbl = ftbl_usb3_phy_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb3_phy_aux_clk_src", + .parent_names = gcc_xo_sleep_clk, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_usb20_master_clk_src[] = { + F(120000000, P_GPLL0, 5, 0, 0), + { } +}; + +static struct clk_rcg2 usb20_master_clk_src = { + .cmd_rcgr = 0x12010, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll0_early_div_map, + .freq_tbl = ftbl_usb20_master_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb20_master_clk_src", + .parent_names = gcc_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 usb20_mock_utmi_clk_src = { + .cmd_rcgr = 0x12024, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll0_early_div_map, + .freq_tbl = ftbl_usb30_mock_utmi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb20_mock_utmi_clk_src", + .parent_names = gcc_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_sdcc1_apps_clk_src[] = { + F(144000, P_XO, 16, 3, 25), + F(400000, P_XO, 12, 1, 4), + F(20000000, P_GPLL0, 15, 1, 2), + F(25000000, P_GPLL0, 12, 1, 2), + F(50000000, P_GPLL0, 12, 0, 0), + F(96000000, P_GPLL4, 4, 0, 0), + F(192000000, P_GPLL4, 2, 0, 0), + F(384000000, P_GPLL4, 1, 0, 0), + { } +}; + +static struct clk_rcg2 sdcc1_apps_clk_src = { + .cmd_rcgr = 0x13010, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll4_gpll0_early_div_map, + .freq_tbl = ftbl_sdcc1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc1_apps_clk_src", + .parent_names = gcc_xo_gpll0_gpll4_gpll0_early_div, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 sdcc1_ice_core_clk_src = { + .cmd_rcgr = 0x13024, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll4_gpll0_early_div_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc1_ice_core_clk_src", + .parent_names = gcc_xo_gpll0_gpll4_gpll0_early_div, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_sdcc2_apps_clk_src[] = { + F(144000, P_XO, 16, 3, 25), + F(400000, P_XO, 12, 1, 4), + F(20000000, P_GPLL0, 15, 1, 2), + F(25000000, P_GPLL0, 12, 1, 2), + F(50000000, P_GPLL0, 12, 0, 0), + F(100000000, P_GPLL0, 6, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + { } +}; + +static struct clk_rcg2 sdcc2_apps_clk_src = { + .cmd_rcgr = 0x14010, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll4_map, + .freq_tbl = ftbl_sdcc2_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc2_apps_clk_src", + .parent_names = gcc_xo_gpll0_gpll4, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 sdcc3_apps_clk_src = { + .cmd_rcgr = 0x15010, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll4_map, + .freq_tbl = ftbl_sdcc2_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc3_apps_clk_src", + .parent_names = gcc_xo_gpll0_gpll4, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_sdcc4_apps_clk_src[] = { + F(144000, P_XO, 16, 3, 25), + F(400000, P_XO, 12, 1, 4), + F(20000000, P_GPLL0, 15, 1, 2), + F(25000000, P_GPLL0, 12, 1, 2), + F(50000000, P_GPLL0, 12, 0, 0), + F(100000000, P_GPLL0, 6, 0, 0), + { } +}; + +static struct clk_rcg2 sdcc4_apps_clk_src = { + .cmd_rcgr = 0x16010, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_sdcc4_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc4_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_blsp1_qup1_spi_apps_clk_src[] = { + F(960000, P_XO, 10, 1, 2), + F(4800000, P_XO, 4, 0, 0), + F(9600000, P_XO, 2, 0, 0), + F(15000000, P_GPLL0, 10, 1, 4), + F(19200000, P_XO, 1, 0, 0), + F(25000000, P_GPLL0, 12, 1, 2), + F(50000000, P_GPLL0, 12, 0, 0), + { } +}; + +static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = { + .cmd_rcgr = 0x1900c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup1_spi_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_blsp1_qup1_i2c_apps_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0, 12, 0, 0), + { } +}; + +static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = { + .cmd_rcgr = 0x19020, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup1_i2c_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_blsp1_uart1_apps_clk_src[] = { + F(3686400, P_GPLL0, 1, 96, 15625), + F(7372800, P_GPLL0, 1, 192, 15625), + F(14745600, P_GPLL0, 1, 384, 15625), + F(16000000, P_GPLL0, 5, 2, 15), + F(19200000, P_XO, 1, 0, 0), + F(24000000, P_GPLL0, 5, 1, 5), + F(32000000, P_GPLL0, 1, 4, 75), + F(40000000, P_GPLL0, 15, 0, 0), + F(46400000, P_GPLL0, 1, 29, 375), + F(48000000, P_GPLL0, 12.5, 0, 0), + F(51200000, P_GPLL0, 1, 32, 375), + F(56000000, P_GPLL0, 1, 7, 75), + F(58982400, P_GPLL0, 1, 1536, 15625), + F(60000000, P_GPLL0, 10, 0, 0), + F(63157895, P_GPLL0, 9.5, 0, 0), + { } +}; + +static struct clk_rcg2 blsp1_uart1_apps_clk_src = { + .cmd_rcgr = 0x1a00c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_uart1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart1_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = { + .cmd_rcgr = 0x1b00c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup2_spi_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = { + .cmd_rcgr = 0x1b020, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup2_i2c_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_uart2_apps_clk_src = { + .cmd_rcgr = 0x1c00c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_uart1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart2_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = { + .cmd_rcgr = 0x1d00c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup3_spi_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = { + .cmd_rcgr = 0x1d020, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup3_i2c_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_uart3_apps_clk_src = { + .cmd_rcgr = 0x1e00c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_uart1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart3_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = { + .cmd_rcgr = 0x1f00c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup4_spi_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = { + .cmd_rcgr = 0x1f020, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup4_i2c_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_uart4_apps_clk_src = { + .cmd_rcgr = 0x2000c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_uart1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart4_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup5_spi_apps_clk_src = { + .cmd_rcgr = 0x2100c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup5_spi_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup5_i2c_apps_clk_src = { + .cmd_rcgr = 0x21020, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup5_i2c_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_uart5_apps_clk_src = { + .cmd_rcgr = 0x2200c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_uart1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart5_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup6_spi_apps_clk_src = { + .cmd_rcgr = 0x2300c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup6_spi_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup6_i2c_apps_clk_src = { + .cmd_rcgr = 0x23020, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup6_i2c_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_uart6_apps_clk_src = { + .cmd_rcgr = 0x2400c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_uart1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart6_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup1_spi_apps_clk_src = { + .cmd_rcgr = 0x2600c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup1_spi_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup1_i2c_apps_clk_src = { + .cmd_rcgr = 0x26020, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup1_i2c_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_uart1_apps_clk_src = { + .cmd_rcgr = 0x2700c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_uart1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_uart1_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup2_spi_apps_clk_src = { + .cmd_rcgr = 0x2800c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup2_spi_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup2_i2c_apps_clk_src = { + .cmd_rcgr = 0x28020, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup2_i2c_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_uart2_apps_clk_src = { + .cmd_rcgr = 0x2900c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_uart1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_uart2_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup3_spi_apps_clk_src = { + .cmd_rcgr = 0x2a00c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup3_spi_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup3_i2c_apps_clk_src = { + .cmd_rcgr = 0x2a020, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup3_i2c_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_uart3_apps_clk_src = { + .cmd_rcgr = 0x2b00c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_uart1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_uart3_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup4_spi_apps_clk_src = { + .cmd_rcgr = 0x2c00c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup4_spi_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup4_i2c_apps_clk_src = { + .cmd_rcgr = 0x2c020, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup4_i2c_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_uart4_apps_clk_src = { + .cmd_rcgr = 0x2d00c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_uart1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_uart4_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup5_spi_apps_clk_src = { + .cmd_rcgr = 0x2e00c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup5_spi_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup5_i2c_apps_clk_src = { + .cmd_rcgr = 0x2e020, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup5_i2c_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_uart5_apps_clk_src = { + .cmd_rcgr = 0x2f00c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_uart1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_uart5_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup6_spi_apps_clk_src = { + .cmd_rcgr = 0x3000c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup6_spi_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup6_i2c_apps_clk_src = { + .cmd_rcgr = 0x30020, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup6_i2c_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_uart6_apps_clk_src = { + .cmd_rcgr = 0x3100c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_blsp1_uart1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_uart6_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_pdm2_clk_src[] = { + F(60000000, P_GPLL0, 10, 0, 0), + { } +}; + +static struct clk_rcg2 pdm2_clk_src = { + .cmd_rcgr = 0x33010, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_pdm2_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pdm2_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_tsif_ref_clk_src[] = { + F(105495, P_XO, 1, 1, 182), + { } +}; + +static struct clk_rcg2 tsif_ref_clk_src = { + .cmd_rcgr = 0x36010, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_aud_ref_clk_map, + .freq_tbl = ftbl_tsif_ref_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "tsif_ref_clk_src", + .parent_names = gcc_xo_gpll0_aud_ref_clk, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_sleep_clk_src = { + .cmd_rcgr = 0x43014, + .hid_width = 5, + .parent_map = gcc_sleep_clk_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_sleep_clk_src", + .parent_names = gcc_sleep_clk, + .num_parents = 1, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 hmss_rbcpr_clk_src = { + .cmd_rcgr = 0x48040, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_usb30_mock_utmi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "hmss_rbcpr_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 hmss_gpll0_clk_src = { + .cmd_rcgr = 0x48058, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "hmss_gpll0_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gp1_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(100000000, P_GPLL0, 6, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gp1_clk_src = { + .cmd_rcgr = 0x64004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_sleep_clk_gpll0_early_div_map, + .freq_tbl = ftbl_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp1_clk_src", + .parent_names = gcc_xo_gpll0_sleep_clk_gpll0_early_div, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gp2_clk_src = { + .cmd_rcgr = 0x65004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_sleep_clk_gpll0_early_div_map, + .freq_tbl = ftbl_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp2_clk_src", + .parent_names = gcc_xo_gpll0_sleep_clk_gpll0_early_div, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gp3_clk_src = { + .cmd_rcgr = 0x66004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_sleep_clk_gpll0_early_div_map, + .freq_tbl = ftbl_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp3_clk_src", + .parent_names = gcc_xo_gpll0_sleep_clk_gpll0_early_div, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_pcie_aux_clk_src[] = { + F(1010526, P_XO, 1, 1, 19), + { } +}; + +static struct clk_rcg2 pcie_aux_clk_src = { + .cmd_rcgr = 0x6c000, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_sleep_clk_map, + .freq_tbl = ftbl_pcie_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pcie_aux_clk_src", + .parent_names = gcc_xo_sleep_clk, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_ufs_axi_clk_src[] = { + F(100000000, P_GPLL0, 6, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + F(240000000, P_GPLL0, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 ufs_axi_clk_src = { + .cmd_rcgr = 0x75024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_ufs_axi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "ufs_axi_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 ufs_ice_core_clk_src = { + .cmd_rcgr = 0x76014, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "ufs_ice_core_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 qspi_ser_clk_src = { + .cmd_rcgr = 0x8b00c, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll1_early_div_gpll1_gpll4_gpll0_early_div_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "qspi_ser_clk_src", + .parent_names = gcc_xo_gpll0_gpll1_early_div_gpll1_gpll4_gpll0_early_div, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_sys_noc_usb3_axi_clk = { + .halt_reg = 0x0f03c, + .clkr = { + .enable_reg = 0x0f03c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sys_noc_usb3_axi_clk", + .parent_names = (const char *[]){ "usb30_master_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sys_noc_ufs_axi_clk = { + .halt_reg = 0x75038, + .clkr = { + .enable_reg = 0x75038, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sys_noc_ufs_axi_clk", + .parent_names = (const char *[]){ "ufs_axi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_periph_noc_usb20_ahb_clk = { + .halt_reg = 0x6010, + .clkr = { + .enable_reg = 0x6010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_periph_noc_usb20_ahb_clk", + .parent_names = (const char *[]){ "usb20_master_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mmss_noc_cfg_ahb_clk = { + .halt_reg = 0x9008, + .clkr = { + .enable_reg = 0x9008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mmss_noc_cfg_ahb_clk", + .parent_names = (const char *[]){ "config_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mmss_bimc_gfx_clk = { + .halt_reg = 0x9010, + .clkr = { + .enable_reg = 0x9010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mmss_bimc_gfx_clk", + .flags = CLK_SET_RATE_PARENT | CLK_IS_ROOT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_master_clk = { + .halt_reg = 0x0f008, + .clkr = { + .enable_reg = 0x0f008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_master_clk", + .parent_names = (const char *[]){ "usb30_master_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_sleep_clk = { + .halt_reg = 0x0f00c, + .clkr = { + .enable_reg = 0x0f00c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_sleep_clk", + .parent_names = (const char *[]){ "gcc_sleep_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_mock_utmi_clk = { + .halt_reg = 0x0f010, + .clkr = { + .enable_reg = 0x0f010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_mock_utmi_clk", + .parent_names = (const char *[]){ "usb30_mock_utmi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_phy_aux_clk = { + .halt_reg = 0x50000, + .clkr = { + .enable_reg = 0x50000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_phy_aux_clk", + .parent_names = (const char *[]){ "usb3_phy_aux_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_phy_pipe_clk = { + .halt_reg = 0x50004, + .clkr = { + .enable_reg = 0x50004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_phy_pipe_clk", + .parent_names = (const char *[]){ "usb3_phy_pipe_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb20_master_clk = { + .halt_reg = 0x12004, + .clkr = { + .enable_reg = 0x12004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb20_master_clk", + .parent_names = (const char *[]){ "usb20_master_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb20_sleep_clk = { + .halt_reg = 0x12008, + .clkr = { + .enable_reg = 0x12008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb20_sleep_clk", + .parent_names = (const char *[]){ "gcc_sleep_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb20_mock_utmi_clk = { + .halt_reg = 0x1200c, + .clkr = { + .enable_reg = 0x1200c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb20_mock_utmi_clk", + .parent_names = (const char *[]){ "usb20_mock_utmi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_phy_cfg_ahb2phy_clk = { + .halt_reg = 0x6a004, + .clkr = { + .enable_reg = 0x6a004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_phy_cfg_ahb2phy_clk", + .parent_names = (const char *[]){ "periph_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_apps_clk = { + .halt_reg = 0x13004, + .clkr = { + .enable_reg = 0x13004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_apps_clk", + .parent_names = (const char *[]){ "sdcc1_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ahb_clk = { + .halt_reg = 0x13008, + .clkr = { + .enable_reg = 0x13008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ahb_clk", + .parent_names = (const char *[]){ "periph_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ice_core_clk = { + .halt_reg = 0x13038, + .clkr = { + .enable_reg = 0x13038, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ice_core_clk", + .parent_names = (const char *[]){ "sdcc1_ice_core_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_apps_clk = { + .halt_reg = 0x14004, + .clkr = { + .enable_reg = 0x14004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_apps_clk", + .parent_names = (const char *[]){ "sdcc2_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_ahb_clk = { + .halt_reg = 0x14008, + .clkr = { + .enable_reg = 0x14008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_ahb_clk", + .parent_names = (const char *[]){ "periph_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc3_apps_clk = { + .halt_reg = 0x15004, + .clkr = { + .enable_reg = 0x15004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc3_apps_clk", + .parent_names = (const char *[]){ "sdcc3_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc3_ahb_clk = { + .halt_reg = 0x15008, + .clkr = { + .enable_reg = 0x15008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc3_ahb_clk", + .parent_names = (const char *[]){ "periph_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc4_apps_clk = { + .halt_reg = 0x16004, + .clkr = { + .enable_reg = 0x16004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc4_apps_clk", + .parent_names = (const char *[]){ "sdcc4_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc4_ahb_clk = { + .halt_reg = 0x16008, + .clkr = { + .enable_reg = 0x16008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc4_ahb_clk", + .parent_names = (const char *[]){ "periph_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_ahb_clk = { + .halt_reg = 0x17004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(17), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_ahb_clk", + .parent_names = (const char *[]){ "periph_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_sleep_clk = { + .halt_reg = 0x17008, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(16), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_sleep_clk", + .parent_names = (const char *[]){ "gcc_sleep_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = { + .halt_reg = 0x19004, + .clkr = { + .enable_reg = 0x19004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup1_spi_apps_clk", + .parent_names = (const char *[]){ "blsp1_qup1_spi_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = { + .halt_reg = 0x19008, + .clkr = { + .enable_reg = 0x19008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup1_i2c_apps_clk", + .parent_names = (const char *[]){ "blsp1_qup1_i2c_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart1_apps_clk = { + .halt_reg = 0x1a004, + .clkr = { + .enable_reg = 0x1a004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart1_apps_clk", + .parent_names = (const char *[]){ "blsp1_uart1_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = { + .halt_reg = 0x1b004, + .clkr = { + .enable_reg = 0x1b004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup2_spi_apps_clk", + .parent_names = (const char *[]){ "blsp1_qup2_spi_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = { + .halt_reg = 0x1b008, + .clkr = { + .enable_reg = 0x1b008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup2_i2c_apps_clk", + .parent_names = (const char *[]){ "blsp1_qup2_i2c_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart2_apps_clk = { + .halt_reg = 0x1c004, + .clkr = { + .enable_reg = 0x1c004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart2_apps_clk", + .parent_names = (const char *[]){ "blsp1_uart2_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = { + .halt_reg = 0x1d004, + .clkr = { + .enable_reg = 0x1d004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup3_spi_apps_clk", + .parent_names = (const char *[]){ "blsp1_qup3_spi_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = { + .halt_reg = 0x1d008, + .clkr = { + .enable_reg = 0x1d008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup3_i2c_apps_clk", + .parent_names = (const char *[]){ "blsp1_qup3_i2c_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart3_apps_clk = { + .halt_reg = 0x1e004, + .clkr = { + .enable_reg = 0x1e004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart3_apps_clk", + .parent_names = (const char *[]){ "blsp1_uart3_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = { + .halt_reg = 0x1f004, + .clkr = { + .enable_reg = 0x1f004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup4_spi_apps_clk", + .parent_names = (const char *[]){ "blsp1_qup4_spi_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = { + .halt_reg = 0x1f008, + .clkr = { + .enable_reg = 0x1f008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup4_i2c_apps_clk", + .parent_names = (const char *[]){ "blsp1_qup4_i2c_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart4_apps_clk = { + .halt_reg = 0x20004, + .clkr = { + .enable_reg = 0x20004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart4_apps_clk", + .parent_names = (const char *[]){ "blsp1_uart4_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup5_spi_apps_clk = { + .halt_reg = 0x21004, + .clkr = { + .enable_reg = 0x21004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup5_spi_apps_clk", + .parent_names = (const char *[]){ "blsp1_qup5_spi_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup5_i2c_apps_clk = { + .halt_reg = 0x21008, + .clkr = { + .enable_reg = 0x21008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup5_i2c_apps_clk", + .parent_names = (const char *[]){ "blsp1_qup5_i2c_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart5_apps_clk = { + .halt_reg = 0x22004, + .clkr = { + .enable_reg = 0x22004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart5_apps_clk", + .parent_names = (const char *[]){ "blsp1_uart5_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup6_spi_apps_clk = { + .halt_reg = 0x23004, + .clkr = { + .enable_reg = 0x23004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup6_spi_apps_clk", + .parent_names = (const char *[]){ "blsp1_qup6_spi_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup6_i2c_apps_clk = { + .halt_reg = 0x23008, + .clkr = { + .enable_reg = 0x23008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup6_i2c_apps_clk", + .parent_names = (const char *[]){ "blsp1_qup6_i2c_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart6_apps_clk = { + .halt_reg = 0x24004, + .clkr = { + .enable_reg = 0x24004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart6_apps_clk", + .parent_names = (const char *[]){ "blsp1_uart6_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_ahb_clk = { + .halt_reg = 0x25004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(15), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_ahb_clk", + .parent_names = (const char *[]){ "periph_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_sleep_clk = { + .halt_reg = 0x25008, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(14), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_sleep_clk", + .parent_names = (const char *[]){ "gcc_sleep_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup1_spi_apps_clk = { + .halt_reg = 0x26004, + .clkr = { + .enable_reg = 0x26004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup1_spi_apps_clk", + .parent_names = (const char *[]){ "blsp2_qup1_spi_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup1_i2c_apps_clk = { + .halt_reg = 0x26008, + .clkr = { + .enable_reg = 0x26008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup1_i2c_apps_clk", + .parent_names = (const char *[]){ "blsp2_qup1_i2c_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_uart1_apps_clk = { + .halt_reg = 0x27004, + .clkr = { + .enable_reg = 0x27004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_uart1_apps_clk", + .parent_names = (const char *[]){ "blsp2_uart1_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup2_spi_apps_clk = { + .halt_reg = 0x28004, + .clkr = { + .enable_reg = 0x28004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup2_spi_apps_clk", + .parent_names = (const char *[]){ "blsp2_qup2_spi_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup2_i2c_apps_clk = { + .halt_reg = 0x28008, + .clkr = { + .enable_reg = 0x28008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup2_i2c_apps_clk", + .parent_names = (const char *[]){ "blsp2_qup2_i2c_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_uart2_apps_clk = { + .halt_reg = 0x29004, + .clkr = { + .enable_reg = 0x29004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_uart2_apps_clk", + .parent_names = (const char *[]){ "blsp2_uart2_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup3_spi_apps_clk = { + .halt_reg = 0x2a004, + .clkr = { + .enable_reg = 0x2a004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup3_spi_apps_clk", + .parent_names = (const char *[]){ "blsp2_qup3_spi_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup3_i2c_apps_clk = { + .halt_reg = 0x2a008, + .clkr = { + .enable_reg = 0x2a008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup3_i2c_apps_clk", + .parent_names = (const char *[]){ "blsp2_qup3_i2c_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_uart3_apps_clk = { + .halt_reg = 0x2b004, + .clkr = { + .enable_reg = 0x2b004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_uart3_apps_clk", + .parent_names = (const char *[]){ "blsp2_uart3_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup4_spi_apps_clk = { + .halt_reg = 0x2c004, + .clkr = { + .enable_reg = 0x2c004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup4_spi_apps_clk", + .parent_names = (const char *[]){ "blsp2_qup4_spi_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup4_i2c_apps_clk = { + .halt_reg = 0x2c008, + .clkr = { + .enable_reg = 0x2c008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup4_i2c_apps_clk", + .parent_names = (const char *[]){ "blsp2_qup4_i2c_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_uart4_apps_clk = { + .halt_reg = 0x2d004, + .clkr = { + .enable_reg = 0x2d004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_uart4_apps_clk", + .parent_names = (const char *[]){ "blsp2_uart4_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup5_spi_apps_clk = { + .halt_reg = 0x2e004, + .clkr = { + .enable_reg = 0x2e004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup5_spi_apps_clk", + .parent_names = (const char *[]){ "blsp2_qup5_spi_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup5_i2c_apps_clk = { + .halt_reg = 0x2e008, + .clkr = { + .enable_reg = 0x2e008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup5_i2c_apps_clk", + .parent_names = (const char *[]){ "blsp2_qup5_i2c_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_uart5_apps_clk = { + .halt_reg = 0x2f004, + .clkr = { + .enable_reg = 0x2f004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_uart5_apps_clk", + .parent_names = (const char *[]){ "blsp2_uart5_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup6_spi_apps_clk = { + .halt_reg = 0x30004, + .clkr = { + .enable_reg = 0x30004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup6_spi_apps_clk", + .parent_names = (const char *[]){ "blsp2_qup6_spi_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup6_i2c_apps_clk = { + .halt_reg = 0x30008, + .clkr = { + .enable_reg = 0x30008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup6_i2c_apps_clk", + .parent_names = (const char *[]){ "blsp2_qup6_i2c_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_uart6_apps_clk = { + .halt_reg = 0x31004, + .clkr = { + .enable_reg = 0x31004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_uart6_apps_clk", + .parent_names = (const char *[]){ "blsp2_uart6_apps_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm_ahb_clk = { + .halt_reg = 0x33004, + .clkr = { + .enable_reg = 0x33004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm_ahb_clk", + .parent_names = (const char *[]){ "periph_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm2_clk = { + .halt_reg = 0x3300c, + .clkr = { + .enable_reg = 0x3300c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm2_clk", + .parent_names = (const char *[]){ "pdm2_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_prng_ahb_clk = { + .halt_reg = 0x34004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(13), + .hw.init = &(struct clk_init_data){ + .name = "gcc_prng_ahb_clk", + .parent_names = (const char *[]){ "config_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_tsif_ahb_clk = { + .halt_reg = 0x36004, + .clkr = { + .enable_reg = 0x36004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_tsif_ahb_clk", + .parent_names = (const char *[]){ "periph_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_tsif_ref_clk = { + .halt_reg = 0x36008, + .clkr = { + .enable_reg = 0x36008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_tsif_ref_clk", + .parent_names = (const char *[]){ "tsif_ref_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_tsif_inactivity_timers_clk = { + .halt_reg = 0x3600c, + .clkr = { + .enable_reg = 0x3600c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_tsif_inactivity_timers_clk", + .parent_names = (const char *[]){ "gcc_sleep_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_boot_rom_ahb_clk = { + .halt_reg = 0x38004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_boot_rom_ahb_clk", + .parent_names = (const char *[]){ "config_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_bimc_gfx_clk = { + .halt_reg = 0x46018, + .clkr = { + .enable_reg = 0x46018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_bimc_gfx_clk", + .flags = CLK_SET_RATE_PARENT | CLK_IS_ROOT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_hmss_rbcpr_clk = { + .halt_reg = 0x4800c, + .clkr = { + .enable_reg = 0x4800c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_hmss_rbcpr_clk", + .parent_names = (const char *[]){ "hmss_rbcpr_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp1_clk = { + .halt_reg = 0x64000, + .clkr = { + .enable_reg = 0x64000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp1_clk", + .parent_names = (const char *[]){ "gp1_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp2_clk = { + .halt_reg = 0x65000, + .clkr = { + .enable_reg = 0x65000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp2_clk", + .parent_names = (const char *[]){ "gp2_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp3_clk = { + .halt_reg = 0x66000, + .clkr = { + .enable_reg = 0x66000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp3_clk", + .parent_names = (const char *[]){ "gp3_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_slv_axi_clk = { + .halt_reg = 0x6b008, + .clkr = { + .enable_reg = 0x6b008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_slv_axi_clk", + .parent_names = (const char *[]){ "system_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_mstr_axi_clk = { + .halt_reg = 0x6b00c, + .clkr = { + .enable_reg = 0x6b00c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_mstr_axi_clk", + .parent_names = (const char *[]){ "system_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_cfg_ahb_clk = { + .halt_reg = 0x6b010, + .clkr = { + .enable_reg = 0x6b010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_cfg_ahb_clk", + .parent_names = (const char *[]){ "config_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_aux_clk = { + .halt_reg = 0x6b014, + .clkr = { + .enable_reg = 0x6b014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_aux_clk", + .parent_names = (const char *[]){ "pcie_aux_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_pipe_clk = { + .halt_reg = 0x6b018, + .clkr = { + .enable_reg = 0x6b018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_pipe_clk", + .parent_names = (const char *[]){ "pcie_0_pipe_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_1_slv_axi_clk = { + .halt_reg = 0x6d008, + .clkr = { + .enable_reg = 0x6d008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_1_slv_axi_clk", + .parent_names = (const char *[]){ "system_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_1_mstr_axi_clk = { + .halt_reg = 0x6d00c, + .clkr = { + .enable_reg = 0x6d00c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_1_mstr_axi_clk", + .parent_names = (const char *[]){ "system_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_1_cfg_ahb_clk = { + .halt_reg = 0x6d010, + .clkr = { + .enable_reg = 0x6d010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_1_cfg_ahb_clk", + .parent_names = (const char *[]){ "config_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_1_aux_clk = { + .halt_reg = 0x6d014, + .clkr = { + .enable_reg = 0x6d014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_1_aux_clk", + .parent_names = (const char *[]){ "pcie_aux_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_1_pipe_clk = { + .halt_reg = 0x6d018, + .clkr = { + .enable_reg = 0x6d018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_1_pipe_clk", + .parent_names = (const char *[]){ "pcie_1_pipe_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_2_slv_axi_clk = { + .halt_reg = 0x6e008, + .clkr = { + .enable_reg = 0x6e008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_2_slv_axi_clk", + .parent_names = (const char *[]){ "system_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_2_mstr_axi_clk = { + .halt_reg = 0x6e00c, + .clkr = { + .enable_reg = 0x6e00c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_2_mstr_axi_clk", + .parent_names = (const char *[]){ "system_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_2_cfg_ahb_clk = { + .halt_reg = 0x6e010, + .clkr = { + .enable_reg = 0x6e010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_2_cfg_ahb_clk", + .parent_names = (const char *[]){ "config_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_2_aux_clk = { + .halt_reg = 0x6e014, + .clkr = { + .enable_reg = 0x6e014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_2_aux_clk", + .parent_names = (const char *[]){ "pcie_aux_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_2_pipe_clk = { + .halt_reg = 0x6e108, + .clkr = { + .enable_reg = 0x6e108, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_2_pipe_clk", + .parent_names = (const char *[]){ "pcie_2_pipe_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_phy_cfg_ahb_clk = { + .halt_reg = 0x6f004, + .clkr = { + .enable_reg = 0x6f004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_phy_cfg_ahb_clk", + .parent_names = (const char *[]){ "config_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_phy_aux_clk = { + .halt_reg = 0x6f008, + .clkr = { + .enable_reg = 0x6f008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_phy_aux_clk", + .parent_names = (const char *[]){ "pcie_aux_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_axi_clk = { + .halt_reg = 0x75008, + .clkr = { + .enable_reg = 0x75008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_axi_clk", + .parent_names = (const char *[]){ "ufs_axi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_ahb_clk = { + .halt_reg = 0x7500c, + .clkr = { + .enable_reg = 0x7500c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_ahb_clk", + .parent_names = (const char *[]){ "config_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_fixed_factor ufs_tx_cfg_clk_src = { + .mult = 1, + .div = 16, + .hw.init = &(struct clk_init_data){ + .name = "ufs_tx_cfg_clk_src", + .parent_names = (const char *[]){ "ufs_axi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_branch gcc_ufs_tx_cfg_clk = { + .halt_reg = 0x75010, + .clkr = { + .enable_reg = 0x75010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_tx_cfg_clk", + .parent_names = (const char *[]){ "ufs_tx_cfg_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_fixed_factor ufs_rx_cfg_clk_src = { + .mult = 1, + .div = 16, + .hw.init = &(struct clk_init_data){ + .name = "ufs_rx_cfg_clk_src", + .parent_names = (const char *[]){ "ufs_axi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_branch gcc_ufs_rx_cfg_clk = { + .halt_reg = 0x75014, + .clkr = { + .enable_reg = 0x75014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_rx_cfg_clk", + .parent_names = (const char *[]){ "ufs_rx_cfg_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_tx_symbol_0_clk = { + .halt_reg = 0x75018, + .clkr = { + .enable_reg = 0x75018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_tx_symbol_0_clk", + .parent_names = (const char *[]){ "ufs_tx_symbol_0_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_rx_symbol_0_clk = { + .halt_reg = 0x7501c, + .clkr = { + .enable_reg = 0x7501c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_rx_symbol_0_clk", + .parent_names = (const char *[]){ "ufs_rx_symbol_0_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_rx_symbol_1_clk = { + .halt_reg = 0x75020, + .clkr = { + .enable_reg = 0x75020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_rx_symbol_1_clk", + .parent_names = (const char *[]){ "ufs_rx_symbol_1_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_fixed_factor ufs_ice_core_postdiv_clk_src = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "ufs_ice_core_postdiv_clk_src", + .parent_names = (const char *[]){ "ufs_ice_core_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_branch gcc_ufs_unipro_core_clk = { + .halt_reg = 0x7600c, + .clkr = { + .enable_reg = 0x7600c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_unipro_core_clk", + .parent_names = (const char *[]){ "ufs_ice_core_postdiv_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_ice_core_clk = { + .halt_reg = 0x76010, + .clkr = { + .enable_reg = 0x76010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_ice_core_clk", + .parent_names = (const char *[]){ "ufs_ice_core_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_sys_clk_core_clk = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x76030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_sys_clk_core_clk", + .ops = &clk_branch2_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gcc_ufs_tx_symbol_clk_core_clk = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x76034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_tx_symbol_clk_core_clk", + .ops = &clk_branch2_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gcc_aggre0_snoc_axi_clk = { + .halt_reg = 0x81008, + .clkr = { + .enable_reg = 0x81008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre0_snoc_axi_clk", + .parent_names = (const char *[]){ "system_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre0_cnoc_ahb_clk = { + .halt_reg = 0x8100c, + .clkr = { + .enable_reg = 0x8100c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre0_cnoc_ahb_clk", + .parent_names = (const char *[]){ "config_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_smmu_aggre0_axi_clk = { + .halt_reg = 0x81014, + .clkr = { + .enable_reg = 0x81014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_smmu_aggre0_axi_clk", + .parent_names = (const char *[]){ "system_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_smmu_aggre0_ahb_clk = { + .halt_reg = 0x81018, + .clkr = { + .enable_reg = 0x81018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_smmu_aggre0_ahb_clk", + .parent_names = (const char *[]){ "config_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre1_pnoc_ahb_clk = { + .halt_reg = 0x82014, + .clkr = { + .enable_reg = 0x82014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre1_pnoc_ahb_clk", + .parent_names = (const char *[]){ "periph_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre2_ufs_axi_clk = { + .halt_reg = 0x83014, + .clkr = { + .enable_reg = 0x83014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre2_ufs_axi_clk", + .parent_names = (const char *[]){ "ufs_axi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre2_usb3_axi_clk = { + .halt_reg = 0x83018, + .clkr = { + .enable_reg = 0x83018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre2_usb3_axi_clk", + .parent_names = (const char *[]){ "usb30_master_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qspi_ahb_clk = { + .halt_reg = 0x8b004, + .clkr = { + .enable_reg = 0x8b004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qspi_ahb_clk", + .parent_names = (const char *[]){ "periph_noc_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qspi_ser_clk = { + .halt_reg = 0x8b008, + .clkr = { + .enable_reg = 0x8b008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qspi_ser_clk", + .parent_names = (const char *[]){ "qspi_ser_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_clkref_clk = { + .halt_reg = 0x8800C, + .clkr = { + .enable_reg = 0x8800C, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_clkref_clk", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_hdmi_clkref_clk = { + .halt_reg = 0x88000, + .clkr = { + .enable_reg = 0x88000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_hdmi_clkref_clk", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_clkref_clk = { + .halt_reg = 0x88008, + .clkr = { + .enable_reg = 0x88008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_clkref_clk", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_clkref_clk = { + .halt_reg = 0x88010, + .clkr = { + .enable_reg = 0x88010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_clkref_clk", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_rx2_usb2_clkref_clk = { + .halt_reg = 0x88014, + .clkr = { + .enable_reg = 0x88014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_rx2_usb2_clkref_clk", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_rx1_usb2_clkref_clk = { + .halt_reg = 0x88018, + .clkr = { + .enable_reg = 0x88018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_rx1_usb2_clkref_clk", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_hw *gcc_msm8996_hws[] = { + &xo.hw, + &gpll0_early_div.hw, + &ufs_tx_cfg_clk_src.hw, + &ufs_rx_cfg_clk_src.hw, + &ufs_ice_core_postdiv_clk_src.hw, +}; + +static struct clk_regmap *gcc_msm8996_clocks[] = { + [GPLL0_EARLY] = &gpll0_early.clkr, + [GPLL0] = &gpll0.clkr, + [GPLL4_EARLY] = &gpll4_early.clkr, + [GPLL4] = &gpll4.clkr, + [SYSTEM_NOC_CLK_SRC] = &system_noc_clk_src.clkr, + [CONFIG_NOC_CLK_SRC] = &config_noc_clk_src.clkr, + [PERIPH_NOC_CLK_SRC] = &periph_noc_clk_src.clkr, + [USB30_MASTER_CLK_SRC] = &usb30_master_clk_src.clkr, + [USB30_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr, + [USB3_PHY_AUX_CLK_SRC] = &usb3_phy_aux_clk_src.clkr, + [USB20_MASTER_CLK_SRC] = &usb20_master_clk_src.clkr, + [USB20_MOCK_UTMI_CLK_SRC] = &usb20_mock_utmi_clk_src.clkr, + [SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr, + [SDCC1_ICE_CORE_CLK_SRC] = &sdcc1_ice_core_clk_src.clkr, + [SDCC2_APPS_CLK_SRC] = &sdcc2_apps_clk_src.clkr, + [SDCC3_APPS_CLK_SRC] = &sdcc3_apps_clk_src.clkr, + [SDCC4_APPS_CLK_SRC] = &sdcc4_apps_clk_src.clkr, + [BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr, + [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr, + [BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr, + [BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr, + [BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr, + [BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr, + [BLSP1_QUP3_SPI_APPS_CLK_SRC] = &blsp1_qup3_spi_apps_clk_src.clkr, + [BLSP1_QUP3_I2C_APPS_CLK_SRC] = &blsp1_qup3_i2c_apps_clk_src.clkr, + [BLSP1_UART3_APPS_CLK_SRC] = &blsp1_uart3_apps_clk_src.clkr, + [BLSP1_QUP4_SPI_APPS_CLK_SRC] = &blsp1_qup4_spi_apps_clk_src.clkr, + [BLSP1_QUP4_I2C_APPS_CLK_SRC] = &blsp1_qup4_i2c_apps_clk_src.clkr, + [BLSP1_UART4_APPS_CLK_SRC] = &blsp1_uart4_apps_clk_src.clkr, + [BLSP1_QUP5_SPI_APPS_CLK_SRC] = &blsp1_qup5_spi_apps_clk_src.clkr, + [BLSP1_QUP5_I2C_APPS_CLK_SRC] = &blsp1_qup5_i2c_apps_clk_src.clkr, + [BLSP1_UART5_APPS_CLK_SRC] = &blsp1_uart5_apps_clk_src.clkr, + [BLSP1_QUP6_SPI_APPS_CLK_SRC] = &blsp1_qup6_spi_apps_clk_src.clkr, + [BLSP1_QUP6_I2C_APPS_CLK_SRC] = &blsp1_qup6_i2c_apps_clk_src.clkr, + [BLSP1_UART6_APPS_CLK_SRC] = &blsp1_uart6_apps_clk_src.clkr, + [BLSP2_QUP1_SPI_APPS_CLK_SRC] = &blsp2_qup1_spi_apps_clk_src.clkr, + [BLSP2_QUP1_I2C_APPS_CLK_SRC] = &blsp2_qup1_i2c_apps_clk_src.clkr, + [BLSP2_UART1_APPS_CLK_SRC] = &blsp2_uart1_apps_clk_src.clkr, + [BLSP2_QUP2_SPI_APPS_CLK_SRC] = &blsp2_qup2_spi_apps_clk_src.clkr, + [BLSP2_QUP2_I2C_APPS_CLK_SRC] = &blsp2_qup2_i2c_apps_clk_src.clkr, + [BLSP2_UART2_APPS_CLK_SRC] = &blsp2_uart2_apps_clk_src.clkr, + [BLSP2_QUP3_SPI_APPS_CLK_SRC] = &blsp2_qup3_spi_apps_clk_src.clkr, + [BLSP2_QUP3_I2C_APPS_CLK_SRC] = &blsp2_qup3_i2c_apps_clk_src.clkr, + [BLSP2_UART3_APPS_CLK_SRC] = &blsp2_uart3_apps_clk_src.clkr, + [BLSP2_QUP4_SPI_APPS_CLK_SRC] = &blsp2_qup4_spi_apps_clk_src.clkr, + [BLSP2_QUP4_I2C_APPS_CLK_SRC] = &blsp2_qup4_i2c_apps_clk_src.clkr, + [BLSP2_UART4_APPS_CLK_SRC] = &blsp2_uart4_apps_clk_src.clkr, + [BLSP2_QUP5_SPI_APPS_CLK_SRC] = &blsp2_qup5_spi_apps_clk_src.clkr, + [BLSP2_QUP5_I2C_APPS_CLK_SRC] = &blsp2_qup5_i2c_apps_clk_src.clkr, + [BLSP2_UART5_APPS_CLK_SRC] = &blsp2_uart5_apps_clk_src.clkr, + [BLSP2_QUP6_SPI_APPS_CLK_SRC] = &blsp2_qup6_spi_apps_clk_src.clkr, + [BLSP2_QUP6_I2C_APPS_CLK_SRC] = &blsp2_qup6_i2c_apps_clk_src.clkr, + [BLSP2_UART6_APPS_CLK_SRC] = &blsp2_uart6_apps_clk_src.clkr, + [PDM2_CLK_SRC] = &pdm2_clk_src.clkr, + [TSIF_REF_CLK_SRC] = &tsif_ref_clk_src.clkr, + [GCC_SLEEP_CLK_SRC] = &gcc_sleep_clk_src.clkr, + [HMSS_RBCPR_CLK_SRC] = &hmss_rbcpr_clk_src.clkr, + [HMSS_GPLL0_CLK_SRC] = &hmss_gpll0_clk_src.clkr, + [GP1_CLK_SRC] = &gp1_clk_src.clkr, + [GP2_CLK_SRC] = &gp2_clk_src.clkr, + [GP3_CLK_SRC] = &gp3_clk_src.clkr, + [PCIE_AUX_CLK_SRC] = &pcie_aux_clk_src.clkr, + [UFS_AXI_CLK_SRC] = &ufs_axi_clk_src.clkr, + [UFS_ICE_CORE_CLK_SRC] = &ufs_ice_core_clk_src.clkr, + [QSPI_SER_CLK_SRC] = &qspi_ser_clk_src.clkr, + [GCC_SYS_NOC_USB3_AXI_CLK] = &gcc_sys_noc_usb3_axi_clk.clkr, + [GCC_SYS_NOC_UFS_AXI_CLK] = &gcc_sys_noc_ufs_axi_clk.clkr, + [GCC_PERIPH_NOC_USB20_AHB_CLK] = &gcc_periph_noc_usb20_ahb_clk.clkr, + [GCC_MMSS_NOC_CFG_AHB_CLK] = &gcc_mmss_noc_cfg_ahb_clk.clkr, + [GCC_MMSS_BIMC_GFX_CLK] = &gcc_mmss_bimc_gfx_clk.clkr, + [GCC_USB30_MASTER_CLK] = &gcc_usb30_master_clk.clkr, + [GCC_USB30_SLEEP_CLK] = &gcc_usb30_sleep_clk.clkr, + [GCC_USB30_MOCK_UTMI_CLK] = &gcc_usb30_mock_utmi_clk.clkr, + [GCC_USB3_PHY_AUX_CLK] = &gcc_usb3_phy_aux_clk.clkr, + [GCC_USB3_PHY_PIPE_CLK] = &gcc_usb3_phy_pipe_clk.clkr, + [GCC_USB20_MASTER_CLK] = &gcc_usb20_master_clk.clkr, + [GCC_USB20_SLEEP_CLK] = &gcc_usb20_sleep_clk.clkr, + [GCC_USB20_MOCK_UTMI_CLK] = &gcc_usb20_mock_utmi_clk.clkr, + [GCC_USB_PHY_CFG_AHB2PHY_CLK] = &gcc_usb_phy_cfg_ahb2phy_clk.clkr, + [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr, + [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr, + [GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr, + [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr, + [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr, + [GCC_SDCC3_APPS_CLK] = &gcc_sdcc3_apps_clk.clkr, + [GCC_SDCC3_AHB_CLK] = &gcc_sdcc3_ahb_clk.clkr, + [GCC_SDCC4_APPS_CLK] = &gcc_sdcc4_apps_clk.clkr, + [GCC_SDCC4_AHB_CLK] = &gcc_sdcc4_ahb_clk.clkr, + [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr, + [GCC_BLSP1_SLEEP_CLK] = &gcc_blsp1_sleep_clk.clkr, + [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr, + [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr, + [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr, + [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr, + [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr, + [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr, + [GCC_BLSP1_QUP3_SPI_APPS_CLK] = &gcc_blsp1_qup3_spi_apps_clk.clkr, + [GCC_BLSP1_QUP3_I2C_APPS_CLK] = &gcc_blsp1_qup3_i2c_apps_clk.clkr, + [GCC_BLSP1_UART3_APPS_CLK] = &gcc_blsp1_uart3_apps_clk.clkr, + [GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr, + [GCC_BLSP1_QUP4_I2C_APPS_CLK] = &gcc_blsp1_qup4_i2c_apps_clk.clkr, + [GCC_BLSP1_UART4_APPS_CLK] = &gcc_blsp1_uart4_apps_clk.clkr, + [GCC_BLSP1_QUP5_SPI_APPS_CLK] = &gcc_blsp1_qup5_spi_apps_clk.clkr, + [GCC_BLSP1_QUP5_I2C_APPS_CLK] = &gcc_blsp1_qup5_i2c_apps_clk.clkr, + [GCC_BLSP1_UART5_APPS_CLK] = &gcc_blsp1_uart5_apps_clk.clkr, + [GCC_BLSP1_QUP6_SPI_APPS_CLK] = &gcc_blsp1_qup6_spi_apps_clk.clkr, + [GCC_BLSP1_QUP6_I2C_APPS_CLK] = &gcc_blsp1_qup6_i2c_apps_clk.clkr, + [GCC_BLSP1_UART6_APPS_CLK] = &gcc_blsp1_uart6_apps_clk.clkr, + [GCC_BLSP2_AHB_CLK] = &gcc_blsp2_ahb_clk.clkr, + [GCC_BLSP2_SLEEP_CLK] = &gcc_blsp2_sleep_clk.clkr, + [GCC_BLSP2_QUP1_SPI_APPS_CLK] = &gcc_blsp2_qup1_spi_apps_clk.clkr, + [GCC_BLSP2_QUP1_I2C_APPS_CLK] = &gcc_blsp2_qup1_i2c_apps_clk.clkr, + [GCC_BLSP2_UART1_APPS_CLK] = &gcc_blsp2_uart1_apps_clk.clkr, + [GCC_BLSP2_QUP2_SPI_APPS_CLK] = &gcc_blsp2_qup2_spi_apps_clk.clkr, + [GCC_BLSP2_QUP2_I2C_APPS_CLK] = &gcc_blsp2_qup2_i2c_apps_clk.clkr, + [GCC_BLSP2_UART2_APPS_CLK] = &gcc_blsp2_uart2_apps_clk.clkr, + [GCC_BLSP2_QUP3_SPI_APPS_CLK] = &gcc_blsp2_qup3_spi_apps_clk.clkr, + [GCC_BLSP2_QUP3_I2C_APPS_CLK] = &gcc_blsp2_qup3_i2c_apps_clk.clkr, + [GCC_BLSP2_UART3_APPS_CLK] = &gcc_blsp2_uart3_apps_clk.clkr, + [GCC_BLSP2_QUP4_SPI_APPS_CLK] = &gcc_blsp2_qup4_spi_apps_clk.clkr, + [GCC_BLSP2_QUP4_I2C_APPS_CLK] = &gcc_blsp2_qup4_i2c_apps_clk.clkr, + [GCC_BLSP2_UART4_APPS_CLK] = &gcc_blsp2_uart4_apps_clk.clkr, + [GCC_BLSP2_QUP5_SPI_APPS_CLK] = &gcc_blsp2_qup5_spi_apps_clk.clkr, + [GCC_BLSP2_QUP5_I2C_APPS_CLK] = &gcc_blsp2_qup5_i2c_apps_clk.clkr, + [GCC_BLSP2_UART5_APPS_CLK] = &gcc_blsp2_uart5_apps_clk.clkr, + [GCC_BLSP2_QUP6_SPI_APPS_CLK] = &gcc_blsp2_qup6_spi_apps_clk.clkr, + [GCC_BLSP2_QUP6_I2C_APPS_CLK] = &gcc_blsp2_qup6_i2c_apps_clk.clkr, + [GCC_BLSP2_UART6_APPS_CLK] = &gcc_blsp2_uart6_apps_clk.clkr, + [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr, + [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr, + [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr, + [GCC_TSIF_AHB_CLK] = &gcc_tsif_ahb_clk.clkr, + [GCC_TSIF_REF_CLK] = &gcc_tsif_ref_clk.clkr, + [GCC_TSIF_INACTIVITY_TIMERS_CLK] = &gcc_tsif_inactivity_timers_clk.clkr, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_BIMC_GFX_CLK] = &gcc_bimc_gfx_clk.clkr, + [GCC_HMSS_RBCPR_CLK] = &gcc_hmss_rbcpr_clk.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_PCIE_0_SLV_AXI_CLK] = &gcc_pcie_0_slv_axi_clk.clkr, + [GCC_PCIE_0_MSTR_AXI_CLK] = &gcc_pcie_0_mstr_axi_clk.clkr, + [GCC_PCIE_0_CFG_AHB_CLK] = &gcc_pcie_0_cfg_ahb_clk.clkr, + [GCC_PCIE_0_AUX_CLK] = &gcc_pcie_0_aux_clk.clkr, + [GCC_PCIE_0_PIPE_CLK] = &gcc_pcie_0_pipe_clk.clkr, + [GCC_PCIE_1_SLV_AXI_CLK] = &gcc_pcie_1_slv_axi_clk.clkr, + [GCC_PCIE_1_MSTR_AXI_CLK] = &gcc_pcie_1_mstr_axi_clk.clkr, + [GCC_PCIE_1_CFG_AHB_CLK] = &gcc_pcie_1_cfg_ahb_clk.clkr, + [GCC_PCIE_1_AUX_CLK] = &gcc_pcie_1_aux_clk.clkr, + [GCC_PCIE_1_PIPE_CLK] = &gcc_pcie_1_pipe_clk.clkr, + [GCC_PCIE_2_SLV_AXI_CLK] = &gcc_pcie_2_slv_axi_clk.clkr, + [GCC_PCIE_2_MSTR_AXI_CLK] = &gcc_pcie_2_mstr_axi_clk.clkr, + [GCC_PCIE_2_CFG_AHB_CLK] = &gcc_pcie_2_cfg_ahb_clk.clkr, + [GCC_PCIE_2_AUX_CLK] = &gcc_pcie_2_aux_clk.clkr, + [GCC_PCIE_2_PIPE_CLK] = &gcc_pcie_2_pipe_clk.clkr, + [GCC_PCIE_PHY_CFG_AHB_CLK] = &gcc_pcie_phy_cfg_ahb_clk.clkr, + [GCC_PCIE_PHY_AUX_CLK] = &gcc_pcie_phy_aux_clk.clkr, + [GCC_UFS_AXI_CLK] = &gcc_ufs_axi_clk.clkr, + [GCC_UFS_AHB_CLK] = &gcc_ufs_ahb_clk.clkr, + [GCC_UFS_TX_CFG_CLK] = &gcc_ufs_tx_cfg_clk.clkr, + [GCC_UFS_RX_CFG_CLK] = &gcc_ufs_rx_cfg_clk.clkr, + [GCC_UFS_TX_SYMBOL_0_CLK] = &gcc_ufs_tx_symbol_0_clk.clkr, + [GCC_UFS_RX_SYMBOL_0_CLK] = &gcc_ufs_rx_symbol_0_clk.clkr, + [GCC_UFS_RX_SYMBOL_1_CLK] = &gcc_ufs_rx_symbol_1_clk.clkr, + [GCC_UFS_UNIPRO_CORE_CLK] = &gcc_ufs_unipro_core_clk.clkr, + [GCC_UFS_ICE_CORE_CLK] = &gcc_ufs_ice_core_clk.clkr, + [GCC_UFS_SYS_CLK_CORE_CLK] = &gcc_ufs_sys_clk_core_clk.clkr, + [GCC_UFS_TX_SYMBOL_CLK_CORE_CLK] = &gcc_ufs_tx_symbol_clk_core_clk.clkr, + [GCC_AGGRE0_SNOC_AXI_CLK] = &gcc_aggre0_snoc_axi_clk.clkr, + [GCC_AGGRE0_CNOC_AHB_CLK] = &gcc_aggre0_cnoc_ahb_clk.clkr, + [GCC_SMMU_AGGRE0_AXI_CLK] = &gcc_smmu_aggre0_axi_clk.clkr, + [GCC_SMMU_AGGRE0_AHB_CLK] = &gcc_smmu_aggre0_ahb_clk.clkr, + [GCC_AGGRE1_PNOC_AHB_CLK] = &gcc_aggre1_pnoc_ahb_clk.clkr, + [GCC_AGGRE2_UFS_AXI_CLK] = &gcc_aggre2_ufs_axi_clk.clkr, + [GCC_AGGRE2_USB3_AXI_CLK] = &gcc_aggre2_usb3_axi_clk.clkr, + [GCC_QSPI_AHB_CLK] = &gcc_qspi_ahb_clk.clkr, + [GCC_QSPI_SER_CLK] = &gcc_qspi_ser_clk.clkr, + [GCC_USB3_CLKREF_CLK] = &gcc_usb3_clkref_clk.clkr, + [GCC_HDMI_CLKREF_CLK] = &gcc_hdmi_clkref_clk.clkr, + [GCC_UFS_CLKREF_CLK] = &gcc_ufs_clkref_clk.clkr, + [GCC_PCIE_CLKREF_CLK] = &gcc_pcie_clkref_clk.clkr, + [GCC_RX2_USB2_CLKREF_CLK] = &gcc_rx2_usb2_clkref_clk.clkr, + [GCC_RX1_USB2_CLKREF_CLK] = &gcc_rx1_usb2_clkref_clk.clkr, +}; + +static const struct qcom_reset_map gcc_msm8996_resets[] = { + [GCC_SYSTEM_NOC_BCR] = { 0x4000 }, + [GCC_CONFIG_NOC_BCR] = { 0x5000 }, + [GCC_PERIPH_NOC_BCR] = { 0x6000 }, + [GCC_IMEM_BCR] = { 0x8000 }, + [GCC_MMSS_BCR] = { 0x9000 }, + [GCC_PIMEM_BCR] = { 0x0a000 }, + [GCC_QDSS_BCR] = { 0x0c000 }, + [GCC_USB_30_BCR] = { 0x0f000 }, + [GCC_USB_20_BCR] = { 0x12000 }, + [GCC_QUSB2PHY_PRIM_BCR] = { 0x12038 }, + [GCC_QUSB2PHY_SEC_BCR] = { 0x1203c }, + [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 }, + [GCC_SDCC1_BCR] = { 0x13000 }, + [GCC_SDCC2_BCR] = { 0x14000 }, + [GCC_SDCC3_BCR] = { 0x15000 }, + [GCC_SDCC4_BCR] = { 0x16000 }, + [GCC_BLSP1_BCR] = { 0x17000 }, + [GCC_BLSP1_QUP1_BCR] = { 0x19000 }, + [GCC_BLSP1_UART1_BCR] = { 0x1a000 }, + [GCC_BLSP1_QUP2_BCR] = { 0x1b000 }, + [GCC_BLSP1_UART2_BCR] = { 0x1c000 }, + [GCC_BLSP1_QUP3_BCR] = { 0x1d000 }, + [GCC_BLSP1_UART3_BCR] = { 0x1e000 }, + [GCC_BLSP1_QUP4_BCR] = { 0x1f000 }, + [GCC_BLSP1_UART4_BCR] = { 0x20000 }, + [GCC_BLSP1_QUP5_BCR] = { 0x21000 }, + [GCC_BLSP1_UART5_BCR] = { 0x22000 }, + [GCC_BLSP1_QUP6_BCR] = { 0x23000 }, + [GCC_BLSP1_UART6_BCR] = { 0x24000 }, + [GCC_BLSP2_BCR] = { 0x25000 }, + [GCC_BLSP2_QUP1_BCR] = { 0x26000 }, + [GCC_BLSP2_UART1_BCR] = { 0x27000 }, + [GCC_BLSP2_QUP2_BCR] = { 0x28000 }, + [GCC_BLSP2_UART2_BCR] = { 0x29000 }, + [GCC_BLSP2_QUP3_BCR] = { 0x2a000 }, + [GCC_BLSP2_UART3_BCR] = { 0x2b000 }, + [GCC_BLSP2_QUP4_BCR] = { 0x2c000 }, + [GCC_BLSP2_UART4_BCR] = { 0x2d000 }, + [GCC_BLSP2_QUP5_BCR] = { 0x2e000 }, + [GCC_BLSP2_UART5_BCR] = { 0x2f000 }, + [GCC_BLSP2_QUP6_BCR] = { 0x30000 }, + [GCC_BLSP2_UART6_BCR] = { 0x31000 }, + [GCC_PDM_BCR] = { 0x33000 }, + [GCC_PRNG_BCR] = { 0x34000 }, + [GCC_TSIF_BCR] = { 0x36000 }, + [GCC_TCSR_BCR] = { 0x37000 }, + [GCC_BOOT_ROM_BCR] = { 0x38000 }, + [GCC_MSG_RAM_BCR] = { 0x39000 }, + [GCC_TLMM_BCR] = { 0x3a000 }, + [GCC_MPM_BCR] = { 0x3b000 }, + [GCC_SEC_CTRL_BCR] = { 0x3d000 }, + [GCC_SPMI_BCR] = { 0x3f000 }, + [GCC_SPDM_BCR] = { 0x40000 }, + [GCC_CE1_BCR] = { 0x41000 }, + [GCC_BIMC_BCR] = { 0x44000 }, + [GCC_SNOC_BUS_TIMEOUT0_BCR] = { 0x49000 }, + [GCC_SNOC_BUS_TIMEOUT2_BCR] = { 0x49008 }, + [GCC_SNOC_BUS_TIMEOUT1_BCR] = { 0x49010 }, + [GCC_SNOC_BUS_TIMEOUT3_BCR] = { 0x49018 }, + [GCC_SNOC_BUS_TIMEOUT_EXTREF_BCR] = { 0x49020 }, + [GCC_PNOC_BUS_TIMEOUT0_BCR] = { 0x4a000 }, + [GCC_PNOC_BUS_TIMEOUT1_BCR] = { 0x4a008 }, + [GCC_PNOC_BUS_TIMEOUT2_BCR] = { 0x4a010 }, + [GCC_PNOC_BUS_TIMEOUT3_BCR] = { 0x4a018 }, + [GCC_PNOC_BUS_TIMEOUT4_BCR] = { 0x4a020 }, + [GCC_CNOC_BUS_TIMEOUT0_BCR] = { 0x4b000 }, + [GCC_CNOC_BUS_TIMEOUT1_BCR] = { 0x4b008 }, + [GCC_CNOC_BUS_TIMEOUT2_BCR] = { 0x4b010 }, + [GCC_CNOC_BUS_TIMEOUT3_BCR] = { 0x4b018 }, + [GCC_CNOC_BUS_TIMEOUT4_BCR] = { 0x4b020 }, + [GCC_CNOC_BUS_TIMEOUT5_BCR] = { 0x4b028 }, + [GCC_CNOC_BUS_TIMEOUT6_BCR] = { 0x4b030 }, + [GCC_CNOC_BUS_TIMEOUT7_BCR] = { 0x4b038 }, + [GCC_CNOC_BUS_TIMEOUT8_BCR] = { 0x80000 }, + [GCC_CNOC_BUS_TIMEOUT9_BCR] = { 0x80008 }, + [GCC_CNOC_BUS_TIMEOUT_EXTREF_BCR] = { 0x80010 }, + [GCC_APB2JTAG_BCR] = { 0x4c000 }, + [GCC_RBCPR_CX_BCR] = { 0x4e000 }, + [GCC_RBCPR_MX_BCR] = { 0x4f000 }, + [GCC_PCIE_0_BCR] = { 0x6b000 }, + [GCC_PCIE_0_PHY_BCR] = { 0x6c01c }, + [GCC_PCIE_1_BCR] = { 0x6d000 }, + [GCC_PCIE_1_PHY_BCR] = { 0x6d038 }, + [GCC_PCIE_2_BCR] = { 0x6e000 }, + [GCC_PCIE_2_PHY_BCR] = { 0x6e038 }, + [GCC_PCIE_PHY_BCR] = { 0x6f000 }, + [GCC_DCD_BCR] = { 0x70000 }, + [GCC_OBT_ODT_BCR] = { 0x73000 }, + [GCC_UFS_BCR] = { 0x75000 }, + [GCC_SSC_BCR] = { 0x63000 }, + [GCC_VS_BCR] = { 0x7a000 }, + [GCC_AGGRE0_NOC_BCR] = { 0x81000 }, + [GCC_AGGRE1_NOC_BCR] = { 0x82000 }, + [GCC_AGGRE2_NOC_BCR] = { 0x83000 }, + [GCC_DCC_BCR] = { 0x84000 }, + [GCC_IPA_BCR] = { 0x89000 }, + [GCC_QSPI_BCR] = { 0x8b000 }, + [GCC_SKL_BCR] = { 0x8c000 }, + [GCC_MSMPU_BCR] = { 0x8d000 }, + [GCC_MSS_Q6_BCR] = { 0x8e000 }, + [GCC_QREFS_VBG_CAL_BCR] = { 0x88020 }, +}; + +static const struct regmap_config gcc_msm8996_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x8f010, + .fast_io = true, +}; + +static const struct qcom_cc_desc gcc_msm8996_desc = { + .config = &gcc_msm8996_regmap_config, + .clks = gcc_msm8996_clocks, + .num_clks = ARRAY_SIZE(gcc_msm8996_clocks), + .resets = gcc_msm8996_resets, + .num_resets = ARRAY_SIZE(gcc_msm8996_resets), +}; + +static const struct of_device_id gcc_msm8996_match_table[] = { + { .compatible = "qcom,gcc-msm8996" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_msm8996_match_table); + +static int gcc_msm8996_probe(struct platform_device *pdev) +{ + struct clk *clk; + struct device *dev = &pdev->dev; + int i; + struct regmap *regmap; + + regmap = qcom_cc_map(pdev, &gcc_msm8996_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + /* + * Set the HMSS_AHB_CLK_SLEEP_ENA bit to allow the hmss_ahb_clk to be + * turned off by hardware during certain apps low power modes. + */ + regmap_update_bits(regmap, 0x52008, BIT(21), BIT(21)); + + for (i = 0; i < ARRAY_SIZE(gcc_msm8996_hws); i++) { + clk = devm_clk_register(dev, gcc_msm8996_hws[i]); + if (IS_ERR(clk)) + return PTR_ERR(clk); + } + + return qcom_cc_really_probe(pdev, &gcc_msm8996_desc, regmap); +} + +static struct platform_driver gcc_msm8996_driver = { + .probe = gcc_msm8996_probe, + .driver = { + .name = "gcc-msm8996", + .of_match_table = gcc_msm8996_match_table, + }, +}; + +static int __init gcc_msm8996_init(void) +{ + return platform_driver_register(&gcc_msm8996_driver); +} +core_initcall(gcc_msm8996_init); + +static void __exit gcc_msm8996_exit(void) +{ + platform_driver_unregister(&gcc_msm8996_driver); +} +module_exit(gcc_msm8996_exit); + +MODULE_DESCRIPTION("QCOM GCC MSM8996 Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:gcc-msm8996"); diff --git a/drivers/clk/qcom/lcc-ipq806x.c b/drivers/clk/qcom/lcc-ipq806x.c index db3998e5e2d8..62e79fadd5f7 100644 --- a/drivers/clk/qcom/lcc-ipq806x.c +++ b/drivers/clk/qcom/lcc-ipq806x.c @@ -419,6 +419,7 @@ static const struct regmap_config lcc_ipq806x_regmap_config = { .val_bits = 32, .max_register = 0xfc, .fast_io = true, + .val_format_endian = REGMAP_ENDIAN_LITTLE, }; static const struct qcom_cc_desc lcc_ipq806x_desc = { diff --git a/drivers/clk/qcom/lcc-msm8960.c b/drivers/clk/qcom/lcc-msm8960.c index 4fcf9d1d233c..bf95bb0ea1b8 100644 --- a/drivers/clk/qcom/lcc-msm8960.c +++ b/drivers/clk/qcom/lcc-msm8960.c @@ -524,6 +524,7 @@ static const struct regmap_config lcc_msm8960_regmap_config = { .val_bits = 32, .max_register = 0xfc, .fast_io = true, + .val_format_endian = REGMAP_ENDIAN_LITTLE, }; static const struct qcom_cc_desc lcc_msm8960_desc = { diff --git a/drivers/clk/qcom/mmcc-apq8084.c b/drivers/clk/qcom/mmcc-apq8084.c index 30777f9f1a43..1e703fda8a0f 100644 --- a/drivers/clk/qcom/mmcc-apq8084.c +++ b/drivers/clk/qcom/mmcc-apq8084.c @@ -3368,6 +3368,7 @@ static const struct regmap_config mmcc_apq8084_regmap_config = { .val_bits = 32, .max_register = 0x5104, .fast_io = true, + .val_format_endian = REGMAP_ENDIAN_LITTLE, }; static const struct qcom_cc_desc mmcc_apq8084_desc = { diff --git a/drivers/clk/qcom/mmcc-msm8960.c b/drivers/clk/qcom/mmcc-msm8960.c index 00e36192a1de..d73a048d3b9d 100644 --- a/drivers/clk/qcom/mmcc-msm8960.c +++ b/drivers/clk/qcom/mmcc-msm8960.c @@ -3029,6 +3029,7 @@ static const struct regmap_config mmcc_msm8960_regmap_config = { .val_bits = 32, .max_register = 0x334, .fast_io = true, + .val_format_endian = REGMAP_ENDIAN_LITTLE, }; static const struct regmap_config mmcc_apq8064_regmap_config = { @@ -3037,6 +3038,7 @@ static const struct regmap_config mmcc_apq8064_regmap_config = { .val_bits = 32, .max_register = 0x350, .fast_io = true, + .val_format_endian = REGMAP_ENDIAN_LITTLE, }; static const struct qcom_cc_desc mmcc_msm8960_desc = { diff --git a/drivers/clk/qcom/mmcc-msm8974.c b/drivers/clk/qcom/mmcc-msm8974.c index 9d790bcadf25..bbe28ed93669 100644 --- a/drivers/clk/qcom/mmcc-msm8974.c +++ b/drivers/clk/qcom/mmcc-msm8974.c @@ -2594,6 +2594,7 @@ static const struct regmap_config mmcc_msm8974_regmap_config = { .val_bits = 32, .max_register = 0x5104, .fast_io = true, + .val_format_endian = REGMAP_ENDIAN_LITTLE, }; static const struct qcom_cc_desc mmcc_msm8974_desc = { diff --git a/drivers/clk/qcom/mmcc-msm8996.c b/drivers/clk/qcom/mmcc-msm8996.c new file mode 100644 index 000000000000..064f3eaa39d0 --- /dev/null +++ b/drivers/clk/qcom/mmcc-msm8996.c @@ -0,0 +1,3217 @@ +/*x + * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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/kernel.h> +#include <linux/bitops.h> +#include <linux/err.h> +#include <linux/platform_device.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/clk-provider.h> +#include <linux/regmap.h> +#include <linux/reset-controller.h> +#include <linux/clk.h> + +#include <dt-bindings/clock/qcom,mmcc-msm8996.h> + +#include "common.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-alpha-pll.h" +#include "clk-rcg.h" +#include "clk-branch.h" +#include "reset.h" + +#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } + +enum { + P_XO, + P_MMPLL0, + P_GPLL0, + P_GPLL0_DIV, + P_MMPLL1, + P_MMPLL9, + P_MMPLL2, + P_MMPLL8, + P_MMPLL3, + P_DSI0PLL, + P_DSI1PLL, + P_MMPLL5, + P_HDMIPLL, + P_DSI0PLL_BYTE, + P_DSI1PLL_BYTE, + P_MMPLL4, +}; + +static const struct parent_map mmss_xo_hdmi_map[] = { + { P_XO, 0 }, + { P_HDMIPLL, 1 } +}; + +static const char * const mmss_xo_hdmi[] = { + "xo", + "hdmipll" +}; + +static const struct parent_map mmss_xo_dsi0pll_dsi1pll_map[] = { + { P_XO, 0 }, + { P_DSI0PLL, 1 }, + { P_DSI1PLL, 2 } +}; + +static const char * const mmss_xo_dsi0pll_dsi1pll[] = { + "xo", + "dsi0pll", + "dsi1pll" +}; + +static const struct parent_map mmss_xo_gpll0_gpll0_div_map[] = { + { P_XO, 0 }, + { P_GPLL0, 5 }, + { P_GPLL0_DIV, 6 } +}; + +static const char * const mmss_xo_gpll0_gpll0_div[] = { + "xo", + "gpll0", + "gpll0_div" +}; + +static const struct parent_map mmss_xo_dsibyte_map[] = { + { P_XO, 0 }, + { P_DSI0PLL_BYTE, 1 }, + { P_DSI1PLL_BYTE, 2 } +}; + +static const char * const mmss_xo_dsibyte[] = { + "xo", + "dsi0pllbyte", + "dsi1pllbyte" +}; + +static const struct parent_map mmss_xo_mmpll0_gpll0_gpll0_div_map[] = { + { P_XO, 0 }, + { P_MMPLL0, 1 }, + { P_GPLL0, 5 }, + { P_GPLL0_DIV, 6 } +}; + +static const char * const mmss_xo_mmpll0_gpll0_gpll0_div[] = { + "xo", + "mmpll0", + "gpll0", + "gpll0_div" +}; + +static const struct parent_map mmss_xo_mmpll0_mmpll1_gpll0_gpll0_div_map[] = { + { P_XO, 0 }, + { P_MMPLL0, 1 }, + { P_MMPLL1, 2 }, + { P_GPLL0, 5 }, + { P_GPLL0_DIV, 6 } +}; + +static const char * const mmss_xo_mmpll0_mmpll1_gpll0_gpll0_div[] = { + "xo", + "mmpll0", + "mmpll1", + "gpll0", + "gpll0_div" +}; + +static const struct parent_map mmss_xo_mmpll0_mmpll3_gpll0_gpll0_div_map[] = { + { P_XO, 0 }, + { P_MMPLL0, 1 }, + { P_MMPLL3, 3 }, + { P_GPLL0, 5 }, + { P_GPLL0_DIV, 6 } +}; + +static const char * const mmss_xo_mmpll0_mmpll3_gpll0_gpll0_div[] = { + "xo", + "mmpll0", + "mmpll3", + "gpll0", + "gpll0_div" +}; + +static const struct parent_map mmss_xo_mmpll0_mmpll5_gpll0_gpll0_div_map[] = { + { P_XO, 0 }, + { P_MMPLL0, 1 }, + { P_MMPLL5, 2 }, + { P_GPLL0, 5 }, + { P_GPLL0_DIV, 6 } +}; + +static const char * const mmss_xo_mmpll0_mmpll5_gpll0_gpll0_div[] = { + "xo", + "mmpll0", + "mmpll5", + "gpll0", + "gpll0_div" +}; + +static const struct parent_map mmss_xo_mmpll0_mmpll4_gpll0_gpll0_div_map[] = { + { P_XO, 0 }, + { P_MMPLL0, 1 }, + { P_MMPLL4, 3 }, + { P_GPLL0, 5 }, + { P_GPLL0_DIV, 6 } +}; + +static const char * const mmss_xo_mmpll0_mmpll4_gpll0_gpll0_div[] = { + "xo", + "mmpll0", + "mmpll4", + "gpll0", + "gpll0_div" +}; + +static const struct parent_map mmss_xo_mmpll0_mmpll9_mmpll2_mmpll8_gpll0_map[] = { + { P_XO, 0 }, + { P_MMPLL0, 1 }, + { P_MMPLL9, 2 }, + { P_MMPLL2, 3 }, + { P_MMPLL8, 4 }, + { P_GPLL0, 5 } +}; + +static const char * const mmss_xo_mmpll0_mmpll9_mmpll2_mmpll8_gpll0[] = { + "xo", + "mmpll0", + "mmpll9", + "mmpll2", + "mmpll8", + "gpll0" +}; + +static const struct parent_map mmss_xo_mmpll0_mmpll9_mmpll2_mmpll8_gpll0_gpll0_div_map[] = { + { P_XO, 0 }, + { P_MMPLL0, 1 }, + { P_MMPLL9, 2 }, + { P_MMPLL2, 3 }, + { P_MMPLL8, 4 }, + { P_GPLL0, 5 }, + { P_GPLL0_DIV, 6 } +}; + +static const char * const mmss_xo_mmpll0_mmpll9_mmpll2_mmpll8_gpll0_gpll0_div[] = { + "xo", + "mmpll0", + "mmpll9", + "mmpll2", + "mmpll8", + "gpll0", + "gpll0_div" +}; + +static const struct parent_map mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div_map[] = { + { P_XO, 0 }, + { P_MMPLL0, 1 }, + { P_MMPLL1, 2 }, + { P_MMPLL4, 3 }, + { P_MMPLL3, 4 }, + { P_GPLL0, 5 }, + { P_GPLL0_DIV, 6 } +}; + +static const char * const mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div[] = { + "xo", + "mmpll0", + "mmpll1", + "mmpll4", + "mmpll3", + "gpll0", + "gpll0_div" +}; + +static struct clk_fixed_factor gpll0_div = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "gpll0_div", + .parent_names = (const char *[]){ "gpll0" }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct pll_vco mmpll_p_vco[] = { + { 250000000, 500000000, 3 }, + { 500000000, 1000000000, 2 }, + { 1000000000, 1500000000, 1 }, + { 1500000000, 2000000000, 0 }, +}; + +static struct pll_vco mmpll_gfx_vco[] = { + { 400000000, 1000000000, 2 }, + { 1000000000, 1500000000, 1 }, + { 1500000000, 2000000000, 0 }, +}; + +static struct pll_vco mmpll_t_vco[] = { + { 500000000, 1500000000, 0 }, +}; + +static struct clk_alpha_pll mmpll0_early = { + .offset = 0x0, + .vco_table = mmpll_p_vco, + .num_vco = ARRAY_SIZE(mmpll_p_vco), + .clkr = { + .enable_reg = 0x100, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmpll0_early", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv mmpll0 = { + .offset = 0x0, + .width = 4, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll0", + .parent_names = (const char *[]){ "mmpll0_early" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_alpha_pll mmpll1_early = { + .offset = 0x30, + .vco_table = mmpll_p_vco, + .num_vco = ARRAY_SIZE(mmpll_p_vco), + .clkr = { + .enable_reg = 0x100, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "mmpll1_early", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + } + }, +}; + +static struct clk_alpha_pll_postdiv mmpll1 = { + .offset = 0x30, + .width = 4, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll1", + .parent_names = (const char *[]){ "mmpll1_early" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_alpha_pll mmpll2_early = { + .offset = 0x4100, + .vco_table = mmpll_gfx_vco, + .num_vco = ARRAY_SIZE(mmpll_gfx_vco), + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll2_early", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, +}; + +static struct clk_alpha_pll_postdiv mmpll2 = { + .offset = 0x4100, + .width = 4, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll2", + .parent_names = (const char *[]){ "mmpll2_early" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_alpha_pll mmpll3_early = { + .offset = 0x60, + .vco_table = mmpll_p_vco, + .num_vco = ARRAY_SIZE(mmpll_p_vco), + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll3_early", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, +}; + +static struct clk_alpha_pll_postdiv mmpll3 = { + .offset = 0x60, + .width = 4, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll3", + .parent_names = (const char *[]){ "mmpll3_early" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_alpha_pll mmpll4_early = { + .offset = 0x90, + .vco_table = mmpll_t_vco, + .num_vco = ARRAY_SIZE(mmpll_t_vco), + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll4_early", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, +}; + +static struct clk_alpha_pll_postdiv mmpll4 = { + .offset = 0x90, + .width = 2, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll4", + .parent_names = (const char *[]){ "mmpll4_early" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_alpha_pll mmpll5_early = { + .offset = 0xc0, + .vco_table = mmpll_p_vco, + .num_vco = ARRAY_SIZE(mmpll_p_vco), + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll5_early", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, +}; + +static struct clk_alpha_pll_postdiv mmpll5 = { + .offset = 0xc0, + .width = 4, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll5", + .parent_names = (const char *[]){ "mmpll5_early" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_alpha_pll mmpll8_early = { + .offset = 0x4130, + .vco_table = mmpll_gfx_vco, + .num_vco = ARRAY_SIZE(mmpll_gfx_vco), + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll8_early", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, +}; + +static struct clk_alpha_pll_postdiv mmpll8 = { + .offset = 0x4130, + .width = 4, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll8", + .parent_names = (const char *[]){ "mmpll8_early" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_alpha_pll mmpll9_early = { + .offset = 0x4200, + .vco_table = mmpll_t_vco, + .num_vco = ARRAY_SIZE(mmpll_t_vco), + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll9_early", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, +}; + +static struct clk_alpha_pll_postdiv mmpll9 = { + .offset = 0x4200, + .width = 2, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll9", + .parent_names = (const char *[]){ "mmpll9_early" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct freq_tbl ftbl_ahb_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(40000000, P_GPLL0_DIV, 7.5, 0, 0), + F(80000000, P_MMPLL0, 10, 0, 0), + { } +}; + +static struct clk_rcg2 ahb_clk_src = { + .cmd_rcgr = 0x5000, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_gpll0_gpll0_div_map, + .freq_tbl = ftbl_ahb_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "ahb_clk_src", + .parent_names = mmss_xo_mmpll0_gpll0_gpll0_div, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_axi_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(75000000, P_GPLL0_DIV, 4, 0, 0), + F(100000000, P_GPLL0, 6, 0, 0), + F(171430000, P_GPLL0, 3.5, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + F(320000000, P_MMPLL0, 2.5, 0, 0), + F(400000000, P_MMPLL0, 2, 0, 0), + { } +}; + +static struct clk_rcg2 axi_clk_src = { + .cmd_rcgr = 0x5040, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll1_gpll0_gpll0_div_map, + .freq_tbl = ftbl_axi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "axi_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll1_gpll0_gpll0_div, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 maxi_clk_src = { + .cmd_rcgr = 0x5090, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll1_gpll0_gpll0_div_map, + .freq_tbl = ftbl_axi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "maxi_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll1_gpll0_gpll0_div, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gfx3d_clk_src = { + .cmd_rcgr = 0x4000, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll9_mmpll2_mmpll8_gpll0_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gfx3d_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll9_mmpll2_mmpll8_gpll0, + .num_parents = 6, + .ops = &clk_gfx3d_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct freq_tbl ftbl_rbbmtimer_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 rbbmtimer_clk_src = { + .cmd_rcgr = 0x4090, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_gpll0_gpll0_div_map, + .freq_tbl = ftbl_rbbmtimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "rbbmtimer_clk_src", + .parent_names = mmss_xo_mmpll0_gpll0_gpll0_div, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 isense_clk_src = { + .cmd_rcgr = 0x4010, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll9_mmpll2_mmpll8_gpll0_gpll0_div_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "isense_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll9_mmpll2_mmpll8_gpll0_gpll0_div, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_rbcpr_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0, 12, 0, 0), + { } +}; + +static struct clk_rcg2 rbcpr_clk_src = { + .cmd_rcgr = 0x4060, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_gpll0_gpll0_div_map, + .freq_tbl = ftbl_rbcpr_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "rbcpr_clk_src", + .parent_names = mmss_xo_mmpll0_gpll0_gpll0_div, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_video_core_clk_src[] = { + F(75000000, P_GPLL0_DIV, 4, 0, 0), + F(150000000, P_GPLL0, 4, 0, 0), + F(346666667, P_MMPLL3, 3, 0, 0), + F(520000000, P_MMPLL3, 2, 0, 0), + { } +}; + +static struct clk_rcg2 video_core_clk_src = { + .cmd_rcgr = 0x1000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll3_gpll0_gpll0_div_map, + .freq_tbl = ftbl_video_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "video_core_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll3_gpll0_gpll0_div, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 video_subcore0_clk_src = { + .cmd_rcgr = 0x1060, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll3_gpll0_gpll0_div_map, + .freq_tbl = ftbl_video_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "video_subcore0_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll3_gpll0_gpll0_div, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 video_subcore1_clk_src = { + .cmd_rcgr = 0x1080, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll3_gpll0_gpll0_div_map, + .freq_tbl = ftbl_video_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "video_subcore1_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll3_gpll0_gpll0_div, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 pclk0_clk_src = { + .cmd_rcgr = 0x2000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmss_xo_dsi0pll_dsi1pll_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pclk0_clk_src", + .parent_names = mmss_xo_dsi0pll_dsi1pll, + .num_parents = 3, + .ops = &clk_pixel_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_rcg2 pclk1_clk_src = { + .cmd_rcgr = 0x2020, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmss_xo_dsi0pll_dsi1pll_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pclk1_clk_src", + .parent_names = mmss_xo_dsi0pll_dsi1pll, + .num_parents = 3, + .ops = &clk_pixel_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct freq_tbl ftbl_mdp_clk_src[] = { + F(85714286, P_GPLL0, 7, 0, 0), + F(100000000, P_GPLL0, 6, 0, 0), + F(150000000, P_GPLL0, 4, 0, 0), + F(171428571, P_GPLL0, 3.5, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + F(275000000, P_MMPLL5, 3, 0, 0), + F(300000000, P_GPLL0, 2, 0, 0), + F(330000000, P_MMPLL5, 2.5, 0, 0), + F(412500000, P_MMPLL5, 2, 0, 0), + { } +}; + +static struct clk_rcg2 mdp_clk_src = { + .cmd_rcgr = 0x2040, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll5_gpll0_gpll0_div_map, + .freq_tbl = ftbl_mdp_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mdp_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll5_gpll0_gpll0_div, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct freq_tbl extpclk_freq_tbl[] = { + { .src = P_HDMIPLL }, + { } +}; + +static struct clk_rcg2 extpclk_clk_src = { + .cmd_rcgr = 0x2060, + .hid_width = 5, + .parent_map = mmss_xo_hdmi_map, + .freq_tbl = extpclk_freq_tbl, + .clkr.hw.init = &(struct clk_init_data){ + .name = "extpclk_clk_src", + .parent_names = mmss_xo_hdmi, + .num_parents = 2, + .ops = &clk_byte_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct freq_tbl ftbl_mdss_vsync_clk[] = { + F(19200000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 vsync_clk_src = { + .cmd_rcgr = 0x2080, + .hid_width = 5, + .parent_map = mmss_xo_gpll0_gpll0_div_map, + .freq_tbl = ftbl_mdss_vsync_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "vsync_clk_src", + .parent_names = mmss_xo_gpll0_gpll0_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct freq_tbl ftbl_mdss_hdmi_clk[] = { + F(19200000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 hdmi_clk_src = { + .cmd_rcgr = 0x2100, + .hid_width = 5, + .parent_map = mmss_xo_gpll0_gpll0_div_map, + .freq_tbl = ftbl_mdss_hdmi_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "hdmi_clk_src", + .parent_names = mmss_xo_gpll0_gpll0_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 byte0_clk_src = { + .cmd_rcgr = 0x2120, + .hid_width = 5, + .parent_map = mmss_xo_dsibyte_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "byte0_clk_src", + .parent_names = mmss_xo_dsibyte, + .num_parents = 3, + .ops = &clk_byte2_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_rcg2 byte1_clk_src = { + .cmd_rcgr = 0x2140, + .hid_width = 5, + .parent_map = mmss_xo_dsibyte_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "byte1_clk_src", + .parent_names = mmss_xo_dsibyte, + .num_parents = 3, + .ops = &clk_byte2_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct freq_tbl ftbl_mdss_esc0_1_clk[] = { + F(19200000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 esc0_clk_src = { + .cmd_rcgr = 0x2160, + .hid_width = 5, + .parent_map = mmss_xo_dsibyte_map, + .freq_tbl = ftbl_mdss_esc0_1_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "esc0_clk_src", + .parent_names = mmss_xo_dsibyte, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 esc1_clk_src = { + .cmd_rcgr = 0x2180, + .hid_width = 5, + .parent_map = mmss_xo_dsibyte_map, + .freq_tbl = ftbl_mdss_esc0_1_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "esc1_clk_src", + .parent_names = mmss_xo_dsibyte, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_camss_gp0_clk_src[] = { + F(10000, P_XO, 16, 1, 120), + F(24000, P_XO, 16, 1, 50), + F(6000000, P_GPLL0_DIV, 10, 1, 5), + F(12000000, P_GPLL0_DIV, 1, 1, 25), + F(13000000, P_GPLL0_DIV, 2, 13, 150), + F(24000000, P_GPLL0_DIV, 1, 2, 25), + { } +}; + +static struct clk_rcg2 camss_gp0_clk_src = { + .cmd_rcgr = 0x3420, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll4_gpll0_gpll0_div_map, + .freq_tbl = ftbl_camss_gp0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "camss_gp0_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll4_gpll0_gpll0_div, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 camss_gp1_clk_src = { + .cmd_rcgr = 0x3450, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll4_gpll0_gpll0_div_map, + .freq_tbl = ftbl_camss_gp0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "camss_gp1_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll4_gpll0_gpll0_div, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_mclk0_clk_src[] = { + F(4800000, P_XO, 4, 0, 0), + F(6000000, P_GPLL0_DIV, 10, 1, 5), + F(8000000, P_GPLL0_DIV, 1, 2, 75), + F(9600000, P_XO, 2, 0, 0), + F(16666667, P_GPLL0_DIV, 2, 1, 9), + F(19200000, P_XO, 1, 0, 0), + F(24000000, P_GPLL0_DIV, 1, 2, 25), + F(33333333, P_GPLL0_DIV, 1, 1, 9), + F(48000000, P_GPLL0, 1, 2, 25), + F(66666667, P_GPLL0, 1, 1, 9), + { } +}; + +static struct clk_rcg2 mclk0_clk_src = { + .cmd_rcgr = 0x3360, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll4_gpll0_gpll0_div_map, + .freq_tbl = ftbl_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mclk0_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll4_gpll0_gpll0_div, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 mclk1_clk_src = { + .cmd_rcgr = 0x3390, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll4_gpll0_gpll0_div_map, + .freq_tbl = ftbl_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mclk1_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll4_gpll0_gpll0_div, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 mclk2_clk_src = { + .cmd_rcgr = 0x33c0, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll4_gpll0_gpll0_div_map, + .freq_tbl = ftbl_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mclk2_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll4_gpll0_gpll0_div, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 mclk3_clk_src = { + .cmd_rcgr = 0x33f0, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll4_gpll0_gpll0_div_map, + .freq_tbl = ftbl_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mclk3_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll4_gpll0_gpll0_div, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cci_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(37500000, P_GPLL0, 16, 0, 0), + F(50000000, P_GPLL0, 12, 0, 0), + F(100000000, P_GPLL0, 6, 0, 0), + { } +}; + +static struct clk_rcg2 cci_clk_src = { + .cmd_rcgr = 0x3300, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll4_gpll0_gpll0_div_map, + .freq_tbl = ftbl_cci_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cci_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll4_gpll0_gpll0_div, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_csi0phytimer_clk_src[] = { + F(100000000, P_GPLL0_DIV, 3, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + F(266666667, P_MMPLL0, 3, 0, 0), + { } +}; + +static struct clk_rcg2 csi0phytimer_clk_src = { + .cmd_rcgr = 0x3000, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div_map, + .freq_tbl = ftbl_csi0phytimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi0phytimer_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 csi1phytimer_clk_src = { + .cmd_rcgr = 0x3030, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div_map, + .freq_tbl = ftbl_csi0phytimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi1phytimer_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 csi2phytimer_clk_src = { + .cmd_rcgr = 0x3060, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div_map, + .freq_tbl = ftbl_csi0phytimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi2phytimer_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_csiphy0_3p_clk_src[] = { + F(100000000, P_GPLL0_DIV, 3, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + F(320000000, P_MMPLL4, 3, 0, 0), + F(384000000, P_MMPLL4, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 csiphy0_3p_clk_src = { + .cmd_rcgr = 0x3240, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div_map, + .freq_tbl = ftbl_csiphy0_3p_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csiphy0_3p_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 csiphy1_3p_clk_src = { + .cmd_rcgr = 0x3260, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div_map, + .freq_tbl = ftbl_csiphy0_3p_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csiphy1_3p_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 csiphy2_3p_clk_src = { + .cmd_rcgr = 0x3280, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div_map, + .freq_tbl = ftbl_csiphy0_3p_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csiphy2_3p_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_jpeg0_clk_src[] = { + F(75000000, P_GPLL0_DIV, 4, 0, 0), + F(150000000, P_GPLL0, 4, 0, 0), + F(228571429, P_MMPLL0, 3.5, 0, 0), + F(266666667, P_MMPLL0, 3, 0, 0), + F(320000000, P_MMPLL0, 2.5, 0, 0), + F(480000000, P_MMPLL4, 2, 0, 0), + { } +}; + +static struct clk_rcg2 jpeg0_clk_src = { + .cmd_rcgr = 0x3500, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div_map, + .freq_tbl = ftbl_jpeg0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "jpeg0_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_jpeg2_clk_src[] = { + F(75000000, P_GPLL0_DIV, 4, 0, 0), + F(150000000, P_GPLL0, 4, 0, 0), + F(228571429, P_MMPLL0, 3.5, 0, 0), + F(266666667, P_MMPLL0, 3, 0, 0), + F(320000000, P_MMPLL0, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 jpeg2_clk_src = { + .cmd_rcgr = 0x3540, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div_map, + .freq_tbl = ftbl_jpeg2_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "jpeg2_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 jpeg_dma_clk_src = { + .cmd_rcgr = 0x3560, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div_map, + .freq_tbl = ftbl_jpeg0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "jpeg_dma_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_vfe0_clk_src[] = { + F(75000000, P_GPLL0_DIV, 4, 0, 0), + F(100000000, P_GPLL0_DIV, 3, 0, 0), + F(300000000, P_GPLL0, 2, 0, 0), + F(320000000, P_MMPLL0, 2.5, 0, 0), + F(480000000, P_MMPLL4, 2, 0, 0), + F(600000000, P_GPLL0, 1, 0, 0), + { } +}; + +static struct clk_rcg2 vfe0_clk_src = { + .cmd_rcgr = 0x3600, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div_map, + .freq_tbl = ftbl_vfe0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "vfe0_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 vfe1_clk_src = { + .cmd_rcgr = 0x3620, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div_map, + .freq_tbl = ftbl_vfe0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "vfe1_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cpp_clk_src[] = { + F(100000000, P_GPLL0_DIV, 3, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + F(320000000, P_MMPLL0, 2.5, 0, 0), + F(480000000, P_MMPLL4, 2, 0, 0), + F(640000000, P_MMPLL4, 1.5, 0, 0), + { } +}; + +static struct clk_rcg2 cpp_clk_src = { + .cmd_rcgr = 0x3640, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div_map, + .freq_tbl = ftbl_cpp_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cpp_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_csi0_clk_src[] = { + F(100000000, P_GPLL0_DIV, 3, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + F(266666667, P_MMPLL0, 3, 0, 0), + F(480000000, P_MMPLL4, 2, 0, 0), + F(600000000, P_GPLL0, 1, 0, 0), + { } +}; + +static struct clk_rcg2 csi0_clk_src = { + .cmd_rcgr = 0x3090, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div_map, + .freq_tbl = ftbl_csi0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi0_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 csi1_clk_src = { + .cmd_rcgr = 0x3100, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div_map, + .freq_tbl = ftbl_csi0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi1_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 csi2_clk_src = { + .cmd_rcgr = 0x3160, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div_map, + .freq_tbl = ftbl_csi0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi2_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 csi3_clk_src = { + .cmd_rcgr = 0x31c0, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div_map, + .freq_tbl = ftbl_csi0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi3_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll1_mmpll4_mmpll3_gpll0_gpll0_div, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_fd_core_clk_src[] = { + F(100000000, P_GPLL0_DIV, 3, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + F(400000000, P_MMPLL0, 2, 0, 0), + { } +}; + +static struct clk_rcg2 fd_core_clk_src = { + .cmd_rcgr = 0x3b00, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll4_gpll0_gpll0_div_map, + .freq_tbl = ftbl_fd_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "fd_core_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll4_gpll0_gpll0_div, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch mmss_mmagic_ahb_clk = { + .halt_reg = 0x5024, + .clkr = { + .enable_reg = 0x5024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mmagic_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_mmagic_cfg_ahb_clk = { + .halt_reg = 0x5054, + .clkr = { + .enable_reg = 0x5054, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mmagic_cfg_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_misc_ahb_clk = { + .halt_reg = 0x5018, + .clkr = { + .enable_reg = 0x5018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_misc_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_misc_cxo_clk = { + .halt_reg = 0x5014, + .clkr = { + .enable_reg = 0x5014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_misc_cxo_clk", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_mmagic_axi_clk = { + .halt_reg = 0x506c, + .clkr = { + .enable_reg = 0x506c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mmagic_axi_clk", + .parent_names = (const char *[]){ "axi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_mmagic_maxi_clk = { + .halt_reg = 0x5074, + .clkr = { + .enable_reg = 0x5074, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mmagic_maxi_clk", + .parent_names = (const char *[]){ "maxi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmagic_camss_axi_clk = { + .halt_reg = 0x3c44, + .clkr = { + .enable_reg = 0x3c44, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmagic_camss_axi_clk", + .parent_names = (const char *[]){ "axi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmagic_camss_noc_cfg_ahb_clk = { + .halt_reg = 0x3c48, + .clkr = { + .enable_reg = 0x3c48, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmagic_camss_noc_cfg_ahb_clk", + .parent_names = (const char *[]){ "gcc_mmss_noc_cfg_ahb_clk" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch smmu_vfe_ahb_clk = { + .halt_reg = 0x3c04, + .clkr = { + .enable_reg = 0x3c04, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "smmu_vfe_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch smmu_vfe_axi_clk = { + .halt_reg = 0x3c08, + .clkr = { + .enable_reg = 0x3c08, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "smmu_vfe_axi_clk", + .parent_names = (const char *[]){ "axi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch smmu_cpp_ahb_clk = { + .halt_reg = 0x3c14, + .clkr = { + .enable_reg = 0x3c14, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "smmu_cpp_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch smmu_cpp_axi_clk = { + .halt_reg = 0x3c18, + .clkr = { + .enable_reg = 0x3c18, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "smmu_cpp_axi_clk", + .parent_names = (const char *[]){ "axi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch smmu_jpeg_ahb_clk = { + .halt_reg = 0x3c24, + .clkr = { + .enable_reg = 0x3c24, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "smmu_jpeg_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch smmu_jpeg_axi_clk = { + .halt_reg = 0x3c28, + .clkr = { + .enable_reg = 0x3c28, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "smmu_jpeg_axi_clk", + .parent_names = (const char *[]){ "axi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmagic_mdss_axi_clk = { + .halt_reg = 0x2474, + .clkr = { + .enable_reg = 0x2474, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmagic_mdss_axi_clk", + .parent_names = (const char *[]){ "axi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmagic_mdss_noc_cfg_ahb_clk = { + .halt_reg = 0x2478, + .clkr = { + .enable_reg = 0x2478, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmagic_mdss_noc_cfg_ahb_clk", + .parent_names = (const char *[]){ "gcc_mmss_noc_cfg_ahb_clk" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch smmu_rot_ahb_clk = { + .halt_reg = 0x2444, + .clkr = { + .enable_reg = 0x2444, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "smmu_rot_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch smmu_rot_axi_clk = { + .halt_reg = 0x2448, + .clkr = { + .enable_reg = 0x2448, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "smmu_rot_axi_clk", + .parent_names = (const char *[]){ "axi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch smmu_mdp_ahb_clk = { + .halt_reg = 0x2454, + .clkr = { + .enable_reg = 0x2454, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "smmu_mdp_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch smmu_mdp_axi_clk = { + .halt_reg = 0x2458, + .clkr = { + .enable_reg = 0x2458, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "smmu_mdp_axi_clk", + .parent_names = (const char *[]){ "axi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmagic_video_axi_clk = { + .halt_reg = 0x1194, + .clkr = { + .enable_reg = 0x1194, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmagic_video_axi_clk", + .parent_names = (const char *[]){ "axi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmagic_video_noc_cfg_ahb_clk = { + .halt_reg = 0x1198, + .clkr = { + .enable_reg = 0x1198, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmagic_video_noc_cfg_ahb_clk", + .parent_names = (const char *[]){ "gcc_mmss_noc_cfg_ahb_clk" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch smmu_video_ahb_clk = { + .halt_reg = 0x1174, + .clkr = { + .enable_reg = 0x1174, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "smmu_video_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch smmu_video_axi_clk = { + .halt_reg = 0x1178, + .clkr = { + .enable_reg = 0x1178, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "smmu_video_axi_clk", + .parent_names = (const char *[]){ "axi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmagic_bimc_axi_clk = { + .halt_reg = 0x5294, + .clkr = { + .enable_reg = 0x5294, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmagic_bimc_axi_clk", + .parent_names = (const char *[]){ "axi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmagic_bimc_noc_cfg_ahb_clk = { + .halt_reg = 0x5298, + .clkr = { + .enable_reg = 0x5298, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmagic_bimc_noc_cfg_ahb_clk", + .parent_names = (const char *[]){ "gcc_mmss_noc_cfg_ahb_clk" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_gx_gfx3d_clk = { + .halt_reg = 0x4028, + .clkr = { + .enable_reg = 0x4028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_gx_gfx3d_clk", + .parent_names = (const char *[]){ "gfx3d_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_gx_rbbmtimer_clk = { + .halt_reg = 0x40b0, + .clkr = { + .enable_reg = 0x40b0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_gx_rbbmtimer_clk", + .parent_names = (const char *[]){ "rbbmtimer_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_ahb_clk = { + .halt_reg = 0x403c, + .clkr = { + .enable_reg = 0x403c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_aon_isense_clk = { + .halt_reg = 0x4044, + .clkr = { + .enable_reg = 0x4044, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_aon_isense_clk", + .parent_names = (const char *[]){ "isense_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch vmem_maxi_clk = { + .halt_reg = 0x1204, + .clkr = { + .enable_reg = 0x1204, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "vmem_maxi_clk", + .parent_names = (const char *[]){ "maxi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch vmem_ahb_clk = { + .halt_reg = 0x1208, + .clkr = { + .enable_reg = 0x1208, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "vmem_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_rbcpr_clk = { + .halt_reg = 0x4084, + .clkr = { + .enable_reg = 0x4084, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_rbcpr_clk", + .parent_names = (const char *[]){ "rbcpr_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_rbcpr_ahb_clk = { + .halt_reg = 0x4088, + .clkr = { + .enable_reg = 0x4088, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_rbcpr_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_core_clk = { + .halt_reg = 0x1028, + .clkr = { + .enable_reg = 0x1028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "video_core_clk", + .parent_names = (const char *[]){ "video_core_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_axi_clk = { + .halt_reg = 0x1034, + .clkr = { + .enable_reg = 0x1034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "video_axi_clk", + .parent_names = (const char *[]){ "axi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_maxi_clk = { + .halt_reg = 0x1038, + .clkr = { + .enable_reg = 0x1038, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "video_maxi_clk", + .parent_names = (const char *[]){ "maxi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_ahb_clk = { + .halt_reg = 0x1030, + .clkr = { + .enable_reg = 0x1030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "video_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_subcore0_clk = { + .halt_reg = 0x1048, + .clkr = { + .enable_reg = 0x1048, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "video_subcore0_clk", + .parent_names = (const char *[]){ "video_subcore0_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_subcore1_clk = { + .halt_reg = 0x104c, + .clkr = { + .enable_reg = 0x104c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "video_subcore1_clk", + .parent_names = (const char *[]){ "video_subcore1_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_ahb_clk = { + .halt_reg = 0x2308, + .clkr = { + .enable_reg = 0x2308, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_hdmi_ahb_clk = { + .halt_reg = 0x230c, + .clkr = { + .enable_reg = 0x230c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_hdmi_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_axi_clk = { + .halt_reg = 0x2310, + .clkr = { + .enable_reg = 0x2310, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_axi_clk", + .parent_names = (const char *[]){ "axi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_pclk0_clk = { + .halt_reg = 0x2314, + .clkr = { + .enable_reg = 0x2314, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_pclk0_clk", + .parent_names = (const char *[]){ "pclk0_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_pclk1_clk = { + .halt_reg = 0x2318, + .clkr = { + .enable_reg = 0x2318, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_pclk1_clk", + .parent_names = (const char *[]){ "pclk1_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_mdp_clk = { + .halt_reg = 0x231c, + .clkr = { + .enable_reg = 0x231c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_mdp_clk", + .parent_names = (const char *[]){ "mdp_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_extpclk_clk = { + .halt_reg = 0x2324, + .clkr = { + .enable_reg = 0x2324, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_extpclk_clk", + .parent_names = (const char *[]){ "extpclk_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_vsync_clk = { + .halt_reg = 0x2328, + .clkr = { + .enable_reg = 0x2328, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_vsync_clk", + .parent_names = (const char *[]){ "vsync_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_hdmi_clk = { + .halt_reg = 0x2338, + .clkr = { + .enable_reg = 0x2338, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_hdmi_clk", + .parent_names = (const char *[]){ "hdmi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_byte0_clk = { + .halt_reg = 0x233c, + .clkr = { + .enable_reg = 0x233c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_byte0_clk", + .parent_names = (const char *[]){ "byte0_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_byte1_clk = { + .halt_reg = 0x2340, + .clkr = { + .enable_reg = 0x2340, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_byte1_clk", + .parent_names = (const char *[]){ "byte1_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_esc0_clk = { + .halt_reg = 0x2344, + .clkr = { + .enable_reg = 0x2344, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_esc0_clk", + .parent_names = (const char *[]){ "esc0_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_esc1_clk = { + .halt_reg = 0x2348, + .clkr = { + .enable_reg = 0x2348, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_esc1_clk", + .parent_names = (const char *[]){ "esc1_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_top_ahb_clk = { + .halt_reg = 0x3484, + .clkr = { + .enable_reg = 0x3484, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_top_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_ahb_clk = { + .halt_reg = 0x348c, + .clkr = { + .enable_reg = 0x348c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_micro_ahb_clk = { + .halt_reg = 0x3494, + .clkr = { + .enable_reg = 0x3494, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_micro_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_gp0_clk = { + .halt_reg = 0x3444, + .clkr = { + .enable_reg = 0x3444, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_gp0_clk", + .parent_names = (const char *[]){ "camss_gp0_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_gp1_clk = { + .halt_reg = 0x3474, + .clkr = { + .enable_reg = 0x3474, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_gp1_clk", + .parent_names = (const char *[]){ "camss_gp1_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_mclk0_clk = { + .halt_reg = 0x3384, + .clkr = { + .enable_reg = 0x3384, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_mclk0_clk", + .parent_names = (const char *[]){ "mclk0_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_mclk1_clk = { + .halt_reg = 0x33b4, + .clkr = { + .enable_reg = 0x33b4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_mclk1_clk", + .parent_names = (const char *[]){ "mclk1_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_mclk2_clk = { + .halt_reg = 0x33e4, + .clkr = { + .enable_reg = 0x33e4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_mclk2_clk", + .parent_names = (const char *[]){ "mclk2_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_mclk3_clk = { + .halt_reg = 0x3414, + .clkr = { + .enable_reg = 0x3414, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_mclk3_clk", + .parent_names = (const char *[]){ "mclk3_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_cci_clk = { + .halt_reg = 0x3344, + .clkr = { + .enable_reg = 0x3344, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_cci_clk", + .parent_names = (const char *[]){ "cci_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_cci_ahb_clk = { + .halt_reg = 0x3348, + .clkr = { + .enable_reg = 0x3348, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_cci_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csi0phytimer_clk = { + .halt_reg = 0x3024, + .clkr = { + .enable_reg = 0x3024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi0phytimer_clk", + .parent_names = (const char *[]){ "csi0phytimer_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csi1phytimer_clk = { + .halt_reg = 0x3054, + .clkr = { + .enable_reg = 0x3054, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi1phytimer_clk", + .parent_names = (const char *[]){ "csi1phytimer_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csi2phytimer_clk = { + .halt_reg = 0x3084, + .clkr = { + .enable_reg = 0x3084, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi2phytimer_clk", + .parent_names = (const char *[]){ "csi2phytimer_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csiphy0_3p_clk = { + .halt_reg = 0x3234, + .clkr = { + .enable_reg = 0x3234, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csiphy0_3p_clk", + .parent_names = (const char *[]){ "csiphy0_3p_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csiphy1_3p_clk = { + .halt_reg = 0x3254, + .clkr = { + .enable_reg = 0x3254, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csiphy1_3p_clk", + .parent_names = (const char *[]){ "csiphy1_3p_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csiphy2_3p_clk = { + .halt_reg = 0x3274, + .clkr = { + .enable_reg = 0x3274, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csiphy2_3p_clk", + .parent_names = (const char *[]){ "csiphy2_3p_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_jpeg0_clk = { + .halt_reg = 0x35a8, + .clkr = { + .enable_reg = 0x35a8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_jpeg0_clk", + .parent_names = (const char *[]){ "jpeg0_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_jpeg2_clk = { + .halt_reg = 0x35b0, + .clkr = { + .enable_reg = 0x35b0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_jpeg2_clk", + .parent_names = (const char *[]){ "jpeg2_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_jpeg_dma_clk = { + .halt_reg = 0x35c0, + .clkr = { + .enable_reg = 0x35c0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_jpeg_dma_clk", + .parent_names = (const char *[]){ "jpeg_dma_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_jpeg_ahb_clk = { + .halt_reg = 0x35b4, + .clkr = { + .enable_reg = 0x35b4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_jpeg_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_jpeg_axi_clk = { + .halt_reg = 0x35b8, + .clkr = { + .enable_reg = 0x35b8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_jpeg_axi_clk", + .parent_names = (const char *[]){ "axi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_vfe_ahb_clk = { + .halt_reg = 0x36b8, + .clkr = { + .enable_reg = 0x36b8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_vfe_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_vfe_axi_clk = { + .halt_reg = 0x36bc, + .clkr = { + .enable_reg = 0x36bc, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_vfe_axi_clk", + .parent_names = (const char *[]){ "axi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_vfe0_clk = { + .halt_reg = 0x36a8, + .clkr = { + .enable_reg = 0x36a8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_vfe0_clk", + .parent_names = (const char *[]){ "vfe0_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_vfe0_stream_clk = { + .halt_reg = 0x3720, + .clkr = { + .enable_reg = 0x3720, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_vfe0_stream_clk", + .parent_names = (const char *[]){ "vfe0_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_vfe0_ahb_clk = { + .halt_reg = 0x3668, + .clkr = { + .enable_reg = 0x3668, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_vfe0_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_vfe1_clk = { + .halt_reg = 0x36ac, + .clkr = { + .enable_reg = 0x36ac, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_vfe1_clk", + .parent_names = (const char *[]){ "vfe1_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_vfe1_stream_clk = { + .halt_reg = 0x3724, + .clkr = { + .enable_reg = 0x3724, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_vfe1_stream_clk", + .parent_names = (const char *[]){ "vfe1_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_vfe1_ahb_clk = { + .halt_reg = 0x3678, + .clkr = { + .enable_reg = 0x3678, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_vfe1_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csi_vfe0_clk = { + .halt_reg = 0x3704, + .clkr = { + .enable_reg = 0x3704, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi_vfe0_clk", + .parent_names = (const char *[]){ "vfe0_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csi_vfe1_clk = { + .halt_reg = 0x3714, + .clkr = { + .enable_reg = 0x3714, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi_vfe1_clk", + .parent_names = (const char *[]){ "vfe1_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_cpp_vbif_ahb_clk = { + .halt_reg = 0x36c8, + .clkr = { + .enable_reg = 0x36c8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_cpp_vbif_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_cpp_axi_clk = { + .halt_reg = 0x36c4, + .clkr = { + .enable_reg = 0x36c4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_cpp_axi_clk", + .parent_names = (const char *[]){ "axi_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_cpp_clk = { + .halt_reg = 0x36b0, + .clkr = { + .enable_reg = 0x36b0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_cpp_clk", + .parent_names = (const char *[]){ "cpp_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_cpp_ahb_clk = { + .halt_reg = 0x36b4, + .clkr = { + .enable_reg = 0x36b4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_cpp_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csi0_clk = { + .halt_reg = 0x30b4, + .clkr = { + .enable_reg = 0x30b4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi0_clk", + .parent_names = (const char *[]){ "csi0_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csi0_ahb_clk = { + .halt_reg = 0x30bc, + .clkr = { + .enable_reg = 0x30bc, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi0_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csi0phy_clk = { + .halt_reg = 0x30c4, + .clkr = { + .enable_reg = 0x30c4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi0phy_clk", + .parent_names = (const char *[]){ "csi0_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csi0rdi_clk = { + .halt_reg = 0x30d4, + .clkr = { + .enable_reg = 0x30d4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi0rdi_clk", + .parent_names = (const char *[]){ "csi0_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csi0pix_clk = { + .halt_reg = 0x30e4, + .clkr = { + .enable_reg = 0x30e4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi0pix_clk", + .parent_names = (const char *[]){ "csi0_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csi1_clk = { + .halt_reg = 0x3124, + .clkr = { + .enable_reg = 0x3124, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi1_clk", + .parent_names = (const char *[]){ "csi1_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csi1_ahb_clk = { + .halt_reg = 0x3128, + .clkr = { + .enable_reg = 0x3128, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi1_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csi1phy_clk = { + .halt_reg = 0x3134, + .clkr = { + .enable_reg = 0x3134, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi1phy_clk", + .parent_names = (const char *[]){ "csi1_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csi1rdi_clk = { + .halt_reg = 0x3144, + .clkr = { + .enable_reg = 0x3144, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi1rdi_clk", + .parent_names = (const char *[]){ "csi1_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csi1pix_clk = { + .halt_reg = 0x3154, + .clkr = { + .enable_reg = 0x3154, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi1pix_clk", + .parent_names = (const char *[]){ "csi1_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csi2_clk = { + .halt_reg = 0x3184, + .clkr = { + .enable_reg = 0x3184, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi2_clk", + .parent_names = (const char *[]){ "csi2_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csi2_ahb_clk = { + .halt_reg = 0x3188, + .clkr = { + .enable_reg = 0x3188, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi2_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csi2phy_clk = { + .halt_reg = 0x3194, + .clkr = { + .enable_reg = 0x3194, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi2phy_clk", + .parent_names = (const char *[]){ "csi2_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csi2rdi_clk = { + .halt_reg = 0x31a4, + .clkr = { + .enable_reg = 0x31a4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi2rdi_clk", + .parent_names = (const char *[]){ "csi2_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csi2pix_clk = { + .halt_reg = 0x31b4, + .clkr = { + .enable_reg = 0x31b4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi2pix_clk", + .parent_names = (const char *[]){ "csi2_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csi3_clk = { + .halt_reg = 0x31e4, + .clkr = { + .enable_reg = 0x31e4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi3_clk", + .parent_names = (const char *[]){ "csi3_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csi3_ahb_clk = { + .halt_reg = 0x31e8, + .clkr = { + .enable_reg = 0x31e8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi3_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csi3phy_clk = { + .halt_reg = 0x31f4, + .clkr = { + .enable_reg = 0x31f4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi3phy_clk", + .parent_names = (const char *[]){ "csi3_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csi3rdi_clk = { + .halt_reg = 0x3204, + .clkr = { + .enable_reg = 0x3204, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi3rdi_clk", + .parent_names = (const char *[]){ "csi3_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_csi3pix_clk = { + .halt_reg = 0x3214, + .clkr = { + .enable_reg = 0x3214, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi3pix_clk", + .parent_names = (const char *[]){ "csi3_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_ispif_ahb_clk = { + .halt_reg = 0x3224, + .clkr = { + .enable_reg = 0x3224, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_ispif_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch fd_core_clk = { + .halt_reg = 0x3b68, + .clkr = { + .enable_reg = 0x3b68, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "fd_core_clk", + .parent_names = (const char *[]){ "fd_core_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch fd_core_uar_clk = { + .halt_reg = 0x3b6c, + .clkr = { + .enable_reg = 0x3b6c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "fd_core_uar_clk", + .parent_names = (const char *[]){ "fd_core_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch fd_ahb_clk = { + .halt_reg = 0x3ba74, + .clkr = { + .enable_reg = 0x3ba74, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "fd_ahb_clk", + .parent_names = (const char *[]){ "ahb_clk_src" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_hw *mmcc_msm8996_hws[] = { + &gpll0_div.hw, +}; + +static struct clk_regmap *mmcc_msm8996_clocks[] = { + [MMPLL0_EARLY] = &mmpll0_early.clkr, + [MMPLL0_PLL] = &mmpll0.clkr, + [MMPLL1_EARLY] = &mmpll1_early.clkr, + [MMPLL1_PLL] = &mmpll1.clkr, + [MMPLL2_EARLY] = &mmpll2_early.clkr, + [MMPLL2_PLL] = &mmpll2.clkr, + [MMPLL3_EARLY] = &mmpll3_early.clkr, + [MMPLL3_PLL] = &mmpll3.clkr, + [MMPLL4_EARLY] = &mmpll4_early.clkr, + [MMPLL4_PLL] = &mmpll4.clkr, + [MMPLL5_EARLY] = &mmpll5_early.clkr, + [MMPLL5_PLL] = &mmpll5.clkr, + [MMPLL8_EARLY] = &mmpll8_early.clkr, + [MMPLL8_PLL] = &mmpll8.clkr, + [MMPLL9_EARLY] = &mmpll9_early.clkr, + [MMPLL9_PLL] = &mmpll9.clkr, + [AHB_CLK_SRC] = &ahb_clk_src.clkr, + [AXI_CLK_SRC] = &axi_clk_src.clkr, + [MAXI_CLK_SRC] = &maxi_clk_src.clkr, + [GFX3D_CLK_SRC] = &gfx3d_clk_src.clkr, + [RBBMTIMER_CLK_SRC] = &rbbmtimer_clk_src.clkr, + [ISENSE_CLK_SRC] = &isense_clk_src.clkr, + [RBCPR_CLK_SRC] = &rbcpr_clk_src.clkr, + [VIDEO_CORE_CLK_SRC] = &video_core_clk_src.clkr, + [VIDEO_SUBCORE0_CLK_SRC] = &video_subcore0_clk_src.clkr, + [VIDEO_SUBCORE1_CLK_SRC] = &video_subcore1_clk_src.clkr, + [PCLK0_CLK_SRC] = &pclk0_clk_src.clkr, + [PCLK1_CLK_SRC] = &pclk1_clk_src.clkr, + [MDP_CLK_SRC] = &mdp_clk_src.clkr, + [EXTPCLK_CLK_SRC] = &extpclk_clk_src.clkr, + [VSYNC_CLK_SRC] = &vsync_clk_src.clkr, + [HDMI_CLK_SRC] = &hdmi_clk_src.clkr, + [BYTE0_CLK_SRC] = &byte0_clk_src.clkr, + [BYTE1_CLK_SRC] = &byte1_clk_src.clkr, + [ESC0_CLK_SRC] = &esc0_clk_src.clkr, + [ESC1_CLK_SRC] = &esc1_clk_src.clkr, + [CAMSS_GP0_CLK_SRC] = &camss_gp0_clk_src.clkr, + [CAMSS_GP1_CLK_SRC] = &camss_gp1_clk_src.clkr, + [MCLK0_CLK_SRC] = &mclk0_clk_src.clkr, + [MCLK1_CLK_SRC] = &mclk1_clk_src.clkr, + [MCLK2_CLK_SRC] = &mclk2_clk_src.clkr, + [MCLK3_CLK_SRC] = &mclk3_clk_src.clkr, + [CCI_CLK_SRC] = &cci_clk_src.clkr, + [CSI0PHYTIMER_CLK_SRC] = &csi0phytimer_clk_src.clkr, + [CSI1PHYTIMER_CLK_SRC] = &csi1phytimer_clk_src.clkr, + [CSI2PHYTIMER_CLK_SRC] = &csi2phytimer_clk_src.clkr, + [CSIPHY0_3P_CLK_SRC] = &csiphy0_3p_clk_src.clkr, + [CSIPHY1_3P_CLK_SRC] = &csiphy1_3p_clk_src.clkr, + [CSIPHY2_3P_CLK_SRC] = &csiphy2_3p_clk_src.clkr, + [JPEG0_CLK_SRC] = &jpeg0_clk_src.clkr, + [JPEG2_CLK_SRC] = &jpeg2_clk_src.clkr, + [JPEG_DMA_CLK_SRC] = &jpeg_dma_clk_src.clkr, + [VFE0_CLK_SRC] = &vfe0_clk_src.clkr, + [VFE1_CLK_SRC] = &vfe1_clk_src.clkr, + [CPP_CLK_SRC] = &cpp_clk_src.clkr, + [CSI0_CLK_SRC] = &csi0_clk_src.clkr, + [CSI1_CLK_SRC] = &csi1_clk_src.clkr, + [CSI2_CLK_SRC] = &csi2_clk_src.clkr, + [CSI3_CLK_SRC] = &csi3_clk_src.clkr, + [FD_CORE_CLK_SRC] = &fd_core_clk_src.clkr, + [MMSS_MMAGIC_AHB_CLK] = &mmss_mmagic_ahb_clk.clkr, + [MMSS_MMAGIC_CFG_AHB_CLK] = &mmss_mmagic_cfg_ahb_clk.clkr, + [MMSS_MISC_AHB_CLK] = &mmss_misc_ahb_clk.clkr, + [MMSS_MISC_CXO_CLK] = &mmss_misc_cxo_clk.clkr, + [MMSS_MMAGIC_AXI_CLK] = &mmss_mmagic_axi_clk.clkr, + [MMSS_MMAGIC_MAXI_CLK] = &mmss_mmagic_maxi_clk.clkr, + [MMAGIC_CAMSS_AXI_CLK] = &mmagic_camss_axi_clk.clkr, + [MMAGIC_CAMSS_NOC_CFG_AHB_CLK] = &mmagic_camss_noc_cfg_ahb_clk.clkr, + [SMMU_VFE_AHB_CLK] = &smmu_vfe_ahb_clk.clkr, + [SMMU_VFE_AXI_CLK] = &smmu_vfe_axi_clk.clkr, + [SMMU_CPP_AHB_CLK] = &smmu_cpp_ahb_clk.clkr, + [SMMU_CPP_AXI_CLK] = &smmu_cpp_axi_clk.clkr, + [SMMU_JPEG_AHB_CLK] = &smmu_jpeg_ahb_clk.clkr, + [SMMU_JPEG_AXI_CLK] = &smmu_jpeg_axi_clk.clkr, + [MMAGIC_MDSS_AXI_CLK] = &mmagic_mdss_axi_clk.clkr, + [MMAGIC_MDSS_NOC_CFG_AHB_CLK] = &mmagic_mdss_noc_cfg_ahb_clk.clkr, + [SMMU_ROT_AHB_CLK] = &smmu_rot_ahb_clk.clkr, + [SMMU_ROT_AXI_CLK] = &smmu_rot_axi_clk.clkr, + [SMMU_MDP_AHB_CLK] = &smmu_mdp_ahb_clk.clkr, + [SMMU_MDP_AXI_CLK] = &smmu_mdp_axi_clk.clkr, + [MMAGIC_VIDEO_AXI_CLK] = &mmagic_video_axi_clk.clkr, + [MMAGIC_VIDEO_NOC_CFG_AHB_CLK] = &mmagic_video_noc_cfg_ahb_clk.clkr, + [SMMU_VIDEO_AHB_CLK] = &smmu_video_ahb_clk.clkr, + [SMMU_VIDEO_AXI_CLK] = &smmu_video_axi_clk.clkr, + [MMAGIC_BIMC_AXI_CLK] = &mmagic_bimc_axi_clk.clkr, + [MMAGIC_BIMC_NOC_CFG_AHB_CLK] = &mmagic_bimc_noc_cfg_ahb_clk.clkr, + [GPU_GX_GFX3D_CLK] = &gpu_gx_gfx3d_clk.clkr, + [GPU_GX_RBBMTIMER_CLK] = &gpu_gx_rbbmtimer_clk.clkr, + [GPU_AHB_CLK] = &gpu_ahb_clk.clkr, + [GPU_AON_ISENSE_CLK] = &gpu_aon_isense_clk.clkr, + [VMEM_MAXI_CLK] = &vmem_maxi_clk.clkr, + [VMEM_AHB_CLK] = &vmem_ahb_clk.clkr, + [MMSS_RBCPR_CLK] = &mmss_rbcpr_clk.clkr, + [MMSS_RBCPR_AHB_CLK] = &mmss_rbcpr_ahb_clk.clkr, + [VIDEO_CORE_CLK] = &video_core_clk.clkr, + [VIDEO_AXI_CLK] = &video_axi_clk.clkr, + [VIDEO_MAXI_CLK] = &video_maxi_clk.clkr, + [VIDEO_AHB_CLK] = &video_ahb_clk.clkr, + [VIDEO_SUBCORE0_CLK] = &video_subcore0_clk.clkr, + [VIDEO_SUBCORE1_CLK] = &video_subcore1_clk.clkr, + [MDSS_AHB_CLK] = &mdss_ahb_clk.clkr, + [MDSS_HDMI_AHB_CLK] = &mdss_hdmi_ahb_clk.clkr, + [MDSS_AXI_CLK] = &mdss_axi_clk.clkr, + [MDSS_PCLK0_CLK] = &mdss_pclk0_clk.clkr, + [MDSS_PCLK1_CLK] = &mdss_pclk1_clk.clkr, + [MDSS_MDP_CLK] = &mdss_mdp_clk.clkr, + [MDSS_EXTPCLK_CLK] = &mdss_extpclk_clk.clkr, + [MDSS_VSYNC_CLK] = &mdss_vsync_clk.clkr, + [MDSS_HDMI_CLK] = &mdss_hdmi_clk.clkr, + [MDSS_BYTE0_CLK] = &mdss_byte0_clk.clkr, + [MDSS_BYTE1_CLK] = &mdss_byte1_clk.clkr, + [MDSS_ESC0_CLK] = &mdss_esc0_clk.clkr, + [MDSS_ESC1_CLK] = &mdss_esc1_clk.clkr, + [CAMSS_TOP_AHB_CLK] = &camss_top_ahb_clk.clkr, + [CAMSS_AHB_CLK] = &camss_ahb_clk.clkr, + [CAMSS_MICRO_AHB_CLK] = &camss_micro_ahb_clk.clkr, + [CAMSS_GP0_CLK] = &camss_gp0_clk.clkr, + [CAMSS_GP1_CLK] = &camss_gp1_clk.clkr, + [CAMSS_MCLK0_CLK] = &camss_mclk0_clk.clkr, + [CAMSS_MCLK1_CLK] = &camss_mclk1_clk.clkr, + [CAMSS_MCLK2_CLK] = &camss_mclk2_clk.clkr, + [CAMSS_MCLK3_CLK] = &camss_mclk3_clk.clkr, + [CAMSS_CCI_CLK] = &camss_cci_clk.clkr, + [CAMSS_CCI_AHB_CLK] = &camss_cci_ahb_clk.clkr, + [CAMSS_CSI0PHYTIMER_CLK] = &camss_csi0phytimer_clk.clkr, + [CAMSS_CSI1PHYTIMER_CLK] = &camss_csi1phytimer_clk.clkr, + [CAMSS_CSI2PHYTIMER_CLK] = &camss_csi2phytimer_clk.clkr, + [CAMSS_CSIPHY0_3P_CLK] = &camss_csiphy0_3p_clk.clkr, + [CAMSS_CSIPHY1_3P_CLK] = &camss_csiphy1_3p_clk.clkr, + [CAMSS_CSIPHY2_3P_CLK] = &camss_csiphy2_3p_clk.clkr, + [CAMSS_JPEG0_CLK] = &camss_jpeg0_clk.clkr, + [CAMSS_JPEG2_CLK] = &camss_jpeg2_clk.clkr, + [CAMSS_JPEG_DMA_CLK] = &camss_jpeg_dma_clk.clkr, + [CAMSS_JPEG_AHB_CLK] = &camss_jpeg_ahb_clk.clkr, + [CAMSS_JPEG_AXI_CLK] = &camss_jpeg_axi_clk.clkr, + [CAMSS_VFE_AHB_CLK] = &camss_vfe_ahb_clk.clkr, + [CAMSS_VFE_AXI_CLK] = &camss_vfe_axi_clk.clkr, + [CAMSS_VFE0_CLK] = &camss_vfe0_clk.clkr, + [CAMSS_VFE0_STREAM_CLK] = &camss_vfe0_stream_clk.clkr, + [CAMSS_VFE0_AHB_CLK] = &camss_vfe0_ahb_clk.clkr, + [CAMSS_VFE1_CLK] = &camss_vfe1_clk.clkr, + [CAMSS_VFE1_STREAM_CLK] = &camss_vfe1_stream_clk.clkr, + [CAMSS_VFE1_AHB_CLK] = &camss_vfe1_ahb_clk.clkr, + [CAMSS_CSI_VFE0_CLK] = &camss_csi_vfe0_clk.clkr, + [CAMSS_CSI_VFE1_CLK] = &camss_csi_vfe1_clk.clkr, + [CAMSS_CPP_VBIF_AHB_CLK] = &camss_cpp_vbif_ahb_clk.clkr, + [CAMSS_CPP_AXI_CLK] = &camss_cpp_axi_clk.clkr, + [CAMSS_CPP_CLK] = &camss_cpp_clk.clkr, + [CAMSS_CPP_AHB_CLK] = &camss_cpp_ahb_clk.clkr, + [CAMSS_CSI0_CLK] = &camss_csi0_clk.clkr, + [CAMSS_CSI0_AHB_CLK] = &camss_csi0_ahb_clk.clkr, + [CAMSS_CSI0PHY_CLK] = &camss_csi0phy_clk.clkr, + [CAMSS_CSI0RDI_CLK] = &camss_csi0rdi_clk.clkr, + [CAMSS_CSI0PIX_CLK] = &camss_csi0pix_clk.clkr, + [CAMSS_CSI1_CLK] = &camss_csi1_clk.clkr, + [CAMSS_CSI1_AHB_CLK] = &camss_csi1_ahb_clk.clkr, + [CAMSS_CSI1PHY_CLK] = &camss_csi1phy_clk.clkr, + [CAMSS_CSI1RDI_CLK] = &camss_csi1rdi_clk.clkr, + [CAMSS_CSI1PIX_CLK] = &camss_csi1pix_clk.clkr, + [CAMSS_CSI2_CLK] = &camss_csi2_clk.clkr, + [CAMSS_CSI2_AHB_CLK] = &camss_csi2_ahb_clk.clkr, + [CAMSS_CSI2PHY_CLK] = &camss_csi2phy_clk.clkr, + [CAMSS_CSI2RDI_CLK] = &camss_csi2rdi_clk.clkr, + [CAMSS_CSI2PIX_CLK] = &camss_csi2pix_clk.clkr, + [CAMSS_CSI3_CLK] = &camss_csi3_clk.clkr, + [CAMSS_CSI3_AHB_CLK] = &camss_csi3_ahb_clk.clkr, + [CAMSS_CSI3PHY_CLK] = &camss_csi3phy_clk.clkr, + [CAMSS_CSI3RDI_CLK] = &camss_csi3rdi_clk.clkr, + [CAMSS_CSI3PIX_CLK] = &camss_csi3pix_clk.clkr, + [CAMSS_ISPIF_AHB_CLK] = &camss_ispif_ahb_clk.clkr, + [FD_CORE_CLK] = &fd_core_clk.clkr, + [FD_CORE_UAR_CLK] = &fd_core_uar_clk.clkr, + [FD_AHB_CLK] = &fd_ahb_clk.clkr, +}; + +static const struct qcom_reset_map mmcc_msm8996_resets[] = { + [MMAGICAHB_BCR] = { 0x5020 }, + [MMAGIC_CFG_BCR] = { 0x5050 }, + [MISC_BCR] = { 0x5010 }, + [BTO_BCR] = { 0x5030 }, + [MMAGICAXI_BCR] = { 0x5060 }, + [MMAGICMAXI_BCR] = { 0x5070 }, + [DSA_BCR] = { 0x50a0 }, + [MMAGIC_CAMSS_BCR] = { 0x3c40 }, + [THROTTLE_CAMSS_BCR] = { 0x3c30 }, + [SMMU_VFE_BCR] = { 0x3c00 }, + [SMMU_CPP_BCR] = { 0x3c10 }, + [SMMU_JPEG_BCR] = { 0x3c20 }, + [MMAGIC_MDSS_BCR] = { 0x2470 }, + [THROTTLE_MDSS_BCR] = { 0x2460 }, + [SMMU_ROT_BCR] = { 0x2440 }, + [SMMU_MDP_BCR] = { 0x2450 }, + [MMAGIC_VIDEO_BCR] = { 0x1190 }, + [THROTTLE_VIDEO_BCR] = { 0x1180 }, + [SMMU_VIDEO_BCR] = { 0x1170 }, + [MMAGIC_BIMC_BCR] = { 0x5290 }, + [GPU_GX_BCR] = { 0x4020 }, + [GPU_BCR] = { 0x4030 }, + [GPU_AON_BCR] = { 0x4040 }, + [VMEM_BCR] = { 0x1200 }, + [MMSS_RBCPR_BCR] = { 0x4080 }, + [VIDEO_BCR] = { 0x1020 }, + [MDSS_BCR] = { 0x2300 }, + [CAMSS_TOP_BCR] = { 0x3480 }, + [CAMSS_AHB_BCR] = { 0x3488 }, + [CAMSS_MICRO_BCR] = { 0x3490 }, + [CAMSS_CCI_BCR] = { 0x3340 }, + [CAMSS_PHY0_BCR] = { 0x3020 }, + [CAMSS_PHY1_BCR] = { 0x3050 }, + [CAMSS_PHY2_BCR] = { 0x3080 }, + [CAMSS_CSIPHY0_3P_BCR] = { 0x3230 }, + [CAMSS_CSIPHY1_3P_BCR] = { 0x3250 }, + [CAMSS_CSIPHY2_3P_BCR] = { 0x3270 }, + [CAMSS_JPEG_BCR] = { 0x35a0 }, + [CAMSS_VFE_BCR] = { 0x36a0 }, + [CAMSS_VFE0_BCR] = { 0x3660 }, + [CAMSS_VFE1_BCR] = { 0x3670 }, + [CAMSS_CSI_VFE0_BCR] = { 0x3700 }, + [CAMSS_CSI_VFE1_BCR] = { 0x3710 }, + [CAMSS_CPP_TOP_BCR] = { 0x36c0 }, + [CAMSS_CPP_BCR] = { 0x36d0 }, + [CAMSS_CSI0_BCR] = { 0x30b0 }, + [CAMSS_CSI0RDI_BCR] = { 0x30d0 }, + [CAMSS_CSI0PIX_BCR] = { 0x30e0 }, + [CAMSS_CSI1_BCR] = { 0x3120 }, + [CAMSS_CSI1RDI_BCR] = { 0x3140 }, + [CAMSS_CSI1PIX_BCR] = { 0x3150 }, + [CAMSS_CSI2_BCR] = { 0x3180 }, + [CAMSS_CSI2RDI_BCR] = { 0x31a0 }, + [CAMSS_CSI2PIX_BCR] = { 0x31b0 }, + [CAMSS_CSI3_BCR] = { 0x31e0 }, + [CAMSS_CSI3RDI_BCR] = { 0x3200 }, + [CAMSS_CSI3PIX_BCR] = { 0x3210 }, + [CAMSS_ISPIF_BCR] = { 0x3220 }, + [FD_BCR] = { 0x3b60 }, + [MMSS_SPDM_RM_BCR] = { 0x300 }, +}; + +static const struct regmap_config mmcc_msm8996_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0xb008, + .fast_io = true, +}; + +static const struct qcom_cc_desc mmcc_msm8996_desc = { + .config = &mmcc_msm8996_regmap_config, + .clks = mmcc_msm8996_clocks, + .num_clks = ARRAY_SIZE(mmcc_msm8996_clocks), + .resets = mmcc_msm8996_resets, + .num_resets = ARRAY_SIZE(mmcc_msm8996_resets), +}; + +static const struct of_device_id mmcc_msm8996_match_table[] = { + { .compatible = "qcom,mmcc-msm8996" }, + { } +}; +MODULE_DEVICE_TABLE(of, mmcc_msm8996_match_table); + +static int mmcc_msm8996_probe(struct platform_device *pdev) +{ + struct clk *clk; + struct device *dev = &pdev->dev; + int i; + struct regmap *regmap; + + regmap = qcom_cc_map(pdev, &mmcc_msm8996_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + /* Disable the AHB DCD */ + regmap_update_bits(regmap, 0x50d8, BIT(31), 0); + /* Disable the NoC FSM for mmss_mmagic_cfg_ahb_clk */ + regmap_update_bits(regmap, 0x5054, BIT(15), 0); + + for (i = 0; i < ARRAY_SIZE(mmcc_msm8996_hws); i++) { + clk = devm_clk_register(dev, mmcc_msm8996_hws[i]); + if (IS_ERR(clk)) + return PTR_ERR(clk); + } + + return qcom_cc_really_probe(pdev, &mmcc_msm8996_desc, regmap); +} + +static struct platform_driver mmcc_msm8996_driver = { + .probe = mmcc_msm8996_probe, + .driver = { + .name = "mmcc-msm8996", + .of_match_table = mmcc_msm8996_match_table, + }, +}; +module_platform_driver(mmcc_msm8996_driver); + +MODULE_DESCRIPTION("QCOM MMCC MSM8996 Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:mmcc-msm8996"); diff --git a/drivers/clk/shmobile/Makefile b/drivers/clk/shmobile/Makefile index 97c71c885e4f..7e2579b30326 100644 --- a/drivers/clk/shmobile/Makefile +++ b/drivers/clk/shmobile/Makefile @@ -1,13 +1,13 @@ obj-$(CONFIG_ARCH_EMEV2) += clk-emev2.o -obj-$(CONFIG_ARCH_R7S72100) += clk-rz.o -obj-$(CONFIG_ARCH_R8A73A4) += clk-r8a73a4.o -obj-$(CONFIG_ARCH_R8A7740) += clk-r8a7740.o -obj-$(CONFIG_ARCH_R8A7778) += clk-r8a7778.o -obj-$(CONFIG_ARCH_R8A7779) += clk-r8a7779.o -obj-$(CONFIG_ARCH_R8A7790) += clk-rcar-gen2.o -obj-$(CONFIG_ARCH_R8A7791) += clk-rcar-gen2.o -obj-$(CONFIG_ARCH_R8A7793) += clk-rcar-gen2.o -obj-$(CONFIG_ARCH_R8A7794) += clk-rcar-gen2.o -obj-$(CONFIG_ARCH_SH73A0) += clk-sh73a0.o -obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += clk-div6.o -obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += clk-mstp.o +obj-$(CONFIG_ARCH_R7S72100) += clk-rz.o clk-mstp.o +obj-$(CONFIG_ARCH_R8A73A4) += clk-r8a73a4.o clk-mstp.o clk-div6.o +obj-$(CONFIG_ARCH_R8A7740) += clk-r8a7740.o clk-mstp.o clk-div6.o +obj-$(CONFIG_ARCH_R8A7778) += clk-r8a7778.o clk-mstp.o +obj-$(CONFIG_ARCH_R8A7779) += clk-r8a7779.o clk-mstp.o +obj-$(CONFIG_ARCH_R8A7790) += clk-rcar-gen2.o clk-mstp.o clk-div6.o +obj-$(CONFIG_ARCH_R8A7791) += clk-rcar-gen2.o clk-mstp.o clk-div6.o +obj-$(CONFIG_ARCH_R8A7793) += clk-rcar-gen2.o clk-mstp.o clk-div6.o +obj-$(CONFIG_ARCH_R8A7794) += clk-rcar-gen2.o clk-mstp.o clk-div6.o +obj-$(CONFIG_ARCH_R8A7795) += renesas-cpg-mssr.o \ + r8a7795-cpg-mssr.o clk-div6.o +obj-$(CONFIG_ARCH_SH73A0) += clk-sh73a0.o clk-mstp.o clk-div6.o diff --git a/drivers/clk/shmobile/clk-div6.c b/drivers/clk/shmobile/clk-div6.c index b4c8d6746f68..999994769450 100644 --- a/drivers/clk/shmobile/clk-div6.c +++ b/drivers/clk/shmobile/clk-div6.c @@ -18,6 +18,8 @@ #include <linux/of_address.h> #include <linux/slab.h> +#include "clk-div6.h" + #define CPG_DIV6_CKSTP BIT(8) #define CPG_DIV6_DIV(d) ((d) & 0x3f) #define CPG_DIV6_DIV_MASK 0x3f @@ -172,67 +174,44 @@ static const struct clk_ops cpg_div6_clock_ops = { .set_rate = cpg_div6_clock_set_rate, }; -static void __init cpg_div6_clock_init(struct device_node *np) + +/** + * cpg_div6_register - Register a DIV6 clock + * @name: Name of the DIV6 clock + * @num_parents: Number of parent clocks of the DIV6 clock (1, 4, or 8) + * @parent_names: Array containing the names of the parent clocks + * @reg: Mapped register used to control the DIV6 clock + */ +struct clk * __init cpg_div6_register(const char *name, + unsigned int num_parents, + const char **parent_names, + void __iomem *reg) { - unsigned int num_parents, valid_parents; - const char **parent_names; + unsigned int valid_parents; struct clk_init_data init; struct div6_clock *clock; - const char *name; struct clk *clk; unsigned int i; - int ret; clock = kzalloc(sizeof(*clock), GFP_KERNEL); if (!clock) - return; + return ERR_PTR(-ENOMEM); - num_parents = of_clk_get_parent_count(np); - if (num_parents < 1) { - pr_err("%s: no parent found for %s DIV6 clock\n", - __func__, np->name); - return; + clock->parents = kmalloc_array(num_parents, sizeof(*clock->parents), + GFP_KERNEL); + if (!clock->parents) { + clk = ERR_PTR(-ENOMEM); + goto free_clock; } - clock->parents = kmalloc_array(num_parents, sizeof(*clock->parents), - GFP_KERNEL); - parent_names = kmalloc_array(num_parents, sizeof(*parent_names), - GFP_KERNEL); - if (!parent_names) - return; + clock->reg = reg; - /* Remap the clock register and read the divisor. Disabling the - * clock overwrites the divisor, so we need to cache its value for the - * enable operation. + /* + * Read the divisor. Disabling the clock overwrites the divisor, so we + * need to cache its value for the enable operation. */ - clock->reg = of_iomap(np, 0); - if (clock->reg == NULL) { - pr_err("%s: failed to map %s DIV6 clock register\n", - __func__, np->name); - goto error; - } - clock->div = (clk_readl(clock->reg) & CPG_DIV6_DIV_MASK) + 1; - /* Parse the DT properties. */ - ret = of_property_read_string(np, "clock-output-names", &name); - if (ret < 0) { - pr_err("%s: failed to get %s DIV6 clock output name\n", - __func__, np->name); - goto error; - } - - - for (i = 0, valid_parents = 0; i < num_parents; i++) { - const char *name = of_clk_get_parent_name(np, i); - - if (name) { - parent_names[valid_parents] = name; - clock->parents[valid_parents] = i; - valid_parents++; - } - } - switch (num_parents) { case 1: /* fixed parent clock */ @@ -250,8 +229,18 @@ static void __init cpg_div6_clock_init(struct device_node *np) break; default: pr_err("%s: invalid number of parents for DIV6 clock %s\n", - __func__, np->name); - goto error; + __func__, name); + clk = ERR_PTR(-EINVAL); + goto free_parents; + } + + /* Filter out invalid parents */ + for (i = 0, valid_parents = 0; i < num_parents; i++) { + if (parent_names[i]) { + parent_names[valid_parents] = parent_names[i]; + clock->parents[valid_parents] = i; + valid_parents++; + } } /* Register the clock. */ @@ -264,6 +253,53 @@ static void __init cpg_div6_clock_init(struct device_node *np) clock->hw.init = &init; clk = clk_register(NULL, &clock->hw); + if (IS_ERR(clk)) + goto free_parents; + + return clk; + +free_parents: + kfree(clock->parents); +free_clock: + kfree(clock); + return clk; +} + +static void __init cpg_div6_clock_init(struct device_node *np) +{ + unsigned int num_parents; + const char **parent_names; + const char *clk_name = np->name; + void __iomem *reg; + struct clk *clk; + unsigned int i; + + num_parents = of_clk_get_parent_count(np); + if (num_parents < 1) { + pr_err("%s: no parent found for %s DIV6 clock\n", + __func__, np->name); + return; + } + + parent_names = kmalloc_array(num_parents, sizeof(*parent_names), + GFP_KERNEL); + if (!parent_names) + return; + + reg = of_iomap(np, 0); + if (reg == NULL) { + pr_err("%s: failed to map %s DIV6 clock register\n", + __func__, np->name); + goto error; + } + + /* Parse the DT properties. */ + of_property_read_string(np, "clock-output-names", &clk_name); + + for (i = 0; i < num_parents; i++) + parent_names[i] = of_clk_get_parent_name(np, i); + + clk = cpg_div6_register(clk_name, num_parents, parent_names, reg); if (IS_ERR(clk)) { pr_err("%s: failed to register %s DIV6 clock (%ld)\n", __func__, np->name, PTR_ERR(clk)); @@ -276,9 +312,8 @@ static void __init cpg_div6_clock_init(struct device_node *np) return; error: - if (clock->reg) - iounmap(clock->reg); + if (reg) + iounmap(reg); kfree(parent_names); - kfree(clock); } CLK_OF_DECLARE(cpg_div6_clk, "renesas,cpg-div6-clock", cpg_div6_clock_init); diff --git a/drivers/clk/shmobile/clk-div6.h b/drivers/clk/shmobile/clk-div6.h new file mode 100644 index 000000000000..9a85a95188da --- /dev/null +++ b/drivers/clk/shmobile/clk-div6.h @@ -0,0 +1,7 @@ +#ifndef __SHMOBILE_CLK_DIV6_H__ +#define __SHMOBILE_CLK_DIV6_H__ + +struct clk *cpg_div6_register(const char *name, unsigned int num_parents, + const char **parent_names, void __iomem *reg); + +#endif diff --git a/drivers/clk/shmobile/clk-rcar-gen2.c b/drivers/clk/shmobile/clk-rcar-gen2.c index 745496f7ee9c..841977240305 100644 --- a/drivers/clk/shmobile/clk-rcar-gen2.c +++ b/drivers/clk/shmobile/clk-rcar-gen2.c @@ -115,7 +115,7 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, * * Using experimental measurements, it seems that no more than * ~10 iterations are needed, independently of the CPU rate. - * Since this value might be dependant of external xtal rate, pll1 + * Since this value might be dependent on external xtal rate, pll1 * rate or even the other emulation clocks rate, use 1000 as a * "super" safe value. */ @@ -262,7 +262,7 @@ static struct clk * __init cpg_adsp_clk_register(struct rcar_gen2_cpg *cpg) * 1 1 0 30 / 2 x172/2 x208/2 x106 * 1 1 1 30 / 2 x172/2 x208/2 x88 * - * *1 : Table 7.6 indicates VCO ouput (PLLx = VCO/2) + * *1 : Table 7.6 indicates VCO output (PLLx = VCO/2) */ #define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 12) | \ (((md) & BIT(13)) >> 12) | \ diff --git a/drivers/clk/shmobile/r8a7795-cpg-mssr.c b/drivers/clk/shmobile/r8a7795-cpg-mssr.c new file mode 100644 index 000000000000..57c413635d1a --- /dev/null +++ b/drivers/clk/shmobile/r8a7795-cpg-mssr.c @@ -0,0 +1,382 @@ +/* + * r8a7795 Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2015 Glider bvba + * + * Based on clk-rcar-gen3.c + * + * Copyright (C) 2015 Renesas Electronics Corp. + * + * 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; version 2 of the License. + */ + +#include <linux/bug.h> +#include <linux/clk-provider.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/of.h> + +#include <dt-bindings/clock/r8a7795-cpg-mssr.h> + +#include "renesas-cpg-mssr.h" + + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R8A7795_CLK_OSC, + + /* External Input Clocks */ + CLK_EXTAL, + CLK_EXTALR, + + /* Internal Core Clocks */ + CLK_MAIN, + CLK_PLL0, + CLK_PLL1, + CLK_PLL2, + CLK_PLL3, + CLK_PLL4, + CLK_PLL1_DIV2, + CLK_PLL1_DIV4, + CLK_S0, + CLK_S1, + CLK_S2, + CLK_S3, + CLK_SDSRC, + CLK_SSPSRC, + + /* Module Clocks */ + MOD_CLK_BASE +}; + +enum r8a7795_clk_types { + CLK_TYPE_GEN3_MAIN = CLK_TYPE_CUSTOM, + CLK_TYPE_GEN3_PLL0, + CLK_TYPE_GEN3_PLL1, + CLK_TYPE_GEN3_PLL2, + CLK_TYPE_GEN3_PLL3, + CLK_TYPE_GEN3_PLL4, +}; + +static const struct cpg_core_clk r8a7795_core_clks[] __initconst = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + DEF_INPUT("extalr", CLK_EXTALR), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL), + DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN3_PLL0, CLK_MAIN), + DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN), + DEF_BASE(".pll2", CLK_PLL2, CLK_TYPE_GEN3_PLL2, CLK_MAIN), + DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN), + DEF_BASE(".pll4", CLK_PLL4, CLK_TYPE_GEN3_PLL4, CLK_MAIN), + + DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1), + DEF_FIXED(".pll1_div4", CLK_PLL1_DIV4, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".s0", CLK_S0, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 3, 1), + DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), + DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), + + /* Core Clock Outputs */ + DEF_FIXED("ztr", R8A7795_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), + DEF_FIXED("ztrd2", R8A7795_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), + DEF_FIXED("zt", R8A7795_CLK_ZT, CLK_PLL1_DIV2, 4, 1), + DEF_FIXED("zx", R8A7795_CLK_ZX, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED("s0d1", R8A7795_CLK_S0D1, CLK_S0, 1, 1), + DEF_FIXED("s0d4", R8A7795_CLK_S0D4, CLK_S0, 4, 1), + DEF_FIXED("s1d1", R8A7795_CLK_S1D1, CLK_S1, 1, 1), + DEF_FIXED("s1d2", R8A7795_CLK_S1D2, CLK_S1, 2, 1), + DEF_FIXED("s1d4", R8A7795_CLK_S1D4, CLK_S1, 4, 1), + DEF_FIXED("s2d1", R8A7795_CLK_S2D1, CLK_S2, 1, 1), + DEF_FIXED("s2d2", R8A7795_CLK_S2D2, CLK_S2, 2, 1), + DEF_FIXED("s2d4", R8A7795_CLK_S2D4, CLK_S2, 4, 1), + DEF_FIXED("s3d1", R8A7795_CLK_S3D1, CLK_S3, 1, 1), + DEF_FIXED("s3d2", R8A7795_CLK_S3D2, CLK_S3, 2, 1), + DEF_FIXED("s3d4", R8A7795_CLK_S3D4, CLK_S3, 4, 1), + DEF_FIXED("cl", R8A7795_CLK_CL, CLK_PLL1_DIV2, 48, 1), + DEF_FIXED("cp", R8A7795_CLK_CP, CLK_EXTAL, 2, 1), + + DEF_DIV6P1("mso", R8A7795_CLK_MSO, CLK_PLL1_DIV4, 0x014), + DEF_DIV6P1("hdmi", R8A7795_CLK_HDMI, CLK_PLL1_DIV2, 0x250), +}; + +static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = { + DEF_MOD("scif5", 202, R8A7795_CLK_S3D4), + DEF_MOD("scif4", 203, R8A7795_CLK_S3D4), + DEF_MOD("scif3", 204, R8A7795_CLK_S3D4), + DEF_MOD("scif1", 206, R8A7795_CLK_S3D4), + DEF_MOD("scif0", 207, R8A7795_CLK_S3D4), + DEF_MOD("msiof3", 208, R8A7795_CLK_MSO), + DEF_MOD("msiof2", 209, R8A7795_CLK_MSO), + DEF_MOD("msiof1", 210, R8A7795_CLK_MSO), + DEF_MOD("msiof0", 211, R8A7795_CLK_MSO), + DEF_MOD("sys-dmac2", 217, R8A7795_CLK_S3D1), + DEF_MOD("sys-dmac1", 218, R8A7795_CLK_S3D1), + DEF_MOD("sys-dmac0", 219, R8A7795_CLK_S3D1), + DEF_MOD("scif2", 310, R8A7795_CLK_S3D4), + DEF_MOD("pcie1", 318, R8A7795_CLK_S3D1), + DEF_MOD("pcie0", 319, R8A7795_CLK_S3D1), + DEF_MOD("intc-ap", 408, R8A7795_CLK_S3D1), + DEF_MOD("audmac0", 502, R8A7795_CLK_S3D4), + DEF_MOD("audmac1", 501, R8A7795_CLK_S3D4), + DEF_MOD("hscif4", 516, R8A7795_CLK_S3D1), + DEF_MOD("hscif3", 517, R8A7795_CLK_S3D1), + DEF_MOD("hscif2", 518, R8A7795_CLK_S3D1), + DEF_MOD("hscif1", 519, R8A7795_CLK_S3D1), + DEF_MOD("hscif0", 520, R8A7795_CLK_S3D1), + DEF_MOD("vspd3", 620, R8A7795_CLK_S2D1), + DEF_MOD("vspd2", 621, R8A7795_CLK_S2D1), + DEF_MOD("vspd1", 622, R8A7795_CLK_S2D1), + DEF_MOD("vspd0", 623, R8A7795_CLK_S2D1), + DEF_MOD("vspbc", 624, R8A7795_CLK_S2D1), + DEF_MOD("vspbd", 626, R8A7795_CLK_S2D1), + DEF_MOD("vspi2", 629, R8A7795_CLK_S2D1), + DEF_MOD("vspi1", 630, R8A7795_CLK_S2D1), + DEF_MOD("vspi0", 631, R8A7795_CLK_S2D1), + DEF_MOD("ehci2", 701, R8A7795_CLK_S3D4), + DEF_MOD("ehci1", 702, R8A7795_CLK_S3D4), + DEF_MOD("ehci0", 703, R8A7795_CLK_S3D4), + DEF_MOD("hsusb", 704, R8A7795_CLK_S3D4), + DEF_MOD("du3", 721, R8A7795_CLK_S2D1), + DEF_MOD("du2", 722, R8A7795_CLK_S2D1), + DEF_MOD("du1", 723, R8A7795_CLK_S2D1), + DEF_MOD("du0", 724, R8A7795_CLK_S2D1), + DEF_MOD("hdmi1", 728, R8A7795_CLK_HDMI), + DEF_MOD("hdmi0", 729, R8A7795_CLK_HDMI), + DEF_MOD("etheravb", 812, R8A7795_CLK_S3D2), + DEF_MOD("gpio7", 905, R8A7795_CLK_CP), + DEF_MOD("gpio6", 906, R8A7795_CLK_CP), + DEF_MOD("gpio5", 907, R8A7795_CLK_CP), + DEF_MOD("gpio4", 908, R8A7795_CLK_CP), + DEF_MOD("gpio3", 909, R8A7795_CLK_CP), + DEF_MOD("gpio2", 910, R8A7795_CLK_CP), + DEF_MOD("gpio1", 911, R8A7795_CLK_CP), + DEF_MOD("gpio0", 912, R8A7795_CLK_CP), + DEF_MOD("i2c6", 918, R8A7795_CLK_S3D2), + DEF_MOD("i2c5", 919, R8A7795_CLK_S3D2), + DEF_MOD("i2c4", 927, R8A7795_CLK_S3D2), + DEF_MOD("i2c3", 928, R8A7795_CLK_S3D2), + DEF_MOD("i2c2", 929, R8A7795_CLK_S3D2), + DEF_MOD("i2c1", 930, R8A7795_CLK_S3D2), + DEF_MOD("i2c0", 931, R8A7795_CLK_S3D2), + DEF_MOD("ssi-all", 1005, R8A7795_CLK_S3D4), + DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)), + DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)), + DEF_MOD("ssi7", 1008, MOD_CLK_ID(1005)), + DEF_MOD("ssi6", 1009, MOD_CLK_ID(1005)), + DEF_MOD("ssi5", 1010, MOD_CLK_ID(1005)), + DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)), + DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)), + DEF_MOD("ssi2", 1013, MOD_CLK_ID(1005)), + DEF_MOD("ssi1", 1014, MOD_CLK_ID(1005)), + DEF_MOD("ssi0", 1015, MOD_CLK_ID(1005)), + DEF_MOD("scu-all", 1017, R8A7795_CLK_S3D4), + DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)), + DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)), + DEF_MOD("scu-src9", 1022, MOD_CLK_ID(1017)), + DEF_MOD("scu-src8", 1023, MOD_CLK_ID(1017)), + DEF_MOD("scu-src7", 1024, MOD_CLK_ID(1017)), + DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)), + DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)), + DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)), + DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)), + DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)), + DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)), + DEF_MOD("scu-src0", 1031, MOD_CLK_ID(1017)), +}; + +static const unsigned int r8a7795_crit_mod_clks[] __initconst = { + MOD_CLK_ID(408), /* INTC-AP (GIC) */ +}; + + +#define CPG_PLL0CR 0x00d8 +#define CPG_PLL2CR 0x002c +#define CPG_PLL4CR 0x01f4 + +/* + * CPG Clock Data + */ + +/* + * MD EXTAL PLL0 PLL1 PLL2 PLL3 PLL4 + * 14 13 19 17 (MHz) + *------------------------------------------------------------------- + * 0 0 0 0 16.66 x 1 x180 x192 x144 x192 x144 + * 0 0 0 1 16.66 x 1 x180 x192 x144 x128 x144 + * 0 0 1 0 Prohibited setting + * 0 0 1 1 16.66 x 1 x180 x192 x144 x192 x144 + * 0 1 0 0 20 x 1 x150 x160 x120 x160 x120 + * 0 1 0 1 20 x 1 x150 x160 x120 x106 x120 + * 0 1 1 0 Prohibited setting + * 0 1 1 1 20 x 1 x150 x160 x120 x160 x120 + * 1 0 0 0 25 x 1 x120 x128 x96 x128 x96 + * 1 0 0 1 25 x 1 x120 x128 x96 x84 x96 + * 1 0 1 0 Prohibited setting + * 1 0 1 1 25 x 1 x120 x128 x96 x128 x96 + * 1 1 0 0 33.33 / 2 x180 x192 x144 x192 x144 + * 1 1 0 1 33.33 / 2 x180 x192 x144 x128 x144 + * 1 1 1 0 Prohibited setting + * 1 1 1 1 33.33 / 2 x180 x192 x144 x192 x144 + */ +#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 11) | \ + (((md) & BIT(13)) >> 11) | \ + (((md) & BIT(19)) >> 18) | \ + (((md) & BIT(17)) >> 17)) + +struct cpg_pll_config { + unsigned int extal_div; + unsigned int pll1_mult; + unsigned int pll3_mult; +}; + +static const struct cpg_pll_config cpg_pll_configs[16] __initconst = { + /* EXTAL div PLL1 mult PLL3 mult */ + { 1, 192, 192, }, + { 1, 192, 128, }, + { 0, /* Prohibited setting */ }, + { 1, 192, 192, }, + { 1, 160, 160, }, + { 1, 160, 106, }, + { 0, /* Prohibited setting */ }, + { 1, 160, 160, }, + { 1, 128, 128, }, + { 1, 128, 84, }, + { 0, /* Prohibited setting */ }, + { 1, 128, 128, }, + { 2, 192, 192, }, + { 2, 192, 128, }, + { 0, /* Prohibited setting */ }, + { 2, 192, 192, }, +}; + +static const struct cpg_pll_config *cpg_pll_config __initdata; + +static +struct clk * __init r8a7795_cpg_clk_register(struct device *dev, + const struct cpg_core_clk *core, + const struct cpg_mssr_info *info, + struct clk **clks, + void __iomem *base) +{ + const struct clk *parent; + unsigned int mult = 1; + unsigned int div = 1; + u32 value; + + parent = clks[core->parent]; + if (IS_ERR(parent)) + return ERR_CAST(parent); + + switch (core->type) { + case CLK_TYPE_GEN3_MAIN: + div = cpg_pll_config->extal_div; + break; + + case CLK_TYPE_GEN3_PLL0: + /* + * PLL0 is a configurable multiplier clock. Register it as a + * fixed factor clock for now as there's no generic multiplier + * clock implementation and we currently have no need to change + * the multiplier value. + */ + value = readl(base + CPG_PLL0CR); + mult = (((value >> 24) & 0x7f) + 1) * 2; + break; + + case CLK_TYPE_GEN3_PLL1: + mult = cpg_pll_config->pll1_mult; + break; + + case CLK_TYPE_GEN3_PLL2: + /* + * PLL2 is a configurable multiplier clock. Register it as a + * fixed factor clock for now as there's no generic multiplier + * clock implementation and we currently have no need to change + * the multiplier value. + */ + value = readl(base + CPG_PLL2CR); + mult = (((value >> 24) & 0x7f) + 1) * 2; + break; + + case CLK_TYPE_GEN3_PLL3: + mult = cpg_pll_config->pll3_mult; + break; + + case CLK_TYPE_GEN3_PLL4: + /* + * PLL4 is a configurable multiplier clock. Register it as a + * fixed factor clock for now as there's no generic multiplier + * clock implementation and we currently have no need to change + * the multiplier value. + */ + value = readl(base + CPG_PLL4CR); + mult = (((value >> 24) & 0x7f) + 1) * 2; + break; + + default: + return ERR_PTR(-EINVAL); + } + + return clk_register_fixed_factor(NULL, core->name, + __clk_get_name(parent), 0, mult, div); +} + +/* + * Reset register definitions. + */ +#define MODEMR 0xe6160060 + +static u32 rcar_gen3_read_mode_pins(void) +{ + void __iomem *modemr = ioremap_nocache(MODEMR, 4); + u32 mode; + + BUG_ON(!modemr); + mode = ioread32(modemr); + iounmap(modemr); + + return mode; +} + +static int __init r8a7795_cpg_mssr_init(struct device *dev) +{ + u32 cpg_mode = rcar_gen3_read_mode_pins(); + + cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; + if (!cpg_pll_config->extal_div) { + dev_err(dev, "Prohibited setting (cpg_mode=0x%x)\n", cpg_mode); + return -EINVAL; + } + + return 0; +} + +const struct cpg_mssr_info r8a7795_cpg_mssr_info __initconst = { + /* Core Clocks */ + .core_clks = r8a7795_core_clks, + .num_core_clks = ARRAY_SIZE(r8a7795_core_clks), + .last_dt_core_clk = LAST_DT_CORE_CLK, + .num_total_core_clks = MOD_CLK_BASE, + + /* Module Clocks */ + .mod_clks = r8a7795_mod_clks, + .num_mod_clks = ARRAY_SIZE(r8a7795_mod_clks), + .num_hw_mod_clks = 12 * 32, + + /* Critical Module Clocks */ + .crit_mod_clks = r8a7795_crit_mod_clks, + .num_crit_mod_clks = ARRAY_SIZE(r8a7795_crit_mod_clks), + + /* Callbacks */ + .init = r8a7795_cpg_mssr_init, + .cpg_clk_register = r8a7795_cpg_clk_register, +}; diff --git a/drivers/clk/shmobile/renesas-cpg-mssr.c b/drivers/clk/shmobile/renesas-cpg-mssr.c new file mode 100644 index 000000000000..9a4d888164bb --- /dev/null +++ b/drivers/clk/shmobile/renesas-cpg-mssr.c @@ -0,0 +1,596 @@ +/* + * Renesas Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2015 Glider bvba + * + * Based on clk-mstp.c, clk-rcar-gen2.c, and clk-rcar-gen3.c + * + * Copyright (C) 2013 Ideas On Board SPRL + * Copyright (C) 2015 Renesas Electronics Corp. + * + * 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; version 2 of the License. + */ + +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/device.h> +#include <linux/init.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/pm_clock.h> +#include <linux/pm_domain.h> +#include <linux/slab.h> + +#include <dt-bindings/clock/renesas-cpg-mssr.h> + +#include "renesas-cpg-mssr.h" +#include "clk-div6.h" + +#ifdef DEBUG +#define WARN_DEBUG(x) do { } while (0) +#else +#define WARN_DEBUG(x) WARN_ON(x) +#endif + + +/* + * Module Standby and Software Reset register offets. + * + * If the registers exist, these are valid for SH-Mobile, R-Mobile, + * R-Car Gen 2, and R-Car Gen 3. + * These are NOT valid for R-Car Gen1 and RZ/A1! + */ + +/* + * Module Stop Status Register offsets + */ + +static const u16 mstpsr[] = { + 0x030, 0x038, 0x040, 0x048, 0x04C, 0x03C, 0x1C0, 0x1C4, + 0x9A0, 0x9A4, 0x9A8, 0x9AC, +}; + +#define MSTPSR(i) mstpsr[i] + + +/* + * System Module Stop Control Register offsets + */ + +static const u16 smstpcr[] = { + 0x130, 0x134, 0x138, 0x13C, 0x140, 0x144, 0x148, 0x14C, + 0x990, 0x994, 0x998, 0x99C, +}; + +#define SMSTPCR(i) smstpcr[i] + + +/* + * Software Reset Register offsets + */ + +static const u16 srcr[] = { + 0x0A0, 0x0A8, 0x0B0, 0x0B8, 0x0BC, 0x0C4, 0x1C8, 0x1CC, + 0x920, 0x924, 0x928, 0x92C, +}; + +#define SRCR(i) srcr[i] + + +/* Realtime Module Stop Control Register offsets */ +#define RMSTPCR(i) (smstpcr[i] - 0x20) + +/* Modem Module Stop Control Register offsets (r8a73a4) */ +#define MMSTPCR(i) (smstpcr[i] + 0x20) + +/* Software Reset Clearing Register offsets */ +#define SRSTCLR(i) (0x940 + (i) * 4) + + +/** + * Clock Pulse Generator / Module Standby and Software Reset Private Data + * + * @dev: CPG/MSSR device + * @base: CPG/MSSR register block base address + * @mstp_lock: protects writes to SMSTPCR + * @clks: Array containing all Core and Module Clocks + * @num_core_clks: Number of Core Clocks in clks[] + * @num_mod_clks: Number of Module Clocks in clks[] + * @last_dt_core_clk: ID of the last Core Clock exported to DT + */ +struct cpg_mssr_priv { + struct device *dev; + void __iomem *base; + spinlock_t mstp_lock; + + struct clk **clks; + unsigned int num_core_clks; + unsigned int num_mod_clks; + unsigned int last_dt_core_clk; +}; + + +/** + * struct mstp_clock - MSTP gating clock + * @hw: handle between common and hardware-specific interfaces + * @index: MSTP clock number + * @priv: CPG/MSSR private data + */ +struct mstp_clock { + struct clk_hw hw; + u32 index; + struct cpg_mssr_priv *priv; +}; + +#define to_mstp_clock(_hw) container_of(_hw, struct mstp_clock, hw) + +static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) +{ + struct mstp_clock *clock = to_mstp_clock(hw); + struct cpg_mssr_priv *priv = clock->priv; + unsigned int reg = clock->index / 32; + unsigned int bit = clock->index % 32; + struct device *dev = priv->dev; + u32 bitmask = BIT(bit); + unsigned long flags; + unsigned int i; + u32 value; + + dev_dbg(dev, "MSTP %u%02u/%pC %s\n", reg, bit, hw->clk, + enable ? "ON" : "OFF"); + spin_lock_irqsave(&priv->mstp_lock, flags); + + value = clk_readl(priv->base + SMSTPCR(reg)); + if (enable) + value &= ~bitmask; + else + value |= bitmask; + clk_writel(value, priv->base + SMSTPCR(reg)); + + spin_unlock_irqrestore(&priv->mstp_lock, flags); + + if (!enable) + return 0; + + for (i = 1000; i > 0; --i) { + if (!(clk_readl(priv->base + MSTPSR(reg)) & + bitmask)) + break; + cpu_relax(); + } + + if (!i) { + dev_err(dev, "Failed to enable SMSTP %p[%d]\n", + priv->base + SMSTPCR(reg), bit); + return -ETIMEDOUT; + } + + return 0; +} + +static int cpg_mstp_clock_enable(struct clk_hw *hw) +{ + return cpg_mstp_clock_endisable(hw, true); +} + +static void cpg_mstp_clock_disable(struct clk_hw *hw) +{ + cpg_mstp_clock_endisable(hw, false); +} + +static int cpg_mstp_clock_is_enabled(struct clk_hw *hw) +{ + struct mstp_clock *clock = to_mstp_clock(hw); + struct cpg_mssr_priv *priv = clock->priv; + u32 value; + + value = clk_readl(priv->base + MSTPSR(clock->index / 32)); + + return !(value & BIT(clock->index % 32)); +} + +static const struct clk_ops cpg_mstp_clock_ops = { + .enable = cpg_mstp_clock_enable, + .disable = cpg_mstp_clock_disable, + .is_enabled = cpg_mstp_clock_is_enabled, +}; + +static +struct clk *cpg_mssr_clk_src_twocell_get(struct of_phandle_args *clkspec, + void *data) +{ + unsigned int clkidx = clkspec->args[1]; + struct cpg_mssr_priv *priv = data; + struct device *dev = priv->dev; + unsigned int idx; + const char *type; + struct clk *clk; + + switch (clkspec->args[0]) { + case CPG_CORE: + type = "core"; + if (clkidx > priv->last_dt_core_clk) { + dev_err(dev, "Invalid %s clock index %u\n", type, + clkidx); + return ERR_PTR(-EINVAL); + } + clk = priv->clks[clkidx]; + break; + + case CPG_MOD: + type = "module"; + idx = MOD_CLK_PACK(clkidx); + if (clkidx % 100 > 31 || idx >= priv->num_mod_clks) { + dev_err(dev, "Invalid %s clock index %u\n", type, + clkidx); + return ERR_PTR(-EINVAL); + } + clk = priv->clks[priv->num_core_clks + idx]; + break; + + default: + dev_err(dev, "Invalid CPG clock type %u\n", clkspec->args[0]); + return ERR_PTR(-EINVAL); + } + + if (IS_ERR(clk)) + dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx, + PTR_ERR(clk)); + else + dev_dbg(dev, "clock (%u, %u) is %pC at %pCr Hz\n", + clkspec->args[0], clkspec->args[1], clk, clk); + return clk; +} + +static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, + const struct cpg_mssr_info *info, + struct cpg_mssr_priv *priv) +{ + struct clk *clk = NULL, *parent; + struct device *dev = priv->dev; + unsigned int id = core->id; + const char *parent_name; + + WARN_DEBUG(id >= priv->num_core_clks); + WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); + + switch (core->type) { + case CLK_TYPE_IN: + clk = of_clk_get_by_name(priv->dev->of_node, core->name); + break; + + case CLK_TYPE_FF: + case CLK_TYPE_DIV6P1: + WARN_DEBUG(core->parent >= priv->num_core_clks); + parent = priv->clks[core->parent]; + if (IS_ERR(parent)) { + clk = parent; + goto fail; + } + + parent_name = __clk_get_name(parent); + if (core->type == CLK_TYPE_FF) { + clk = clk_register_fixed_factor(NULL, core->name, + parent_name, 0, + core->mult, core->div); + } else { + clk = cpg_div6_register(core->name, 1, &parent_name, + priv->base + core->offset); + } + break; + + default: + if (info->cpg_clk_register) + clk = info->cpg_clk_register(dev, core, info, + priv->clks, priv->base); + else + dev_err(dev, "%s has unsupported core clock type %u\n", + core->name, core->type); + break; + } + + if (IS_ERR_OR_NULL(clk)) + goto fail; + + dev_dbg(dev, "Core clock %pC at %pCr Hz\n", clk, clk); + priv->clks[id] = clk; + return; + +fail: + dev_err(dev, "Failed to register %s clock %s: %ld\n", "core,", + core->name, PTR_ERR(clk)); +} + +static void __init cpg_mssr_register_mod_clk(const struct mssr_mod_clk *mod, + const struct cpg_mssr_info *info, + struct cpg_mssr_priv *priv) +{ + struct mstp_clock *clock = NULL; + struct device *dev = priv->dev; + unsigned int id = mod->id; + struct clk_init_data init; + struct clk *parent, *clk; + const char *parent_name; + unsigned int i; + + WARN_DEBUG(id < priv->num_core_clks); + WARN_DEBUG(id >= priv->num_core_clks + priv->num_mod_clks); + WARN_DEBUG(mod->parent >= priv->num_core_clks + priv->num_mod_clks); + WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); + + parent = priv->clks[mod->parent]; + if (IS_ERR(parent)) { + clk = parent; + goto fail; + } + + clock = kzalloc(sizeof(*clock), GFP_KERNEL); + if (!clock) { + clk = ERR_PTR(-ENOMEM); + goto fail; + } + + init.name = mod->name; + init.ops = &cpg_mstp_clock_ops; + init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; + for (i = 0; i < info->num_crit_mod_clks; i++) + if (id == info->crit_mod_clks[i]) { +#ifdef CLK_ENABLE_HAND_OFF + dev_dbg(dev, "MSTP %s setting CLK_ENABLE_HAND_OFF\n", + mod->name); + init.flags |= CLK_ENABLE_HAND_OFF; + break; +#else + dev_dbg(dev, "Ignoring MSTP %s to prevent disabling\n", + mod->name); + return; +#endif + } + + parent_name = __clk_get_name(parent); + init.parent_names = &parent_name; + init.num_parents = 1; + + clock->index = id - priv->num_core_clks; + clock->priv = priv; + clock->hw.init = &init; + + clk = clk_register(NULL, &clock->hw); + if (IS_ERR(clk)) + goto fail; + + dev_dbg(dev, "Module clock %pC at %pCr Hz\n", clk, clk); + priv->clks[id] = clk; + return; + +fail: + dev_err(dev, "Failed to register %s clock %s: %ld\n", "module,", + mod->name, PTR_ERR(clk)); + kfree(clock); +} + + +#ifdef CONFIG_PM_GENERIC_DOMAINS_OF +struct cpg_mssr_clk_domain { + struct generic_pm_domain genpd; + struct device_node *np; + unsigned int num_core_pm_clks; + unsigned int core_pm_clks[0]; +}; + +static bool cpg_mssr_is_pm_clk(const struct of_phandle_args *clkspec, + struct cpg_mssr_clk_domain *pd) +{ + unsigned int i; + + if (clkspec->np != pd->np || clkspec->args_count != 2) + return false; + + switch (clkspec->args[0]) { + case CPG_CORE: + for (i = 0; i < pd->num_core_pm_clks; i++) + if (clkspec->args[1] == pd->core_pm_clks[i]) + return true; + return false; + + case CPG_MOD: + return true; + + default: + return false; + } +} + +static int cpg_mssr_attach_dev(struct generic_pm_domain *genpd, + struct device *dev) +{ + struct cpg_mssr_clk_domain *pd = + container_of(genpd, struct cpg_mssr_clk_domain, genpd); + struct device_node *np = dev->of_node; + struct of_phandle_args clkspec; + struct clk *clk; + int i = 0; + int error; + + while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i, + &clkspec)) { + if (cpg_mssr_is_pm_clk(&clkspec, pd)) + goto found; + + of_node_put(clkspec.np); + i++; + } + + return 0; + +found: + clk = of_clk_get_from_provider(&clkspec); + of_node_put(clkspec.np); + + if (IS_ERR(clk)) + return PTR_ERR(clk); + + error = pm_clk_create(dev); + if (error) { + dev_err(dev, "pm_clk_create failed %d\n", error); + goto fail_put; + } + + error = pm_clk_add_clk(dev, clk); + if (error) { + dev_err(dev, "pm_clk_add_clk %pC failed %d\n", clk, error); + goto fail_destroy; + } + + return 0; + +fail_destroy: + pm_clk_destroy(dev); +fail_put: + clk_put(clk); + return error; +} + +static void cpg_mssr_detach_dev(struct generic_pm_domain *genpd, + struct device *dev) +{ + if (!list_empty(&dev->power.subsys_data->clock_list)) + pm_clk_destroy(dev); +} + +static int __init cpg_mssr_add_clk_domain(struct device *dev, + const unsigned int *core_pm_clks, + unsigned int num_core_pm_clks) +{ + struct device_node *np = dev->of_node; + struct generic_pm_domain *genpd; + struct cpg_mssr_clk_domain *pd; + size_t pm_size = num_core_pm_clks * sizeof(core_pm_clks[0]); + + pd = devm_kzalloc(dev, sizeof(*pd) + pm_size, GFP_KERNEL); + if (!pd) + return -ENOMEM; + + pd->np = np; + pd->num_core_pm_clks = num_core_pm_clks; + memcpy(pd->core_pm_clks, core_pm_clks, pm_size); + + genpd = &pd->genpd; + genpd->name = np->name; + genpd->flags = GENPD_FLAG_PM_CLK; + pm_genpd_init(genpd, &simple_qos_governor, false); + genpd->attach_dev = cpg_mssr_attach_dev; + genpd->detach_dev = cpg_mssr_detach_dev; + + of_genpd_add_provider_simple(np, genpd); + return 0; +} +#else +static inline int cpg_mssr_add_clk_domain(struct device *dev, + const unsigned int *core_pm_clks, + unsigned int num_core_pm_clks) +{ + return 0; +} +#endif /* !CONFIG_PM_GENERIC_DOMAINS_OF */ + + +static const struct of_device_id cpg_mssr_match[] = { +#ifdef CONFIG_ARCH_R8A7795 + { + .compatible = "renesas,r8a7795-cpg-mssr", + .data = &r8a7795_cpg_mssr_info, + }, +#endif + { /* sentinel */ } +}; + +static void cpg_mssr_del_clk_provider(void *data) +{ + of_clk_del_provider(data); +} + +static int __init cpg_mssr_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + const struct cpg_mssr_info *info; + struct cpg_mssr_priv *priv; + unsigned int nclks, i; + struct resource *res; + struct clk **clks; + int error; + + info = of_match_node(cpg_mssr_match, np)->data; + if (info->init) { + error = info->init(dev); + if (error) + return error; + } + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->dev = dev; + spin_lock_init(&priv->mstp_lock); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + priv->base = devm_ioremap_resource(dev, res); + if (IS_ERR(priv->base)) + return PTR_ERR(priv->base); + + nclks = info->num_total_core_clks + info->num_hw_mod_clks; + clks = devm_kmalloc_array(dev, nclks, sizeof(*clks), GFP_KERNEL); + if (!clks) + return -ENOMEM; + + priv->clks = clks; + priv->num_core_clks = info->num_total_core_clks; + priv->num_mod_clks = info->num_hw_mod_clks; + priv->last_dt_core_clk = info->last_dt_core_clk; + + for (i = 0; i < nclks; i++) + clks[i] = ERR_PTR(-ENOENT); + + for (i = 0; i < info->num_core_clks; i++) + cpg_mssr_register_core_clk(&info->core_clks[i], info, priv); + + for (i = 0; i < info->num_mod_clks; i++) + cpg_mssr_register_mod_clk(&info->mod_clks[i], info, priv); + + error = of_clk_add_provider(np, cpg_mssr_clk_src_twocell_get, priv); + if (error) + return error; + + devm_add_action(dev, cpg_mssr_del_clk_provider, np); + + error = cpg_mssr_add_clk_domain(dev, info->core_pm_clks, + info->num_core_pm_clks); + if (error) + return error; + + return 0; +} + +static struct platform_driver cpg_mssr_driver = { + .driver = { + .name = "renesas-cpg-mssr", + .of_match_table = cpg_mssr_match, + }, +}; + +static int __init cpg_mssr_init(void) +{ + return platform_driver_probe(&cpg_mssr_driver, cpg_mssr_probe); +} + +subsys_initcall(cpg_mssr_init); + +MODULE_DESCRIPTION("Renesas CPG/MSSR Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/shmobile/renesas-cpg-mssr.h b/drivers/clk/shmobile/renesas-cpg-mssr.h new file mode 100644 index 000000000000..e09f03cbf086 --- /dev/null +++ b/drivers/clk/shmobile/renesas-cpg-mssr.h @@ -0,0 +1,132 @@ +/* + * Renesas Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2015 Glider bvba + * + * 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; version 2 of the License. + */ + +#ifndef __CLK_RENESAS_CPG_MSSR_H__ +#define __CLK_RENESAS_CPG_MSSR_H__ + + /* + * Definitions of CPG Core Clocks + * + * These include: + * - Clock outputs exported to DT + * - External input clocks + * - Internal CPG clocks + */ + +struct cpg_core_clk { + /* Common */ + const char *name; + unsigned int id; + unsigned int type; + /* Depending on type */ + unsigned int parent; /* Core Clocks only */ + unsigned int div; + unsigned int mult; + unsigned int offset; +}; + +enum clk_types { + /* Generic */ + CLK_TYPE_IN, /* External Clock Input */ + CLK_TYPE_FF, /* Fixed Factor Clock */ + CLK_TYPE_DIV6P1, /* DIV6 Clock with 1 parent clock */ + + /* Custom definitions start here */ + CLK_TYPE_CUSTOM, +}; + +#define DEF_TYPE(_name, _id, _type...) \ + { .name = _name, .id = _id, .type = _type } +#define DEF_BASE(_name, _id, _type, _parent...) \ + DEF_TYPE(_name, _id, _type, .parent = _parent) + +#define DEF_INPUT(_name, _id) \ + DEF_TYPE(_name, _id, CLK_TYPE_IN) +#define DEF_FIXED(_name, _id, _parent, _div, _mult) \ + DEF_BASE(_name, _id, CLK_TYPE_FF, _parent, .div = _div, .mult = _mult) +#define DEF_DIV6P1(_name, _id, _parent, _offset) \ + DEF_BASE(_name, _id, CLK_TYPE_DIV6P1, _parent, .offset = _offset) + + + /* + * Definitions of Module Clocks + */ + +struct mssr_mod_clk { + const char *name; + unsigned int id; + unsigned int parent; /* Add MOD_CLK_BASE for Module Clocks */ +}; + +/* Convert from sparse base-100 to packed index space */ +#define MOD_CLK_PACK(x) ((x) - ((x) / 100) * (100 - 32)) + +#define MOD_CLK_ID(x) (MOD_CLK_BASE + MOD_CLK_PACK(x)) + +#define DEF_MOD(_name, _mod, _parent...) \ + { .name = _name, .id = MOD_CLK_ID(_mod), .parent = _parent } + + +struct device_node; + + /** + * SoC-specific CPG/MSSR Description + * + * @core_clks: Array of Core Clock definitions + * @num_core_clks: Number of entries in core_clks[] + * @last_dt_core_clk: ID of the last Core Clock exported to DT + * @num_total_core_clks: Total number of Core Clocks (exported + internal) + * + * @mod_clks: Array of Module Clock definitions + * @num_mod_clks: Number of entries in mod_clks[] + * @num_hw_mod_clks: Number of Module Clocks supported by the hardware + * + * @crit_mod_clks: Array with Module Clock IDs of critical clocks that + * should not be disabled without a knowledgeable driver + * @num_crit_mod_clks: Number of entries in crit_mod_clks[] + * + * @core_pm_clks: Array with IDs of Core Clocks that are suitable for Power + * Management, in addition to Module Clocks + * @num_core_pm_clks: Number of entries in core_pm_clks[] + * + * @init: Optional callback to perform SoC-specific initialization + * @cpg_clk_register: Optional callback to handle special Core Clock types + */ + +struct cpg_mssr_info { + /* Core Clocks */ + const struct cpg_core_clk *core_clks; + unsigned int num_core_clks; + unsigned int last_dt_core_clk; + unsigned int num_total_core_clks; + + /* Module Clocks */ + const struct mssr_mod_clk *mod_clks; + unsigned int num_mod_clks; + unsigned int num_hw_mod_clks; + + /* Critical Module Clocks that should not be disabled */ + const unsigned int *crit_mod_clks; + unsigned int num_crit_mod_clks; + + /* Core Clocks suitable for PM, in addition to the Module Clocks */ + const unsigned int *core_pm_clks; + unsigned int num_core_pm_clks; + + /* Callbacks */ + int (*init)(struct device *dev); + struct clk *(*cpg_clk_register)(struct device *dev, + const struct cpg_core_clk *core, + const struct cpg_mssr_info *info, + struct clk **clks, void __iomem *base); +}; + +extern const struct cpg_mssr_info r8a7795_cpg_mssr_info; +#endif diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c index 576cd0354d48..ccb324d97160 100644 --- a/drivers/clk/st/clkgen-fsyn.c +++ b/drivers/clk/st/clkgen-fsyn.c @@ -549,19 +549,20 @@ static int clk_fs660c32_vco_get_params(unsigned long input, return 0; } -static long quadfs_pll_fs660c32_round_rate(struct clk_hw *hw, unsigned long rate - , unsigned long *prate) +static long quadfs_pll_fs660c32_round_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long *prate) { struct stm_fs params; - if (!clk_fs660c32_vco_get_params(*prate, rate, ¶ms)) - clk_fs660c32_vco_get_rate(*prate, ¶ms, &rate); + if (clk_fs660c32_vco_get_params(*prate, rate, ¶ms)) + return rate; - pr_debug("%s: %s new rate %ld [sdiv=0x%x,md=0x%x,pe=0x%x,nsdiv3=%u]\n", + clk_fs660c32_vco_get_rate(*prate, ¶ms, &rate); + + pr_debug("%s: %s new rate %ld [ndiv=%u]\n", __func__, clk_hw_get_name(hw), - rate, (unsigned int)params.sdiv, - (unsigned int)params.mdiv, - (unsigned int)params.pe, (unsigned int)params.nsdiv); + rate, (unsigned int)params.ndiv); return rate; } diff --git a/drivers/clk/sunxi/clk-a10-pll2.c b/drivers/clk/sunxi/clk-a10-pll2.c index 5484c31ec568..0ee1f363e4be 100644 --- a/drivers/clk/sunxi/clk-a10-pll2.c +++ b/drivers/clk/sunxi/clk-a10-pll2.c @@ -41,15 +41,10 @@ #define SUN4I_PLL2_OUTPUTS 4 -struct sun4i_pll2_data { - u32 post_div_offset; - u32 pre_div_flags; -}; - static DEFINE_SPINLOCK(sun4i_a10_pll2_lock); static void __init sun4i_pll2_setup(struct device_node *node, - struct sun4i_pll2_data *data) + int post_div_offset) { const char *clk_name = node->name, *parent; struct clk **clks, *base_clk, *prediv_clk; @@ -76,7 +71,7 @@ static void __init sun4i_pll2_setup(struct device_node *node, parent, 0, reg, SUN4I_PLL2_PRE_DIV_SHIFT, SUN4I_PLL2_PRE_DIV_WIDTH, - data->pre_div_flags, + CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, &sun4i_a10_pll2_lock); if (!prediv_clk) { pr_err("Couldn't register the prediv clock\n"); @@ -127,7 +122,7 @@ static void __init sun4i_pll2_setup(struct device_node *node, */ val = readl(reg); val &= ~(SUN4I_PLL2_POST_DIV_MASK << SUN4I_PLL2_POST_DIV_SHIFT); - val |= (SUN4I_PLL2_POST_DIV_VALUE - data->post_div_offset) << SUN4I_PLL2_POST_DIV_SHIFT; + val |= (SUN4I_PLL2_POST_DIV_VALUE - post_div_offset) << SUN4I_PLL2_POST_DIV_SHIFT; writel(val, reg); of_property_read_string_index(node, "clock-output-names", @@ -191,25 +186,17 @@ err_unmap: iounmap(reg); } -static struct sun4i_pll2_data sun4i_a10_pll2_data = { - .pre_div_flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, -}; - static void __init sun4i_a10_pll2_setup(struct device_node *node) { - sun4i_pll2_setup(node, &sun4i_a10_pll2_data); + sun4i_pll2_setup(node, 0); } CLK_OF_DECLARE(sun4i_a10_pll2, "allwinner,sun4i-a10-pll2-clk", sun4i_a10_pll2_setup); -static struct sun4i_pll2_data sun5i_a13_pll2_data = { - .post_div_offset = 1, -}; - static void __init sun5i_a13_pll2_setup(struct device_node *node) { - sun4i_pll2_setup(node, &sun5i_a13_pll2_data); + sun4i_pll2_setup(node, 1); } CLK_OF_DECLARE(sun5i_a13_pll2, "allwinner,sun5i-a13-pll2-clk", diff --git a/drivers/clk/ti/apll.c b/drivers/clk/ti/apll.c index f3eab6e79027..b336a8c11e2a 100644 --- a/drivers/clk/ti/apll.c +++ b/drivers/clk/ti/apll.c @@ -323,7 +323,7 @@ static void omap2_apll_deny_idle(struct clk_hw_omap *clk) omap2_apll_set_autoidle(clk, OMAP2_APLL_AUTOIDLE_DISABLE); } -static struct clk_hw_omap_ops omap2_apll_hwops = { +static const struct clk_hw_omap_ops omap2_apll_hwops = { .allow_idle = &omap2_apll_allow_idle, .deny_idle = &omap2_apll_deny_idle, }; diff --git a/drivers/clk/ti/clk-816x.c b/drivers/clk/ti/clk-816x.c index 1dfad0c712cd..2a5d84fdddc5 100644 --- a/drivers/clk/ti/clk-816x.c +++ b/drivers/clk/ti/clk-816x.c @@ -20,6 +20,8 @@ static struct ti_dt_clk dm816x_clks[] = { DT_CLK(NULL, "sys_clkin", "sys_clkin_ck"), DT_CLK(NULL, "timer_sys_ck", "sys_clkin_ck"), DT_CLK(NULL, "sys_32k_ck", "sys_32k_ck"), + DT_CLK(NULL, "timer_32k_ck", "sysclk18_ck"), + DT_CLK(NULL, "timer_ext_ck", "tclkin_ck"), DT_CLK(NULL, "mpu_ck", "mpu_ck"), DT_CLK(NULL, "timer1_fck", "timer1_fck"), DT_CLK(NULL, "timer2_fck", "timer2_fck"), diff --git a/drivers/clk/ti/clkt_dpll.c b/drivers/clk/ti/clkt_dpll.c index 9023ca9caf84..b5cc6f66ae5d 100644 --- a/drivers/clk/ti/clkt_dpll.c +++ b/drivers/clk/ti/clkt_dpll.c @@ -240,7 +240,7 @@ u8 omap2_init_dpll_parent(struct clk_hw *hw) */ unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk) { - long long dpll_clk; + u64 dpll_clk; u32 dpll_mult, dpll_div, v; struct dpll_data *dd; @@ -262,7 +262,7 @@ unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk) dpll_div = v & dd->div1_mask; dpll_div >>= __ffs(dd->div1_mask); - dpll_clk = (long long)clk_get_rate(dd->clk_ref) * dpll_mult; + dpll_clk = (u64)clk_get_rate(dd->clk_ref) * dpll_mult; do_div(dpll_clk, dpll_div + 1); return dpll_clk; diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c index 5b1726829e6d..df2558350fc1 100644 --- a/drivers/clk/ti/divider.c +++ b/drivers/clk/ti/divider.c @@ -214,7 +214,6 @@ static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, { struct clk_divider *divider; unsigned int div, value; - unsigned long flags = 0; u32 val; if (!hw || !rate) @@ -228,9 +227,6 @@ static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, if (value > div_mask(divider)) value = div_mask(divider); - if (divider->lock) - spin_lock_irqsave(divider->lock, flags); - if (divider->flags & CLK_DIVIDER_HIWORD_MASK) { val = div_mask(divider) << (divider->shift + 16); } else { @@ -240,9 +236,6 @@ static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, val |= value << divider->shift; ti_clk_ll_ops->clk_writel(val, divider->reg); - if (divider->lock) - spin_unlock_irqrestore(divider->lock, flags); - return 0; } @@ -256,8 +249,7 @@ static struct clk *_register_divider(struct device *dev, const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags, - const struct clk_div_table *table, - spinlock_t *lock) + const struct clk_div_table *table) { struct clk_divider *div; struct clk *clk; @@ -288,7 +280,6 @@ static struct clk *_register_divider(struct device *dev, const char *name, div->shift = shift; div->width = width; div->flags = clk_divider_flags; - div->lock = lock; div->hw.init = &init; div->table = table; @@ -421,7 +412,7 @@ struct clk *ti_clk_register_divider(struct ti_clk *setup) clk = _register_divider(NULL, setup->name, div->parent, flags, (void __iomem *)reg, div->bit_shift, - width, div_flags, table, NULL); + width, div_flags, table); if (IS_ERR(clk)) kfree(table); @@ -584,8 +575,7 @@ static void __init of_ti_divider_clk_setup(struct device_node *node) goto cleanup; clk = _register_divider(NULL, node->name, parent_name, flags, reg, - shift, width, clk_divider_flags, table, - NULL); + shift, width, clk_divider_flags, table); if (!IS_ERR(clk)) { of_clk_add_provider(node, of_clk_src_simple_get, clk); diff --git a/drivers/clk/ti/dpll3xxx.c b/drivers/clk/ti/dpll3xxx.c index f4dec00fb684..1c300388782b 100644 --- a/drivers/clk/ti/dpll3xxx.c +++ b/drivers/clk/ti/dpll3xxx.c @@ -305,8 +305,9 @@ static void _lookup_sddiv(struct clk_hw_omap *clk, u8 *sd_div, u16 m, u8 n) static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, u16 freqsel) { struct dpll_data *dd = clk->dpll_data; - u8 dco, sd_div; + u8 dco, sd_div, ai = 0; u32 v; + bool errata_i810; /* 3430 ES2 TRM: 4.7.6.9 DPLL Programming Sequence */ _omap3_noncore_dpll_bypass(clk); @@ -350,6 +351,25 @@ static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, u16 freqsel) v |= sd_div << __ffs(dd->sddiv_mask); } + /* + * Errata i810 - DPLL controller can get stuck while transitioning + * to a power saving state. Software must ensure the DPLL can not + * transition to a low power state while changing M/N values. + * Easiest way to accomplish this is to prevent DPLL autoidle + * before doing the M/N re-program. + */ + errata_i810 = ti_clk_get_features()->flags & TI_CLK_ERRATA_I810; + + if (errata_i810) { + ai = omap3_dpll_autoidle_read(clk); + if (ai) { + omap3_dpll_deny_idle(clk); + + /* OCP barrier */ + omap3_dpll_autoidle_read(clk); + } + } + ti_clk_ll_ops->clk_writel(v, dd->mult_div1_reg); /* Set 4X multiplier and low-power mode */ @@ -379,6 +399,9 @@ static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, u16 freqsel) _omap3_noncore_dpll_lock(clk); + if (errata_i810 && ai) + omap3_dpll_allow_idle(clk); + return 0; } diff --git a/drivers/clk/ti/fapll.c b/drivers/clk/ti/fapll.c index f4b2e9888bdf..66a0d0ed8b55 100644 --- a/drivers/clk/ti/fapll.c +++ b/drivers/clk/ti/fapll.c @@ -168,7 +168,7 @@ static unsigned long ti_fapll_recalc_rate(struct clk_hw *hw, { struct fapll_data *fd = to_fapll(hw); u32 fapll_n, fapll_p, v; - long long rate; + u64 rate; if (ti_fapll_clock_is_bypass(fd)) return parent_rate; @@ -314,7 +314,7 @@ static unsigned long ti_fapll_synth_recalc_rate(struct clk_hw *hw, { struct fapll_synth *synth = to_synth(hw); u32 synth_div_m; - long long rate; + u64 rate; /* The audio_pll_clk1 is hardwired to produce 32.768KiHz clock */ if (!synth->div) diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c index 69f08a1d047d..dab9ba88b9d6 100644 --- a/drivers/clk/ti/mux.c +++ b/drivers/clk/ti/mux.c @@ -69,7 +69,6 @@ static int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index) { struct clk_mux *mux = to_clk_mux(hw); u32 val; - unsigned long flags = 0; if (mux->table) { index = mux->table[index]; @@ -81,9 +80,6 @@ static int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index) index++; } - if (mux->lock) - spin_lock_irqsave(mux->lock, flags); - if (mux->flags & CLK_MUX_HIWORD_MASK) { val = mux->mask << (mux->shift + 16); } else { @@ -93,9 +89,6 @@ static int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index) val |= index << mux->shift; ti_clk_ll_ops->clk_writel(val, mux->reg); - if (mux->lock) - spin_unlock_irqrestore(mux->lock, flags); - return 0; } @@ -109,7 +102,7 @@ static struct clk *_register_mux(struct device *dev, const char *name, const char **parent_names, u8 num_parents, unsigned long flags, void __iomem *reg, u8 shift, u32 mask, u8 clk_mux_flags, - u32 *table, spinlock_t *lock) + u32 *table) { struct clk_mux *mux; struct clk *clk; @@ -133,7 +126,6 @@ static struct clk *_register_mux(struct device *dev, const char *name, mux->shift = shift; mux->mask = mask; mux->flags = clk_mux_flags; - mux->lock = lock; mux->table = table; mux->hw.init = &init; @@ -175,7 +167,7 @@ struct clk *ti_clk_register_mux(struct ti_clk *setup) return _register_mux(NULL, setup->name, mux->parents, mux->num_parents, flags, (void __iomem *)reg, mux->bit_shift, mask, - mux_flags, NULL, NULL); + mux_flags, NULL); } /** @@ -227,8 +219,7 @@ static void of_mux_clk_setup(struct device_node *node) mask = (1 << fls(mask)) - 1; clk = _register_mux(NULL, node->name, parent_names, num_parents, - flags, reg, shift, mask, clk_mux_flags, NULL, - NULL); + flags, reg, shift, mask, clk_mux_flags, NULL); if (!IS_ERR(clk)) of_clk_add_provider(node, of_clk_src_simple_get, clk); diff --git a/drivers/clk/versatile/clk-sp810.c b/drivers/clk/versatile/clk-sp810.c index a1cdef6b0f90..e78755e0ef78 100644 --- a/drivers/clk/versatile/clk-sp810.c +++ b/drivers/clk/versatile/clk-sp810.c @@ -95,13 +95,12 @@ static void __init clk_sp810_of_setup(struct device_node *node) int i; bool deprecated; - if (!sp810) { - pr_err("Failed to allocate memory for SP810!\n"); + if (!sp810) return; - } if (of_clk_parent_fill(node, parent_names, num) != num) { pr_warn("Failed to obtain parent clocks for SP810!\n"); + kfree(sp810); return; } |