diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-23 18:56:08 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-23 18:56:08 -0800 |
commit | 7e21774db5cc9cf8fe93a64a2f0c6cf47db8ab24 (patch) | |
tree | 460812792bc3b23789a83968b7bad840cc3eb047 /drivers | |
parent | 0ba3307a8ec35252f7b1e222e32889a6f3d9ceb3 (diff) | |
parent | 2e84d75116c17c2034e917b411250d2d11755435 (diff) | |
download | kernel-common-7e21774db5cc9cf8fe93a64a2f0c6cf47db8ab24.tar.gz kernel-common-7e21774db5cc9cf8fe93a64a2f0c6cf47db8ab24.tar.bz2 kernel-common-7e21774db5cc9cf8fe93a64a2f0c6cf47db8ab24.zip |
Merge tag 'clk-for-linus-3.14-part1' of git://git.linaro.org/people/mike.turquette/linux
Pull clk framework changes from Mike Turquette:
"The first half of the clk framework pull request is made up almost
entirely of new platform/driver support. There are some conversions
of existing drivers to the common-clock Device Tree binding, and a few
non-critical fixes to the framework.
Due to an entirely unnecessary cyclical dependency with the arm-soc
tree this pull request is broken into two pieces. The second piece
will be sent out after arm-soc sends you the pull request that merged
in core support for the HiSilicon 3620 platform. That same pull
request from arm-soc depends on this pull request to merge in those
HiSilicon bits without causing build failures"
[ Just did the ARM SoC merges, so getting ready for the second clk tree
pull request - Linus ]
* tag 'clk-for-linus-3.14-part1' of git://git.linaro.org/people/mike.turquette/linux: (97 commits)
devicetree: bindings: Document qcom,mmcc
devicetree: bindings: Document qcom,gcc
clk: qcom: Add support for MSM8660's global clock controller (GCC)
clk: qcom: Add support for MSM8974's multimedia clock controller (MMCC)
clk: qcom: Add support for MSM8974's global clock controller (GCC)
clk: qcom: Add support for MSM8960's multimedia clock controller (MMCC)
clk: qcom: Add support for MSM8960's global clock controller (GCC)
clk: qcom: Add reset controller support
clk: qcom: Add support for branches/gate clocks
clk: qcom: Add support for root clock generators (RCGs)
clk: qcom: Add support for phase locked loops (PLLs)
clk: qcom: Add a regmap type clock struct
clk: Add set_rate_and_parent() op
reset: Silence warning in reset-controller.h
clk: sirf: re-arch to make the codes support both prima2 and atlas6
clk: composite: pass mux_hw into determine_rate
clk: shmobile: Fix MSTP clock array initialization
clk: shmobile: Fix MSTP clock index
ARM: dts: Add clock provider specific properties to max77686 node
clk: max77686: Register OF clock provider
...
Diffstat (limited to 'drivers')
65 files changed, 19561 insertions, 1561 deletions
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 5c51115081b3..7641965d208d 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -23,16 +23,6 @@ config COMMON_CLK menu "Common Clock Framework" depends on COMMON_CLK -config COMMON_CLK_DEBUG - bool "DebugFS representation of clock tree" - select DEBUG_FS - ---help--- - Creates a directory hierarchy in debugfs for visualizing the clk - tree structure. Each directory contains read-only members - that export information specific to that clk node: clk_rate, - clk_flags, clk_prepare_count, clk_enable_count & - clk_notifier_count. - config COMMON_CLK_WM831X tristate "Clock driver for WM831x/2x PMICs" depends on MFD_WM831X @@ -64,6 +54,16 @@ config COMMON_CLK_SI5351 This driver supports Silicon Labs 5351A/B/C programmable clock generators. +config COMMON_CLK_SI570 + tristate "Clock driver for SiLabs 570 and compatible devices" + depends on I2C + depends on OF + select REGMAP_I2C + help + ---help--- + This driver supports Silicon Labs 570/571/598/599 programmable + clock generators. + config COMMON_CLK_S2MPS11 tristate "Clock driver for S2MPS11 MFD" depends on MFD_SEC_CORE @@ -107,6 +107,8 @@ config COMMON_CLK_KEYSTONE Supports clock drivers for Keystone based SOCs. These SOCs have local a power sleep control module that gate the clock to the IPs and PLLs. +source "drivers/clk/qcom/Kconfig" + endmenu source "drivers/clk/mvebu/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index a3b7c5dd3c16..0c16e9cdfb87 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -14,13 +14,14 @@ obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o +obj-$(CONFIG_ARCH_HI3xxx) += hisilicon/ obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o obj-$(CONFIG_ARCH_MXS) += mxs/ obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/ obj-$(CONFIG_PLAT_SPEAR) += spear/ obj-$(CONFIG_ARCH_U300) += clk-u300.o obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/ -obj-$(CONFIG_ARCH_SIRF) += clk-prima2.o +obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/ obj-$(CONFIG_PLAT_ORION) += mvebu/ ifeq ($(CONFIG_COMMON_CLK), y) obj-$(CONFIG_ARCH_MMP) += mmp/ @@ -30,6 +31,7 @@ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ obj-$(CONFIG_ARCH_SUNXI) += sunxi/ obj-$(CONFIG_ARCH_U8500) += ux500/ obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o +obj-$(CONFIG_ARCH_SIRF) += sirf/ obj-$(CONFIG_ARCH_ZYNQ) += zynq/ obj-$(CONFIG_ARCH_TEGRA) += tegra/ obj-$(CONFIG_PLAT_SAMSUNG) += samsung/ @@ -45,6 +47,7 @@ obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o +obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o obj-$(CONFIG_CLK_PPC_CORENET) += clk-ppc-corenet.o diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c index a33f46f20a41..57a078e06efe 100644 --- a/drivers/clk/clk-composite.c +++ b/drivers/clk/clk-composite.c @@ -55,6 +55,30 @@ static unsigned long clk_composite_recalc_rate(struct clk_hw *hw, return rate_ops->recalc_rate(rate_hw, parent_rate); } +static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *best_parent_rate, + struct clk **best_parent_p) +{ + struct clk_composite *composite = to_clk_composite(hw); + const struct clk_ops *rate_ops = composite->rate_ops; + const struct clk_ops *mux_ops = composite->mux_ops; + struct clk_hw *rate_hw = composite->rate_hw; + struct clk_hw *mux_hw = composite->mux_hw; + + if (rate_hw && rate_ops && rate_ops->determine_rate) { + rate_hw->clk = hw->clk; + return rate_ops->determine_rate(rate_hw, rate, best_parent_rate, + best_parent_p); + } else if (mux_hw && mux_ops && mux_ops->determine_rate) { + mux_hw->clk = hw->clk; + return mux_ops->determine_rate(mux_hw, rate, best_parent_rate, + best_parent_p); + } else { + pr_err("clk: clk_composite_determine_rate function called, but no mux or rate callback set!\n"); + return 0; + } +} + static long clk_composite_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate) { @@ -147,6 +171,8 @@ struct clk *clk_register_composite(struct device *dev, const char *name, composite->mux_ops = mux_ops; clk_composite_ops->get_parent = clk_composite_get_parent; clk_composite_ops->set_parent = clk_composite_set_parent; + if (mux_ops->determine_rate) + clk_composite_ops->determine_rate = clk_composite_determine_rate; } if (rate_hw && rate_ops) { @@ -170,6 +196,8 @@ struct clk *clk_register_composite(struct device *dev, const char *name, composite->rate_hw = rate_hw; composite->rate_ops = rate_ops; clk_composite_ops->recalc_rate = clk_composite_recalc_rate; + if (rate_ops->determine_rate) + clk_composite_ops->determine_rate = clk_composite_determine_rate; } if (gate_hw && gate_ops) { diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c index 1ed591ab8b1d..0fc56ab6e844 100644 --- a/drivers/clk/clk-fixed-rate.c +++ b/drivers/clk/clk-fixed-rate.c @@ -34,22 +34,31 @@ static unsigned long clk_fixed_rate_recalc_rate(struct clk_hw *hw, return to_clk_fixed_rate(hw)->fixed_rate; } +static unsigned long clk_fixed_rate_recalc_accuracy(struct clk_hw *hw, + unsigned long parent_accuracy) +{ + return to_clk_fixed_rate(hw)->fixed_accuracy; +} + const struct clk_ops clk_fixed_rate_ops = { .recalc_rate = clk_fixed_rate_recalc_rate, + .recalc_accuracy = clk_fixed_rate_recalc_accuracy, }; EXPORT_SYMBOL_GPL(clk_fixed_rate_ops); /** - * clk_register_fixed_rate - register fixed-rate clock with the clock framework + * clk_register_fixed_rate_with_accuracy - register fixed-rate clock with the + * clock framework * @dev: device that is registering this clock * @name: name of this clock * @parent_name: name of clock's parent * @flags: framework-specific flags * @fixed_rate: non-adjustable clock rate + * @fixed_accuracy: non-adjustable clock rate */ -struct clk *clk_register_fixed_rate(struct device *dev, const char *name, - const char *parent_name, unsigned long flags, - unsigned long fixed_rate) +struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev, + const char *name, const char *parent_name, unsigned long flags, + unsigned long fixed_rate, unsigned long fixed_accuracy) { struct clk_fixed_rate *fixed; struct clk *clk; @@ -70,16 +79,33 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name, /* struct clk_fixed_rate assignments */ fixed->fixed_rate = fixed_rate; + fixed->fixed_accuracy = fixed_accuracy; fixed->hw.init = &init; /* register the clock */ clk = clk_register(dev, &fixed->hw); - if (IS_ERR(clk)) kfree(fixed); return clk; } +EXPORT_SYMBOL_GPL(clk_register_fixed_rate_with_accuracy); + +/** + * clk_register_fixed_rate - register fixed-rate clock with the clock framework + * @dev: device that is registering this clock + * @name: name of this clock + * @parent_name: name of clock's parent + * @flags: framework-specific flags + * @fixed_rate: non-adjustable clock rate + */ +struct clk *clk_register_fixed_rate(struct device *dev, const char *name, + const char *parent_name, unsigned long flags, + unsigned long fixed_rate) +{ + return clk_register_fixed_rate_with_accuracy(dev, name, parent_name, + flags, fixed_rate, 0); +} EXPORT_SYMBOL_GPL(clk_register_fixed_rate); #ifdef CONFIG_OF @@ -91,13 +117,18 @@ void of_fixed_clk_setup(struct device_node *node) struct clk *clk; const char *clk_name = node->name; u32 rate; + u32 accuracy = 0; if (of_property_read_u32(node, "clock-frequency", &rate)) return; + of_property_read_u32(node, "clock-accuracy", &accuracy); + of_property_read_string(node, "clock-output-names", &clk_name); - clk = clk_register_fixed_rate(NULL, clk_name, NULL, CLK_IS_ROOT, rate); + clk = clk_register_fixed_rate_with_accuracy(NULL, clk_name, NULL, + CLK_IS_ROOT, rate, + accuracy); if (!IS_ERR(clk)) of_clk_add_provider(node, of_clk_src_simple_get, clk); } diff --git a/drivers/clk/clk-max77686.c b/drivers/clk/clk-max77686.c index 9f57bc37cd60..3d7e8dd8fd58 100644 --- a/drivers/clk/clk-max77686.c +++ b/drivers/clk/clk-max77686.c @@ -66,7 +66,7 @@ static void max77686_clk_unprepare(struct clk_hw *hw) MAX77686_REG_32KHZ, max77686->mask, ~max77686->mask); } -static int max77686_clk_is_enabled(struct clk_hw *hw) +static int max77686_clk_is_prepared(struct clk_hw *hw) { struct max77686_clk *max77686 = to_max77686_clk(hw); int ret; @@ -81,10 +81,17 @@ static int max77686_clk_is_enabled(struct clk_hw *hw) return val & max77686->mask; } +static unsigned long max77686_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return 32768; +} + static struct clk_ops max77686_clk_ops = { .prepare = max77686_clk_prepare, .unprepare = max77686_clk_unprepare, - .is_enabled = max77686_clk_is_enabled, + .is_prepared = max77686_clk_is_prepared, + .recalc_rate = max77686_recalc_rate, }; static struct clk_init_data max77686_clks_init[MAX77686_CLKS_NUM] = { @@ -105,38 +112,38 @@ static struct clk_init_data max77686_clks_init[MAX77686_CLKS_NUM] = { }, }; -static int max77686_clk_register(struct device *dev, +static struct clk *max77686_clk_register(struct device *dev, struct max77686_clk *max77686) { struct clk *clk; struct clk_hw *hw = &max77686->hw; clk = clk_register(dev, hw); - if (IS_ERR(clk)) - return -ENOMEM; + return clk; max77686->lookup = kzalloc(sizeof(struct clk_lookup), GFP_KERNEL); if (!max77686->lookup) - return -ENOMEM; + return ERR_PTR(-ENOMEM); max77686->lookup->con_id = hw->init->name; max77686->lookup->clk = clk; clkdev_add(max77686->lookup); - return 0; + return clk; } static int max77686_clk_probe(struct platform_device *pdev) { struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); - struct max77686_clk **max77686_clks; + struct max77686_clk *max77686_clks[MAX77686_CLKS_NUM]; + struct clk **clocks; int i, ret; - max77686_clks = devm_kzalloc(&pdev->dev, sizeof(struct max77686_clk *) + clocks = devm_kzalloc(&pdev->dev, sizeof(struct clk *) * MAX77686_CLKS_NUM, GFP_KERNEL); - if (!max77686_clks) + if (!clocks) return -ENOMEM; for (i = 0; i < MAX77686_CLKS_NUM; i++) { @@ -151,47 +158,63 @@ static int max77686_clk_probe(struct platform_device *pdev) max77686_clks[i]->mask = 1 << i; max77686_clks[i]->hw.init = &max77686_clks_init[i]; - ret = max77686_clk_register(&pdev->dev, max77686_clks[i]); + clocks[i] = max77686_clk_register(&pdev->dev, max77686_clks[i]); + if (IS_ERR(clocks[i])) { + ret = PTR_ERR(clocks[i]); + dev_err(&pdev->dev, "failed to register %s\n", + max77686_clks[i]->hw.init->name); + goto err_clocks; + } + } + + platform_set_drvdata(pdev, clocks); + + if (iodev->dev->of_node) { + struct clk_onecell_data *of_data; + + of_data = devm_kzalloc(&pdev->dev, + sizeof(*of_data), GFP_KERNEL); + if (!of_data) { + ret = -ENOMEM; + goto err_clocks; + } + + of_data->clks = clocks; + of_data->clk_num = MAX77686_CLKS_NUM; + ret = of_clk_add_provider(iodev->dev->of_node, + of_clk_src_onecell_get, of_data); if (ret) { - switch (i) { - case MAX77686_CLK_AP: - dev_err(&pdev->dev, "Fail to register CLK_AP\n"); - goto err_clk_ap; - break; - case MAX77686_CLK_CP: - dev_err(&pdev->dev, "Fail to register CLK_CP\n"); - goto err_clk_cp; - break; - case MAX77686_CLK_PMIC: - dev_err(&pdev->dev, "Fail to register CLK_PMIC\n"); - goto err_clk_pmic; - } + dev_err(&pdev->dev, "failed to register OF clock provider\n"); + goto err_clocks; } } - platform_set_drvdata(pdev, max77686_clks); + return 0; - goto out; +err_clocks: + for (--i; i >= 0; --i) { + clkdev_drop(max77686_clks[i]->lookup); + clk_unregister(max77686_clks[i]->hw.clk); + } -err_clk_pmic: - clkdev_drop(max77686_clks[MAX77686_CLK_CP]->lookup); - kfree(max77686_clks[MAX77686_CLK_CP]->hw.clk); -err_clk_cp: - clkdev_drop(max77686_clks[MAX77686_CLK_AP]->lookup); - kfree(max77686_clks[MAX77686_CLK_AP]->hw.clk); -err_clk_ap: -out: return ret; } static int max77686_clk_remove(struct platform_device *pdev) { - struct max77686_clk **max77686_clks = platform_get_drvdata(pdev); + struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); + struct clk **clocks = platform_get_drvdata(pdev); int i; + if (iodev->dev->of_node) + of_clk_del_provider(iodev->dev->of_node); + for (i = 0; i < MAX77686_CLKS_NUM; i++) { - clkdev_drop(max77686_clks[i]->lookup); - kfree(max77686_clks[i]->hw.clk); + struct clk_hw *hw = __clk_get_hw(clocks[i]); + struct max77686_clk *max77686 = to_max77686_clk(hw); + + clkdev_drop(max77686->lookup); + clk_unregister(clocks[i]); } return 0; } diff --git a/drivers/clk/clk-si570.c b/drivers/clk/clk-si570.c new file mode 100644 index 000000000000..4bbbe32585ec --- /dev/null +++ b/drivers/clk/clk-si570.c @@ -0,0 +1,531 @@ +/* + * Driver for Silicon Labs Si570/Si571 Programmable XO/VCXO + * + * Copyright (C) 2010, 2011 Ericsson AB. + * Copyright (C) 2011 Guenter Roeck. + * Copyright (C) 2011 - 2013 Xilinx Inc. + * + * Author: Guenter Roeck <guenter.roeck@ericsson.com> + * Sören Brinkmann <soren.brinkmann@xilinx.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/clk-provider.h> +#include <linux/delay.h> +#include <linux/module.h> +#include <linux/i2c.h> +#include <linux/regmap.h> +#include <linux/slab.h> + +/* Si570 registers */ +#define SI570_REG_HS_N1 7 +#define SI570_REG_N1_RFREQ0 8 +#define SI570_REG_RFREQ1 9 +#define SI570_REG_RFREQ2 10 +#define SI570_REG_RFREQ3 11 +#define SI570_REG_RFREQ4 12 +#define SI570_REG_CONTROL 135 +#define SI570_REG_FREEZE_DCO 137 +#define SI570_DIV_OFFSET_7PPM 6 + +#define HS_DIV_SHIFT 5 +#define HS_DIV_MASK 0xe0 +#define HS_DIV_OFFSET 4 +#define N1_6_2_MASK 0x1f +#define N1_1_0_MASK 0xc0 +#define RFREQ_37_32_MASK 0x3f + +#define SI570_MIN_FREQ 10000000L +#define SI570_MAX_FREQ 1417500000L +#define SI598_MAX_FREQ 525000000L + +#define FDCO_MIN 4850000000LL +#define FDCO_MAX 5670000000LL + +#define SI570_CNTRL_RECALL (1 << 0) +#define SI570_CNTRL_FREEZE_M (1 << 5) +#define SI570_CNTRL_NEWFREQ (1 << 6) + +#define SI570_FREEZE_DCO (1 << 4) + +/** + * struct clk_si570: + * @hw: Clock hw struct + * @regmap: Device's regmap + * @div_offset: Rgister offset for dividers + * @max_freq: Maximum frequency for this device + * @fxtal: Factory xtal frequency + * @n1: Clock divider N1 + * @hs_div: Clock divider HSDIV + * @rfreq: Clock multiplier RFREQ + * @frequency: Current output frequency + * @i2c_client: I2C client pointer + */ +struct clk_si570 { + struct clk_hw hw; + struct regmap *regmap; + unsigned int div_offset; + u64 max_freq; + u64 fxtal; + unsigned int n1; + unsigned int hs_div; + u64 rfreq; + u64 frequency; + struct i2c_client *i2c_client; +}; +#define to_clk_si570(_hw) container_of(_hw, struct clk_si570, hw) + +enum clk_si570_variant { + si57x, + si59x +}; + +/** + * si570_get_divs() - Read clock dividers from HW + * @data: Pointer to struct clk_si570 + * @rfreq: Fractional multiplier (output) + * @n1: Divider N1 (output) + * @hs_div: Divider HSDIV (output) + * Returns 0 on success, negative errno otherwise. + * + * Retrieve clock dividers and multipliers from the HW. + */ +static int si570_get_divs(struct clk_si570 *data, u64 *rfreq, + unsigned int *n1, unsigned int *hs_div) +{ + int err; + u8 reg[6]; + u64 tmp; + + err = regmap_bulk_read(data->regmap, SI570_REG_HS_N1 + data->div_offset, + reg, ARRAY_SIZE(reg)); + if (err) + return err; + + *hs_div = ((reg[0] & HS_DIV_MASK) >> HS_DIV_SHIFT) + HS_DIV_OFFSET; + *n1 = ((reg[0] & N1_6_2_MASK) << 2) + ((reg[1] & N1_1_0_MASK) >> 6) + 1; + /* Handle invalid cases */ + if (*n1 > 1) + *n1 &= ~1; + + tmp = reg[1] & RFREQ_37_32_MASK; + tmp = (tmp << 8) + reg[2]; + tmp = (tmp << 8) + reg[3]; + tmp = (tmp << 8) + reg[4]; + tmp = (tmp << 8) + reg[5]; + *rfreq = tmp; + + return 0; +} + +/** + * si570_get_defaults() - Get default values + * @data: Driver data structure + * @fout: Factory frequency output + * Returns 0 on success, negative errno otherwise. + */ +static int si570_get_defaults(struct clk_si570 *data, u64 fout) +{ + int err; + u64 fdco; + + regmap_write(data->regmap, SI570_REG_CONTROL, SI570_CNTRL_RECALL); + + err = si570_get_divs(data, &data->rfreq, &data->n1, &data->hs_div); + if (err) + return err; + + /* + * Accept optional precision loss to avoid arithmetic overflows. + * Acceptable per Silicon Labs Application Note AN334. + */ + fdco = fout * data->n1 * data->hs_div; + if (fdco >= (1LL << 36)) + data->fxtal = div64_u64(fdco << 24, data->rfreq >> 4); + else + data->fxtal = div64_u64(fdco << 28, data->rfreq); + + data->frequency = fout; + + return 0; +} + +/** + * si570_update_rfreq() - Update clock multiplier + * @data: Driver data structure + * Passes on regmap_bulk_write() return value. + */ +static int si570_update_rfreq(struct clk_si570 *data) +{ + u8 reg[5]; + + reg[0] = ((data->n1 - 1) << 6) | + ((data->rfreq >> 32) & RFREQ_37_32_MASK); + reg[1] = (data->rfreq >> 24) & 0xff; + reg[2] = (data->rfreq >> 16) & 0xff; + reg[3] = (data->rfreq >> 8) & 0xff; + reg[4] = data->rfreq & 0xff; + + return regmap_bulk_write(data->regmap, SI570_REG_N1_RFREQ0 + + data->div_offset, reg, ARRAY_SIZE(reg)); +} + +/** + * si570_calc_divs() - Caluclate clock dividers + * @frequency: Target frequency + * @data: Driver data structure + * @out_rfreq: RFREG fractional multiplier (output) + * @out_n1: Clock divider N1 (output) + * @out_hs_div: Clock divider HSDIV (output) + * Returns 0 on success, negative errno otherwise. + * + * Calculate the clock dividers (@out_hs_div, @out_n1) and clock multiplier + * (@out_rfreq) for a given target @frequency. + */ +static int si570_calc_divs(unsigned long frequency, struct clk_si570 *data, + u64 *out_rfreq, unsigned int *out_n1, unsigned int *out_hs_div) +{ + int i; + unsigned int n1, hs_div; + u64 fdco, best_fdco = ULLONG_MAX; + static const uint8_t si570_hs_div_values[] = { 11, 9, 7, 6, 5, 4 }; + + for (i = 0; i < ARRAY_SIZE(si570_hs_div_values); i++) { + hs_div = si570_hs_div_values[i]; + /* Calculate lowest possible value for n1 */ + n1 = div_u64(div_u64(FDCO_MIN, hs_div), frequency); + if (!n1 || (n1 & 1)) + n1++; + while (n1 <= 128) { + fdco = (u64)frequency * (u64)hs_div * (u64)n1; + if (fdco > FDCO_MAX) + break; + if (fdco >= FDCO_MIN && fdco < best_fdco) { + *out_n1 = n1; + *out_hs_div = hs_div; + *out_rfreq = div64_u64(fdco << 28, data->fxtal); + best_fdco = fdco; + } + n1 += (n1 == 1 ? 1 : 2); + } + } + + if (best_fdco == ULLONG_MAX) + return -EINVAL; + + return 0; +} + +static unsigned long si570_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + int err; + u64 rfreq, rate; + unsigned int n1, hs_div; + struct clk_si570 *data = to_clk_si570(hw); + + err = si570_get_divs(data, &rfreq, &n1, &hs_div); + if (err) { + dev_err(&data->i2c_client->dev, "unable to recalc rate\n"); + return data->frequency; + } + + rfreq = div_u64(rfreq, hs_div * n1); + rate = (data->fxtal * rfreq) >> 28; + + return rate; +} + +static long si570_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + int err; + u64 rfreq; + unsigned int n1, hs_div; + struct clk_si570 *data = to_clk_si570(hw); + + if (!rate) + return 0; + + if (div64_u64(abs(rate - data->frequency) * 10000LL, + data->frequency) < 35) { + rfreq = div64_u64((data->rfreq * rate) + + div64_u64(data->frequency, 2), data->frequency); + n1 = data->n1; + hs_div = data->hs_div; + + } else { + err = si570_calc_divs(rate, data, &rfreq, &n1, &hs_div); + if (err) { + dev_err(&data->i2c_client->dev, + "unable to round rate\n"); + return 0; + } + } + + return rate; +} + +/** + * si570_set_frequency() - Adjust output frequency + * @data: Driver data structure + * @frequency: Target frequency + * Returns 0 on success. + * + * Update output frequency for big frequency changes (> 3,500 ppm). + */ +static int si570_set_frequency(struct clk_si570 *data, unsigned long frequency) +{ + int err; + + err = si570_calc_divs(frequency, data, &data->rfreq, &data->n1, + &data->hs_div); + if (err) + return err; + + /* + * The DCO reg should be accessed with a read-modify-write operation + * per AN334 + */ + regmap_write(data->regmap, SI570_REG_FREEZE_DCO, SI570_FREEZE_DCO); + regmap_write(data->regmap, SI570_REG_HS_N1 + data->div_offset, + ((data->hs_div - HS_DIV_OFFSET) << HS_DIV_SHIFT) | + (((data->n1 - 1) >> 2) & N1_6_2_MASK)); + si570_update_rfreq(data); + regmap_write(data->regmap, SI570_REG_FREEZE_DCO, 0); + regmap_write(data->regmap, SI570_REG_CONTROL, SI570_CNTRL_NEWFREQ); + + /* Applying a new frequency can take up to 10ms */ + usleep_range(10000, 12000); + + return 0; +} + +/** + * si570_set_frequency_small() - Adjust output frequency + * @data: Driver data structure + * @frequency: Target frequency + * Returns 0 on success. + * + * Update output frequency for small frequency changes (< 3,500 ppm). + */ +static int si570_set_frequency_small(struct clk_si570 *data, + unsigned long frequency) +{ + /* + * This is a re-implementation of DIV_ROUND_CLOSEST + * using the div64_u64 function lieu of letting the compiler + * insert EABI calls + */ + data->rfreq = div64_u64((data->rfreq * frequency) + + div_u64(data->frequency, 2), data->frequency); + regmap_write(data->regmap, SI570_REG_CONTROL, SI570_CNTRL_FREEZE_M); + si570_update_rfreq(data); + regmap_write(data->regmap, SI570_REG_CONTROL, 0); + + /* Applying a new frequency (small change) can take up to 100us */ + usleep_range(100, 200); + + return 0; +} + +static int si570_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_si570 *data = to_clk_si570(hw); + struct i2c_client *client = data->i2c_client; + int err; + + if (rate < SI570_MIN_FREQ || rate > data->max_freq) { + dev_err(&client->dev, + "requested frequency %lu Hz is out of range\n", rate); + return -EINVAL; + } + + if (div64_u64(abs(rate - data->frequency) * 10000LL, + data->frequency) < 35) + err = si570_set_frequency_small(data, rate); + else + err = si570_set_frequency(data, rate); + + if (err) + return err; + + data->frequency = rate; + + return 0; +} + +static const struct clk_ops si570_clk_ops = { + .recalc_rate = si570_recalc_rate, + .round_rate = si570_round_rate, + .set_rate = si570_set_rate, +}; + +static bool si570_regmap_is_volatile(struct device *dev, unsigned int reg) +{ + switch (reg) { + case SI570_REG_CONTROL: + return true; + default: + return false; + } +} + +static bool si570_regmap_is_writeable(struct device *dev, unsigned int reg) +{ + switch (reg) { + case SI570_REG_HS_N1 ... (SI570_REG_RFREQ4 + SI570_DIV_OFFSET_7PPM): + case SI570_REG_CONTROL: + case SI570_REG_FREEZE_DCO: + return true; + default: + return false; + } +} + +static struct regmap_config si570_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, + .max_register = 137, + .writeable_reg = si570_regmap_is_writeable, + .volatile_reg = si570_regmap_is_volatile, +}; + +static int si570_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct clk_si570 *data; + struct clk_init_data init; + struct clk *clk; + u32 initial_fout, factory_fout, stability; + int err; + enum clk_si570_variant variant = id->driver_data; + + data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + init.ops = &si570_clk_ops; + init.flags = CLK_IS_ROOT; + init.num_parents = 0; + data->hw.init = &init; + data->i2c_client = client; + + if (variant == si57x) { + err = of_property_read_u32(client->dev.of_node, + "temperature-stability", &stability); + if (err) { + dev_err(&client->dev, + "'temperature-stability' property missing\n"); + return err; + } + /* adjust register offsets for 7ppm devices */ + if (stability == 7) + data->div_offset = SI570_DIV_OFFSET_7PPM; + + data->max_freq = SI570_MAX_FREQ; + } else { + data->max_freq = SI598_MAX_FREQ; + } + + if (of_property_read_string(client->dev.of_node, "clock-output-names", + &init.name)) + init.name = client->dev.of_node->name; + + err = of_property_read_u32(client->dev.of_node, "factory-fout", + &factory_fout); + if (err) { + dev_err(&client->dev, "'factory-fout' property missing\n"); + return err; + } + + data->regmap = devm_regmap_init_i2c(client, &si570_regmap_config); + if (IS_ERR(data->regmap)) { + dev_err(&client->dev, "failed to allocate register map\n"); + return PTR_ERR(data->regmap); + } + + i2c_set_clientdata(client, data); + err = si570_get_defaults(data, factory_fout); + if (err) + return err; + + clk = devm_clk_register(&client->dev, &data->hw); + if (IS_ERR(clk)) { + dev_err(&client->dev, "clock registration failed\n"); + return PTR_ERR(clk); + } + err = of_clk_add_provider(client->dev.of_node, of_clk_src_simple_get, + clk); + if (err) { + dev_err(&client->dev, "unable to add clk provider\n"); + return err; + } + + /* Read the requested initial output frequency from device tree */ + if (!of_property_read_u32(client->dev.of_node, "clock-frequency", + &initial_fout)) { + err = clk_set_rate(clk, initial_fout); + if (err) { + of_clk_del_provider(client->dev.of_node); + return err; + } + } + + /* Display a message indicating that we've successfully registered */ + dev_info(&client->dev, "registered, current frequency %llu Hz\n", + data->frequency); + + return 0; +} + +static int si570_remove(struct i2c_client *client) +{ + of_clk_del_provider(client->dev.of_node); + return 0; +} + +static const struct i2c_device_id si570_id[] = { + { "si570", si57x }, + { "si571", si57x }, + { "si598", si59x }, + { "si599", si59x }, + { } +}; +MODULE_DEVICE_TABLE(i2c, si570_id); + +static const struct of_device_id clk_si570_of_match[] = { + { .compatible = "silabs,si570" }, + { .compatible = "silabs,si571" }, + { .compatible = "silabs,si598" }, + { .compatible = "silabs,si599" }, + { }, +}; +MODULE_DEVICE_TABLE(of, clk_si570_of_match); + +static struct i2c_driver si570_driver = { + .driver = { + .name = "si570", + .of_match_table = clk_si570_of_match, + }, + .probe = si570_probe, + .remove = si570_remove, + .id_table = si570_id, +}; +module_i2c_driver(si570_driver); + +MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>"); +MODULE_AUTHOR("Soeren Brinkmann <soren.brinkmann@xilinx.com"); +MODULE_DESCRIPTION("Si570 driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c index 7fd5c5e9e25d..37e928846ec5 100644 --- a/drivers/clk/clk-vt8500.c +++ b/drivers/clk/clk-vt8500.c @@ -641,7 +641,7 @@ static unsigned long vtwm_pll_recalc_rate(struct clk_hw *hw, return pll_freq; } -const struct clk_ops vtwm_pll_ops = { +static const struct clk_ops vtwm_pll_ops = { .round_rate = vtwm_pll_round_rate, .set_rate = vtwm_pll_set_rate, .recalc_rate = vtwm_pll_recalc_rate, diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 2cf2ea6b77a1..2b38dc99063f 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -21,6 +21,8 @@ #include <linux/init.h> #include <linux/sched.h> +#include "clk.h" + static DEFINE_SPINLOCK(enable_lock); static DEFINE_MUTEX(prepare_lock); @@ -92,7 +94,7 @@ static void clk_enable_unlock(unsigned long flags) /*** debugfs support ***/ -#ifdef CONFIG_COMMON_CLK_DEBUG +#ifdef CONFIG_DEBUG_FS #include <linux/debugfs.h> static struct dentry *rootdir; @@ -104,10 +106,11 @@ static void clk_summary_show_one(struct seq_file *s, struct clk *c, int level) if (!c) return; - seq_printf(s, "%*s%-*s %-11d %-12d %-10lu", + seq_printf(s, "%*s%-*s %-11d %-12d %-10lu %-11lu", level * 3 + 1, "", 30 - level * 3, c->name, - c->enable_count, c->prepare_count, clk_get_rate(c)); + c->enable_count, c->prepare_count, clk_get_rate(c), + clk_get_accuracy(c)); seq_printf(s, "\n"); } @@ -129,8 +132,8 @@ static int clk_summary_show(struct seq_file *s, void *data) { struct clk *c; - seq_printf(s, " clock enable_cnt prepare_cnt rate\n"); - seq_printf(s, "---------------------------------------------------------------------\n"); + seq_printf(s, " clock enable_cnt prepare_cnt rate accuracy\n"); + seq_printf(s, "---------------------------------------------------------------------------------\n"); clk_prepare_lock(); @@ -167,6 +170,7 @@ static void clk_dump_one(struct seq_file *s, struct clk *c, int level) seq_printf(s, "\"enable_count\": %d,", c->enable_count); seq_printf(s, "\"prepare_count\": %d,", c->prepare_count); seq_printf(s, "\"rate\": %lu", clk_get_rate(c)); + seq_printf(s, "\"accuracy\": %lu", clk_get_accuracy(c)); } static void clk_dump_subtree(struct seq_file *s, struct clk *c, int level) @@ -248,6 +252,11 @@ static int clk_debug_create_one(struct clk *clk, struct dentry *pdentry) if (!d) goto err_out; + d = debugfs_create_u32("clk_accuracy", S_IRUGO, clk->dentry, + (u32 *)&clk->accuracy); + if (!d) + goto err_out; + d = debugfs_create_x32("clk_flags", S_IRUGO, clk->dentry, (u32 *)&clk->flags); if (!d) @@ -272,7 +281,8 @@ static int clk_debug_create_one(struct clk *clk, struct dentry *pdentry) goto out; err_out: - debugfs_remove(clk->dentry); + debugfs_remove_recursive(clk->dentry); + clk->dentry = NULL; out: return ret; } @@ -342,6 +352,21 @@ out: return ret; } + /** + * clk_debug_unregister - remove a clk node from the debugfs clk tree + * @clk: the clk being removed from the debugfs clk tree + * + * Dynamically removes a clk and all it's children clk nodes from the + * debugfs clk tree if clk->dentry points to debugfs created by + * clk_debug_register in __clk_init. + * + * Caller must hold prepare_lock. + */ +static void clk_debug_unregister(struct clk *clk) +{ + debugfs_remove_recursive(clk->dentry); +} + /** * clk_debug_reparent - reparent clk node in the debugfs clk tree * @clk: the clk being reparented @@ -432,6 +457,9 @@ static inline int clk_debug_register(struct clk *clk) { return 0; } static inline void clk_debug_reparent(struct clk *clk, struct clk *new_parent) { } +static inline void clk_debug_unregister(struct clk *clk) +{ +} #endif /* caller must hold prepare_lock */ @@ -602,6 +630,14 @@ out: return ret; } +unsigned long __clk_get_accuracy(struct clk *clk) +{ + if (!clk) + return 0; + + return clk->accuracy; +} + unsigned long __clk_get_flags(struct clk *clk) { return !clk ? 0 : clk->flags; @@ -1016,6 +1052,59 @@ static int __clk_notify(struct clk *clk, unsigned long msg, } /** + * __clk_recalc_accuracies + * @clk: first clk in the subtree + * + * Walks the subtree of clks starting with clk and recalculates accuracies as + * it goes. Note that if a clk does not implement the .recalc_accuracy + * callback then it is assumed that the clock will take on the accuracy of it's + * parent. + * + * Caller must hold prepare_lock. + */ +static void __clk_recalc_accuracies(struct clk *clk) +{ + unsigned long parent_accuracy = 0; + struct clk *child; + + if (clk->parent) + parent_accuracy = clk->parent->accuracy; + + if (clk->ops->recalc_accuracy) + clk->accuracy = clk->ops->recalc_accuracy(clk->hw, + parent_accuracy); + else + clk->accuracy = parent_accuracy; + + hlist_for_each_entry(child, &clk->children, child_node) + __clk_recalc_accuracies(child); +} + +/** + * clk_get_accuracy - return the accuracy of clk + * @clk: the clk whose accuracy is being returned + * + * Simply returns the cached accuracy of the clk, unless + * CLK_GET_ACCURACY_NOCACHE flag is set, which means a recalc_rate will be + * issued. + * If clk is NULL then returns 0. + */ +long clk_get_accuracy(struct clk *clk) +{ + unsigned long accuracy; + + clk_prepare_lock(); + if (clk && (clk->flags & CLK_GET_ACCURACY_NOCACHE)) + __clk_recalc_accuracies(clk); + + accuracy = __clk_get_accuracy(clk); + clk_prepare_unlock(); + + return accuracy; +} +EXPORT_SYMBOL_GPL(clk_get_accuracy); + +/** * __clk_recalc_rates * @clk: first clk in the subtree * @msg: notification type (see include/linux/clk.h) @@ -1129,10 +1218,9 @@ static void clk_reparent(struct clk *clk, struct clk *new_parent) clk->parent = new_parent; } -static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index) +static struct clk *__clk_set_parent_before(struct clk *clk, struct clk *parent) { unsigned long flags; - int ret = 0; struct clk *old_parent = clk->parent; /* @@ -1163,6 +1251,34 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index) clk_reparent(clk, parent); clk_enable_unlock(flags); + return old_parent; +} + +static void __clk_set_parent_after(struct clk *clk, struct clk *parent, + struct clk *old_parent) +{ + /* + * Finish the migration of prepare state and undo the changes done + * for preventing a race with clk_enable(). + */ + if (clk->prepare_count) { + clk_disable(clk); + clk_disable(old_parent); + __clk_unprepare(old_parent); + } + + /* update debugfs with new clk tree topology */ + clk_debug_reparent(clk, parent); +} + +static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index) +{ + unsigned long flags; + int ret = 0; + struct clk *old_parent; + + old_parent = __clk_set_parent_before(clk, parent); + /* change clock input source */ if (parent && clk->ops->set_parent) ret = clk->ops->set_parent(clk->hw, p_index); @@ -1180,18 +1296,8 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index) return ret; } - /* - * Finish the migration of prepare state and undo the changes done - * for preventing a race with clk_enable(). - */ - if (clk->prepare_count) { - clk_disable(clk); - clk_disable(old_parent); - __clk_unprepare(old_parent); - } + __clk_set_parent_after(clk, parent, old_parent); - /* update debugfs with new clk tree topology */ - clk_debug_reparent(clk, parent); return 0; } @@ -1376,17 +1482,32 @@ static void clk_change_rate(struct clk *clk) struct clk *child; unsigned long old_rate; unsigned long best_parent_rate = 0; + bool skip_set_rate = false; + struct clk *old_parent; old_rate = clk->rate; - /* set parent */ - if (clk->new_parent && clk->new_parent != clk->parent) - __clk_set_parent(clk, clk->new_parent, clk->new_parent_index); - - if (clk->parent) + if (clk->new_parent) + best_parent_rate = clk->new_parent->rate; + else if (clk->parent) best_parent_rate = clk->parent->rate; - if (clk->ops->set_rate) + if (clk->new_parent && clk->new_parent != clk->parent) { + old_parent = __clk_set_parent_before(clk, clk->new_parent); + + if (clk->ops->set_rate_and_parent) { + skip_set_rate = true; + clk->ops->set_rate_and_parent(clk->hw, clk->new_rate, + best_parent_rate, + clk->new_parent_index); + } else if (clk->ops->set_parent) { + clk->ops->set_parent(clk->hw, clk->new_parent_index); + } + + __clk_set_parent_after(clk, clk->new_parent, old_parent); + } + + if (!skip_set_rate && clk->ops->set_rate) clk->ops->set_rate(clk->hw, clk->new_rate, best_parent_rate); if (clk->ops->recalc_rate) @@ -1551,6 +1672,7 @@ void __clk_reparent(struct clk *clk, struct clk *new_parent) { clk_reparent(clk, new_parent); clk_debug_reparent(clk, new_parent); + __clk_recalc_accuracies(clk); __clk_recalc_rates(clk, POST_RATE_CHANGE); } @@ -1621,11 +1743,13 @@ int clk_set_parent(struct clk *clk, struct clk *parent) /* do the re-parent */ ret = __clk_set_parent(clk, parent, p_index); - /* propagate rate recalculation accordingly */ - if (ret) + /* propagate rate an accuracy recalculation accordingly */ + if (ret) { __clk_recalc_rates(clk, ABORT_RATE_CHANGE); - else + } else { __clk_recalc_rates(clk, POST_RATE_CHANGE); + __clk_recalc_accuracies(clk); + } out: clk_prepare_unlock(); @@ -1678,6 +1802,14 @@ int __clk_init(struct device *dev, struct clk *clk) goto out; } + if (clk->ops->set_rate_and_parent && + !(clk->ops->set_parent && clk->ops->set_rate)) { + pr_warn("%s: %s must implement .set_parent & .set_rate\n", + __func__, clk->name); + ret = -EINVAL; + goto out; + } + /* throw a WARN if any entries in parent_names are NULL */ for (i = 0; i < clk->num_parents; i++) WARN(!clk->parent_names[i], @@ -1730,6 +1862,21 @@ int __clk_init(struct device *dev, struct clk *clk) hlist_add_head(&clk->child_node, &clk_orphan_list); /* + * Set clk's accuracy. The preferred method is to use + * .recalc_accuracy. For simple clocks and lazy developers the default + * fallback is to use the parent's accuracy. If a clock doesn't have a + * parent (or is orphaned) then accuracy is set to zero (perfect + * clock). + */ + if (clk->ops->recalc_accuracy) + clk->accuracy = clk->ops->recalc_accuracy(clk->hw, + __clk_get_accuracy(clk->parent)); + else if (clk->parent) + clk->accuracy = clk->parent->accuracy; + else + clk->accuracy = 0; + + /* * Set clk's rate. The preferred method is to use .recalc_rate. For * simple clocks and lazy developers the default fallback is to use the * parent's rate. If a clock doesn't have a parent (or is orphaned) @@ -1743,6 +1890,7 @@ int __clk_init(struct device *dev, struct clk *clk) else clk->rate = 0; + clk_debug_register(clk); /* * walk the list of orphan clocks and reparent any that are children of * this clock @@ -1773,8 +1921,7 @@ int __clk_init(struct device *dev, struct clk *clk) if (clk->ops->init) clk->ops->init(clk->hw); - clk_debug_register(clk); - + kref_init(&clk->ref); out: clk_prepare_unlock(); @@ -1810,6 +1957,10 @@ struct clk *__clk_register(struct device *dev, struct clk_hw *hw) clk->flags = hw->init->flags; clk->parent_names = hw->init->parent_names; clk->num_parents = hw->init->num_parents; + if (dev && dev->driver) + clk->owner = dev->driver->owner; + else + clk->owner = NULL; ret = __clk_init(dev, clk); if (ret) @@ -1830,6 +1981,8 @@ static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) goto fail_name; } clk->ops = hw->init->ops; + if (dev && dev->driver) + clk->owner = dev->driver->owner; clk->hw = hw; clk->flags = hw->init->flags; clk->num_parents = hw->init->num_parents; @@ -1904,13 +2057,104 @@ fail_out: } EXPORT_SYMBOL_GPL(clk_register); +/* + * Free memory allocated for a clock. + * Caller must hold prepare_lock. + */ +static void __clk_release(struct kref *ref) +{ + struct clk *clk = container_of(ref, struct clk, ref); + int i = clk->num_parents; + + kfree(clk->parents); + while (--i >= 0) + kfree(clk->parent_names[i]); + + kfree(clk->parent_names); + kfree(clk->name); + kfree(clk); +} + +/* + * Empty clk_ops for unregistered clocks. These are used temporarily + * after clk_unregister() was called on a clock and until last clock + * consumer calls clk_put() and the struct clk object is freed. + */ +static int clk_nodrv_prepare_enable(struct clk_hw *hw) +{ + return -ENXIO; +} + +static void clk_nodrv_disable_unprepare(struct clk_hw *hw) +{ + WARN_ON_ONCE(1); +} + +static int clk_nodrv_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + return -ENXIO; +} + +static int clk_nodrv_set_parent(struct clk_hw *hw, u8 index) +{ + return -ENXIO; +} + +static const struct clk_ops clk_nodrv_ops = { + .enable = clk_nodrv_prepare_enable, + .disable = clk_nodrv_disable_unprepare, + .prepare = clk_nodrv_prepare_enable, + .unprepare = clk_nodrv_disable_unprepare, + .set_rate = clk_nodrv_set_rate, + .set_parent = clk_nodrv_set_parent, +}; + /** * clk_unregister - unregister a currently registered clock * @clk: clock to unregister - * - * Currently unimplemented. */ -void clk_unregister(struct clk *clk) {} +void clk_unregister(struct clk *clk) +{ + unsigned long flags; + + if (!clk || WARN_ON_ONCE(IS_ERR(clk))) + return; + + clk_prepare_lock(); + + if (clk->ops == &clk_nodrv_ops) { + pr_err("%s: unregistered clock: %s\n", __func__, clk->name); + goto out; + } + /* + * Assign empty clock ops for consumers that might still hold + * a reference to this clock. + */ + flags = clk_enable_lock(); + clk->ops = &clk_nodrv_ops; + clk_enable_unlock(flags); + + if (!hlist_empty(&clk->children)) { + struct clk *child; + + /* Reparent all children to the orphan list. */ + hlist_for_each_entry(child, &clk->children, child_node) + clk_set_parent(child, NULL); + } + + clk_debug_unregister(clk); + + hlist_del_init(&clk->child_node); + + if (clk->prepare_count) + pr_warn("%s: unregistering prepared clock: %s\n", + __func__, clk->name); + + kref_put(&clk->ref, __clk_release); +out: + clk_prepare_unlock(); +} EXPORT_SYMBOL_GPL(clk_unregister); static void devm_clk_release(struct device *dev, void *res) @@ -1970,6 +2214,31 @@ void devm_clk_unregister(struct device *dev, struct clk *clk) } EXPORT_SYMBOL_GPL(devm_clk_unregister); +/* + * clkdev helpers + */ +int __clk_get(struct clk *clk) +{ + if (clk && !try_module_get(clk->owner)) + return 0; + + kref_get(&clk->ref); + return 1; +} + +void __clk_put(struct clk *clk) +{ + if (WARN_ON_ONCE(IS_ERR(clk))) + return; + + clk_prepare_lock(); + kref_put(&clk->ref, __clk_release); + clk_prepare_unlock(); + + if (clk) + module_put(clk->owner); +} + /*** clk rate change notifiers ***/ /** @@ -2110,7 +2379,18 @@ static const struct of_device_id __clk_of_table_sentinel __used __section(__clk_of_table_end); static LIST_HEAD(of_clk_providers); -static DEFINE_MUTEX(of_clk_lock); +static DEFINE_MUTEX(of_clk_mutex); + +/* of_clk_provider list locking helpers */ +void of_clk_lock(void) +{ + mutex_lock(&of_clk_mutex); +} + +void of_clk_unlock(void) +{ + mutex_unlock(&of_clk_mutex); +} struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec, void *data) @@ -2154,9 +2434,9 @@ int of_clk_add_provider(struct device_node *np, cp->data = data; cp->get = clk_src_get; - mutex_lock(&of_clk_lock); + mutex_lock(&of_clk_mutex); list_add(&cp->link, &of_clk_providers); - mutex_unlock(&of_clk_lock); + mutex_unlock(&of_clk_mutex); pr_debug("Added clock from %s\n", np->full_name); return 0; @@ -2171,7 +2451,7 @@ void of_clk_del_provider(struct device_node *np) { struct of_clk_provider *cp; - mutex_lock(&of_clk_lock); + mutex_lock(&of_clk_mutex); list_for_each_entry(cp, &of_clk_providers, link) { if (cp->node == np) { list_del(&cp->link); @@ -2180,24 +2460,33 @@ void of_clk_del_provider(struct device_node *np) break; } } - mutex_unlock(&of_clk_lock); + mutex_unlock(&of_clk_mutex); } EXPORT_SYMBOL_GPL(of_clk_del_provider); -struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec) +struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec) { struct of_clk_provider *provider; struct clk *clk = ERR_PTR(-ENOENT); /* Check if we have such a provider in our array */ - mutex_lock(&of_clk_lock); list_for_each_entry(provider, &of_clk_providers, link) { if (provider->node == clkspec->np) clk = provider->get(clkspec, provider->data); if (!IS_ERR(clk)) break; } - mutex_unlock(&of_clk_lock); + + return clk; +} + +struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec) +{ + struct clk *clk; + + mutex_lock(&of_clk_mutex); + clk = __of_clk_get_from_provider(clkspec); + mutex_unlock(&of_clk_mutex); return clk; } diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h new file mode 100644 index 000000000000..795cc9f0dac0 --- /dev/null +++ b/drivers/clk/clk.h @@ -0,0 +1,16 @@ +/* + * linux/drivers/clk/clk.h + * + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Sylwester Nawrocki <s.nawrocki@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) +struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec); +void of_clk_lock(void); +void of_clk_unlock(void); +#endif diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index 442a31363873..48f67218247c 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c @@ -21,6 +21,8 @@ #include <linux/clkdev.h> #include <linux/of.h> +#include "clk.h" + static LIST_HEAD(clocks); static DEFINE_MUTEX(clocks_mutex); @@ -39,7 +41,13 @@ struct clk *of_clk_get(struct device_node *np, int index) if (rc) return ERR_PTR(rc); - clk = of_clk_get_from_provider(&clkspec); + of_clk_lock(); + clk = __of_clk_get_from_provider(&clkspec); + + if (!IS_ERR(clk) && !__clk_get(clk)) + clk = ERR_PTR(-ENOENT); + + of_clk_unlock(); of_node_put(clkspec.np); return clk; } @@ -157,7 +165,7 @@ struct clk *clk_get(struct device *dev, const char *con_id) if (dev) { clk = of_clk_get_by_name(dev->of_node, con_id); - if (!IS_ERR(clk) && __clk_get(clk)) + if (!IS_ERR(clk)) return clk; } diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile new file mode 100644 index 000000000000..a049108341fc --- /dev/null +++ b/drivers/clk/hisilicon/Makefile @@ -0,0 +1,5 @@ +# +# Hisilicon Clock specific Makefile +# + +obj-y += clk.o clkgate-separated.o clk-hi3620.o diff --git a/drivers/clk/hisilicon/clk-hi3620.c b/drivers/clk/hisilicon/clk-hi3620.c new file mode 100644 index 000000000000..f24ad6a3a797 --- /dev/null +++ b/drivers/clk/hisilicon/clk-hi3620.c @@ -0,0 +1,242 @@ +/* + * Hisilicon Hi3620 clock driver + * + * Copyright (c) 2012-2013 Hisilicon Limited. + * Copyright (c) 2012-2013 Linaro Limited. + * + * Author: Haojian Zhuang <haojian.zhuang@linaro.org> + * Xin Li <li.xin@linaro.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include <linux/kernel.h> +#include <linux/clk-provider.h> +#include <linux/clkdev.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/slab.h> +#include <linux/clk.h> + +#include <dt-bindings/clock/hi3620-clock.h> + +#include "clk.h" + +/* clock parent list */ +static const char *timer0_mux_p[] __initdata = { "osc32k", "timerclk01", }; +static const char *timer1_mux_p[] __initdata = { "osc32k", "timerclk01", }; +static const char *timer2_mux_p[] __initdata = { "osc32k", "timerclk23", }; +static const char *timer3_mux_p[] __initdata = { "osc32k", "timerclk23", }; +static const char *timer4_mux_p[] __initdata = { "osc32k", "timerclk45", }; +static const char *timer5_mux_p[] __initdata = { "osc32k", "timerclk45", }; +static const char *timer6_mux_p[] __initdata = { "osc32k", "timerclk67", }; +static const char *timer7_mux_p[] __initdata = { "osc32k", "timerclk67", }; +static const char *timer8_mux_p[] __initdata = { "osc32k", "timerclk89", }; +static const char *timer9_mux_p[] __initdata = { "osc32k", "timerclk89", }; +static const char *uart0_mux_p[] __initdata = { "osc26m", "pclk", }; +static const char *uart1_mux_p[] __initdata = { "osc26m", "pclk", }; +static const char *uart2_mux_p[] __initdata = { "osc26m", "pclk", }; +static const char *uart3_mux_p[] __initdata = { "osc26m", "pclk", }; +static const char *uart4_mux_p[] __initdata = { "osc26m", "pclk", }; +static const char *spi0_mux_p[] __initdata = { "osc26m", "rclk_cfgaxi", }; +static const char *spi1_mux_p[] __initdata = { "osc26m", "rclk_cfgaxi", }; +static const char *spi2_mux_p[] __initdata = { "osc26m", "rclk_cfgaxi", }; +/* share axi parent */ +static const char *saxi_mux_p[] __initdata = { "armpll3", "armpll2", }; +static const char *pwm0_mux_p[] __initdata = { "osc32k", "osc26m", }; +static const char *pwm1_mux_p[] __initdata = { "osc32k", "osc26m", }; +static const char *sd_mux_p[] __initdata = { "armpll2", "armpll3", }; +static const char *mmc1_mux_p[] __initdata = { "armpll2", "armpll3", }; +static const char *mmc1_mux2_p[] __initdata = { "osc26m", "mmc1_div", }; +static const char *g2d_mux_p[] __initdata = { "armpll2", "armpll3", }; +static const char *venc_mux_p[] __initdata = { "armpll2", "armpll3", }; +static const char *vdec_mux_p[] __initdata = { "armpll2", "armpll3", }; +static const char *vpp_mux_p[] __initdata = { "armpll2", "armpll3", }; +static const char *edc0_mux_p[] __initdata = { "armpll2", "armpll3", }; +static const char *ldi0_mux_p[] __initdata = { "armpll2", "armpll4", + "armpll3", "armpll5", }; +static const char *edc1_mux_p[] __initdata = { "armpll2", "armpll3", }; +static const char *ldi1_mux_p[] __initdata = { "armpll2", "armpll4", + "armpll3", "armpll5", }; +static const char *rclk_hsic_p[] __initdata = { "armpll3", "armpll2", }; +static const char *mmc2_mux_p[] __initdata = { "armpll2", "armpll3", }; +static const char *mmc3_mux_p[] __initdata = { "armpll2", "armpll3", }; + + +/* fixed rate clocks */ +static struct hisi_fixed_rate_clock hi3620_fixed_rate_clks[] __initdata = { + { HI3620_OSC32K, "osc32k", NULL, CLK_IS_ROOT, 32768, }, + { HI3620_OSC26M, "osc26m", NULL, CLK_IS_ROOT, 26000000, }, + { HI3620_PCLK, "pclk", NULL, CLK_IS_ROOT, 26000000, }, + { HI3620_PLL_ARM0, "armpll0", NULL, CLK_IS_ROOT, 1600000000, }, + { HI3620_PLL_ARM1, "armpll1", NULL, CLK_IS_ROOT, 1600000000, }, + { HI3620_PLL_PERI, "armpll2", NULL, CLK_IS_ROOT, 1440000000, }, + { HI3620_PLL_USB, "armpll3", NULL, CLK_IS_ROOT, 1440000000, }, + { HI3620_PLL_HDMI, "armpll4", NULL, CLK_IS_ROOT, 1188000000, }, + { HI3620_PLL_GPU, "armpll5", NULL, CLK_IS_ROOT, 1300000000, }, +}; + +/* fixed factor clocks */ +static struct hisi_fixed_factor_clock hi3620_fixed_factor_clks[] __initdata = { + { HI3620_RCLK_TCXO, "rclk_tcxo", "osc26m", 1, 4, 0, }, + { HI3620_RCLK_CFGAXI, "rclk_cfgaxi", "armpll2", 1, 30, 0, }, + { HI3620_RCLK_PICO, "rclk_pico", "hsic_div", 1, 40, 0, }, +}; + +static struct hisi_mux_clock hi3620_mux_clks[] __initdata = { + { HI3620_TIMER0_MUX, "timer0_mux", timer0_mux_p, ARRAY_SIZE(timer0_mux_p), CLK_SET_RATE_PARENT, 0, 15, 2, 0, }, + { HI3620_TIMER1_MUX, "timer1_mux", timer1_mux_p, ARRAY_SIZE(timer1_mux_p), CLK_SET_RATE_PARENT, 0, 17, 2, 0, }, + { HI3620_TIMER2_MUX, "timer2_mux", timer2_mux_p, ARRAY_SIZE(timer2_mux_p), CLK_SET_RATE_PARENT, 0, 19, 2, 0, }, + { HI3620_TIMER3_MUX, "timer3_mux", timer3_mux_p, ARRAY_SIZE(timer3_mux_p), CLK_SET_RATE_PARENT, 0, 21, 2, 0, }, + { HI3620_TIMER4_MUX, "timer4_mux", timer4_mux_p, ARRAY_SIZE(timer4_mux_p), CLK_SET_RATE_PARENT, 0x18, 0, 2, 0, }, + { HI3620_TIMER5_MUX, "timer5_mux", timer5_mux_p, ARRAY_SIZE(timer5_mux_p), CLK_SET_RATE_PARENT, 0x18, 2, 2, 0, }, + { HI3620_TIMER6_MUX, "timer6_mux", timer6_mux_p, ARRAY_SIZE(timer6_mux_p), CLK_SET_RATE_PARENT, 0x18, 4, 2, 0, }, + { HI3620_TIMER7_MUX, "timer7_mux", timer7_mux_p, ARRAY_SIZE(timer7_mux_p), CLK_SET_RATE_PARENT, 0x18, 6, 2, 0, }, + { HI3620_TIMER8_MUX, "timer8_mux", timer8_mux_p, ARRAY_SIZE(timer8_mux_p), CLK_SET_RATE_PARENT, 0x18, 8, 2, 0, }, + { HI3620_TIMER9_MUX, "timer9_mux", timer9_mux_p, ARRAY_SIZE(timer9_mux_p), CLK_SET_RATE_PARENT, 0x18, 10, 2, 0, }, + { HI3620_UART0_MUX, "uart0_mux", uart0_mux_p, ARRAY_SIZE(uart0_mux_p), CLK_SET_RATE_PARENT, 0x100, 7, 1, CLK_MUX_HIWORD_MASK, }, + { HI3620_UART1_MUX, "uart1_mux", uart1_mux_p, ARRAY_SIZE(uart1_mux_p), CLK_SET_RATE_PARENT, 0x100, 8, 1, CLK_MUX_HIWORD_MASK, }, + { HI3620_UART2_MUX, "uart2_mux", uart2_mux_p, ARRAY_SIZE(uart2_mux_p), CLK_SET_RATE_PARENT, 0x100, 9, 1, CLK_MUX_HIWORD_MASK, }, + { HI3620_UART3_MUX, "uart3_mux", uart3_mux_p, ARRAY_SIZE(uart3_mux_p), CLK_SET_RATE_PARENT, 0x100, 10, 1, CLK_MUX_HIWORD_MASK, }, + { HI3620_UART4_MUX, "uart4_mux", uart4_mux_p, ARRAY_SIZE(uart4_mux_p), CLK_SET_RATE_PARENT, 0x100, 11, 1, CLK_MUX_HIWORD_MASK, }, + { HI3620_SPI0_MUX, "spi0_mux", spi0_mux_p, ARRAY_SIZE(spi0_mux_p), CLK_SET_RATE_PARENT, 0x100, 12, 1, CLK_MUX_HIWORD_MASK, }, + { HI3620_SPI1_MUX, "spi1_mux", spi1_mux_p, ARRAY_SIZE(spi1_mux_p), CLK_SET_RATE_PARENT, 0x100, 13, 1, CLK_MUX_HIWORD_MASK, }, + { HI3620_SPI2_MUX, "spi2_mux", spi2_mux_p, ARRAY_SIZE(spi2_mux_p), CLK_SET_RATE_PARENT, 0x100, 14, 1, CLK_MUX_HIWORD_MASK, }, + { HI3620_SAXI_MUX, "saxi_mux", saxi_mux_p, ARRAY_SIZE(saxi_mux_p), CLK_SET_RATE_PARENT, 0x100, 15, 1, CLK_MUX_HIWORD_MASK, }, + { HI3620_PWM0_MUX, "pwm0_mux", pwm0_mux_p, ARRAY_SIZE(pwm0_mux_p), CLK_SET_RATE_PARENT, 0x104, 10, 1, CLK_MUX_HIWORD_MASK, }, + { HI3620_PWM1_MUX, "pwm1_mux", pwm1_mux_p, ARRAY_SIZE(pwm1_mux_p), CLK_SET_RATE_PARENT, 0x104, 11, 1, CLK_MUX_HIWORD_MASK, }, + { HI3620_SD_MUX, "sd_mux", sd_mux_p, ARRAY_SIZE(sd_mux_p), CLK_SET_RATE_PARENT, 0x108, 4, 1, CLK_MUX_HIWORD_MASK, }, + { HI3620_MMC1_MUX, "mmc1_mux", mmc1_mux_p, ARRAY_SIZE(mmc1_mux_p), CLK_SET_RATE_PARENT, 0x108, 9, 1, CLK_MUX_HIWORD_MASK, }, + { HI3620_MMC1_MUX2, "mmc1_mux2", mmc1_mux2_p, ARRAY_SIZE(mmc1_mux2_p), CLK_SET_RATE_PARENT, 0x108, 10, 1, CLK_MUX_HIWORD_MASK, }, + { HI3620_G2D_MUX, "g2d_mux", g2d_mux_p, ARRAY_SIZE(g2d_mux_p), CLK_SET_RATE_PARENT, 0x10c, 5, 1, CLK_MUX_HIWORD_MASK, }, + { HI3620_VENC_MUX, "venc_mux", venc_mux_p, ARRAY_SIZE(venc_mux_p), CLK_SET_RATE_PARENT, 0x10c, 11, 1, CLK_MUX_HIWORD_MASK, }, + { HI3620_VDEC_MUX, "vdec_mux", vdec_mux_p, ARRAY_SIZE(vdec_mux_p), CLK_SET_RATE_PARENT, 0x110, 5, 1, CLK_MUX_HIWORD_MASK, }, + { HI3620_VPP_MUX, "vpp_mux", vpp_mux_p, ARRAY_SIZE(vpp_mux_p), CLK_SET_RATE_PARENT, 0x110, 11, 1, CLK_MUX_HIWORD_MASK, }, + { HI3620_EDC0_MUX, "edc0_mux", edc0_mux_p, ARRAY_SIZE(edc0_mux_p), CLK_SET_RATE_PARENT, 0x114, 6, 1, CLK_MUX_HIWORD_MASK, }, + { HI3620_LDI0_MUX, "ldi0_mux", ldi0_mux_p, ARRAY_SIZE(ldi0_mux_p), CLK_SET_RATE_PARENT, 0x114, 13, 2, CLK_MUX_HIWORD_MASK, }, + { HI3620_EDC1_MUX, "edc1_mux", edc1_mux_p, ARRAY_SIZE(edc1_mux_p), CLK_SET_RATE_PARENT, 0x118, 6, 1, CLK_MUX_HIWORD_MASK, }, + { HI3620_LDI1_MUX, "ldi1_mux", ldi1_mux_p, ARRAY_SIZE(ldi1_mux_p), CLK_SET_RATE_PARENT, 0x118, 14, 2, CLK_MUX_HIWORD_MASK, }, + { HI3620_RCLK_HSIC, "rclk_hsic", rclk_hsic_p, ARRAY_SIZE(rclk_hsic_p), CLK_SET_RATE_PARENT, 0x130, 2, 1, CLK_MUX_HIWORD_MASK, }, + { HI3620_MMC2_MUX, "mmc2_mux", mmc2_mux_p, ARRAY_SIZE(mmc2_mux_p), CLK_SET_RATE_PARENT, 0x140, 4, 1, CLK_MUX_HIWORD_MASK, }, + { HI3620_MMC3_MUX, "mmc3_mux", mmc3_mux_p, ARRAY_SIZE(mmc3_mux_p), CLK_SET_RATE_PARENT, 0x140, 9, 1, CLK_MUX_HIWORD_MASK, }, +}; + +static struct hisi_divider_clock hi3620_div_clks[] __initdata = { + { HI3620_SHAREAXI_DIV, "saxi_div", "saxi_mux", 0, 0x100, 0, 5, CLK_DIVIDER_HIWORD_MASK, NULL, }, + { HI3620_CFGAXI_DIV, "cfgaxi_div", "saxi_div", 0, 0x100, 5, 2, CLK_DIVIDER_HIWORD_MASK, NULL, }, + { HI3620_SD_DIV, "sd_div", "sd_mux", 0, 0x108, 0, 4, CLK_DIVIDER_HIWORD_MASK, NULL, }, + { HI3620_MMC1_DIV, "mmc1_div", "mmc1_mux", 0, 0x108, 5, 4, CLK_DIVIDER_HIWORD_MASK, NULL, }, + { HI3620_HSIC_DIV, "hsic_div", "rclk_hsic", 0, 0x130, 0, 2, CLK_DIVIDER_HIWORD_MASK, NULL, }, + { HI3620_MMC2_DIV, "mmc2_div", "mmc2_mux", 0, 0x140, 0, 4, CLK_DIVIDER_HIWORD_MASK, NULL, }, + { HI3620_MMC3_DIV, "mmc3_div", "mmc3_mux", 0, 0x140, 5, 4, CLK_DIVIDER_HIWORD_MASK, NULL, }, +}; + +static struct hisi_gate_clock hi3620_seperated_gate_clks[] __initdata = { + { HI3620_TIMERCLK01, "timerclk01", "timer_rclk01", CLK_SET_RATE_PARENT, 0x20, 0, 0, }, + { HI3620_TIMER_RCLK01, "timer_rclk01", "rclk_tcxo", CLK_SET_RATE_PARENT, 0x20, 1, 0, }, + { HI3620_TIMERCLK23, "timerclk23", "timer_rclk23", CLK_SET_RATE_PARENT, 0x20, 2, 0, }, + { HI3620_TIMER_RCLK23, "timer_rclk23", "rclk_tcxo", CLK_SET_RATE_PARENT, 0x20, 3, 0, }, + { HI3620_RTCCLK, "rtcclk", "pclk", CLK_SET_RATE_PARENT, 0x20, 5, 0, }, + { HI3620_KPC_CLK, "kpc_clk", "pclk", CLK_SET_RATE_PARENT, 0x20, 6, 0, }, + { HI3620_GPIOCLK0, "gpioclk0", "pclk", CLK_SET_RATE_PARENT, 0x20, 8, 0, }, + { HI3620_GPIOCLK1, "gpioclk1", "pclk", CLK_SET_RATE_PARENT, 0x20, 9, 0, }, + { HI3620_GPIOCLK2, "gpioclk2", "pclk", CLK_SET_RATE_PARENT, 0x20, 10, 0, }, + { HI3620_GPIOCLK3, "gpioclk3", "pclk", CLK_SET_RATE_PARENT, 0x20, 11, 0, }, + { HI3620_GPIOCLK4, "gpioclk4", "pclk", CLK_SET_RATE_PARENT, 0x20, 12, 0, }, + { HI3620_GPIOCLK5, "gpioclk5", "pclk", CLK_SET_RATE_PARENT, 0x20, 13, 0, }, + { HI3620_GPIOCLK6, "gpioclk6", "pclk", CLK_SET_RATE_PARENT, 0x20, 14, 0, }, + { HI3620_GPIOCLK7, "gpioclk7", "pclk", CLK_SET_RATE_PARENT, 0x20, 15, 0, }, + { HI3620_GPIOCLK8, "gpioclk8", "pclk", CLK_SET_RATE_PARENT, 0x20, 16, 0, }, + { HI3620_GPIOCLK9, "gpioclk9", "pclk", CLK_SET_RATE_PARENT, 0x20, 17, 0, }, + { HI3620_GPIOCLK10, "gpioclk10", "pclk", CLK_SET_RATE_PARENT, 0x20, 18, 0, }, + { HI3620_GPIOCLK11, "gpioclk11", "pclk", CLK_SET_RATE_PARENT, 0x20, 19, 0, }, + { HI3620_GPIOCLK12, "gpioclk12", "pclk", CLK_SET_RATE_PARENT, 0x20, 20, 0, }, + { HI3620_GPIOCLK13, "gpioclk13", "pclk", CLK_SET_RATE_PARENT, 0x20, 21, 0, }, + { HI3620_GPIOCLK14, "gpioclk14", "pclk", CLK_SET_RATE_PARENT, 0x20, 22, 0, }, + { HI3620_GPIOCLK15, "gpioclk15", "pclk", CLK_SET_RATE_PARENT, 0x20, 23, 0, }, + { HI3620_GPIOCLK16, "gpioclk16", "pclk", CLK_SET_RATE_PARENT, 0x20, 24, 0, }, + { HI3620_GPIOCLK17, "gpioclk17", "pclk", CLK_SET_RATE_PARENT, 0x20, 25, 0, }, + { HI3620_GPIOCLK18, "gpioclk18", "pclk", CLK_SET_RATE_PARENT, 0x20, 26, 0, }, + { HI3620_GPIOCLK19, "gpioclk19", "pclk", CLK_SET_RATE_PARENT, 0x20, 27, 0, }, + { HI3620_GPIOCLK20, "gpioclk20", "pclk", CLK_SET_RATE_PARENT, 0x20, 28, 0, }, + { HI3620_GPIOCLK21, "gpioclk21", "pclk", CLK_SET_RATE_PARENT, 0x20, 29, 0, }, + { HI3620_DPHY0_CLK, "dphy0_clk", "osc26m", CLK_SET_RATE_PARENT, 0x30, 15, 0, }, + { HI3620_DPHY1_CLK, "dphy1_clk", "osc26m", CLK_SET_RATE_PARENT, 0x30, 16, 0, }, + { HI3620_DPHY2_CLK, "dphy2_clk", "osc26m", CLK_SET_RATE_PARENT, 0x30, 17, 0, }, + { HI3620_USBPHY_CLK, "usbphy_clk", "rclk_pico", CLK_SET_RATE_PARENT, 0x30, 24, 0, }, + { HI3620_ACP_CLK, "acp_clk", "rclk_cfgaxi", CLK_SET_RATE_PARENT, 0x30, 28, 0, }, + { HI3620_TIMERCLK45, "timerclk45", "rclk_tcxo", CLK_SET_RATE_PARENT, 0x40, 3, 0, }, + { HI3620_TIMERCLK67, "timerclk67", "rclk_tcxo", CLK_SET_RATE_PARENT, 0x40, 4, 0, }, + { HI3620_TIMERCLK89, "timerclk89", "rclk_tcxo", CLK_SET_RATE_PARENT, 0x40, 5, 0, }, + { HI3620_PWMCLK0, "pwmclk0", "pwm0_mux", CLK_SET_RATE_PARENT, 0x40, 7, 0, }, + { HI3620_PWMCLK1, "pwmclk1", "pwm1_mux", CLK_SET_RATE_PARENT, 0x40, 8, 0, }, + { HI3620_UARTCLK0, "uartclk0", "uart0_mux", CLK_SET_RATE_PARENT, 0x40, 16, 0, }, + { HI3620_UARTCLK1, "uartclk1", "uart1_mux", CLK_SET_RATE_PARENT, 0x40, 17, 0, }, + { HI3620_UARTCLK2, "uartclk2", "uart2_mux", CLK_SET_RATE_PARENT, 0x40, 18, 0, }, + { HI3620_UARTCLK3, "uartclk3", "uart3_mux", CLK_SET_RATE_PARENT, 0x40, 19, 0, }, + { HI3620_UARTCLK4, "uartclk4", "uart4_mux", CLK_SET_RATE_PARENT, 0x40, 20, 0, }, + { HI3620_SPICLK0, "spiclk0", "spi0_mux", CLK_SET_RATE_PARENT, 0x40, 21, 0, }, + { HI3620_SPICLK1, "spiclk1", "spi1_mux", CLK_SET_RATE_PARENT, 0x40, 22, 0, }, + { HI3620_SPICLK2, "spiclk2", "spi2_mux", CLK_SET_RATE_PARENT, 0x40, 23, 0, }, + { HI3620_I2CCLK0, "i2cclk0", "pclk", CLK_SET_RATE_PARENT, 0x40, 24, 0, }, + { HI3620_I2CCLK1, "i2cclk1", "pclk", CLK_SET_RATE_PARENT, 0x40, 25, 0, }, + { HI3620_SCI_CLK, "sci_clk", "osc26m", CLK_SET_RATE_PARENT, 0x40, 26, 0, }, + { HI3620_I2CCLK2, "i2cclk2", "pclk", CLK_SET_RATE_PARENT, 0x40, 28, 0, }, + { HI3620_I2CCLK3, "i2cclk3", "pclk", CLK_SET_RATE_PARENT, 0x40, 29, 0, }, + { HI3620_DDRC_PER_CLK, "ddrc_per_clk", "rclk_cfgaxi", CLK_SET_RATE_PARENT, 0x50, 9, 0, }, + { HI3620_DMAC_CLK, "dmac_clk", "rclk_cfgaxi", CLK_SET_RATE_PARENT, 0x50, 10, 0, }, + { HI3620_USB2DVC_CLK, "usb2dvc_clk", "rclk_cfgaxi", CLK_SET_RATE_PARENT, 0x50, 17, 0, }, + { HI3620_SD_CLK, "sd_clk", "sd_div", CLK_SET_RATE_PARENT, 0x50, 20, 0, }, + { HI3620_MMC_CLK1, "mmc_clk1", "mmc1_mux2", CLK_SET_RATE_PARENT, 0x50, 21, 0, }, + { HI3620_MMC_CLK2, "mmc_clk2", "mmc2_div", CLK_SET_RATE_PARENT, 0x50, 22, 0, }, + { HI3620_MMC_CLK3, "mmc_clk3", "mmc3_div", CLK_SET_RATE_PARENT, 0x50, 23, 0, }, + { HI3620_MCU_CLK, "mcu_clk", "acp_clk", CLK_SET_RATE_PARENT, 0x50, 24, 0, }, +}; + +static void __init hi3620_clk_init(struct device_node *np) +{ + void __iomem *base; + + if (np) { + base = of_iomap(np, 0); + if (!base) { + pr_err("failed to map Hi3620 clock registers\n"); + return; + } + } else { + pr_err("failed to find Hi3620 clock node in DTS\n"); + return; + } + + hisi_clk_init(np, HI3620_NR_CLKS); + + hisi_clk_register_fixed_rate(hi3620_fixed_rate_clks, + ARRAY_SIZE(hi3620_fixed_rate_clks), + base); + hisi_clk_register_fixed_factor(hi3620_fixed_factor_clks, + ARRAY_SIZE(hi3620_fixed_factor_clks), + base); + hisi_clk_register_mux(hi3620_mux_clks, ARRAY_SIZE(hi3620_mux_clks), + base); + hisi_clk_register_divider(hi3620_div_clks, ARRAY_SIZE(hi3620_div_clks), + base); + hisi_clk_register_gate_sep(hi3620_seperated_gate_clks, + ARRAY_SIZE(hi3620_seperated_gate_clks), + base); +} +CLK_OF_DECLARE(hi3620_clk, "hisilicon,hi3620-clock", hi3620_clk_init); diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c new file mode 100644 index 000000000000..a3a7152c92d9 --- /dev/null +++ b/drivers/clk/hisilicon/clk.c @@ -0,0 +1,171 @@ +/* + * Hisilicon clock driver + * + * Copyright (c) 2012-2013 Hisilicon Limited. + * Copyright (c) 2012-2013 Linaro Limited. + * + * Author: Haojian Zhuang <haojian.zhuang@linaro.org> + * Xin Li <li.xin@linaro.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include <linux/kernel.h> +#include <linux/clk-provider.h> +#include <linux/clkdev.h> +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/slab.h> +#include <linux/clk.h> + +#include "clk.h" + +static DEFINE_SPINLOCK(hisi_clk_lock); +static struct clk **clk_table; +static struct clk_onecell_data clk_data; + +void __init hisi_clk_init(struct device_node *np, int nr_clks) +{ + clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL); + if (!clk_table) { + pr_err("%s: could not allocate clock lookup table\n", __func__); + return; + } + clk_data.clks = clk_table; + clk_data.clk_num = nr_clks; + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); +} + +void __init hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *clks, + int nums, void __iomem *base) +{ + struct clk *clk; + int i; + + for (i = 0; i < nums; i++) { + clk = clk_register_fixed_rate(NULL, clks[i].name, + clks[i].parent_name, + clks[i].flags, + clks[i].fixed_rate); + if (IS_ERR(clk)) { + pr_err("%s: failed to register clock %s\n", + __func__, clks[i].name); + continue; + } + } +} + +void __init hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *clks, + int nums, void __iomem *base) +{ + struct clk *clk; + int i; + + for (i = 0; i < nums; i++) { + clk = clk_register_fixed_factor(NULL, clks[i].name, + clks[i].parent_name, + clks[i].flags, clks[i].mult, + clks[i].div); + if (IS_ERR(clk)) { + pr_err("%s: failed to register clock %s\n", + __func__, clks[i].name); + continue; + } + } +} + +void __init hisi_clk_register_mux(struct hisi_mux_clock *clks, + int nums, void __iomem *base) +{ + struct clk *clk; + int i; + + for (i = 0; i < nums; i++) { + clk = clk_register_mux(NULL, clks[i].name, clks[i].parent_names, + clks[i].num_parents, clks[i].flags, + base + clks[i].offset, clks[i].shift, + clks[i].width, clks[i].mux_flags, + &hisi_clk_lock); + if (IS_ERR(clk)) { + pr_err("%s: failed to register clock %s\n", + __func__, clks[i].name); + continue; + } + + if (clks[i].alias) + clk_register_clkdev(clk, clks[i].alias, NULL); + + clk_table[clks[i].id] = clk; + } +} + +void __init hisi_clk_register_divider(struct hisi_divider_clock *clks, + int nums, void __iomem *base) +{ + struct clk *clk; + int i; + + for (i = 0; i < nums; i++) { + clk = clk_register_divider_table(NULL, clks[i].name, + clks[i].parent_name, + clks[i].flags, + base + clks[i].offset, + clks[i].shift, clks[i].width, + clks[i].div_flags, + clks[i].table, + &hisi_clk_lock); + if (IS_ERR(clk)) { + pr_err("%s: failed to register clock %s\n", + __func__, clks[i].name); + continue; + } + + if (clks[i].alias) + clk_register_clkdev(clk, clks[i].alias, NULL); + + clk_table[clks[i].id] = clk; + } +} + +void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *clks, + int nums, void __iomem *base) +{ + struct clk *clk; + int i; + + for (i = 0; i < nums; i++) { + clk = hisi_register_clkgate_sep(NULL, clks[i].name, + clks[i].parent_name, + clks[i].flags, + base + clks[i].offset, + clks[i].bit_idx, + clks[i].gate_flags, + &hisi_clk_lock); + if (IS_ERR(clk)) { + pr_err("%s: failed to register clock %s\n", + __func__, clks[i].name); + continue; + } + + if (clks[i].alias) + clk_register_clkdev(clk, clks[i].alias, NULL); + + clk_table[clks[i].id] = clk; + } +} diff --git a/drivers/clk/hisilicon/clk.h b/drivers/clk/hisilicon/clk.h new file mode 100644 index 000000000000..4a6beebefb7a --- /dev/null +++ b/drivers/clk/hisilicon/clk.h @@ -0,0 +1,103 @@ +/* + * Hisilicon Hi3620 clock gate driver + * + * Copyright (c) 2012-2013 Hisilicon Limited. + * Copyright (c) 2012-2013 Linaro Limited. + * + * Author: Haojian Zhuang <haojian.zhuang@linaro.org> + * Xin Li <li.xin@linaro.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifndef __HISI_CLK_H +#define __HISI_CLK_H + +#include <linux/clk-provider.h> +#include <linux/io.h> +#include <linux/spinlock.h> + +struct hisi_fixed_rate_clock { + unsigned int id; + char *name; + const char *parent_name; + unsigned long flags; + unsigned long fixed_rate; +}; + +struct hisi_fixed_factor_clock { + unsigned int id; + char *name; + const char *parent_name; + unsigned long mult; + unsigned long div; + unsigned long flags; +}; + +struct hisi_mux_clock { + unsigned int id; + const char *name; + const char **parent_names; + u8 num_parents; + unsigned long flags; + unsigned long offset; + u8 shift; + u8 width; + u8 mux_flags; + const char *alias; +}; + +struct hisi_divider_clock { + unsigned int id; + const char *name; + const char *parent_name; + unsigned long flags; + unsigned long offset; + u8 shift; + u8 width; + u8 div_flags; + struct clk_div_table *table; + const char *alias; +}; + +struct hisi_gate_clock { + unsigned int id; + const char *name; + const char *parent_name; + unsigned long flags; + unsigned long offset; + u8 bit_idx; + u8 gate_flags; + const char *alias; +}; + +struct clk *hisi_register_clkgate_sep(struct device *, const char *, + const char *, unsigned long, + void __iomem *, u8, + u8, spinlock_t *); + +void __init hisi_clk_init(struct device_node *, int); +void __init hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *, + int, void __iomem *); +void __init hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *, + int, void __iomem *); +void __init hisi_clk_register_mux(struct hisi_mux_clock *, int, + void __iomem *); +void __init hisi_clk_register_divider(struct hisi_divider_clock *, + int, void __iomem *); +void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *, + int, void __iomem *); +#endif /* __HISI_CLK_H */ diff --git a/drivers/clk/hisilicon/clkgate-separated.c b/drivers/clk/hisilicon/clkgate-separated.c new file mode 100644 index 000000000000..b03d5a7246f9 --- /dev/null +++ b/drivers/clk/hisilicon/clkgate-separated.c @@ -0,0 +1,130 @@ +/* + * Hisilicon clock separated gate driver + * + * Copyright (c) 2012-2013 Hisilicon Limited. + * Copyright (c) 2012-2013 Linaro Limited. + * + * Author: Haojian Zhuang <haojian.zhuang@linaro.org> + * Xin Li <li.xin@linaro.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include <linux/kernel.h> +#include <linux/clk-provider.h> +#include <linux/clkdev.h> +#include <linux/io.h> +#include <linux/slab.h> +#include <linux/clk.h> + +#include "clk.h" + +/* clock separated gate register offset */ +#define CLKGATE_SEPERATED_ENABLE 0x0 +#define CLKGATE_SEPERATED_DISABLE 0x4 +#define CLKGATE_SEPERATED_STATUS 0x8 + +struct clkgate_separated { + struct clk_hw hw; + void __iomem *enable; /* enable register */ + u8 bit_idx; /* bits in enable/disable register */ + u8 flags; + spinlock_t *lock; +}; + +static int clkgate_separated_enable(struct clk_hw *hw) +{ + struct clkgate_separated *sclk; + unsigned long flags = 0; + u32 reg; + + sclk = container_of(hw, struct clkgate_separated, hw); + if (sclk->lock) + spin_lock_irqsave(sclk->lock, flags); + reg = BIT(sclk->bit_idx); + writel_relaxed(reg, sclk->enable); + readl_relaxed(sclk->enable + CLKGATE_SEPERATED_STATUS); + if (sclk->lock) + spin_unlock_irqrestore(sclk->lock, flags); + return 0; +} + +static void clkgate_separated_disable(struct clk_hw *hw) +{ + struct clkgate_separated *sclk; + unsigned long flags = 0; + u32 reg; + + sclk = container_of(hw, struct clkgate_separated, hw); + if (sclk->lock) + spin_lock_irqsave(sclk->lock, flags); + reg = BIT(sclk->bit_idx); + writel_relaxed(reg, sclk->enable + CLKGATE_SEPERATED_DISABLE); + readl_relaxed(sclk->enable + CLKGATE_SEPERATED_STATUS); + if (sclk->lock) + spin_unlock_irqrestore(sclk->lock, flags); +} + +static int clkgate_separated_is_enabled(struct clk_hw *hw) +{ + struct clkgate_separated *sclk; + u32 reg; + + sclk = container_of(hw, struct clkgate_separated, hw); + reg = readl_relaxed(sclk->enable + CLKGATE_SEPERATED_STATUS); + reg &= BIT(sclk->bit_idx); + + return reg ? 1 : 0; +} + +static struct clk_ops clkgate_separated_ops = { + .enable = clkgate_separated_enable, + .disable = clkgate_separated_disable, + .is_enabled = clkgate_separated_is_enabled, +}; + +struct clk *hisi_register_clkgate_sep(struct device *dev, const char *name, + const char *parent_name, + unsigned long flags, + void __iomem *reg, u8 bit_idx, + u8 clk_gate_flags, spinlock_t *lock) +{ + struct clkgate_separated *sclk; + struct clk *clk; + struct clk_init_data init; + + sclk = kzalloc(sizeof(*sclk), GFP_KERNEL); + if (!sclk) { + pr_err("%s: fail to allocate separated gated clk\n", __func__); + return ERR_PTR(-ENOMEM); + } + + init.name = name; + init.ops = &clkgate_separated_ops; + init.flags = flags | CLK_IS_BASIC; + init.parent_names = (parent_name ? &parent_name : NULL); + init.num_parents = (parent_name ? 1 : 0); + + sclk->enable = reg + CLKGATE_SEPERATED_ENABLE; + sclk->bit_idx = bit_idx; + sclk->flags = clk_gate_flags; + sclk->hw.init = &init; + + clk = clk_register(dev, &sclk->hw); + if (IS_ERR(clk)) + kfree(sclk); + return clk; +} diff --git a/drivers/clk/keystone/gate.c b/drivers/clk/keystone/gate.c index 1f333bcfc22e..17a598398a53 100644 --- a/drivers/clk/keystone/gate.c +++ b/drivers/clk/keystone/gate.c @@ -223,8 +223,7 @@ static void __init of_psc_clk_init(struct device_node *node, spinlock_t *lock) data->domain_base = of_iomap(node, i); if (!data->domain_base) { pr_err("%s: domain ioremap failed\n", __func__); - iounmap(data->control_base); - goto out; + goto unmap_ctrl; } of_property_read_u32(node, "domain-id", &data->domain_id); @@ -237,16 +236,21 @@ static void __init of_psc_clk_init(struct device_node *node, spinlock_t *lock) parent_name = of_clk_get_parent_name(node, 0); if (!parent_name) { pr_err("%s: Parent clock not found\n", __func__); - goto out; + goto unmap_domain; } clk = clk_register_psc(NULL, clk_name, parent_name, data, lock); - if (clk) { + if (!IS_ERR(clk)) { of_clk_add_provider(node, of_clk_src_simple_get, clk); return; } pr_err("%s: error registering clk %s\n", __func__, node->name); + +unmap_domain: + iounmap(data->domain_base); +unmap_ctrl: + iounmap(data->control_base); out: kfree(data); return; diff --git a/drivers/clk/keystone/pll.c b/drivers/clk/keystone/pll.c index 47a1bd9f1726..0dd8a4b12747 100644 --- a/drivers/clk/keystone/pll.c +++ b/drivers/clk/keystone/pll.c @@ -24,6 +24,8 @@ #define MAIN_PLLM_HIGH_MASK 0x7f000 #define PLLM_HIGH_SHIFT 6 #define PLLD_MASK 0x3f +#define CLKOD_MASK 0x780000 +#define CLKOD_SHIFT 19 /** * struct clk_pll_data - pll data structure @@ -41,7 +43,10 @@ * @pllm_upper_mask: multiplier upper mask * @pllm_upper_shift: multiplier upper shift * @plld_mask: divider mask - * @postdiv: Post divider + * @clkod_mask: output divider mask + * @clkod_shift: output divider shift + * @plld_mask: divider mask + * @postdiv: Fixed post divider */ struct clk_pll_data { bool has_pllctrl; @@ -53,6 +58,8 @@ struct clk_pll_data { u32 pllm_upper_mask; u32 pllm_upper_shift; u32 plld_mask; + u32 clkod_mask; + u32 clkod_shift; u32 postdiv; }; @@ -90,7 +97,13 @@ static unsigned long clk_pllclk_recalc(struct clk_hw *hw, mult |= ((val & pll_data->pllm_upper_mask) >> pll_data->pllm_upper_shift); prediv = (val & pll_data->plld_mask); - postdiv = pll_data->postdiv; + + if (!pll_data->has_pllctrl) + /* read post divider from od bits*/ + postdiv = ((val & pll_data->clkod_mask) >> + pll_data->clkod_shift) + 1; + else + postdiv = pll_data->postdiv; rate /= (prediv + 1); rate = (rate * (mult + 1)); @@ -155,8 +168,11 @@ static void __init _of_pll_clk_init(struct device_node *node, bool pllctrl) } parent_name = of_clk_get_parent_name(node, 0); - if (of_property_read_u32(node, "fixed-postdiv", &pll_data->postdiv)) - goto out; + if (of_property_read_u32(node, "fixed-postdiv", &pll_data->postdiv)) { + /* assume the PLL has output divider register bits */ + pll_data->clkod_mask = CLKOD_MASK; + pll_data->clkod_shift = CLKOD_SHIFT; + } i = of_property_match_string(node, "reg-names", "control"); pll_data->pll_ctl0 = of_iomap(node, i); diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig index 0b0f3e729cf7..c339b829d3e3 100644 --- a/drivers/clk/mvebu/Kconfig +++ b/drivers/clk/mvebu/Kconfig @@ -4,15 +4,20 @@ config MVEBU_CLK_COMMON config MVEBU_CLK_CPU bool +config MVEBU_CLK_COREDIV + bool + config ARMADA_370_CLK bool select MVEBU_CLK_COMMON select MVEBU_CLK_CPU + select MVEBU_CLK_COREDIV config ARMADA_XP_CLK bool select MVEBU_CLK_COMMON select MVEBU_CLK_CPU + select MVEBU_CLK_COREDIV config DOVE_CLK bool diff --git a/drivers/clk/mvebu/Makefile b/drivers/clk/mvebu/Makefile index 1c7e70c63fb2..21bbfb4a9f42 100644 --- a/drivers/clk/mvebu/Makefile +++ b/drivers/clk/mvebu/Makefile @@ -1,5 +1,6 @@ obj-$(CONFIG_MVEBU_CLK_COMMON) += common.o obj-$(CONFIG_MVEBU_CLK_CPU) += clk-cpu.o +obj-$(CONFIG_MVEBU_CLK_COREDIV) += clk-corediv.o obj-$(CONFIG_ARMADA_370_CLK) += armada-370.o obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o diff --git a/drivers/clk/mvebu/clk-corediv.c b/drivers/clk/mvebu/clk-corediv.c new file mode 100644 index 000000000000..7162615bcdcd --- /dev/null +++ b/drivers/clk/mvebu/clk-corediv.c @@ -0,0 +1,223 @@ +/* + * MVEBU Core divider clock + * + * Copyright (C) 2013 Marvell + * + * Ezequiel Garcia <ezequiel.garcia@free-electrons.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <linux/kernel.h> +#include <linux/clk-provider.h> +#include <linux/of_address.h> +#include <linux/slab.h> +#include <linux/delay.h> +#include "common.h" + +#define CORE_CLK_DIV_RATIO_MASK 0xff +#define CORE_CLK_DIV_RATIO_RELOAD BIT(8) +#define CORE_CLK_DIV_ENABLE_OFFSET 24 +#define CORE_CLK_DIV_RATIO_OFFSET 0x8 + +struct clk_corediv_desc { + unsigned int mask; + unsigned int offset; + unsigned int fieldbit; +}; + +struct clk_corediv { + struct clk_hw hw; + void __iomem *reg; + struct clk_corediv_desc desc; + spinlock_t lock; +}; + +static struct clk_onecell_data clk_data; + +static const struct clk_corediv_desc mvebu_corediv_desc[] __initconst = { + { .mask = 0x3f, .offset = 8, .fieldbit = 1 }, /* NAND clock */ +}; + +#define to_corediv_clk(p) container_of(p, struct clk_corediv, hw) + +static int clk_corediv_is_enabled(struct clk_hw *hwclk) +{ + struct clk_corediv *corediv = to_corediv_clk(hwclk); + struct clk_corediv_desc *desc = &corediv->desc; + u32 enable_mask = BIT(desc->fieldbit) << CORE_CLK_DIV_ENABLE_OFFSET; + + return !!(readl(corediv->reg) & enable_mask); +} + +static int clk_corediv_enable(struct clk_hw *hwclk) +{ + struct clk_corediv *corediv = to_corediv_clk(hwclk); + struct clk_corediv_desc *desc = &corediv->desc; + unsigned long flags = 0; + u32 reg; + + spin_lock_irqsave(&corediv->lock, flags); + + reg = readl(corediv->reg); + reg |= (BIT(desc->fieldbit) << CORE_CLK_DIV_ENABLE_OFFSET); + writel(reg, corediv->reg); + + spin_unlock_irqrestore(&corediv->lock, flags); + + return 0; +} + +static void clk_corediv_disable(struct clk_hw *hwclk) +{ + struct clk_corediv *corediv = to_corediv_clk(hwclk); + struct clk_corediv_desc *desc = &corediv->desc; + unsigned long flags = 0; + u32 reg; + + spin_lock_irqsave(&corediv->lock, flags); + + reg = readl(corediv->reg); + reg &= ~(BIT(desc->fieldbit) << CORE_CLK_DIV_ENABLE_OFFSET); + writel(reg, corediv->reg); + + spin_unlock_irqrestore(&corediv->lock, flags); +} + +static unsigned long clk_corediv_recalc_rate(struct clk_hw *hwclk, + unsigned long parent_rate) +{ + struct clk_corediv *corediv = to_corediv_clk(hwclk); + struct clk_corediv_desc *desc = &corediv->desc; + u32 reg, div; + + reg = readl(corediv->reg + CORE_CLK_DIV_RATIO_OFFSET); + div = (reg >> desc->offset) & desc->mask; + return parent_rate / div; +} + +static long clk_corediv_round_rate(struct clk_hw *hwclk, unsigned long rate, + unsigned long *parent_rate) +{ + /* Valid ratio are 1:4, 1:5, 1:6 and 1:8 */ + u32 div; + + div = *parent_rate / rate; + if (div < 4) + div = 4; + else if (div > 6) + div = 8; + + return *parent_rate / div; +} + +static int clk_corediv_set_rate(struct clk_hw *hwclk, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_corediv *corediv = to_corediv_clk(hwclk); + struct clk_corediv_desc *desc = &corediv->desc; + unsigned long flags = 0; + u32 reg, div; + + div = parent_rate / rate; + + spin_lock_irqsave(&corediv->lock, flags); + + /* Write new divider to the divider ratio register */ + reg = readl(corediv->reg + CORE_CLK_DIV_RATIO_OFFSET); + reg &= ~(desc->mask << desc->offset); + reg |= (div & desc->mask) << desc->offset; + writel(reg, corediv->reg + CORE_CLK_DIV_RATIO_OFFSET); + + /* Set reload-force for this clock */ + reg = readl(corediv->reg) | BIT(desc->fieldbit); + writel(reg, corediv->reg); + + /* Now trigger the clock update */ + reg = readl(corediv->reg) | CORE_CLK_DIV_RATIO_RELOAD; + writel(reg, corediv->reg); + + /* + * Wait for clocks to settle down, and then clear all the + * ratios request and the reload request. + */ + udelay(1000); + reg &= ~(CORE_CLK_DIV_RATIO_MASK | CORE_CLK_DIV_RATIO_RELOAD); + writel(reg, corediv->reg); + udelay(1000); + + spin_unlock_irqrestore(&corediv->lock, flags); + + return 0; +} + +static const struct clk_ops corediv_ops = { + .enable = clk_corediv_enable, + .disable = clk_corediv_disable, + .is_enabled = clk_corediv_is_enabled, + .recalc_rate = clk_corediv_recalc_rate, + .round_rate = clk_corediv_round_rate, + .set_rate = clk_corediv_set_rate, +}; + +static void __init mvebu_corediv_clk_init(struct device_node *node) +{ + struct clk_init_data init; + struct clk_corediv *corediv; + struct clk **clks; + void __iomem *base; + const char *parent_name; + const char *clk_name; + int i; + + base = of_iomap(node, 0); + if (WARN_ON(!base)) + return; + + parent_name = of_clk_get_parent_name(node, 0); + + clk_data.clk_num = ARRAY_SIZE(mvebu_corediv_desc); + + /* clks holds the clock array */ + clks = kcalloc(clk_data.clk_num, sizeof(struct clk *), + GFP_KERNEL); + if (WARN_ON(!clks)) + goto err_unmap; + /* corediv holds the clock specific array */ + corediv = kcalloc(clk_data.clk_num, sizeof(struct clk_corediv), + GFP_KERNEL); + if (WARN_ON(!corediv)) + goto err_free_clks; + + spin_lock_init(&corediv->lock); + + for (i = 0; i < clk_data.clk_num; i++) { + of_property_read_string_index(node, "clock-output-names", + i, &clk_name); + init.num_parents = 1; + init.parent_names = &parent_name; + init.name = clk_name; + init.ops = &corediv_ops; + init.flags = 0; + + corediv[i].desc = mvebu_corediv_desc[i]; + corediv[i].reg = base; + corediv[i].hw.init = &init; + + clks[i] = clk_register(NULL, &corediv[i].hw); + WARN_ON(IS_ERR(clks[i])); + } + + clk_data.clks = clks; + of_clk_add_provider(node, of_clk_src_onecell_get, &clk_data); + return; + +err_free_clks: + kfree(clks); +err_unmap: + iounmap(base); +} +CLK_OF_DECLARE(mvebu_corediv_clk, "marvell,armada-370-corediv-clock", + mvebu_corediv_clk_init); diff --git a/drivers/clk/mvebu/clk-cpu.c b/drivers/clk/mvebu/clk-cpu.c index 1466865b0743..8ebf757d29e2 100644 --- a/drivers/clk/mvebu/clk-cpu.c +++ b/drivers/clk/mvebu/clk-cpu.c @@ -101,7 +101,7 @@ static const struct clk_ops cpu_ops = { .set_rate = clk_cpu_set_rate, }; -void __init of_cpu_clk_setup(struct device_node *node) +static void __init of_cpu_clk_setup(struct device_node *node) { struct cpu_clk *cpuclk; void __iomem *clock_complex_base = of_iomap(node, 0); diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig new file mode 100644 index 000000000000..995bcfa021a4 --- /dev/null +++ b/drivers/clk/qcom/Kconfig @@ -0,0 +1,47 @@ +config COMMON_CLK_QCOM + tristate "Support for Qualcomm's clock controllers" + depends on OF + select REGMAP_MMIO + select RESET_CONTROLLER + +config MSM_GCC_8660 + tristate "MSM8660 Global Clock Controller" + depends on COMMON_CLK_QCOM + help + Support for the global clock controller on msm8660 devices. + Say Y if you want to use peripheral devices such as UART, SPI, + i2c, USB, SD/eMMC, etc. + +config MSM_GCC_8960 + tristate "MSM8960 Global Clock Controller" + depends on COMMON_CLK_QCOM + help + Support for the global clock controller on msm8960 devices. + Say Y if you want to use peripheral devices such as UART, SPI, + i2c, USB, SD/eMMC, SATA, PCIe, etc. + +config MSM_MMCC_8960 + tristate "MSM8960 Multimedia Clock Controller" + select MSM_GCC_8960 + depends on COMMON_CLK_QCOM + help + Support for the multimedia clock controller on msm8960 devices. + Say Y if you want to support multimedia devices such as display, + graphics, video encode/decode, camera, etc. + +config MSM_GCC_8974 + tristate "MSM8974 Global Clock Controller" + depends on COMMON_CLK_QCOM + help + Support for the global clock controller on msm8974 devices. + Say Y if you want to use peripheral devices such as UART, SPI, + i2c, USB, SD/eMMC, SATA, PCIe, etc. + +config MSM_MMCC_8974 + tristate "MSM8974 Multimedia Clock Controller" + select MSM_GCC_8974 + depends on COMMON_CLK_QCOM + help + Support for the multimedia clock controller on msm8974 devices. + Say Y if you want to support multimedia devices such as display, + graphics, video encode/decode, camera, etc. diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile new file mode 100644 index 000000000000..190d38433202 --- /dev/null +++ b/drivers/clk/qcom/Makefile @@ -0,0 +1,14 @@ +obj-$(CONFIG_COMMON_CLK_QCOM) += clk-qcom.o + +clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-regmap.o +clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-pll.o +clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-rcg.o +clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-rcg2.o +clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-branch.o +clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += reset.o + +obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o +obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o +obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o +obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o +obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o diff --git a/drivers/clk/qcom/clk-branch.c b/drivers/clk/qcom/clk-branch.c new file mode 100644 index 000000000000..6b4d2bcb1a53 --- /dev/null +++ b/drivers/clk/qcom/clk-branch.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2013, 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/delay.h> +#include <linux/export.h> +#include <linux/clk-provider.h> +#include <linux/regmap.h> + +#include "clk-branch.h" + +static bool clk_branch_in_hwcg_mode(const struct clk_branch *br) +{ + u32 val; + + if (!br->hwcg_reg) + return 0; + + regmap_read(br->clkr.regmap, br->hwcg_reg, &val); + + return !!(val & BIT(br->hwcg_bit)); +} + +static bool clk_branch_check_halt(const struct clk_branch *br, bool enabling) +{ + bool invert = (br->halt_check == BRANCH_HALT_ENABLE); + u32 val; + + regmap_read(br->clkr.regmap, br->halt_reg, &val); + + val &= BIT(br->halt_bit); + if (invert) + val = !val; + + return !!val == !enabling; +} + +#define BRANCH_CLK_OFF BIT(31) +#define BRANCH_NOC_FSM_STATUS_SHIFT 28 +#define BRANCH_NOC_FSM_STATUS_MASK 0x7 +#define BRANCH_NOC_FSM_STATUS_ON (0x2 << BRANCH_NOC_FSM_STATUS_SHIFT) + +static bool clk_branch2_check_halt(const struct clk_branch *br, bool enabling) +{ + u32 val; + u32 mask; + + mask = BRANCH_NOC_FSM_STATUS_MASK << BRANCH_NOC_FSM_STATUS_SHIFT; + mask |= BRANCH_CLK_OFF; + + regmap_read(br->clkr.regmap, br->halt_reg, &val); + + if (enabling) { + val &= mask; + return (val & BRANCH_CLK_OFF) == 0 || + val == BRANCH_NOC_FSM_STATUS_ON; + } else { + return val & BRANCH_CLK_OFF; + } +} + +static int clk_branch_wait(const struct clk_branch *br, bool enabling, + bool (check_halt)(const struct clk_branch *, bool)) +{ + bool voted = br->halt_check & BRANCH_VOTED; + const char *name = __clk_get_name(br->clkr.hw.clk); + + /* Skip checking halt bit if the clock is in hardware gated mode */ + if (clk_branch_in_hwcg_mode(br)) + return 0; + + if (br->halt_check == BRANCH_HALT_DELAY || (!enabling && voted)) { + udelay(10); + } else if (br->halt_check == BRANCH_HALT_ENABLE || + br->halt_check == BRANCH_HALT || + (enabling && voted)) { + int count = 200; + + while (count-- > 0) { + if (check_halt(br, enabling)) + return 0; + udelay(1); + } + WARN(1, "%s status stuck at 'o%s'", name, + enabling ? "ff" : "n"); + return -EBUSY; + } + return 0; +} + +static int clk_branch_toggle(struct clk_hw *hw, bool en, + bool (check_halt)(const struct clk_branch *, bool)) +{ + struct clk_branch *br = to_clk_branch(hw); + int ret; + + if (en) { + ret = clk_enable_regmap(hw); + if (ret) + return ret; + } else { + clk_disable_regmap(hw); + } + + return clk_branch_wait(br, en, check_halt); +} + +static int clk_branch_enable(struct clk_hw *hw) +{ + return clk_branch_toggle(hw, true, clk_branch_check_halt); +} + +static void clk_branch_disable(struct clk_hw *hw) +{ + clk_branch_toggle(hw, false, clk_branch_check_halt); +} + +const struct clk_ops clk_branch_ops = { + .enable = clk_branch_enable, + .disable = clk_branch_disable, + .is_enabled = clk_is_enabled_regmap, +}; +EXPORT_SYMBOL_GPL(clk_branch_ops); + +static int clk_branch2_enable(struct clk_hw *hw) +{ + return clk_branch_toggle(hw, true, clk_branch2_check_halt); +} + +static void clk_branch2_disable(struct clk_hw *hw) +{ + clk_branch_toggle(hw, false, clk_branch2_check_halt); +} + +const struct clk_ops clk_branch2_ops = { + .enable = clk_branch2_enable, + .disable = clk_branch2_disable, + .is_enabled = clk_is_enabled_regmap, +}; +EXPORT_SYMBOL_GPL(clk_branch2_ops); + +const struct clk_ops clk_branch_simple_ops = { + .enable = clk_enable_regmap, + .disable = clk_disable_regmap, + .is_enabled = clk_is_enabled_regmap, +}; +EXPORT_SYMBOL_GPL(clk_branch_simple_ops); diff --git a/drivers/clk/qcom/clk-branch.h b/drivers/clk/qcom/clk-branch.h new file mode 100644 index 000000000000..284df3f3c55f --- /dev/null +++ b/drivers/clk/qcom/clk-branch.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013, 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_BRANCH_H__ +#define __QCOM_CLK_BRANCH_H__ + +#include <linux/clk-provider.h> + +#include "clk-regmap.h" + +/** + * struct clk_branch - gating clock with status bit and dynamic hardware gating + * + * @hwcg_reg: dynamic hardware clock gating register + * @hwcg_bit: ORed with @hwcg_reg to enable dynamic hardware clock gating + * @halt_reg: halt register + * @halt_bit: ANDed with @halt_reg to test for clock halted + * @halt_check: type of halt checking to perform + * @clkr: handle between common and hardware-specific interfaces + * + * Clock which can gate its output. + */ +struct clk_branch { + u32 hwcg_reg; + u32 halt_reg; + u8 hwcg_bit; + u8 halt_bit; + u8 halt_check; +#define BRANCH_VOTED BIT(7) /* Delay on disable */ +#define BRANCH_HALT 0 /* pol: 1 = halt */ +#define BRANCH_HALT_VOTED (BRANCH_HALT | BRANCH_VOTED) +#define BRANCH_HALT_ENABLE 1 /* pol: 0 = halt */ +#define BRANCH_HALT_ENABLE_VOTED (BRANCH_HALT_ENABLE | BRANCH_VOTED) +#define BRANCH_HALT_DELAY 2 /* No bit to check; just delay */ + + struct clk_regmap clkr; +}; + +extern const struct clk_ops clk_branch_ops; +extern const struct clk_ops clk_branch2_ops; +extern const struct clk_ops clk_branch_simple_ops; + +#define to_clk_branch(_hw) \ + container_of(to_clk_regmap(_hw), struct clk_branch, clkr) + +#endif diff --git a/drivers/clk/qcom/clk-pll.c b/drivers/clk/qcom/clk-pll.c new file mode 100644 index 000000000000..0f927c538613 --- /dev/null +++ b/drivers/clk/qcom/clk-pll.c @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2013, 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/bug.h> +#include <linux/delay.h> +#include <linux/export.h> +#include <linux/clk-provider.h> +#include <linux/regmap.h> + +#include <asm/div64.h> + +#include "clk-pll.h" + +#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) + +static int clk_pll_enable(struct clk_hw *hw) +{ + struct clk_pll *pll = to_clk_pll(hw); + int ret; + u32 mask, val; + + mask = PLL_OUTCTRL | PLL_RESET_N | PLL_BYPASSNL; + ret = regmap_read(pll->clkr.regmap, pll->mode_reg, &val); + if (ret) + return ret; + + /* Skip if already enabled or in FSM mode */ + if ((val & mask) == mask || val & PLL_VOTE_FSM_ENA) + return 0; + + /* Disable PLL bypass mode. */ + ret = regmap_update_bits(pll->clkr.regmap, pll->mode_reg, PLL_BYPASSNL, + PLL_BYPASSNL); + if (ret) + return ret; + + /* + * H/W requires a 5us delay between disabling the bypass and + * de-asserting the reset. Delay 10us just to be safe. + */ + udelay(10); + + /* De-assert active-low PLL reset. */ + ret = regmap_update_bits(pll->clkr.regmap, pll->mode_reg, PLL_RESET_N, + PLL_RESET_N); + if (ret) + return ret; + + /* Wait until PLL is locked. */ + udelay(50); + + /* Enable PLL output. */ + ret = regmap_update_bits(pll->clkr.regmap, pll->mode_reg, PLL_OUTCTRL, + PLL_OUTCTRL); + if (ret) + return ret; + + return 0; +} + +static void clk_pll_disable(struct clk_hw *hw) +{ + struct clk_pll *pll = to_clk_pll(hw); + u32 mask; + u32 val; + + regmap_read(pll->clkr.regmap, pll->mode_reg, &val); + /* Skip if in FSM mode */ + if (val & PLL_VOTE_FSM_ENA) + return; + mask = PLL_OUTCTRL | PLL_RESET_N | PLL_BYPASSNL; + regmap_update_bits(pll->clkr.regmap, pll->mode_reg, mask, 0); +} + +static unsigned long +clk_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + struct clk_pll *pll = to_clk_pll(hw); + u32 l, m, n; + unsigned long rate; + u64 tmp; + + regmap_read(pll->clkr.regmap, pll->l_reg, &l); + regmap_read(pll->clkr.regmap, pll->m_reg, &m); + regmap_read(pll->clkr.regmap, pll->n_reg, &n); + + l &= 0x3ff; + m &= 0x7ffff; + n &= 0x7ffff; + + rate = parent_rate * l; + if (n) { + tmp = parent_rate; + tmp *= m; + do_div(tmp, n); + rate += tmp; + } + return rate; +} + +const struct clk_ops clk_pll_ops = { + .enable = clk_pll_enable, + .disable = clk_pll_disable, + .recalc_rate = clk_pll_recalc_rate, +}; +EXPORT_SYMBOL_GPL(clk_pll_ops); + +static int wait_for_pll(struct clk_pll *pll) +{ + u32 val; + int count; + int ret; + const char *name = __clk_get_name(pll->clkr.hw.clk); + + /* Wait for pll to enable. */ + for (count = 200; count > 0; count--) { + ret = regmap_read(pll->clkr.regmap, pll->status_reg, &val); + if (ret) + return ret; + if (val & BIT(pll->status_bit)) + return 0; + udelay(1); + } + + WARN(1, "%s didn't enable after voting for it!\n", name); + return -ETIMEDOUT; +} + +static int clk_pll_vote_enable(struct clk_hw *hw) +{ + int ret; + struct clk_pll *p = to_clk_pll(__clk_get_hw(__clk_get_parent(hw->clk))); + + ret = clk_enable_regmap(hw); + if (ret) + return ret; + + return wait_for_pll(p); +} + +const struct clk_ops clk_pll_vote_ops = { + .enable = clk_pll_vote_enable, + .disable = clk_disable_regmap, +}; +EXPORT_SYMBOL_GPL(clk_pll_vote_ops); + +static void +clk_pll_set_fsm_mode(struct clk_pll *pll, struct regmap *regmap) +{ + u32 val; + u32 mask; + + /* De-assert reset to FSM */ + regmap_update_bits(regmap, pll->mode_reg, PLL_VOTE_FSM_RESET, 0); + + /* Program bias count and lock count */ + val = 1 << PLL_BIAS_COUNT_SHIFT; + mask = PLL_BIAS_COUNT_MASK << PLL_BIAS_COUNT_SHIFT; + mask |= PLL_LOCK_COUNT_MASK << PLL_LOCK_COUNT_SHIFT; + regmap_update_bits(regmap, pll->mode_reg, mask, val); + + /* Enable PLL FSM voting */ + regmap_update_bits(regmap, pll->mode_reg, PLL_VOTE_FSM_ENA, + PLL_VOTE_FSM_ENA); +} + +static void clk_pll_configure(struct clk_pll *pll, struct regmap *regmap, + const struct pll_config *config) +{ + u32 val; + u32 mask; + + regmap_write(regmap, pll->l_reg, config->l); + regmap_write(regmap, pll->m_reg, config->m); + regmap_write(regmap, pll->n_reg, config->n); + + val = config->vco_val; + val |= config->pre_div_val; + val |= config->post_div_val; + val |= config->mn_ena_mask; + val |= config->main_output_mask; + val |= config->aux_output_mask; + + mask = config->vco_mask; + mask |= config->pre_div_mask; + mask |= config->post_div_mask; + mask |= config->mn_ena_mask; + mask |= config->main_output_mask; + mask |= config->aux_output_mask; + + regmap_update_bits(regmap, pll->config_reg, mask, val); +} + +void clk_pll_configure_sr_hpm_lp(struct clk_pll *pll, struct regmap *regmap, + const struct pll_config *config, bool fsm_mode) +{ + clk_pll_configure(pll, regmap, config); + if (fsm_mode) + clk_pll_set_fsm_mode(pll, regmap); +} +EXPORT_SYMBOL_GPL(clk_pll_configure_sr_hpm_lp); diff --git a/drivers/clk/qcom/clk-pll.h b/drivers/clk/qcom/clk-pll.h new file mode 100644 index 000000000000..0775a99ca768 --- /dev/null +++ b/drivers/clk/qcom/clk-pll.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013, 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_PLL_H__ +#define __QCOM_CLK_PLL_H__ + +#include <linux/clk-provider.h> +#include "clk-regmap.h" + +/** + * struct clk_pll - phase locked loop (PLL) + * @l_reg: L register + * @m_reg: M register + * @n_reg: N register + * @config_reg: config register + * @mode_reg: mode register + * @status_reg: status register + * @status_bit: ANDed with @status_reg to determine if PLL is enabled + * @hw: handle between common and hardware-specific interfaces + */ +struct clk_pll { + u32 l_reg; + u32 m_reg; + u32 n_reg; + u32 config_reg; + u32 mode_reg; + u32 status_reg; + u8 status_bit; + + struct clk_regmap clkr; +}; + +extern const struct clk_ops clk_pll_ops; +extern const struct clk_ops clk_pll_vote_ops; + +#define to_clk_pll(_hw) container_of(to_clk_regmap(_hw), struct clk_pll, clkr) + +struct pll_config { + u16 l; + u32 m; + u32 n; + u32 vco_val; + u32 vco_mask; + u32 pre_div_val; + u32 pre_div_mask; + u32 post_div_val; + u32 post_div_mask; + u32 mn_ena_mask; + u32 main_output_mask; + u32 aux_output_mask; +}; + +void clk_pll_configure_sr_hpm_lp(struct clk_pll *pll, struct regmap *regmap, + const struct pll_config *config, bool fsm_mode); + +#endif diff --git a/drivers/clk/qcom/clk-rcg.c b/drivers/clk/qcom/clk-rcg.c new file mode 100644 index 000000000000..abfc2b675aea --- /dev/null +++ b/drivers/clk/qcom/clk-rcg.c @@ -0,0 +1,517 @@ +/* + * Copyright (c) 2013, 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/export.h> +#include <linux/clk-provider.h> +#include <linux/regmap.h> + +#include <asm/div64.h> + +#include "clk-rcg.h" + +static u32 ns_to_src(struct src_sel *s, u32 ns) +{ + ns >>= s->src_sel_shift; + ns &= SRC_SEL_MASK; + return ns; +} + +static u32 src_to_ns(struct src_sel *s, u8 src, u32 ns) +{ + u32 mask; + + mask = SRC_SEL_MASK; + mask <<= s->src_sel_shift; + ns &= ~mask; + + ns |= src << s->src_sel_shift; + return ns; +} + +static u8 clk_rcg_get_parent(struct clk_hw *hw) +{ + struct clk_rcg *rcg = to_clk_rcg(hw); + int num_parents = __clk_get_num_parents(hw->clk); + u32 ns; + int i; + + regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns); + ns = ns_to_src(&rcg->s, ns); + for (i = 0; i < num_parents; i++) + if (ns == rcg->s.parent_map[i]) + return i; + + return -EINVAL; +} + +static int reg_to_bank(struct clk_dyn_rcg *rcg, u32 bank) +{ + bank &= BIT(rcg->mux_sel_bit); + return !!bank; +} + +static u8 clk_dyn_rcg_get_parent(struct clk_hw *hw) +{ + struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw); + int num_parents = __clk_get_num_parents(hw->clk); + u32 ns, ctl; + int bank; + int i; + struct src_sel *s; + + regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &ctl); + bank = reg_to_bank(rcg, ctl); + s = &rcg->s[bank]; + + regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns); + ns = ns_to_src(s, ns); + + for (i = 0; i < num_parents; i++) + if (ns == s->parent_map[i]) + return i; + + return -EINVAL; +} + +static int clk_rcg_set_parent(struct clk_hw *hw, u8 index) +{ + struct clk_rcg *rcg = to_clk_rcg(hw); + u32 ns; + + regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns); + ns = src_to_ns(&rcg->s, rcg->s.parent_map[index], ns); + regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns); + + return 0; +} + +static u32 md_to_m(struct mn *mn, u32 md) +{ + md >>= mn->m_val_shift; + md &= BIT(mn->width) - 1; + return md; +} + +static u32 ns_to_pre_div(struct pre_div *p, u32 ns) +{ + ns >>= p->pre_div_shift; + ns &= BIT(p->pre_div_width) - 1; + return ns; +} + +static u32 pre_div_to_ns(struct pre_div *p, u8 pre_div, u32 ns) +{ + u32 mask; + + mask = BIT(p->pre_div_width) - 1; + mask <<= p->pre_div_shift; + ns &= ~mask; + + ns |= pre_div << p->pre_div_shift; + return ns; +} + +static u32 mn_to_md(struct mn *mn, u32 m, u32 n, u32 md) +{ + u32 mask, mask_w; + + mask_w = BIT(mn->width) - 1; + mask = (mask_w << mn->m_val_shift) | mask_w; + md &= ~mask; + + if (n) { + m <<= mn->m_val_shift; + md |= m; + md |= ~n & mask_w; + } + + return md; +} + +static u32 ns_m_to_n(struct mn *mn, u32 ns, u32 m) +{ + ns = ~ns >> mn->n_val_shift; + ns &= BIT(mn->width) - 1; + return ns + m; +} + +static u32 reg_to_mnctr_mode(struct mn *mn, u32 val) +{ + val >>= mn->mnctr_mode_shift; + val &= MNCTR_MODE_MASK; + return val; +} + +static u32 mn_to_ns(struct mn *mn, u32 m, u32 n, u32 ns) +{ + u32 mask; + + mask = BIT(mn->width) - 1; + mask <<= mn->n_val_shift; + ns &= ~mask; + + if (n) { + n = n - m; + n = ~n; + n &= BIT(mn->width) - 1; + n <<= mn->n_val_shift; + ns |= n; + } + + return ns; +} + +static u32 mn_to_reg(struct mn *mn, u32 m, u32 n, u32 val) +{ + u32 mask; + + mask = MNCTR_MODE_MASK << mn->mnctr_mode_shift; + mask |= BIT(mn->mnctr_en_bit); + val &= ~mask; + + if (n) { + val |= BIT(mn->mnctr_en_bit); + val |= MNCTR_MODE_DUAL << mn->mnctr_mode_shift; + } + + return val; +} + +static void configure_bank(struct clk_dyn_rcg *rcg, const struct freq_tbl *f) +{ + u32 ns, md, ctl, *regp; + int bank, new_bank; + struct mn *mn; + struct pre_div *p; + struct src_sel *s; + bool enabled; + u32 md_reg; + u32 bank_reg; + bool banked_mn = !!rcg->mn[1].width; + struct clk_hw *hw = &rcg->clkr.hw; + + enabled = __clk_is_enabled(hw->clk); + + regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns); + regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &ctl); + + if (banked_mn) { + regp = &ctl; + bank_reg = rcg->clkr.enable_reg; + } else { + regp = &ns; + bank_reg = rcg->ns_reg; + } + + bank = reg_to_bank(rcg, *regp); + new_bank = enabled ? !bank : bank; + + if (banked_mn) { + mn = &rcg->mn[new_bank]; + md_reg = rcg->md_reg[new_bank]; + + ns |= BIT(mn->mnctr_reset_bit); + regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns); + + regmap_read(rcg->clkr.regmap, md_reg, &md); + md = mn_to_md(mn, f->m, f->n, md); + regmap_write(rcg->clkr.regmap, md_reg, md); + + ns = mn_to_ns(mn, f->m, f->n, ns); + regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns); + + ctl = mn_to_reg(mn, f->m, f->n, ctl); + regmap_write(rcg->clkr.regmap, rcg->clkr.enable_reg, ctl); + + ns &= ~BIT(mn->mnctr_reset_bit); + regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns); + } else { + p = &rcg->p[new_bank]; + ns = pre_div_to_ns(p, f->pre_div - 1, ns); + } + + s = &rcg->s[new_bank]; + ns = src_to_ns(s, s->parent_map[f->src], ns); + regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns); + + if (enabled) { + *regp ^= BIT(rcg->mux_sel_bit); + regmap_write(rcg->clkr.regmap, bank_reg, *regp); + } +} + +static int clk_dyn_rcg_set_parent(struct clk_hw *hw, u8 index) +{ + struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw); + u32 ns, ctl, md, reg; + int bank; + struct freq_tbl f = { 0 }; + bool banked_mn = !!rcg->mn[1].width; + + regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns); + regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &ctl); + reg = banked_mn ? ctl : ns; + + bank = reg_to_bank(rcg, reg); + + if (banked_mn) { + regmap_read(rcg->clkr.regmap, rcg->md_reg[bank], &md); + f.m = md_to_m(&rcg->mn[bank], md); + f.n = ns_m_to_n(&rcg->mn[bank], ns, f.m); + } else { + f.pre_div = ns_to_pre_div(&rcg->p[bank], ns) + 1; + } + f.src = index; + + configure_bank(rcg, &f); + + return 0; +} + +/* + * Calculate m/n:d rate + * + * parent_rate m + * rate = ----------- x --- + * pre_div n + */ +static unsigned long +calc_rate(unsigned long rate, u32 m, u32 n, u32 mode, u32 pre_div) +{ + if (pre_div) + rate /= pre_div + 1; + + if (mode) { + u64 tmp = rate; + tmp *= m; + do_div(tmp, n); + rate = tmp; + } + + return rate; +} + +static unsigned long +clk_rcg_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + struct clk_rcg *rcg = to_clk_rcg(hw); + u32 pre_div, m = 0, n = 0, ns, md, mode = 0; + struct mn *mn = &rcg->mn; + + regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns); + pre_div = ns_to_pre_div(&rcg->p, ns); + + if (rcg->mn.width) { + regmap_read(rcg->clkr.regmap, rcg->md_reg, &md); + m = md_to_m(mn, md); + n = ns_m_to_n(mn, ns, m); + /* MN counter mode is in hw.enable_reg sometimes */ + if (rcg->clkr.enable_reg != rcg->ns_reg) + regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &mode); + else + mode = ns; + mode = reg_to_mnctr_mode(mn, mode); + } + + return calc_rate(parent_rate, m, n, mode, pre_div); +} + +static unsigned long +clk_dyn_rcg_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw); + u32 m, n, pre_div, ns, md, mode, reg; + int bank; + struct mn *mn; + bool banked_mn = !!rcg->mn[1].width; + + regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns); + + if (banked_mn) + regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, ®); + else + reg = ns; + + bank = reg_to_bank(rcg, reg); + + if (banked_mn) { + mn = &rcg->mn[bank]; + regmap_read(rcg->clkr.regmap, rcg->md_reg[bank], &md); + m = md_to_m(mn, md); + n = ns_m_to_n(mn, ns, m); + mode = reg_to_mnctr_mode(mn, reg); + return calc_rate(parent_rate, m, n, mode, 0); + } else { + pre_div = ns_to_pre_div(&rcg->p[bank], ns); + return calc_rate(parent_rate, 0, 0, 0, pre_div); + } +} + +static const +struct freq_tbl *find_freq(const struct freq_tbl *f, unsigned long rate) +{ + if (!f) + return NULL; + + for (; f->freq; f++) + if (rate <= f->freq) + return f; + + return NULL; +} + +static long _freq_tbl_determine_rate(struct clk_hw *hw, + const struct freq_tbl *f, unsigned long rate, + unsigned long *p_rate, struct clk **p) +{ + unsigned long clk_flags; + + f = find_freq(f, rate); + if (!f) + return -EINVAL; + + clk_flags = __clk_get_flags(hw->clk); + *p = clk_get_parent_by_index(hw->clk, f->src); + if (clk_flags & CLK_SET_RATE_PARENT) { + rate = rate * f->pre_div; + if (f->n) { + u64 tmp = rate; + tmp = tmp * f->n; + do_div(tmp, f->m); + rate = tmp; + } + } else { + rate = __clk_get_rate(*p); + } + *p_rate = rate; + + return f->freq; +} + +static long clk_rcg_determine_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *p_rate, struct clk **p) +{ + struct clk_rcg *rcg = to_clk_rcg(hw); + + return _freq_tbl_determine_rate(hw, rcg->freq_tbl, rate, p_rate, p); +} + +static long clk_dyn_rcg_determine_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *p_rate, struct clk **p) +{ + struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw); + + return _freq_tbl_determine_rate(hw, rcg->freq_tbl, rate, p_rate, p); +} + +static int clk_rcg_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_rcg *rcg = to_clk_rcg(hw); + const struct freq_tbl *f; + u32 ns, md, ctl; + struct mn *mn = &rcg->mn; + u32 mask = 0; + unsigned int reset_reg; + + f = find_freq(rcg->freq_tbl, rate); + if (!f) + return -EINVAL; + + if (rcg->mn.reset_in_cc) + reset_reg = rcg->clkr.enable_reg; + else + reset_reg = rcg->ns_reg; + + if (rcg->mn.width) { + mask = BIT(mn->mnctr_reset_bit); + regmap_update_bits(rcg->clkr.regmap, reset_reg, mask, mask); + + regmap_read(rcg->clkr.regmap, rcg->md_reg, &md); + md = mn_to_md(mn, f->m, f->n, md); + regmap_write(rcg->clkr.regmap, rcg->md_reg, md); + + regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns); + /* MN counter mode is in hw.enable_reg sometimes */ + if (rcg->clkr.enable_reg != rcg->ns_reg) { + regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &ctl); + ctl = mn_to_reg(mn, f->m, f->n, ctl); + regmap_write(rcg->clkr.regmap, rcg->clkr.enable_reg, ctl); + } else { + ns = mn_to_reg(mn, f->m, f->n, ns); + } + ns = mn_to_ns(mn, f->m, f->n, ns); + } else { + regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns); + } + + ns = pre_div_to_ns(&rcg->p, f->pre_div - 1, ns); + regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns); + + regmap_update_bits(rcg->clkr.regmap, reset_reg, mask, 0); + + return 0; +} + +static int __clk_dyn_rcg_set_rate(struct clk_hw *hw, unsigned long rate) +{ + struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw); + const struct freq_tbl *f; + + f = find_freq(rcg->freq_tbl, rate); + if (!f) + return -EINVAL; + + configure_bank(rcg, f); + + return 0; +} + +static int clk_dyn_rcg_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + return __clk_dyn_rcg_set_rate(hw, rate); +} + +static int clk_dyn_rcg_set_rate_and_parent(struct clk_hw *hw, + unsigned long rate, unsigned long parent_rate, u8 index) +{ + return __clk_dyn_rcg_set_rate(hw, rate); +} + +const struct clk_ops clk_rcg_ops = { + .enable = clk_enable_regmap, + .disable = clk_disable_regmap, + .get_parent = clk_rcg_get_parent, + .set_parent = clk_rcg_set_parent, + .recalc_rate = clk_rcg_recalc_rate, + .determine_rate = clk_rcg_determine_rate, + .set_rate = clk_rcg_set_rate, +}; +EXPORT_SYMBOL_GPL(clk_rcg_ops); + +const struct clk_ops clk_dyn_rcg_ops = { + .enable = clk_enable_regmap, + .is_enabled = clk_is_enabled_regmap, + .disable = clk_disable_regmap, + .get_parent = clk_dyn_rcg_get_parent, + .set_parent = clk_dyn_rcg_set_parent, + .recalc_rate = clk_dyn_rcg_recalc_rate, + .determine_rate = clk_dyn_rcg_determine_rate, + .set_rate = clk_dyn_rcg_set_rate, + .set_rate_and_parent = clk_dyn_rcg_set_rate_and_parent, +}; +EXPORT_SYMBOL_GPL(clk_dyn_rcg_ops); diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h new file mode 100644 index 000000000000..1d6b6dece328 --- /dev/null +++ b/drivers/clk/qcom/clk-rcg.h @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2013, 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_RCG_H__ +#define __QCOM_CLK_RCG_H__ + +#include <linux/clk-provider.h> +#include "clk-regmap.h" + +struct freq_tbl { + unsigned long freq; + u8 src; + u8 pre_div; + u16 m; + u16 n; +}; + +/** + * struct mn - M/N:D counter + * @mnctr_en_bit: bit to enable mn counter + * @mnctr_reset_bit: bit to assert mn counter reset + * @mnctr_mode_shift: lowest bit of mn counter mode field + * @n_val_shift: lowest bit of n value field + * @m_val_shift: lowest bit of m value field + * @width: number of bits in m/n/d values + * @reset_in_cc: true if the mnctr_reset_bit is in the CC register + */ +struct mn { + u8 mnctr_en_bit; + u8 mnctr_reset_bit; + u8 mnctr_mode_shift; +#define MNCTR_MODE_DUAL 0x2 +#define MNCTR_MODE_MASK 0x3 + u8 n_val_shift; + u8 m_val_shift; + u8 width; + bool reset_in_cc; +}; + +/** + * struct pre_div - pre-divider + * @pre_div_shift: lowest bit of pre divider field + * @pre_div_width: number of bits in predivider + */ +struct pre_div { + u8 pre_div_shift; + u8 pre_div_width; +}; + +/** + * struct src_sel - source selector + * @src_sel_shift: lowest bit of source selection field + * @parent_map: map from software's parent index to hardware's src_sel field + */ +struct src_sel { + u8 src_sel_shift; +#define SRC_SEL_MASK 0x7 + const u8 *parent_map; +}; + +/** + * struct clk_rcg - root clock generator + * + * @ns_reg: NS register + * @md_reg: MD register + * @mn: mn counter + * @p: pre divider + * @s: source selector + * @freq_tbl: frequency table + * @clkr: regmap clock handle + * @lock: register lock + * + */ +struct clk_rcg { + u32 ns_reg; + u32 md_reg; + + struct mn mn; + struct pre_div p; + struct src_sel s; + + const struct freq_tbl *freq_tbl; + + struct clk_regmap clkr; +}; + +extern const struct clk_ops clk_rcg_ops; + +#define to_clk_rcg(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg, clkr) + +/** + * struct clk_dyn_rcg - root clock generator with glitch free mux + * + * @mux_sel_bit: bit to switch glitch free mux + * @ns_reg: NS register + * @md_reg: MD0 and MD1 register + * @mn: mn counter (banked) + * @s: source selector (banked) + * @freq_tbl: frequency table + * @clkr: regmap clock handle + * @lock: register lock + * + */ +struct clk_dyn_rcg { + u32 ns_reg; + u32 md_reg[2]; + + u8 mux_sel_bit; + + struct mn mn[2]; + struct pre_div p[2]; + struct src_sel s[2]; + + const struct freq_tbl *freq_tbl; + + struct clk_regmap clkr; +}; + +extern const struct clk_ops clk_dyn_rcg_ops; + +#define to_clk_dyn_rcg(_hw) \ + container_of(to_clk_regmap(_hw), struct clk_dyn_rcg, clkr) + +/** + * struct clk_rcg2 - root clock generator + * + * @cmd_rcgr: corresponds to *_CMD_RCGR + * @mnd_width: number of bits in m/n/d values + * @hid_width: number of bits in half integer divider + * @parent_map: map from software's parent index to hardware's src_sel field + * @freq_tbl: frequency table + * @clkr: regmap clock handle + * @lock: register lock + * + */ +struct clk_rcg2 { + u32 cmd_rcgr; + u8 mnd_width; + u8 hid_width; + const u8 *parent_map; + const struct freq_tbl *freq_tbl; + struct clk_regmap clkr; +}; + +#define to_clk_rcg2(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg2, clkr) + +extern const struct clk_ops clk_rcg2_ops; + +#endif diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c new file mode 100644 index 000000000000..00f878a04d3f --- /dev/null +++ b/drivers/clk/qcom/clk-rcg2.c @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2013, 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/bug.h> +#include <linux/export.h> +#include <linux/clk-provider.h> +#include <linux/delay.h> +#include <linux/regmap.h> + +#include <asm/div64.h> + +#include "clk-rcg.h" + +#define CMD_REG 0x0 +#define CMD_UPDATE BIT(0) +#define CMD_ROOT_EN BIT(1) +#define CMD_DIRTY_CFG BIT(4) +#define CMD_DIRTY_N BIT(5) +#define CMD_DIRTY_M BIT(6) +#define CMD_DIRTY_D BIT(7) +#define CMD_ROOT_OFF BIT(31) + +#define CFG_REG 0x4 +#define CFG_SRC_DIV_SHIFT 0 +#define CFG_SRC_SEL_SHIFT 8 +#define CFG_SRC_SEL_MASK (0x7 << CFG_SRC_SEL_SHIFT) +#define CFG_MODE_SHIFT 12 +#define CFG_MODE_MASK (0x3 << CFG_MODE_SHIFT) +#define CFG_MODE_DUAL_EDGE (0x2 << CFG_MODE_SHIFT) + +#define M_REG 0x8 +#define N_REG 0xc +#define D_REG 0x10 + +static int clk_rcg2_is_enabled(struct clk_hw *hw) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + u32 cmd; + int ret; + + ret = regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CMD_REG, &cmd); + if (ret) + return ret; + + return (cmd & CMD_ROOT_OFF) != 0; +} + +static u8 clk_rcg2_get_parent(struct clk_hw *hw) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + int num_parents = __clk_get_num_parents(hw->clk); + u32 cfg; + int i, ret; + + ret = regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg); + if (ret) + return ret; + + cfg &= CFG_SRC_SEL_MASK; + cfg >>= CFG_SRC_SEL_SHIFT; + + for (i = 0; i < num_parents; i++) + if (cfg == rcg->parent_map[i]) + return i; + + return -EINVAL; +} + +static int update_config(struct clk_rcg2 *rcg) +{ + int count, ret; + u32 cmd; + struct clk_hw *hw = &rcg->clkr.hw; + const char *name = __clk_get_name(hw->clk); + + ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CMD_REG, + CMD_UPDATE, CMD_UPDATE); + if (ret) + return ret; + + /* Wait for update to take effect */ + for (count = 500; count > 0; count--) { + ret = regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CMD_REG, &cmd); + if (ret) + return ret; + if (!(cmd & CMD_UPDATE)) + return 0; + udelay(1); + } + + WARN(1, "%s: rcg didn't update its configuration.", name); + return 0; +} + +static int clk_rcg2_set_parent(struct clk_hw *hw, u8 index) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + int ret; + + ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, + CFG_SRC_SEL_MASK, + rcg->parent_map[index] << CFG_SRC_SEL_SHIFT); + if (ret) + return ret; + + return update_config(rcg); +} + +/* + * Calculate m/n:d rate + * + * parent_rate m + * rate = ----------- x --- + * hid_div n + */ +static unsigned long +calc_rate(unsigned long rate, u32 m, u32 n, u32 mode, u32 hid_div) +{ + if (hid_div) { + rate *= 2; + rate /= hid_div + 1; + } + + if (mode) { + u64 tmp = rate; + tmp *= m; + do_div(tmp, n); + rate = tmp; + } + + return rate; +} + +static unsigned long +clk_rcg2_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + u32 cfg, hid_div, m = 0, n = 0, mode = 0, mask; + + regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg); + + if (rcg->mnd_width) { + mask = BIT(rcg->mnd_width) - 1; + regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + M_REG, &m); + m &= mask; + regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + N_REG, &n); + n = ~n; + n &= mask; + n += m; + mode = cfg & CFG_MODE_MASK; + mode >>= CFG_MODE_SHIFT; + } + + mask = BIT(rcg->hid_width) - 1; + hid_div = cfg >> CFG_SRC_DIV_SHIFT; + hid_div &= mask; + + return calc_rate(parent_rate, m, n, mode, hid_div); +} + +static const +struct freq_tbl *find_freq(const struct freq_tbl *f, unsigned long rate) +{ + if (!f) + return NULL; + + for (; f->freq; f++) + if (rate <= f->freq) + return f; + + return NULL; +} + +static long _freq_tbl_determine_rate(struct clk_hw *hw, + const struct freq_tbl *f, unsigned long rate, + unsigned long *p_rate, struct clk **p) +{ + unsigned long clk_flags; + + f = find_freq(f, rate); + if (!f) + return -EINVAL; + + clk_flags = __clk_get_flags(hw->clk); + *p = clk_get_parent_by_index(hw->clk, f->src); + if (clk_flags & CLK_SET_RATE_PARENT) { + if (f->pre_div) { + rate /= 2; + rate *= f->pre_div + 1; + } + + if (f->n) { + u64 tmp = rate; + tmp = tmp * f->n; + do_div(tmp, f->m); + rate = tmp; + } + } else { + rate = __clk_get_rate(*p); + } + *p_rate = rate; + + return f->freq; +} + +static long clk_rcg2_determine_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *p_rate, struct clk **p) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + + return _freq_tbl_determine_rate(hw, rcg->freq_tbl, rate, p_rate, p); +} + +static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + const struct freq_tbl *f; + u32 cfg, mask; + int ret; + + f = find_freq(rcg->freq_tbl, rate); + if (!f) + return -EINVAL; + + if (rcg->mnd_width && f->n) { + mask = BIT(rcg->mnd_width) - 1; + ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + M_REG, + mask, f->m); + if (ret) + return ret; + + ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + N_REG, + mask, ~(f->n - f->m)); + if (ret) + return ret; + + ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + D_REG, + mask, ~f->n); + if (ret) + return ret; + } + + mask = BIT(rcg->hid_width) - 1; + mask |= CFG_SRC_SEL_MASK | CFG_MODE_MASK; + cfg = f->pre_div << CFG_SRC_DIV_SHIFT; + cfg |= rcg->parent_map[f->src] << CFG_SRC_SEL_SHIFT; + if (rcg->mnd_width && f->n) + cfg |= CFG_MODE_DUAL_EDGE; + ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, mask, + cfg); + if (ret) + return ret; + + return update_config(rcg); +} + +static int clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + return __clk_rcg2_set_rate(hw, rate); +} + +static int clk_rcg2_set_rate_and_parent(struct clk_hw *hw, + unsigned long rate, unsigned long parent_rate, u8 index) +{ + return __clk_rcg2_set_rate(hw, rate); +} + +const struct clk_ops clk_rcg2_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, + .determine_rate = clk_rcg2_determine_rate, + .set_rate = clk_rcg2_set_rate, + .set_rate_and_parent = clk_rcg2_set_rate_and_parent, +}; +EXPORT_SYMBOL_GPL(clk_rcg2_ops); diff --git a/drivers/clk/qcom/clk-regmap.c b/drivers/clk/qcom/clk-regmap.c new file mode 100644 index 000000000000..a58ba39a900c --- /dev/null +++ b/drivers/clk/qcom/clk-regmap.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2014, 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/device.h> +#include <linux/clk-provider.h> +#include <linux/regmap.h> +#include <linux/export.h> + +#include "clk-regmap.h" + +/** + * clk_is_enabled_regmap - standard is_enabled() for regmap users + * + * @hw: clk to operate on + * + * Clocks that use regmap for their register I/O can set the + * enable_reg and enable_mask fields in their struct clk_regmap and then use + * this as their is_enabled operation, saving some code. + */ +int clk_is_enabled_regmap(struct clk_hw *hw) +{ + struct clk_regmap *rclk = to_clk_regmap(hw); + unsigned int val; + int ret; + + ret = regmap_read(rclk->regmap, rclk->enable_reg, &val); + if (ret != 0) + return ret; + + if (rclk->enable_is_inverted) + return (val & rclk->enable_mask) == 0; + else + return (val & rclk->enable_mask) != 0; +} +EXPORT_SYMBOL_GPL(clk_is_enabled_regmap); + +/** + * clk_enable_regmap - standard enable() for regmap users + * + * @hw: clk to operate on + * + * Clocks that use regmap for their register I/O can set the + * enable_reg and enable_mask fields in their struct clk_regmap and then use + * this as their enable() operation, saving some code. + */ +int clk_enable_regmap(struct clk_hw *hw) +{ + struct clk_regmap *rclk = to_clk_regmap(hw); + unsigned int val; + + if (rclk->enable_is_inverted) + val = 0; + else + val = rclk->enable_mask; + + return regmap_update_bits(rclk->regmap, rclk->enable_reg, + rclk->enable_mask, val); +} +EXPORT_SYMBOL_GPL(clk_enable_regmap); + +/** + * clk_disable_regmap - standard disable() for regmap users + * + * @hw: clk to operate on + * + * Clocks that use regmap for their register I/O can set the + * enable_reg and enable_mask fields in their struct clk_regmap and then use + * this as their disable() operation, saving some code. + */ +void clk_disable_regmap(struct clk_hw *hw) +{ + struct clk_regmap *rclk = to_clk_regmap(hw); + unsigned int val; + + if (rclk->enable_is_inverted) + val = rclk->enable_mask; + else + val = 0; + + regmap_update_bits(rclk->regmap, rclk->enable_reg, rclk->enable_mask, + val); +} +EXPORT_SYMBOL_GPL(clk_disable_regmap); + +/** + * devm_clk_register_regmap - register a clk_regmap clock + * + * @rclk: clk to operate on + * + * Clocks that use regmap for their register I/O should register their + * clk_regmap struct via this function so that the regmap is initialized + * and so that the clock is registered with the common clock framework. + */ +struct clk *devm_clk_register_regmap(struct device *dev, + struct clk_regmap *rclk) +{ + if (dev && dev_get_regmap(dev, NULL)) + rclk->regmap = dev_get_regmap(dev, NULL); + else if (dev && dev->parent) + rclk->regmap = dev_get_regmap(dev->parent, NULL); + + return devm_clk_register(dev, &rclk->hw); +} +EXPORT_SYMBOL_GPL(devm_clk_register_regmap); diff --git a/drivers/clk/qcom/clk-regmap.h b/drivers/clk/qcom/clk-regmap.h new file mode 100644 index 000000000000..491a63d537df --- /dev/null +++ b/drivers/clk/qcom/clk-regmap.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2014, 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_REGMAP_H__ +#define __QCOM_CLK_REGMAP_H__ + +#include <linux/clk-provider.h> + +struct regmap; + +/** + * struct clk_regmap - regmap supporting clock + * @hw: handle between common and hardware-specific interfaces + * @regmap: regmap to use for regmap helpers and/or by providers + * @enable_reg: register when using regmap enable/disable ops + * @enable_mask: mask when using regmap enable/disable ops + * @enable_is_inverted: flag to indicate set enable_mask bits to disable + * when using clock_enable_regmap and friends APIs. + */ +struct clk_regmap { + struct clk_hw hw; + struct regmap *regmap; + unsigned int enable_reg; + unsigned int enable_mask; + bool enable_is_inverted; +}; +#define to_clk_regmap(_hw) container_of(_hw, struct clk_regmap, hw) + +int clk_is_enabled_regmap(struct clk_hw *hw); +int clk_enable_regmap(struct clk_hw *hw); +void clk_disable_regmap(struct clk_hw *hw); +struct clk * +devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk); + +#endif diff --git a/drivers/clk/qcom/gcc-msm8660.c b/drivers/clk/qcom/gcc-msm8660.c new file mode 100644 index 000000000000..bc0b7f1fcfbe --- /dev/null +++ b/drivers/clk/qcom/gcc-msm8660.c @@ -0,0 +1,2819 @@ +/* + * Copyright (c) 2013, 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-msm8660.h> +#include <dt-bindings/reset/qcom,gcc-msm8660.h> + +#include "clk-regmap.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-branch.h" +#include "reset.h" + +static struct clk_pll pll8 = { + .l_reg = 0x3144, + .m_reg = 0x3148, + .n_reg = 0x314c, + .config_reg = 0x3154, + .mode_reg = 0x3140, + .status_reg = 0x3158, + .status_bit = 16, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pll8", + .parent_names = (const char *[]){ "pxo" }, + .num_parents = 1, + .ops = &clk_pll_ops, + }, +}; + +static struct clk_regmap pll8_vote = { + .enable_reg = 0x34c0, + .enable_mask = BIT(8), + .hw.init = &(struct clk_init_data){ + .name = "pll8_vote", + .parent_names = (const char *[]){ "pll8" }, + .num_parents = 1, + .ops = &clk_pll_vote_ops, + }, +}; + +#define P_PXO 0 +#define P_PLL8 1 +#define P_CXO 2 + +static const u8 gcc_pxo_pll8_map[] = { + [P_PXO] = 0, + [P_PLL8] = 3, +}; + +static const char *gcc_pxo_pll8[] = { + "pxo", + "pll8_vote", +}; + +static const u8 gcc_pxo_pll8_cxo_map[] = { + [P_PXO] = 0, + [P_PLL8] = 3, + [P_CXO] = 5, +}; + +static const char *gcc_pxo_pll8_cxo[] = { + "pxo", + "pll8_vote", + "cxo", +}; + +static struct freq_tbl clk_tbl_gsbi_uart[] = { + { 1843200, P_PLL8, 2, 6, 625 }, + { 3686400, P_PLL8, 2, 12, 625 }, + { 7372800, P_PLL8, 2, 24, 625 }, + { 14745600, P_PLL8, 2, 48, 625 }, + { 16000000, P_PLL8, 4, 1, 6 }, + { 24000000, P_PLL8, 4, 1, 4 }, + { 32000000, P_PLL8, 4, 1, 3 }, + { 40000000, P_PLL8, 1, 5, 48 }, + { 46400000, P_PLL8, 1, 29, 240 }, + { 48000000, P_PLL8, 4, 1, 2 }, + { 51200000, P_PLL8, 1, 2, 15 }, + { 56000000, P_PLL8, 1, 7, 48 }, + { 58982400, P_PLL8, 1, 96, 625 }, + { 64000000, P_PLL8, 2, 1, 3 }, + { } +}; + +static struct clk_rcg gsbi1_uart_src = { + .ns_reg = 0x29d4, + .md_reg = 0x29d0, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x29d4, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi1_uart_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi1_uart_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 10, + .clkr = { + .enable_reg = 0x29d4, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi1_uart_clk", + .parent_names = (const char *[]){ + "gsbi1_uart_src", + }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi2_uart_src = { + .ns_reg = 0x29f4, + .md_reg = 0x29f0, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x29f4, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi2_uart_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi2_uart_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 6, + .clkr = { + .enable_reg = 0x29f4, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi2_uart_clk", + .parent_names = (const char *[]){ + "gsbi2_uart_src", + }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi3_uart_src = { + .ns_reg = 0x2a14, + .md_reg = 0x2a10, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x2a14, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi3_uart_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi3_uart_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 2, + .clkr = { + .enable_reg = 0x2a14, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi3_uart_clk", + .parent_names = (const char *[]){ + "gsbi3_uart_src", + }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi4_uart_src = { + .ns_reg = 0x2a34, + .md_reg = 0x2a30, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x2a34, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi4_uart_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi4_uart_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 26, + .clkr = { + .enable_reg = 0x2a34, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi4_uart_clk", + .parent_names = (const char *[]){ + "gsbi4_uart_src", + }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi5_uart_src = { + .ns_reg = 0x2a54, + .md_reg = 0x2a50, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x2a54, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi5_uart_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi5_uart_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 22, + .clkr = { + .enable_reg = 0x2a54, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi5_uart_clk", + .parent_names = (const char *[]){ + "gsbi5_uart_src", + }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi6_uart_src = { + .ns_reg = 0x2a74, + .md_reg = 0x2a70, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x2a74, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi6_uart_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi6_uart_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 18, + .clkr = { + .enable_reg = 0x2a74, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi6_uart_clk", + .parent_names = (const char *[]){ + "gsbi6_uart_src", + }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi7_uart_src = { + .ns_reg = 0x2a94, + .md_reg = 0x2a90, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x2a94, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi7_uart_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi7_uart_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 14, + .clkr = { + .enable_reg = 0x2a94, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi7_uart_clk", + .parent_names = (const char *[]){ + "gsbi7_uart_src", + }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi8_uart_src = { + .ns_reg = 0x2ab4, + .md_reg = 0x2ab0, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x2ab4, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi8_uart_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi8_uart_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 10, + .clkr = { + .enable_reg = 0x2ab4, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi8_uart_clk", + .parent_names = (const char *[]){ "gsbi8_uart_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi9_uart_src = { + .ns_reg = 0x2ad4, + .md_reg = 0x2ad0, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x2ad4, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi9_uart_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi9_uart_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 6, + .clkr = { + .enable_reg = 0x2ad4, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi9_uart_clk", + .parent_names = (const char *[]){ "gsbi9_uart_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi10_uart_src = { + .ns_reg = 0x2af4, + .md_reg = 0x2af0, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x2af4, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi10_uart_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi10_uart_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 2, + .clkr = { + .enable_reg = 0x2af4, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi10_uart_clk", + .parent_names = (const char *[]){ "gsbi10_uart_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi11_uart_src = { + .ns_reg = 0x2b14, + .md_reg = 0x2b10, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x2b14, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi11_uart_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi11_uart_clk = { + .halt_reg = 0x2fd4, + .halt_bit = 17, + .clkr = { + .enable_reg = 0x2b14, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi11_uart_clk", + .parent_names = (const char *[]){ "gsbi11_uart_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi12_uart_src = { + .ns_reg = 0x2b34, + .md_reg = 0x2b30, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x2b34, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi12_uart_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi12_uart_clk = { + .halt_reg = 0x2fd4, + .halt_bit = 13, + .clkr = { + .enable_reg = 0x2b34, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi12_uart_clk", + .parent_names = (const char *[]){ "gsbi12_uart_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct freq_tbl clk_tbl_gsbi_qup[] = { + { 1100000, P_PXO, 1, 2, 49 }, + { 5400000, P_PXO, 1, 1, 5 }, + { 10800000, P_PXO, 1, 2, 5 }, + { 15060000, P_PLL8, 1, 2, 51 }, + { 24000000, P_PLL8, 4, 1, 4 }, + { 25600000, P_PLL8, 1, 1, 15 }, + { 27000000, P_PXO, 1, 0, 0 }, + { 48000000, P_PLL8, 4, 1, 2 }, + { 51200000, P_PLL8, 1, 2, 15 }, + { } +}; + +static struct clk_rcg gsbi1_qup_src = { + .ns_reg = 0x29cc, + .md_reg = 0x29c8, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x29cc, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi1_qup_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi1_qup_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 9, + .clkr = { + .enable_reg = 0x29cc, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi1_qup_clk", + .parent_names = (const char *[]){ "gsbi1_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi2_qup_src = { + .ns_reg = 0x29ec, + .md_reg = 0x29e8, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x29ec, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi2_qup_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi2_qup_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 4, + .clkr = { + .enable_reg = 0x29ec, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi2_qup_clk", + .parent_names = (const char *[]){ "gsbi2_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi3_qup_src = { + .ns_reg = 0x2a0c, + .md_reg = 0x2a08, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x2a0c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi3_qup_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi3_qup_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 0, + .clkr = { + .enable_reg = 0x2a0c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi3_qup_clk", + .parent_names = (const char *[]){ "gsbi3_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi4_qup_src = { + .ns_reg = 0x2a2c, + .md_reg = 0x2a28, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x2a2c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi4_qup_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi4_qup_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 24, + .clkr = { + .enable_reg = 0x2a2c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi4_qup_clk", + .parent_names = (const char *[]){ "gsbi4_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi5_qup_src = { + .ns_reg = 0x2a4c, + .md_reg = 0x2a48, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x2a4c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi5_qup_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi5_qup_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 20, + .clkr = { + .enable_reg = 0x2a4c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi5_qup_clk", + .parent_names = (const char *[]){ "gsbi5_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi6_qup_src = { + .ns_reg = 0x2a6c, + .md_reg = 0x2a68, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x2a6c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi6_qup_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi6_qup_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 16, + .clkr = { + .enable_reg = 0x2a6c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi6_qup_clk", + .parent_names = (const char *[]){ "gsbi6_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi7_qup_src = { + .ns_reg = 0x2a8c, + .md_reg = 0x2a88, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x2a8c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi7_qup_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi7_qup_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 12, + .clkr = { + .enable_reg = 0x2a8c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi7_qup_clk", + .parent_names = (const char *[]){ "gsbi7_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi8_qup_src = { + .ns_reg = 0x2aac, + .md_reg = 0x2aa8, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x2aac, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi8_qup_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi8_qup_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 8, + .clkr = { + .enable_reg = 0x2aac, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi8_qup_clk", + .parent_names = (const char *[]){ "gsbi8_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi9_qup_src = { + .ns_reg = 0x2acc, + .md_reg = 0x2ac8, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x2acc, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi9_qup_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi9_qup_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 4, + .clkr = { + .enable_reg = 0x2acc, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi9_qup_clk", + .parent_names = (const char *[]){ "gsbi9_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi10_qup_src = { + .ns_reg = 0x2aec, + .md_reg = 0x2ae8, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x2aec, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi10_qup_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi10_qup_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 0, + .clkr = { + .enable_reg = 0x2aec, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi10_qup_clk", + .parent_names = (const char *[]){ "gsbi10_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi11_qup_src = { + .ns_reg = 0x2b0c, + .md_reg = 0x2b08, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x2b0c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi11_qup_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi11_qup_clk = { + .halt_reg = 0x2fd4, + .halt_bit = 15, + .clkr = { + .enable_reg = 0x2b0c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi11_qup_clk", + .parent_names = (const char *[]){ "gsbi11_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi12_qup_src = { + .ns_reg = 0x2b2c, + .md_reg = 0x2b28, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x2b2c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi12_qup_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi12_qup_clk = { + .halt_reg = 0x2fd4, + .halt_bit = 11, + .clkr = { + .enable_reg = 0x2b2c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi12_qup_clk", + .parent_names = (const char *[]){ "gsbi12_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl clk_tbl_gp[] = { + { 9600000, P_CXO, 2, 0, 0 }, + { 13500000, P_PXO, 2, 0, 0 }, + { 19200000, P_CXO, 1, 0, 0 }, + { 27000000, P_PXO, 1, 0, 0 }, + { 64000000, P_PLL8, 2, 1, 3 }, + { 76800000, P_PLL8, 1, 1, 5 }, + { 96000000, P_PLL8, 4, 0, 0 }, + { 128000000, P_PLL8, 3, 0, 0 }, + { 192000000, P_PLL8, 2, 0, 0 }, + { } +}; + +static struct clk_rcg gp0_src = { + .ns_reg = 0x2d24, + .md_reg = 0x2d00, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_cxo_map, + }, + .freq_tbl = clk_tbl_gp, + .clkr = { + .enable_reg = 0x2d24, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gp0_src", + .parent_names = gcc_pxo_pll8_cxo, + .num_parents = 3, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + } +}; + +static struct clk_branch gp0_clk = { + .halt_reg = 0x2fd8, + .halt_bit = 7, + .clkr = { + .enable_reg = 0x2d24, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gp0_clk", + .parent_names = (const char *[]){ "gp0_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gp1_src = { + .ns_reg = 0x2d44, + .md_reg = 0x2d40, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_cxo_map, + }, + .freq_tbl = clk_tbl_gp, + .clkr = { + .enable_reg = 0x2d44, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gp1_src", + .parent_names = gcc_pxo_pll8_cxo, + .num_parents = 3, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch gp1_clk = { + .halt_reg = 0x2fd8, + .halt_bit = 6, + .clkr = { + .enable_reg = 0x2d44, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gp1_clk", + .parent_names = (const char *[]){ "gp1_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gp2_src = { + .ns_reg = 0x2d64, + .md_reg = 0x2d60, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_cxo_map, + }, + .freq_tbl = clk_tbl_gp, + .clkr = { + .enable_reg = 0x2d64, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gp2_src", + .parent_names = gcc_pxo_pll8_cxo, + .num_parents = 3, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch gp2_clk = { + .halt_reg = 0x2fd8, + .halt_bit = 5, + .clkr = { + .enable_reg = 0x2d64, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gp2_clk", + .parent_names = (const char *[]){ "gp2_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch pmem_clk = { + .hwcg_reg = 0x25a0, + .hwcg_bit = 6, + .halt_reg = 0x2fc8, + .halt_bit = 20, + .clkr = { + .enable_reg = 0x25a0, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "pmem_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_rcg prng_src = { + .ns_reg = 0x2e80, + .p = { + .pre_div_shift = 3, + .pre_div_width = 4, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .clkr.hw = { + .init = &(struct clk_init_data){ + .name = "prng_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + }, + }, +}; + +static struct clk_branch prng_clk = { + .halt_reg = 0x2fd8, + .halt_check = BRANCH_HALT_VOTED, + .halt_bit = 10, + .clkr = { + .enable_reg = 0x3080, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "prng_clk", + .parent_names = (const char *[]){ "prng_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + }, + }, +}; + +static const struct freq_tbl clk_tbl_sdc[] = { + { 144000, P_PXO, 3, 2, 125 }, + { 400000, P_PLL8, 4, 1, 240 }, + { 16000000, P_PLL8, 4, 1, 6 }, + { 17070000, P_PLL8, 1, 2, 45 }, + { 20210000, P_PLL8, 1, 1, 19 }, + { 24000000, P_PLL8, 4, 1, 4 }, + { 48000000, P_PLL8, 4, 1, 2 }, + { } +}; + +static struct clk_rcg sdc1_src = { + .ns_reg = 0x282c, + .md_reg = 0x2828, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_sdc, + .clkr = { + .enable_reg = 0x282c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "sdc1_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch sdc1_clk = { + .halt_reg = 0x2fc8, + .halt_bit = 6, + .clkr = { + .enable_reg = 0x282c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "sdc1_clk", + .parent_names = (const char *[]){ "sdc1_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg sdc2_src = { + .ns_reg = 0x284c, + .md_reg = 0x2848, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_sdc, + .clkr = { + .enable_reg = 0x284c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "sdc2_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch sdc2_clk = { + .halt_reg = 0x2fc8, + .halt_bit = 5, + .clkr = { + .enable_reg = 0x284c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "sdc2_clk", + .parent_names = (const char *[]){ "sdc2_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg sdc3_src = { + .ns_reg = 0x286c, + .md_reg = 0x2868, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_sdc, + .clkr = { + .enable_reg = 0x286c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "sdc3_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch sdc3_clk = { + .halt_reg = 0x2fc8, + .halt_bit = 4, + .clkr = { + .enable_reg = 0x286c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "sdc3_clk", + .parent_names = (const char *[]){ "sdc3_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg sdc4_src = { + .ns_reg = 0x288c, + .md_reg = 0x2888, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_sdc, + .clkr = { + .enable_reg = 0x288c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "sdc4_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch sdc4_clk = { + .halt_reg = 0x2fc8, + .halt_bit = 3, + .clkr = { + .enable_reg = 0x288c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "sdc4_clk", + .parent_names = (const char *[]){ "sdc4_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg sdc5_src = { + .ns_reg = 0x28ac, + .md_reg = 0x28a8, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_sdc, + .clkr = { + .enable_reg = 0x28ac, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "sdc5_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch sdc5_clk = { + .halt_reg = 0x2fc8, + .halt_bit = 2, + .clkr = { + .enable_reg = 0x28ac, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "sdc5_clk", + .parent_names = (const char *[]){ "sdc5_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl clk_tbl_tsif_ref[] = { + { 105000, P_PXO, 1, 1, 256 }, + { } +}; + +static struct clk_rcg tsif_ref_src = { + .ns_reg = 0x2710, + .md_reg = 0x270c, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_tsif_ref, + .clkr = { + .enable_reg = 0x2710, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "tsif_ref_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch tsif_ref_clk = { + .halt_reg = 0x2fd4, + .halt_bit = 5, + .clkr = { + .enable_reg = 0x2710, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "tsif_ref_clk", + .parent_names = (const char *[]){ "tsif_ref_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl clk_tbl_usb[] = { + { 60000000, P_PLL8, 1, 5, 32 }, + { } +}; + +static struct clk_rcg usb_hs1_xcvr_src = { + .ns_reg = 0x290c, + .md_reg = 0x2908, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_usb, + .clkr = { + .enable_reg = 0x290c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "usb_hs1_xcvr_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch usb_hs1_xcvr_clk = { + .halt_reg = 0x2fc8, + .halt_bit = 0, + .clkr = { + .enable_reg = 0x290c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "usb_hs1_xcvr_clk", + .parent_names = (const char *[]){ "usb_hs1_xcvr_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg usb_fs1_xcvr_fs_src = { + .ns_reg = 0x2968, + .md_reg = 0x2964, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_usb, + .clkr = { + .enable_reg = 0x2968, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "usb_fs1_xcvr_fs_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static const char *usb_fs1_xcvr_fs_src_p[] = { "usb_fs1_xcvr_fs_src" }; + +static struct clk_branch usb_fs1_xcvr_fs_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 15, + .clkr = { + .enable_reg = 0x2968, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "usb_fs1_xcvr_fs_clk", + .parent_names = usb_fs1_xcvr_fs_src_p, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch usb_fs1_system_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 16, + .clkr = { + .enable_reg = 0x296c, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .parent_names = usb_fs1_xcvr_fs_src_p, + .num_parents = 1, + .name = "usb_fs1_system_clk", + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg usb_fs2_xcvr_fs_src = { + .ns_reg = 0x2988, + .md_reg = 0x2984, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_usb, + .clkr = { + .enable_reg = 0x2988, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "usb_fs2_xcvr_fs_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static const char *usb_fs2_xcvr_fs_src_p[] = { "usb_fs2_xcvr_fs_src" }; + +static struct clk_branch usb_fs2_xcvr_fs_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 12, + .clkr = { + .enable_reg = 0x2988, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "usb_fs2_xcvr_fs_clk", + .parent_names = usb_fs2_xcvr_fs_src_p, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch usb_fs2_system_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 13, + .clkr = { + .enable_reg = 0x298c, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "usb_fs2_system_clk", + .parent_names = usb_fs2_xcvr_fs_src_p, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch gsbi1_h_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 11, + .clkr = { + .enable_reg = 0x29c0, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi1_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gsbi2_h_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 7, + .clkr = { + .enable_reg = 0x29e0, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi2_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gsbi3_h_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 3, + .clkr = { + .enable_reg = 0x2a00, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi3_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gsbi4_h_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 27, + .clkr = { + .enable_reg = 0x2a20, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi4_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gsbi5_h_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 23, + .clkr = { + .enable_reg = 0x2a40, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi5_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gsbi6_h_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 19, + .clkr = { + .enable_reg = 0x2a60, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi6_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gsbi7_h_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 15, + .clkr = { + .enable_reg = 0x2a80, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi7_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gsbi8_h_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 11, + .clkr = { + .enable_reg = 0x2aa0, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi8_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gsbi9_h_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 7, + .clkr = { + .enable_reg = 0x2ac0, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi9_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gsbi10_h_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 3, + .clkr = { + .enable_reg = 0x2ae0, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi10_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gsbi11_h_clk = { + .halt_reg = 0x2fd4, + .halt_bit = 18, + .clkr = { + .enable_reg = 0x2b00, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi11_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gsbi12_h_clk = { + .halt_reg = 0x2fd4, + .halt_bit = 14, + .clkr = { + .enable_reg = 0x2b20, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi12_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch tsif_h_clk = { + .halt_reg = 0x2fd4, + .halt_bit = 7, + .clkr = { + .enable_reg = 0x2700, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "tsif_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch usb_fs1_h_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 17, + .clkr = { + .enable_reg = 0x2960, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "usb_fs1_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch usb_fs2_h_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 14, + .clkr = { + .enable_reg = 0x2980, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "usb_fs2_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch usb_hs1_h_clk = { + .halt_reg = 0x2fc8, + .halt_bit = 1, + .clkr = { + .enable_reg = 0x2900, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "usb_hs1_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch sdc1_h_clk = { + .halt_reg = 0x2fc8, + .halt_bit = 11, + .clkr = { + .enable_reg = 0x2820, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "sdc1_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch sdc2_h_clk = { + .halt_reg = 0x2fc8, + .halt_bit = 10, + .clkr = { + .enable_reg = 0x2840, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "sdc2_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch sdc3_h_clk = { + .halt_reg = 0x2fc8, + .halt_bit = 9, + .clkr = { + .enable_reg = 0x2860, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "sdc3_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch sdc4_h_clk = { + .halt_reg = 0x2fc8, + .halt_bit = 8, + .clkr = { + .enable_reg = 0x2880, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "sdc4_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch sdc5_h_clk = { + .halt_reg = 0x2fc8, + .halt_bit = 7, + .clkr = { + .enable_reg = 0x28a0, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "sdc5_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch adm0_clk = { + .halt_reg = 0x2fdc, + .halt_check = BRANCH_HALT_VOTED, + .halt_bit = 14, + .clkr = { + .enable_reg = 0x3080, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "adm0_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch adm0_pbus_clk = { + .halt_reg = 0x2fdc, + .halt_check = BRANCH_HALT_VOTED, + .halt_bit = 13, + .clkr = { + .enable_reg = 0x3080, + .enable_mask = BIT(3), + .hw.init = &(struct clk_init_data){ + .name = "adm0_pbus_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch adm1_clk = { + .halt_reg = 0x2fdc, + .halt_bit = 12, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x3080, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "adm1_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch adm1_pbus_clk = { + .halt_reg = 0x2fdc, + .halt_bit = 11, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x3080, + .enable_mask = BIT(5), + .hw.init = &(struct clk_init_data){ + .name = "adm1_pbus_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch modem_ahb1_h_clk = { + .halt_reg = 0x2fdc, + .halt_bit = 8, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x3080, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "modem_ahb1_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch modem_ahb2_h_clk = { + .halt_reg = 0x2fdc, + .halt_bit = 7, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x3080, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "modem_ahb2_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch pmic_arb0_h_clk = { + .halt_reg = 0x2fd8, + .halt_check = BRANCH_HALT_VOTED, + .halt_bit = 22, + .clkr = { + .enable_reg = 0x3080, + .enable_mask = BIT(8), + .hw.init = &(struct clk_init_data){ + .name = "pmic_arb0_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch pmic_arb1_h_clk = { + .halt_reg = 0x2fd8, + .halt_check = BRANCH_HALT_VOTED, + .halt_bit = 21, + .clkr = { + .enable_reg = 0x3080, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "pmic_arb1_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch pmic_ssbi2_clk = { + .halt_reg = 0x2fd8, + .halt_check = BRANCH_HALT_VOTED, + .halt_bit = 23, + .clkr = { + .enable_reg = 0x3080, + .enable_mask = BIT(7), + .hw.init = &(struct clk_init_data){ + .name = "pmic_ssbi2_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch rpm_msg_ram_h_clk = { + .hwcg_reg = 0x27e0, + .hwcg_bit = 6, + .halt_reg = 0x2fd8, + .halt_check = BRANCH_HALT_VOTED, + .halt_bit = 12, + .clkr = { + .enable_reg = 0x3080, + .enable_mask = BIT(6), + .hw.init = &(struct clk_init_data){ + .name = "rpm_msg_ram_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_regmap *gcc_msm8660_clks[] = { + [PLL8] = &pll8.clkr, + [PLL8_VOTE] = &pll8_vote, + [GSBI1_UART_SRC] = &gsbi1_uart_src.clkr, + [GSBI1_UART_CLK] = &gsbi1_uart_clk.clkr, + [GSBI2_UART_SRC] = &gsbi2_uart_src.clkr, + [GSBI2_UART_CLK] = &gsbi2_uart_clk.clkr, + [GSBI3_UART_SRC] = &gsbi3_uart_src.clkr, + [GSBI3_UART_CLK] = &gsbi3_uart_clk.clkr, + [GSBI4_UART_SRC] = &gsbi4_uart_src.clkr, + [GSBI4_UART_CLK] = &gsbi4_uart_clk.clkr, + [GSBI5_UART_SRC] = &gsbi5_uart_src.clkr, + [GSBI5_UART_CLK] = &gsbi5_uart_clk.clkr, + [GSBI6_UART_SRC] = &gsbi6_uart_src.clkr, + [GSBI6_UART_CLK] = &gsbi6_uart_clk.clkr, + [GSBI7_UART_SRC] = &gsbi7_uart_src.clkr, + [GSBI7_UART_CLK] = &gsbi7_uart_clk.clkr, + [GSBI8_UART_SRC] = &gsbi8_uart_src.clkr, + [GSBI8_UART_CLK] = &gsbi8_uart_clk.clkr, + [GSBI9_UART_SRC] = &gsbi9_uart_src.clkr, + [GSBI9_UART_CLK] = &gsbi9_uart_clk.clkr, + [GSBI10_UART_SRC] = &gsbi10_uart_src.clkr, + [GSBI10_UART_CLK] = &gsbi10_uart_clk.clkr, + [GSBI11_UART_SRC] = &gsbi11_uart_src.clkr, + [GSBI11_UART_CLK] = &gsbi11_uart_clk.clkr, + [GSBI12_UART_SRC] = &gsbi12_uart_src.clkr, + [GSBI12_UART_CLK] = &gsbi12_uart_clk.clkr, + [GSBI1_QUP_SRC] = &gsbi1_qup_src.clkr, + [GSBI1_QUP_CLK] = &gsbi1_qup_clk.clkr, + [GSBI2_QUP_SRC] = &gsbi2_qup_src.clkr, + [GSBI2_QUP_CLK] = &gsbi2_qup_clk.clkr, + [GSBI3_QUP_SRC] = &gsbi3_qup_src.clkr, + [GSBI3_QUP_CLK] = &gsbi3_qup_clk.clkr, + [GSBI4_QUP_SRC] = &gsbi4_qup_src.clkr, + [GSBI4_QUP_CLK] = &gsbi4_qup_clk.clkr, + [GSBI5_QUP_SRC] = &gsbi5_qup_src.clkr, + [GSBI5_QUP_CLK] = &gsbi5_qup_clk.clkr, + [GSBI6_QUP_SRC] = &gsbi6_qup_src.clkr, + [GSBI6_QUP_CLK] = &gsbi6_qup_clk.clkr, + [GSBI7_QUP_SRC] = &gsbi7_qup_src.clkr, + [GSBI7_QUP_CLK] = &gsbi7_qup_clk.clkr, + [GSBI8_QUP_SRC] = &gsbi8_qup_src.clkr, + [GSBI8_QUP_CLK] = &gsbi8_qup_clk.clkr, + [GSBI9_QUP_SRC] = &gsbi9_qup_src.clkr, + [GSBI9_QUP_CLK] = &gsbi9_qup_clk.clkr, + [GSBI10_QUP_SRC] = &gsbi10_qup_src.clkr, + [GSBI10_QUP_CLK] = &gsbi10_qup_clk.clkr, + [GSBI11_QUP_SRC] = &gsbi11_qup_src.clkr, + [GSBI11_QUP_CLK] = &gsbi11_qup_clk.clkr, + [GSBI12_QUP_SRC] = &gsbi12_qup_src.clkr, + [GSBI12_QUP_CLK] = &gsbi12_qup_clk.clkr, + [GP0_SRC] = &gp0_src.clkr, + [GP0_CLK] = &gp0_clk.clkr, + [GP1_SRC] = &gp1_src.clkr, + [GP1_CLK] = &gp1_clk.clkr, + [GP2_SRC] = &gp2_src.clkr, + [GP2_CLK] = &gp2_clk.clkr, + [PMEM_CLK] = &pmem_clk.clkr, + [PRNG_SRC] = &prng_src.clkr, + [PRNG_CLK] = &prng_clk.clkr, + [SDC1_SRC] = &sdc1_src.clkr, + [SDC1_CLK] = &sdc1_clk.clkr, + [SDC2_SRC] = &sdc2_src.clkr, + [SDC2_CLK] = &sdc2_clk.clkr, + [SDC3_SRC] = &sdc3_src.clkr, + [SDC3_CLK] = &sdc3_clk.clkr, + [SDC4_SRC] = &sdc4_src.clkr, + [SDC4_CLK] = &sdc4_clk.clkr, + [SDC5_SRC] = &sdc5_src.clkr, + [SDC5_CLK] = &sdc5_clk.clkr, + [TSIF_REF_SRC] = &tsif_ref_src.clkr, + [TSIF_REF_CLK] = &tsif_ref_clk.clkr, + [USB_HS1_XCVR_SRC] = &usb_hs1_xcvr_src.clkr, + [USB_HS1_XCVR_CLK] = &usb_hs1_xcvr_clk.clkr, + [USB_FS1_XCVR_FS_SRC] = &usb_fs1_xcvr_fs_src.clkr, + [USB_FS1_XCVR_FS_CLK] = &usb_fs1_xcvr_fs_clk.clkr, + [USB_FS1_SYSTEM_CLK] = &usb_fs1_system_clk.clkr, + [USB_FS2_XCVR_FS_SRC] = &usb_fs2_xcvr_fs_src.clkr, + [USB_FS2_XCVR_FS_CLK] = &usb_fs2_xcvr_fs_clk.clkr, + [USB_FS2_SYSTEM_CLK] = &usb_fs2_system_clk.clkr, + [GSBI1_H_CLK] = &gsbi1_h_clk.clkr, + [GSBI2_H_CLK] = &gsbi2_h_clk.clkr, + [GSBI3_H_CLK] = &gsbi3_h_clk.clkr, + [GSBI4_H_CLK] = &gsbi4_h_clk.clkr, + [GSBI5_H_CLK] = &gsbi5_h_clk.clkr, + [GSBI6_H_CLK] = &gsbi6_h_clk.clkr, + [GSBI7_H_CLK] = &gsbi7_h_clk.clkr, + [GSBI8_H_CLK] = &gsbi8_h_clk.clkr, + [GSBI9_H_CLK] = &gsbi9_h_clk.clkr, + [GSBI10_H_CLK] = &gsbi10_h_clk.clkr, + [GSBI11_H_CLK] = &gsbi11_h_clk.clkr, + [GSBI12_H_CLK] = &gsbi12_h_clk.clkr, + [TSIF_H_CLK] = &tsif_h_clk.clkr, + [USB_FS1_H_CLK] = &usb_fs1_h_clk.clkr, + [USB_FS2_H_CLK] = &usb_fs2_h_clk.clkr, + [USB_HS1_H_CLK] = &usb_hs1_h_clk.clkr, + [SDC1_H_CLK] = &sdc1_h_clk.clkr, + [SDC2_H_CLK] = &sdc2_h_clk.clkr, + [SDC3_H_CLK] = &sdc3_h_clk.clkr, + [SDC4_H_CLK] = &sdc4_h_clk.clkr, + [SDC5_H_CLK] = &sdc5_h_clk.clkr, + [ADM0_CLK] = &adm0_clk.clkr, + [ADM0_PBUS_CLK] = &adm0_pbus_clk.clkr, + [ADM1_CLK] = &adm1_clk.clkr, + [ADM1_PBUS_CLK] = &adm1_pbus_clk.clkr, + [MODEM_AHB1_H_CLK] = &modem_ahb1_h_clk.clkr, + [MODEM_AHB2_H_CLK] = &modem_ahb2_h_clk.clkr, + [PMIC_ARB0_H_CLK] = &pmic_arb0_h_clk.clkr, + [PMIC_ARB1_H_CLK] = &pmic_arb1_h_clk.clkr, + [PMIC_SSBI2_CLK] = &pmic_ssbi2_clk.clkr, + [RPM_MSG_RAM_H_CLK] = &rpm_msg_ram_h_clk.clkr, +}; + +static const struct qcom_reset_map gcc_msm8660_resets[] = { + [AFAB_CORE_RESET] = { 0x2080, 7 }, + [SCSS_SYS_RESET] = { 0x20b4, 1 }, + [SCSS_SYS_POR_RESET] = { 0x20b4 }, + [AFAB_SMPSS_S_RESET] = { 0x20b8, 2 }, + [AFAB_SMPSS_M1_RESET] = { 0x20b8, 1 }, + [AFAB_SMPSS_M0_RESET] = { 0x20b8 }, + [AFAB_EBI1_S_RESET] = { 0x20c0, 7 }, + [SFAB_CORE_RESET] = { 0x2120, 7 }, + [SFAB_ADM0_M0_RESET] = { 0x21e0, 7 }, + [SFAB_ADM0_M1_RESET] = { 0x21e4, 7 }, + [SFAB_ADM0_M2_RESET] = { 0x21e4, 7 }, + [ADM0_C2_RESET] = { 0x220c, 4 }, + [ADM0_C1_RESET] = { 0x220c, 3 }, + [ADM0_C0_RESET] = { 0x220c, 2 }, + [ADM0_PBUS_RESET] = { 0x220c, 1 }, + [ADM0_RESET] = { 0x220c }, + [SFAB_ADM1_M0_RESET] = { 0x2220, 7 }, + [SFAB_ADM1_M1_RESET] = { 0x2224, 7 }, + [SFAB_ADM1_M2_RESET] = { 0x2228, 7 }, + [MMFAB_ADM1_M3_RESET] = { 0x2240, 7 }, + [ADM1_C3_RESET] = { 0x226c, 5 }, + [ADM1_C2_RESET] = { 0x226c, 4 }, + [ADM1_C1_RESET] = { 0x226c, 3 }, + [ADM1_C0_RESET] = { 0x226c, 2 }, + [ADM1_PBUS_RESET] = { 0x226c, 1 }, + [ADM1_RESET] = { 0x226c }, + [IMEM0_RESET] = { 0x2280, 7 }, + [SFAB_LPASS_Q6_RESET] = { 0x23a0, 7 }, + [SFAB_AFAB_M_RESET] = { 0x23e0, 7 }, + [AFAB_SFAB_M0_RESET] = { 0x2420, 7 }, + [AFAB_SFAB_M1_RESET] = { 0x2424, 7 }, + [DFAB_CORE_RESET] = { 0x24ac, 7 }, + [SFAB_DFAB_M_RESET] = { 0x2500, 7 }, + [DFAB_SFAB_M_RESET] = { 0x2520, 7 }, + [DFAB_SWAY0_RESET] = { 0x2540, 7 }, + [DFAB_SWAY1_RESET] = { 0x2544, 7 }, + [DFAB_ARB0_RESET] = { 0x2560, 7 }, + [DFAB_ARB1_RESET] = { 0x2564, 7 }, + [PPSS_PROC_RESET] = { 0x2594, 1 }, + [PPSS_RESET] = { 0x2594 }, + [PMEM_RESET] = { 0x25a0, 7 }, + [DMA_BAM_RESET] = { 0x25c0, 7 }, + [SIC_RESET] = { 0x25e0, 7 }, + [SPS_TIC_RESET] = { 0x2600, 7 }, + [CFBP0_RESET] = { 0x2650, 7 }, + [CFBP1_RESET] = { 0x2654, 7 }, + [CFBP2_RESET] = { 0x2658, 7 }, + [EBI2_RESET] = { 0x2664, 7 }, + [SFAB_CFPB_M_RESET] = { 0x2680, 7 }, + [CFPB_MASTER_RESET] = { 0x26a0, 7 }, + [SFAB_CFPB_S_RESET] = { 0x26c0, 7 }, + [CFPB_SPLITTER_RESET] = { 0x26e0, 7 }, + [TSIF_RESET] = { 0x2700, 7 }, + [CE1_RESET] = { 0x2720, 7 }, + [CE2_RESET] = { 0x2740, 7 }, + [SFAB_SFPB_M_RESET] = { 0x2780, 7 }, + [SFAB_SFPB_S_RESET] = { 0x27a0, 7 }, + [RPM_PROC_RESET] = { 0x27c0, 7 }, + [RPM_BUS_RESET] = { 0x27c4, 7 }, + [RPM_MSG_RAM_RESET] = { 0x27e0, 7 }, + [PMIC_ARB0_RESET] = { 0x2800, 7 }, + [PMIC_ARB1_RESET] = { 0x2804, 7 }, + [PMIC_SSBI2_RESET] = { 0x280c, 12 }, + [SDC1_RESET] = { 0x2830 }, + [SDC2_RESET] = { 0x2850 }, + [SDC3_RESET] = { 0x2870 }, + [SDC4_RESET] = { 0x2890 }, + [SDC5_RESET] = { 0x28b0 }, + [USB_HS1_RESET] = { 0x2910 }, + [USB_HS2_XCVR_RESET] = { 0x2934, 1 }, + [USB_HS2_RESET] = { 0x2934 }, + [USB_FS1_XCVR_RESET] = { 0x2974, 1 }, + [USB_FS1_RESET] = { 0x2974 }, + [USB_FS2_XCVR_RESET] = { 0x2994, 1 }, + [USB_FS2_RESET] = { 0x2994 }, + [GSBI1_RESET] = { 0x29dc }, + [GSBI2_RESET] = { 0x29fc }, + [GSBI3_RESET] = { 0x2a1c }, + [GSBI4_RESET] = { 0x2a3c }, + [GSBI5_RESET] = { 0x2a5c }, + [GSBI6_RESET] = { 0x2a7c }, + [GSBI7_RESET] = { 0x2a9c }, + [GSBI8_RESET] = { 0x2abc }, + [GSBI9_RESET] = { 0x2adc }, + [GSBI10_RESET] = { 0x2afc }, + [GSBI11_RESET] = { 0x2b1c }, + [GSBI12_RESET] = { 0x2b3c }, + [SPDM_RESET] = { 0x2b6c }, + [SEC_CTRL_RESET] = { 0x2b80, 7 }, + [TLMM_H_RESET] = { 0x2ba0, 7 }, + [TLMM_RESET] = { 0x2ba4, 7 }, + [MARRM_PWRON_RESET] = { 0x2bd4, 1 }, + [MARM_RESET] = { 0x2bd4 }, + [MAHB1_RESET] = { 0x2be4, 7 }, + [SFAB_MSS_S_RESET] = { 0x2c00, 7 }, + [MAHB2_RESET] = { 0x2c20, 7 }, + [MODEM_SW_AHB_RESET] = { 0x2c48, 1 }, + [MODEM_RESET] = { 0x2c48 }, + [SFAB_MSS_MDM1_RESET] = { 0x2c4c, 1 }, + [SFAB_MSS_MDM0_RESET] = { 0x2c4c }, + [MSS_SLP_RESET] = { 0x2c60, 7 }, + [MSS_MARM_SAW_RESET] = { 0x2c68, 1 }, + [MSS_WDOG_RESET] = { 0x2c68 }, + [TSSC_RESET] = { 0x2ca0, 7 }, + [PDM_RESET] = { 0x2cc0, 12 }, + [SCSS_CORE0_RESET] = { 0x2d60, 1 }, + [SCSS_CORE0_POR_RESET] = { 0x2d60 }, + [SCSS_CORE1_RESET] = { 0x2d80, 1 }, + [SCSS_CORE1_POR_RESET] = { 0x2d80 }, + [MPM_RESET] = { 0x2da4, 1 }, + [EBI1_1X_DIV_RESET] = { 0x2dec, 9 }, + [EBI1_RESET] = { 0x2dec, 7 }, + [SFAB_SMPSS_S_RESET] = { 0x2e00, 7 }, + [USB_PHY0_RESET] = { 0x2e20 }, + [USB_PHY1_RESET] = { 0x2e40 }, + [PRNG_RESET] = { 0x2e80, 12 }, +}; + +static const struct regmap_config gcc_msm8660_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x363c, + .fast_io = true, +}; + +static const struct of_device_id gcc_msm8660_match_table[] = { + { .compatible = "qcom,gcc-msm8660" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_msm8660_match_table); + +struct qcom_cc { + struct qcom_reset_controller reset; + struct clk_onecell_data data; + struct clk *clks[]; +}; + +static int gcc_msm8660_probe(struct platform_device *pdev) +{ + void __iomem *base; + struct resource *res; + int i, ret; + struct device *dev = &pdev->dev; + struct clk *clk; + struct clk_onecell_data *data; + struct clk **clks; + struct regmap *regmap; + size_t num_clks; + struct qcom_reset_controller *reset; + struct qcom_cc *cc; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + regmap = devm_regmap_init_mmio(dev, base, &gcc_msm8660_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + num_clks = ARRAY_SIZE(gcc_msm8660_clks); + cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks, + GFP_KERNEL); + if (!cc) + return -ENOMEM; + + clks = cc->clks; + data = &cc->data; + data->clks = clks; + data->clk_num = num_clks; + + /* 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); + + clk = clk_register_fixed_rate(dev, "pxo", NULL, CLK_IS_ROOT, 27000000); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + for (i = 0; i < num_clks; i++) { + if (!gcc_msm8660_clks[i]) + continue; + clk = devm_clk_register_regmap(dev, gcc_msm8660_clks[i]); + if (IS_ERR(clk)) + return PTR_ERR(clk); + clks[i] = clk; + } + + ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data); + if (ret) + return ret; + + reset = &cc->reset; + reset->rcdev.of_node = dev->of_node; + reset->rcdev.ops = &qcom_reset_ops, + reset->rcdev.owner = THIS_MODULE, + reset->rcdev.nr_resets = ARRAY_SIZE(gcc_msm8660_resets), + reset->regmap = regmap; + reset->reset_map = gcc_msm8660_resets, + platform_set_drvdata(pdev, &reset->rcdev); + + ret = reset_controller_register(&reset->rcdev); + if (ret) + of_clk_del_provider(dev->of_node); + + return ret; +} + +static int gcc_msm8660_remove(struct platform_device *pdev) +{ + of_clk_del_provider(pdev->dev.of_node); + reset_controller_unregister(platform_get_drvdata(pdev)); + return 0; +} + +static struct platform_driver gcc_msm8660_driver = { + .probe = gcc_msm8660_probe, + .remove = gcc_msm8660_remove, + .driver = { + .name = "gcc-msm8660", + .owner = THIS_MODULE, + .of_match_table = gcc_msm8660_match_table, + }, +}; + +static int __init gcc_msm8660_init(void) +{ + return platform_driver_register(&gcc_msm8660_driver); +} +core_initcall(gcc_msm8660_init); + +static void __exit gcc_msm8660_exit(void) +{ + platform_driver_unregister(&gcc_msm8660_driver); +} +module_exit(gcc_msm8660_exit); + +MODULE_DESCRIPTION("GCC MSM 8660 Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:gcc-msm8660"); diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c new file mode 100644 index 000000000000..fd446ab2fd98 --- /dev/null +++ b/drivers/clk/qcom/gcc-msm8960.c @@ -0,0 +1,2993 @@ +/* + * Copyright (c) 2013, 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-msm8960.h> +#include <dt-bindings/reset/qcom,gcc-msm8960.h> + +#include "clk-regmap.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-branch.h" +#include "reset.h" + +static struct clk_pll pll3 = { + .l_reg = 0x3164, + .m_reg = 0x3168, + .n_reg = 0x316c, + .config_reg = 0x3174, + .mode_reg = 0x3160, + .status_reg = 0x3178, + .status_bit = 16, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pll3", + .parent_names = (const char *[]){ "pxo" }, + .num_parents = 1, + .ops = &clk_pll_ops, + }, +}; + +static struct clk_pll pll8 = { + .l_reg = 0x3144, + .m_reg = 0x3148, + .n_reg = 0x314c, + .config_reg = 0x3154, + .mode_reg = 0x3140, + .status_reg = 0x3158, + .status_bit = 16, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pll8", + .parent_names = (const char *[]){ "pxo" }, + .num_parents = 1, + .ops = &clk_pll_ops, + }, +}; + +static struct clk_regmap pll8_vote = { + .enable_reg = 0x34c0, + .enable_mask = BIT(8), + .hw.init = &(struct clk_init_data){ + .name = "pll8_vote", + .parent_names = (const char *[]){ "pll8" }, + .num_parents = 1, + .ops = &clk_pll_vote_ops, + }, +}; + +static struct clk_pll pll14 = { + .l_reg = 0x31c4, + .m_reg = 0x31c8, + .n_reg = 0x31cc, + .config_reg = 0x31d4, + .mode_reg = 0x31c0, + .status_reg = 0x31d8, + .status_bit = 16, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pll14", + .parent_names = (const char *[]){ "pxo" }, + .num_parents = 1, + .ops = &clk_pll_ops, + }, +}; + +static struct clk_regmap pll14_vote = { + .enable_reg = 0x34c0, + .enable_mask = BIT(14), + .hw.init = &(struct clk_init_data){ + .name = "pll14_vote", + .parent_names = (const char *[]){ "pll14" }, + .num_parents = 1, + .ops = &clk_pll_vote_ops, + }, +}; + +#define P_PXO 0 +#define P_PLL8 1 +#define P_CXO 2 + +static const u8 gcc_pxo_pll8_map[] = { + [P_PXO] = 0, + [P_PLL8] = 3, +}; + +static const char *gcc_pxo_pll8[] = { + "pxo", + "pll8_vote", +}; + +static const u8 gcc_pxo_pll8_cxo_map[] = { + [P_PXO] = 0, + [P_PLL8] = 3, + [P_CXO] = 5, +}; + +static const char *gcc_pxo_pll8_cxo[] = { + "pxo", + "pll8_vote", + "cxo", +}; + +static struct freq_tbl clk_tbl_gsbi_uart[] = { + { 1843200, P_PLL8, 2, 6, 625 }, + { 3686400, P_PLL8, 2, 12, 625 }, + { 7372800, P_PLL8, 2, 24, 625 }, + { 14745600, P_PLL8, 2, 48, 625 }, + { 16000000, P_PLL8, 4, 1, 6 }, + { 24000000, P_PLL8, 4, 1, 4 }, + { 32000000, P_PLL8, 4, 1, 3 }, + { 40000000, P_PLL8, 1, 5, 48 }, + { 46400000, P_PLL8, 1, 29, 240 }, + { 48000000, P_PLL8, 4, 1, 2 }, + { 51200000, P_PLL8, 1, 2, 15 }, + { 56000000, P_PLL8, 1, 7, 48 }, + { 58982400, P_PLL8, 1, 96, 625 }, + { 64000000, P_PLL8, 2, 1, 3 }, + { } +}; + +static struct clk_rcg gsbi1_uart_src = { + .ns_reg = 0x29d4, + .md_reg = 0x29d0, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x29d4, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi1_uart_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi1_uart_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 10, + .clkr = { + .enable_reg = 0x29d4, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi1_uart_clk", + .parent_names = (const char *[]){ + "gsbi1_uart_src", + }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi2_uart_src = { + .ns_reg = 0x29f4, + .md_reg = 0x29f0, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x29f4, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi2_uart_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi2_uart_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 6, + .clkr = { + .enable_reg = 0x29f4, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi2_uart_clk", + .parent_names = (const char *[]){ + "gsbi2_uart_src", + }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi3_uart_src = { + .ns_reg = 0x2a14, + .md_reg = 0x2a10, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x2a14, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi3_uart_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi3_uart_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 2, + .clkr = { + .enable_reg = 0x2a14, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi3_uart_clk", + .parent_names = (const char *[]){ + "gsbi3_uart_src", + }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi4_uart_src = { + .ns_reg = 0x2a34, + .md_reg = 0x2a30, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x2a34, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi4_uart_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi4_uart_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 26, + .clkr = { + .enable_reg = 0x2a34, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi4_uart_clk", + .parent_names = (const char *[]){ + "gsbi4_uart_src", + }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi5_uart_src = { + .ns_reg = 0x2a54, + .md_reg = 0x2a50, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x2a54, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi5_uart_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi5_uart_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 22, + .clkr = { + .enable_reg = 0x2a54, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi5_uart_clk", + .parent_names = (const char *[]){ + "gsbi5_uart_src", + }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi6_uart_src = { + .ns_reg = 0x2a74, + .md_reg = 0x2a70, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x2a74, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi6_uart_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi6_uart_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 18, + .clkr = { + .enable_reg = 0x2a74, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi6_uart_clk", + .parent_names = (const char *[]){ + "gsbi6_uart_src", + }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi7_uart_src = { + .ns_reg = 0x2a94, + .md_reg = 0x2a90, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x2a94, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi7_uart_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi7_uart_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 14, + .clkr = { + .enable_reg = 0x2a94, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi7_uart_clk", + .parent_names = (const char *[]){ + "gsbi7_uart_src", + }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi8_uart_src = { + .ns_reg = 0x2ab4, + .md_reg = 0x2ab0, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x2ab4, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi8_uart_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi8_uart_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 10, + .clkr = { + .enable_reg = 0x2ab4, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi8_uart_clk", + .parent_names = (const char *[]){ "gsbi8_uart_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi9_uart_src = { + .ns_reg = 0x2ad4, + .md_reg = 0x2ad0, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x2ad4, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi9_uart_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi9_uart_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 6, + .clkr = { + .enable_reg = 0x2ad4, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi9_uart_clk", + .parent_names = (const char *[]){ "gsbi9_uart_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi10_uart_src = { + .ns_reg = 0x2af4, + .md_reg = 0x2af0, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x2af4, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi10_uart_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi10_uart_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 2, + .clkr = { + .enable_reg = 0x2af4, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi10_uart_clk", + .parent_names = (const char *[]){ "gsbi10_uart_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi11_uart_src = { + .ns_reg = 0x2b14, + .md_reg = 0x2b10, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x2b14, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi11_uart_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi11_uart_clk = { + .halt_reg = 0x2fd4, + .halt_bit = 17, + .clkr = { + .enable_reg = 0x2b14, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi11_uart_clk", + .parent_names = (const char *[]){ "gsbi11_uart_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi12_uart_src = { + .ns_reg = 0x2b34, + .md_reg = 0x2b30, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x2b34, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi12_uart_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi12_uart_clk = { + .halt_reg = 0x2fd4, + .halt_bit = 13, + .clkr = { + .enable_reg = 0x2b34, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi12_uart_clk", + .parent_names = (const char *[]){ "gsbi12_uart_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct freq_tbl clk_tbl_gsbi_qup[] = { + { 1100000, P_PXO, 1, 2, 49 }, + { 5400000, P_PXO, 1, 1, 5 }, + { 10800000, P_PXO, 1, 2, 5 }, + { 15060000, P_PLL8, 1, 2, 51 }, + { 24000000, P_PLL8, 4, 1, 4 }, + { 25600000, P_PLL8, 1, 1, 15 }, + { 27000000, P_PXO, 1, 0, 0 }, + { 48000000, P_PLL8, 4, 1, 2 }, + { 51200000, P_PLL8, 1, 2, 15 }, + { } +}; + +static struct clk_rcg gsbi1_qup_src = { + .ns_reg = 0x29cc, + .md_reg = 0x29c8, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x29cc, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi1_qup_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi1_qup_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 9, + .clkr = { + .enable_reg = 0x29cc, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi1_qup_clk", + .parent_names = (const char *[]){ "gsbi1_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi2_qup_src = { + .ns_reg = 0x29ec, + .md_reg = 0x29e8, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x29ec, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi2_qup_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi2_qup_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 4, + .clkr = { + .enable_reg = 0x29ec, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi2_qup_clk", + .parent_names = (const char *[]){ "gsbi2_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi3_qup_src = { + .ns_reg = 0x2a0c, + .md_reg = 0x2a08, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x2a0c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi3_qup_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi3_qup_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 0, + .clkr = { + .enable_reg = 0x2a0c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi3_qup_clk", + .parent_names = (const char *[]){ "gsbi3_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi4_qup_src = { + .ns_reg = 0x2a2c, + .md_reg = 0x2a28, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x2a2c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi4_qup_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi4_qup_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 24, + .clkr = { + .enable_reg = 0x2a2c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi4_qup_clk", + .parent_names = (const char *[]){ "gsbi4_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi5_qup_src = { + .ns_reg = 0x2a4c, + .md_reg = 0x2a48, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x2a4c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi5_qup_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi5_qup_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 20, + .clkr = { + .enable_reg = 0x2a4c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi5_qup_clk", + .parent_names = (const char *[]){ "gsbi5_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi6_qup_src = { + .ns_reg = 0x2a6c, + .md_reg = 0x2a68, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x2a6c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi6_qup_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi6_qup_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 16, + .clkr = { + .enable_reg = 0x2a6c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi6_qup_clk", + .parent_names = (const char *[]){ "gsbi6_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi7_qup_src = { + .ns_reg = 0x2a8c, + .md_reg = 0x2a88, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x2a8c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi7_qup_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi7_qup_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 12, + .clkr = { + .enable_reg = 0x2a8c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi7_qup_clk", + .parent_names = (const char *[]){ "gsbi7_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi8_qup_src = { + .ns_reg = 0x2aac, + .md_reg = 0x2aa8, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x2aac, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi8_qup_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi8_qup_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 8, + .clkr = { + .enable_reg = 0x2aac, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi8_qup_clk", + .parent_names = (const char *[]){ "gsbi8_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi9_qup_src = { + .ns_reg = 0x2acc, + .md_reg = 0x2ac8, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x2acc, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi9_qup_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi9_qup_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 4, + .clkr = { + .enable_reg = 0x2acc, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi9_qup_clk", + .parent_names = (const char *[]){ "gsbi9_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi10_qup_src = { + .ns_reg = 0x2aec, + .md_reg = 0x2ae8, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x2aec, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi10_qup_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi10_qup_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 0, + .clkr = { + .enable_reg = 0x2aec, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi10_qup_clk", + .parent_names = (const char *[]){ "gsbi10_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi11_qup_src = { + .ns_reg = 0x2b0c, + .md_reg = 0x2b08, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x2b0c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi11_qup_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi11_qup_clk = { + .halt_reg = 0x2fd4, + .halt_bit = 15, + .clkr = { + .enable_reg = 0x2b0c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi11_qup_clk", + .parent_names = (const char *[]){ "gsbi11_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi12_qup_src = { + .ns_reg = 0x2b2c, + .md_reg = 0x2b28, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x2b2c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi12_qup_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi12_qup_clk = { + .halt_reg = 0x2fd4, + .halt_bit = 11, + .clkr = { + .enable_reg = 0x2b2c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi12_qup_clk", + .parent_names = (const char *[]){ "gsbi12_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl clk_tbl_gp[] = { + { 9600000, P_CXO, 2, 0, 0 }, + { 13500000, P_PXO, 2, 0, 0 }, + { 19200000, P_CXO, 1, 0, 0 }, + { 27000000, P_PXO, 1, 0, 0 }, + { 64000000, P_PLL8, 2, 1, 3 }, + { 76800000, P_PLL8, 1, 1, 5 }, + { 96000000, P_PLL8, 4, 0, 0 }, + { 128000000, P_PLL8, 3, 0, 0 }, + { 192000000, P_PLL8, 2, 0, 0 }, + { } +}; + +static struct clk_rcg gp0_src = { + .ns_reg = 0x2d24, + .md_reg = 0x2d00, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_cxo_map, + }, + .freq_tbl = clk_tbl_gp, + .clkr = { + .enable_reg = 0x2d24, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gp0_src", + .parent_names = gcc_pxo_pll8_cxo, + .num_parents = 3, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + } +}; + +static struct clk_branch gp0_clk = { + .halt_reg = 0x2fd8, + .halt_bit = 7, + .clkr = { + .enable_reg = 0x2d24, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gp0_clk", + .parent_names = (const char *[]){ "gp0_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gp1_src = { + .ns_reg = 0x2d44, + .md_reg = 0x2d40, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_cxo_map, + }, + .freq_tbl = clk_tbl_gp, + .clkr = { + .enable_reg = 0x2d44, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gp1_src", + .parent_names = gcc_pxo_pll8_cxo, + .num_parents = 3, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch gp1_clk = { + .halt_reg = 0x2fd8, + .halt_bit = 6, + .clkr = { + .enable_reg = 0x2d44, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gp1_clk", + .parent_names = (const char *[]){ "gp1_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gp2_src = { + .ns_reg = 0x2d64, + .md_reg = 0x2d60, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_cxo_map, + }, + .freq_tbl = clk_tbl_gp, + .clkr = { + .enable_reg = 0x2d64, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gp2_src", + .parent_names = gcc_pxo_pll8_cxo, + .num_parents = 3, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch gp2_clk = { + .halt_reg = 0x2fd8, + .halt_bit = 5, + .clkr = { + .enable_reg = 0x2d64, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gp2_clk", + .parent_names = (const char *[]){ "gp2_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch pmem_clk = { + .hwcg_reg = 0x25a0, + .hwcg_bit = 6, + .halt_reg = 0x2fc8, + .halt_bit = 20, + .clkr = { + .enable_reg = 0x25a0, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "pmem_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_rcg prng_src = { + .ns_reg = 0x2e80, + .p = { + .pre_div_shift = 3, + .pre_div_width = 4, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "prng_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + }, + }, +}; + +static struct clk_branch prng_clk = { + .halt_reg = 0x2fd8, + .halt_check = BRANCH_HALT_VOTED, + .halt_bit = 10, + .clkr = { + .enable_reg = 0x3080, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "prng_clk", + .parent_names = (const char *[]){ "prng_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + }, + }, +}; + +static const struct freq_tbl clk_tbl_sdc[] = { + { 144000, P_PXO, 3, 2, 125 }, + { 400000, P_PLL8, 4, 1, 240 }, + { 16000000, P_PLL8, 4, 1, 6 }, + { 17070000, P_PLL8, 1, 2, 45 }, + { 20210000, P_PLL8, 1, 1, 19 }, + { 24000000, P_PLL8, 4, 1, 4 }, + { 48000000, P_PLL8, 4, 1, 2 }, + { 64000000, P_PLL8, 3, 1, 2 }, + { 96000000, P_PLL8, 4, 0, 0 }, + { 192000000, P_PLL8, 2, 0, 0 }, + { } +}; + +static struct clk_rcg sdc1_src = { + .ns_reg = 0x282c, + .md_reg = 0x2828, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_sdc, + .clkr = { + .enable_reg = 0x282c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "sdc1_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch sdc1_clk = { + .halt_reg = 0x2fc8, + .halt_bit = 6, + .clkr = { + .enable_reg = 0x282c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "sdc1_clk", + .parent_names = (const char *[]){ "sdc1_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg sdc2_src = { + .ns_reg = 0x284c, + .md_reg = 0x2848, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_sdc, + .clkr = { + .enable_reg = 0x284c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "sdc2_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch sdc2_clk = { + .halt_reg = 0x2fc8, + .halt_bit = 5, + .clkr = { + .enable_reg = 0x284c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "sdc2_clk", + .parent_names = (const char *[]){ "sdc2_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg sdc3_src = { + .ns_reg = 0x286c, + .md_reg = 0x2868, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_sdc, + .clkr = { + .enable_reg = 0x286c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "sdc3_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch sdc3_clk = { + .halt_reg = 0x2fc8, + .halt_bit = 4, + .clkr = { + .enable_reg = 0x286c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "sdc3_clk", + .parent_names = (const char *[]){ "sdc3_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg sdc4_src = { + .ns_reg = 0x288c, + .md_reg = 0x2888, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_sdc, + .clkr = { + .enable_reg = 0x288c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "sdc4_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch sdc4_clk = { + .halt_reg = 0x2fc8, + .halt_bit = 3, + .clkr = { + .enable_reg = 0x288c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "sdc4_clk", + .parent_names = (const char *[]){ "sdc4_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg sdc5_src = { + .ns_reg = 0x28ac, + .md_reg = 0x28a8, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_sdc, + .clkr = { + .enable_reg = 0x28ac, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "sdc5_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch sdc5_clk = { + .halt_reg = 0x2fc8, + .halt_bit = 2, + .clkr = { + .enable_reg = 0x28ac, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "sdc5_clk", + .parent_names = (const char *[]){ "sdc5_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl clk_tbl_tsif_ref[] = { + { 105000, P_PXO, 1, 1, 256 }, + { } +}; + +static struct clk_rcg tsif_ref_src = { + .ns_reg = 0x2710, + .md_reg = 0x270c, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_tsif_ref, + .clkr = { + .enable_reg = 0x2710, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "tsif_ref_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch tsif_ref_clk = { + .halt_reg = 0x2fd4, + .halt_bit = 5, + .clkr = { + .enable_reg = 0x2710, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "tsif_ref_clk", + .parent_names = (const char *[]){ "tsif_ref_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl clk_tbl_usb[] = { + { 60000000, P_PLL8, 1, 5, 32 }, + { } +}; + +static struct clk_rcg usb_hs1_xcvr_src = { + .ns_reg = 0x290c, + .md_reg = 0x2908, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_usb, + .clkr = { + .enable_reg = 0x290c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "usb_hs1_xcvr_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch usb_hs1_xcvr_clk = { + .halt_reg = 0x2fc8, + .halt_bit = 0, + .clkr = { + .enable_reg = 0x290c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "usb_hs1_xcvr_clk", + .parent_names = (const char *[]){ "usb_hs1_xcvr_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg usb_hsic_xcvr_fs_src = { + .ns_reg = 0x2928, + .md_reg = 0x2924, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_usb, + .clkr = { + .enable_reg = 0x2928, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "usb_hsic_xcvr_fs_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static const char *usb_hsic_xcvr_fs_src_p[] = { "usb_hsic_xcvr_fs_src" }; + +static struct clk_branch usb_hsic_xcvr_fs_clk = { + .halt_reg = 0x2fc8, + .halt_bit = 2, + .clkr = { + .enable_reg = 0x2928, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "usb_hsic_xcvr_fs_clk", + .parent_names = usb_hsic_xcvr_fs_src_p, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch usb_hsic_system_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 24, + .clkr = { + .enable_reg = 0x292c, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .parent_names = usb_hsic_xcvr_fs_src_p, + .num_parents = 1, + .name = "usb_hsic_system_clk", + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch usb_hsic_hsic_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 19, + .clkr = { + .enable_reg = 0x2b44, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .parent_names = (const char *[]){ "pll14_vote" }, + .num_parents = 1, + .name = "usb_hsic_hsic_clk", + .ops = &clk_branch_ops, + }, + }, +}; + +static struct clk_branch usb_hsic_hsio_cal_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 23, + .clkr = { + .enable_reg = 0x2b48, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "usb_hsic_hsio_cal_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_rcg usb_fs1_xcvr_fs_src = { + .ns_reg = 0x2968, + .md_reg = 0x2964, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_usb, + .clkr = { + .enable_reg = 0x2968, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "usb_fs1_xcvr_fs_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static const char *usb_fs1_xcvr_fs_src_p[] = { "usb_fs1_xcvr_fs_src" }; + +static struct clk_branch usb_fs1_xcvr_fs_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 15, + .clkr = { + .enable_reg = 0x2968, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "usb_fs1_xcvr_fs_clk", + .parent_names = usb_fs1_xcvr_fs_src_p, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch usb_fs1_system_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 16, + .clkr = { + .enable_reg = 0x296c, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .parent_names = usb_fs1_xcvr_fs_src_p, + .num_parents = 1, + .name = "usb_fs1_system_clk", + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg usb_fs2_xcvr_fs_src = { + .ns_reg = 0x2988, + .md_reg = 0x2984, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_pxo_pll8_map, + }, + .freq_tbl = clk_tbl_usb, + .clkr = { + .enable_reg = 0x2988, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "usb_fs2_xcvr_fs_src", + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static const char *usb_fs2_xcvr_fs_src_p[] = { "usb_fs2_xcvr_fs_src" }; + +static struct clk_branch usb_fs2_xcvr_fs_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 12, + .clkr = { + .enable_reg = 0x2988, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "usb_fs2_xcvr_fs_clk", + .parent_names = usb_fs2_xcvr_fs_src_p, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch usb_fs2_system_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 13, + .clkr = { + .enable_reg = 0x298c, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "usb_fs2_system_clk", + .parent_names = usb_fs2_xcvr_fs_src_p, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch ce1_core_clk = { + .hwcg_reg = 0x2724, + .hwcg_bit = 6, + .halt_reg = 0x2fd4, + .halt_bit = 27, + .clkr = { + .enable_reg = 0x2724, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "ce1_core_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch ce1_h_clk = { + .halt_reg = 0x2fd4, + .halt_bit = 1, + .clkr = { + .enable_reg = 0x2720, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "ce1_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch dma_bam_h_clk = { + .hwcg_reg = 0x25c0, + .hwcg_bit = 6, + .halt_reg = 0x2fc8, + .halt_bit = 12, + .clkr = { + .enable_reg = 0x25c0, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "dma_bam_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gsbi1_h_clk = { + .hwcg_reg = 0x29c0, + .hwcg_bit = 6, + .halt_reg = 0x2fcc, + .halt_bit = 11, + .clkr = { + .enable_reg = 0x29c0, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi1_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gsbi2_h_clk = { + .hwcg_reg = 0x29e0, + .hwcg_bit = 6, + .halt_reg = 0x2fcc, + .halt_bit = 7, + .clkr = { + .enable_reg = 0x29e0, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi2_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gsbi3_h_clk = { + .hwcg_reg = 0x2a00, + .hwcg_bit = 6, + .halt_reg = 0x2fcc, + .halt_bit = 3, + .clkr = { + .enable_reg = 0x2a00, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi3_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gsbi4_h_clk = { + .hwcg_reg = 0x2a20, + .hwcg_bit = 6, + .halt_reg = 0x2fd0, + .halt_bit = 27, + .clkr = { + .enable_reg = 0x2a20, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi4_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gsbi5_h_clk = { + .hwcg_reg = 0x2a40, + .hwcg_bit = 6, + .halt_reg = 0x2fd0, + .halt_bit = 23, + .clkr = { + .enable_reg = 0x2a40, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi5_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gsbi6_h_clk = { + .hwcg_reg = 0x2a60, + .hwcg_bit = 6, + .halt_reg = 0x2fd0, + .halt_bit = 19, + .clkr = { + .enable_reg = 0x2a60, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi6_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gsbi7_h_clk = { + .hwcg_reg = 0x2a80, + .hwcg_bit = 6, + .halt_reg = 0x2fd0, + .halt_bit = 15, + .clkr = { + .enable_reg = 0x2a80, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi7_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gsbi8_h_clk = { + .hwcg_reg = 0x2aa0, + .hwcg_bit = 6, + .halt_reg = 0x2fd0, + .halt_bit = 11, + .clkr = { + .enable_reg = 0x2aa0, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi8_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gsbi9_h_clk = { + .hwcg_reg = 0x2ac0, + .hwcg_bit = 6, + .halt_reg = 0x2fd0, + .halt_bit = 7, + .clkr = { + .enable_reg = 0x2ac0, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi9_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gsbi10_h_clk = { + .hwcg_reg = 0x2ae0, + .hwcg_bit = 6, + .halt_reg = 0x2fd0, + .halt_bit = 3, + .clkr = { + .enable_reg = 0x2ae0, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi10_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gsbi11_h_clk = { + .hwcg_reg = 0x2b00, + .hwcg_bit = 6, + .halt_reg = 0x2fd4, + .halt_bit = 18, + .clkr = { + .enable_reg = 0x2b00, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi11_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gsbi12_h_clk = { + .hwcg_reg = 0x2b20, + .hwcg_bit = 6, + .halt_reg = 0x2fd4, + .halt_bit = 14, + .clkr = { + .enable_reg = 0x2b20, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi12_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch tsif_h_clk = { + .hwcg_reg = 0x2700, + .hwcg_bit = 6, + .halt_reg = 0x2fd4, + .halt_bit = 7, + .clkr = { + .enable_reg = 0x2700, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "tsif_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch usb_fs1_h_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 17, + .clkr = { + .enable_reg = 0x2960, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "usb_fs1_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch usb_fs2_h_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 14, + .clkr = { + .enable_reg = 0x2980, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "usb_fs2_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch usb_hs1_h_clk = { + .hwcg_reg = 0x2900, + .hwcg_bit = 6, + .halt_reg = 0x2fc8, + .halt_bit = 1, + .clkr = { + .enable_reg = 0x2900, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "usb_hs1_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch usb_hsic_h_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 28, + .clkr = { + .enable_reg = 0x2920, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "usb_hsic_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch sdc1_h_clk = { + .hwcg_reg = 0x2820, + .hwcg_bit = 6, + .halt_reg = 0x2fc8, + .halt_bit = 11, + .clkr = { + .enable_reg = 0x2820, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "sdc1_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch sdc2_h_clk = { + .hwcg_reg = 0x2840, + .hwcg_bit = 6, + .halt_reg = 0x2fc8, + .halt_bit = 10, + .clkr = { + .enable_reg = 0x2840, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "sdc2_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch sdc3_h_clk = { + .hwcg_reg = 0x2860, + .hwcg_bit = 6, + .halt_reg = 0x2fc8, + .halt_bit = 9, + .clkr = { + .enable_reg = 0x2860, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "sdc3_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch sdc4_h_clk = { + .hwcg_reg = 0x2880, + .hwcg_bit = 6, + .halt_reg = 0x2fc8, + .halt_bit = 8, + .clkr = { + .enable_reg = 0x2880, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "sdc4_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch sdc5_h_clk = { + .hwcg_reg = 0x28a0, + .hwcg_bit = 6, + .halt_reg = 0x2fc8, + .halt_bit = 7, + .clkr = { + .enable_reg = 0x28a0, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "sdc5_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch adm0_clk = { + .halt_reg = 0x2fdc, + .halt_check = BRANCH_HALT_VOTED, + .halt_bit = 14, + .clkr = { + .enable_reg = 0x3080, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "adm0_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch adm0_pbus_clk = { + .hwcg_reg = 0x2208, + .hwcg_bit = 6, + .halt_reg = 0x2fdc, + .halt_check = BRANCH_HALT_VOTED, + .halt_bit = 13, + .clkr = { + .enable_reg = 0x3080, + .enable_mask = BIT(3), + .hw.init = &(struct clk_init_data){ + .name = "adm0_pbus_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch pmic_arb0_h_clk = { + .halt_reg = 0x2fd8, + .halt_check = BRANCH_HALT_VOTED, + .halt_bit = 22, + .clkr = { + .enable_reg = 0x3080, + .enable_mask = BIT(8), + .hw.init = &(struct clk_init_data){ + .name = "pmic_arb0_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch pmic_arb1_h_clk = { + .halt_reg = 0x2fd8, + .halt_check = BRANCH_HALT_VOTED, + .halt_bit = 21, + .clkr = { + .enable_reg = 0x3080, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "pmic_arb1_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch pmic_ssbi2_clk = { + .halt_reg = 0x2fd8, + .halt_check = BRANCH_HALT_VOTED, + .halt_bit = 23, + .clkr = { + .enable_reg = 0x3080, + .enable_mask = BIT(7), + .hw.init = &(struct clk_init_data){ + .name = "pmic_ssbi2_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch rpm_msg_ram_h_clk = { + .hwcg_reg = 0x27e0, + .hwcg_bit = 6, + .halt_reg = 0x2fd8, + .halt_check = BRANCH_HALT_VOTED, + .halt_bit = 12, + .clkr = { + .enable_reg = 0x3080, + .enable_mask = BIT(6), + .hw.init = &(struct clk_init_data){ + .name = "rpm_msg_ram_h_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_regmap *gcc_msm8960_clks[] = { + [PLL3] = &pll3.clkr, + [PLL8] = &pll8.clkr, + [PLL8_VOTE] = &pll8_vote, + [PLL14] = &pll14.clkr, + [PLL14_VOTE] = &pll14_vote, + [GSBI1_UART_SRC] = &gsbi1_uart_src.clkr, + [GSBI1_UART_CLK] = &gsbi1_uart_clk.clkr, + [GSBI2_UART_SRC] = &gsbi2_uart_src.clkr, + [GSBI2_UART_CLK] = &gsbi2_uart_clk.clkr, + [GSBI3_UART_SRC] = &gsbi3_uart_src.clkr, + [GSBI3_UART_CLK] = &gsbi3_uart_clk.clkr, + [GSBI4_UART_SRC] = &gsbi4_uart_src.clkr, + [GSBI4_UART_CLK] = &gsbi4_uart_clk.clkr, + [GSBI5_UART_SRC] = &gsbi5_uart_src.clkr, + [GSBI5_UART_CLK] = &gsbi5_uart_clk.clkr, + [GSBI6_UART_SRC] = &gsbi6_uart_src.clkr, + [GSBI6_UART_CLK] = &gsbi6_uart_clk.clkr, + [GSBI7_UART_SRC] = &gsbi7_uart_src.clkr, + [GSBI7_UART_CLK] = &gsbi7_uart_clk.clkr, + [GSBI8_UART_SRC] = &gsbi8_uart_src.clkr, + [GSBI8_UART_CLK] = &gsbi8_uart_clk.clkr, + [GSBI9_UART_SRC] = &gsbi9_uart_src.clkr, + [GSBI9_UART_CLK] = &gsbi9_uart_clk.clkr, + [GSBI10_UART_SRC] = &gsbi10_uart_src.clkr, + [GSBI10_UART_CLK] = &gsbi10_uart_clk.clkr, + [GSBI11_UART_SRC] = &gsbi11_uart_src.clkr, + [GSBI11_UART_CLK] = &gsbi11_uart_clk.clkr, + [GSBI12_UART_SRC] = &gsbi12_uart_src.clkr, + [GSBI12_UART_CLK] = &gsbi12_uart_clk.clkr, + [GSBI1_QUP_SRC] = &gsbi1_qup_src.clkr, + [GSBI1_QUP_CLK] = &gsbi1_qup_clk.clkr, + [GSBI2_QUP_SRC] = &gsbi2_qup_src.clkr, + [GSBI2_QUP_CLK] = &gsbi2_qup_clk.clkr, + [GSBI3_QUP_SRC] = &gsbi3_qup_src.clkr, + [GSBI3_QUP_CLK] = &gsbi3_qup_clk.clkr, + [GSBI4_QUP_SRC] = &gsbi4_qup_src.clkr, + [GSBI4_QUP_CLK] = &gsbi4_qup_clk.clkr, + [GSBI5_QUP_SRC] = &gsbi5_qup_src.clkr, + [GSBI5_QUP_CLK] = &gsbi5_qup_clk.clkr, + [GSBI6_QUP_SRC] = &gsbi6_qup_src.clkr, + [GSBI6_QUP_CLK] = &gsbi6_qup_clk.clkr, + [GSBI7_QUP_SRC] = &gsbi7_qup_src.clkr, + [GSBI7_QUP_CLK] = &gsbi7_qup_clk.clkr, + [GSBI8_QUP_SRC] = &gsbi8_qup_src.clkr, + [GSBI8_QUP_CLK] = &gsbi8_qup_clk.clkr, + [GSBI9_QUP_SRC] = &gsbi9_qup_src.clkr, + [GSBI9_QUP_CLK] = &gsbi9_qup_clk.clkr, + [GSBI10_QUP_SRC] = &gsbi10_qup_src.clkr, + [GSBI10_QUP_CLK] = &gsbi10_qup_clk.clkr, + [GSBI11_QUP_SRC] = &gsbi11_qup_src.clkr, + [GSBI11_QUP_CLK] = &gsbi11_qup_clk.clkr, + [GSBI12_QUP_SRC] = &gsbi12_qup_src.clkr, + [GSBI12_QUP_CLK] = &gsbi12_qup_clk.clkr, + [GP0_SRC] = &gp0_src.clkr, + [GP0_CLK] = &gp0_clk.clkr, + [GP1_SRC] = &gp1_src.clkr, + [GP1_CLK] = &gp1_clk.clkr, + [GP2_SRC] = &gp2_src.clkr, + [GP2_CLK] = &gp2_clk.clkr, + [PMEM_A_CLK] = &pmem_clk.clkr, + [PRNG_SRC] = &prng_src.clkr, + [PRNG_CLK] = &prng_clk.clkr, + [SDC1_SRC] = &sdc1_src.clkr, + [SDC1_CLK] = &sdc1_clk.clkr, + [SDC2_SRC] = &sdc2_src.clkr, + [SDC2_CLK] = &sdc2_clk.clkr, + [SDC3_SRC] = &sdc3_src.clkr, + [SDC3_CLK] = &sdc3_clk.clkr, + [SDC4_SRC] = &sdc4_src.clkr, + [SDC4_CLK] = &sdc4_clk.clkr, + [SDC5_SRC] = &sdc5_src.clkr, + [SDC5_CLK] = &sdc5_clk.clkr, + [TSIF_REF_SRC] = &tsif_ref_src.clkr, + [TSIF_REF_CLK] = &tsif_ref_clk.clkr, + [USB_HS1_XCVR_SRC] = &usb_hs1_xcvr_src.clkr, + [USB_HS1_XCVR_CLK] = &usb_hs1_xcvr_clk.clkr, + [USB_HSIC_XCVR_FS_SRC] = &usb_hsic_xcvr_fs_src.clkr, + [USB_HSIC_XCVR_FS_CLK] = &usb_hsic_xcvr_fs_clk.clkr, + [USB_HSIC_SYSTEM_CLK] = &usb_hsic_system_clk.clkr, + [USB_HSIC_HSIC_CLK] = &usb_hsic_hsic_clk.clkr, + [USB_HSIC_HSIO_CAL_CLK] = &usb_hsic_hsio_cal_clk.clkr, + [USB_FS1_XCVR_FS_SRC] = &usb_fs1_xcvr_fs_src.clkr, + [USB_FS1_XCVR_FS_CLK] = &usb_fs1_xcvr_fs_clk.clkr, + [USB_FS1_SYSTEM_CLK] = &usb_fs1_system_clk.clkr, + [USB_FS2_XCVR_FS_SRC] = &usb_fs2_xcvr_fs_src.clkr, + [USB_FS2_XCVR_FS_CLK] = &usb_fs2_xcvr_fs_clk.clkr, + [USB_FS2_SYSTEM_CLK] = &usb_fs2_system_clk.clkr, + [CE1_CORE_CLK] = &ce1_core_clk.clkr, + [CE1_H_CLK] = &ce1_h_clk.clkr, + [DMA_BAM_H_CLK] = &dma_bam_h_clk.clkr, + [GSBI1_H_CLK] = &gsbi1_h_clk.clkr, + [GSBI2_H_CLK] = &gsbi2_h_clk.clkr, + [GSBI3_H_CLK] = &gsbi3_h_clk.clkr, + [GSBI4_H_CLK] = &gsbi4_h_clk.clkr, + [GSBI5_H_CLK] = &gsbi5_h_clk.clkr, + [GSBI6_H_CLK] = &gsbi6_h_clk.clkr, + [GSBI7_H_CLK] = &gsbi7_h_clk.clkr, + [GSBI8_H_CLK] = &gsbi8_h_clk.clkr, + [GSBI9_H_CLK] = &gsbi9_h_clk.clkr, + [GSBI10_H_CLK] = &gsbi10_h_clk.clkr, + [GSBI11_H_CLK] = &gsbi11_h_clk.clkr, + [GSBI12_H_CLK] = &gsbi12_h_clk.clkr, + [TSIF_H_CLK] = &tsif_h_clk.clkr, + [USB_FS1_H_CLK] = &usb_fs1_h_clk.clkr, + [USB_FS2_H_CLK] = &usb_fs2_h_clk.clkr, + [USB_HS1_H_CLK] = &usb_hs1_h_clk.clkr, + [USB_HSIC_H_CLK] = &usb_hsic_h_clk.clkr, + [SDC1_H_CLK] = &sdc1_h_clk.clkr, + [SDC2_H_CLK] = &sdc2_h_clk.clkr, + [SDC3_H_CLK] = &sdc3_h_clk.clkr, + [SDC4_H_CLK] = &sdc4_h_clk.clkr, + [SDC5_H_CLK] = &sdc5_h_clk.clkr, + [ADM0_CLK] = &adm0_clk.clkr, + [ADM0_PBUS_CLK] = &adm0_pbus_clk.clkr, + [PMIC_ARB0_H_CLK] = &pmic_arb0_h_clk.clkr, + [PMIC_ARB1_H_CLK] = &pmic_arb1_h_clk.clkr, + [PMIC_SSBI2_CLK] = &pmic_ssbi2_clk.clkr, + [RPM_MSG_RAM_H_CLK] = &rpm_msg_ram_h_clk.clkr, +}; + +static const struct qcom_reset_map gcc_msm8960_resets[] = { + [SFAB_MSS_Q6_SW_RESET] = { 0x2040, 7 }, + [SFAB_MSS_Q6_FW_RESET] = { 0x2044, 7 }, + [QDSS_STM_RESET] = { 0x2060, 6 }, + [AFAB_SMPSS_S_RESET] = { 0x20b8, 2 }, + [AFAB_SMPSS_M1_RESET] = { 0x20b8, 1 }, + [AFAB_SMPSS_M0_RESET] = { 0x20b8 }, + [AFAB_EBI1_CH0_RESET] = { 0x20c0, 7 }, + [AFAB_EBI1_CH1_RESET] = { 0x20c4, 7}, + [SFAB_ADM0_M0_RESET] = { 0x21e0, 7 }, + [SFAB_ADM0_M1_RESET] = { 0x21e4, 7 }, + [SFAB_ADM0_M2_RESET] = { 0x21e8, 7 }, + [ADM0_C2_RESET] = { 0x220c, 4}, + [ADM0_C1_RESET] = { 0x220c, 3}, + [ADM0_C0_RESET] = { 0x220c, 2}, + [ADM0_PBUS_RESET] = { 0x220c, 1 }, + [ADM0_RESET] = { 0x220c }, + [QDSS_CLKS_SW_RESET] = { 0x2260, 5 }, + [QDSS_POR_RESET] = { 0x2260, 4 }, + [QDSS_TSCTR_RESET] = { 0x2260, 3 }, + [QDSS_HRESET_RESET] = { 0x2260, 2 }, + [QDSS_AXI_RESET] = { 0x2260, 1 }, + [QDSS_DBG_RESET] = { 0x2260 }, + [PCIE_A_RESET] = { 0x22c0, 7 }, + [PCIE_AUX_RESET] = { 0x22c8, 7 }, + [PCIE_H_RESET] = { 0x22d0, 7 }, + [SFAB_PCIE_M_RESET] = { 0x22d4, 1 }, + [SFAB_PCIE_S_RESET] = { 0x22d4 }, + [SFAB_MSS_M_RESET] = { 0x2340, 7 }, + [SFAB_USB3_M_RESET] = { 0x2360, 7 }, + [SFAB_RIVA_M_RESET] = { 0x2380, 7 }, + [SFAB_LPASS_RESET] = { 0x23a0, 7 }, + [SFAB_AFAB_M_RESET] = { 0x23e0, 7 }, + [AFAB_SFAB_M0_RESET] = { 0x2420, 7 }, + [AFAB_SFAB_M1_RESET] = { 0x2424, 7 }, + [SFAB_SATA_S_RESET] = { 0x2480, 7 }, + [SFAB_DFAB_M_RESET] = { 0x2500, 7 }, + [DFAB_SFAB_M_RESET] = { 0x2520, 7 }, + [DFAB_SWAY0_RESET] = { 0x2540, 7 }, + [DFAB_SWAY1_RESET] = { 0x2544, 7 }, + [DFAB_ARB0_RESET] = { 0x2560, 7 }, + [DFAB_ARB1_RESET] = { 0x2564, 7 }, + [PPSS_PROC_RESET] = { 0x2594, 1 }, + [PPSS_RESET] = { 0x2594}, + [DMA_BAM_RESET] = { 0x25c0, 7 }, + [SIC_TIC_RESET] = { 0x2600, 7 }, + [SLIMBUS_H_RESET] = { 0x2620, 7 }, + [SFAB_CFPB_M_RESET] = { 0x2680, 7 }, + [SFAB_CFPB_S_RESET] = { 0x26c0, 7 }, + [TSIF_H_RESET] = { 0x2700, 7 }, + [CE1_H_RESET] = { 0x2720, 7 }, + [CE1_CORE_RESET] = { 0x2724, 7 }, + [CE1_SLEEP_RESET] = { 0x2728, 7 }, + [CE2_H_RESET] = { 0x2740, 7 }, + [CE2_CORE_RESET] = { 0x2744, 7 }, + [SFAB_SFPB_M_RESET] = { 0x2780, 7 }, + [SFAB_SFPB_S_RESET] = { 0x27a0, 7 }, + [RPM_PROC_RESET] = { 0x27c0, 7 }, + [PMIC_SSBI2_RESET] = { 0x270c, 12 }, + [SDC1_RESET] = { 0x2830 }, + [SDC2_RESET] = { 0x2850 }, + [SDC3_RESET] = { 0x2870 }, + [SDC4_RESET] = { 0x2890 }, + [SDC5_RESET] = { 0x28b0 }, + [DFAB_A2_RESET] = { 0x28c0, 7 }, + [USB_HS1_RESET] = { 0x2910 }, + [USB_HSIC_RESET] = { 0x2934 }, + [USB_FS1_XCVR_RESET] = { 0x2974, 1 }, + [USB_FS1_RESET] = { 0x2974 }, + [USB_FS2_XCVR_RESET] = { 0x2994, 1 }, + [USB_FS2_RESET] = { 0x2994 }, + [GSBI1_RESET] = { 0x29dc }, + [GSBI2_RESET] = { 0x29fc }, + [GSBI3_RESET] = { 0x2a1c }, + [GSBI4_RESET] = { 0x2a3c }, + [GSBI5_RESET] = { 0x2a5c }, + [GSBI6_RESET] = { 0x2a7c }, + [GSBI7_RESET] = { 0x2a9c }, + [GSBI8_RESET] = { 0x2abc }, + [GSBI9_RESET] = { 0x2adc }, + [GSBI10_RESET] = { 0x2afc }, + [GSBI11_RESET] = { 0x2b1c }, + [GSBI12_RESET] = { 0x2b3c }, + [SPDM_RESET] = { 0x2b6c }, + [TLMM_H_RESET] = { 0x2ba0, 7 }, + [SFAB_MSS_S_RESET] = { 0x2c00, 7 }, + [MSS_SLP_RESET] = { 0x2c60, 7 }, + [MSS_Q6SW_JTAG_RESET] = { 0x2c68, 7 }, + [MSS_Q6FW_JTAG_RESET] = { 0x2c6c, 7 }, + [MSS_RESET] = { 0x2c64 }, + [SATA_H_RESET] = { 0x2c80, 7 }, + [SATA_RXOOB_RESE] = { 0x2c8c, 7 }, + [SATA_PMALIVE_RESET] = { 0x2c90, 7 }, + [SATA_SFAB_M_RESET] = { 0x2c98, 7 }, + [TSSC_RESET] = { 0x2ca0, 7 }, + [PDM_RESET] = { 0x2cc0, 12 }, + [MPM_H_RESET] = { 0x2da0, 7 }, + [MPM_RESET] = { 0x2da4 }, + [SFAB_SMPSS_S_RESET] = { 0x2e00, 7 }, + [PRNG_RESET] = { 0x2e80, 12 }, + [RIVA_RESET] = { 0x35e0 }, +}; + +static const struct regmap_config gcc_msm8960_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x3660, + .fast_io = true, +}; + +static const struct of_device_id gcc_msm8960_match_table[] = { + { .compatible = "qcom,gcc-msm8960" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_msm8960_match_table); + +struct qcom_cc { + struct qcom_reset_controller reset; + struct clk_onecell_data data; + struct clk *clks[]; +}; + +static int gcc_msm8960_probe(struct platform_device *pdev) +{ + void __iomem *base; + struct resource *res; + int i, ret; + struct device *dev = &pdev->dev; + struct clk *clk; + struct clk_onecell_data *data; + struct clk **clks; + struct regmap *regmap; + size_t num_clks; + struct qcom_reset_controller *reset; + struct qcom_cc *cc; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + regmap = devm_regmap_init_mmio(dev, base, &gcc_msm8960_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + num_clks = ARRAY_SIZE(gcc_msm8960_clks); + cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks, + GFP_KERNEL); + if (!cc) + return -ENOMEM; + + clks = cc->clks; + data = &cc->data; + data->clks = clks; + data->clk_num = num_clks; + + /* 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); + + clk = clk_register_fixed_rate(dev, "pxo", NULL, CLK_IS_ROOT, 27000000); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + for (i = 0; i < num_clks; i++) { + if (!gcc_msm8960_clks[i]) + continue; + clk = devm_clk_register_regmap(dev, gcc_msm8960_clks[i]); + if (IS_ERR(clk)) + return PTR_ERR(clk); + clks[i] = clk; + } + + ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data); + if (ret) + return ret; + + reset = &cc->reset; + reset->rcdev.of_node = dev->of_node; + reset->rcdev.ops = &qcom_reset_ops, + reset->rcdev.owner = THIS_MODULE, + reset->rcdev.nr_resets = ARRAY_SIZE(gcc_msm8960_resets), + reset->regmap = regmap; + reset->reset_map = gcc_msm8960_resets, + platform_set_drvdata(pdev, &reset->rcdev); + + ret = reset_controller_register(&reset->rcdev); + if (ret) + of_clk_del_provider(dev->of_node); + + return ret; +} + +static int gcc_msm8960_remove(struct platform_device *pdev) +{ + of_clk_del_provider(pdev->dev.of_node); + reset_controller_unregister(platform_get_drvdata(pdev)); + return 0; +} + +static struct platform_driver gcc_msm8960_driver = { + .probe = gcc_msm8960_probe, + .remove = gcc_msm8960_remove, + .driver = { + .name = "gcc-msm8960", + .owner = THIS_MODULE, + .of_match_table = gcc_msm8960_match_table, + }, +}; + +static int __init gcc_msm8960_init(void) +{ + return platform_driver_register(&gcc_msm8960_driver); +} +core_initcall(gcc_msm8960_init); + +static void __exit gcc_msm8960_exit(void) +{ + platform_driver_unregister(&gcc_msm8960_driver); +} +module_exit(gcc_msm8960_exit); + +MODULE_DESCRIPTION("QCOM GCC MSM8960 Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:gcc-msm8960"); diff --git a/drivers/clk/qcom/gcc-msm8974.c b/drivers/clk/qcom/gcc-msm8974.c new file mode 100644 index 000000000000..51d457e2b959 --- /dev/null +++ b/drivers/clk/qcom/gcc-msm8974.c @@ -0,0 +1,2694 @@ +/* + * Copyright (c) 2013, 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-msm8974.h> +#include <dt-bindings/reset/qcom,gcc-msm8974.h> + +#include "clk-regmap.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-branch.h" +#include "reset.h" + +#define P_XO 0 +#define P_GPLL0 1 +#define P_GPLL1 1 + +static const u8 gcc_xo_gpll0_map[] = { + [P_XO] = 0, + [P_GPLL0] = 1, +}; + +static const char *gcc_xo_gpll0[] = { + "xo", + "gpll0_vote", +}; + +#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } + +static struct clk_pll gpll0 = { + .l_reg = 0x0004, + .m_reg = 0x0008, + .n_reg = 0x000c, + .config_reg = 0x0014, + .mode_reg = 0x0000, + .status_reg = 0x001c, + .status_bit = 17, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll0", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_pll_ops, + }, +}; + +static struct clk_regmap gpll0_vote = { + .enable_reg = 0x1480, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpll0_vote", + .parent_names = (const char *[]){ "gpll0" }, + .num_parents = 1, + .ops = &clk_pll_vote_ops, + }, +}; + +static struct clk_rcg2 config_noc_clk_src = { + .cmd_rcgr = 0x0150, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .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 struct clk_rcg2 periph_noc_clk_src = { + .cmd_rcgr = 0x0190, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .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 struct clk_rcg2 system_noc_clk_src = { + .cmd_rcgr = 0x0120, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "system_noc_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_pll gpll1 = { + .l_reg = 0x0044, + .m_reg = 0x0048, + .n_reg = 0x004c, + .config_reg = 0x0054, + .mode_reg = 0x0040, + .status_reg = 0x005c, + .status_bit = 17, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll1", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_pll_ops, + }, +}; + +static struct clk_regmap gpll1_vote = { + .enable_reg = 0x1480, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gpll1_vote", + .parent_names = (const char *[]){ "gpll1" }, + .num_parents = 1, + .ops = &clk_pll_vote_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb30_master_clk[] = { + F(125000000, P_GPLL0, 1, 5, 24), + { } +}; + +static struct clk_rcg2 usb30_master_clk_src = { + .cmd_rcgr = 0x03d4, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_usb30_master_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb30_master_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk[] = { + F(19200000, P_XO, 1, 0, 0), + F(37500000, P_GPLL0, 16, 0, 0), + F(50000000, P_GPLL0, 12, 0, 0), + { } +}; + +static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = { + .cmd_rcgr = 0x0660, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk, + .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_gcc_blsp1_2_qup1_6_spi_apps_clk[] = { + 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 = 0x064c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_spi_apps_clk, + .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 struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = { + .cmd_rcgr = 0x06e0, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk, + .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_qup2_spi_apps_clk_src = { + .cmd_rcgr = 0x06cc, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_spi_apps_clk, + .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_qup3_i2c_apps_clk_src = { + .cmd_rcgr = 0x0760, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk, + .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_qup3_spi_apps_clk_src = { + .cmd_rcgr = 0x074c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_spi_apps_clk, + .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_qup4_i2c_apps_clk_src = { + .cmd_rcgr = 0x07e0, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk, + .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_qup4_spi_apps_clk_src = { + .cmd_rcgr = 0x07cc, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_spi_apps_clk, + .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_qup5_i2c_apps_clk_src = { + .cmd_rcgr = 0x0860, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk, + .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_qup5_spi_apps_clk_src = { + .cmd_rcgr = 0x084c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_spi_apps_clk, + .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_qup6_i2c_apps_clk_src = { + .cmd_rcgr = 0x08e0, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk, + .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_qup6_spi_apps_clk_src = { + .cmd_rcgr = 0x08cc, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_spi_apps_clk, + .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 const struct freq_tbl ftbl_gcc_blsp1_2_uart1_6_apps_clk[] = { + 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(63160000, P_GPLL0, 9.5, 0, 0), + { } +}; + +static struct clk_rcg2 blsp1_uart1_apps_clk_src = { + .cmd_rcgr = 0x068c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk, + .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_uart2_apps_clk_src = { + .cmd_rcgr = 0x070c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk, + .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_uart3_apps_clk_src = { + .cmd_rcgr = 0x078c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk, + .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_uart4_apps_clk_src = { + .cmd_rcgr = 0x080c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk, + .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_uart5_apps_clk_src = { + .cmd_rcgr = 0x088c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk, + .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_uart6_apps_clk_src = { + .cmd_rcgr = 0x090c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk, + .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_i2c_apps_clk_src = { + .cmd_rcgr = 0x09a0, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk, + .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_qup1_spi_apps_clk_src = { + .cmd_rcgr = 0x098c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_spi_apps_clk, + .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_qup2_i2c_apps_clk_src = { + .cmd_rcgr = 0x0a20, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk, + .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_qup2_spi_apps_clk_src = { + .cmd_rcgr = 0x0a0c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_spi_apps_clk, + .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_qup3_i2c_apps_clk_src = { + .cmd_rcgr = 0x0aa0, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk, + .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_qup3_spi_apps_clk_src = { + .cmd_rcgr = 0x0a8c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_spi_apps_clk, + .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_qup4_i2c_apps_clk_src = { + .cmd_rcgr = 0x0b20, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk, + .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_qup4_spi_apps_clk_src = { + .cmd_rcgr = 0x0b0c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_spi_apps_clk, + .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_qup5_i2c_apps_clk_src = { + .cmd_rcgr = 0x0ba0, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk, + .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_qup5_spi_apps_clk_src = { + .cmd_rcgr = 0x0b8c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_spi_apps_clk, + .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_qup6_i2c_apps_clk_src = { + .cmd_rcgr = 0x0c20, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk, + .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_qup6_spi_apps_clk_src = { + .cmd_rcgr = 0x0c0c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_spi_apps_clk, + .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_uart1_apps_clk_src = { + .cmd_rcgr = 0x09cc, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk, + .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_uart2_apps_clk_src = { + .cmd_rcgr = 0x0a4c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk, + .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_uart3_apps_clk_src = { + .cmd_rcgr = 0x0acc, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk, + .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_uart4_apps_clk_src = { + .cmd_rcgr = 0x0b4c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk, + .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_uart5_apps_clk_src = { + .cmd_rcgr = 0x0bcc, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk, + .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_uart6_apps_clk_src = { + .cmd_rcgr = 0x0c4c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk, + .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_gcc_ce1_clk[] = { + F(50000000, P_GPLL0, 12, 0, 0), + F(75000000, P_GPLL0, 8, 0, 0), + F(100000000, P_GPLL0, 6, 0, 0), + F(150000000, P_GPLL0, 4, 0, 0), + { } +}; + +static struct clk_rcg2 ce1_clk_src = { + .cmd_rcgr = 0x1050, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_ce1_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "ce1_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ce2_clk[] = { + F(50000000, P_GPLL0, 12, 0, 0), + F(75000000, P_GPLL0, 8, 0, 0), + F(100000000, P_GPLL0, 6, 0, 0), + F(150000000, P_GPLL0, 4, 0, 0), + { } +}; + +static struct clk_rcg2 ce2_clk_src = { + .cmd_rcgr = 0x1090, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_ce2_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "ce2_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_gp_clk[] = { + F(4800000, P_XO, 4, 0, 0), + F(6000000, P_GPLL0, 10, 1, 10), + F(6750000, P_GPLL0, 1, 1, 89), + F(8000000, P_GPLL0, 15, 1, 5), + F(9600000, P_XO, 2, 0, 0), + F(16000000, P_GPLL0, 1, 2, 75), + F(19200000, P_XO, 1, 0, 0), + F(24000000, P_GPLL0, 5, 1, 5), + { } +}; + + +static struct clk_rcg2 gp1_clk_src = { + .cmd_rcgr = 0x1904, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_gp_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp1_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gp2_clk_src = { + .cmd_rcgr = 0x1944, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_gp_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp2_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gp3_clk_src = { + .cmd_rcgr = 0x1984, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_gp_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp3_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pdm2_clk[] = { + F(60000000, P_GPLL0, 10, 0, 0), + { } +}; + +static struct clk_rcg2 pdm2_clk_src = { + .cmd_rcgr = 0x0cd0, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_pdm2_clk, + .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_gcc_sdcc1_4_apps_clk[] = { + 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 sdcc1_apps_clk_src = { + .cmd_rcgr = 0x04d0, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_sdcc1_4_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc1_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 sdcc2_apps_clk_src = { + .cmd_rcgr = 0x0510, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_sdcc1_4_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc2_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 sdcc3_apps_clk_src = { + .cmd_rcgr = 0x0550, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_sdcc1_4_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc3_apps_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 sdcc4_apps_clk_src = { + .cmd_rcgr = 0x0590, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_sdcc1_4_apps_clk, + .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_gcc_tsif_ref_clk[] = { + F(105000, P_XO, 2, 1, 91), + { } +}; + +static struct clk_rcg2 tsif_ref_clk_src = { + .cmd_rcgr = 0x0d90, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_tsif_ref_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "tsif_ref_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb30_mock_utmi_clk[] = { + F(60000000, P_GPLL0, 10, 0, 0), + { } +}; + +static struct clk_rcg2 usb30_mock_utmi_clk_src = { + .cmd_rcgr = 0x03e8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_usb30_mock_utmi_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb30_mock_utmi_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb_hs_system_clk[] = { + F(60000000, P_GPLL0, 10, 0, 0), + F(75000000, P_GPLL0, 8, 0, 0), + { } +}; + +static struct clk_rcg2 usb_hs_system_clk_src = { + .cmd_rcgr = 0x0490, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_usb_hs_system_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb_hs_system_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb_hsic_clk[] = { + F(480000000, P_GPLL1, 1, 0, 0), + { } +}; + +static u8 usb_hsic_clk_src_map[] = { + [P_XO] = 0, + [P_GPLL1] = 4, +}; + +static struct clk_rcg2 usb_hsic_clk_src = { + .cmd_rcgr = 0x0440, + .hid_width = 5, + .parent_map = usb_hsic_clk_src_map, + .freq_tbl = ftbl_gcc_usb_hsic_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb_hsic_clk_src", + .parent_names = (const char *[]){ + "xo", + "gpll1_vote", + }, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb_hsic_io_cal_clk[] = { + F(9600000, P_XO, 2, 0, 0), + { } +}; + +static struct clk_rcg2 usb_hsic_io_cal_clk_src = { + .cmd_rcgr = 0x0458, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_usb_hsic_io_cal_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb_hsic_io_cal_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 1, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb_hsic_system_clk[] = { + F(60000000, P_GPLL0, 10, 0, 0), + F(75000000, P_GPLL0, 8, 0, 0), + { } +}; + +static struct clk_rcg2 usb_hsic_system_clk_src = { + .cmd_rcgr = 0x041c, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_usb_hsic_system_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb_hsic_system_clk_src", + .parent_names = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_regmap gcc_mmss_gpll0_clk_src = { + .enable_reg = 0x1484, + .enable_mask = BIT(26), + .hw.init = &(struct clk_init_data){ + .name = "mmss_gpll0_vote", + .parent_names = (const char *[]){ + "gpll0_vote", + }, + .num_parents = 1, + .ops = &clk_branch_simple_ops, + }, +}; + +static struct clk_branch gcc_bam_dma_ahb_clk = { + .halt_reg = 0x0d44, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x1484, + .enable_mask = BIT(12), + .hw.init = &(struct clk_init_data){ + .name = "gcc_bam_dma_ahb_clk", + .parent_names = (const char *[]){ + "periph_noc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_ahb_clk = { + .halt_reg = 0x05c4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x1484, + .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, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = { + .halt_reg = 0x0648, + .clkr = { + .enable_reg = 0x0648, + .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_qup1_spi_apps_clk = { + .halt_reg = 0x0644, + .clkr = { + .enable_reg = 0x0644, + .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_qup2_i2c_apps_clk = { + .halt_reg = 0x06c8, + .clkr = { + .enable_reg = 0x06c8, + .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_qup2_spi_apps_clk = { + .halt_reg = 0x06c4, + .clkr = { + .enable_reg = 0x06c4, + .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_qup3_i2c_apps_clk = { + .halt_reg = 0x0748, + .clkr = { + .enable_reg = 0x0748, + .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_qup3_spi_apps_clk = { + .halt_reg = 0x0744, + .clkr = { + .enable_reg = 0x0744, + .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_qup4_i2c_apps_clk = { + .halt_reg = 0x07c8, + .clkr = { + .enable_reg = 0x07c8, + .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_qup4_spi_apps_clk = { + .halt_reg = 0x07c4, + .clkr = { + .enable_reg = 0x07c4, + .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_qup5_i2c_apps_clk = { + .halt_reg = 0x0848, + .clkr = { + .enable_reg = 0x0848, + .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_qup5_spi_apps_clk = { + .halt_reg = 0x0844, + .clkr = { + .enable_reg = 0x0844, + .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_qup6_i2c_apps_clk = { + .halt_reg = 0x08c8, + .clkr = { + .enable_reg = 0x08c8, + .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_qup6_spi_apps_clk = { + .halt_reg = 0x08c4, + .clkr = { + .enable_reg = 0x08c4, + .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_uart1_apps_clk = { + .halt_reg = 0x0684, + .clkr = { + .enable_reg = 0x0684, + .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_uart2_apps_clk = { + .halt_reg = 0x0704, + .clkr = { + .enable_reg = 0x0704, + .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_uart3_apps_clk = { + .halt_reg = 0x0784, + .clkr = { + .enable_reg = 0x0784, + .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_uart4_apps_clk = { + .halt_reg = 0x0804, + .clkr = { + .enable_reg = 0x0804, + .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_uart5_apps_clk = { + .halt_reg = 0x0884, + .clkr = { + .enable_reg = 0x0884, + .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_uart6_apps_clk = { + .halt_reg = 0x0904, + .clkr = { + .enable_reg = 0x0904, + .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 = 0x05c4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x1484, + .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, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup1_i2c_apps_clk = { + .halt_reg = 0x0988, + .clkr = { + .enable_reg = 0x0988, + .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_qup1_spi_apps_clk = { + .halt_reg = 0x0984, + .clkr = { + .enable_reg = 0x0984, + .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_qup2_i2c_apps_clk = { + .halt_reg = 0x0a08, + .clkr = { + .enable_reg = 0x0a08, + .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_qup2_spi_apps_clk = { + .halt_reg = 0x0a04, + .clkr = { + .enable_reg = 0x0a04, + .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_qup3_i2c_apps_clk = { + .halt_reg = 0x0a88, + .clkr = { + .enable_reg = 0x0a88, + .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_qup3_spi_apps_clk = { + .halt_reg = 0x0a84, + .clkr = { + .enable_reg = 0x0a84, + .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_qup4_i2c_apps_clk = { + .halt_reg = 0x0b08, + .clkr = { + .enable_reg = 0x0b08, + .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_qup4_spi_apps_clk = { + .halt_reg = 0x0b04, + .clkr = { + .enable_reg = 0x0b04, + .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_qup5_i2c_apps_clk = { + .halt_reg = 0x0b88, + .clkr = { + .enable_reg = 0x0b88, + .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_qup5_spi_apps_clk = { + .halt_reg = 0x0b84, + .clkr = { + .enable_reg = 0x0b84, + .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_qup6_i2c_apps_clk = { + .halt_reg = 0x0c08, + .clkr = { + .enable_reg = 0x0c08, + .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_qup6_spi_apps_clk = { + .halt_reg = 0x0c04, + .clkr = { + .enable_reg = 0x0c04, + .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_uart1_apps_clk = { + .halt_reg = 0x09c4, + .clkr = { + .enable_reg = 0x09c4, + .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_uart2_apps_clk = { + .halt_reg = 0x0a44, + .clkr = { + .enable_reg = 0x0a44, + .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_uart3_apps_clk = { + .halt_reg = 0x0ac4, + .clkr = { + .enable_reg = 0x0ac4, + .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_uart4_apps_clk = { + .halt_reg = 0x0b44, + .clkr = { + .enable_reg = 0x0b44, + .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_uart5_apps_clk = { + .halt_reg = 0x0bc4, + .clkr = { + .enable_reg = 0x0bc4, + .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_uart6_apps_clk = { + .halt_reg = 0x0c44, + .clkr = { + .enable_reg = 0x0c44, + .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_boot_rom_ahb_clk = { + .halt_reg = 0x0e04, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x1484, + .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, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ce1_ahb_clk = { + .halt_reg = 0x104c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x1484, + .enable_mask = BIT(3), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ce1_ahb_clk", + .parent_names = (const char *[]){ + "config_noc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ce1_axi_clk = { + .halt_reg = 0x1048, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x1484, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ce1_axi_clk", + .parent_names = (const char *[]){ + "system_noc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ce1_clk = { + .halt_reg = 0x1050, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x1484, + .enable_mask = BIT(5), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ce1_clk", + .parent_names = (const char *[]){ + "ce1_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ce2_ahb_clk = { + .halt_reg = 0x108c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x1484, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ce2_ahb_clk", + .parent_names = (const char *[]){ + "config_noc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ce2_axi_clk = { + .halt_reg = 0x1088, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x1484, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ce2_axi_clk", + .parent_names = (const char *[]){ + "system_noc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ce2_clk = { + .halt_reg = 0x1090, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x1484, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ce2_clk", + .parent_names = (const char *[]){ + "ce2_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp1_clk = { + .halt_reg = 0x1900, + .clkr = { + .enable_reg = 0x1900, + .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 = 0x1940, + .clkr = { + .enable_reg = 0x1940, + .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 = 0x1980, + .clkr = { + .enable_reg = 0x1980, + .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_lpass_q6_axi_clk = { + .halt_reg = 0x11c0, + .clkr = { + .enable_reg = 0x11c0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_lpass_q6_axi_clk", + .parent_names = (const char *[]){ + "system_noc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mmss_noc_cfg_ahb_clk = { + .halt_reg = 0x024c, + .clkr = { + .enable_reg = 0x024c, + .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, + .ops = &clk_branch2_ops, + .flags = CLK_IGNORE_UNUSED, + }, + }, +}; + +static struct clk_branch gcc_ocmem_noc_cfg_ahb_clk = { + .halt_reg = 0x0248, + .clkr = { + .enable_reg = 0x0248, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ocmem_noc_cfg_ahb_clk", + .parent_names = (const char *[]){ + "config_noc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_cfg_ahb_clk = { + .halt_reg = 0x0280, + .clkr = { + .enable_reg = 0x0280, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_cfg_ahb_clk", + .parent_names = (const char *[]){ + "config_noc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_q6_bimc_axi_clk = { + .halt_reg = 0x0284, + .clkr = { + .enable_reg = 0x0284, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_q6_bimc_axi_clk", + .flags = CLK_IS_ROOT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm2_clk = { + .halt_reg = 0x0ccc, + .clkr = { + .enable_reg = 0x0ccc, + .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_pdm_ahb_clk = { + .halt_reg = 0x0cc4, + .clkr = { + .enable_reg = 0x0cc4, + .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, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_prng_ahb_clk = { + .halt_reg = 0x0d04, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x1484, + .enable_mask = BIT(13), + .hw.init = &(struct clk_init_data){ + .name = "gcc_prng_ahb_clk", + .parent_names = (const char *[]){ + "periph_noc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ahb_clk = { + .halt_reg = 0x04c8, + .clkr = { + .enable_reg = 0x04c8, + .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, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_apps_clk = { + .halt_reg = 0x04c4, + .clkr = { + .enable_reg = 0x04c4, + .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_sdcc2_ahb_clk = { + .halt_reg = 0x0508, + .clkr = { + .enable_reg = 0x0508, + .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, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_apps_clk = { + .halt_reg = 0x0504, + .clkr = { + .enable_reg = 0x0504, + .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_sdcc3_ahb_clk = { + .halt_reg = 0x0548, + .clkr = { + .enable_reg = 0x0548, + .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, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc3_apps_clk = { + .halt_reg = 0x0544, + .clkr = { + .enable_reg = 0x0544, + .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_sdcc4_ahb_clk = { + .halt_reg = 0x0588, + .clkr = { + .enable_reg = 0x0588, + .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, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc4_apps_clk = { + .halt_reg = 0x0584, + .clkr = { + .enable_reg = 0x0584, + .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_sys_noc_usb3_axi_clk = { + .halt_reg = 0x0108, + .clkr = { + .enable_reg = 0x0108, + .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_tsif_ahb_clk = { + .halt_reg = 0x0d84, + .clkr = { + .enable_reg = 0x0d84, + .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, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_tsif_ref_clk = { + .halt_reg = 0x0d88, + .clkr = { + .enable_reg = 0x0d88, + .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_usb2a_phy_sleep_clk = { + .halt_reg = 0x04ac, + .clkr = { + .enable_reg = 0x04ac, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb2a_phy_sleep_clk", + .parent_names = (const char *[]){ + "sleep_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb2b_phy_sleep_clk = { + .halt_reg = 0x04b4, + .clkr = { + .enable_reg = 0x04b4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb2b_phy_sleep_clk", + .parent_names = (const char *[]){ + "sleep_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_master_clk = { + .halt_reg = 0x03c8, + .clkr = { + .enable_reg = 0x03c8, + .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_mock_utmi_clk = { + .halt_reg = 0x03d0, + .clkr = { + .enable_reg = 0x03d0, + .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_usb30_sleep_clk = { + .halt_reg = 0x03cc, + .clkr = { + .enable_reg = 0x03cc, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_sleep_clk", + .parent_names = (const char *[]){ + "sleep_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_hs_ahb_clk = { + .halt_reg = 0x0488, + .clkr = { + .enable_reg = 0x0488, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_hs_ahb_clk", + .parent_names = (const char *[]){ + "periph_noc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_hs_system_clk = { + .halt_reg = 0x0484, + .clkr = { + .enable_reg = 0x0484, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_hs_system_clk", + .parent_names = (const char *[]){ + "usb_hs_system_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_hsic_ahb_clk = { + .halt_reg = 0x0408, + .clkr = { + .enable_reg = 0x0408, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_hsic_ahb_clk", + .parent_names = (const char *[]){ + "periph_noc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_hsic_clk = { + .halt_reg = 0x0410, + .clkr = { + .enable_reg = 0x0410, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_hsic_clk", + .parent_names = (const char *[]){ + "usb_hsic_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_hsic_io_cal_clk = { + .halt_reg = 0x0414, + .clkr = { + .enable_reg = 0x0414, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_hsic_io_cal_clk", + .parent_names = (const char *[]){ + "usb_hsic_io_cal_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_hsic_io_cal_sleep_clk = { + .halt_reg = 0x0418, + .clkr = { + .enable_reg = 0x0418, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_hsic_io_cal_sleep_clk", + .parent_names = (const char *[]){ + "sleep_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_hsic_system_clk = { + .halt_reg = 0x040c, + .clkr = { + .enable_reg = 0x040c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_hsic_system_clk", + .parent_names = (const char *[]){ + "usb_hsic_system_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_regmap *gcc_msm8974_clocks[] = { + [GPLL0] = &gpll0.clkr, + [GPLL0_VOTE] = &gpll0_vote, + [CONFIG_NOC_CLK_SRC] = &config_noc_clk_src.clkr, + [PERIPH_NOC_CLK_SRC] = &periph_noc_clk_src.clkr, + [SYSTEM_NOC_CLK_SRC] = &system_noc_clk_src.clkr, + [GPLL1] = &gpll1.clkr, + [GPLL1_VOTE] = &gpll1_vote, + [USB30_MASTER_CLK_SRC] = &usb30_master_clk_src.clkr, + [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr, + [BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr, + [BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr, + [BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr, + [BLSP1_QUP3_I2C_APPS_CLK_SRC] = &blsp1_qup3_i2c_apps_clk_src.clkr, + [BLSP1_QUP3_SPI_APPS_CLK_SRC] = &blsp1_qup3_spi_apps_clk_src.clkr, + [BLSP1_QUP4_I2C_APPS_CLK_SRC] = &blsp1_qup4_i2c_apps_clk_src.clkr, + [BLSP1_QUP4_SPI_APPS_CLK_SRC] = &blsp1_qup4_spi_apps_clk_src.clkr, + [BLSP1_QUP5_I2C_APPS_CLK_SRC] = &blsp1_qup5_i2c_apps_clk_src.clkr, + [BLSP1_QUP5_SPI_APPS_CLK_SRC] = &blsp1_qup5_spi_apps_clk_src.clkr, + [BLSP1_QUP6_I2C_APPS_CLK_SRC] = &blsp1_qup6_i2c_apps_clk_src.clkr, + [BLSP1_QUP6_SPI_APPS_CLK_SRC] = &blsp1_qup6_spi_apps_clk_src.clkr, + [BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr, + [BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr, + [BLSP1_UART3_APPS_CLK_SRC] = &blsp1_uart3_apps_clk_src.clkr, + [BLSP1_UART4_APPS_CLK_SRC] = &blsp1_uart4_apps_clk_src.clkr, + [BLSP1_UART5_APPS_CLK_SRC] = &blsp1_uart5_apps_clk_src.clkr, + [BLSP1_UART6_APPS_CLK_SRC] = &blsp1_uart6_apps_clk_src.clkr, + [BLSP2_QUP1_I2C_APPS_CLK_SRC] = &blsp2_qup1_i2c_apps_clk_src.clkr, + [BLSP2_QUP1_SPI_APPS_CLK_SRC] = &blsp2_qup1_spi_apps_clk_src.clkr, + [BLSP2_QUP2_I2C_APPS_CLK_SRC] = &blsp2_qup2_i2c_apps_clk_src.clkr, + [BLSP2_QUP2_SPI_APPS_CLK_SRC] = &blsp2_qup2_spi_apps_clk_src.clkr, + [BLSP2_QUP3_I2C_APPS_CLK_SRC] = &blsp2_qup3_i2c_apps_clk_src.clkr, + [BLSP2_QUP3_SPI_APPS_CLK_SRC] = &blsp2_qup3_spi_apps_clk_src.clkr, + [BLSP2_QUP4_I2C_APPS_CLK_SRC] = &blsp2_qup4_i2c_apps_clk_src.clkr, + [BLSP2_QUP4_SPI_APPS_CLK_SRC] = &blsp2_qup4_spi_apps_clk_src.clkr, + [BLSP2_QUP5_I2C_APPS_CLK_SRC] = &blsp2_qup5_i2c_apps_clk_src.clkr, + [BLSP2_QUP5_SPI_APPS_CLK_SRC] = &blsp2_qup5_spi_apps_clk_src.clkr, + [BLSP2_QUP6_I2C_APPS_CLK_SRC] = &blsp2_qup6_i2c_apps_clk_src.clkr, + [BLSP2_QUP6_SPI_APPS_CLK_SRC] = &blsp2_qup6_spi_apps_clk_src.clkr, + [BLSP2_UART1_APPS_CLK_SRC] = &blsp2_uart1_apps_clk_src.clkr, + [BLSP2_UART2_APPS_CLK_SRC] = &blsp2_uart2_apps_clk_src.clkr, + [BLSP2_UART3_APPS_CLK_SRC] = &blsp2_uart3_apps_clk_src.clkr, + [BLSP2_UART4_APPS_CLK_SRC] = &blsp2_uart4_apps_clk_src.clkr, + [BLSP2_UART5_APPS_CLK_SRC] = &blsp2_uart5_apps_clk_src.clkr, + [BLSP2_UART6_APPS_CLK_SRC] = &blsp2_uart6_apps_clk_src.clkr, + [CE1_CLK_SRC] = &ce1_clk_src.clkr, + [CE2_CLK_SRC] = &ce2_clk_src.clkr, + [GP1_CLK_SRC] = &gp1_clk_src.clkr, + [GP2_CLK_SRC] = &gp2_clk_src.clkr, + [GP3_CLK_SRC] = &gp3_clk_src.clkr, + [PDM2_CLK_SRC] = &pdm2_clk_src.clkr, + [SDCC1_APPS_CLK_SRC] = &sdcc1_apps_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, + [TSIF_REF_CLK_SRC] = &tsif_ref_clk_src.clkr, + [USB30_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr, + [USB_HS_SYSTEM_CLK_SRC] = &usb_hs_system_clk_src.clkr, + [USB_HSIC_CLK_SRC] = &usb_hsic_clk_src.clkr, + [USB_HSIC_IO_CAL_CLK_SRC] = &usb_hsic_io_cal_clk_src.clkr, + [USB_HSIC_SYSTEM_CLK_SRC] = &usb_hsic_system_clk_src.clkr, + [GCC_BAM_DMA_AHB_CLK] = &gcc_bam_dma_ahb_clk.clkr, + [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr, + [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr, + [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr, + [GCC_BLSP1_QUP3_I2C_APPS_CLK] = &gcc_blsp1_qup3_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP3_SPI_APPS_CLK] = &gcc_blsp1_qup3_spi_apps_clk.clkr, + [GCC_BLSP1_QUP4_I2C_APPS_CLK] = &gcc_blsp1_qup4_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr, + [GCC_BLSP1_QUP5_I2C_APPS_CLK] = &gcc_blsp1_qup5_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP5_SPI_APPS_CLK] = &gcc_blsp1_qup5_spi_apps_clk.clkr, + [GCC_BLSP1_QUP6_I2C_APPS_CLK] = &gcc_blsp1_qup6_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP6_SPI_APPS_CLK] = &gcc_blsp1_qup6_spi_apps_clk.clkr, + [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr, + [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr, + [GCC_BLSP1_UART3_APPS_CLK] = &gcc_blsp1_uart3_apps_clk.clkr, + [GCC_BLSP1_UART4_APPS_CLK] = &gcc_blsp1_uart4_apps_clk.clkr, + [GCC_BLSP1_UART5_APPS_CLK] = &gcc_blsp1_uart5_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_QUP1_I2C_APPS_CLK] = &gcc_blsp2_qup1_i2c_apps_clk.clkr, + [GCC_BLSP2_QUP1_SPI_APPS_CLK] = &gcc_blsp2_qup1_spi_apps_clk.clkr, + [GCC_BLSP2_QUP2_I2C_APPS_CLK] = &gcc_blsp2_qup2_i2c_apps_clk.clkr, + [GCC_BLSP2_QUP2_SPI_APPS_CLK] = &gcc_blsp2_qup2_spi_apps_clk.clkr, + [GCC_BLSP2_QUP3_I2C_APPS_CLK] = &gcc_blsp2_qup3_i2c_apps_clk.clkr, + [GCC_BLSP2_QUP3_SPI_APPS_CLK] = &gcc_blsp2_qup3_spi_apps_clk.clkr, + [GCC_BLSP2_QUP4_I2C_APPS_CLK] = &gcc_blsp2_qup4_i2c_apps_clk.clkr, + [GCC_BLSP2_QUP4_SPI_APPS_CLK] = &gcc_blsp2_qup4_spi_apps_clk.clkr, + [GCC_BLSP2_QUP5_I2C_APPS_CLK] = &gcc_blsp2_qup5_i2c_apps_clk.clkr, + [GCC_BLSP2_QUP5_SPI_APPS_CLK] = &gcc_blsp2_qup5_spi_apps_clk.clkr, + [GCC_BLSP2_QUP6_I2C_APPS_CLK] = &gcc_blsp2_qup6_i2c_apps_clk.clkr, + [GCC_BLSP2_QUP6_SPI_APPS_CLK] = &gcc_blsp2_qup6_spi_apps_clk.clkr, + [GCC_BLSP2_UART1_APPS_CLK] = &gcc_blsp2_uart1_apps_clk.clkr, + [GCC_BLSP2_UART2_APPS_CLK] = &gcc_blsp2_uart2_apps_clk.clkr, + [GCC_BLSP2_UART3_APPS_CLK] = &gcc_blsp2_uart3_apps_clk.clkr, + [GCC_BLSP2_UART4_APPS_CLK] = &gcc_blsp2_uart4_apps_clk.clkr, + [GCC_BLSP2_UART5_APPS_CLK] = &gcc_blsp2_uart5_apps_clk.clkr, + [GCC_BLSP2_UART6_APPS_CLK] = &gcc_blsp2_uart6_apps_clk.clkr, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_CE1_AHB_CLK] = &gcc_ce1_ahb_clk.clkr, + [GCC_CE1_AXI_CLK] = &gcc_ce1_axi_clk.clkr, + [GCC_CE1_CLK] = &gcc_ce1_clk.clkr, + [GCC_CE2_AHB_CLK] = &gcc_ce2_ahb_clk.clkr, + [GCC_CE2_AXI_CLK] = &gcc_ce2_axi_clk.clkr, + [GCC_CE2_CLK] = &gcc_ce2_clk.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_LPASS_Q6_AXI_CLK] = &gcc_lpass_q6_axi_clk.clkr, + [GCC_MMSS_NOC_CFG_AHB_CLK] = &gcc_mmss_noc_cfg_ahb_clk.clkr, + [GCC_OCMEM_NOC_CFG_AHB_CLK] = &gcc_ocmem_noc_cfg_ahb_clk.clkr, + [GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr, + [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr, + [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr, + [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr, + [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr, + [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr, + [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr, + [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr, + [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr, + [GCC_SDCC3_AHB_CLK] = &gcc_sdcc3_ahb_clk.clkr, + [GCC_SDCC3_APPS_CLK] = &gcc_sdcc3_apps_clk.clkr, + [GCC_SDCC4_AHB_CLK] = &gcc_sdcc4_ahb_clk.clkr, + [GCC_SDCC4_APPS_CLK] = &gcc_sdcc4_apps_clk.clkr, + [GCC_SYS_NOC_USB3_AXI_CLK] = &gcc_sys_noc_usb3_axi_clk.clkr, + [GCC_TSIF_AHB_CLK] = &gcc_tsif_ahb_clk.clkr, + [GCC_TSIF_REF_CLK] = &gcc_tsif_ref_clk.clkr, + [GCC_USB2A_PHY_SLEEP_CLK] = &gcc_usb2a_phy_sleep_clk.clkr, + [GCC_USB2B_PHY_SLEEP_CLK] = &gcc_usb2b_phy_sleep_clk.clkr, + [GCC_USB30_MASTER_CLK] = &gcc_usb30_master_clk.clkr, + [GCC_USB30_MOCK_UTMI_CLK] = &gcc_usb30_mock_utmi_clk.clkr, + [GCC_USB30_SLEEP_CLK] = &gcc_usb30_sleep_clk.clkr, + [GCC_USB_HS_AHB_CLK] = &gcc_usb_hs_ahb_clk.clkr, + [GCC_USB_HS_SYSTEM_CLK] = &gcc_usb_hs_system_clk.clkr, + [GCC_USB_HSIC_AHB_CLK] = &gcc_usb_hsic_ahb_clk.clkr, + [GCC_USB_HSIC_CLK] = &gcc_usb_hsic_clk.clkr, + [GCC_USB_HSIC_IO_CAL_CLK] = &gcc_usb_hsic_io_cal_clk.clkr, + [GCC_USB_HSIC_IO_CAL_SLEEP_CLK] = &gcc_usb_hsic_io_cal_sleep_clk.clkr, + [GCC_USB_HSIC_SYSTEM_CLK] = &gcc_usb_hsic_system_clk.clkr, + [GCC_MMSS_GPLL0_CLK_SRC] = &gcc_mmss_gpll0_clk_src, +}; + +static const struct qcom_reset_map gcc_msm8974_resets[] = { + [GCC_SYSTEM_NOC_BCR] = { 0x0100 }, + [GCC_CONFIG_NOC_BCR] = { 0x0140 }, + [GCC_PERIPH_NOC_BCR] = { 0x0180 }, + [GCC_IMEM_BCR] = { 0x0200 }, + [GCC_MMSS_BCR] = { 0x0240 }, + [GCC_QDSS_BCR] = { 0x0300 }, + [GCC_USB_30_BCR] = { 0x03c0 }, + [GCC_USB3_PHY_BCR] = { 0x03fc }, + [GCC_USB_HS_HSIC_BCR] = { 0x0400 }, + [GCC_USB_HS_BCR] = { 0x0480 }, + [GCC_USB2A_PHY_BCR] = { 0x04a8 }, + [GCC_USB2B_PHY_BCR] = { 0x04b0 }, + [GCC_SDCC1_BCR] = { 0x04c0 }, + [GCC_SDCC2_BCR] = { 0x0500 }, + [GCC_SDCC3_BCR] = { 0x0540 }, + [GCC_SDCC4_BCR] = { 0x0580 }, + [GCC_BLSP1_BCR] = { 0x05c0 }, + [GCC_BLSP1_QUP1_BCR] = { 0x0640 }, + [GCC_BLSP1_UART1_BCR] = { 0x0680 }, + [GCC_BLSP1_QUP2_BCR] = { 0x06c0 }, + [GCC_BLSP1_UART2_BCR] = { 0x0700 }, + [GCC_BLSP1_QUP3_BCR] = { 0x0740 }, + [GCC_BLSP1_UART3_BCR] = { 0x0780 }, + [GCC_BLSP1_QUP4_BCR] = { 0x07c0 }, + [GCC_BLSP1_UART4_BCR] = { 0x0800 }, + [GCC_BLSP1_QUP5_BCR] = { 0x0840 }, + [GCC_BLSP1_UART5_BCR] = { 0x0880 }, + [GCC_BLSP1_QUP6_BCR] = { 0x08c0 }, + [GCC_BLSP1_UART6_BCR] = { 0x0900 }, + [GCC_BLSP2_BCR] = { 0x0940 }, + [GCC_BLSP2_QUP1_BCR] = { 0x0980 }, + [GCC_BLSP2_UART1_BCR] = { 0x09c0 }, + [GCC_BLSP2_QUP2_BCR] = { 0x0a00 }, + [GCC_BLSP2_UART2_BCR] = { 0x0a40 }, + [GCC_BLSP2_QUP3_BCR] = { 0x0a80 }, + [GCC_BLSP2_UART3_BCR] = { 0x0ac0 }, + [GCC_BLSP2_QUP4_BCR] = { 0x0b00 }, + [GCC_BLSP2_UART4_BCR] = { 0x0b40 }, + [GCC_BLSP2_QUP5_BCR] = { 0x0b80 }, + [GCC_BLSP2_UART5_BCR] = { 0x0bc0 }, + [GCC_BLSP2_QUP6_BCR] = { 0x0c00 }, + [GCC_BLSP2_UART6_BCR] = { 0x0c40 }, + [GCC_PDM_BCR] = { 0x0cc0 }, + [GCC_BAM_DMA_BCR] = { 0x0d40 }, + [GCC_TSIF_BCR] = { 0x0d80 }, + [GCC_TCSR_BCR] = { 0x0dc0 }, + [GCC_BOOT_ROM_BCR] = { 0x0e00 }, + [GCC_MSG_RAM_BCR] = { 0x0e40 }, + [GCC_TLMM_BCR] = { 0x0e80 }, + [GCC_MPM_BCR] = { 0x0ec0 }, + [GCC_SEC_CTRL_BCR] = { 0x0f40 }, + [GCC_SPMI_BCR] = { 0x0fc0 }, + [GCC_SPDM_BCR] = { 0x1000 }, + [GCC_CE1_BCR] = { 0x1040 }, + [GCC_CE2_BCR] = { 0x1080 }, + [GCC_BIMC_BCR] = { 0x1100 }, + [GCC_MPM_NON_AHB_RESET] = { 0x0ec4, 2 }, + [GCC_MPM_AHB_RESET] = { 0x0ec4, 1 }, + [GCC_SNOC_BUS_TIMEOUT0_BCR] = { 0x1240 }, + [GCC_SNOC_BUS_TIMEOUT2_BCR] = { 0x1248 }, + [GCC_PNOC_BUS_TIMEOUT0_BCR] = { 0x1280 }, + [GCC_PNOC_BUS_TIMEOUT1_BCR] = { 0x1288 }, + [GCC_PNOC_BUS_TIMEOUT2_BCR] = { 0x1290 }, + [GCC_PNOC_BUS_TIMEOUT3_BCR] = { 0x1298 }, + [GCC_PNOC_BUS_TIMEOUT4_BCR] = { 0x12a0 }, + [GCC_CNOC_BUS_TIMEOUT0_BCR] = { 0x12c0 }, + [GCC_CNOC_BUS_TIMEOUT1_BCR] = { 0x12c8 }, + [GCC_CNOC_BUS_TIMEOUT2_BCR] = { 0x12d0 }, + [GCC_CNOC_BUS_TIMEOUT3_BCR] = { 0x12d8 }, + [GCC_CNOC_BUS_TIMEOUT4_BCR] = { 0x12e0 }, + [GCC_CNOC_BUS_TIMEOUT5_BCR] = { 0x12e8 }, + [GCC_CNOC_BUS_TIMEOUT6_BCR] = { 0x12f0 }, + [GCC_DEHR_BCR] = { 0x1300 }, + [GCC_RBCPR_BCR] = { 0x1380 }, + [GCC_MSS_RESTART] = { 0x1680 }, + [GCC_LPASS_RESTART] = { 0x16c0 }, + [GCC_WCSS_RESTART] = { 0x1700 }, + [GCC_VENUS_RESTART] = { 0x1740 }, +}; + +static const struct regmap_config gcc_msm8974_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x1fc0, + .fast_io = true, +}; + +static const struct of_device_id gcc_msm8974_match_table[] = { + { .compatible = "qcom,gcc-msm8974" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_msm8974_match_table); + +struct qcom_cc { + struct qcom_reset_controller reset; + struct clk_onecell_data data; + struct clk *clks[]; +}; + +static int gcc_msm8974_probe(struct platform_device *pdev) +{ + void __iomem *base; + struct resource *res; + int i, ret; + struct device *dev = &pdev->dev; + struct clk *clk; + struct clk_onecell_data *data; + struct clk **clks; + struct regmap *regmap; + size_t num_clks; + struct qcom_reset_controller *reset; + struct qcom_cc *cc; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + regmap = devm_regmap_init_mmio(dev, base, &gcc_msm8974_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + num_clks = ARRAY_SIZE(gcc_msm8974_clocks); + cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks, + GFP_KERNEL); + if (!cc) + return -ENOMEM; + + clks = cc->clks; + data = &cc->data; + data->clks = clks; + data->clk_num = num_clks; + + /* 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); + + /* 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); + + for (i = 0; i < num_clks; i++) { + if (!gcc_msm8974_clocks[i]) + continue; + clk = devm_clk_register_regmap(dev, gcc_msm8974_clocks[i]); + if (IS_ERR(clk)) + return PTR_ERR(clk); + clks[i] = clk; + } + + ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data); + if (ret) + return ret; + + reset = &cc->reset; + reset->rcdev.of_node = dev->of_node; + reset->rcdev.ops = &qcom_reset_ops, + reset->rcdev.owner = THIS_MODULE, + reset->rcdev.nr_resets = ARRAY_SIZE(gcc_msm8974_resets), + reset->regmap = regmap; + reset->reset_map = gcc_msm8974_resets, + platform_set_drvdata(pdev, &reset->rcdev); + + ret = reset_controller_register(&reset->rcdev); + if (ret) + of_clk_del_provider(dev->of_node); + + return ret; +} + +static int gcc_msm8974_remove(struct platform_device *pdev) +{ + of_clk_del_provider(pdev->dev.of_node); + reset_controller_unregister(platform_get_drvdata(pdev)); + return 0; +} + +static struct platform_driver gcc_msm8974_driver = { + .probe = gcc_msm8974_probe, + .remove = gcc_msm8974_remove, + .driver = { + .name = "gcc-msm8974", + .owner = THIS_MODULE, + .of_match_table = gcc_msm8974_match_table, + }, +}; + +static int __init gcc_msm8974_init(void) +{ + return platform_driver_register(&gcc_msm8974_driver); +} +core_initcall(gcc_msm8974_init); + +static void __exit gcc_msm8974_exit(void) +{ + platform_driver_unregister(&gcc_msm8974_driver); +} +module_exit(gcc_msm8974_exit); + +MODULE_DESCRIPTION("QCOM GCC MSM8974 Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:gcc-msm8974"); diff --git a/drivers/clk/qcom/mmcc-msm8960.c b/drivers/clk/qcom/mmcc-msm8960.c new file mode 100644 index 000000000000..f9b59c7e48e9 --- /dev/null +++ b/drivers/clk/qcom/mmcc-msm8960.c @@ -0,0 +1,2321 @@ +/* + * Copyright (c) 2013, 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/delay.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,mmcc-msm8960.h> +#include <dt-bindings/reset/qcom,mmcc-msm8960.h> + +#include "clk-regmap.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-branch.h" +#include "reset.h" + +#define P_PXO 0 +#define P_PLL8 1 +#define P_PLL2 2 +#define P_PLL3 3 + +static u8 mmcc_pxo_pll8_pll2_map[] = { + [P_PXO] = 0, + [P_PLL8] = 2, + [P_PLL2] = 1, +}; + +static const char *mmcc_pxo_pll8_pll2[] = { + "pxo", + "pll8_vote", + "pll2", +}; + +static u8 mmcc_pxo_pll8_pll2_pll3_map[] = { + [P_PXO] = 0, + [P_PLL8] = 2, + [P_PLL2] = 1, + [P_PLL3] = 3, +}; + +static const char *mmcc_pxo_pll8_pll2_pll3[] = { + "pxo", + "pll2", + "pll8_vote", + "pll3", +}; + +static struct clk_pll pll2 = { + .l_reg = 0x320, + .m_reg = 0x324, + .n_reg = 0x328, + .config_reg = 0x32c, + .mode_reg = 0x31c, + .status_reg = 0x334, + .status_bit = 16, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pll2", + .parent_names = (const char *[]){ "pxo" }, + .num_parents = 1, + .ops = &clk_pll_ops, + }, +}; + +static struct freq_tbl clk_tbl_cam[] = { + { 6000000, P_PLL8, 4, 1, 16 }, + { 8000000, P_PLL8, 4, 1, 12 }, + { 12000000, P_PLL8, 4, 1, 8 }, + { 16000000, P_PLL8, 4, 1, 6 }, + { 19200000, P_PLL8, 4, 1, 5 }, + { 24000000, P_PLL8, 4, 1, 4 }, + { 32000000, P_PLL8, 4, 1, 3 }, + { 48000000, P_PLL8, 4, 1, 2 }, + { 64000000, P_PLL8, 3, 1, 2 }, + { 96000000, P_PLL8, 4, 0, 0 }, + { 128000000, P_PLL8, 3, 0, 0 }, + { } +}; + +static struct clk_rcg camclk0_src = { + .ns_reg = 0x0148, + .md_reg = 0x0144, + .mn = { + .mnctr_en_bit = 5, + .mnctr_reset_bit = 8, + .reset_in_cc = true, + .mnctr_mode_shift = 6, + .n_val_shift = 24, + .m_val_shift = 8, + .width = 8, + }, + .p = { + .pre_div_shift = 14, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = mmcc_pxo_pll8_pll2_map, + }, + .freq_tbl = clk_tbl_cam, + .clkr = { + .enable_reg = 0x0140, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "camclk0_src", + .parent_names = mmcc_pxo_pll8_pll2, + .num_parents = 3, + .ops = &clk_rcg_ops, + }, + }, +}; + +static struct clk_branch camclk0_clk = { + .halt_reg = 0x01e8, + .halt_bit = 15, + .clkr = { + .enable_reg = 0x0140, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camclk0_clk", + .parent_names = (const char *[]){ "camclk0_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + }, + }, + +}; + +static struct clk_rcg camclk1_src = { + .ns_reg = 0x015c, + .md_reg = 0x0158, + .mn = { + .mnctr_en_bit = 5, + .mnctr_reset_bit = 8, + .reset_in_cc = true, + .mnctr_mode_shift = 6, + .n_val_shift = 24, + .m_val_shift = 8, + .width = 8, + }, + .p = { + .pre_div_shift = 14, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = mmcc_pxo_pll8_pll2_map, + }, + .freq_tbl = clk_tbl_cam, + .clkr = { + .enable_reg = 0x0154, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "camclk1_src", + .parent_names = mmcc_pxo_pll8_pll2, + .num_parents = 3, + .ops = &clk_rcg_ops, + }, + }, +}; + +static struct clk_branch camclk1_clk = { + .halt_reg = 0x01e8, + .halt_bit = 16, + .clkr = { + .enable_reg = 0x0154, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camclk1_clk", + .parent_names = (const char *[]){ "camclk1_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + }, + }, + +}; + +static struct clk_rcg camclk2_src = { + .ns_reg = 0x0228, + .md_reg = 0x0224, + .mn = { + .mnctr_en_bit = 5, + .mnctr_reset_bit = 8, + .reset_in_cc = true, + .mnctr_mode_shift = 6, + .n_val_shift = 24, + .m_val_shift = 8, + .width = 8, + }, + .p = { + .pre_div_shift = 14, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = mmcc_pxo_pll8_pll2_map, + }, + .freq_tbl = clk_tbl_cam, + .clkr = { + .enable_reg = 0x0220, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "camclk2_src", + .parent_names = mmcc_pxo_pll8_pll2, + .num_parents = 3, + .ops = &clk_rcg_ops, + }, + }, +}; + +static struct clk_branch camclk2_clk = { + .halt_reg = 0x01e8, + .halt_bit = 16, + .clkr = { + .enable_reg = 0x0220, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camclk2_clk", + .parent_names = (const char *[]){ "camclk2_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + }, + }, + +}; + +static struct freq_tbl clk_tbl_csi[] = { + { 27000000, P_PXO, 1, 0, 0 }, + { 85330000, P_PLL8, 1, 2, 9 }, + { 177780000, P_PLL2, 1, 2, 9 }, + { } +}; + +static struct clk_rcg csi0_src = { + .ns_reg = 0x0048, + .md_reg = 0x0044, + .mn = { + .mnctr_en_bit = 5, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 6, + .n_val_shift = 24, + .m_val_shift = 8, + .width = 8, + }, + .p = { + .pre_div_shift = 14, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = mmcc_pxo_pll8_pll2_map, + }, + .freq_tbl = clk_tbl_csi, + .clkr = { + .enable_reg = 0x0040, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "csi0_src", + .parent_names = mmcc_pxo_pll8_pll2, + .num_parents = 3, + .ops = &clk_rcg_ops, + }, + }, +}; + +static struct clk_branch csi0_clk = { + .halt_reg = 0x01cc, + .halt_bit = 13, + .clkr = { + .enable_reg = 0x0040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .parent_names = (const char *[]){ "csi0_src" }, + .num_parents = 1, + .name = "csi0_clk", + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch csi0_phy_clk = { + .halt_reg = 0x01e8, + .halt_bit = 9, + .clkr = { + .enable_reg = 0x0040, + .enable_mask = BIT(8), + .hw.init = &(struct clk_init_data){ + .parent_names = (const char *[]){ "csi0_src" }, + .num_parents = 1, + .name = "csi0_phy_clk", + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg csi1_src = { + .ns_reg = 0x0010, + .md_reg = 0x0028, + .mn = { + .mnctr_en_bit = 5, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 6, + .n_val_shift = 24, + .m_val_shift = 8, + .width = 8, + }, + .p = { + .pre_div_shift = 14, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = mmcc_pxo_pll8_pll2_map, + }, + .freq_tbl = clk_tbl_csi, + .clkr = { + .enable_reg = 0x0024, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "csi1_src", + .parent_names = mmcc_pxo_pll8_pll2, + .num_parents = 3, + .ops = &clk_rcg_ops, + }, + }, +}; + +static struct clk_branch csi1_clk = { + .halt_reg = 0x01cc, + .halt_bit = 14, + .clkr = { + .enable_reg = 0x0024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .parent_names = (const char *[]){ "csi1_src" }, + .num_parents = 1, + .name = "csi1_clk", + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch csi1_phy_clk = { + .halt_reg = 0x01e8, + .halt_bit = 10, + .clkr = { + .enable_reg = 0x0024, + .enable_mask = BIT(8), + .hw.init = &(struct clk_init_data){ + .parent_names = (const char *[]){ "csi1_src" }, + .num_parents = 1, + .name = "csi1_phy_clk", + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg csi2_src = { + .ns_reg = 0x0234, + .md_reg = 0x022c, + .mn = { + .mnctr_en_bit = 5, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 6, + .n_val_shift = 24, + .m_val_shift = 8, + .width = 8, + }, + .p = { + .pre_div_shift = 14, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = mmcc_pxo_pll8_pll2_map, + }, + .freq_tbl = clk_tbl_csi, + .clkr = { + .enable_reg = 0x022c, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "csi2_src", + .parent_names = mmcc_pxo_pll8_pll2, + .num_parents = 3, + .ops = &clk_rcg_ops, + }, + }, +}; + +static struct clk_branch csi2_clk = { + .halt_reg = 0x01cc, + .halt_bit = 29, + .clkr = { + .enable_reg = 0x022c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .parent_names = (const char *[]){ "csi2_src" }, + .num_parents = 1, + .name = "csi2_clk", + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch csi2_phy_clk = { + .halt_reg = 0x01e8, + .halt_bit = 29, + .clkr = { + .enable_reg = 0x022c, + .enable_mask = BIT(8), + .hw.init = &(struct clk_init_data){ + .parent_names = (const char *[]){ "csi2_src" }, + .num_parents = 1, + .name = "csi2_phy_clk", + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +struct clk_pix_rdi { + u32 s_reg; + u32 s_mask; + u32 s2_reg; + u32 s2_mask; + struct clk_regmap clkr; +}; + +#define to_clk_pix_rdi(_hw) \ + container_of(to_clk_regmap(_hw), struct clk_pix_rdi, clkr) + +static int pix_rdi_set_parent(struct clk_hw *hw, u8 index) +{ + int i; + int ret = 0; + u32 val; + struct clk_pix_rdi *rdi = to_clk_pix_rdi(hw); + struct clk *clk = hw->clk; + int num_parents = __clk_get_num_parents(hw->clk); + + /* + * These clocks select three inputs via two muxes. One mux selects + * between csi0 and csi1 and the second mux selects between that mux's + * output and csi2. The source and destination selections for each + * mux must be clocking for the switch to succeed so just turn on + * all three sources because it's easier than figuring out what source + * needs to be on at what time. + */ + for (i = 0; i < num_parents; i++) { + ret = clk_prepare_enable(clk_get_parent_by_index(clk, i)); + if (ret) + goto err; + } + + if (index == 2) + val = rdi->s2_mask; + else + val = 0; + regmap_update_bits(rdi->clkr.regmap, rdi->s2_reg, rdi->s2_mask, val); + /* + * Wait at least 6 cycles of slowest clock + * for the glitch-free MUX to fully switch sources. + */ + udelay(1); + + if (index == 1) + val = rdi->s_mask; + else + val = 0; + regmap_update_bits(rdi->clkr.regmap, rdi->s_reg, rdi->s_mask, val); + /* + * Wait at least 6 cycles of slowest clock + * for the glitch-free MUX to fully switch sources. + */ + udelay(1); + +err: + for (i--; i >= 0; i--) + clk_disable_unprepare(clk_get_parent_by_index(clk, i)); + + return ret; +} + +static u8 pix_rdi_get_parent(struct clk_hw *hw) +{ + u32 val; + struct clk_pix_rdi *rdi = to_clk_pix_rdi(hw); + + + regmap_read(rdi->clkr.regmap, rdi->s2_reg, &val); + if (val & rdi->s2_mask) + return 2; + + regmap_read(rdi->clkr.regmap, rdi->s_reg, &val); + if (val & rdi->s_mask) + return 1; + + return 0; +} + +static const struct clk_ops clk_ops_pix_rdi = { + .enable = clk_enable_regmap, + .disable = clk_disable_regmap, + .set_parent = pix_rdi_set_parent, + .get_parent = pix_rdi_get_parent, + .determine_rate = __clk_mux_determine_rate, +}; + +static const char *pix_rdi_parents[] = { + "csi0_clk", + "csi1_clk", + "csi2_clk", +}; + +static struct clk_pix_rdi csi_pix_clk = { + .s_reg = 0x0058, + .s_mask = BIT(25), + .s2_reg = 0x0238, + .s2_mask = BIT(13), + .clkr = { + .enable_reg = 0x0058, + .enable_mask = BIT(26), + .hw.init = &(struct clk_init_data){ + .name = "csi_pix_clk", + .parent_names = pix_rdi_parents, + .num_parents = 3, + .ops = &clk_ops_pix_rdi, + }, + }, +}; + +static struct clk_pix_rdi csi_pix1_clk = { + .s_reg = 0x0238, + .s_mask = BIT(8), + .s2_reg = 0x0238, + .s2_mask = BIT(9), + .clkr = { + .enable_reg = 0x0238, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "csi_pix1_clk", + .parent_names = pix_rdi_parents, + .num_parents = 3, + .ops = &clk_ops_pix_rdi, + }, + }, +}; + +static struct clk_pix_rdi csi_rdi_clk = { + .s_reg = 0x0058, + .s_mask = BIT(12), + .s2_reg = 0x0238, + .s2_mask = BIT(12), + .clkr = { + .enable_reg = 0x0058, + .enable_mask = BIT(13), + .hw.init = &(struct clk_init_data){ + .name = "csi_rdi_clk", + .parent_names = pix_rdi_parents, + .num_parents = 3, + .ops = &clk_ops_pix_rdi, + }, + }, +}; + +static struct clk_pix_rdi csi_rdi1_clk = { + .s_reg = 0x0238, + .s_mask = BIT(0), + .s2_reg = 0x0238, + .s2_mask = BIT(1), + .clkr = { + .enable_reg = 0x0238, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "csi_rdi1_clk", + .parent_names = pix_rdi_parents, + .num_parents = 3, + .ops = &clk_ops_pix_rdi, + }, + }, +}; + +static struct clk_pix_rdi csi_rdi2_clk = { + .s_reg = 0x0238, + .s_mask = BIT(4), + .s2_reg = 0x0238, + .s2_mask = BIT(5), + .clkr = { + .enable_reg = 0x0238, + .enable_mask = BIT(6), + .hw.init = &(struct clk_init_data){ + .name = "csi_rdi2_clk", + .parent_names = pix_rdi_parents, + .num_parents = 3, + .ops = &clk_ops_pix_rdi, + }, + }, +}; + +static struct freq_tbl clk_tbl_csiphytimer[] = { + { 85330000, P_PLL8, 1, 2, 9 }, + { 177780000, P_PLL2, 1, 2, 9 }, + { } +}; + +static struct clk_rcg csiphytimer_src = { + .ns_reg = 0x0168, + .md_reg = 0x0164, + .mn = { + .mnctr_en_bit = 5, + .mnctr_reset_bit = 8, + .reset_in_cc = true, + .mnctr_mode_shift = 6, + .n_val_shift = 24, + .m_val_shift = 8, + .width = 8, + }, + .p = { + .pre_div_shift = 14, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = mmcc_pxo_pll8_pll2_map, + }, + .freq_tbl = clk_tbl_csiphytimer, + .clkr = { + .enable_reg = 0x0160, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "csiphytimer_src", + .parent_names = mmcc_pxo_pll8_pll2, + .num_parents = 3, + .ops = &clk_rcg_ops, + }, + }, +}; + +static const char *csixphy_timer_src[] = { "csiphytimer_src" }; + +static struct clk_branch csiphy0_timer_clk = { + .halt_reg = 0x01e8, + .halt_bit = 17, + .clkr = { + .enable_reg = 0x0160, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .parent_names = csixphy_timer_src, + .num_parents = 1, + .name = "csiphy0_timer_clk", + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch csiphy1_timer_clk = { + .halt_reg = 0x01e8, + .halt_bit = 18, + .clkr = { + .enable_reg = 0x0160, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .parent_names = csixphy_timer_src, + .num_parents = 1, + .name = "csiphy1_timer_clk", + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch csiphy2_timer_clk = { + .halt_reg = 0x01e8, + .halt_bit = 30, + .clkr = { + .enable_reg = 0x0160, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .parent_names = csixphy_timer_src, + .num_parents = 1, + .name = "csiphy2_timer_clk", + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct freq_tbl clk_tbl_gfx2d[] = { + { 27000000, P_PXO, 1, 0 }, + { 48000000, P_PLL8, 1, 8 }, + { 54857000, P_PLL8, 1, 7 }, + { 64000000, P_PLL8, 1, 6 }, + { 76800000, P_PLL8, 1, 5 }, + { 96000000, P_PLL8, 1, 4 }, + { 128000000, P_PLL8, 1, 3 }, + { 145455000, P_PLL2, 2, 11 }, + { 160000000, P_PLL2, 1, 5 }, + { 177778000, P_PLL2, 2, 9 }, + { 200000000, P_PLL2, 1, 4 }, + { 228571000, P_PLL2, 2, 7 }, + { } +}; + +static struct clk_dyn_rcg gfx2d0_src = { + .ns_reg = 0x0070, + .md_reg[0] = 0x0064, + .md_reg[1] = 0x0068, + .mn[0] = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 25, + .mnctr_mode_shift = 9, + .n_val_shift = 20, + .m_val_shift = 4, + .width = 4, + }, + .mn[1] = { + .mnctr_en_bit = 5, + .mnctr_reset_bit = 24, + .mnctr_mode_shift = 6, + .n_val_shift = 16, + .m_val_shift = 4, + .width = 4, + }, + .s[0] = { + .src_sel_shift = 3, + .parent_map = mmcc_pxo_pll8_pll2_map, + }, + .s[1] = { + .src_sel_shift = 0, + .parent_map = mmcc_pxo_pll8_pll2_map, + }, + .mux_sel_bit = 11, + .freq_tbl = clk_tbl_gfx2d, + .clkr = { + .enable_reg = 0x0060, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gfx2d0_src", + .parent_names = mmcc_pxo_pll8_pll2, + .num_parents = 3, + .ops = &clk_dyn_rcg_ops, + }, + }, +}; + +static struct clk_branch gfx2d0_clk = { + .halt_reg = 0x01c8, + .halt_bit = 9, + .clkr = { + .enable_reg = 0x0060, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gfx2d0_clk", + .parent_names = (const char *[]){ "gfx2d0_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_dyn_rcg gfx2d1_src = { + .ns_reg = 0x007c, + .md_reg[0] = 0x0078, + .md_reg[1] = 0x006c, + .mn[0] = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 25, + .mnctr_mode_shift = 9, + .n_val_shift = 20, + .m_val_shift = 4, + .width = 4, + }, + .mn[1] = { + .mnctr_en_bit = 5, + .mnctr_reset_bit = 24, + .mnctr_mode_shift = 6, + .n_val_shift = 16, + .m_val_shift = 4, + .width = 4, + }, + .s[0] = { + .src_sel_shift = 3, + .parent_map = mmcc_pxo_pll8_pll2_map, + }, + .s[1] = { + .src_sel_shift = 0, + .parent_map = mmcc_pxo_pll8_pll2_map, + }, + .mux_sel_bit = 11, + .freq_tbl = clk_tbl_gfx2d, + .clkr = { + .enable_reg = 0x0074, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gfx2d1_src", + .parent_names = mmcc_pxo_pll8_pll2, + .num_parents = 3, + .ops = &clk_dyn_rcg_ops, + }, + }, +}; + +static struct clk_branch gfx2d1_clk = { + .halt_reg = 0x01c8, + .halt_bit = 14, + .clkr = { + .enable_reg = 0x0074, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gfx2d1_clk", + .parent_names = (const char *[]){ "gfx2d1_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct freq_tbl clk_tbl_gfx3d[] = { + { 27000000, P_PXO, 1, 0 }, + { 48000000, P_PLL8, 1, 8 }, + { 54857000, P_PLL8, 1, 7 }, + { 64000000, P_PLL8, 1, 6 }, + { 76800000, P_PLL8, 1, 5 }, + { 96000000, P_PLL8, 1, 4 }, + { 128000000, P_PLL8, 1, 3 }, + { 145455000, P_PLL2, 2, 11 }, + { 160000000, P_PLL2, 1, 5 }, + { 177778000, P_PLL2, 2, 9 }, + { 200000000, P_PLL2, 1, 4 }, + { 228571000, P_PLL2, 2, 7 }, + { 266667000, P_PLL2, 1, 3 }, + { 300000000, P_PLL3, 1, 4 }, + { 320000000, P_PLL2, 2, 5 }, + { 400000000, P_PLL2, 1, 2 }, + { } +}; + +static struct clk_dyn_rcg gfx3d_src = { + .ns_reg = 0x008c, + .md_reg[0] = 0x0084, + .md_reg[1] = 0x0088, + .mn[0] = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 25, + .mnctr_mode_shift = 9, + .n_val_shift = 18, + .m_val_shift = 4, + .width = 4, + }, + .mn[1] = { + .mnctr_en_bit = 5, + .mnctr_reset_bit = 24, + .mnctr_mode_shift = 6, + .n_val_shift = 14, + .m_val_shift = 4, + .width = 4, + }, + .s[0] = { + .src_sel_shift = 3, + .parent_map = mmcc_pxo_pll8_pll2_pll3_map, + }, + .s[1] = { + .src_sel_shift = 0, + .parent_map = mmcc_pxo_pll8_pll2_pll3_map, + }, + .mux_sel_bit = 11, + .freq_tbl = clk_tbl_gfx3d, + .clkr = { + .enable_reg = 0x0080, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gfx3d_src", + .parent_names = mmcc_pxo_pll8_pll2_pll3, + .num_parents = 3, + .ops = &clk_dyn_rcg_ops, + }, + }, +}; + +static struct clk_branch gfx3d_clk = { + .halt_reg = 0x01c8, + .halt_bit = 4, + .clkr = { + .enable_reg = 0x0080, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gfx3d_clk", + .parent_names = (const char *[]){ "gfx3d_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct freq_tbl clk_tbl_ijpeg[] = { + { 27000000, P_PXO, 1, 0, 0 }, + { 36570000, P_PLL8, 1, 2, 21 }, + { 54860000, P_PLL8, 7, 0, 0 }, + { 96000000, P_PLL8, 4, 0, 0 }, + { 109710000, P_PLL8, 1, 2, 7 }, + { 128000000, P_PLL8, 3, 0, 0 }, + { 153600000, P_PLL8, 1, 2, 5 }, + { 200000000, P_PLL2, 4, 0, 0 }, + { 228571000, P_PLL2, 1, 2, 7 }, + { 266667000, P_PLL2, 1, 1, 3 }, + { 320000000, P_PLL2, 1, 2, 5 }, + { } +}; + +static struct clk_rcg ijpeg_src = { + .ns_reg = 0x00a0, + .md_reg = 0x009c, + .mn = { + .mnctr_en_bit = 5, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 6, + .n_val_shift = 16, + .m_val_shift = 8, + .width = 8, + }, + .p = { + .pre_div_shift = 12, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = mmcc_pxo_pll8_pll2_map, + }, + .freq_tbl = clk_tbl_ijpeg, + .clkr = { + .enable_reg = 0x0098, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "ijpeg_src", + .parent_names = mmcc_pxo_pll8_pll2, + .num_parents = 3, + .ops = &clk_rcg_ops, + }, + }, +}; + +static struct clk_branch ijpeg_clk = { + .halt_reg = 0x01c8, + .halt_bit = 24, + .clkr = { + .enable_reg = 0x0098, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "ijpeg_clk", + .parent_names = (const char *[]){ "ijpeg_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct freq_tbl clk_tbl_jpegd[] = { + { 64000000, P_PLL8, 6 }, + { 76800000, P_PLL8, 5 }, + { 96000000, P_PLL8, 4 }, + { 160000000, P_PLL2, 5 }, + { 200000000, P_PLL2, 4 }, + { } +}; + +static struct clk_rcg jpegd_src = { + .ns_reg = 0x00ac, + .p = { + .pre_div_shift = 12, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = mmcc_pxo_pll8_pll2_map, + }, + .freq_tbl = clk_tbl_jpegd, + .clkr = { + .enable_reg = 0x00a4, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "jpegd_src", + .parent_names = mmcc_pxo_pll8_pll2, + .num_parents = 3, + .ops = &clk_rcg_ops, + }, + }, +}; + +static struct clk_branch jpegd_clk = { + .halt_reg = 0x01c8, + .halt_bit = 19, + .clkr = { + .enable_reg = 0x00a4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "jpegd_clk", + .parent_names = (const char *[]){ "jpegd_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct freq_tbl clk_tbl_mdp[] = { + { 9600000, P_PLL8, 1, 1, 40 }, + { 13710000, P_PLL8, 1, 1, 28 }, + { 27000000, P_PXO, 1, 0, 0 }, + { 29540000, P_PLL8, 1, 1, 13 }, + { 34910000, P_PLL8, 1, 1, 11 }, + { 38400000, P_PLL8, 1, 1, 10 }, + { 59080000, P_PLL8, 1, 2, 13 }, + { 76800000, P_PLL8, 1, 1, 5 }, + { 85330000, P_PLL8, 1, 2, 9 }, + { 96000000, P_PLL8, 1, 1, 4 }, + { 128000000, P_PLL8, 1, 1, 3 }, + { 160000000, P_PLL2, 1, 1, 5 }, + { 177780000, P_PLL2, 1, 2, 9 }, + { 200000000, P_PLL2, 1, 1, 4 }, + { 228571000, P_PLL2, 1, 2, 7 }, + { 266667000, P_PLL2, 1, 1, 3 }, + { } +}; + +static struct clk_dyn_rcg mdp_src = { + .ns_reg = 0x00d0, + .md_reg[0] = 0x00c4, + .md_reg[1] = 0x00c8, + .mn[0] = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 31, + .mnctr_mode_shift = 9, + .n_val_shift = 22, + .m_val_shift = 8, + .width = 8, + }, + .mn[1] = { + .mnctr_en_bit = 5, + .mnctr_reset_bit = 30, + .mnctr_mode_shift = 6, + .n_val_shift = 14, + .m_val_shift = 8, + .width = 8, + }, + .s[0] = { + .src_sel_shift = 3, + .parent_map = mmcc_pxo_pll8_pll2_map, + }, + .s[1] = { + .src_sel_shift = 0, + .parent_map = mmcc_pxo_pll8_pll2_map, + }, + .mux_sel_bit = 11, + .freq_tbl = clk_tbl_mdp, + .clkr = { + .enable_reg = 0x00c0, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "mdp_src", + .parent_names = mmcc_pxo_pll8_pll2, + .num_parents = 3, + .ops = &clk_dyn_rcg_ops, + }, + }, +}; + +static struct clk_branch mdp_clk = { + .halt_reg = 0x01d0, + .halt_bit = 10, + .clkr = { + .enable_reg = 0x00c0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdp_clk", + .parent_names = (const char *[]){ "mdp_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch mdp_lut_clk = { + .halt_reg = 0x01e8, + .halt_bit = 13, + .clkr = { + .enable_reg = 0x016c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .parent_names = (const char *[]){ "mdp_clk" }, + .num_parents = 1, + .name = "mdp_lut_clk", + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch mdp_vsync_clk = { + .halt_reg = 0x01cc, + .halt_bit = 22, + .clkr = { + .enable_reg = 0x0058, + .enable_mask = BIT(6), + .hw.init = &(struct clk_init_data){ + .name = "mdp_vsync_clk", + .parent_names = (const char *[]){ "pxo" }, + .num_parents = 1, + .ops = &clk_branch_ops + }, + }, +}; + +static struct freq_tbl clk_tbl_rot[] = { + { 27000000, P_PXO, 1 }, + { 29540000, P_PLL8, 13 }, + { 32000000, P_PLL8, 12 }, + { 38400000, P_PLL8, 10 }, + { 48000000, P_PLL8, 8 }, + { 54860000, P_PLL8, 7 }, + { 64000000, P_PLL8, 6 }, + { 76800000, P_PLL8, 5 }, + { 96000000, P_PLL8, 4 }, + { 100000000, P_PLL2, 8 }, + { 114290000, P_PLL2, 7 }, + { 133330000, P_PLL2, 6 }, + { 160000000, P_PLL2, 5 }, + { 200000000, P_PLL2, 4 }, + { } +}; + +static struct clk_dyn_rcg rot_src = { + .ns_reg = 0x00e8, + .p[0] = { + .pre_div_shift = 22, + .pre_div_width = 4, + }, + .p[1] = { + .pre_div_shift = 26, + .pre_div_width = 4, + }, + .s[0] = { + .src_sel_shift = 16, + .parent_map = mmcc_pxo_pll8_pll2_map, + }, + .s[1] = { + .src_sel_shift = 19, + .parent_map = mmcc_pxo_pll8_pll2_map, + }, + .mux_sel_bit = 30, + .freq_tbl = clk_tbl_rot, + .clkr = { + .enable_reg = 0x00e0, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "rot_src", + .parent_names = mmcc_pxo_pll8_pll2, + .num_parents = 3, + .ops = &clk_dyn_rcg_ops, + }, + }, +}; + +static struct clk_branch rot_clk = { + .halt_reg = 0x01d0, + .halt_bit = 15, + .clkr = { + .enable_reg = 0x00e0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "rot_clk", + .parent_names = (const char *[]){ "rot_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +#define P_HDMI_PLL 1 + +static u8 mmcc_pxo_hdmi_map[] = { + [P_PXO] = 0, + [P_HDMI_PLL] = 2, +}; + +static const char *mmcc_pxo_hdmi[] = { + "pxo", + "hdmi_pll", +}; + +static struct freq_tbl clk_tbl_tv[] = { + { 25200000, P_HDMI_PLL, 1, 0, 0 }, + { 27000000, P_HDMI_PLL, 1, 0, 0 }, + { 27030000, P_HDMI_PLL, 1, 0, 0 }, + { 74250000, P_HDMI_PLL, 1, 0, 0 }, + { 108000000, P_HDMI_PLL, 1, 0, 0 }, + { 148500000, P_HDMI_PLL, 1, 0, 0 }, + { } +}; + +static struct clk_rcg tv_src = { + .ns_reg = 0x00f4, + .md_reg = 0x00f0, + .mn = { + .mnctr_en_bit = 5, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 6, + .n_val_shift = 16, + .m_val_shift = 8, + .width = 8, + }, + .p = { + .pre_div_shift = 14, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = mmcc_pxo_hdmi_map, + }, + .freq_tbl = clk_tbl_tv, + .clkr = { + .enable_reg = 0x00ec, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "tv_src", + .parent_names = mmcc_pxo_hdmi, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const char *tv_src_name[] = { "tv_src" }; + +static struct clk_branch tv_enc_clk = { + .halt_reg = 0x01d4, + .halt_bit = 9, + .clkr = { + .enable_reg = 0x00ec, + .enable_mask = BIT(8), + .hw.init = &(struct clk_init_data){ + .parent_names = tv_src_name, + .num_parents = 1, + .name = "tv_enc_clk", + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch tv_dac_clk = { + .halt_reg = 0x01d4, + .halt_bit = 10, + .clkr = { + .enable_reg = 0x00ec, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .parent_names = tv_src_name, + .num_parents = 1, + .name = "tv_dac_clk", + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch mdp_tv_clk = { + .halt_reg = 0x01d4, + .halt_bit = 12, + .clkr = { + .enable_reg = 0x00ec, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .parent_names = tv_src_name, + .num_parents = 1, + .name = "mdp_tv_clk", + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch hdmi_tv_clk = { + .halt_reg = 0x01d4, + .halt_bit = 11, + .clkr = { + .enable_reg = 0x00ec, + .enable_mask = BIT(12), + .hw.init = &(struct clk_init_data){ + .parent_names = tv_src_name, + .num_parents = 1, + .name = "hdmi_tv_clk", + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch hdmi_app_clk = { + .halt_reg = 0x01cc, + .halt_bit = 25, + .clkr = { + .enable_reg = 0x005c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .parent_names = (const char *[]){ "pxo" }, + .num_parents = 1, + .name = "hdmi_app_clk", + .ops = &clk_branch_ops, + }, + }, +}; + +static struct freq_tbl clk_tbl_vcodec[] = { + { 27000000, P_PXO, 1, 0 }, + { 32000000, P_PLL8, 1, 12 }, + { 48000000, P_PLL8, 1, 8 }, + { 54860000, P_PLL8, 1, 7 }, + { 96000000, P_PLL8, 1, 4 }, + { 133330000, P_PLL2, 1, 6 }, + { 200000000, P_PLL2, 1, 4 }, + { 228570000, P_PLL2, 2, 7 }, + { 266670000, P_PLL2, 1, 3 }, + { } +}; + +static struct clk_dyn_rcg vcodec_src = { + .ns_reg = 0x0100, + .md_reg[0] = 0x00fc, + .md_reg[1] = 0x0128, + .mn[0] = { + .mnctr_en_bit = 5, + .mnctr_reset_bit = 31, + .mnctr_mode_shift = 6, + .n_val_shift = 11, + .m_val_shift = 8, + .width = 8, + }, + .mn[1] = { + .mnctr_en_bit = 10, + .mnctr_reset_bit = 30, + .mnctr_mode_shift = 11, + .n_val_shift = 19, + .m_val_shift = 8, + .width = 8, + }, + .s[0] = { + .src_sel_shift = 27, + .parent_map = mmcc_pxo_pll8_pll2_map, + }, + .s[1] = { + .src_sel_shift = 0, + .parent_map = mmcc_pxo_pll8_pll2_map, + }, + .mux_sel_bit = 13, + .freq_tbl = clk_tbl_vcodec, + .clkr = { + .enable_reg = 0x00f8, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "vcodec_src", + .parent_names = mmcc_pxo_pll8_pll2, + .num_parents = 3, + .ops = &clk_dyn_rcg_ops, + }, + }, +}; + +static struct clk_branch vcodec_clk = { + .halt_reg = 0x01d0, + .halt_bit = 29, + .clkr = { + .enable_reg = 0x00f8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "vcodec_clk", + .parent_names = (const char *[]){ "vcodec_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct freq_tbl clk_tbl_vpe[] = { + { 27000000, P_PXO, 1 }, + { 34909000, P_PLL8, 11 }, + { 38400000, P_PLL8, 10 }, + { 64000000, P_PLL8, 6 }, + { 76800000, P_PLL8, 5 }, + { 96000000, P_PLL8, 4 }, + { 100000000, P_PLL2, 8 }, + { 160000000, P_PLL2, 5 }, + { } +}; + +static struct clk_rcg vpe_src = { + .ns_reg = 0x0118, + .p = { + .pre_div_shift = 12, + .pre_div_width = 4, + }, + .s = { + .src_sel_shift = 0, + .parent_map = mmcc_pxo_pll8_pll2_map, + }, + .freq_tbl = clk_tbl_vpe, + .clkr = { + .enable_reg = 0x0110, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "vpe_src", + .parent_names = mmcc_pxo_pll8_pll2, + .num_parents = 3, + .ops = &clk_rcg_ops, + }, + }, +}; + +static struct clk_branch vpe_clk = { + .halt_reg = 0x01c8, + .halt_bit = 28, + .clkr = { + .enable_reg = 0x0110, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "vpe_clk", + .parent_names = (const char *[]){ "vpe_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct freq_tbl clk_tbl_vfe[] = { + { 13960000, P_PLL8, 1, 2, 55 }, + { 27000000, P_PXO, 1, 0, 0 }, + { 36570000, P_PLL8, 1, 2, 21 }, + { 38400000, P_PLL8, 2, 1, 5 }, + { 45180000, P_PLL8, 1, 2, 17 }, + { 48000000, P_PLL8, 2, 1, 4 }, + { 54860000, P_PLL8, 1, 1, 7 }, + { 64000000, P_PLL8, 2, 1, 3 }, + { 76800000, P_PLL8, 1, 1, 5 }, + { 96000000, P_PLL8, 2, 1, 2 }, + { 109710000, P_PLL8, 1, 2, 7 }, + { 128000000, P_PLL8, 1, 1, 3 }, + { 153600000, P_PLL8, 1, 2, 5 }, + { 200000000, P_PLL2, 2, 1, 2 }, + { 228570000, P_PLL2, 1, 2, 7 }, + { 266667000, P_PLL2, 1, 1, 3 }, + { 320000000, P_PLL2, 1, 2, 5 }, + { } +}; + +static struct clk_rcg vfe_src = { + .ns_reg = 0x0108, + .mn = { + .mnctr_en_bit = 5, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 6, + .n_val_shift = 16, + .m_val_shift = 8, + .width = 8, + }, + .p = { + .pre_div_shift = 10, + .pre_div_width = 1, + }, + .s = { + .src_sel_shift = 0, + .parent_map = mmcc_pxo_pll8_pll2_map, + }, + .freq_tbl = clk_tbl_vfe, + .clkr = { + .enable_reg = 0x0104, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "vfe_src", + .parent_names = mmcc_pxo_pll8_pll2, + .num_parents = 3, + .ops = &clk_rcg_ops, + }, + }, +}; + +static struct clk_branch vfe_clk = { + .halt_reg = 0x01cc, + .halt_bit = 6, + .clkr = { + .enable_reg = 0x0104, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "vfe_clk", + .parent_names = (const char *[]){ "vfe_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch vfe_csi_clk = { + .halt_reg = 0x01cc, + .halt_bit = 8, + .clkr = { + .enable_reg = 0x0104, + .enable_mask = BIT(12), + .hw.init = &(struct clk_init_data){ + .parent_names = (const char *[]){ "vfe_src" }, + .num_parents = 1, + .name = "vfe_csi_clk", + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch gmem_axi_clk = { + .halt_reg = 0x01d8, + .halt_bit = 6, + .clkr = { + .enable_reg = 0x0018, + .enable_mask = BIT(24), + .hw.init = &(struct clk_init_data){ + .name = "gmem_axi_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch ijpeg_axi_clk = { + .hwcg_reg = 0x0018, + .hwcg_bit = 11, + .halt_reg = 0x01d8, + .halt_bit = 4, + .clkr = { + .enable_reg = 0x0018, + .enable_mask = BIT(21), + .hw.init = &(struct clk_init_data){ + .name = "ijpeg_axi_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch mmss_imem_axi_clk = { + .hwcg_reg = 0x0018, + .hwcg_bit = 15, + .halt_reg = 0x01d8, + .halt_bit = 7, + .clkr = { + .enable_reg = 0x0018, + .enable_mask = BIT(22), + .hw.init = &(struct clk_init_data){ + .name = "mmss_imem_axi_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch jpegd_axi_clk = { + .halt_reg = 0x01d8, + .halt_bit = 5, + .clkr = { + .enable_reg = 0x0018, + .enable_mask = BIT(25), + .hw.init = &(struct clk_init_data){ + .name = "jpegd_axi_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch vcodec_axi_b_clk = { + .hwcg_reg = 0x0114, + .hwcg_bit = 22, + .halt_reg = 0x01e8, + .halt_bit = 25, + .clkr = { + .enable_reg = 0x0114, + .enable_mask = BIT(23), + .hw.init = &(struct clk_init_data){ + .name = "vcodec_axi_b_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch vcodec_axi_a_clk = { + .hwcg_reg = 0x0114, + .hwcg_bit = 24, + .halt_reg = 0x01e8, + .halt_bit = 26, + .clkr = { + .enable_reg = 0x0114, + .enable_mask = BIT(25), + .hw.init = &(struct clk_init_data){ + .name = "vcodec_axi_a_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch vcodec_axi_clk = { + .hwcg_reg = 0x0018, + .hwcg_bit = 13, + .halt_reg = 0x01d8, + .halt_bit = 3, + .clkr = { + .enable_reg = 0x0018, + .enable_mask = BIT(19), + .hw.init = &(struct clk_init_data){ + .name = "vcodec_axi_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch vfe_axi_clk = { + .halt_reg = 0x01d8, + .halt_bit = 0, + .clkr = { + .enable_reg = 0x0018, + .enable_mask = BIT(18), + .hw.init = &(struct clk_init_data){ + .name = "vfe_axi_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch mdp_axi_clk = { + .hwcg_reg = 0x0018, + .hwcg_bit = 16, + .halt_reg = 0x01d8, + .halt_bit = 8, + .clkr = { + .enable_reg = 0x0018, + .enable_mask = BIT(23), + .hw.init = &(struct clk_init_data){ + .name = "mdp_axi_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch rot_axi_clk = { + .hwcg_reg = 0x0020, + .hwcg_bit = 25, + .halt_reg = 0x01d8, + .halt_bit = 2, + .clkr = { + .enable_reg = 0x0020, + .enable_mask = BIT(24), + .hw.init = &(struct clk_init_data){ + .name = "rot_axi_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch vpe_axi_clk = { + .hwcg_reg = 0x0020, + .hwcg_bit = 27, + .halt_reg = 0x01d8, + .halt_bit = 1, + .clkr = { + .enable_reg = 0x0020, + .enable_mask = BIT(26), + .hw.init = &(struct clk_init_data){ + .name = "vpe_axi_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gfx3d_axi_clk = { + .hwcg_reg = 0x0244, + .hwcg_bit = 24, + .halt_reg = 0x0240, + .halt_bit = 30, + .clkr = { + .enable_reg = 0x0244, + .enable_mask = BIT(25), + .hw.init = &(struct clk_init_data){ + .name = "gfx3d_axi_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch amp_ahb_clk = { + .halt_reg = 0x01dc, + .halt_bit = 18, + .clkr = { + .enable_reg = 0x0008, + .enable_mask = BIT(24), + .hw.init = &(struct clk_init_data){ + .name = "amp_ahb_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch csi_ahb_clk = { + .halt_reg = 0x01dc, + .halt_bit = 16, + .clkr = { + .enable_reg = 0x0008, + .enable_mask = BIT(7), + .hw.init = &(struct clk_init_data){ + .name = "csi_ahb_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT + }, + }, +}; + +static struct clk_branch dsi_m_ahb_clk = { + .halt_reg = 0x01dc, + .halt_bit = 19, + .clkr = { + .enable_reg = 0x0008, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "dsi_m_ahb_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch dsi_s_ahb_clk = { + .hwcg_reg = 0x0038, + .hwcg_bit = 20, + .halt_reg = 0x01dc, + .halt_bit = 21, + .clkr = { + .enable_reg = 0x0008, + .enable_mask = BIT(18), + .hw.init = &(struct clk_init_data){ + .name = "dsi_s_ahb_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch dsi2_m_ahb_clk = { + .halt_reg = 0x01d8, + .halt_bit = 18, + .clkr = { + .enable_reg = 0x0008, + .enable_mask = BIT(17), + .hw.init = &(struct clk_init_data){ + .name = "dsi2_m_ahb_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT + }, + }, +}; + +static struct clk_branch dsi2_s_ahb_clk = { + .hwcg_reg = 0x0038, + .hwcg_bit = 15, + .halt_reg = 0x01dc, + .halt_bit = 20, + .clkr = { + .enable_reg = 0x0008, + .enable_mask = BIT(22), + .hw.init = &(struct clk_init_data){ + .name = "dsi2_s_ahb_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gfx2d0_ahb_clk = { + .hwcg_reg = 0x0038, + .hwcg_bit = 28, + .halt_reg = 0x01dc, + .halt_bit = 2, + .clkr = { + .enable_reg = 0x0008, + .enable_mask = BIT(19), + .hw.init = &(struct clk_init_data){ + .name = "gfx2d0_ahb_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gfx2d1_ahb_clk = { + .hwcg_reg = 0x0038, + .hwcg_bit = 29, + .halt_reg = 0x01dc, + .halt_bit = 3, + .clkr = { + .enable_reg = 0x0008, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gfx2d1_ahb_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch gfx3d_ahb_clk = { + .hwcg_reg = 0x0038, + .hwcg_bit = 27, + .halt_reg = 0x01dc, + .halt_bit = 4, + .clkr = { + .enable_reg = 0x0008, + .enable_mask = BIT(3), + .hw.init = &(struct clk_init_data){ + .name = "gfx3d_ahb_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch hdmi_m_ahb_clk = { + .hwcg_reg = 0x0038, + .hwcg_bit = 21, + .halt_reg = 0x01dc, + .halt_bit = 5, + .clkr = { + .enable_reg = 0x0008, + .enable_mask = BIT(14), + .hw.init = &(struct clk_init_data){ + .name = "hdmi_m_ahb_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch hdmi_s_ahb_clk = { + .hwcg_reg = 0x0038, + .hwcg_bit = 22, + .halt_reg = 0x01dc, + .halt_bit = 6, + .clkr = { + .enable_reg = 0x0008, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "hdmi_s_ahb_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch ijpeg_ahb_clk = { + .halt_reg = 0x01dc, + .halt_bit = 9, + .clkr = { + .enable_reg = 0x0008, + .enable_mask = BIT(5), + .hw.init = &(struct clk_init_data){ + .name = "ijpeg_ahb_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT + }, + }, +}; + +static struct clk_branch mmss_imem_ahb_clk = { + .hwcg_reg = 0x0038, + .hwcg_bit = 12, + .halt_reg = 0x01dc, + .halt_bit = 10, + .clkr = { + .enable_reg = 0x0008, + .enable_mask = BIT(6), + .hw.init = &(struct clk_init_data){ + .name = "mmss_imem_ahb_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT + }, + }, +}; + +static struct clk_branch jpegd_ahb_clk = { + .halt_reg = 0x01dc, + .halt_bit = 7, + .clkr = { + .enable_reg = 0x0008, + .enable_mask = BIT(21), + .hw.init = &(struct clk_init_data){ + .name = "jpegd_ahb_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch mdp_ahb_clk = { + .halt_reg = 0x01dc, + .halt_bit = 11, + .clkr = { + .enable_reg = 0x0008, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "mdp_ahb_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch rot_ahb_clk = { + .halt_reg = 0x01dc, + .halt_bit = 13, + .clkr = { + .enable_reg = 0x0008, + .enable_mask = BIT(12), + .hw.init = &(struct clk_init_data){ + .name = "rot_ahb_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT + }, + }, +}; + +static struct clk_branch smmu_ahb_clk = { + .hwcg_reg = 0x0008, + .hwcg_bit = 26, + .halt_reg = 0x01dc, + .halt_bit = 22, + .clkr = { + .enable_reg = 0x0008, + .enable_mask = BIT(15), + .hw.init = &(struct clk_init_data){ + .name = "smmu_ahb_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch tv_enc_ahb_clk = { + .halt_reg = 0x01dc, + .halt_bit = 23, + .clkr = { + .enable_reg = 0x0008, + .enable_mask = BIT(25), + .hw.init = &(struct clk_init_data){ + .name = "tv_enc_ahb_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch vcodec_ahb_clk = { + .hwcg_reg = 0x0038, + .hwcg_bit = 26, + .halt_reg = 0x01dc, + .halt_bit = 12, + .clkr = { + .enable_reg = 0x0008, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "vcodec_ahb_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch vfe_ahb_clk = { + .halt_reg = 0x01dc, + .halt_bit = 14, + .clkr = { + .enable_reg = 0x0008, + .enable_mask = BIT(13), + .hw.init = &(struct clk_init_data){ + .name = "vfe_ahb_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_branch vpe_ahb_clk = { + .halt_reg = 0x01dc, + .halt_bit = 15, + .clkr = { + .enable_reg = 0x0008, + .enable_mask = BIT(16), + .hw.init = &(struct clk_init_data){ + .name = "vpe_ahb_clk", + .ops = &clk_branch_ops, + .flags = CLK_IS_ROOT, + }, + }, +}; + +static struct clk_regmap *mmcc_msm8960_clks[] = { + [TV_ENC_AHB_CLK] = &tv_enc_ahb_clk.clkr, + [AMP_AHB_CLK] = &_ahb_clk.clkr, + [DSI2_S_AHB_CLK] = &dsi2_s_ahb_clk.clkr, + [JPEGD_AHB_CLK] = &jpegd_ahb_clk.clkr, + [GFX2D0_AHB_CLK] = &gfx2d0_ahb_clk.clkr, + [DSI_S_AHB_CLK] = &dsi_s_ahb_clk.clkr, + [DSI2_M_AHB_CLK] = &dsi2_m_ahb_clk.clkr, + [VPE_AHB_CLK] = &vpe_ahb_clk.clkr, + [SMMU_AHB_CLK] = &smmu_ahb_clk.clkr, + [HDMI_M_AHB_CLK] = &hdmi_m_ahb_clk.clkr, + [VFE_AHB_CLK] = &vfe_ahb_clk.clkr, + [ROT_AHB_CLK] = &rot_ahb_clk.clkr, + [VCODEC_AHB_CLK] = &vcodec_ahb_clk.clkr, + [MDP_AHB_CLK] = &mdp_ahb_clk.clkr, + [DSI_M_AHB_CLK] = &dsi_m_ahb_clk.clkr, + [CSI_AHB_CLK] = &csi_ahb_clk.clkr, + [MMSS_IMEM_AHB_CLK] = &mmss_imem_ahb_clk.clkr, + [IJPEG_AHB_CLK] = &ijpeg_ahb_clk.clkr, + [HDMI_S_AHB_CLK] = &hdmi_s_ahb_clk.clkr, + [GFX3D_AHB_CLK] = &gfx3d_ahb_clk.clkr, + [GFX2D1_AHB_CLK] = &gfx2d1_ahb_clk.clkr, + [JPEGD_AXI_CLK] = &jpegd_axi_clk.clkr, + [GMEM_AXI_CLK] = &gmem_axi_clk.clkr, + [MDP_AXI_CLK] = &mdp_axi_clk.clkr, + [MMSS_IMEM_AXI_CLK] = &mmss_imem_axi_clk.clkr, + [IJPEG_AXI_CLK] = &ijpeg_axi_clk.clkr, + [GFX3D_AXI_CLK] = &gfx3d_axi_clk.clkr, + [VCODEC_AXI_CLK] = &vcodec_axi_clk.clkr, + [VFE_AXI_CLK] = &vfe_axi_clk.clkr, + [VPE_AXI_CLK] = &vpe_axi_clk.clkr, + [ROT_AXI_CLK] = &rot_axi_clk.clkr, + [VCODEC_AXI_A_CLK] = &vcodec_axi_a_clk.clkr, + [VCODEC_AXI_B_CLK] = &vcodec_axi_b_clk.clkr, + [CSI0_SRC] = &csi0_src.clkr, + [CSI0_CLK] = &csi0_clk.clkr, + [CSI0_PHY_CLK] = &csi0_phy_clk.clkr, + [CSI1_SRC] = &csi1_src.clkr, + [CSI1_CLK] = &csi1_clk.clkr, + [CSI1_PHY_CLK] = &csi1_phy_clk.clkr, + [CSI2_SRC] = &csi2_src.clkr, + [CSI2_CLK] = &csi2_clk.clkr, + [CSI2_PHY_CLK] = &csi2_phy_clk.clkr, + [CSI_PIX_CLK] = &csi_pix_clk.clkr, + [CSI_RDI_CLK] = &csi_rdi_clk.clkr, + [MDP_VSYNC_CLK] = &mdp_vsync_clk.clkr, + [HDMI_APP_CLK] = &hdmi_app_clk.clkr, + [CSI_PIX1_CLK] = &csi_pix1_clk.clkr, + [CSI_RDI2_CLK] = &csi_rdi2_clk.clkr, + [CSI_RDI1_CLK] = &csi_rdi1_clk.clkr, + [GFX2D0_SRC] = &gfx2d0_src.clkr, + [GFX2D0_CLK] = &gfx2d0_clk.clkr, + [GFX2D1_SRC] = &gfx2d1_src.clkr, + [GFX2D1_CLK] = &gfx2d1_clk.clkr, + [GFX3D_SRC] = &gfx3d_src.clkr, + [GFX3D_CLK] = &gfx3d_clk.clkr, + [IJPEG_SRC] = &ijpeg_src.clkr, + [IJPEG_CLK] = &ijpeg_clk.clkr, + [JPEGD_SRC] = &jpegd_src.clkr, + [JPEGD_CLK] = &jpegd_clk.clkr, + [MDP_SRC] = &mdp_src.clkr, + [MDP_CLK] = &mdp_clk.clkr, + [MDP_LUT_CLK] = &mdp_lut_clk.clkr, + [ROT_SRC] = &rot_src.clkr, + [ROT_CLK] = &rot_clk.clkr, + [TV_ENC_CLK] = &tv_enc_clk.clkr, + [TV_DAC_CLK] = &tv_dac_clk.clkr, + [HDMI_TV_CLK] = &hdmi_tv_clk.clkr, + [MDP_TV_CLK] = &mdp_tv_clk.clkr, + [TV_SRC] = &tv_src.clkr, + [VCODEC_SRC] = &vcodec_src.clkr, + [VCODEC_CLK] = &vcodec_clk.clkr, + [VFE_SRC] = &vfe_src.clkr, + [VFE_CLK] = &vfe_clk.clkr, + [VFE_CSI_CLK] = &vfe_csi_clk.clkr, + [VPE_SRC] = &vpe_src.clkr, + [VPE_CLK] = &vpe_clk.clkr, + [CAMCLK0_SRC] = &camclk0_src.clkr, + [CAMCLK0_CLK] = &camclk0_clk.clkr, + [CAMCLK1_SRC] = &camclk1_src.clkr, + [CAMCLK1_CLK] = &camclk1_clk.clkr, + [CAMCLK2_SRC] = &camclk2_src.clkr, + [CAMCLK2_CLK] = &camclk2_clk.clkr, + [CSIPHYTIMER_SRC] = &csiphytimer_src.clkr, + [CSIPHY2_TIMER_CLK] = &csiphy2_timer_clk.clkr, + [CSIPHY1_TIMER_CLK] = &csiphy1_timer_clk.clkr, + [CSIPHY0_TIMER_CLK] = &csiphy0_timer_clk.clkr, + [PLL2] = &pll2.clkr, +}; + +static const struct qcom_reset_map mmcc_msm8960_resets[] = { + [VPE_AXI_RESET] = { 0x0208, 15 }, + [IJPEG_AXI_RESET] = { 0x0208, 14 }, + [MPD_AXI_RESET] = { 0x0208, 13 }, + [VFE_AXI_RESET] = { 0x0208, 9 }, + [SP_AXI_RESET] = { 0x0208, 8 }, + [VCODEC_AXI_RESET] = { 0x0208, 7 }, + [ROT_AXI_RESET] = { 0x0208, 6 }, + [VCODEC_AXI_A_RESET] = { 0x0208, 5 }, + [VCODEC_AXI_B_RESET] = { 0x0208, 4 }, + [FAB_S3_AXI_RESET] = { 0x0208, 3 }, + [FAB_S2_AXI_RESET] = { 0x0208, 2 }, + [FAB_S1_AXI_RESET] = { 0x0208, 1 }, + [FAB_S0_AXI_RESET] = { 0x0208 }, + [SMMU_GFX3D_ABH_RESET] = { 0x020c, 31 }, + [SMMU_VPE_AHB_RESET] = { 0x020c, 30 }, + [SMMU_VFE_AHB_RESET] = { 0x020c, 29 }, + [SMMU_ROT_AHB_RESET] = { 0x020c, 28 }, + [SMMU_VCODEC_B_AHB_RESET] = { 0x020c, 27 }, + [SMMU_VCODEC_A_AHB_RESET] = { 0x020c, 26 }, + [SMMU_MDP1_AHB_RESET] = { 0x020c, 25 }, + [SMMU_MDP0_AHB_RESET] = { 0x020c, 24 }, + [SMMU_JPEGD_AHB_RESET] = { 0x020c, 23 }, + [SMMU_IJPEG_AHB_RESET] = { 0x020c, 22 }, + [SMMU_GFX2D0_AHB_RESET] = { 0x020c, 21 }, + [SMMU_GFX2D1_AHB_RESET] = { 0x020c, 20 }, + [APU_AHB_RESET] = { 0x020c, 18 }, + [CSI_AHB_RESET] = { 0x020c, 17 }, + [TV_ENC_AHB_RESET] = { 0x020c, 15 }, + [VPE_AHB_RESET] = { 0x020c, 14 }, + [FABRIC_AHB_RESET] = { 0x020c, 13 }, + [GFX2D0_AHB_RESET] = { 0x020c, 12 }, + [GFX2D1_AHB_RESET] = { 0x020c, 11 }, + [GFX3D_AHB_RESET] = { 0x020c, 10 }, + [HDMI_AHB_RESET] = { 0x020c, 9 }, + [MSSS_IMEM_AHB_RESET] = { 0x020c, 8 }, + [IJPEG_AHB_RESET] = { 0x020c, 7 }, + [DSI_M_AHB_RESET] = { 0x020c, 6 }, + [DSI_S_AHB_RESET] = { 0x020c, 5 }, + [JPEGD_AHB_RESET] = { 0x020c, 4 }, + [MDP_AHB_RESET] = { 0x020c, 3 }, + [ROT_AHB_RESET] = { 0x020c, 2 }, + [VCODEC_AHB_RESET] = { 0x020c, 1 }, + [VFE_AHB_RESET] = { 0x020c, 0 }, + [DSI2_M_AHB_RESET] = { 0x0210, 31 }, + [DSI2_S_AHB_RESET] = { 0x0210, 30 }, + [CSIPHY2_RESET] = { 0x0210, 29 }, + [CSI_PIX1_RESET] = { 0x0210, 28 }, + [CSIPHY0_RESET] = { 0x0210, 27 }, + [CSIPHY1_RESET] = { 0x0210, 26 }, + [DSI2_RESET] = { 0x0210, 25 }, + [VFE_CSI_RESET] = { 0x0210, 24 }, + [MDP_RESET] = { 0x0210, 21 }, + [AMP_RESET] = { 0x0210, 20 }, + [JPEGD_RESET] = { 0x0210, 19 }, + [CSI1_RESET] = { 0x0210, 18 }, + [VPE_RESET] = { 0x0210, 17 }, + [MMSS_FABRIC_RESET] = { 0x0210, 16 }, + [VFE_RESET] = { 0x0210, 15 }, + [GFX2D0_RESET] = { 0x0210, 14 }, + [GFX2D1_RESET] = { 0x0210, 13 }, + [GFX3D_RESET] = { 0x0210, 12 }, + [HDMI_RESET] = { 0x0210, 11 }, + [MMSS_IMEM_RESET] = { 0x0210, 10 }, + [IJPEG_RESET] = { 0x0210, 9 }, + [CSI0_RESET] = { 0x0210, 8 }, + [DSI_RESET] = { 0x0210, 7 }, + [VCODEC_RESET] = { 0x0210, 6 }, + [MDP_TV_RESET] = { 0x0210, 4 }, + [MDP_VSYNC_RESET] = { 0x0210, 3 }, + [ROT_RESET] = { 0x0210, 2 }, + [TV_HDMI_RESET] = { 0x0210, 1 }, + [TV_ENC_RESET] = { 0x0210 }, + [CSI2_RESET] = { 0x0214, 2 }, + [CSI_RDI1_RESET] = { 0x0214, 1 }, + [CSI_RDI2_RESET] = { 0x0214 }, +}; + +static const struct regmap_config mmcc_msm8960_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x334, + .fast_io = true, +}; + +static const struct of_device_id mmcc_msm8960_match_table[] = { + { .compatible = "qcom,mmcc-msm8960" }, + { } +}; +MODULE_DEVICE_TABLE(of, mmcc_msm8960_match_table); + +struct qcom_cc { + struct qcom_reset_controller reset; + struct clk_onecell_data data; + struct clk *clks[]; +}; + +static int mmcc_msm8960_probe(struct platform_device *pdev) +{ + void __iomem *base; + struct resource *res; + int i, ret; + struct device *dev = &pdev->dev; + struct clk *clk; + struct clk_onecell_data *data; + struct clk **clks; + struct regmap *regmap; + size_t num_clks; + struct qcom_reset_controller *reset; + struct qcom_cc *cc; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + regmap = devm_regmap_init_mmio(dev, base, &mmcc_msm8960_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + num_clks = ARRAY_SIZE(mmcc_msm8960_clks); + cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks, + GFP_KERNEL); + if (!cc) + return -ENOMEM; + + clks = cc->clks; + data = &cc->data; + data->clks = clks; + data->clk_num = num_clks; + + for (i = 0; i < num_clks; i++) { + if (!mmcc_msm8960_clks[i]) + continue; + clk = devm_clk_register_regmap(dev, mmcc_msm8960_clks[i]); + if (IS_ERR(clk)) + return PTR_ERR(clk); + clks[i] = clk; + } + + ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data); + if (ret) + return ret; + + reset = &cc->reset; + reset->rcdev.of_node = dev->of_node; + reset->rcdev.ops = &qcom_reset_ops, + reset->rcdev.owner = THIS_MODULE, + reset->rcdev.nr_resets = ARRAY_SIZE(mmcc_msm8960_resets), + reset->regmap = regmap; + reset->reset_map = mmcc_msm8960_resets, + platform_set_drvdata(pdev, &reset->rcdev); + + ret = reset_controller_register(&reset->rcdev); + if (ret) + of_clk_del_provider(dev->of_node); + + return ret; +} + +static int mmcc_msm8960_remove(struct platform_device *pdev) +{ + of_clk_del_provider(pdev->dev.of_node); + reset_controller_unregister(platform_get_drvdata(pdev)); + return 0; +} + +static struct platform_driver mmcc_msm8960_driver = { + .probe = mmcc_msm8960_probe, + .remove = mmcc_msm8960_remove, + .driver = { + .name = "mmcc-msm8960", + .owner = THIS_MODULE, + .of_match_table = mmcc_msm8960_match_table, + }, +}; + +module_platform_driver(mmcc_msm8960_driver); + +MODULE_DESCRIPTION("QCOM MMCC MSM8960 Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:mmcc-msm8960"); diff --git a/drivers/clk/qcom/mmcc-msm8974.c b/drivers/clk/qcom/mmcc-msm8974.c new file mode 100644 index 000000000000..c95774514b81 --- /dev/null +++ b/drivers/clk/qcom/mmcc-msm8974.c @@ -0,0 +1,2625 @@ +/* + * Copyright (c) 2013, 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,mmcc-msm8974.h> +#include <dt-bindings/reset/qcom,mmcc-msm8974.h> + +#include "clk-regmap.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-branch.h" +#include "reset.h" + +#define P_XO 0 +#define P_MMPLL0 1 +#define P_EDPLINK 1 +#define P_MMPLL1 2 +#define P_HDMIPLL 2 +#define P_GPLL0 3 +#define P_EDPVCO 3 +#define P_GPLL1 4 +#define P_DSI0PLL 4 +#define P_MMPLL2 4 +#define P_MMPLL3 4 +#define P_DSI1PLL 5 + +static const u8 mmcc_xo_mmpll0_mmpll1_gpll0_map[] = { + [P_XO] = 0, + [P_MMPLL0] = 1, + [P_MMPLL1] = 2, + [P_GPLL0] = 5, +}; + +static const char *mmcc_xo_mmpll0_mmpll1_gpll0[] = { + "xo", + "mmpll0_vote", + "mmpll1_vote", + "mmss_gpll0_vote", +}; + +static const u8 mmcc_xo_mmpll0_dsi_hdmi_gpll0_map[] = { + [P_XO] = 0, + [P_MMPLL0] = 1, + [P_HDMIPLL] = 4, + [P_GPLL0] = 5, + [P_DSI0PLL] = 2, + [P_DSI1PLL] = 3, +}; + +static const char *mmcc_xo_mmpll0_dsi_hdmi_gpll0[] = { + "xo", + "mmpll0_vote", + "hdmipll", + "mmss_gpll0_vote", + "dsi0pll", + "dsi1pll", +}; + +static const u8 mmcc_xo_mmpll0_1_2_gpll0_map[] = { + [P_XO] = 0, + [P_MMPLL0] = 1, + [P_MMPLL1] = 2, + [P_GPLL0] = 5, + [P_MMPLL2] = 3, +}; + +static const char *mmcc_xo_mmpll0_1_2_gpll0[] = { + "xo", + "mmpll0_vote", + "mmpll1_vote", + "mmss_gpll0_vote", + "mmpll2", +}; + +static const u8 mmcc_xo_mmpll0_1_3_gpll0_map[] = { + [P_XO] = 0, + [P_MMPLL0] = 1, + [P_MMPLL1] = 2, + [P_GPLL0] = 5, + [P_MMPLL3] = 3, +}; + +static const char *mmcc_xo_mmpll0_1_3_gpll0[] = { + "xo", + "mmpll0_vote", + "mmpll1_vote", + "mmss_gpll0_vote", + "mmpll3", +}; + +static const u8 mmcc_xo_mmpll0_1_gpll1_0_map[] = { + [P_XO] = 0, + [P_MMPLL0] = 1, + [P_MMPLL1] = 2, + [P_GPLL0] = 5, + [P_GPLL1] = 4, +}; + +static const char *mmcc_xo_mmpll0_1_gpll1_0[] = { + "xo", + "mmpll0_vote", + "mmpll1_vote", + "mmss_gpll0_vote", + "gpll1_vote", +}; + +static const u8 mmcc_xo_dsi_hdmi_edp_map[] = { + [P_XO] = 0, + [P_EDPLINK] = 4, + [P_HDMIPLL] = 3, + [P_EDPVCO] = 5, + [P_DSI0PLL] = 1, + [P_DSI1PLL] = 2, +}; + +static const char *mmcc_xo_dsi_hdmi_edp[] = { + "xo", + "edp_link_clk", + "hdmipll", + "edp_vco_div", + "dsi0pll", + "dsi1pll", +}; + +static const u8 mmcc_xo_dsi_hdmi_edp_gpll0_map[] = { + [P_XO] = 0, + [P_EDPLINK] = 4, + [P_HDMIPLL] = 3, + [P_GPLL0] = 5, + [P_DSI0PLL] = 1, + [P_DSI1PLL] = 2, +}; + +static const char *mmcc_xo_dsi_hdmi_edp_gpll0[] = { + "xo", + "edp_link_clk", + "hdmipll", + "gpll0_vote", + "dsi0pll", + "dsi1pll", +}; + +#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } + +static struct clk_pll mmpll0 = { + .l_reg = 0x0004, + .m_reg = 0x0008, + .n_reg = 0x000c, + .config_reg = 0x0014, + .mode_reg = 0x0000, + .status_reg = 0x001c, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll0", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_pll_ops, + }, +}; + +static struct clk_regmap mmpll0_vote = { + .enable_reg = 0x0100, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmpll0_vote", + .parent_names = (const char *[]){ "mmpll0" }, + .num_parents = 1, + .ops = &clk_pll_vote_ops, + }, +}; + +static struct clk_pll mmpll1 = { + .l_reg = 0x0044, + .m_reg = 0x0048, + .n_reg = 0x004c, + .config_reg = 0x0054, + .mode_reg = 0x0040, + .status_reg = 0x005c, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll1", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_pll_ops, + }, +}; + +static struct clk_regmap mmpll1_vote = { + .enable_reg = 0x0100, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "mmpll1_vote", + .parent_names = (const char *[]){ "mmpll1" }, + .num_parents = 1, + .ops = &clk_pll_vote_ops, + }, +}; + +static struct clk_pll mmpll2 = { + .l_reg = 0x4104, + .m_reg = 0x4108, + .n_reg = 0x410c, + .config_reg = 0x4114, + .mode_reg = 0x4100, + .status_reg = 0x411c, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll2", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_pll_ops, + }, +}; + +static struct clk_pll mmpll3 = { + .l_reg = 0x0084, + .m_reg = 0x0088, + .n_reg = 0x008c, + .config_reg = 0x0094, + .mode_reg = 0x0080, + .status_reg = 0x009c, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll3", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_pll_ops, + }, +}; + +static struct clk_rcg2 mmss_ahb_clk_src = { + .cmd_rcgr = 0x5000, + .hid_width = 5, + .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmss_ahb_clk_src", + .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct freq_tbl ftbl_mmss_axi_clk[] = { + 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), + F(150000000, P_GPLL0, 4, 0, 0), + F(291750000, P_MMPLL1, 4, 0, 0), + F(400000000, P_MMPLL0, 2, 0, 0), + F(466800000, P_MMPLL1, 2.5, 0, 0), +}; + +static struct clk_rcg2 mmss_axi_clk_src = { + .cmd_rcgr = 0x5040, + .hid_width = 5, + .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map, + .freq_tbl = ftbl_mmss_axi_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmss_axi_clk_src", + .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct freq_tbl ftbl_ocmemnoc_clk[] = { + 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), + F(150000000, P_GPLL0, 4, 0, 0), + F(291750000, P_MMPLL1, 4, 0, 0), + F(400000000, P_MMPLL0, 2, 0, 0), +}; + +static struct clk_rcg2 ocmemnoc_clk_src = { + .cmd_rcgr = 0x5090, + .hid_width = 5, + .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map, + .freq_tbl = ftbl_ocmemnoc_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "ocmemnoc_clk_src", + .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct freq_tbl ftbl_camss_csi0_3_clk[] = { + F(100000000, P_GPLL0, 6, 0, 0), + F(200000000, P_MMPLL0, 4, 0, 0), + { } +}; + +static struct clk_rcg2 csi0_clk_src = { + .cmd_rcgr = 0x3090, + .hid_width = 5, + .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map, + .freq_tbl = ftbl_camss_csi0_3_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi0_clk_src", + .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 csi1_clk_src = { + .cmd_rcgr = 0x3100, + .hid_width = 5, + .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map, + .freq_tbl = ftbl_camss_csi0_3_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi1_clk_src", + .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 csi2_clk_src = { + .cmd_rcgr = 0x3160, + .hid_width = 5, + .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map, + .freq_tbl = ftbl_camss_csi0_3_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi2_clk_src", + .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 csi3_clk_src = { + .cmd_rcgr = 0x31c0, + .hid_width = 5, + .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map, + .freq_tbl = ftbl_camss_csi0_3_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi3_clk_src", + .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct freq_tbl ftbl_camss_vfe_vfe0_1_clk[] = { + F(37500000, P_GPLL0, 16, 0, 0), + F(50000000, P_GPLL0, 12, 0, 0), + F(60000000, P_GPLL0, 10, 0, 0), + F(80000000, P_GPLL0, 7.5, 0, 0), + F(100000000, P_GPLL0, 6, 0, 0), + F(109090000, P_GPLL0, 5.5, 0, 0), + F(133330000, P_GPLL0, 4.5, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + F(228570000, P_MMPLL0, 3.5, 0, 0), + F(266670000, P_MMPLL0, 3, 0, 0), + F(320000000, P_MMPLL0, 2.5, 0, 0), + F(400000000, P_MMPLL0, 2, 0, 0), + F(465000000, P_MMPLL3, 2, 0, 0), + { } +}; + +static struct clk_rcg2 vfe0_clk_src = { + .cmd_rcgr = 0x3600, + .hid_width = 5, + .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map, + .freq_tbl = ftbl_camss_vfe_vfe0_1_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "vfe0_clk_src", + .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 vfe1_clk_src = { + .cmd_rcgr = 0x3620, + .hid_width = 5, + .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map, + .freq_tbl = ftbl_camss_vfe_vfe0_1_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "vfe1_clk_src", + .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct freq_tbl ftbl_mdss_mdp_clk[] = { + F(37500000, P_GPLL0, 16, 0, 0), + F(60000000, P_GPLL0, 10, 0, 0), + F(75000000, P_GPLL0, 8, 0, 0), + F(85710000, P_GPLL0, 7, 0, 0), + F(100000000, P_GPLL0, 6, 0, 0), + F(133330000, P_MMPLL0, 6, 0, 0), + F(160000000, P_MMPLL0, 5, 0, 0), + F(200000000, P_MMPLL0, 4, 0, 0), + F(228570000, P_MMPLL0, 3.5, 0, 0), + F(240000000, P_GPLL0, 2.5, 0, 0), + F(266670000, P_MMPLL0, 3, 0, 0), + F(320000000, P_MMPLL0, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 mdp_clk_src = { + .cmd_rcgr = 0x2040, + .hid_width = 5, + .parent_map = mmcc_xo_mmpll0_dsi_hdmi_gpll0_map, + .freq_tbl = ftbl_mdss_mdp_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mdp_clk_src", + .parent_names = mmcc_xo_mmpll0_dsi_hdmi_gpll0, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gfx3d_clk_src = { + .cmd_rcgr = 0x4000, + .hid_width = 5, + .parent_map = mmcc_xo_mmpll0_1_2_gpll0_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gfx3d_clk_src", + .parent_names = mmcc_xo_mmpll0_1_2_gpll0, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct freq_tbl ftbl_camss_jpeg_jpeg0_2_clk[] = { + F(75000000, P_GPLL0, 8, 0, 0), + F(133330000, P_GPLL0, 4.5, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + F(228570000, P_MMPLL0, 3.5, 0, 0), + F(266670000, P_MMPLL0, 3, 0, 0), + F(320000000, P_MMPLL0, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 jpeg0_clk_src = { + .cmd_rcgr = 0x3500, + .hid_width = 5, + .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map, + .freq_tbl = ftbl_camss_jpeg_jpeg0_2_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "jpeg0_clk_src", + .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 jpeg1_clk_src = { + .cmd_rcgr = 0x3520, + .hid_width = 5, + .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map, + .freq_tbl = ftbl_camss_jpeg_jpeg0_2_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "jpeg1_clk_src", + .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 jpeg2_clk_src = { + .cmd_rcgr = 0x3540, + .hid_width = 5, + .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map, + .freq_tbl = ftbl_camss_jpeg_jpeg0_2_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "jpeg2_clk_src", + .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct freq_tbl ftbl_mdss_pclk0_clk[] = { + F(125000000, P_DSI0PLL, 2, 0, 0), + F(250000000, P_DSI0PLL, 1, 0, 0), + { } +}; + +static struct freq_tbl ftbl_mdss_pclk1_clk[] = { + F(125000000, P_DSI1PLL, 2, 0, 0), + F(250000000, P_DSI1PLL, 1, 0, 0), + { } +}; + +static struct clk_rcg2 pclk0_clk_src = { + .cmd_rcgr = 0x2000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map, + .freq_tbl = ftbl_mdss_pclk0_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pclk0_clk_src", + .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 pclk1_clk_src = { + .cmd_rcgr = 0x2020, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map, + .freq_tbl = ftbl_mdss_pclk1_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pclk1_clk_src", + .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +static struct freq_tbl ftbl_venus0_vcodec0_clk[] = { + F(50000000, P_GPLL0, 12, 0, 0), + F(100000000, P_GPLL0, 6, 0, 0), + F(133330000, P_MMPLL0, 6, 0, 0), + F(200000000, P_MMPLL0, 4, 0, 0), + F(266670000, P_MMPLL0, 3, 0, 0), + F(465000000, P_MMPLL3, 2, 0, 0), + { } +}; + +static struct clk_rcg2 vcodec0_clk_src = { + .cmd_rcgr = 0x1000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmcc_xo_mmpll0_1_3_gpll0_map, + .freq_tbl = ftbl_venus0_vcodec0_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "vcodec0_clk_src", + .parent_names = mmcc_xo_mmpll0_1_3_gpll0, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct freq_tbl ftbl_camss_cci_cci_clk[] = { + F(19200000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cci_clk_src = { + .cmd_rcgr = 0x3300, + .hid_width = 5, + .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map, + .freq_tbl = ftbl_camss_cci_cci_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cci_clk_src", + .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct freq_tbl ftbl_camss_gp0_1_clk[] = { + F(10000, P_XO, 16, 1, 120), + F(24000, P_XO, 16, 1, 50), + F(6000000, P_GPLL0, 10, 1, 10), + F(12000000, P_GPLL0, 10, 1, 5), + F(13000000, P_GPLL0, 4, 13, 150), + F(24000000, P_GPLL0, 5, 1, 5), + { } +}; + +static struct clk_rcg2 camss_gp0_clk_src = { + .cmd_rcgr = 0x3420, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmcc_xo_mmpll0_1_gpll1_0_map, + .freq_tbl = ftbl_camss_gp0_1_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "camss_gp0_clk_src", + .parent_names = mmcc_xo_mmpll0_1_gpll1_0, + .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 = mmcc_xo_mmpll0_1_gpll1_0_map, + .freq_tbl = ftbl_camss_gp0_1_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "camss_gp1_clk_src", + .parent_names = mmcc_xo_mmpll0_1_gpll1_0, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct freq_tbl ftbl_camss_mclk0_3_clk[] = { + F(4800000, P_XO, 4, 0, 0), + F(6000000, P_GPLL0, 10, 1, 10), + F(8000000, P_GPLL0, 15, 1, 5), + F(9600000, P_XO, 2, 0, 0), + F(16000000, P_GPLL0, 12.5, 1, 3), + F(19200000, P_XO, 1, 0, 0), + F(24000000, P_GPLL0, 5, 1, 5), + F(32000000, P_MMPLL0, 5, 1, 5), + F(48000000, P_GPLL0, 12.5, 0, 0), + F(64000000, P_MMPLL0, 12.5, 0, 0), + F(66670000, P_GPLL0, 9, 0, 0), + { } +}; + +static struct clk_rcg2 mclk0_clk_src = { + .cmd_rcgr = 0x3360, + .hid_width = 5, + .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map, + .freq_tbl = ftbl_camss_mclk0_3_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mclk0_clk_src", + .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 mclk1_clk_src = { + .cmd_rcgr = 0x3390, + .hid_width = 5, + .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map, + .freq_tbl = ftbl_camss_mclk0_3_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mclk1_clk_src", + .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 mclk2_clk_src = { + .cmd_rcgr = 0x33c0, + .hid_width = 5, + .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map, + .freq_tbl = ftbl_camss_mclk0_3_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mclk2_clk_src", + .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 mclk3_clk_src = { + .cmd_rcgr = 0x33f0, + .hid_width = 5, + .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map, + .freq_tbl = ftbl_camss_mclk0_3_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mclk3_clk_src", + .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct freq_tbl ftbl_camss_phy0_2_csi0_2phytimer_clk[] = { + F(100000000, P_GPLL0, 6, 0, 0), + F(200000000, P_MMPLL0, 4, 0, 0), + { } +}; + +static struct clk_rcg2 csi0phytimer_clk_src = { + .cmd_rcgr = 0x3000, + .hid_width = 5, + .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map, + .freq_tbl = ftbl_camss_phy0_2_csi0_2phytimer_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi0phytimer_clk_src", + .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 csi1phytimer_clk_src = { + .cmd_rcgr = 0x3030, + .hid_width = 5, + .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map, + .freq_tbl = ftbl_camss_phy0_2_csi0_2phytimer_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi1phytimer_clk_src", + .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 csi2phytimer_clk_src = { + .cmd_rcgr = 0x3060, + .hid_width = 5, + .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map, + .freq_tbl = ftbl_camss_phy0_2_csi0_2phytimer_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi2phytimer_clk_src", + .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct freq_tbl ftbl_camss_vfe_cpp_clk[] = { + F(133330000, P_GPLL0, 4.5, 0, 0), + F(266670000, P_MMPLL0, 3, 0, 0), + F(320000000, P_MMPLL0, 2.5, 0, 0), + F(400000000, P_MMPLL0, 2, 0, 0), + F(465000000, P_MMPLL3, 2, 0, 0), + { } +}; + +static struct clk_rcg2 cpp_clk_src = { + .cmd_rcgr = 0x3640, + .hid_width = 5, + .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map, + .freq_tbl = ftbl_camss_vfe_cpp_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cpp_clk_src", + .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct freq_tbl ftbl_mdss_byte0_clk[] = { + F(93750000, P_DSI0PLL, 8, 0, 0), + F(187500000, P_DSI0PLL, 4, 0, 0), + { } +}; + +static struct freq_tbl ftbl_mdss_byte1_clk[] = { + F(93750000, P_DSI1PLL, 8, 0, 0), + F(187500000, P_DSI1PLL, 4, 0, 0), + { } +}; + +static struct clk_rcg2 byte0_clk_src = { + .cmd_rcgr = 0x2120, + .hid_width = 5, + .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map, + .freq_tbl = ftbl_mdss_byte0_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "byte0_clk_src", + .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 byte1_clk_src = { + .cmd_rcgr = 0x2140, + .hid_width = 5, + .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map, + .freq_tbl = ftbl_mdss_byte1_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "byte1_clk_src", + .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +static struct freq_tbl ftbl_mdss_edpaux_clk[] = { + F(19200000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 edpaux_clk_src = { + .cmd_rcgr = 0x20e0, + .hid_width = 5, + .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map, + .freq_tbl = ftbl_mdss_edpaux_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "edpaux_clk_src", + .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct freq_tbl ftbl_mdss_edplink_clk[] = { + F(135000000, P_EDPLINK, 2, 0, 0), + F(270000000, P_EDPLINK, 11, 0, 0), + { } +}; + +static struct clk_rcg2 edplink_clk_src = { + .cmd_rcgr = 0x20c0, + .hid_width = 5, + .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map, + .freq_tbl = ftbl_mdss_edplink_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "edplink_clk_src", + .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +static struct freq_tbl ftbl_mdss_edppixel_clk[] = { + F(175000000, P_EDPVCO, 2, 0, 0), + F(350000000, P_EDPVCO, 11, 0, 0), + { } +}; + +static struct clk_rcg2 edppixel_clk_src = { + .cmd_rcgr = 0x20a0, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmcc_xo_dsi_hdmi_edp_map, + .freq_tbl = ftbl_mdss_edppixel_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "edppixel_clk_src", + .parent_names = mmcc_xo_dsi_hdmi_edp, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +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 = mmcc_xo_dsi_hdmi_edp_gpll0_map, + .freq_tbl = ftbl_mdss_esc0_1_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "esc0_clk_src", + .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 esc1_clk_src = { + .cmd_rcgr = 0x2180, + .hid_width = 5, + .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map, + .freq_tbl = ftbl_mdss_esc0_1_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "esc1_clk_src", + .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +static struct freq_tbl ftbl_mdss_extpclk_clk[] = { + F(25200000, P_HDMIPLL, 1, 0, 0), + F(27000000, P_HDMIPLL, 1, 0, 0), + F(27030000, P_HDMIPLL, 1, 0, 0), + F(65000000, P_HDMIPLL, 1, 0, 0), + F(74250000, P_HDMIPLL, 1, 0, 0), + F(108000000, P_HDMIPLL, 1, 0, 0), + F(148500000, P_HDMIPLL, 1, 0, 0), + F(268500000, P_HDMIPLL, 1, 0, 0), + F(297000000, P_HDMIPLL, 1, 0, 0), + { } +}; + +static struct clk_rcg2 extpclk_clk_src = { + .cmd_rcgr = 0x2060, + .hid_width = 5, + .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map, + .freq_tbl = ftbl_mdss_extpclk_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "extpclk_clk_src", + .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, + .num_parents = 6, + .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 = mmcc_xo_mmpll0_mmpll1_gpll0_map, + .freq_tbl = ftbl_mdss_hdmi_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "hdmi_clk_src", + .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +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 = mmcc_xo_mmpll0_mmpll1_gpll0_map, + .freq_tbl = ftbl_mdss_vsync_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "vsync_clk_src", + .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch camss_cci_cci_ahb_clk = { + .halt_reg = 0x3348, + .clkr = { + .enable_reg = 0x3348, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_cci_cci_ahb_clk", + .parent_names = (const char *[]){ + "mmss_ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_cci_cci_clk = { + .halt_reg = 0x3344, + .clkr = { + .enable_reg = 0x3344, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_cci_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_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 *[]){ + "mmss_ahb_clk_src", + }, + .num_parents = 1, + .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_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_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_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_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 *[]){ + "mmss_ahb_clk_src", + }, + .num_parents = 1, + .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_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_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_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_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 *[]){ + "mmss_ahb_clk_src", + }, + .num_parents = 1, + .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_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_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_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_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 *[]){ + "mmss_ahb_clk_src", + }, + .num_parents = 1, + .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_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_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_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_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_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_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 *[]){ + "mmss_ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_jpeg_jpeg0_clk = { + .halt_reg = 0x35a8, + .clkr = { + .enable_reg = 0x35a8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_jpeg_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_jpeg_jpeg1_clk = { + .halt_reg = 0x35ac, + .clkr = { + .enable_reg = 0x35ac, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_jpeg_jpeg1_clk", + .parent_names = (const char *[]){ + "jpeg1_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_jpeg_jpeg2_clk = { + .halt_reg = 0x35b0, + .clkr = { + .enable_reg = 0x35b0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_jpeg_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_jpeg_ahb_clk = { + .halt_reg = 0x35b4, + .clkr = { + .enable_reg = 0x35b4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_jpeg_jpeg_ahb_clk", + .parent_names = (const char *[]){ + "mmss_ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_jpeg_jpeg_axi_clk = { + .halt_reg = 0x35b8, + .clkr = { + .enable_reg = 0x35b8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_jpeg_jpeg_axi_clk", + .parent_names = (const char *[]){ + "mmss_axi_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_jpeg_jpeg_ocmemnoc_clk = { + .halt_reg = 0x35bc, + .clkr = { + .enable_reg = 0x35bc, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_jpeg_jpeg_ocmemnoc_clk", + .parent_names = (const char *[]){ + "ocmemnoc_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_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 *[]){ + "mmss_ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_phy0_csi0phytimer_clk = { + .halt_reg = 0x3024, + .clkr = { + .enable_reg = 0x3024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_phy0_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_phy1_csi1phytimer_clk = { + .halt_reg = 0x3054, + .clkr = { + .enable_reg = 0x3054, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_phy1_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_phy2_csi2phytimer_clk = { + .halt_reg = 0x3084, + .clkr = { + .enable_reg = 0x3084, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_phy2_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_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 *[]){ + "mmss_ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_vfe_cpp_ahb_clk = { + .halt_reg = 0x36b4, + .clkr = { + .enable_reg = 0x36b4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_vfe_cpp_ahb_clk", + .parent_names = (const char *[]){ + "mmss_ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_vfe_cpp_clk = { + .halt_reg = 0x36b0, + .clkr = { + .enable_reg = 0x36b0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_vfe_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_vfe_vfe0_clk = { + .halt_reg = 0x36a8, + .clkr = { + .enable_reg = 0x36a8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_vfe_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_vfe_vfe1_clk = { + .halt_reg = 0x36ac, + .clkr = { + .enable_reg = 0x36ac, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_vfe_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_vfe_vfe_ahb_clk = { + .halt_reg = 0x36b8, + .clkr = { + .enable_reg = 0x36b8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_vfe_vfe_ahb_clk", + .parent_names = (const char *[]){ + "mmss_ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_vfe_vfe_axi_clk = { + .halt_reg = 0x36bc, + .clkr = { + .enable_reg = 0x36bc, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_vfe_vfe_axi_clk", + .parent_names = (const char *[]){ + "mmss_axi_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_vfe_vfe_ocmemnoc_clk = { + .halt_reg = 0x36c0, + .clkr = { + .enable_reg = 0x36c0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_vfe_vfe_ocmemnoc_clk", + .parent_names = (const char *[]){ + "ocmemnoc_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 *[]){ + "mmss_ahb_clk_src", + }, + .num_parents = 1, + .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 *[]){ + "mmss_axi_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_edpaux_clk = { + .halt_reg = 0x2334, + .clkr = { + .enable_reg = 0x2334, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_edpaux_clk", + .parent_names = (const char *[]){ + "edpaux_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_edplink_clk = { + .halt_reg = 0x2330, + .clkr = { + .enable_reg = 0x2330, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_edplink_clk", + .parent_names = (const char *[]){ + "edplink_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_edppixel_clk = { + .halt_reg = 0x232c, + .clkr = { + .enable_reg = 0x232c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_edppixel_clk", + .parent_names = (const char *[]){ + "edppixel_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 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_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 *[]){ + "mmss_ahb_clk_src", + }, + .num_parents = 1, + .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_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_mdp_lut_clk = { + .halt_reg = 0x2320, + .clkr = { + .enable_reg = 0x2320, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_mdp_lut_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_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_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 mmss_misc_ahb_clk = { + .halt_reg = 0x502c, + .clkr = { + .enable_reg = 0x502c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_misc_ahb_clk", + .parent_names = (const char *[]){ + "mmss_ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_mmssnoc_ahb_clk = { + .halt_reg = 0x5024, + .clkr = { + .enable_reg = 0x5024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mmssnoc_ahb_clk", + .parent_names = (const char *[]){ + "mmss_ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_IGNORE_UNUSED, + }, + }, +}; + +static struct clk_branch mmss_mmssnoc_bto_ahb_clk = { + .halt_reg = 0x5028, + .clkr = { + .enable_reg = 0x5028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mmssnoc_bto_ahb_clk", + .parent_names = (const char *[]){ + "mmss_ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_IGNORE_UNUSED, + }, + }, +}; + +static struct clk_branch mmss_mmssnoc_axi_clk = { + .halt_reg = 0x506c, + .clkr = { + .enable_reg = 0x506c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mmssnoc_axi_clk", + .parent_names = (const char *[]){ + "mmss_axi_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_s0_axi_clk = { + .halt_reg = 0x5064, + .clkr = { + .enable_reg = 0x5064, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_s0_axi_clk", + .parent_names = (const char *[]){ + "mmss_axi_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_IGNORE_UNUSED, + }, + }, +}; + +static struct clk_branch ocmemcx_ahb_clk = { + .halt_reg = 0x405c, + .clkr = { + .enable_reg = 0x405c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "ocmemcx_ahb_clk", + .parent_names = (const char *[]){ + "mmss_ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch ocmemcx_ocmemnoc_clk = { + .halt_reg = 0x4058, + .clkr = { + .enable_reg = 0x4058, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "ocmemcx_ocmemnoc_clk", + .parent_names = (const char *[]){ + "ocmemnoc_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch oxili_ocmemgx_clk = { + .halt_reg = 0x402c, + .clkr = { + .enable_reg = 0x402c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "oxili_ocmemgx_clk", + .parent_names = (const char *[]){ + "gfx3d_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch ocmemnoc_clk = { + .halt_reg = 0x50b4, + .clkr = { + .enable_reg = 0x50b4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "ocmemnoc_clk", + .parent_names = (const char *[]){ + "ocmemnoc_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch oxili_gfx3d_clk = { + .halt_reg = 0x4028, + .clkr = { + .enable_reg = 0x4028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "oxili_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 oxilicx_ahb_clk = { + .halt_reg = 0x403c, + .clkr = { + .enable_reg = 0x403c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "oxilicx_ahb_clk", + .parent_names = (const char *[]){ + "mmss_ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch oxilicx_axi_clk = { + .halt_reg = 0x4038, + .clkr = { + .enable_reg = 0x4038, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "oxilicx_axi_clk", + .parent_names = (const char *[]){ + "mmss_axi_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch venus0_ahb_clk = { + .halt_reg = 0x1030, + .clkr = { + .enable_reg = 0x1030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "venus0_ahb_clk", + .parent_names = (const char *[]){ + "mmss_ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch venus0_axi_clk = { + .halt_reg = 0x1034, + .clkr = { + .enable_reg = 0x1034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "venus0_axi_clk", + .parent_names = (const char *[]){ + "mmss_axi_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch venus0_ocmemnoc_clk = { + .halt_reg = 0x1038, + .clkr = { + .enable_reg = 0x1038, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "venus0_ocmemnoc_clk", + .parent_names = (const char *[]){ + "ocmemnoc_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch venus0_vcodec0_clk = { + .halt_reg = 0x1028, + .clkr = { + .enable_reg = 0x1028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "venus0_vcodec0_clk", + .parent_names = (const char *[]){ + "vcodec0_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static const struct pll_config mmpll1_config = { + .l = 60, + .m = 25, + .n = 32, + .vco_val = 0x0, + .vco_mask = 0x3 << 20, + .pre_div_val = 0x0, + .pre_div_mask = 0x3 << 12, + .post_div_val = 0x0, + .post_div_mask = 0x3 << 8, + .mn_ena_mask = BIT(24), + .main_output_mask = BIT(0), +}; + +static struct pll_config mmpll3_config = { + .l = 48, + .m = 7, + .n = 16, + .vco_val = 0x0, + .vco_mask = 0x3 << 20, + .pre_div_val = 0x0, + .pre_div_mask = 0x3 << 12, + .post_div_val = 0x0, + .post_div_mask = 0x3 << 8, + .mn_ena_mask = BIT(24), + .main_output_mask = BIT(0), + .aux_output_mask = BIT(1), +}; + +static struct clk_regmap *mmcc_msm8974_clocks[] = { + [MMSS_AHB_CLK_SRC] = &mmss_ahb_clk_src.clkr, + [MMSS_AXI_CLK_SRC] = &mmss_axi_clk_src.clkr, + [OCMEMNOC_CLK_SRC] = &ocmemnoc_clk_src.clkr, + [MMPLL0] = &mmpll0.clkr, + [MMPLL0_VOTE] = &mmpll0_vote, + [MMPLL1] = &mmpll1.clkr, + [MMPLL1_VOTE] = &mmpll1_vote, + [MMPLL2] = &mmpll2.clkr, + [MMPLL3] = &mmpll3.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, + [VFE0_CLK_SRC] = &vfe0_clk_src.clkr, + [VFE1_CLK_SRC] = &vfe1_clk_src.clkr, + [MDP_CLK_SRC] = &mdp_clk_src.clkr, + [GFX3D_CLK_SRC] = &gfx3d_clk_src.clkr, + [JPEG0_CLK_SRC] = &jpeg0_clk_src.clkr, + [JPEG1_CLK_SRC] = &jpeg1_clk_src.clkr, + [JPEG2_CLK_SRC] = &jpeg2_clk_src.clkr, + [PCLK0_CLK_SRC] = &pclk0_clk_src.clkr, + [PCLK1_CLK_SRC] = &pclk1_clk_src.clkr, + [VCODEC0_CLK_SRC] = &vcodec0_clk_src.clkr, + [CCI_CLK_SRC] = &cci_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, + [CSI0PHYTIMER_CLK_SRC] = &csi0phytimer_clk_src.clkr, + [CSI1PHYTIMER_CLK_SRC] = &csi1phytimer_clk_src.clkr, + [CSI2PHYTIMER_CLK_SRC] = &csi2phytimer_clk_src.clkr, + [CPP_CLK_SRC] = &cpp_clk_src.clkr, + [BYTE0_CLK_SRC] = &byte0_clk_src.clkr, + [BYTE1_CLK_SRC] = &byte1_clk_src.clkr, + [EDPAUX_CLK_SRC] = &edpaux_clk_src.clkr, + [EDPLINK_CLK_SRC] = &edplink_clk_src.clkr, + [EDPPIXEL_CLK_SRC] = &edppixel_clk_src.clkr, + [ESC0_CLK_SRC] = &esc0_clk_src.clkr, + [ESC1_CLK_SRC] = &esc1_clk_src.clkr, + [EXTPCLK_CLK_SRC] = &extpclk_clk_src.clkr, + [HDMI_CLK_SRC] = &hdmi_clk_src.clkr, + [VSYNC_CLK_SRC] = &vsync_clk_src.clkr, + [CAMSS_CCI_CCI_AHB_CLK] = &camss_cci_cci_ahb_clk.clkr, + [CAMSS_CCI_CCI_CLK] = &camss_cci_cci_clk.clkr, + [CAMSS_CSI0_AHB_CLK] = &camss_csi0_ahb_clk.clkr, + [CAMSS_CSI0_CLK] = &camss_csi0_clk.clkr, + [CAMSS_CSI0PHY_CLK] = &camss_csi0phy_clk.clkr, + [CAMSS_CSI0PIX_CLK] = &camss_csi0pix_clk.clkr, + [CAMSS_CSI0RDI_CLK] = &camss_csi0rdi_clk.clkr, + [CAMSS_CSI1_AHB_CLK] = &camss_csi1_ahb_clk.clkr, + [CAMSS_CSI1_CLK] = &camss_csi1_clk.clkr, + [CAMSS_CSI1PHY_CLK] = &camss_csi1phy_clk.clkr, + [CAMSS_CSI1PIX_CLK] = &camss_csi1pix_clk.clkr, + [CAMSS_CSI1RDI_CLK] = &camss_csi1rdi_clk.clkr, + [CAMSS_CSI2_AHB_CLK] = &camss_csi2_ahb_clk.clkr, + [CAMSS_CSI2_CLK] = &camss_csi2_clk.clkr, + [CAMSS_CSI2PHY_CLK] = &camss_csi2phy_clk.clkr, + [CAMSS_CSI2PIX_CLK] = &camss_csi2pix_clk.clkr, + [CAMSS_CSI2RDI_CLK] = &camss_csi2rdi_clk.clkr, + [CAMSS_CSI3_AHB_CLK] = &camss_csi3_ahb_clk.clkr, + [CAMSS_CSI3_CLK] = &camss_csi3_clk.clkr, + [CAMSS_CSI3PHY_CLK] = &camss_csi3phy_clk.clkr, + [CAMSS_CSI3PIX_CLK] = &camss_csi3pix_clk.clkr, + [CAMSS_CSI3RDI_CLK] = &camss_csi3rdi_clk.clkr, + [CAMSS_CSI_VFE0_CLK] = &camss_csi_vfe0_clk.clkr, + [CAMSS_CSI_VFE1_CLK] = &camss_csi_vfe1_clk.clkr, + [CAMSS_GP0_CLK] = &camss_gp0_clk.clkr, + [CAMSS_GP1_CLK] = &camss_gp1_clk.clkr, + [CAMSS_ISPIF_AHB_CLK] = &camss_ispif_ahb_clk.clkr, + [CAMSS_JPEG_JPEG0_CLK] = &camss_jpeg_jpeg0_clk.clkr, + [CAMSS_JPEG_JPEG1_CLK] = &camss_jpeg_jpeg1_clk.clkr, + [CAMSS_JPEG_JPEG2_CLK] = &camss_jpeg_jpeg2_clk.clkr, + [CAMSS_JPEG_JPEG_AHB_CLK] = &camss_jpeg_jpeg_ahb_clk.clkr, + [CAMSS_JPEG_JPEG_AXI_CLK] = &camss_jpeg_jpeg_axi_clk.clkr, + [CAMSS_JPEG_JPEG_OCMEMNOC_CLK] = &camss_jpeg_jpeg_ocmemnoc_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_MICRO_AHB_CLK] = &camss_micro_ahb_clk.clkr, + [CAMSS_PHY0_CSI0PHYTIMER_CLK] = &camss_phy0_csi0phytimer_clk.clkr, + [CAMSS_PHY1_CSI1PHYTIMER_CLK] = &camss_phy1_csi1phytimer_clk.clkr, + [CAMSS_PHY2_CSI2PHYTIMER_CLK] = &camss_phy2_csi2phytimer_clk.clkr, + [CAMSS_TOP_AHB_CLK] = &camss_top_ahb_clk.clkr, + [CAMSS_VFE_CPP_AHB_CLK] = &camss_vfe_cpp_ahb_clk.clkr, + [CAMSS_VFE_CPP_CLK] = &camss_vfe_cpp_clk.clkr, + [CAMSS_VFE_VFE0_CLK] = &camss_vfe_vfe0_clk.clkr, + [CAMSS_VFE_VFE1_CLK] = &camss_vfe_vfe1_clk.clkr, + [CAMSS_VFE_VFE_AHB_CLK] = &camss_vfe_vfe_ahb_clk.clkr, + [CAMSS_VFE_VFE_AXI_CLK] = &camss_vfe_vfe_axi_clk.clkr, + [CAMSS_VFE_VFE_OCMEMNOC_CLK] = &camss_vfe_vfe_ocmemnoc_clk.clkr, + [MDSS_AHB_CLK] = &mdss_ahb_clk.clkr, + [MDSS_AXI_CLK] = &mdss_axi_clk.clkr, + [MDSS_BYTE0_CLK] = &mdss_byte0_clk.clkr, + [MDSS_BYTE1_CLK] = &mdss_byte1_clk.clkr, + [MDSS_EDPAUX_CLK] = &mdss_edpaux_clk.clkr, + [MDSS_EDPLINK_CLK] = &mdss_edplink_clk.clkr, + [MDSS_EDPPIXEL_CLK] = &mdss_edppixel_clk.clkr, + [MDSS_ESC0_CLK] = &mdss_esc0_clk.clkr, + [MDSS_ESC1_CLK] = &mdss_esc1_clk.clkr, + [MDSS_EXTPCLK_CLK] = &mdss_extpclk_clk.clkr, + [MDSS_HDMI_AHB_CLK] = &mdss_hdmi_ahb_clk.clkr, + [MDSS_HDMI_CLK] = &mdss_hdmi_clk.clkr, + [MDSS_MDP_CLK] = &mdss_mdp_clk.clkr, + [MDSS_MDP_LUT_CLK] = &mdss_mdp_lut_clk.clkr, + [MDSS_PCLK0_CLK] = &mdss_pclk0_clk.clkr, + [MDSS_PCLK1_CLK] = &mdss_pclk1_clk.clkr, + [MDSS_VSYNC_CLK] = &mdss_vsync_clk.clkr, + [MMSS_MISC_AHB_CLK] = &mmss_misc_ahb_clk.clkr, + [MMSS_MMSSNOC_AHB_CLK] = &mmss_mmssnoc_ahb_clk.clkr, + [MMSS_MMSSNOC_BTO_AHB_CLK] = &mmss_mmssnoc_bto_ahb_clk.clkr, + [MMSS_MMSSNOC_AXI_CLK] = &mmss_mmssnoc_axi_clk.clkr, + [MMSS_S0_AXI_CLK] = &mmss_s0_axi_clk.clkr, + [OCMEMCX_AHB_CLK] = &ocmemcx_ahb_clk.clkr, + [OCMEMCX_OCMEMNOC_CLK] = &ocmemcx_ocmemnoc_clk.clkr, + [OXILI_OCMEMGX_CLK] = &oxili_ocmemgx_clk.clkr, + [OCMEMNOC_CLK] = &ocmemnoc_clk.clkr, + [OXILI_GFX3D_CLK] = &oxili_gfx3d_clk.clkr, + [OXILICX_AHB_CLK] = &oxilicx_ahb_clk.clkr, + [OXILICX_AXI_CLK] = &oxilicx_axi_clk.clkr, + [VENUS0_AHB_CLK] = &venus0_ahb_clk.clkr, + [VENUS0_AXI_CLK] = &venus0_axi_clk.clkr, + [VENUS0_OCMEMNOC_CLK] = &venus0_ocmemnoc_clk.clkr, + [VENUS0_VCODEC0_CLK] = &venus0_vcodec0_clk.clkr, +}; + +static const struct qcom_reset_map mmcc_msm8974_resets[] = { + [SPDM_RESET] = { 0x0200 }, + [SPDM_RM_RESET] = { 0x0300 }, + [VENUS0_RESET] = { 0x1020 }, + [MDSS_RESET] = { 0x2300 }, + [CAMSS_PHY0_RESET] = { 0x3020 }, + [CAMSS_PHY1_RESET] = { 0x3050 }, + [CAMSS_PHY2_RESET] = { 0x3080 }, + [CAMSS_CSI0_RESET] = { 0x30b0 }, + [CAMSS_CSI0PHY_RESET] = { 0x30c0 }, + [CAMSS_CSI0RDI_RESET] = { 0x30d0 }, + [CAMSS_CSI0PIX_RESET] = { 0x30e0 }, + [CAMSS_CSI1_RESET] = { 0x3120 }, + [CAMSS_CSI1PHY_RESET] = { 0x3130 }, + [CAMSS_CSI1RDI_RESET] = { 0x3140 }, + [CAMSS_CSI1PIX_RESET] = { 0x3150 }, + [CAMSS_CSI2_RESET] = { 0x3180 }, + [CAMSS_CSI2PHY_RESET] = { 0x3190 }, + [CAMSS_CSI2RDI_RESET] = { 0x31a0 }, + [CAMSS_CSI2PIX_RESET] = { 0x31b0 }, + [CAMSS_CSI3_RESET] = { 0x31e0 }, + [CAMSS_CSI3PHY_RESET] = { 0x31f0 }, + [CAMSS_CSI3RDI_RESET] = { 0x3200 }, + [CAMSS_CSI3PIX_RESET] = { 0x3210 }, + [CAMSS_ISPIF_RESET] = { 0x3220 }, + [CAMSS_CCI_RESET] = { 0x3340 }, + [CAMSS_MCLK0_RESET] = { 0x3380 }, + [CAMSS_MCLK1_RESET] = { 0x33b0 }, + [CAMSS_MCLK2_RESET] = { 0x33e0 }, + [CAMSS_MCLK3_RESET] = { 0x3410 }, + [CAMSS_GP0_RESET] = { 0x3440 }, + [CAMSS_GP1_RESET] = { 0x3470 }, + [CAMSS_TOP_RESET] = { 0x3480 }, + [CAMSS_MICRO_RESET] = { 0x3490 }, + [CAMSS_JPEG_RESET] = { 0x35a0 }, + [CAMSS_VFE_RESET] = { 0x36a0 }, + [CAMSS_CSI_VFE0_RESET] = { 0x3700 }, + [CAMSS_CSI_VFE1_RESET] = { 0x3710 }, + [OXILI_RESET] = { 0x4020 }, + [OXILICX_RESET] = { 0x4030 }, + [OCMEMCX_RESET] = { 0x4050 }, + [MMSS_RBCRP_RESET] = { 0x4080 }, + [MMSSNOCAHB_RESET] = { 0x5020 }, + [MMSSNOCAXI_RESET] = { 0x5060 }, + [OCMEMNOC_RESET] = { 0x50b0 }, +}; + +static const struct regmap_config mmcc_msm8974_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x5104, + .fast_io = true, +}; + +static const struct of_device_id mmcc_msm8974_match_table[] = { + { .compatible = "qcom,mmcc-msm8974" }, + { } +}; +MODULE_DEVICE_TABLE(of, mmcc_msm8974_match_table); + +struct qcom_cc { + struct qcom_reset_controller reset; + struct clk_onecell_data data; + struct clk *clks[]; +}; + +static int mmcc_msm8974_probe(struct platform_device *pdev) +{ + void __iomem *base; + struct resource *res; + int i, ret; + struct device *dev = &pdev->dev; + struct clk *clk; + struct clk_onecell_data *data; + struct clk **clks; + struct regmap *regmap; + size_t num_clks; + struct qcom_reset_controller *reset; + struct qcom_cc *cc; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + regmap = devm_regmap_init_mmio(dev, base, &mmcc_msm8974_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + num_clks = ARRAY_SIZE(mmcc_msm8974_clocks); + cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks, + GFP_KERNEL); + if (!cc) + return -ENOMEM; + + clks = cc->clks; + data = &cc->data; + data->clks = clks; + data->clk_num = num_clks; + + clk_pll_configure_sr_hpm_lp(&mmpll1, regmap, &mmpll1_config, true); + clk_pll_configure_sr_hpm_lp(&mmpll3, regmap, &mmpll3_config, false); + + for (i = 0; i < num_clks; i++) { + if (!mmcc_msm8974_clocks[i]) + continue; + clk = devm_clk_register_regmap(dev, mmcc_msm8974_clocks[i]); + if (IS_ERR(clk)) + return PTR_ERR(clk); + clks[i] = clk; + } + + ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data); + if (ret) + return ret; + + reset = &cc->reset; + reset->rcdev.of_node = dev->of_node; + reset->rcdev.ops = &qcom_reset_ops, + reset->rcdev.owner = THIS_MODULE, + reset->rcdev.nr_resets = ARRAY_SIZE(mmcc_msm8974_resets), + reset->regmap = regmap; + reset->reset_map = mmcc_msm8974_resets, + platform_set_drvdata(pdev, &reset->rcdev); + + ret = reset_controller_register(&reset->rcdev); + if (ret) + of_clk_del_provider(dev->of_node); + + return ret; +} + +static int mmcc_msm8974_remove(struct platform_device *pdev) +{ + of_clk_del_provider(pdev->dev.of_node); + reset_controller_unregister(platform_get_drvdata(pdev)); + return 0; +} + +static struct platform_driver mmcc_msm8974_driver = { + .probe = mmcc_msm8974_probe, + .remove = mmcc_msm8974_remove, + .driver = { + .name = "mmcc-msm8974", + .owner = THIS_MODULE, + .of_match_table = mmcc_msm8974_match_table, + }, +}; +module_platform_driver(mmcc_msm8974_driver); + +MODULE_DESCRIPTION("QCOM MMCC MSM8974 Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:mmcc-msm8974"); diff --git a/drivers/clk/qcom/reset.c b/drivers/clk/qcom/reset.c new file mode 100644 index 000000000000..6c977d3a8590 --- /dev/null +++ b/drivers/clk/qcom/reset.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013, 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/bitops.h> +#include <linux/export.h> +#include <linux/regmap.h> +#include <linux/reset-controller.h> +#include <linux/delay.h> + +#include "reset.h" + +static int qcom_reset(struct reset_controller_dev *rcdev, unsigned long id) +{ + rcdev->ops->assert(rcdev, id); + udelay(1); + rcdev->ops->deassert(rcdev, id); + return 0; +} + +static int +qcom_reset_assert(struct reset_controller_dev *rcdev, unsigned long id) +{ + struct qcom_reset_controller *rst; + const struct qcom_reset_map *map; + u32 mask; + + rst = to_qcom_reset_controller(rcdev); + map = &rst->reset_map[id]; + mask = BIT(map->bit); + + return regmap_update_bits(rst->regmap, map->reg, mask, mask); +} + +static int +qcom_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id) +{ + struct qcom_reset_controller *rst; + const struct qcom_reset_map *map; + u32 mask; + + rst = to_qcom_reset_controller(rcdev); + map = &rst->reset_map[id]; + mask = BIT(map->bit); + + return regmap_update_bits(rst->regmap, map->reg, mask, 0); +} + +struct reset_control_ops qcom_reset_ops = { + .reset = qcom_reset, + .assert = qcom_reset_assert, + .deassert = qcom_reset_deassert, +}; +EXPORT_SYMBOL_GPL(qcom_reset_ops); diff --git a/drivers/clk/qcom/reset.h b/drivers/clk/qcom/reset.h new file mode 100644 index 000000000000..0e11e2130f97 --- /dev/null +++ b/drivers/clk/qcom/reset.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2013, 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_RESET_H__ +#define __QCOM_CLK_RESET_H__ + +#include <linux/reset-controller.h> + +struct qcom_reset_map { + unsigned int reg; + u8 bit; +}; + +struct regmap; + +struct qcom_reset_controller { + const struct qcom_reset_map *reset_map; + struct regmap *regmap; + struct reset_controller_dev rcdev; +}; + +#define to_qcom_reset_controller(r) \ + container_of(r, struct qcom_reset_controller, rcdev); + +extern struct reset_control_ops qcom_reset_ops; + +#endif diff --git a/drivers/clk/samsung/clk-exynos-audss.c b/drivers/clk/samsung/clk-exynos-audss.c index 68e515d093d8..884187fbfe00 100644 --- a/drivers/clk/samsung/clk-exynos-audss.c +++ b/drivers/clk/samsung/clk-exynos-audss.c @@ -14,9 +14,17 @@ #include <linux/clk-provider.h> #include <linux/of_address.h> #include <linux/syscore_ops.h> +#include <linux/module.h> +#include <linux/platform_device.h> #include <dt-bindings/clk/exynos-audss-clk.h> +enum exynos_audss_clk_type { + TYPE_EXYNOS4210, + TYPE_EXYNOS5250, + TYPE_EXYNOS5420, +}; + static DEFINE_SPINLOCK(lock); static struct clk **clk_table; static void __iomem *reg_base; @@ -26,10 +34,6 @@ static struct clk_onecell_data clk_data; #define ASS_CLK_DIV 0x4 #define ASS_CLK_GATE 0x8 -/* list of all parent clock list */ -static const char *mout_audss_p[] = { "fin_pll", "fout_epll" }; -static const char *mout_i2s_p[] = { "mout_audss", "cdclk0", "sclk_audio0" }; - #ifdef CONFIG_PM_SLEEP static unsigned long reg_save[][2] = { {ASS_CLK_SRC, 0}, @@ -61,31 +65,69 @@ static struct syscore_ops exynos_audss_clk_syscore_ops = { }; #endif /* CONFIG_PM_SLEEP */ +static const struct of_device_id exynos_audss_clk_of_match[] = { + { .compatible = "samsung,exynos4210-audss-clock", + .data = (void *)TYPE_EXYNOS4210, }, + { .compatible = "samsung,exynos5250-audss-clock", + .data = (void *)TYPE_EXYNOS5250, }, + { .compatible = "samsung,exynos5420-audss-clock", + .data = (void *)TYPE_EXYNOS5420, }, + {}, +}; + /* register exynos_audss clocks */ -static void __init exynos_audss_clk_init(struct device_node *np) +static int exynos_audss_clk_probe(struct platform_device *pdev) { - reg_base = of_iomap(np, 0); - if (!reg_base) { - pr_err("%s: failed to map audss registers\n", __func__); - return; + int i, ret = 0; + struct resource *res; + const char *mout_audss_p[] = {"fin_pll", "fout_epll"}; + const char *mout_i2s_p[] = {"mout_audss", "cdclk0", "sclk_audio0"}; + const char *sclk_pcm_p = "sclk_pcm0"; + struct clk *pll_ref, *pll_in, *cdclk, *sclk_audio, *sclk_pcm_in; + const struct of_device_id *match; + enum exynos_audss_clk_type variant; + + match = of_match_node(exynos_audss_clk_of_match, pdev->dev.of_node); + if (!match) + return -EINVAL; + variant = (enum exynos_audss_clk_type)match->data; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(reg_base)) { + dev_err(&pdev->dev, "failed to map audss registers\n"); + return PTR_ERR(reg_base); } - clk_table = kzalloc(sizeof(struct clk *) * EXYNOS_AUDSS_MAX_CLKS, + clk_table = devm_kzalloc(&pdev->dev, + sizeof(struct clk *) * EXYNOS_AUDSS_MAX_CLKS, GFP_KERNEL); - if (!clk_table) { - pr_err("%s: could not allocate clk lookup table\n", __func__); - return; - } + if (!clk_table) + return -ENOMEM; clk_data.clks = clk_table; - clk_data.clk_num = EXYNOS_AUDSS_MAX_CLKS; - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); - + if (variant == TYPE_EXYNOS5420) + clk_data.clk_num = EXYNOS_AUDSS_MAX_CLKS; + else + clk_data.clk_num = EXYNOS_AUDSS_MAX_CLKS - 1; + + pll_ref = devm_clk_get(&pdev->dev, "pll_ref"); + pll_in = devm_clk_get(&pdev->dev, "pll_in"); + if (!IS_ERR(pll_ref)) + mout_audss_p[0] = __clk_get_name(pll_ref); + if (!IS_ERR(pll_in)) + mout_audss_p[1] = __clk_get_name(pll_in); clk_table[EXYNOS_MOUT_AUDSS] = clk_register_mux(NULL, "mout_audss", mout_audss_p, ARRAY_SIZE(mout_audss_p), CLK_SET_RATE_NO_REPARENT, reg_base + ASS_CLK_SRC, 0, 1, 0, &lock); + cdclk = devm_clk_get(&pdev->dev, "cdclk"); + sclk_audio = devm_clk_get(&pdev->dev, "sclk_audio"); + if (!IS_ERR(cdclk)) + mout_i2s_p[1] = __clk_get_name(cdclk); + if (!IS_ERR(sclk_audio)) + mout_i2s_p[2] = __clk_get_name(sclk_audio); clk_table[EXYNOS_MOUT_I2S] = clk_register_mux(NULL, "mout_i2s", mout_i2s_p, ARRAY_SIZE(mout_i2s_p), CLK_SET_RATE_NO_REPARENT, @@ -119,17 +161,88 @@ static void __init exynos_audss_clk_init(struct device_node *np) "sclk_pcm", CLK_SET_RATE_PARENT, reg_base + ASS_CLK_GATE, 4, 0, &lock); + sclk_pcm_in = devm_clk_get(&pdev->dev, "sclk_pcm_in"); + if (!IS_ERR(sclk_pcm_in)) + sclk_pcm_p = __clk_get_name(sclk_pcm_in); clk_table[EXYNOS_SCLK_PCM] = clk_register_gate(NULL, "sclk_pcm", - "div_pcm0", CLK_SET_RATE_PARENT, + sclk_pcm_p, CLK_SET_RATE_PARENT, reg_base + ASS_CLK_GATE, 5, 0, &lock); + if (variant == TYPE_EXYNOS5420) { + clk_table[EXYNOS_ADMA] = clk_register_gate(NULL, "adma", + "dout_srp", CLK_SET_RATE_PARENT, + reg_base + ASS_CLK_GATE, 9, 0, &lock); + } + + for (i = 0; i < clk_data.clk_num; i++) { + if (IS_ERR(clk_table[i])) { + dev_err(&pdev->dev, "failed to register clock %d\n", i); + ret = PTR_ERR(clk_table[i]); + goto unregister; + } + } + + ret = of_clk_add_provider(pdev->dev.of_node, of_clk_src_onecell_get, + &clk_data); + if (ret) { + dev_err(&pdev->dev, "failed to add clock provider\n"); + goto unregister; + } + #ifdef CONFIG_PM_SLEEP register_syscore_ops(&exynos_audss_clk_syscore_ops); #endif - pr_info("Exynos: Audss: clock setup completed\n"); + dev_info(&pdev->dev, "setup completed\n"); + + return 0; + +unregister: + for (i = 0; i < clk_data.clk_num; i++) { + if (!IS_ERR(clk_table[i])) + clk_unregister(clk_table[i]); + } + + return ret; } -CLK_OF_DECLARE(exynos4210_audss_clk, "samsung,exynos4210-audss-clock", - exynos_audss_clk_init); -CLK_OF_DECLARE(exynos5250_audss_clk, "samsung,exynos5250-audss-clock", - exynos_audss_clk_init); + +static int exynos_audss_clk_remove(struct platform_device *pdev) +{ + int i; + + of_clk_del_provider(pdev->dev.of_node); + + for (i = 0; i < clk_data.clk_num; i++) { + if (!IS_ERR(clk_table[i])) + clk_unregister(clk_table[i]); + } + + return 0; +} + +static struct platform_driver exynos_audss_clk_driver = { + .driver = { + .name = "exynos-audss-clk", + .owner = THIS_MODULE, + .of_match_table = exynos_audss_clk_of_match, + }, + .probe = exynos_audss_clk_probe, + .remove = exynos_audss_clk_remove, +}; + +static int __init exynos_audss_clk_init(void) +{ + return platform_driver_register(&exynos_audss_clk_driver); +} +core_initcall(exynos_audss_clk_init); + +static void __exit exynos_audss_clk_exit(void) +{ + platform_driver_unregister(&exynos_audss_clk_driver); +} +module_exit(exynos_audss_clk_exit); + +MODULE_AUTHOR("Padmavathi Venna <padma.v@samsung.com>"); +MODULE_DESCRIPTION("Exynos Audio Subsystem Clock Controller"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:exynos-audss-clk"); diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 3852e44db0f8..010f071af883 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -10,6 +10,7 @@ * Common Clock Framework support for all Exynos4 SoCs. */ +#include <dt-bindings/clock/exynos4.h> #include <linux/clk.h> #include <linux/clkdev.h> #include <linux/clk-provider.h> @@ -130,68 +131,6 @@ enum exynos4_plls { }; /* - * Let each supported clock get a unique id. This id is used to lookup the clock - * for device tree based platforms. The clocks are categorized into three - * sections: core, sclk gate and bus interface gate clocks. - * - * When adding a new clock to this list, it is advised to choose a clock - * category and add it to the end of that category. That is because the the - * device tree source file is referring to these ids and any change in the - * sequence number of existing clocks will require corresponding change in the - * device tree files. This limitation would go away when pre-processor support - * for dtc would be available. - */ -enum exynos4_clks { - none, - - /* core clocks */ - xxti, xusbxti, fin_pll, fout_apll, fout_mpll, fout_epll, fout_vpll, - sclk_apll, sclk_mpll, sclk_epll, sclk_vpll, arm_clk, aclk200, aclk100, - aclk160, aclk133, mout_mpll_user_t, mout_mpll_user_c, mout_core, - mout_apll, /* 20 */ - - /* gate for special clocks (sclk) */ - sclk_fimc0 = 128, sclk_fimc1, sclk_fimc2, sclk_fimc3, sclk_cam0, - sclk_cam1, sclk_csis0, sclk_csis1, sclk_hdmi, sclk_mixer, sclk_dac, - sclk_pixel, sclk_fimd0, sclk_mdnie0, sclk_mdnie_pwm0, sclk_mipi0, - sclk_audio0, sclk_mmc0, sclk_mmc1, sclk_mmc2, sclk_mmc3, sclk_mmc4, - sclk_sata, sclk_uart0, sclk_uart1, sclk_uart2, sclk_uart3, sclk_uart4, - sclk_audio1, sclk_audio2, sclk_spdif, sclk_spi0, sclk_spi1, sclk_spi2, - sclk_slimbus, sclk_fimd1, sclk_mipi1, sclk_pcm1, sclk_pcm2, sclk_i2s1, - sclk_i2s2, sclk_mipihsi, sclk_mfc, sclk_pcm0, sclk_g3d, sclk_pwm_isp, - sclk_spi0_isp, sclk_spi1_isp, sclk_uart_isp, sclk_fimg2d, - - /* gate clocks */ - fimc0 = 256, fimc1, fimc2, fimc3, csis0, csis1, jpeg, smmu_fimc0, - smmu_fimc1, smmu_fimc2, smmu_fimc3, smmu_jpeg, vp, mixer, tvenc, hdmi, - smmu_tv, mfc, smmu_mfcl, smmu_mfcr, g3d, g2d, rotator, mdma, smmu_g2d, - smmu_rotator, smmu_mdma, fimd0, mie0, mdnie0, dsim0, smmu_fimd0, fimd1, - mie1, dsim1, smmu_fimd1, pdma0, pdma1, pcie_phy, sata_phy, tsi, sdmmc0, - sdmmc1, sdmmc2, sdmmc3, sdmmc4, sata, sromc, usb_host, usb_device, pcie, - onenand, nfcon, smmu_pcie, gps, smmu_gps, uart0, uart1, uart2, uart3, - uart4, i2c0, i2c1, i2c2, i2c3, i2c4, i2c5, i2c6, i2c7, i2c_hdmi, tsadc, - spi0, spi1, spi2, i2s1, i2s2, pcm0, i2s0, pcm1, pcm2, pwm, slimbus, - spdif, ac97, modemif, chipid, sysreg, hdmi_cec, mct, wdt, rtc, keyif, - audss, mipi_hsi, mdma2, pixelasyncm0, pixelasyncm1, fimc_lite0, - fimc_lite1, ppmuispx, ppmuispmx, fimc_isp, fimc_drc, fimc_fd, mcuisp, - gicisp, smmu_isp, smmu_drc, smmu_fd, smmu_lite0, smmu_lite1, mcuctl_isp, - mpwm_isp, i2c0_isp, i2c1_isp, mtcadc_isp, pwm_isp, wdt_isp, uart_isp, - asyncaxim, smmu_ispcx, spi0_isp, spi1_isp, pwm_isp_sclk, spi0_isp_sclk, - spi1_isp_sclk, uart_isp_sclk, tmu_apbif, - - /* mux clocks */ - mout_fimc0 = 384, mout_fimc1, mout_fimc2, mout_fimc3, mout_cam0, - mout_cam1, mout_csis0, mout_csis1, mout_g3d0, mout_g3d1, mout_g3d, - aclk400_mcuisp, - - /* div clocks */ - div_isp0 = 450, div_isp1, div_mcuisp0, div_mcuisp1, div_aclk200, - div_aclk400_mcuisp, - - nr_clks, -}; - -/* * list of controller registers to be saved and restored during a * suspend/resume cycle. */ @@ -347,256 +286,256 @@ PNAME(mout_user_aclk266_gps_p4x12) = {"fin_pll", "div_aclk266_gps", }; /* fixed rate clocks generated outside the soc */ static struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] __initdata = { - FRATE(xxti, "xxti", NULL, CLK_IS_ROOT, 0), - FRATE(xusbxti, "xusbxti", NULL, CLK_IS_ROOT, 0), + FRATE(CLK_XXTI, "xxti", NULL, CLK_IS_ROOT, 0), + FRATE(CLK_XUSBXTI, "xusbxti", NULL, CLK_IS_ROOT, 0), }; /* fixed rate clocks generated inside the soc */ static struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] __initdata = { - FRATE(none, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 24000000), - FRATE(none, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000), - FRATE(none, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000), + FRATE(0, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 24000000), + FRATE(0, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000), + FRATE(0, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000), }; static struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] __initdata = { - FRATE(none, "sclk_usbphy1", NULL, CLK_IS_ROOT, 48000000), + FRATE(0, "sclk_usbphy1", NULL, CLK_IS_ROOT, 48000000), }; /* list of mux clocks supported in all exynos4 soc's */ static struct samsung_mux_clock exynos4_mux_clks[] __initdata = { - MUX_FA(mout_apll, "mout_apll", mout_apll_p, SRC_CPU, 0, 1, + MUX_FA(CLK_MOUT_APLL, "mout_apll", mout_apll_p, SRC_CPU, 0, 1, CLK_SET_RATE_PARENT, 0, "mout_apll"), - MUX(none, "mout_hdmi", mout_hdmi_p, SRC_TV, 0, 1), - MUX(none, "mout_mfc1", sclk_evpll_p, SRC_MFC, 4, 1), - MUX(none, "mout_mfc", mout_mfc_p, SRC_MFC, 8, 1), - MUX_F(mout_g3d1, "mout_g3d1", sclk_evpll_p, SRC_G3D, 4, 1, + MUX(0, "mout_hdmi", mout_hdmi_p, SRC_TV, 0, 1), + MUX(0, "mout_mfc1", sclk_evpll_p, SRC_MFC, 4, 1), + MUX(0, "mout_mfc", mout_mfc_p, SRC_MFC, 8, 1), + MUX_F(CLK_MOUT_G3D1, "mout_g3d1", sclk_evpll_p, SRC_G3D, 4, 1, CLK_SET_RATE_PARENT, 0), - MUX_F(mout_g3d, "mout_g3d", mout_g3d_p, SRC_G3D, 8, 1, + MUX_F(CLK_MOUT_G3D, "mout_g3d", mout_g3d_p, SRC_G3D, 8, 1, CLK_SET_RATE_PARENT, 0), - MUX(none, "mout_spdif", mout_spdif_p, SRC_PERIL1, 8, 2), - MUX(none, "mout_onenand1", mout_onenand1_p, SRC_TOP0, 0, 1), - MUX(sclk_epll, "sclk_epll", mout_epll_p, SRC_TOP0, 4, 1), - MUX(none, "mout_onenand", mout_onenand_p, SRC_TOP0, 28, 1), + MUX(0, "mout_spdif", mout_spdif_p, SRC_PERIL1, 8, 2), + MUX(0, "mout_onenand1", mout_onenand1_p, SRC_TOP0, 0, 1), + MUX(CLK_SCLK_EPLL, "sclk_epll", mout_epll_p, SRC_TOP0, 4, 1), + MUX(0, "mout_onenand", mout_onenand_p, SRC_TOP0, 28, 1), }; /* list of mux clocks supported in exynos4210 soc */ static struct samsung_mux_clock exynos4210_mux_early[] __initdata = { - MUX(none, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP1, 0, 1), + MUX(0, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP1, 0, 1), }; static struct samsung_mux_clock exynos4210_mux_clks[] __initdata = { - MUX(none, "mout_aclk200", sclk_ampll_p4210, SRC_TOP0, 12, 1), - MUX(none, "mout_aclk100", sclk_ampll_p4210, SRC_TOP0, 16, 1), - MUX(none, "mout_aclk160", sclk_ampll_p4210, SRC_TOP0, 20, 1), - MUX(none, "mout_aclk133", sclk_ampll_p4210, SRC_TOP0, 24, 1), - MUX(none, "mout_mixer", mout_mixer_p4210, SRC_TV, 4, 1), - MUX(none, "mout_dac", mout_dac_p4210, SRC_TV, 8, 1), - MUX(none, "mout_g2d0", sclk_ampll_p4210, E4210_SRC_IMAGE, 0, 1), - MUX(none, "mout_g2d1", sclk_evpll_p, E4210_SRC_IMAGE, 4, 1), - MUX(none, "mout_g2d", mout_g2d_p, E4210_SRC_IMAGE, 8, 1), - MUX(none, "mout_fimd1", group1_p4210, E4210_SRC_LCD1, 0, 4), - MUX(none, "mout_mipi1", group1_p4210, E4210_SRC_LCD1, 12, 4), - MUX(sclk_mpll, "sclk_mpll", mout_mpll_p, SRC_CPU, 8, 1), - MUX(mout_core, "mout_core", mout_core_p4210, SRC_CPU, 16, 1), - MUX(sclk_vpll, "sclk_vpll", sclk_vpll_p4210, SRC_TOP0, 8, 1), - MUX(mout_fimc0, "mout_fimc0", group1_p4210, SRC_CAM, 0, 4), - MUX(mout_fimc1, "mout_fimc1", group1_p4210, SRC_CAM, 4, 4), - MUX(mout_fimc2, "mout_fimc2", group1_p4210, SRC_CAM, 8, 4), - MUX(mout_fimc3, "mout_fimc3", group1_p4210, SRC_CAM, 12, 4), - MUX(mout_cam0, "mout_cam0", group1_p4210, SRC_CAM, 16, 4), - MUX(mout_cam1, "mout_cam1", group1_p4210, SRC_CAM, 20, 4), - MUX(mout_csis0, "mout_csis0", group1_p4210, SRC_CAM, 24, 4), - MUX(mout_csis1, "mout_csis1", group1_p4210, SRC_CAM, 28, 4), - MUX(none, "mout_mfc0", sclk_ampll_p4210, SRC_MFC, 0, 1), - MUX_F(mout_g3d0, "mout_g3d0", sclk_ampll_p4210, SRC_G3D, 0, 1, + MUX(0, "mout_aclk200", sclk_ampll_p4210, SRC_TOP0, 12, 1), + MUX(0, "mout_aclk100", sclk_ampll_p4210, SRC_TOP0, 16, 1), + MUX(0, "mout_aclk160", sclk_ampll_p4210, SRC_TOP0, 20, 1), + MUX(0, "mout_aclk133", sclk_ampll_p4210, SRC_TOP0, 24, 1), + MUX(0, "mout_mixer", mout_mixer_p4210, SRC_TV, 4, 1), + MUX(0, "mout_dac", mout_dac_p4210, SRC_TV, 8, 1), + MUX(0, "mout_g2d0", sclk_ampll_p4210, E4210_SRC_IMAGE, 0, 1), + MUX(0, "mout_g2d1", sclk_evpll_p, E4210_SRC_IMAGE, 4, 1), + MUX(0, "mout_g2d", mout_g2d_p, E4210_SRC_IMAGE, 8, 1), + MUX(0, "mout_fimd1", group1_p4210, E4210_SRC_LCD1, 0, 4), + MUX(0, "mout_mipi1", group1_p4210, E4210_SRC_LCD1, 12, 4), + MUX(CLK_SCLK_MPLL, "sclk_mpll", mout_mpll_p, SRC_CPU, 8, 1), + MUX(CLK_MOUT_CORE, "mout_core", mout_core_p4210, SRC_CPU, 16, 1), + MUX(CLK_SCLK_VPLL, "sclk_vpll", sclk_vpll_p4210, SRC_TOP0, 8, 1), + MUX(CLK_MOUT_FIMC0, "mout_fimc0", group1_p4210, SRC_CAM, 0, 4), + MUX(CLK_MOUT_FIMC1, "mout_fimc1", group1_p4210, SRC_CAM, 4, 4), + MUX(CLK_MOUT_FIMC2, "mout_fimc2", group1_p4210, SRC_CAM, 8, 4), + MUX(CLK_MOUT_FIMC3, "mout_fimc3", group1_p4210, SRC_CAM, 12, 4), + MUX(CLK_MOUT_CAM0, "mout_cam0", group1_p4210, SRC_CAM, 16, 4), + MUX(CLK_MOUT_CAM1, "mout_cam1", group1_p4210, SRC_CAM, 20, 4), + MUX(CLK_MOUT_CSIS0, "mout_csis0", group1_p4210, SRC_CAM, 24, 4), + MUX(CLK_MOUT_CSIS1, "mout_csis1", group1_p4210, SRC_CAM, 28, 4), + MUX(0, "mout_mfc0", sclk_ampll_p4210, SRC_MFC, 0, 1), + MUX_F(CLK_MOUT_G3D0, "mout_g3d0", sclk_ampll_p4210, SRC_G3D, 0, 1, CLK_SET_RATE_PARENT, 0), - MUX(none, "mout_fimd0", group1_p4210, SRC_LCD0, 0, 4), - MUX(none, "mout_mipi0", group1_p4210, SRC_LCD0, 12, 4), - MUX(none, "mout_audio0", mout_audio0_p4210, SRC_MAUDIO, 0, 4), - MUX(none, "mout_mmc0", group1_p4210, SRC_FSYS, 0, 4), - MUX(none, "mout_mmc1", group1_p4210, SRC_FSYS, 4, 4), - MUX(none, "mout_mmc2", group1_p4210, SRC_FSYS, 8, 4), - MUX(none, "mout_mmc3", group1_p4210, SRC_FSYS, 12, 4), - MUX(none, "mout_mmc4", group1_p4210, SRC_FSYS, 16, 4), - MUX(none, "mout_sata", sclk_ampll_p4210, SRC_FSYS, 24, 1), - MUX(none, "mout_uart0", group1_p4210, SRC_PERIL0, 0, 4), - MUX(none, "mout_uart1", group1_p4210, SRC_PERIL0, 4, 4), - MUX(none, "mout_uart2", group1_p4210, SRC_PERIL0, 8, 4), - MUX(none, "mout_uart3", group1_p4210, SRC_PERIL0, 12, 4), - MUX(none, "mout_uart4", group1_p4210, SRC_PERIL0, 16, 4), - MUX(none, "mout_audio1", mout_audio1_p4210, SRC_PERIL1, 0, 4), - MUX(none, "mout_audio2", mout_audio2_p4210, SRC_PERIL1, 4, 4), - MUX(none, "mout_spi0", group1_p4210, SRC_PERIL1, 16, 4), - MUX(none, "mout_spi1", group1_p4210, SRC_PERIL1, 20, 4), - MUX(none, "mout_spi2", group1_p4210, SRC_PERIL1, 24, 4), + MUX(0, "mout_fimd0", group1_p4210, SRC_LCD0, 0, 4), + MUX(0, "mout_mipi0", group1_p4210, SRC_LCD0, 12, 4), + MUX(0, "mout_audio0", mout_audio0_p4210, SRC_MAUDIO, 0, 4), + MUX(0, "mout_mmc0", group1_p4210, SRC_FSYS, 0, 4), + MUX(0, "mout_mmc1", group1_p4210, SRC_FSYS, 4, 4), + MUX(0, "mout_mmc2", group1_p4210, SRC_FSYS, 8, 4), + MUX(0, "mout_mmc3", group1_p4210, SRC_FSYS, 12, 4), + MUX(0, "mout_mmc4", group1_p4210, SRC_FSYS, 16, 4), + MUX(0, "mout_sata", sclk_ampll_p4210, SRC_FSYS, 24, 1), + MUX(0, "mout_uart0", group1_p4210, SRC_PERIL0, 0, 4), + MUX(0, "mout_uart1", group1_p4210, SRC_PERIL0, 4, 4), + MUX(0, "mout_uart2", group1_p4210, SRC_PERIL0, 8, 4), + MUX(0, "mout_uart3", group1_p4210, SRC_PERIL0, 12, 4), + MUX(0, "mout_uart4", group1_p4210, SRC_PERIL0, 16, 4), + MUX(0, "mout_audio1", mout_audio1_p4210, SRC_PERIL1, 0, 4), + MUX(0, "mout_audio2", mout_audio2_p4210, SRC_PERIL1, 4, 4), + MUX(0, "mout_spi0", group1_p4210, SRC_PERIL1, 16, 4), + MUX(0, "mout_spi1", group1_p4210, SRC_PERIL1, 20, 4), + MUX(0, "mout_spi2", group1_p4210, SRC_PERIL1, 24, 4), }; /* list of mux clocks supported in exynos4x12 soc */ static struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = { - MUX(mout_mpll_user_c, "mout_mpll_user_c", mout_mpll_user_p4x12, + MUX(CLK_MOUT_MPLL_USER_C, "mout_mpll_user_c", mout_mpll_user_p4x12, SRC_CPU, 24, 1), - MUX(none, "mout_aclk266_gps", aclk_p4412, SRC_TOP1, 4, 1), - MUX(none, "mout_aclk400_mcuisp", aclk_p4412, SRC_TOP1, 8, 1), - MUX(mout_mpll_user_t, "mout_mpll_user_t", mout_mpll_user_p4x12, + MUX(0, "mout_aclk266_gps", aclk_p4412, SRC_TOP1, 4, 1), + MUX(0, "mout_aclk400_mcuisp", aclk_p4412, SRC_TOP1, 8, 1), + MUX(CLK_MOUT_MPLL_USER_T, "mout_mpll_user_t", mout_mpll_user_p4x12, SRC_TOP1, 12, 1), - MUX(none, "mout_user_aclk266_gps", mout_user_aclk266_gps_p4x12, + MUX(0, "mout_user_aclk266_gps", mout_user_aclk266_gps_p4x12, SRC_TOP1, 16, 1), - MUX(aclk200, "aclk200", mout_user_aclk200_p4x12, SRC_TOP1, 20, 1), - MUX(aclk400_mcuisp, "aclk400_mcuisp", mout_user_aclk400_mcuisp_p4x12, - SRC_TOP1, 24, 1), - MUX(none, "mout_aclk200", aclk_p4412, SRC_TOP0, 12, 1), - MUX(none, "mout_aclk100", aclk_p4412, SRC_TOP0, 16, 1), - MUX(none, "mout_aclk160", aclk_p4412, SRC_TOP0, 20, 1), - MUX(none, "mout_aclk133", aclk_p4412, SRC_TOP0, 24, 1), - MUX(none, "mout_mdnie0", group1_p4x12, SRC_LCD0, 4, 4), - MUX(none, "mout_mdnie_pwm0", group1_p4x12, SRC_LCD0, 8, 4), - MUX(none, "mout_sata", sclk_ampll_p4x12, SRC_FSYS, 24, 1), - MUX(none, "mout_jpeg0", sclk_ampll_p4x12, E4X12_SRC_CAM1, 0, 1), - MUX(none, "mout_jpeg1", sclk_evpll_p, E4X12_SRC_CAM1, 4, 1), - MUX(none, "mout_jpeg", mout_jpeg_p, E4X12_SRC_CAM1, 8, 1), - MUX(sclk_mpll, "sclk_mpll", mout_mpll_p, SRC_DMC, 12, 1), - MUX(sclk_vpll, "sclk_vpll", mout_vpll_p, SRC_TOP0, 8, 1), - MUX(mout_core, "mout_core", mout_core_p4x12, SRC_CPU, 16, 1), - MUX(mout_fimc0, "mout_fimc0", group1_p4x12, SRC_CAM, 0, 4), - MUX(mout_fimc1, "mout_fimc1", group1_p4x12, SRC_CAM, 4, 4), - MUX(mout_fimc2, "mout_fimc2", group1_p4x12, SRC_CAM, 8, 4), - MUX(mout_fimc3, "mout_fimc3", group1_p4x12, SRC_CAM, 12, 4), - MUX(mout_cam0, "mout_cam0", group1_p4x12, SRC_CAM, 16, 4), - MUX(mout_cam1, "mout_cam1", group1_p4x12, SRC_CAM, 20, 4), - MUX(mout_csis0, "mout_csis0", group1_p4x12, SRC_CAM, 24, 4), - MUX(mout_csis1, "mout_csis1", group1_p4x12, SRC_CAM, 28, 4), - MUX(none, "mout_mfc0", sclk_ampll_p4x12, SRC_MFC, 0, 1), - MUX_F(mout_g3d0, "mout_g3d0", sclk_ampll_p4x12, SRC_G3D, 0, 1, + MUX(CLK_ACLK200, "aclk200", mout_user_aclk200_p4x12, SRC_TOP1, 20, 1), + MUX(CLK_ACLK400_MCUISP, "aclk400_mcuisp", + mout_user_aclk400_mcuisp_p4x12, SRC_TOP1, 24, 1), + MUX(0, "mout_aclk200", aclk_p4412, SRC_TOP0, 12, 1), + MUX(0, "mout_aclk100", aclk_p4412, SRC_TOP0, 16, 1), + MUX(0, "mout_aclk160", aclk_p4412, SRC_TOP0, 20, 1), + MUX(0, "mout_aclk133", aclk_p4412, SRC_TOP0, 24, 1), + MUX(0, "mout_mdnie0", group1_p4x12, SRC_LCD0, 4, 4), + MUX(0, "mout_mdnie_pwm0", group1_p4x12, SRC_LCD0, 8, 4), + MUX(0, "mout_sata", sclk_ampll_p4x12, SRC_FSYS, 24, 1), + MUX(0, "mout_jpeg0", sclk_ampll_p4x12, E4X12_SRC_CAM1, 0, 1), + MUX(0, "mout_jpeg1", sclk_evpll_p, E4X12_SRC_CAM1, 4, 1), + MUX(0, "mout_jpeg", mout_jpeg_p, E4X12_SRC_CAM1, 8, 1), + MUX(CLK_SCLK_MPLL, "sclk_mpll", mout_mpll_p, SRC_DMC, 12, 1), + MUX(CLK_SCLK_VPLL, "sclk_vpll", mout_vpll_p, SRC_TOP0, 8, 1), + MUX(CLK_MOUT_CORE, "mout_core", mout_core_p4x12, SRC_CPU, 16, 1), + MUX(CLK_MOUT_FIMC0, "mout_fimc0", group1_p4x12, SRC_CAM, 0, 4), + MUX(CLK_MOUT_FIMC1, "mout_fimc1", group1_p4x12, SRC_CAM, 4, 4), + MUX(CLK_MOUT_FIMC2, "mout_fimc2", group1_p4x12, SRC_CAM, 8, 4), + MUX(CLK_MOUT_FIMC3, "mout_fimc3", group1_p4x12, SRC_CAM, 12, 4), + MUX(CLK_MOUT_CAM0, "mout_cam0", group1_p4x12, SRC_CAM, 16, 4), + MUX(CLK_MOUT_CAM1, "mout_cam1", group1_p4x12, SRC_CAM, 20, 4), + MUX(CLK_MOUT_CSIS0, "mout_csis0", group1_p4x12, SRC_CAM, 24, 4), + MUX(CLK_MOUT_CSIS1, "mout_csis1", group1_p4x12, SRC_CAM, 28, 4), + MUX(0, "mout_mfc0", sclk_ampll_p4x12, SRC_MFC, 0, 1), + MUX_F(CLK_MOUT_G3D0, "mout_g3d0", sclk_ampll_p4x12, SRC_G3D, 0, 1, CLK_SET_RATE_PARENT, 0), - MUX(none, "mout_fimd0", group1_p4x12, SRC_LCD0, 0, 4), - MUX(none, "mout_mipi0", group1_p4x12, SRC_LCD0, 12, 4), - MUX(none, "mout_audio0", mout_audio0_p4x12, SRC_MAUDIO, 0, 4), - MUX(none, "mout_mmc0", group1_p4x12, SRC_FSYS, 0, 4), - MUX(none, "mout_mmc1", group1_p4x12, SRC_FSYS, 4, 4), - MUX(none, "mout_mmc2", group1_p4x12, SRC_FSYS, 8, 4), - MUX(none, "mout_mmc3", group1_p4x12, SRC_FSYS, 12, 4), - MUX(none, "mout_mmc4", group1_p4x12, SRC_FSYS, 16, 4), - MUX(none, "mout_mipihsi", aclk_p4412, SRC_FSYS, 24, 1), - MUX(none, "mout_uart0", group1_p4x12, SRC_PERIL0, 0, 4), - MUX(none, "mout_uart1", group1_p4x12, SRC_PERIL0, 4, 4), - MUX(none, "mout_uart2", group1_p4x12, SRC_PERIL0, 8, 4), - MUX(none, "mout_uart3", group1_p4x12, SRC_PERIL0, 12, 4), - MUX(none, "mout_uart4", group1_p4x12, SRC_PERIL0, 16, 4), - MUX(none, "mout_audio1", mout_audio1_p4x12, SRC_PERIL1, 0, 4), - MUX(none, "mout_audio2", mout_audio2_p4x12, SRC_PERIL1, 4, 4), - MUX(none, "mout_spi0", group1_p4x12, SRC_PERIL1, 16, 4), - MUX(none, "mout_spi1", group1_p4x12, SRC_PERIL1, 20, 4), - MUX(none, "mout_spi2", group1_p4x12, SRC_PERIL1, 24, 4), - MUX(none, "mout_pwm_isp", group1_p4x12, E4X12_SRC_ISP, 0, 4), - MUX(none, "mout_spi0_isp", group1_p4x12, E4X12_SRC_ISP, 4, 4), - MUX(none, "mout_spi1_isp", group1_p4x12, E4X12_SRC_ISP, 8, 4), - MUX(none, "mout_uart_isp", group1_p4x12, E4X12_SRC_ISP, 12, 4), - MUX(none, "mout_g2d0", sclk_ampll_p4210, SRC_DMC, 20, 1), - MUX(none, "mout_g2d1", sclk_evpll_p, SRC_DMC, 24, 1), - MUX(none, "mout_g2d", mout_g2d_p, SRC_DMC, 28, 1), + MUX(0, "mout_fimd0", group1_p4x12, SRC_LCD0, 0, 4), + MUX(0, "mout_mipi0", group1_p4x12, SRC_LCD0, 12, 4), + MUX(0, "mout_audio0", mout_audio0_p4x12, SRC_MAUDIO, 0, 4), + MUX(0, "mout_mmc0", group1_p4x12, SRC_FSYS, 0, 4), + MUX(0, "mout_mmc1", group1_p4x12, SRC_FSYS, 4, 4), + MUX(0, "mout_mmc2", group1_p4x12, SRC_FSYS, 8, 4), + MUX(0, "mout_mmc3", group1_p4x12, SRC_FSYS, 12, 4), + MUX(0, "mout_mmc4", group1_p4x12, SRC_FSYS, 16, 4), + MUX(0, "mout_mipihsi", aclk_p4412, SRC_FSYS, 24, 1), + MUX(0, "mout_uart0", group1_p4x12, SRC_PERIL0, 0, 4), + MUX(0, "mout_uart1", group1_p4x12, SRC_PERIL0, 4, 4), + MUX(0, "mout_uart2", group1_p4x12, SRC_PERIL0, 8, 4), + MUX(0, "mout_uart3", group1_p4x12, SRC_PERIL0, 12, 4), + MUX(0, "mout_uart4", group1_p4x12, SRC_PERIL0, 16, 4), + MUX(0, "mout_audio1", mout_audio1_p4x12, SRC_PERIL1, 0, 4), + MUX(0, "mout_audio2", mout_audio2_p4x12, SRC_PERIL1, 4, 4), + MUX(0, "mout_spi0", group1_p4x12, SRC_PERIL1, 16, 4), + MUX(0, "mout_spi1", group1_p4x12, SRC_PERIL1, 20, 4), + MUX(0, "mout_spi2", group1_p4x12, SRC_PERIL1, 24, 4), + MUX(0, "mout_pwm_isp", group1_p4x12, E4X12_SRC_ISP, 0, 4), + MUX(0, "mout_spi0_isp", group1_p4x12, E4X12_SRC_ISP, 4, 4), + MUX(0, "mout_spi1_isp", group1_p4x12, E4X12_SRC_ISP, 8, 4), + MUX(0, "mout_uart_isp", group1_p4x12, E4X12_SRC_ISP, 12, 4), + MUX(0, "mout_g2d0", sclk_ampll_p4210, SRC_DMC, 20, 1), + MUX(0, "mout_g2d1", sclk_evpll_p, SRC_DMC, 24, 1), + MUX(0, "mout_g2d", mout_g2d_p, SRC_DMC, 28, 1), }; /* list of divider clocks supported in all exynos4 soc's */ static struct samsung_div_clock exynos4_div_clks[] __initdata = { - DIV(none, "div_core", "mout_core", DIV_CPU0, 0, 3), - DIV(none, "div_core2", "div_core", DIV_CPU0, 28, 3), - DIV(none, "div_fimc0", "mout_fimc0", DIV_CAM, 0, 4), - DIV(none, "div_fimc1", "mout_fimc1", DIV_CAM, 4, 4), - DIV(none, "div_fimc2", "mout_fimc2", DIV_CAM, 8, 4), - DIV(none, "div_fimc3", "mout_fimc3", DIV_CAM, 12, 4), - DIV(none, "div_cam0", "mout_cam0", DIV_CAM, 16, 4), - DIV(none, "div_cam1", "mout_cam1", DIV_CAM, 20, 4), - DIV(none, "div_csis0", "mout_csis0", DIV_CAM, 24, 4), - DIV(none, "div_csis1", "mout_csis1", DIV_CAM, 28, 4), - DIV(sclk_mfc, "sclk_mfc", "mout_mfc", DIV_MFC, 0, 4), - DIV_F(none, "div_g3d", "mout_g3d", DIV_G3D, 0, 4, + DIV(0, "div_core", "mout_core", DIV_CPU0, 0, 3), + DIV(0, "div_core2", "div_core", DIV_CPU0, 28, 3), + DIV(0, "div_fimc0", "mout_fimc0", DIV_CAM, 0, 4), + DIV(0, "div_fimc1", "mout_fimc1", DIV_CAM, 4, 4), + DIV(0, "div_fimc2", "mout_fimc2", DIV_CAM, 8, 4), + DIV(0, "div_fimc3", "mout_fimc3", DIV_CAM, 12, 4), + DIV(0, "div_cam0", "mout_cam0", DIV_CAM, 16, 4), + DIV(0, "div_cam1", "mout_cam1", DIV_CAM, 20, 4), + DIV(0, "div_csis0", "mout_csis0", DIV_CAM, 24, 4), + DIV(0, "div_csis1", "mout_csis1", DIV_CAM, 28, 4), + DIV(CLK_SCLK_MFC, "sclk_mfc", "mout_mfc", DIV_MFC, 0, 4), + DIV_F(0, "div_g3d", "mout_g3d", DIV_G3D, 0, 4, CLK_SET_RATE_PARENT, 0), - DIV(none, "div_fimd0", "mout_fimd0", DIV_LCD0, 0, 4), - DIV(none, "div_mipi0", "mout_mipi0", DIV_LCD0, 16, 4), - DIV(none, "div_audio0", "mout_audio0", DIV_MAUDIO, 0, 4), - DIV(sclk_pcm0, "sclk_pcm0", "sclk_audio0", DIV_MAUDIO, 4, 8), - DIV(none, "div_mmc0", "mout_mmc0", DIV_FSYS1, 0, 4), - DIV(none, "div_mmc1", "mout_mmc1", DIV_FSYS1, 16, 4), - DIV(none, "div_mmc2", "mout_mmc2", DIV_FSYS2, 0, 4), - DIV(none, "div_mmc3", "mout_mmc3", DIV_FSYS2, 16, 4), - DIV(sclk_pixel, "sclk_pixel", "sclk_vpll", DIV_TV, 0, 4), - DIV(aclk100, "aclk100", "mout_aclk100", DIV_TOP, 4, 4), - DIV(aclk160, "aclk160", "mout_aclk160", DIV_TOP, 8, 3), - DIV(aclk133, "aclk133", "mout_aclk133", DIV_TOP, 12, 3), - DIV(none, "div_onenand", "mout_onenand1", DIV_TOP, 16, 3), - DIV(sclk_slimbus, "sclk_slimbus", "sclk_epll", DIV_PERIL3, 4, 4), - DIV(sclk_pcm1, "sclk_pcm1", "sclk_audio1", DIV_PERIL4, 4, 8), - DIV(sclk_pcm2, "sclk_pcm2", "sclk_audio2", DIV_PERIL4, 20, 8), - DIV(sclk_i2s1, "sclk_i2s1", "sclk_audio1", DIV_PERIL5, 0, 6), - DIV(sclk_i2s2, "sclk_i2s2", "sclk_audio2", DIV_PERIL5, 8, 6), - DIV(none, "div_mmc4", "mout_mmc4", DIV_FSYS3, 0, 4), - DIV_F(none, "div_mmc_pre4", "div_mmc4", DIV_FSYS3, 8, 8, + DIV(0, "div_fimd0", "mout_fimd0", DIV_LCD0, 0, 4), + DIV(0, "div_mipi0", "mout_mipi0", DIV_LCD0, 16, 4), + DIV(0, "div_audio0", "mout_audio0", DIV_MAUDIO, 0, 4), + DIV(CLK_SCLK_PCM0, "sclk_pcm0", "sclk_audio0", DIV_MAUDIO, 4, 8), + DIV(0, "div_mmc0", "mout_mmc0", DIV_FSYS1, 0, 4), + DIV(0, "div_mmc1", "mout_mmc1", DIV_FSYS1, 16, 4), + DIV(0, "div_mmc2", "mout_mmc2", DIV_FSYS2, 0, 4), + DIV(0, "div_mmc3", "mout_mmc3", DIV_FSYS2, 16, 4), + DIV(CLK_SCLK_PIXEL, "sclk_pixel", "sclk_vpll", DIV_TV, 0, 4), + DIV(CLK_ACLK100, "aclk100", "mout_aclk100", DIV_TOP, 4, 4), + DIV(CLK_ACLK160, "aclk160", "mout_aclk160", DIV_TOP, 8, 3), + DIV(CLK_ACLK133, "aclk133", "mout_aclk133", DIV_TOP, 12, 3), + DIV(0, "div_onenand", "mout_onenand1", DIV_TOP, 16, 3), + DIV(CLK_SCLK_SLIMBUS, "sclk_slimbus", "sclk_epll", DIV_PERIL3, 4, 4), + DIV(CLK_SCLK_PCM1, "sclk_pcm1", "sclk_audio1", DIV_PERIL4, 4, 8), + DIV(CLK_SCLK_PCM2, "sclk_pcm2", "sclk_audio2", DIV_PERIL4, 20, 8), + DIV(CLK_SCLK_I2S1, "sclk_i2s1", "sclk_audio1", DIV_PERIL5, 0, 6), + DIV(CLK_SCLK_I2S2, "sclk_i2s2", "sclk_audio2", DIV_PERIL5, 8, 6), + DIV(0, "div_mmc4", "mout_mmc4", DIV_FSYS3, 0, 4), + DIV_F(0, "div_mmc_pre4", "div_mmc4", DIV_FSYS3, 8, 8, CLK_SET_RATE_PARENT, 0), - DIV(none, "div_uart0", "mout_uart0", DIV_PERIL0, 0, 4), - DIV(none, "div_uart1", "mout_uart1", DIV_PERIL0, 4, 4), - DIV(none, "div_uart2", "mout_uart2", DIV_PERIL0, 8, 4), - DIV(none, "div_uart3", "mout_uart3", DIV_PERIL0, 12, 4), - DIV(none, "div_uart4", "mout_uart4", DIV_PERIL0, 16, 4), - DIV(none, "div_spi0", "mout_spi0", DIV_PERIL1, 0, 4), - DIV(none, "div_spi_pre0", "div_spi0", DIV_PERIL1, 8, 8), - DIV(none, "div_spi1", "mout_spi1", DIV_PERIL1, 16, 4), - DIV(none, "div_spi_pre1", "div_spi1", DIV_PERIL1, 24, 8), - DIV(none, "div_spi2", "mout_spi2", DIV_PERIL2, 0, 4), - DIV(none, "div_spi_pre2", "div_spi2", DIV_PERIL2, 8, 8), - DIV(none, "div_audio1", "mout_audio1", DIV_PERIL4, 0, 4), - DIV(none, "div_audio2", "mout_audio2", DIV_PERIL4, 16, 4), - DIV(arm_clk, "arm_clk", "div_core2", DIV_CPU0, 28, 3), - DIV(sclk_apll, "sclk_apll", "mout_apll", DIV_CPU0, 24, 3), - DIV_F(none, "div_mipi_pre0", "div_mipi0", DIV_LCD0, 20, 4, + DIV(0, "div_uart0", "mout_uart0", DIV_PERIL0, 0, 4), + DIV(0, "div_uart1", "mout_uart1", DIV_PERIL0, 4, 4), + DIV(0, "div_uart2", "mout_uart2", DIV_PERIL0, 8, 4), + DIV(0, "div_uart3", "mout_uart3", DIV_PERIL0, 12, 4), + DIV(0, "div_uart4", "mout_uart4", DIV_PERIL0, 16, 4), + DIV(0, "div_spi0", "mout_spi0", DIV_PERIL1, 0, 4), + DIV(0, "div_spi_pre0", "div_spi0", DIV_PERIL1, 8, 8), + DIV(0, "div_spi1", "mout_spi1", DIV_PERIL1, 16, 4), + DIV(0, "div_spi_pre1", "div_spi1", DIV_PERIL1, 24, 8), + DIV(0, "div_spi2", "mout_spi2", DIV_PERIL2, 0, 4), + DIV(0, "div_spi_pre2", "div_spi2", DIV_PERIL2, 8, 8), + DIV(0, "div_audio1", "mout_audio1", DIV_PERIL4, 0, 4), + DIV(0, "div_audio2", "mout_audio2", DIV_PERIL4, 16, 4), + DIV(CLK_ARM_CLK, "arm_clk", "div_core2", DIV_CPU0, 28, 3), + DIV(CLK_SCLK_APLL, "sclk_apll", "mout_apll", DIV_CPU0, 24, 3), + DIV_F(0, "div_mipi_pre0", "div_mipi0", DIV_LCD0, 20, 4, CLK_SET_RATE_PARENT, 0), - DIV_F(none, "div_mmc_pre0", "div_mmc0", DIV_FSYS1, 8, 8, + DIV_F(0, "div_mmc_pre0", "div_mmc0", DIV_FSYS1, 8, 8, CLK_SET_RATE_PARENT, 0), - DIV_F(none, "div_mmc_pre1", "div_mmc1", DIV_FSYS1, 24, 8, + DIV_F(0, "div_mmc_pre1", "div_mmc1", DIV_FSYS1, 24, 8, CLK_SET_RATE_PARENT, 0), - DIV_F(none, "div_mmc_pre2", "div_mmc2", DIV_FSYS2, 8, 8, + DIV_F(0, "div_mmc_pre2", "div_mmc2", DIV_FSYS2, 8, 8, CLK_SET_RATE_PARENT, 0), - DIV_F(none, "div_mmc_pre3", "div_mmc3", DIV_FSYS2, 24, 8, + DIV_F(0, "div_mmc_pre3", "div_mmc3", DIV_FSYS2, 24, 8, CLK_SET_RATE_PARENT, 0), }; /* list of divider clocks supported in exynos4210 soc */ static struct samsung_div_clock exynos4210_div_clks[] __initdata = { - DIV(aclk200, "aclk200", "mout_aclk200", DIV_TOP, 0, 3), - DIV(sclk_fimg2d, "sclk_fimg2d", "mout_g2d", DIV_IMAGE, 0, 4), - DIV(none, "div_fimd1", "mout_fimd1", E4210_DIV_LCD1, 0, 4), - DIV(none, "div_mipi1", "mout_mipi1", E4210_DIV_LCD1, 16, 4), - DIV(none, "div_sata", "mout_sata", DIV_FSYS0, 20, 4), - DIV_F(none, "div_mipi_pre1", "div_mipi1", E4210_DIV_LCD1, 20, 4, + DIV(CLK_ACLK200, "aclk200", "mout_aclk200", DIV_TOP, 0, 3), + DIV(CLK_SCLK_FIMG2D, "sclk_fimg2d", "mout_g2d", DIV_IMAGE, 0, 4), + DIV(0, "div_fimd1", "mout_fimd1", E4210_DIV_LCD1, 0, 4), + DIV(0, "div_mipi1", "mout_mipi1", E4210_DIV_LCD1, 16, 4), + DIV(0, "div_sata", "mout_sata", DIV_FSYS0, 20, 4), + DIV_F(0, "div_mipi_pre1", "div_mipi1", E4210_DIV_LCD1, 20, 4, CLK_SET_RATE_PARENT, 0), }; /* list of divider clocks supported in exynos4x12 soc */ static struct samsung_div_clock exynos4x12_div_clks[] __initdata = { - DIV(none, "div_mdnie0", "mout_mdnie0", DIV_LCD0, 4, 4), - DIV(none, "div_mdnie_pwm0", "mout_mdnie_pwm0", DIV_LCD0, 8, 4), - DIV(none, "div_mdnie_pwm_pre0", "div_mdnie_pwm0", DIV_LCD0, 12, 4), - DIV(none, "div_mipihsi", "mout_mipihsi", DIV_FSYS0, 20, 4), - DIV(none, "div_jpeg", "mout_jpeg", E4X12_DIV_CAM1, 0, 4), - DIV(div_aclk200, "div_aclk200", "mout_aclk200", DIV_TOP, 0, 3), - DIV(none, "div_aclk266_gps", "mout_aclk266_gps", DIV_TOP, 20, 3), - DIV(div_aclk400_mcuisp, "div_aclk400_mcuisp", "mout_aclk400_mcuisp", + DIV(0, "div_mdnie0", "mout_mdnie0", DIV_LCD0, 4, 4), + DIV(0, "div_mdnie_pwm0", "mout_mdnie_pwm0", DIV_LCD0, 8, 4), + DIV(0, "div_mdnie_pwm_pre0", "div_mdnie_pwm0", DIV_LCD0, 12, 4), + DIV(0, "div_mipihsi", "mout_mipihsi", DIV_FSYS0, 20, 4), + DIV(0, "div_jpeg", "mout_jpeg", E4X12_DIV_CAM1, 0, 4), + DIV(CLK_DIV_ACLK200, "div_aclk200", "mout_aclk200", DIV_TOP, 0, 3), + DIV(0, "div_aclk266_gps", "mout_aclk266_gps", DIV_TOP, 20, 3), + DIV(CLK_DIV_ACLK400_MCUISP, "div_aclk400_mcuisp", "mout_aclk400_mcuisp", DIV_TOP, 24, 3), - DIV(none, "div_pwm_isp", "mout_pwm_isp", E4X12_DIV_ISP, 0, 4), - DIV(none, "div_spi0_isp", "mout_spi0_isp", E4X12_DIV_ISP, 4, 4), - DIV(none, "div_spi0_isp_pre", "div_spi0_isp", E4X12_DIV_ISP, 8, 8), - DIV(none, "div_spi1_isp", "mout_spi1_isp", E4X12_DIV_ISP, 16, 4), - DIV(none, "div_spi1_isp_pre", "div_spi1_isp", E4X12_DIV_ISP, 20, 8), - DIV(none, "div_uart_isp", "mout_uart_isp", E4X12_DIV_ISP, 28, 4), - DIV_F(div_isp0, "div_isp0", "aclk200", E4X12_DIV_ISP0, 0, 3, + DIV(0, "div_pwm_isp", "mout_pwm_isp", E4X12_DIV_ISP, 0, 4), + DIV(0, "div_spi0_isp", "mout_spi0_isp", E4X12_DIV_ISP, 4, 4), + DIV(0, "div_spi0_isp_pre", "div_spi0_isp", E4X12_DIV_ISP, 8, 8), + DIV(0, "div_spi1_isp", "mout_spi1_isp", E4X12_DIV_ISP, 16, 4), + DIV(0, "div_spi1_isp_pre", "div_spi1_isp", E4X12_DIV_ISP, 20, 8), + DIV(0, "div_uart_isp", "mout_uart_isp", E4X12_DIV_ISP, 28, 4), + DIV_F(CLK_DIV_ISP0, "div_isp0", "aclk200", E4X12_DIV_ISP0, 0, 3, CLK_GET_RATE_NOCACHE, 0), - DIV_F(div_isp1, "div_isp1", "aclk200", E4X12_DIV_ISP0, 4, 3, + DIV_F(CLK_DIV_ISP1, "div_isp1", "aclk200", E4X12_DIV_ISP0, 4, 3, CLK_GET_RATE_NOCACHE, 0), - DIV(none, "div_mpwm", "div_isp1", E4X12_DIV_ISP1, 0, 3), - DIV_F(div_mcuisp0, "div_mcuisp0", "aclk400_mcuisp", E4X12_DIV_ISP1, + DIV(0, "div_mpwm", "div_isp1", E4X12_DIV_ISP1, 0, 3), + DIV_F(CLK_DIV_MCUISP0, "div_mcuisp0", "aclk400_mcuisp", E4X12_DIV_ISP1, 4, 3, CLK_GET_RATE_NOCACHE, 0), - DIV_F(div_mcuisp1, "div_mcuisp1", "div_mcuisp0", E4X12_DIV_ISP1, + DIV_F(CLK_DIV_MCUISP1, "div_mcuisp1", "div_mcuisp0", E4X12_DIV_ISP1, 8, 3, CLK_GET_RATE_NOCACHE, 0), - DIV(sclk_fimg2d, "sclk_fimg2d", "mout_g2d", DIV_DMC1, 0, 4), + DIV(CLK_SCLK_FIMG2D, "sclk_fimg2d", "mout_g2d", DIV_DMC1, 0, 4), }; /* list of gate clocks supported in all exynos4 soc's */ @@ -606,333 +545,341 @@ static struct samsung_gate_clock exynos4_gate_clks[] __initdata = { * the device name and clock alias names specified below for some * of the clocks can be removed. */ - GATE(sclk_hdmi, "sclk_hdmi", "mout_hdmi", SRC_MASK_TV, 0, 0, 0), - GATE(sclk_spdif, "sclk_spdif", "mout_spdif", SRC_MASK_PERIL1, 8, 0, 0), - GATE(jpeg, "jpeg", "aclk160", GATE_IP_CAM, 6, 0, 0), - GATE(mie0, "mie0", "aclk160", GATE_IP_LCD0, 1, 0, 0), - GATE(dsim0, "dsim0", "aclk160", GATE_IP_LCD0, 3, 0, 0), - GATE(fimd1, "fimd1", "aclk160", E4210_GATE_IP_LCD1, 0, 0, 0), - GATE(mie1, "mie1", "aclk160", E4210_GATE_IP_LCD1, 1, 0, 0), - GATE(dsim1, "dsim1", "aclk160", E4210_GATE_IP_LCD1, 3, 0, 0), - GATE(smmu_fimd1, "smmu_fimd1", "aclk160", E4210_GATE_IP_LCD1, 4, 0, 0), - GATE(tsi, "tsi", "aclk133", GATE_IP_FSYS, 4, 0, 0), - GATE(sromc, "sromc", "aclk133", GATE_IP_FSYS, 11, 0, 0), - GATE(sclk_g3d, "sclk_g3d", "div_g3d", GATE_IP_G3D, 0, + GATE(CLK_SCLK_HDMI, "sclk_hdmi", "mout_hdmi", SRC_MASK_TV, 0, 0, 0), + GATE(CLK_SCLK_SPDIF, "sclk_spdif", "mout_spdif", SRC_MASK_PERIL1, 8, 0, + 0), + GATE(CLK_JPEG, "jpeg", "aclk160", GATE_IP_CAM, 6, 0, 0), + GATE(CLK_MIE0, "mie0", "aclk160", GATE_IP_LCD0, 1, 0, 0), + GATE(CLK_DSIM0, "dsim0", "aclk160", GATE_IP_LCD0, 3, 0, 0), + GATE(CLK_FIMD1, "fimd1", "aclk160", E4210_GATE_IP_LCD1, 0, 0, 0), + GATE(CLK_MIE1, "mie1", "aclk160", E4210_GATE_IP_LCD1, 1, 0, 0), + GATE(CLK_DSIM1, "dsim1", "aclk160", E4210_GATE_IP_LCD1, 3, 0, 0), + GATE(CLK_SMMU_FIMD1, "smmu_fimd1", "aclk160", E4210_GATE_IP_LCD1, 4, 0, + 0), + GATE(CLK_TSI, "tsi", "aclk133", GATE_IP_FSYS, 4, 0, 0), + GATE(CLK_SROMC, "sromc", "aclk133", GATE_IP_FSYS, 11, 0, 0), + GATE(CLK_SCLK_G3D, "sclk_g3d", "div_g3d", GATE_IP_G3D, 0, CLK_SET_RATE_PARENT, 0), - GATE(usb_device, "usb_device", "aclk133", GATE_IP_FSYS, 13, 0, 0), - GATE(onenand, "onenand", "aclk133", GATE_IP_FSYS, 15, 0, 0), - GATE(nfcon, "nfcon", "aclk133", GATE_IP_FSYS, 16, 0, 0), - GATE(gps, "gps", "aclk133", GATE_IP_GPS, 0, 0, 0), - GATE(smmu_gps, "smmu_gps", "aclk133", GATE_IP_GPS, 1, 0, 0), - GATE(slimbus, "slimbus", "aclk100", GATE_IP_PERIL, 25, 0, 0), - GATE(sclk_cam0, "sclk_cam0", "div_cam0", GATE_SCLK_CAM, 4, + GATE(CLK_USB_DEVICE, "usb_device", "aclk133", GATE_IP_FSYS, 13, 0, 0), + GATE(CLK_ONENAND, "onenand", "aclk133", GATE_IP_FSYS, 15, 0, 0), + GATE(CLK_NFCON, "nfcon", "aclk133", GATE_IP_FSYS, 16, 0, 0), + GATE(CLK_GPS, "gps", "aclk133", GATE_IP_GPS, 0, 0, 0), + GATE(CLK_SMMU_GPS, "smmu_gps", "aclk133", GATE_IP_GPS, 1, 0, 0), + GATE(CLK_SLIMBUS, "slimbus", "aclk100", GATE_IP_PERIL, 25, 0, 0), + GATE(CLK_SCLK_CAM0, "sclk_cam0", "div_cam0", GATE_SCLK_CAM, 4, CLK_SET_RATE_PARENT, 0), - GATE(sclk_cam1, "sclk_cam1", "div_cam1", GATE_SCLK_CAM, 5, + GATE(CLK_SCLK_CAM1, "sclk_cam1", "div_cam1", GATE_SCLK_CAM, 5, CLK_SET_RATE_PARENT, 0), - GATE(sclk_mipi0, "sclk_mipi0", "div_mipi_pre0", + GATE(CLK_SCLK_MIPI0, "sclk_mipi0", "div_mipi_pre0", SRC_MASK_LCD0, 12, CLK_SET_RATE_PARENT, 0), - GATE(sclk_audio0, "sclk_audio0", "div_audio0", SRC_MASK_MAUDIO, 0, + GATE(CLK_SCLK_AUDIO0, "sclk_audio0", "div_audio0", SRC_MASK_MAUDIO, 0, CLK_SET_RATE_PARENT, 0), - GATE(sclk_audio1, "sclk_audio1", "div_audio1", SRC_MASK_PERIL1, 0, + GATE(CLK_SCLK_AUDIO1, "sclk_audio1", "div_audio1", SRC_MASK_PERIL1, 0, CLK_SET_RATE_PARENT, 0), - GATE(vp, "vp", "aclk160", GATE_IP_TV, 0, 0, 0), - GATE(mixer, "mixer", "aclk160", GATE_IP_TV, 1, 0, 0), - GATE(hdmi, "hdmi", "aclk160", GATE_IP_TV, 3, 0, 0), - GATE(pwm, "pwm", "aclk100", GATE_IP_PERIL, 24, 0, 0), - GATE(sdmmc4, "sdmmc4", "aclk133", GATE_IP_FSYS, 9, 0, 0), - GATE(usb_host, "usb_host", "aclk133", GATE_IP_FSYS, 12, 0, 0), - GATE(sclk_fimc0, "sclk_fimc0", "div_fimc0", SRC_MASK_CAM, 0, + GATE(CLK_VP, "vp", "aclk160", GATE_IP_TV, 0, 0, 0), + GATE(CLK_MIXER, "mixer", "aclk160", GATE_IP_TV, 1, 0, 0), + GATE(CLK_HDMI, "hdmi", "aclk160", GATE_IP_TV, 3, 0, 0), + GATE(CLK_PWM, "pwm", "aclk100", GATE_IP_PERIL, 24, 0, 0), + GATE(CLK_SDMMC4, "sdmmc4", "aclk133", GATE_IP_FSYS, 9, 0, 0), + GATE(CLK_USB_HOST, "usb_host", "aclk133", GATE_IP_FSYS, 12, 0, 0), + GATE(CLK_SCLK_FIMC0, "sclk_fimc0", "div_fimc0", SRC_MASK_CAM, 0, CLK_SET_RATE_PARENT, 0), - GATE(sclk_fimc1, "sclk_fimc1", "div_fimc1", SRC_MASK_CAM, 4, + GATE(CLK_SCLK_FIMC1, "sclk_fimc1", "div_fimc1", SRC_MASK_CAM, 4, CLK_SET_RATE_PARENT, 0), - GATE(sclk_fimc2, "sclk_fimc2", "div_fimc2", SRC_MASK_CAM, 8, + GATE(CLK_SCLK_FIMC2, "sclk_fimc2", "div_fimc2", SRC_MASK_CAM, 8, CLK_SET_RATE_PARENT, 0), - GATE(sclk_fimc3, "sclk_fimc3", "div_fimc3", SRC_MASK_CAM, 12, + GATE(CLK_SCLK_FIMC3, "sclk_fimc3", "div_fimc3", SRC_MASK_CAM, 12, CLK_SET_RATE_PARENT, 0), - GATE(sclk_csis0, "sclk_csis0", "div_csis0", SRC_MASK_CAM, 24, + GATE(CLK_SCLK_CSIS0, "sclk_csis0", "div_csis0", SRC_MASK_CAM, 24, CLK_SET_RATE_PARENT, 0), - GATE(sclk_csis1, "sclk_csis1", "div_csis1", SRC_MASK_CAM, 28, + GATE(CLK_SCLK_CSIS1, "sclk_csis1", "div_csis1", SRC_MASK_CAM, 28, CLK_SET_RATE_PARENT, 0), - GATE(sclk_fimd0, "sclk_fimd0", "div_fimd0", SRC_MASK_LCD0, 0, + GATE(CLK_SCLK_FIMD0, "sclk_fimd0", "div_fimd0", SRC_MASK_LCD0, 0, CLK_SET_RATE_PARENT, 0), - GATE(sclk_mmc0, "sclk_mmc0", "div_mmc_pre0", SRC_MASK_FSYS, 0, + GATE(CLK_SCLK_MMC0, "sclk_mmc0", "div_mmc_pre0", SRC_MASK_FSYS, 0, CLK_SET_RATE_PARENT, 0), - GATE(sclk_mmc1, "sclk_mmc1", "div_mmc_pre1", SRC_MASK_FSYS, 4, + GATE(CLK_SCLK_MMC1, "sclk_mmc1", "div_mmc_pre1", SRC_MASK_FSYS, 4, CLK_SET_RATE_PARENT, 0), - GATE(sclk_mmc2, "sclk_mmc2", "div_mmc_pre2", SRC_MASK_FSYS, 8, + GATE(CLK_SCLK_MMC2, "sclk_mmc2", "div_mmc_pre2", SRC_MASK_FSYS, 8, CLK_SET_RATE_PARENT, 0), - GATE(sclk_mmc3, "sclk_mmc3", "div_mmc_pre3", SRC_MASK_FSYS, 12, + GATE(CLK_SCLK_MMC3, "sclk_mmc3", "div_mmc_pre3", SRC_MASK_FSYS, 12, CLK_SET_RATE_PARENT, 0), - GATE(sclk_mmc4, "sclk_mmc4", "div_mmc_pre4", SRC_MASK_FSYS, 16, + GATE(CLK_SCLK_MMC4, "sclk_mmc4", "div_mmc_pre4", SRC_MASK_FSYS, 16, CLK_SET_RATE_PARENT, 0), - GATE(sclk_uart0, "uclk0", "div_uart0", SRC_MASK_PERIL0, 0, + GATE(CLK_SCLK_UART0, "uclk0", "div_uart0", SRC_MASK_PERIL0, 0, CLK_SET_RATE_PARENT, 0), - GATE(sclk_uart1, "uclk1", "div_uart1", SRC_MASK_PERIL0, 4, + GATE(CLK_SCLK_UART1, "uclk1", "div_uart1", SRC_MASK_PERIL0, 4, CLK_SET_RATE_PARENT, 0), - GATE(sclk_uart2, "uclk2", "div_uart2", SRC_MASK_PERIL0, 8, + GATE(CLK_SCLK_UART2, "uclk2", "div_uart2", SRC_MASK_PERIL0, 8, CLK_SET_RATE_PARENT, 0), - GATE(sclk_uart3, "uclk3", "div_uart3", SRC_MASK_PERIL0, 12, + GATE(CLK_SCLK_UART3, "uclk3", "div_uart3", SRC_MASK_PERIL0, 12, CLK_SET_RATE_PARENT, 0), - GATE(sclk_uart4, "uclk4", "div_uart4", SRC_MASK_PERIL0, 16, + GATE(CLK_SCLK_UART4, "uclk4", "div_uart4", SRC_MASK_PERIL0, 16, CLK_SET_RATE_PARENT, 0), - GATE(sclk_audio2, "sclk_audio2", "div_audio2", SRC_MASK_PERIL1, 4, + GATE(CLK_SCLK_AUDIO2, "sclk_audio2", "div_audio2", SRC_MASK_PERIL1, 4, CLK_SET_RATE_PARENT, 0), - GATE(sclk_spi0, "sclk_spi0", "div_spi_pre0", SRC_MASK_PERIL1, 16, + GATE(CLK_SCLK_SPI0, "sclk_spi0", "div_spi_pre0", SRC_MASK_PERIL1, 16, CLK_SET_RATE_PARENT, 0), - GATE(sclk_spi1, "sclk_spi1", "div_spi_pre1", SRC_MASK_PERIL1, 20, + GATE(CLK_SCLK_SPI1, "sclk_spi1", "div_spi_pre1", SRC_MASK_PERIL1, 20, CLK_SET_RATE_PARENT, 0), - GATE(sclk_spi2, "sclk_spi2", "div_spi_pre2", SRC_MASK_PERIL1, 24, + GATE(CLK_SCLK_SPI2, "sclk_spi2", "div_spi_pre2", SRC_MASK_PERIL1, 24, CLK_SET_RATE_PARENT, 0), - GATE(fimc0, "fimc0", "aclk160", GATE_IP_CAM, 0, + GATE(CLK_FIMC0, "fimc0", "aclk160", GATE_IP_CAM, 0, 0, 0), - GATE(fimc1, "fimc1", "aclk160", GATE_IP_CAM, 1, + GATE(CLK_FIMC1, "fimc1", "aclk160", GATE_IP_CAM, 1, 0, 0), - GATE(fimc2, "fimc2", "aclk160", GATE_IP_CAM, 2, + GATE(CLK_FIMC2, "fimc2", "aclk160", GATE_IP_CAM, 2, 0, 0), - GATE(fimc3, "fimc3", "aclk160", GATE_IP_CAM, 3, + GATE(CLK_FIMC3, "fimc3", "aclk160", GATE_IP_CAM, 3, 0, 0), - GATE(csis0, "csis0", "aclk160", GATE_IP_CAM, 4, + GATE(CLK_CSIS0, "csis0", "aclk160", GATE_IP_CAM, 4, 0, 0), - GATE(csis1, "csis1", "aclk160", GATE_IP_CAM, 5, + GATE(CLK_CSIS1, "csis1", "aclk160", GATE_IP_CAM, 5, 0, 0), - GATE(smmu_fimc0, "smmu_fimc0", "aclk160", GATE_IP_CAM, 7, + GATE(CLK_SMMU_FIMC0, "smmu_fimc0", "aclk160", GATE_IP_CAM, 7, 0, 0), - GATE(smmu_fimc1, "smmu_fimc1", "aclk160", GATE_IP_CAM, 8, + GATE(CLK_SMMU_FIMC1, "smmu_fimc1", "aclk160", GATE_IP_CAM, 8, 0, 0), - GATE(smmu_fimc2, "smmu_fimc2", "aclk160", GATE_IP_CAM, 9, + GATE(CLK_SMMU_FIMC2, "smmu_fimc2", "aclk160", GATE_IP_CAM, 9, 0, 0), - GATE(smmu_fimc3, "smmu_fimc3", "aclk160", GATE_IP_CAM, 10, + GATE(CLK_SMMU_FIMC3, "smmu_fimc3", "aclk160", GATE_IP_CAM, 10, 0, 0), - GATE(smmu_jpeg, "smmu_jpeg", "aclk160", GATE_IP_CAM, 11, + GATE(CLK_SMMU_JPEG, "smmu_jpeg", "aclk160", GATE_IP_CAM, 11, 0, 0), - GATE(pixelasyncm0, "pxl_async0", "aclk160", GATE_IP_CAM, 17, 0, 0), - GATE(pixelasyncm1, "pxl_async1", "aclk160", GATE_IP_CAM, 18, 0, 0), - GATE(smmu_tv, "smmu_tv", "aclk160", GATE_IP_TV, 4, + GATE(CLK_PIXELASYNCM0, "pxl_async0", "aclk160", GATE_IP_CAM, 17, 0, 0), + GATE(CLK_PIXELASYNCM1, "pxl_async1", "aclk160", GATE_IP_CAM, 18, 0, 0), + GATE(CLK_SMMU_TV, "smmu_tv", "aclk160", GATE_IP_TV, 4, 0, 0), - GATE(mfc, "mfc", "aclk100", GATE_IP_MFC, 0, 0, 0), - GATE(smmu_mfcl, "smmu_mfcl", "aclk100", GATE_IP_MFC, 1, + GATE(CLK_MFC, "mfc", "aclk100", GATE_IP_MFC, 0, 0, 0), + GATE(CLK_SMMU_MFCL, "smmu_mfcl", "aclk100", GATE_IP_MFC, 1, 0, 0), - GATE(smmu_mfcr, "smmu_mfcr", "aclk100", GATE_IP_MFC, 2, + GATE(CLK_SMMU_MFCR, "smmu_mfcr", "aclk100", GATE_IP_MFC, 2, 0, 0), - GATE(fimd0, "fimd0", "aclk160", GATE_IP_LCD0, 0, + GATE(CLK_FIMD0, "fimd0", "aclk160", GATE_IP_LCD0, 0, 0, 0), - GATE(smmu_fimd0, "smmu_fimd0", "aclk160", GATE_IP_LCD0, 4, + GATE(CLK_SMMU_FIMD0, "smmu_fimd0", "aclk160", GATE_IP_LCD0, 4, 0, 0), - GATE(pdma0, "pdma0", "aclk133", GATE_IP_FSYS, 0, + GATE(CLK_PDMA0, "pdma0", "aclk133", GATE_IP_FSYS, 0, 0, 0), - GATE(pdma1, "pdma1", "aclk133", GATE_IP_FSYS, 1, + GATE(CLK_PDMA1, "pdma1", "aclk133", GATE_IP_FSYS, 1, 0, 0), - GATE(sdmmc0, "sdmmc0", "aclk133", GATE_IP_FSYS, 5, + GATE(CLK_SDMMC0, "sdmmc0", "aclk133", GATE_IP_FSYS, 5, 0, 0), - GATE(sdmmc1, "sdmmc1", "aclk133", GATE_IP_FSYS, 6, + GATE(CLK_SDMMC1, "sdmmc1", "aclk133", GATE_IP_FSYS, 6, 0, 0), - GATE(sdmmc2, "sdmmc2", "aclk133", GATE_IP_FSYS, 7, + GATE(CLK_SDMMC2, "sdmmc2", "aclk133", GATE_IP_FSYS, 7, 0, 0), - GATE(sdmmc3, "sdmmc3", "aclk133", GATE_IP_FSYS, 8, + GATE(CLK_SDMMC3, "sdmmc3", "aclk133", GATE_IP_FSYS, 8, 0, 0), - GATE(uart0, "uart0", "aclk100", GATE_IP_PERIL, 0, + GATE(CLK_UART0, "uart0", "aclk100", GATE_IP_PERIL, 0, 0, 0), - GATE(uart1, "uart1", "aclk100", GATE_IP_PERIL, 1, + GATE(CLK_UART1, "uart1", "aclk100", GATE_IP_PERIL, 1, 0, 0), - GATE(uart2, "uart2", "aclk100", GATE_IP_PERIL, 2, + GATE(CLK_UART2, "uart2", "aclk100", GATE_IP_PERIL, 2, 0, 0), - GATE(uart3, "uart3", "aclk100", GATE_IP_PERIL, 3, + GATE(CLK_UART3, "uart3", "aclk100", GATE_IP_PERIL, 3, 0, 0), - GATE(uart4, "uart4", "aclk100", GATE_IP_PERIL, 4, + GATE(CLK_UART4, "uart4", "aclk100", GATE_IP_PERIL, 4, 0, 0), - GATE(i2c0, "i2c0", "aclk100", GATE_IP_PERIL, 6, + GATE(CLK_I2C0, "i2c0", "aclk100", GATE_IP_PERIL, 6, 0, 0), - GATE(i2c1, "i2c1", "aclk100", GATE_IP_PERIL, 7, + GATE(CLK_I2C1, "i2c1", "aclk100", GATE_IP_PERIL, 7, 0, 0), - GATE(i2c2, "i2c2", "aclk100", GATE_IP_PERIL, 8, + GATE(CLK_I2C2, "i2c2", "aclk100", GATE_IP_PERIL, 8, 0, 0), - GATE(i2c3, "i2c3", "aclk100", GATE_IP_PERIL, 9, + GATE(CLK_I2C3, "i2c3", "aclk100", GATE_IP_PERIL, 9, 0, 0), - GATE(i2c4, "i2c4", "aclk100", GATE_IP_PERIL, 10, + GATE(CLK_I2C4, "i2c4", "aclk100", GATE_IP_PERIL, 10, 0, 0), - GATE(i2c5, "i2c5", "aclk100", GATE_IP_PERIL, 11, + GATE(CLK_I2C5, "i2c5", "aclk100", GATE_IP_PERIL, 11, 0, 0), - GATE(i2c6, "i2c6", "aclk100", GATE_IP_PERIL, 12, + GATE(CLK_I2C6, "i2c6", "aclk100", GATE_IP_PERIL, 12, 0, 0), - GATE(i2c7, "i2c7", "aclk100", GATE_IP_PERIL, 13, + GATE(CLK_I2C7, "i2c7", "aclk100", GATE_IP_PERIL, 13, 0, 0), - GATE(i2c_hdmi, "i2c-hdmi", "aclk100", GATE_IP_PERIL, 14, + GATE(CLK_I2C_HDMI, "i2c-hdmi", "aclk100", GATE_IP_PERIL, 14, 0, 0), - GATE(spi0, "spi0", "aclk100", GATE_IP_PERIL, 16, + GATE(CLK_SPI0, "spi0", "aclk100", GATE_IP_PERIL, 16, 0, 0), - GATE(spi1, "spi1", "aclk100", GATE_IP_PERIL, 17, + GATE(CLK_SPI1, "spi1", "aclk100", GATE_IP_PERIL, 17, 0, 0), - GATE(spi2, "spi2", "aclk100", GATE_IP_PERIL, 18, + GATE(CLK_SPI2, "spi2", "aclk100", GATE_IP_PERIL, 18, 0, 0), - GATE(i2s1, "i2s1", "aclk100", GATE_IP_PERIL, 20, + GATE(CLK_I2S1, "i2s1", "aclk100", GATE_IP_PERIL, 20, 0, 0), - GATE(i2s2, "i2s2", "aclk100", GATE_IP_PERIL, 21, + GATE(CLK_I2S2, "i2s2", "aclk100", GATE_IP_PERIL, 21, 0, 0), - GATE(pcm1, "pcm1", "aclk100", GATE_IP_PERIL, 22, + GATE(CLK_PCM1, "pcm1", "aclk100", GATE_IP_PERIL, 22, 0, 0), - GATE(pcm2, "pcm2", "aclk100", GATE_IP_PERIL, 23, + GATE(CLK_PCM2, "pcm2", "aclk100", GATE_IP_PERIL, 23, 0, 0), - GATE(spdif, "spdif", "aclk100", GATE_IP_PERIL, 26, + GATE(CLK_SPDIF, "spdif", "aclk100", GATE_IP_PERIL, 26, 0, 0), - GATE(ac97, "ac97", "aclk100", GATE_IP_PERIL, 27, + GATE(CLK_AC97, "ac97", "aclk100", GATE_IP_PERIL, 27, 0, 0), }; /* list of gate clocks supported in exynos4210 soc */ static struct samsung_gate_clock exynos4210_gate_clks[] __initdata = { - GATE(tvenc, "tvenc", "aclk160", GATE_IP_TV, 2, 0, 0), - GATE(g2d, "g2d", "aclk200", E4210_GATE_IP_IMAGE, 0, 0, 0), - GATE(rotator, "rotator", "aclk200", E4210_GATE_IP_IMAGE, 1, 0, 0), - GATE(mdma, "mdma", "aclk200", E4210_GATE_IP_IMAGE, 2, 0, 0), - GATE(smmu_g2d, "smmu_g2d", "aclk200", E4210_GATE_IP_IMAGE, 3, 0, 0), - GATE(smmu_mdma, "smmu_mdma", "aclk200", E4210_GATE_IP_IMAGE, 5, 0, 0), - GATE(pcie_phy, "pcie_phy", "aclk133", GATE_IP_FSYS, 2, 0, 0), - GATE(sata_phy, "sata_phy", "aclk133", GATE_IP_FSYS, 3, 0, 0), - GATE(sata, "sata", "aclk133", GATE_IP_FSYS, 10, 0, 0), - GATE(pcie, "pcie", "aclk133", GATE_IP_FSYS, 14, 0, 0), - GATE(smmu_pcie, "smmu_pcie", "aclk133", GATE_IP_FSYS, 18, 0, 0), - GATE(modemif, "modemif", "aclk100", GATE_IP_PERIL, 28, 0, 0), - GATE(chipid, "chipid", "aclk100", E4210_GATE_IP_PERIR, 0, 0, 0), - GATE(sysreg, "sysreg", "aclk100", E4210_GATE_IP_PERIR, 0, + GATE(CLK_TVENC, "tvenc", "aclk160", GATE_IP_TV, 2, 0, 0), + GATE(CLK_G2D, "g2d", "aclk200", E4210_GATE_IP_IMAGE, 0, 0, 0), + GATE(CLK_ROTATOR, "rotator", "aclk200", E4210_GATE_IP_IMAGE, 1, 0, 0), + GATE(CLK_MDMA, "mdma", "aclk200", E4210_GATE_IP_IMAGE, 2, 0, 0), + GATE(CLK_SMMU_G2D, "smmu_g2d", "aclk200", E4210_GATE_IP_IMAGE, 3, 0, 0), + GATE(CLK_SMMU_MDMA, "smmu_mdma", "aclk200", E4210_GATE_IP_IMAGE, 5, 0, + 0), + GATE(CLK_PCIE_PHY, "pcie_phy", "aclk133", GATE_IP_FSYS, 2, 0, 0), + GATE(CLK_SATA_PHY, "sata_phy", "aclk133", GATE_IP_FSYS, 3, 0, 0), + GATE(CLK_SATA, "sata", "aclk133", GATE_IP_FSYS, 10, 0, 0), + GATE(CLK_PCIE, "pcie", "aclk133", GATE_IP_FSYS, 14, 0, 0), + GATE(CLK_SMMU_PCIE, "smmu_pcie", "aclk133", GATE_IP_FSYS, 18, 0, 0), + GATE(CLK_MODEMIF, "modemif", "aclk100", GATE_IP_PERIL, 28, 0, 0), + GATE(CLK_CHIPID, "chipid", "aclk100", E4210_GATE_IP_PERIR, 0, 0, 0), + GATE(CLK_SYSREG, "sysreg", "aclk100", E4210_GATE_IP_PERIR, 0, CLK_IGNORE_UNUSED, 0), - GATE(hdmi_cec, "hdmi_cec", "aclk100", E4210_GATE_IP_PERIR, 11, 0, 0), - GATE(smmu_rotator, "smmu_rotator", "aclk200", + GATE(CLK_HDMI_CEC, "hdmi_cec", "aclk100", E4210_GATE_IP_PERIR, 11, 0, + 0), + GATE(CLK_SMMU_ROTATOR, "smmu_rotator", "aclk200", E4210_GATE_IP_IMAGE, 4, 0, 0), - GATE(sclk_mipi1, "sclk_mipi1", "div_mipi_pre1", + GATE(CLK_SCLK_MIPI1, "sclk_mipi1", "div_mipi_pre1", E4210_SRC_MASK_LCD1, 12, CLK_SET_RATE_PARENT, 0), - GATE(sclk_sata, "sclk_sata", "div_sata", + GATE(CLK_SCLK_SATA, "sclk_sata", "div_sata", SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0), - GATE(sclk_mixer, "sclk_mixer", "mout_mixer", SRC_MASK_TV, 4, 0, 0), - GATE(sclk_dac, "sclk_dac", "mout_dac", SRC_MASK_TV, 8, 0, 0), - GATE(tsadc, "tsadc", "aclk100", GATE_IP_PERIL, 15, + GATE(CLK_SCLK_MIXER, "sclk_mixer", "mout_mixer", SRC_MASK_TV, 4, 0, 0), + GATE(CLK_SCLK_DAC, "sclk_dac", "mout_dac", SRC_MASK_TV, 8, 0, 0), + GATE(CLK_TSADC, "tsadc", "aclk100", GATE_IP_PERIL, 15, 0, 0), - GATE(mct, "mct", "aclk100", E4210_GATE_IP_PERIR, 13, + GATE(CLK_MCT, "mct", "aclk100", E4210_GATE_IP_PERIR, 13, 0, 0), - GATE(wdt, "watchdog", "aclk100", E4210_GATE_IP_PERIR, 14, + GATE(CLK_WDT, "watchdog", "aclk100", E4210_GATE_IP_PERIR, 14, 0, 0), - GATE(rtc, "rtc", "aclk100", E4210_GATE_IP_PERIR, 15, + GATE(CLK_RTC, "rtc", "aclk100", E4210_GATE_IP_PERIR, 15, 0, 0), - GATE(keyif, "keyif", "aclk100", E4210_GATE_IP_PERIR, 16, + GATE(CLK_KEYIF, "keyif", "aclk100", E4210_GATE_IP_PERIR, 16, 0, 0), - GATE(sclk_fimd1, "sclk_fimd1", "div_fimd1", E4210_SRC_MASK_LCD1, 0, + GATE(CLK_SCLK_FIMD1, "sclk_fimd1", "div_fimd1", E4210_SRC_MASK_LCD1, 0, CLK_SET_RATE_PARENT, 0), - GATE(tmu_apbif, "tmu_apbif", "aclk100", E4210_GATE_IP_PERIR, 17, 0, 0), + GATE(CLK_TMU_APBIF, "tmu_apbif", "aclk100", E4210_GATE_IP_PERIR, 17, 0, + 0), }; /* list of gate clocks supported in exynos4x12 soc */ static struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = { - GATE(audss, "audss", "sclk_epll", E4X12_GATE_IP_MAUDIO, 0, 0, 0), - GATE(mdnie0, "mdnie0", "aclk160", GATE_IP_LCD0, 2, 0, 0), - GATE(rotator, "rotator", "aclk200", E4X12_GATE_IP_IMAGE, 1, 0, 0), - GATE(mdma2, "mdma2", "aclk200", E4X12_GATE_IP_IMAGE, 2, 0, 0), - GATE(smmu_mdma, "smmu_mdma", "aclk200", E4X12_GATE_IP_IMAGE, 5, 0, 0), - GATE(mipi_hsi, "mipi_hsi", "aclk133", GATE_IP_FSYS, 10, 0, 0), - GATE(chipid, "chipid", "aclk100", E4X12_GATE_IP_PERIR, 0, 0, 0), - GATE(sysreg, "sysreg", "aclk100", E4X12_GATE_IP_PERIR, 1, + GATE(CLK_AUDSS, "audss", "sclk_epll", E4X12_GATE_IP_MAUDIO, 0, 0, 0), + GATE(CLK_MDNIE0, "mdnie0", "aclk160", GATE_IP_LCD0, 2, 0, 0), + GATE(CLK_ROTATOR, "rotator", "aclk200", E4X12_GATE_IP_IMAGE, 1, 0, 0), + GATE(CLK_MDMA2, "mdma2", "aclk200", E4X12_GATE_IP_IMAGE, 2, 0, 0), + GATE(CLK_SMMU_MDMA, "smmu_mdma", "aclk200", E4X12_GATE_IP_IMAGE, 5, 0, + 0), + GATE(CLK_MIPI_HSI, "mipi_hsi", "aclk133", GATE_IP_FSYS, 10, 0, 0), + GATE(CLK_CHIPID, "chipid", "aclk100", E4X12_GATE_IP_PERIR, 0, 0, 0), + GATE(CLK_SYSREG, "sysreg", "aclk100", E4X12_GATE_IP_PERIR, 1, CLK_IGNORE_UNUSED, 0), - GATE(hdmi_cec, "hdmi_cec", "aclk100", E4X12_GATE_IP_PERIR, 11, 0, 0), - GATE(sclk_mdnie0, "sclk_mdnie0", "div_mdnie0", + GATE(CLK_HDMI_CEC, "hdmi_cec", "aclk100", E4X12_GATE_IP_PERIR, 11, 0, + 0), + GATE(CLK_SCLK_MDNIE0, "sclk_mdnie0", "div_mdnie0", SRC_MASK_LCD0, 4, CLK_SET_RATE_PARENT, 0), - GATE(sclk_mdnie_pwm0, "sclk_mdnie_pwm0", "div_mdnie_pwm_pre0", + GATE(CLK_SCLK_MDNIE_PWM0, "sclk_mdnie_pwm0", "div_mdnie_pwm_pre0", SRC_MASK_LCD0, 8, CLK_SET_RATE_PARENT, 0), - GATE(sclk_mipihsi, "sclk_mipihsi", "div_mipihsi", + GATE(CLK_SCLK_MIPIHSI, "sclk_mipihsi", "div_mipihsi", SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0), - GATE(smmu_rotator, "smmu_rotator", "aclk200", + GATE(CLK_SMMU_ROTATOR, "smmu_rotator", "aclk200", E4X12_GATE_IP_IMAGE, 4, 0, 0), - GATE(mct, "mct", "aclk100", E4X12_GATE_IP_PERIR, 13, + GATE(CLK_MCT, "mct", "aclk100", E4X12_GATE_IP_PERIR, 13, 0, 0), - GATE(rtc, "rtc", "aclk100", E4X12_GATE_IP_PERIR, 15, + GATE(CLK_RTC, "rtc", "aclk100", E4X12_GATE_IP_PERIR, 15, 0, 0), - GATE(keyif, "keyif", "aclk100", E4X12_GATE_IP_PERIR, 16, 0, 0), - GATE(sclk_pwm_isp, "sclk_pwm_isp", "div_pwm_isp", + GATE(CLK_KEYIF, "keyif", "aclk100", E4X12_GATE_IP_PERIR, 16, 0, 0), + GATE(CLK_SCLK_PWM_ISP, "sclk_pwm_isp", "div_pwm_isp", E4X12_SRC_MASK_ISP, 0, CLK_SET_RATE_PARENT, 0), - GATE(sclk_spi0_isp, "sclk_spi0_isp", "div_spi0_isp_pre", + GATE(CLK_SCLK_SPI0_ISP, "sclk_spi0_isp", "div_spi0_isp_pre", E4X12_SRC_MASK_ISP, 4, CLK_SET_RATE_PARENT, 0), - GATE(sclk_spi1_isp, "sclk_spi1_isp", "div_spi1_isp_pre", + GATE(CLK_SCLK_SPI1_ISP, "sclk_spi1_isp", "div_spi1_isp_pre", E4X12_SRC_MASK_ISP, 8, CLK_SET_RATE_PARENT, 0), - GATE(sclk_uart_isp, "sclk_uart_isp", "div_uart_isp", + GATE(CLK_SCLK_UART_ISP, "sclk_uart_isp", "div_uart_isp", E4X12_SRC_MASK_ISP, 12, CLK_SET_RATE_PARENT, 0), - GATE(pwm_isp_sclk, "pwm_isp_sclk", "sclk_pwm_isp", + GATE(CLK_PWM_ISP_SCLK, "pwm_isp_sclk", "sclk_pwm_isp", E4X12_GATE_IP_ISP, 0, 0, 0), - GATE(spi0_isp_sclk, "spi0_isp_sclk", "sclk_spi0_isp", + GATE(CLK_SPI0_ISP_SCLK, "spi0_isp_sclk", "sclk_spi0_isp", E4X12_GATE_IP_ISP, 1, 0, 0), - GATE(spi1_isp_sclk, "spi1_isp_sclk", "sclk_spi1_isp", + GATE(CLK_SPI1_ISP_SCLK, "spi1_isp_sclk", "sclk_spi1_isp", E4X12_GATE_IP_ISP, 2, 0, 0), - GATE(uart_isp_sclk, "uart_isp_sclk", "sclk_uart_isp", + GATE(CLK_UART_ISP_SCLK, "uart_isp_sclk", "sclk_uart_isp", E4X12_GATE_IP_ISP, 3, 0, 0), - GATE(wdt, "watchdog", "aclk100", E4X12_GATE_IP_PERIR, 14, 0, 0), - GATE(pcm0, "pcm0", "aclk100", E4X12_GATE_IP_MAUDIO, 2, + GATE(CLK_WDT, "watchdog", "aclk100", E4X12_GATE_IP_PERIR, 14, 0, 0), + GATE(CLK_PCM0, "pcm0", "aclk100", E4X12_GATE_IP_MAUDIO, 2, 0, 0), - GATE(i2s0, "i2s0", "aclk100", E4X12_GATE_IP_MAUDIO, 3, + GATE(CLK_I2S0, "i2s0", "aclk100", E4X12_GATE_IP_MAUDIO, 3, 0, 0), - GATE(fimc_isp, "isp", "aclk200", E4X12_GATE_ISP0, 0, + GATE(CLK_FIMC_ISP, "isp", "aclk200", E4X12_GATE_ISP0, 0, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(fimc_drc, "drc", "aclk200", E4X12_GATE_ISP0, 1, + GATE(CLK_FIMC_DRC, "drc", "aclk200", E4X12_GATE_ISP0, 1, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(fimc_fd, "fd", "aclk200", E4X12_GATE_ISP0, 2, + GATE(CLK_FIMC_FD, "fd", "aclk200", E4X12_GATE_ISP0, 2, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(fimc_lite0, "lite0", "aclk200", E4X12_GATE_ISP0, 3, + GATE(CLK_FIMC_LITE0, "lite0", "aclk200", E4X12_GATE_ISP0, 3, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(fimc_lite1, "lite1", "aclk200", E4X12_GATE_ISP0, 4, + GATE(CLK_FIMC_LITE1, "lite1", "aclk200", E4X12_GATE_ISP0, 4, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(mcuisp, "mcuisp", "aclk200", E4X12_GATE_ISP0, 5, + GATE(CLK_MCUISP, "mcuisp", "aclk200", E4X12_GATE_ISP0, 5, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(gicisp, "gicisp", "aclk200", E4X12_GATE_ISP0, 7, + GATE(CLK_GICISP, "gicisp", "aclk200", E4X12_GATE_ISP0, 7, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(smmu_isp, "smmu_isp", "aclk200", E4X12_GATE_ISP0, 8, + GATE(CLK_SMMU_ISP, "smmu_isp", "aclk200", E4X12_GATE_ISP0, 8, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(smmu_drc, "smmu_drc", "aclk200", E4X12_GATE_ISP0, 9, + GATE(CLK_SMMU_DRC, "smmu_drc", "aclk200", E4X12_GATE_ISP0, 9, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(smmu_fd, "smmu_fd", "aclk200", E4X12_GATE_ISP0, 10, + GATE(CLK_SMMU_FD, "smmu_fd", "aclk200", E4X12_GATE_ISP0, 10, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(smmu_lite0, "smmu_lite0", "aclk200", E4X12_GATE_ISP0, 11, + GATE(CLK_SMMU_LITE0, "smmu_lite0", "aclk200", E4X12_GATE_ISP0, 11, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(smmu_lite1, "smmu_lite1", "aclk200", E4X12_GATE_ISP0, 12, + GATE(CLK_SMMU_LITE1, "smmu_lite1", "aclk200", E4X12_GATE_ISP0, 12, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(ppmuispmx, "ppmuispmx", "aclk200", E4X12_GATE_ISP0, 20, + GATE(CLK_PPMUISPMX, "ppmuispmx", "aclk200", E4X12_GATE_ISP0, 20, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(ppmuispx, "ppmuispx", "aclk200", E4X12_GATE_ISP0, 21, + GATE(CLK_PPMUISPX, "ppmuispx", "aclk200", E4X12_GATE_ISP0, 21, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(mcuctl_isp, "mcuctl_isp", "aclk200", E4X12_GATE_ISP0, 23, + GATE(CLK_MCUCTL_ISP, "mcuctl_isp", "aclk200", E4X12_GATE_ISP0, 23, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(mpwm_isp, "mpwm_isp", "aclk200", E4X12_GATE_ISP0, 24, + GATE(CLK_MPWM_ISP, "mpwm_isp", "aclk200", E4X12_GATE_ISP0, 24, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(i2c0_isp, "i2c0_isp", "aclk200", E4X12_GATE_ISP0, 25, + GATE(CLK_I2C0_ISP, "i2c0_isp", "aclk200", E4X12_GATE_ISP0, 25, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(i2c1_isp, "i2c1_isp", "aclk200", E4X12_GATE_ISP0, 26, + GATE(CLK_I2C1_ISP, "i2c1_isp", "aclk200", E4X12_GATE_ISP0, 26, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(mtcadc_isp, "mtcadc_isp", "aclk200", E4X12_GATE_ISP0, 27, + GATE(CLK_MTCADC_ISP, "mtcadc_isp", "aclk200", E4X12_GATE_ISP0, 27, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(pwm_isp, "pwm_isp", "aclk200", E4X12_GATE_ISP0, 28, + GATE(CLK_PWM_ISP, "pwm_isp", "aclk200", E4X12_GATE_ISP0, 28, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(wdt_isp, "wdt_isp", "aclk200", E4X12_GATE_ISP0, 30, + GATE(CLK_WDT_ISP, "wdt_isp", "aclk200", E4X12_GATE_ISP0, 30, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(uart_isp, "uart_isp", "aclk200", E4X12_GATE_ISP0, 31, + GATE(CLK_UART_ISP, "uart_isp", "aclk200", E4X12_GATE_ISP0, 31, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(asyncaxim, "asyncaxim", "aclk200", E4X12_GATE_ISP1, 0, + GATE(CLK_ASYNCAXIM, "asyncaxim", "aclk200", E4X12_GATE_ISP1, 0, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(smmu_ispcx, "smmu_ispcx", "aclk200", E4X12_GATE_ISP1, 4, + GATE(CLK_SMMU_ISPCX, "smmu_ispcx", "aclk200", E4X12_GATE_ISP1, 4, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(spi0_isp, "spi0_isp", "aclk200", E4X12_GATE_ISP1, 12, + GATE(CLK_SPI0_ISP, "spi0_isp", "aclk200", E4X12_GATE_ISP1, 12, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(spi1_isp, "spi1_isp", "aclk200", E4X12_GATE_ISP1, 13, + GATE(CLK_SPI1_ISP, "spi1_isp", "aclk200", E4X12_GATE_ISP1, 13, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(g2d, "g2d", "aclk200", GATE_IP_DMC, 23, 0, 0), - GATE(tmu_apbif, "tmu_apbif", "aclk100", E4X12_GATE_IP_PERIR, 17, 0, 0), + GATE(CLK_G2D, "g2d", "aclk200", GATE_IP_DMC, 23, 0, 0), + GATE(CLK_TMU_APBIF, "tmu_apbif", "aclk100", E4X12_GATE_IP_PERIR, 17, 0, + 0), }; static struct samsung_clock_alias exynos4_aliases[] __initdata = { - ALIAS(mout_core, NULL, "moutcore"), - ALIAS(arm_clk, NULL, "armclk"), - ALIAS(sclk_apll, NULL, "mout_apll"), + ALIAS(CLK_MOUT_CORE, NULL, "moutcore"), + ALIAS(CLK_ARM_CLK, NULL, "armclk"), + ALIAS(CLK_SCLK_APLL, NULL, "mout_apll"), }; static struct samsung_clock_alias exynos4210_aliases[] __initdata = { - ALIAS(sclk_mpll, NULL, "mout_mpll"), + ALIAS(CLK_SCLK_MPLL, NULL, "mout_mpll"), }; static struct samsung_clock_alias exynos4x12_aliases[] __initdata = { - ALIAS(mout_mpll_user_c, NULL, "mout_mpll"), + ALIAS(CLK_MOUT_MPLL_USER_C, NULL, "mout_mpll"), }; /* @@ -978,7 +925,7 @@ static void __init exynos4_clk_register_finpll(unsigned long xom) finpll_f = clk_get_rate(clk); } - fclk.id = fin_pll; + fclk.id = CLK_FIN_PLL; fclk.name = "fin_pll"; fclk.parent_name = NULL; fclk.flags = CLK_IS_ROOT; @@ -1068,24 +1015,24 @@ static struct samsung_pll_rate_table exynos4x12_vpll_rates[] __initdata = { }; static struct samsung_pll_clock exynos4210_plls[nr_plls] __initdata = { - [apll] = PLL_A(pll_4508, fout_apll, "fout_apll", "fin_pll", APLL_LOCK, - APLL_CON0, "fout_apll", NULL), - [mpll] = PLL_A(pll_4508, fout_mpll, "fout_mpll", "fin_pll", + [apll] = PLL_A(pll_4508, CLK_FOUT_APLL, "fout_apll", "fin_pll", + APLL_LOCK, APLL_CON0, "fout_apll", NULL), + [mpll] = PLL_A(pll_4508, CLK_FOUT_MPLL, "fout_mpll", "fin_pll", E4210_MPLL_LOCK, E4210_MPLL_CON0, "fout_mpll", NULL), - [epll] = PLL_A(pll_4600, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK, - EPLL_CON0, "fout_epll", NULL), - [vpll] = PLL_A(pll_4650c, fout_vpll, "fout_vpll", "mout_vpllsrc", + [epll] = PLL_A(pll_4600, CLK_FOUT_EPLL, "fout_epll", "fin_pll", + EPLL_LOCK, EPLL_CON0, "fout_epll", NULL), + [vpll] = PLL_A(pll_4650c, CLK_FOUT_VPLL, "fout_vpll", "mout_vpllsrc", VPLL_LOCK, VPLL_CON0, "fout_vpll", NULL), }; static struct samsung_pll_clock exynos4x12_plls[nr_plls] __initdata = { - [apll] = PLL(pll_35xx, fout_apll, "fout_apll", "fin_pll", + [apll] = PLL(pll_35xx, CLK_FOUT_APLL, "fout_apll", "fin_pll", APLL_LOCK, APLL_CON0, NULL), - [mpll] = PLL(pll_35xx, fout_mpll, "fout_mpll", "fin_pll", + [mpll] = PLL(pll_35xx, CLK_FOUT_MPLL, "fout_mpll", "fin_pll", E4X12_MPLL_LOCK, E4X12_MPLL_CON0, NULL), - [epll] = PLL(pll_36xx, fout_epll, "fout_epll", "fin_pll", + [epll] = PLL(pll_36xx, CLK_FOUT_EPLL, "fout_epll", "fin_pll", EPLL_LOCK, EPLL_CON0, NULL), - [vpll] = PLL(pll_36xx, fout_vpll, "fout_vpll", "fin_pll", + [vpll] = PLL(pll_36xx, CLK_FOUT_VPLL, "fout_vpll", "fin_pll", VPLL_LOCK, VPLL_CON0, NULL), }; @@ -1099,11 +1046,11 @@ static void __init exynos4_clk_init(struct device_node *np, panic("%s: failed to map registers\n", __func__); if (exynos4_soc == EXYNOS4210) - samsung_clk_init(np, reg_base, nr_clks, + samsung_clk_init(np, reg_base, CLK_NR_CLKS, exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs), exynos4210_clk_save, ARRAY_SIZE(exynos4210_clk_save)); else - samsung_clk_init(np, reg_base, nr_clks, + samsung_clk_init(np, reg_base, CLK_NR_CLKS, exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs), exynos4x12_clk_save, ARRAY_SIZE(exynos4x12_clk_save)); diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c index e52359cf9b6f..ff4beebe1f0b 100644 --- a/drivers/clk/samsung/clk-exynos5250.c +++ b/drivers/clk/samsung/clk-exynos5250.c @@ -10,6 +10,7 @@ * Common Clock Framework support for Exynos5250 SoC. */ +#include <dt-bindings/clock/exynos5250.h> #include <linux/clk.h> #include <linux/clkdev.h> #include <linux/clk-provider.h> @@ -36,6 +37,7 @@ #define GPLL_CON0 0x10150 #define SRC_TOP0 0x10210 #define SRC_TOP2 0x10218 +#define SRC_TOP3 0x1021c #define SRC_GSCL 0x10220 #define SRC_DISP1_0 0x1022c #define SRC_MAU 0x10240 @@ -66,6 +68,7 @@ #define DIV_PERIC4 0x10568 #define DIV_PERIC5 0x1056c #define GATE_IP_GSCL 0x10920 +#define GATE_IP_DISP1 0x10928 #define GATE_IP_MFC 0x1092c #define GATE_IP_GEN 0x10934 #define GATE_IP_FSYS 0x10944 @@ -75,7 +78,6 @@ #define BPLL_CON0 0x20110 #define SRC_CDREX 0x20200 #define PLL_DIV2_SEL 0x20a24 -#define GATE_IP_DISP1 0x10928 /* list of PLLs to be registered */ enum exynos5250_plls { @@ -84,52 +86,6 @@ enum exynos5250_plls { }; /* - * Let each supported clock get a unique id. This id is used to lookup the clock - * for device tree based platforms. The clocks are categorized into three - * sections: core, sclk gate and bus interface gate clocks. - * - * When adding a new clock to this list, it is advised to choose a clock - * category and add it to the end of that category. That is because the the - * device tree source file is referring to these ids and any change in the - * sequence number of existing clocks will require corresponding change in the - * device tree files. This limitation would go away when pre-processor support - * for dtc would be available. - */ -enum exynos5250_clks { - none, - - /* core clocks */ - fin_pll, fout_apll, fout_mpll, fout_bpll, fout_gpll, fout_cpll, - fout_epll, fout_vpll, - - /* gate for special clocks (sclk) */ - sclk_cam_bayer = 128, sclk_cam0, sclk_cam1, sclk_gscl_wa, sclk_gscl_wb, - sclk_fimd1, sclk_mipi1, sclk_dp, sclk_hdmi, sclk_pixel, sclk_audio0, - sclk_mmc0, sclk_mmc1, sclk_mmc2, sclk_mmc3, sclk_sata, sclk_usb3, - sclk_jpeg, sclk_uart0, sclk_uart1, sclk_uart2, sclk_uart3, sclk_pwm, - sclk_audio1, sclk_audio2, sclk_spdif, sclk_spi0, sclk_spi1, sclk_spi2, - div_i2s1, div_i2s2, sclk_hdmiphy, - - /* gate clocks */ - gscl0 = 256, gscl1, gscl2, gscl3, gscl_wa, gscl_wb, smmu_gscl0, - smmu_gscl1, smmu_gscl2, smmu_gscl3, mfc, smmu_mfcl, smmu_mfcr, rotator, - jpeg, mdma1, smmu_rotator, smmu_jpeg, smmu_mdma1, pdma0, pdma1, sata, - usbotg, mipi_hsi, sdmmc0, sdmmc1, sdmmc2, sdmmc3, sromc, usb2, usb3, - sata_phyctrl, sata_phyi2c, uart0, uart1, uart2, uart3, uart4, i2c0, - i2c1, i2c2, i2c3, i2c4, i2c5, i2c6, i2c7, i2c_hdmi, adc, spi0, spi1, - spi2, i2s1, i2s2, pcm1, pcm2, pwm, spdif, ac97, hsi2c0, hsi2c1, hsi2c2, - hsi2c3, chipid, sysreg, pmu, cmu_top, cmu_core, cmu_mem, tzpc0, tzpc1, - tzpc2, tzpc3, tzpc4, tzpc5, tzpc6, tzpc7, tzpc8, tzpc9, hdmi_cec, mct, - wdt, rtc, tmu, fimd1, mie1, dsim0, dp, mixer, hdmi, g2d, mdma0, - smmu_mdma0, - - /* mux clocks */ - mout_hdmi = 1024, - - nr_clks, -}; - -/* * list of controller registers to be saved and restored during a * suspend/resume cycle. */ @@ -139,6 +95,7 @@ static unsigned long exynos5250_clk_regs[] __initdata = { SRC_CORE1, SRC_TOP0, SRC_TOP2, + SRC_TOP3, SRC_GSCL, SRC_DISP1_0, SRC_MAU, @@ -182,7 +139,7 @@ static unsigned long exynos5250_clk_regs[] __initdata = { /* list of all parent clock list */ PNAME(mout_apll_p) = { "fin_pll", "fout_apll", }; -PNAME(mout_cpu_p) = { "mout_apll", "sclk_mpll", }; +PNAME(mout_cpu_p) = { "mout_apll", "mout_mpll", }; PNAME(mout_mpll_fout_p) = { "fout_mplldiv2", "fout_mpll" }; PNAME(mout_mpll_p) = { "fin_pll", "mout_mpll_fout" }; PNAME(mout_bpll_fout_p) = { "fout_bplldiv2", "fout_bpll" }; @@ -191,311 +148,432 @@ PNAME(mout_vpllsrc_p) = { "fin_pll", "sclk_hdmi27m" }; PNAME(mout_vpll_p) = { "mout_vpllsrc", "fout_vpll" }; PNAME(mout_cpll_p) = { "fin_pll", "fout_cpll" }; PNAME(mout_epll_p) = { "fin_pll", "fout_epll" }; -PNAME(mout_mpll_user_p) = { "fin_pll", "sclk_mpll" }; -PNAME(mout_bpll_user_p) = { "fin_pll", "sclk_bpll" }; -PNAME(mout_aclk166_p) = { "sclk_cpll", "sclk_mpll_user" }; -PNAME(mout_aclk200_p) = { "sclk_mpll_user", "sclk_bpll_user" }; +PNAME(mout_mpll_user_p) = { "fin_pll", "mout_mpll" }; +PNAME(mout_bpll_user_p) = { "fin_pll", "mout_bpll" }; +PNAME(mout_aclk166_p) = { "mout_cpll", "mout_mpll_user" }; +PNAME(mout_aclk200_p) = { "mout_mpll_user", "mout_bpll_user" }; +PNAME(mout_aclk200_sub_p) = { "fin_pll", "div_aclk200" }; +PNAME(mout_aclk266_sub_p) = { "fin_pll", "div_aclk266" }; +PNAME(mout_aclk333_sub_p) = { "fin_pll", "div_aclk333" }; PNAME(mout_hdmi_p) = { "div_hdmi_pixel", "sclk_hdmiphy" }; -PNAME(mout_usb3_p) = { "sclk_mpll_user", "sclk_cpll" }; +PNAME(mout_usb3_p) = { "mout_mpll_user", "mout_cpll" }; PNAME(mout_group1_p) = { "fin_pll", "fin_pll", "sclk_hdmi27m", "sclk_dptxphy", "sclk_uhostphy", "sclk_hdmiphy", - "sclk_mpll_user", "sclk_epll", "sclk_vpll", - "sclk_cpll" }; + "mout_mpll_user", "mout_epll", "mout_vpll", + "mout_cpll", "none", "none", + "none", "none", "none", + "none" }; PNAME(mout_audio0_p) = { "cdclk0", "fin_pll", "sclk_hdmi27m", "sclk_dptxphy", - "sclk_uhostphy", "sclk_hdmiphy", - "sclk_mpll_user", "sclk_epll", "sclk_vpll", - "sclk_cpll" }; + "sclk_uhostphy", "fin_pll", + "mout_mpll_user", "mout_epll", "mout_vpll", + "mout_cpll", "none", "none", + "none", "none", "none", + "none" }; PNAME(mout_audio1_p) = { "cdclk1", "fin_pll", "sclk_hdmi27m", "sclk_dptxphy", - "sclk_uhostphy", "sclk_hdmiphy", - "sclk_mpll_user", "sclk_epll", "sclk_vpll", - "sclk_cpll" }; + "sclk_uhostphy", "fin_pll", + "mout_mpll_user", "mout_epll", "mout_vpll", + "mout_cpll", "none", "none", + "none", "none", "none", + "none" }; PNAME(mout_audio2_p) = { "cdclk2", "fin_pll", "sclk_hdmi27m", "sclk_dptxphy", - "sclk_uhostphy", "sclk_hdmiphy", - "sclk_mpll_user", "sclk_epll", "sclk_vpll", - "sclk_cpll" }; + "sclk_uhostphy", "fin_pll", + "mout_mpll_user", "mout_epll", "mout_vpll", + "mout_cpll", "none", "none", + "none", "none", "none", + "none" }; PNAME(mout_spdif_p) = { "sclk_audio0", "sclk_audio1", "sclk_audio2", "spdif_extclk" }; /* fixed rate clocks generated outside the soc */ static struct samsung_fixed_rate_clock exynos5250_fixed_rate_ext_clks[] __initdata = { - FRATE(fin_pll, "fin_pll", NULL, CLK_IS_ROOT, 0), + FRATE(CLK_FIN_PLL, "fin_pll", NULL, CLK_IS_ROOT, 0), }; /* fixed rate clocks generated inside the soc */ static struct samsung_fixed_rate_clock exynos5250_fixed_rate_clks[] __initdata = { - FRATE(sclk_hdmiphy, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 24000000), - FRATE(none, "sclk_hdmi27m", NULL, CLK_IS_ROOT, 27000000), - FRATE(none, "sclk_dptxphy", NULL, CLK_IS_ROOT, 24000000), - FRATE(none, "sclk_uhostphy", NULL, CLK_IS_ROOT, 48000000), + FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 24000000), + FRATE(0, "sclk_hdmi27m", NULL, CLK_IS_ROOT, 27000000), + FRATE(0, "sclk_dptxphy", NULL, CLK_IS_ROOT, 24000000), + FRATE(0, "sclk_uhostphy", NULL, CLK_IS_ROOT, 48000000), }; static struct samsung_fixed_factor_clock exynos5250_fixed_factor_clks[] __initdata = { - FFACTOR(none, "fout_mplldiv2", "fout_mpll", 1, 2, 0), - FFACTOR(none, "fout_bplldiv2", "fout_bpll", 1, 2, 0), + FFACTOR(0, "fout_mplldiv2", "fout_mpll", 1, 2, 0), + FFACTOR(0, "fout_bplldiv2", "fout_bpll", 1, 2, 0), }; static struct samsung_mux_clock exynos5250_pll_pmux_clks[] __initdata = { - MUX(none, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP2, 0, 1), + MUX(0, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP2, 0, 1), }; static struct samsung_mux_clock exynos5250_mux_clks[] __initdata = { - MUX_A(none, "mout_apll", mout_apll_p, SRC_CPU, 0, 1, "mout_apll"), - MUX_A(none, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1, "mout_cpu"), - MUX(none, "mout_mpll_fout", mout_mpll_fout_p, PLL_DIV2_SEL, 4, 1), - MUX_A(none, "sclk_mpll", mout_mpll_p, SRC_CORE1, 8, 1, "mout_mpll"), - MUX(none, "mout_bpll_fout", mout_bpll_fout_p, PLL_DIV2_SEL, 0, 1), - MUX(none, "sclk_bpll", mout_bpll_p, SRC_CDREX, 0, 1), - MUX(none, "sclk_vpll", mout_vpll_p, SRC_TOP2, 16, 1), - MUX(none, "sclk_epll", mout_epll_p, SRC_TOP2, 12, 1), - MUX(none, "sclk_cpll", mout_cpll_p, SRC_TOP2, 8, 1), - MUX(none, "sclk_mpll_user", mout_mpll_user_p, SRC_TOP2, 20, 1), - MUX(none, "sclk_bpll_user", mout_bpll_user_p, SRC_TOP2, 24, 1), - MUX(none, "mout_aclk166", mout_aclk166_p, SRC_TOP0, 8, 1), - MUX(none, "mout_aclk333", mout_aclk166_p, SRC_TOP0, 16, 1), - MUX(none, "mout_aclk200", mout_aclk200_p, SRC_TOP0, 12, 1), - MUX(none, "mout_cam_bayer", mout_group1_p, SRC_GSCL, 12, 4), - MUX(none, "mout_cam0", mout_group1_p, SRC_GSCL, 16, 4), - MUX(none, "mout_cam1", mout_group1_p, SRC_GSCL, 20, 4), - MUX(none, "mout_gscl_wa", mout_group1_p, SRC_GSCL, 24, 4), - MUX(none, "mout_gscl_wb", mout_group1_p, SRC_GSCL, 28, 4), - MUX(none, "mout_fimd1", mout_group1_p, SRC_DISP1_0, 0, 4), - MUX(none, "mout_mipi1", mout_group1_p, SRC_DISP1_0, 12, 4), - MUX(none, "mout_dp", mout_group1_p, SRC_DISP1_0, 16, 4), - MUX(mout_hdmi, "mout_hdmi", mout_hdmi_p, SRC_DISP1_0, 20, 1), - MUX(none, "mout_audio0", mout_audio0_p, SRC_MAU, 0, 4), - MUX(none, "mout_mmc0", mout_group1_p, SRC_FSYS, 0, 4), - MUX(none, "mout_mmc1", mout_group1_p, SRC_FSYS, 4, 4), - MUX(none, "mout_mmc2", mout_group1_p, SRC_FSYS, 8, 4), - MUX(none, "mout_mmc3", mout_group1_p, SRC_FSYS, 12, 4), - MUX(none, "mout_sata", mout_aclk200_p, SRC_FSYS, 24, 1), - MUX(none, "mout_usb3", mout_usb3_p, SRC_FSYS, 28, 1), - MUX(none, "mout_jpeg", mout_group1_p, SRC_GEN, 0, 4), - MUX(none, "mout_uart0", mout_group1_p, SRC_PERIC0, 0, 4), - MUX(none, "mout_uart1", mout_group1_p, SRC_PERIC0, 4, 4), - MUX(none, "mout_uart2", mout_group1_p, SRC_PERIC0, 8, 4), - MUX(none, "mout_uart3", mout_group1_p, SRC_PERIC0, 12, 4), - MUX(none, "mout_pwm", mout_group1_p, SRC_PERIC0, 24, 4), - MUX(none, "mout_audio1", mout_audio1_p, SRC_PERIC1, 0, 4), - MUX(none, "mout_audio2", mout_audio2_p, SRC_PERIC1, 4, 4), - MUX(none, "mout_spdif", mout_spdif_p, SRC_PERIC1, 8, 2), - MUX(none, "mout_spi0", mout_group1_p, SRC_PERIC1, 16, 4), - MUX(none, "mout_spi1", mout_group1_p, SRC_PERIC1, 20, 4), - MUX(none, "mout_spi2", mout_group1_p, SRC_PERIC1, 24, 4), + /* + * NOTE: Following table is sorted by (clock domain, register address, + * bitfield shift) triplet in ascending order. When adding new entries, + * please make sure that the order is kept, to avoid merge conflicts + * and make further work with defined data easier. + */ + + /* + * CMU_CPU + */ + MUX_FA(0, "mout_apll", mout_apll_p, SRC_CPU, 0, 1, + CLK_SET_RATE_PARENT, 0, "mout_apll"), + MUX_A(0, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1, "mout_cpu"), + + /* + * CMU_CORE + */ + MUX_A(0, "mout_mpll", mout_mpll_p, SRC_CORE1, 8, 1, "mout_mpll"), + + /* + * CMU_TOP + */ + MUX(0, "mout_aclk166", mout_aclk166_p, SRC_TOP0, 8, 1), + MUX(0, "mout_aclk200", mout_aclk200_p, SRC_TOP0, 12, 1), + MUX(0, "mout_aclk333", mout_aclk166_p, SRC_TOP0, 16, 1), + + MUX(0, "mout_cpll", mout_cpll_p, SRC_TOP2, 8, 1), + MUX(0, "mout_epll", mout_epll_p, SRC_TOP2, 12, 1), + MUX(0, "mout_vpll", mout_vpll_p, SRC_TOP2, 16, 1), + MUX(0, "mout_mpll_user", mout_mpll_user_p, SRC_TOP2, 20, 1), + MUX(0, "mout_bpll_user", mout_bpll_user_p, SRC_TOP2, 24, 1), + + MUX(0, "mout_aclk200_disp1_sub", mout_aclk200_sub_p, SRC_TOP3, 4, 1), + MUX(0, "mout_aclk266_gscl_sub", mout_aclk266_sub_p, SRC_TOP3, 8, 1), + MUX(0, "mout_aclk333_sub", mout_aclk333_sub_p, SRC_TOP3, 24, 1), + + MUX(0, "mout_cam_bayer", mout_group1_p, SRC_GSCL, 12, 4), + MUX(0, "mout_cam0", mout_group1_p, SRC_GSCL, 16, 4), + MUX(0, "mout_cam1", mout_group1_p, SRC_GSCL, 20, 4), + MUX(0, "mout_gscl_wa", mout_group1_p, SRC_GSCL, 24, 4), + MUX(0, "mout_gscl_wb", mout_group1_p, SRC_GSCL, 28, 4), + + MUX(0, "mout_fimd1", mout_group1_p, SRC_DISP1_0, 0, 4), + MUX(0, "mout_mipi1", mout_group1_p, SRC_DISP1_0, 12, 4), + MUX(0, "mout_dp", mout_group1_p, SRC_DISP1_0, 16, 4), + MUX(CLK_MOUT_HDMI, "mout_hdmi", mout_hdmi_p, SRC_DISP1_0, 20, 1), + + MUX(0, "mout_audio0", mout_audio0_p, SRC_MAU, 0, 4), + + MUX(0, "mout_mmc0", mout_group1_p, SRC_FSYS, 0, 4), + MUX(0, "mout_mmc1", mout_group1_p, SRC_FSYS, 4, 4), + MUX(0, "mout_mmc2", mout_group1_p, SRC_FSYS, 8, 4), + MUX(0, "mout_mmc3", mout_group1_p, SRC_FSYS, 12, 4), + MUX(0, "mout_sata", mout_aclk200_p, SRC_FSYS, 24, 1), + MUX(0, "mout_usb3", mout_usb3_p, SRC_FSYS, 28, 1), + + MUX(0, "mout_jpeg", mout_group1_p, SRC_GEN, 0, 4), + + MUX(0, "mout_uart0", mout_group1_p, SRC_PERIC0, 0, 4), + MUX(0, "mout_uart1", mout_group1_p, SRC_PERIC0, 4, 4), + MUX(0, "mout_uart2", mout_group1_p, SRC_PERIC0, 8, 4), + MUX(0, "mout_uart3", mout_group1_p, SRC_PERIC0, 12, 4), + MUX(0, "mout_pwm", mout_group1_p, SRC_PERIC0, 24, 4), + + MUX(0, "mout_audio1", mout_audio1_p, SRC_PERIC1, 0, 4), + MUX(0, "mout_audio2", mout_audio2_p, SRC_PERIC1, 4, 4), + MUX(0, "mout_spdif", mout_spdif_p, SRC_PERIC1, 8, 2), + MUX(0, "mout_spi0", mout_group1_p, SRC_PERIC1, 16, 4), + MUX(0, "mout_spi1", mout_group1_p, SRC_PERIC1, 20, 4), + MUX(0, "mout_spi2", mout_group1_p, SRC_PERIC1, 24, 4), + + /* + * CMU_CDREX + */ + MUX(0, "mout_bpll", mout_bpll_p, SRC_CDREX, 0, 1), + + MUX(0, "mout_mpll_fout", mout_mpll_fout_p, PLL_DIV2_SEL, 4, 1), + MUX(0, "mout_bpll_fout", mout_bpll_fout_p, PLL_DIV2_SEL, 0, 1), }; static struct samsung_div_clock exynos5250_div_clks[] __initdata = { - DIV(none, "div_arm", "mout_cpu", DIV_CPU0, 0, 3), - DIV(none, "sclk_apll", "mout_apll", DIV_CPU0, 24, 3), - DIV(none, "aclk66_pre", "sclk_mpll_user", DIV_TOP1, 24, 3), - DIV(none, "aclk66", "aclk66_pre", DIV_TOP0, 0, 3), - DIV(none, "aclk266", "sclk_mpll_user", DIV_TOP0, 16, 3), - DIV(none, "aclk166", "mout_aclk166", DIV_TOP0, 8, 3), - DIV(none, "aclk333", "mout_aclk333", DIV_TOP0, 20, 3), - DIV(none, "aclk200", "mout_aclk200", DIV_TOP0, 12, 3), - DIV(none, "div_cam_bayer", "mout_cam_bayer", DIV_GSCL, 12, 4), - DIV(none, "div_cam0", "mout_cam0", DIV_GSCL, 16, 4), - DIV(none, "div_cam1", "mout_cam1", DIV_GSCL, 20, 4), - DIV(none, "div_gscl_wa", "mout_gscl_wa", DIV_GSCL, 24, 4), - DIV(none, "div_gscl_wb", "mout_gscl_wb", DIV_GSCL, 28, 4), - DIV(none, "div_fimd1", "mout_fimd1", DIV_DISP1_0, 0, 4), - DIV(none, "div_mipi1", "mout_mipi1", DIV_DISP1_0, 16, 4), - DIV(none, "div_dp", "mout_dp", DIV_DISP1_0, 24, 4), - DIV(none, "div_jpeg", "mout_jpeg", DIV_GEN, 4, 4), - DIV(none, "div_audio0", "mout_audio0", DIV_MAU, 0, 4), - DIV(none, "div_pcm0", "sclk_audio0", DIV_MAU, 4, 8), - DIV(none, "div_sata", "mout_sata", DIV_FSYS0, 20, 4), - DIV(none, "div_usb3", "mout_usb3", DIV_FSYS0, 24, 4), - DIV(none, "div_mmc0", "mout_mmc0", DIV_FSYS1, 0, 4), - DIV(none, "div_mmc1", "mout_mmc1", DIV_FSYS1, 16, 4), - DIV(none, "div_mmc2", "mout_mmc2", DIV_FSYS2, 0, 4), - DIV(none, "div_mmc3", "mout_mmc3", DIV_FSYS2, 16, 4), - DIV(none, "div_uart0", "mout_uart0", DIV_PERIC0, 0, 4), - DIV(none, "div_uart1", "mout_uart1", DIV_PERIC0, 4, 4), - DIV(none, "div_uart2", "mout_uart2", DIV_PERIC0, 8, 4), - DIV(none, "div_uart3", "mout_uart3", DIV_PERIC0, 12, 4), - DIV(none, "div_spi0", "mout_spi0", DIV_PERIC1, 0, 4), - DIV(none, "div_spi1", "mout_spi1", DIV_PERIC1, 16, 4), - DIV(none, "div_spi2", "mout_spi2", DIV_PERIC2, 0, 4), - DIV(none, "div_pwm", "mout_pwm", DIV_PERIC3, 0, 4), - DIV(none, "div_audio1", "mout_audio1", DIV_PERIC4, 0, 4), - DIV(none, "div_pcm1", "sclk_audio1", DIV_PERIC4, 4, 8), - DIV(none, "div_audio2", "mout_audio2", DIV_PERIC4, 16, 4), - DIV(none, "div_pcm2", "sclk_audio2", DIV_PERIC4, 20, 8), - DIV(div_i2s1, "div_i2s1", "sclk_audio1", DIV_PERIC5, 0, 6), - DIV(div_i2s2, "div_i2s2", "sclk_audio2", DIV_PERIC5, 8, 6), - DIV(sclk_pixel, "div_hdmi_pixel", "sclk_vpll", DIV_DISP1_0, 28, 4), - DIV_A(none, "armclk", "div_arm", DIV_CPU0, 28, 3, "armclk"), - DIV_F(none, "div_mipi1_pre", "div_mipi1", + /* + * NOTE: Following table is sorted by (clock domain, register address, + * bitfield shift) triplet in ascending order. When adding new entries, + * please make sure that the order is kept, to avoid merge conflicts + * and make further work with defined data easier. + */ + + /* + * CMU_CPU + */ + DIV(0, "div_arm", "mout_cpu", DIV_CPU0, 0, 3), + DIV(0, "div_apll", "mout_apll", DIV_CPU0, 24, 3), + DIV_A(0, "div_arm2", "div_arm", DIV_CPU0, 28, 3, "armclk"), + + /* + * CMU_TOP + */ + DIV(0, "div_aclk66", "div_aclk66_pre", DIV_TOP0, 0, 3), + DIV(0, "div_aclk166", "mout_aclk166", DIV_TOP0, 8, 3), + DIV(0, "div_aclk200", "mout_aclk200", DIV_TOP0, 12, 3), + DIV(0, "div_aclk266", "mout_mpll_user", DIV_TOP0, 16, 3), + DIV(0, "div_aclk333", "mout_aclk333", DIV_TOP0, 20, 3), + + DIV(0, "div_aclk66_pre", "mout_mpll_user", DIV_TOP1, 24, 3), + + DIV(0, "div_cam_bayer", "mout_cam_bayer", DIV_GSCL, 12, 4), + DIV(0, "div_cam0", "mout_cam0", DIV_GSCL, 16, 4), + DIV(0, "div_cam1", "mout_cam1", DIV_GSCL, 20, 4), + DIV(0, "div_gscl_wa", "mout_gscl_wa", DIV_GSCL, 24, 4), + DIV(0, "div_gscl_wb", "mout_gscl_wb", DIV_GSCL, 28, 4), + + DIV(0, "div_fimd1", "mout_fimd1", DIV_DISP1_0, 0, 4), + DIV(0, "div_mipi1", "mout_mipi1", DIV_DISP1_0, 16, 4), + DIV_F(0, "div_mipi1_pre", "div_mipi1", DIV_DISP1_0, 20, 4, CLK_SET_RATE_PARENT, 0), - DIV_F(none, "div_mmc_pre0", "div_mmc0", + DIV(0, "div_dp", "mout_dp", DIV_DISP1_0, 24, 4), + DIV(CLK_SCLK_PIXEL, "div_hdmi_pixel", "mout_vpll", DIV_DISP1_0, 28, 4), + + DIV(0, "div_jpeg", "mout_jpeg", DIV_GEN, 4, 4), + + DIV(0, "div_audio0", "mout_audio0", DIV_MAU, 0, 4), + DIV(CLK_DIV_PCM0, "div_pcm0", "sclk_audio0", DIV_MAU, 4, 8), + + DIV(0, "div_sata", "mout_sata", DIV_FSYS0, 20, 4), + DIV(0, "div_usb3", "mout_usb3", DIV_FSYS0, 24, 4), + + DIV(0, "div_mmc0", "mout_mmc0", DIV_FSYS1, 0, 4), + DIV_F(0, "div_mmc_pre0", "div_mmc0", DIV_FSYS1, 8, 8, CLK_SET_RATE_PARENT, 0), - DIV_F(none, "div_mmc_pre1", "div_mmc1", + DIV(0, "div_mmc1", "mout_mmc1", DIV_FSYS1, 16, 4), + DIV_F(0, "div_mmc_pre1", "div_mmc1", DIV_FSYS1, 24, 8, CLK_SET_RATE_PARENT, 0), - DIV_F(none, "div_mmc_pre2", "div_mmc2", + + DIV(0, "div_mmc2", "mout_mmc2", DIV_FSYS2, 0, 4), + DIV_F(0, "div_mmc_pre2", "div_mmc2", DIV_FSYS2, 8, 8, CLK_SET_RATE_PARENT, 0), - DIV_F(none, "div_mmc_pre3", "div_mmc3", + DIV(0, "div_mmc3", "mout_mmc3", DIV_FSYS2, 16, 4), + DIV_F(0, "div_mmc_pre3", "div_mmc3", DIV_FSYS2, 24, 8, CLK_SET_RATE_PARENT, 0), - DIV_F(none, "div_spi_pre0", "div_spi0", + + DIV(0, "div_uart0", "mout_uart0", DIV_PERIC0, 0, 4), + DIV(0, "div_uart1", "mout_uart1", DIV_PERIC0, 4, 4), + DIV(0, "div_uart2", "mout_uart2", DIV_PERIC0, 8, 4), + DIV(0, "div_uart3", "mout_uart3", DIV_PERIC0, 12, 4), + + DIV(0, "div_spi0", "mout_spi0", DIV_PERIC1, 0, 4), + DIV_F(0, "div_spi_pre0", "div_spi0", DIV_PERIC1, 8, 8, CLK_SET_RATE_PARENT, 0), - DIV_F(none, "div_spi_pre1", "div_spi1", + DIV(0, "div_spi1", "mout_spi1", DIV_PERIC1, 16, 4), + DIV_F(0, "div_spi_pre1", "div_spi1", DIV_PERIC1, 24, 8, CLK_SET_RATE_PARENT, 0), - DIV_F(none, "div_spi_pre2", "div_spi2", + + DIV(0, "div_spi2", "mout_spi2", DIV_PERIC2, 0, 4), + DIV_F(0, "div_spi_pre2", "div_spi2", DIV_PERIC2, 8, 8, CLK_SET_RATE_PARENT, 0), + + DIV(0, "div_pwm", "mout_pwm", DIV_PERIC3, 0, 4), + + DIV(0, "div_audio1", "mout_audio1", DIV_PERIC4, 0, 4), + DIV(0, "div_pcm1", "sclk_audio1", DIV_PERIC4, 4, 8), + DIV(0, "div_audio2", "mout_audio2", DIV_PERIC4, 16, 4), + DIV(0, "div_pcm2", "sclk_audio2", DIV_PERIC4, 20, 8), + + DIV(CLK_DIV_I2S1, "div_i2s1", "sclk_audio1", DIV_PERIC5, 0, 6), + DIV(CLK_DIV_I2S2, "div_i2s2", "sclk_audio2", DIV_PERIC5, 8, 6), }; static struct samsung_gate_clock exynos5250_gate_clks[] __initdata = { - GATE(gscl0, "gscl0", "none", GATE_IP_GSCL, 0, 0, 0), - GATE(gscl1, "gscl1", "none", GATE_IP_GSCL, 1, 0, 0), - GATE(gscl2, "gscl2", "aclk266", GATE_IP_GSCL, 2, 0, 0), - GATE(gscl3, "gscl3", "aclk266", GATE_IP_GSCL, 3, 0, 0), - GATE(gscl_wa, "gscl_wa", "div_gscl_wa", GATE_IP_GSCL, 5, 0, 0), - GATE(gscl_wb, "gscl_wb", "div_gscl_wb", GATE_IP_GSCL, 6, 0, 0), - GATE(smmu_gscl0, "smmu_gscl0", "aclk266", GATE_IP_GSCL, 7, 0, 0), - GATE(smmu_gscl1, "smmu_gscl1", "aclk266", GATE_IP_GSCL, 8, 0, 0), - GATE(smmu_gscl2, "smmu_gscl2", "aclk266", GATE_IP_GSCL, 9, 0, 0), - GATE(smmu_gscl3, "smmu_gscl3", "aclk266", GATE_IP_GSCL, 10, 0, 0), - GATE(mfc, "mfc", "aclk333", GATE_IP_MFC, 0, 0, 0), - GATE(smmu_mfcl, "smmu_mfcl", "aclk333", GATE_IP_MFC, 2, 0, 0), - GATE(smmu_mfcr, "smmu_mfcr", "aclk333", GATE_IP_MFC, 1, 0, 0), - GATE(rotator, "rotator", "aclk266", GATE_IP_GEN, 1, 0, 0), - GATE(jpeg, "jpeg", "aclk166", GATE_IP_GEN, 2, 0, 0), - GATE(mdma1, "mdma1", "aclk266", GATE_IP_GEN, 4, 0, 0), - GATE(smmu_rotator, "smmu_rotator", "aclk266", GATE_IP_GEN, 6, 0, 0), - GATE(smmu_jpeg, "smmu_jpeg", "aclk166", GATE_IP_GEN, 7, 0, 0), - GATE(smmu_mdma1, "smmu_mdma1", "aclk266", GATE_IP_GEN, 9, 0, 0), - GATE(pdma0, "pdma0", "aclk200", GATE_IP_FSYS, 1, 0, 0), - GATE(pdma1, "pdma1", "aclk200", GATE_IP_FSYS, 2, 0, 0), - GATE(sata, "sata", "aclk200", GATE_IP_FSYS, 6, 0, 0), - GATE(usbotg, "usbotg", "aclk200", GATE_IP_FSYS, 7, 0, 0), - GATE(mipi_hsi, "mipi_hsi", "aclk200", GATE_IP_FSYS, 8, 0, 0), - GATE(sdmmc0, "sdmmc0", "aclk200", GATE_IP_FSYS, 12, 0, 0), - GATE(sdmmc1, "sdmmc1", "aclk200", GATE_IP_FSYS, 13, 0, 0), - GATE(sdmmc2, "sdmmc2", "aclk200", GATE_IP_FSYS, 14, 0, 0), - GATE(sdmmc3, "sdmmc3", "aclk200", GATE_IP_FSYS, 15, 0, 0), - GATE(sromc, "sromc", "aclk200", GATE_IP_FSYS, 17, 0, 0), - GATE(usb2, "usb2", "aclk200", GATE_IP_FSYS, 18, 0, 0), - GATE(usb3, "usb3", "aclk200", GATE_IP_FSYS, 19, 0, 0), - GATE(sata_phyctrl, "sata_phyctrl", "aclk200", GATE_IP_FSYS, 24, 0, 0), - GATE(sata_phyi2c, "sata_phyi2c", "aclk200", GATE_IP_FSYS, 25, 0, 0), - GATE(uart0, "uart0", "aclk66", GATE_IP_PERIC, 0, 0, 0), - GATE(uart1, "uart1", "aclk66", GATE_IP_PERIC, 1, 0, 0), - GATE(uart2, "uart2", "aclk66", GATE_IP_PERIC, 2, 0, 0), - GATE(uart3, "uart3", "aclk66", GATE_IP_PERIC, 3, 0, 0), - GATE(uart4, "uart4", "aclk66", GATE_IP_PERIC, 4, 0, 0), - GATE(i2c0, "i2c0", "aclk66", GATE_IP_PERIC, 6, 0, 0), - GATE(i2c1, "i2c1", "aclk66", GATE_IP_PERIC, 7, 0, 0), - GATE(i2c2, "i2c2", "aclk66", GATE_IP_PERIC, 8, 0, 0), - GATE(i2c3, "i2c3", "aclk66", GATE_IP_PERIC, 9, 0, 0), - GATE(i2c4, "i2c4", "aclk66", GATE_IP_PERIC, 10, 0, 0), - GATE(i2c5, "i2c5", "aclk66", GATE_IP_PERIC, 11, 0, 0), - GATE(i2c6, "i2c6", "aclk66", GATE_IP_PERIC, 12, 0, 0), - GATE(i2c7, "i2c7", "aclk66", GATE_IP_PERIC, 13, 0, 0), - GATE(i2c_hdmi, "i2c_hdmi", "aclk66", GATE_IP_PERIC, 14, 0, 0), - GATE(adc, "adc", "aclk66", GATE_IP_PERIC, 15, 0, 0), - GATE(spi0, "spi0", "aclk66", GATE_IP_PERIC, 16, 0, 0), - GATE(spi1, "spi1", "aclk66", GATE_IP_PERIC, 17, 0, 0), - GATE(spi2, "spi2", "aclk66", GATE_IP_PERIC, 18, 0, 0), - GATE(i2s1, "i2s1", "aclk66", GATE_IP_PERIC, 20, 0, 0), - GATE(i2s2, "i2s2", "aclk66", GATE_IP_PERIC, 21, 0, 0), - GATE(pcm1, "pcm1", "aclk66", GATE_IP_PERIC, 22, 0, 0), - GATE(pcm2, "pcm2", "aclk66", GATE_IP_PERIC, 23, 0, 0), - GATE(pwm, "pwm", "aclk66", GATE_IP_PERIC, 24, 0, 0), - GATE(spdif, "spdif", "aclk66", GATE_IP_PERIC, 26, 0, 0), - GATE(ac97, "ac97", "aclk66", GATE_IP_PERIC, 27, 0, 0), - GATE(hsi2c0, "hsi2c0", "aclk66", GATE_IP_PERIC, 28, 0, 0), - GATE(hsi2c1, "hsi2c1", "aclk66", GATE_IP_PERIC, 29, 0, 0), - GATE(hsi2c2, "hsi2c2", "aclk66", GATE_IP_PERIC, 30, 0, 0), - GATE(hsi2c3, "hsi2c3", "aclk66", GATE_IP_PERIC, 31, 0, 0), - GATE(chipid, "chipid", "aclk66", GATE_IP_PERIS, 0, 0, 0), - GATE(sysreg, "sysreg", "aclk66", - GATE_IP_PERIS, 1, CLK_IGNORE_UNUSED, 0), - GATE(pmu, "pmu", "aclk66", GATE_IP_PERIS, 2, CLK_IGNORE_UNUSED, 0), - GATE(tzpc0, "tzpc0", "aclk66", GATE_IP_PERIS, 6, 0, 0), - GATE(tzpc1, "tzpc1", "aclk66", GATE_IP_PERIS, 7, 0, 0), - GATE(tzpc2, "tzpc2", "aclk66", GATE_IP_PERIS, 8, 0, 0), - GATE(tzpc3, "tzpc3", "aclk66", GATE_IP_PERIS, 9, 0, 0), - GATE(tzpc4, "tzpc4", "aclk66", GATE_IP_PERIS, 10, 0, 0), - GATE(tzpc5, "tzpc5", "aclk66", GATE_IP_PERIS, 11, 0, 0), - GATE(tzpc6, "tzpc6", "aclk66", GATE_IP_PERIS, 12, 0, 0), - GATE(tzpc7, "tzpc7", "aclk66", GATE_IP_PERIS, 13, 0, 0), - GATE(tzpc8, "tzpc8", "aclk66", GATE_IP_PERIS, 14, 0, 0), - GATE(tzpc9, "tzpc9", "aclk66", GATE_IP_PERIS, 15, 0, 0), - GATE(hdmi_cec, "hdmi_cec", "aclk66", GATE_IP_PERIS, 16, 0, 0), - GATE(mct, "mct", "aclk66", GATE_IP_PERIS, 18, 0, 0), - GATE(wdt, "wdt", "aclk66", GATE_IP_PERIS, 19, 0, 0), - GATE(rtc, "rtc", "aclk66", GATE_IP_PERIS, 20, 0, 0), - GATE(tmu, "tmu", "aclk66", GATE_IP_PERIS, 21, 0, 0), - GATE(cmu_top, "cmu_top", "aclk66", - GATE_IP_PERIS, 3, CLK_IGNORE_UNUSED, 0), - GATE(cmu_core, "cmu_core", "aclk66", - GATE_IP_PERIS, 4, CLK_IGNORE_UNUSED, 0), - GATE(cmu_mem, "cmu_mem", "aclk66", - GATE_IP_PERIS, 5, CLK_IGNORE_UNUSED, 0), - GATE(sclk_cam_bayer, "sclk_cam_bayer", "div_cam_bayer", + /* + * NOTE: Following table is sorted by (clock domain, register address, + * bitfield shift) triplet in ascending order. When adding new entries, + * please make sure that the order is kept, to avoid merge conflicts + * and make further work with defined data easier. + */ + + /* + * CMU_ACP + */ + GATE(CLK_MDMA0, "mdma0", "div_aclk266", GATE_IP_ACP, 1, 0, 0), + GATE(CLK_G2D, "g2d", "div_aclk200", GATE_IP_ACP, 3, 0, 0), + GATE(CLK_SMMU_MDMA0, "smmu_mdma0", "div_aclk266", GATE_IP_ACP, 5, 0, 0), + + /* + * CMU_TOP + */ + GATE(CLK_SCLK_CAM_BAYER, "sclk_cam_bayer", "div_cam_bayer", SRC_MASK_GSCL, 12, CLK_SET_RATE_PARENT, 0), - GATE(sclk_cam0, "sclk_cam0", "div_cam0", + GATE(CLK_SCLK_CAM0, "sclk_cam0", "div_cam0", SRC_MASK_GSCL, 16, CLK_SET_RATE_PARENT, 0), - GATE(sclk_cam1, "sclk_cam1", "div_cam1", + GATE(CLK_SCLK_CAM1, "sclk_cam1", "div_cam1", SRC_MASK_GSCL, 20, CLK_SET_RATE_PARENT, 0), - GATE(sclk_gscl_wa, "sclk_gscl_wa", "div_gscl_wa", + GATE(CLK_SCLK_GSCL_WA, "sclk_gscl_wa", "div_gscl_wa", SRC_MASK_GSCL, 24, CLK_SET_RATE_PARENT, 0), - GATE(sclk_gscl_wb, "sclk_gscl_wb", "div_gscl_wb", + GATE(CLK_SCLK_GSCL_WB, "sclk_gscl_wb", "div_gscl_wb", SRC_MASK_GSCL, 28, CLK_SET_RATE_PARENT, 0), - GATE(sclk_fimd1, "sclk_fimd1", "div_fimd1", + + GATE(CLK_SCLK_FIMD1, "sclk_fimd1", "div_fimd1", SRC_MASK_DISP1_0, 0, CLK_SET_RATE_PARENT, 0), - GATE(sclk_mipi1, "sclk_mipi1", "div_mipi1", + GATE(CLK_SCLK_MIPI1, "sclk_mipi1", "div_mipi1", SRC_MASK_DISP1_0, 12, CLK_SET_RATE_PARENT, 0), - GATE(sclk_dp, "sclk_dp", "div_dp", + GATE(CLK_SCLK_DP, "sclk_dp", "div_dp", SRC_MASK_DISP1_0, 16, CLK_SET_RATE_PARENT, 0), - GATE(sclk_hdmi, "sclk_hdmi", "mout_hdmi", + GATE(CLK_SCLK_HDMI, "sclk_hdmi", "mout_hdmi", SRC_MASK_DISP1_0, 20, 0, 0), - GATE(sclk_audio0, "sclk_audio0", "div_audio0", + + GATE(CLK_SCLK_AUDIO0, "sclk_audio0", "div_audio0", SRC_MASK_MAU, 0, CLK_SET_RATE_PARENT, 0), - GATE(sclk_mmc0, "sclk_mmc0", "div_mmc_pre0", + + GATE(CLK_SCLK_MMC0, "sclk_mmc0", "div_mmc_pre0", SRC_MASK_FSYS, 0, CLK_SET_RATE_PARENT, 0), - GATE(sclk_mmc1, "sclk_mmc1", "div_mmc_pre1", + GATE(CLK_SCLK_MMC1, "sclk_mmc1", "div_mmc_pre1", SRC_MASK_FSYS, 4, CLK_SET_RATE_PARENT, 0), - GATE(sclk_mmc2, "sclk_mmc2", "div_mmc_pre2", + GATE(CLK_SCLK_MMC2, "sclk_mmc2", "div_mmc_pre2", SRC_MASK_FSYS, 8, CLK_SET_RATE_PARENT, 0), - GATE(sclk_mmc3, "sclk_mmc3", "div_mmc_pre3", + GATE(CLK_SCLK_MMC3, "sclk_mmc3", "div_mmc_pre3", SRC_MASK_FSYS, 12, CLK_SET_RATE_PARENT, 0), - GATE(sclk_sata, "sclk_sata", "div_sata", + GATE(CLK_SCLK_SATA, "sclk_sata", "div_sata", SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0), - GATE(sclk_usb3, "sclk_usb3", "div_usb3", + GATE(CLK_SCLK_USB3, "sclk_usb3", "div_usb3", SRC_MASK_FSYS, 28, CLK_SET_RATE_PARENT, 0), - GATE(sclk_jpeg, "sclk_jpeg", "div_jpeg", + + GATE(CLK_SCLK_JPEG, "sclk_jpeg", "div_jpeg", SRC_MASK_GEN, 0, CLK_SET_RATE_PARENT, 0), - GATE(sclk_uart0, "sclk_uart0", "div_uart0", + + GATE(CLK_SCLK_UART0, "sclk_uart0", "div_uart0", SRC_MASK_PERIC0, 0, CLK_SET_RATE_PARENT, 0), - GATE(sclk_uart1, "sclk_uart1", "div_uart1", + GATE(CLK_SCLK_UART1, "sclk_uart1", "div_uart1", SRC_MASK_PERIC0, 4, CLK_SET_RATE_PARENT, 0), - GATE(sclk_uart2, "sclk_uart2", "div_uart2", + GATE(CLK_SCLK_UART2, "sclk_uart2", "div_uart2", SRC_MASK_PERIC0, 8, CLK_SET_RATE_PARENT, 0), - GATE(sclk_uart3, "sclk_uart3", "div_uart3", + GATE(CLK_SCLK_UART3, "sclk_uart3", "div_uart3", SRC_MASK_PERIC0, 12, CLK_SET_RATE_PARENT, 0), - GATE(sclk_pwm, "sclk_pwm", "div_pwm", + GATE(CLK_SCLK_PWM, "sclk_pwm", "div_pwm", SRC_MASK_PERIC0, 24, CLK_SET_RATE_PARENT, 0), - GATE(sclk_audio1, "sclk_audio1", "div_audio1", + + GATE(CLK_SCLK_AUDIO1, "sclk_audio1", "div_audio1", SRC_MASK_PERIC1, 0, CLK_SET_RATE_PARENT, 0), - GATE(sclk_audio2, "sclk_audio2", "div_audio2", + GATE(CLK_SCLK_AUDIO2, "sclk_audio2", "div_audio2", SRC_MASK_PERIC1, 4, CLK_SET_RATE_PARENT, 0), - GATE(sclk_spdif, "sclk_spdif", "mout_spdif", + GATE(CLK_SCLK_SPDIF, "sclk_spdif", "mout_spdif", SRC_MASK_PERIC1, 4, 0, 0), - GATE(sclk_spi0, "sclk_spi0", "div_spi_pre0", + GATE(CLK_SCLK_SPI0, "sclk_spi0", "div_spi_pre0", SRC_MASK_PERIC1, 16, CLK_SET_RATE_PARENT, 0), - GATE(sclk_spi1, "sclk_spi1", "div_spi_pre1", + GATE(CLK_SCLK_SPI1, "sclk_spi1", "div_spi_pre1", SRC_MASK_PERIC1, 20, CLK_SET_RATE_PARENT, 0), - GATE(sclk_spi2, "sclk_spi2", "div_spi_pre2", + GATE(CLK_SCLK_SPI2, "sclk_spi2", "div_spi_pre2", SRC_MASK_PERIC1, 24, CLK_SET_RATE_PARENT, 0), - GATE(fimd1, "fimd1", "aclk200", GATE_IP_DISP1, 0, 0, 0), - GATE(mie1, "mie1", "aclk200", GATE_IP_DISP1, 1, 0, 0), - GATE(dsim0, "dsim0", "aclk200", GATE_IP_DISP1, 3, 0, 0), - GATE(dp, "dp", "aclk200", GATE_IP_DISP1, 4, 0, 0), - GATE(mixer, "mixer", "mout_aclk200_disp1", GATE_IP_DISP1, 5, 0, 0), - GATE(hdmi, "hdmi", "mout_aclk200_disp1", GATE_IP_DISP1, 6, 0, 0), - GATE(g2d, "g2d", "aclk200", GATE_IP_ACP, 3, 0, 0), - GATE(mdma0, "mdma0", "aclk266", GATE_IP_ACP, 1, 0, 0), - GATE(smmu_mdma0, "smmu_mdma0", "aclk266", GATE_IP_ACP, 5, 0, 0), + + GATE(CLK_GSCL0, "gscl0", "mout_aclk266_gscl_sub", GATE_IP_GSCL, 0, 0, + 0), + GATE(CLK_GSCL1, "gscl1", "mout_aclk266_gscl_sub", GATE_IP_GSCL, 1, 0, + 0), + GATE(CLK_GSCL2, "gscl2", "mout_aclk266_gscl_sub", GATE_IP_GSCL, 2, 0, + 0), + GATE(CLK_GSCL3, "gscl3", "mout_aclk266_gscl_sub", GATE_IP_GSCL, 3, 0, + 0), + GATE(CLK_GSCL_WA, "gscl_wa", "div_gscl_wa", GATE_IP_GSCL, 5, 0, 0), + GATE(CLK_GSCL_WB, "gscl_wb", "div_gscl_wb", GATE_IP_GSCL, 6, 0, 0), + GATE(CLK_SMMU_GSCL0, "smmu_gscl0", "mout_aclk266_gscl_sub", + GATE_IP_GSCL, 7, 0, 0), + GATE(CLK_SMMU_GSCL1, "smmu_gscl1", "mout_aclk266_gscl_sub", + GATE_IP_GSCL, 8, 0, 0), + GATE(CLK_SMMU_GSCL2, "smmu_gscl2", "mout_aclk266_gscl_sub", + GATE_IP_GSCL, 9, 0, 0), + GATE(CLK_SMMU_GSCL3, "smmu_gscl3", "mout_aclk266_gscl_sub", + GATE_IP_GSCL, 10, 0, 0), + + GATE(CLK_FIMD1, "fimd1", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 0, 0, + 0), + GATE(CLK_MIE1, "mie1", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 1, 0, + 0), + GATE(CLK_DSIM0, "dsim0", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 3, 0, + 0), + GATE(CLK_DP, "dp", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 4, 0, 0), + GATE(CLK_MIXER, "mixer", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 5, 0, + 0), + GATE(CLK_HDMI, "hdmi", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 6, 0, + 0), + + GATE(CLK_MFC, "mfc", "mout_aclk333_sub", GATE_IP_MFC, 0, 0, 0), + GATE(CLK_SMMU_MFCR, "smmu_mfcr", "mout_aclk333_sub", GATE_IP_MFC, 1, 0, + 0), + GATE(CLK_SMMU_MFCL, "smmu_mfcl", "mout_aclk333_sub", GATE_IP_MFC, 2, 0, + 0), + + GATE(CLK_ROTATOR, "rotator", "div_aclk266", GATE_IP_GEN, 1, 0, 0), + GATE(CLK_JPEG, "jpeg", "div_aclk166", GATE_IP_GEN, 2, 0, 0), + GATE(CLK_MDMA1, "mdma1", "div_aclk266", GATE_IP_GEN, 4, 0, 0), + GATE(CLK_SMMU_ROTATOR, "smmu_rotator", "div_aclk266", GATE_IP_GEN, 6, 0, + 0), + GATE(CLK_SMMU_JPEG, "smmu_jpeg", "div_aclk166", GATE_IP_GEN, 7, 0, 0), + GATE(CLK_SMMU_MDMA1, "smmu_mdma1", "div_aclk266", GATE_IP_GEN, 9, 0, 0), + + GATE(CLK_PDMA0, "pdma0", "div_aclk200", GATE_IP_FSYS, 1, 0, 0), + GATE(CLK_PDMA1, "pdma1", "div_aclk200", GATE_IP_FSYS, 2, 0, 0), + GATE(CLK_SATA, "sata", "div_aclk200", GATE_IP_FSYS, 6, 0, 0), + GATE(CLK_USBOTG, "usbotg", "div_aclk200", GATE_IP_FSYS, 7, 0, 0), + GATE(CLK_MIPI_HSI, "mipi_hsi", "div_aclk200", GATE_IP_FSYS, 8, 0, 0), + GATE(CLK_SDMMC0, "sdmmc0", "div_aclk200", GATE_IP_FSYS, 12, 0, 0), + GATE(CLK_SDMMC1, "sdmmc1", "div_aclk200", GATE_IP_FSYS, 13, 0, 0), + GATE(CLK_SDMMC2, "sdmmc2", "div_aclk200", GATE_IP_FSYS, 14, 0, 0), + GATE(CLK_SDMMC3, "sdmmc3", "div_aclk200", GATE_IP_FSYS, 15, 0, 0), + GATE(CLK_SROMC, "sromc", "div_aclk200", GATE_IP_FSYS, 17, 0, 0), + GATE(CLK_USB2, "usb2", "div_aclk200", GATE_IP_FSYS, 18, 0, 0), + GATE(CLK_USB3, "usb3", "div_aclk200", GATE_IP_FSYS, 19, 0, 0), + GATE(CLK_SATA_PHYCTRL, "sata_phyctrl", "div_aclk200", + GATE_IP_FSYS, 24, 0, 0), + GATE(CLK_SATA_PHYI2C, "sata_phyi2c", "div_aclk200", GATE_IP_FSYS, 25, 0, + 0), + + GATE(CLK_UART0, "uart0", "div_aclk66", GATE_IP_PERIC, 0, 0, 0), + GATE(CLK_UART1, "uart1", "div_aclk66", GATE_IP_PERIC, 1, 0, 0), + GATE(CLK_UART2, "uart2", "div_aclk66", GATE_IP_PERIC, 2, 0, 0), + GATE(CLK_UART3, "uart3", "div_aclk66", GATE_IP_PERIC, 3, 0, 0), + GATE(CLK_UART4, "uart4", "div_aclk66", GATE_IP_PERIC, 4, 0, 0), + GATE(CLK_I2C0, "i2c0", "div_aclk66", GATE_IP_PERIC, 6, 0, 0), + GATE(CLK_I2C1, "i2c1", "div_aclk66", GATE_IP_PERIC, 7, 0, 0), + GATE(CLK_I2C2, "i2c2", "div_aclk66", GATE_IP_PERIC, 8, 0, 0), + GATE(CLK_I2C3, "i2c3", "div_aclk66", GATE_IP_PERIC, 9, 0, 0), + GATE(CLK_I2C4, "i2c4", "div_aclk66", GATE_IP_PERIC, 10, 0, 0), + GATE(CLK_I2C5, "i2c5", "div_aclk66", GATE_IP_PERIC, 11, 0, 0), + GATE(CLK_I2C6, "i2c6", "div_aclk66", GATE_IP_PERIC, 12, 0, 0), + GATE(CLK_I2C7, "i2c7", "div_aclk66", GATE_IP_PERIC, 13, 0, 0), + GATE(CLK_I2C_HDMI, "i2c_hdmi", "div_aclk66", GATE_IP_PERIC, 14, 0, 0), + GATE(CLK_ADC, "adc", "div_aclk66", GATE_IP_PERIC, 15, 0, 0), + GATE(CLK_SPI0, "spi0", "div_aclk66", GATE_IP_PERIC, 16, 0, 0), + GATE(CLK_SPI1, "spi1", "div_aclk66", GATE_IP_PERIC, 17, 0, 0), + GATE(CLK_SPI2, "spi2", "div_aclk66", GATE_IP_PERIC, 18, 0, 0), + GATE(CLK_I2S1, "i2s1", "div_aclk66", GATE_IP_PERIC, 20, 0, 0), + GATE(CLK_I2S2, "i2s2", "div_aclk66", GATE_IP_PERIC, 21, 0, 0), + GATE(CLK_PCM1, "pcm1", "div_aclk66", GATE_IP_PERIC, 22, 0, 0), + GATE(CLK_PCM2, "pcm2", "div_aclk66", GATE_IP_PERIC, 23, 0, 0), + GATE(CLK_PWM, "pwm", "div_aclk66", GATE_IP_PERIC, 24, 0, 0), + GATE(CLK_SPDIF, "spdif", "div_aclk66", GATE_IP_PERIC, 26, 0, 0), + GATE(CLK_AC97, "ac97", "div_aclk66", GATE_IP_PERIC, 27, 0, 0), + GATE(CLK_HSI2C0, "hsi2c0", "div_aclk66", GATE_IP_PERIC, 28, 0, 0), + GATE(CLK_HSI2C1, "hsi2c1", "div_aclk66", GATE_IP_PERIC, 29, 0, 0), + GATE(CLK_HSI2C2, "hsi2c2", "div_aclk66", GATE_IP_PERIC, 30, 0, 0), + GATE(CLK_HSI2C3, "hsi2c3", "div_aclk66", GATE_IP_PERIC, 31, 0, 0), + + GATE(CLK_CHIPID, "chipid", "div_aclk66", GATE_IP_PERIS, 0, 0, 0), + GATE(CLK_SYSREG, "sysreg", "div_aclk66", + GATE_IP_PERIS, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PMU, "pmu", "div_aclk66", GATE_IP_PERIS, 2, CLK_IGNORE_UNUSED, + 0), + GATE(CLK_CMU_TOP, "cmu_top", "div_aclk66", + GATE_IP_PERIS, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_CMU_CORE, "cmu_core", "div_aclk66", + GATE_IP_PERIS, 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_CMU_MEM, "cmu_mem", "div_aclk66", + GATE_IP_PERIS, 5, CLK_IGNORE_UNUSED, 0), + GATE(CLK_TZPC0, "tzpc0", "div_aclk66", GATE_IP_PERIS, 6, 0, 0), + GATE(CLK_TZPC1, "tzpc1", "div_aclk66", GATE_IP_PERIS, 7, 0, 0), + GATE(CLK_TZPC2, "tzpc2", "div_aclk66", GATE_IP_PERIS, 8, 0, 0), + GATE(CLK_TZPC3, "tzpc3", "div_aclk66", GATE_IP_PERIS, 9, 0, 0), + GATE(CLK_TZPC4, "tzpc4", "div_aclk66", GATE_IP_PERIS, 10, 0, 0), + GATE(CLK_TZPC5, "tzpc5", "div_aclk66", GATE_IP_PERIS, 11, 0, 0), + GATE(CLK_TZPC6, "tzpc6", "div_aclk66", GATE_IP_PERIS, 12, 0, 0), + GATE(CLK_TZPC7, "tzpc7", "div_aclk66", GATE_IP_PERIS, 13, 0, 0), + GATE(CLK_TZPC8, "tzpc8", "div_aclk66", GATE_IP_PERIS, 14, 0, 0), + GATE(CLK_TZPC9, "tzpc9", "div_aclk66", GATE_IP_PERIS, 15, 0, 0), + GATE(CLK_HDMI_CEC, "hdmi_cec", "div_aclk66", GATE_IP_PERIS, 16, 0, 0), + GATE(CLK_MCT, "mct", "div_aclk66", GATE_IP_PERIS, 18, 0, 0), + GATE(CLK_WDT, "wdt", "div_aclk66", GATE_IP_PERIS, 19, 0, 0), + GATE(CLK_RTC, "rtc", "div_aclk66", GATE_IP_PERIS, 20, 0, 0), + GATE(CLK_TMU, "tmu", "div_aclk66", GATE_IP_PERIS, 21, 0, 0), }; static struct samsung_pll_rate_table vpll_24mhz_tbl[] __initdata = { @@ -521,20 +599,41 @@ static struct samsung_pll_rate_table epll_24mhz_tbl[] __initdata = { { }, }; +static struct samsung_pll_rate_table apll_24mhz_tbl[] __initdata = { + /* sorted in descending order */ + /* PLL_35XX_RATE(rate, m, p, s) */ + PLL_35XX_RATE(1700000000, 425, 6, 0), + PLL_35XX_RATE(1600000000, 200, 3, 0), + PLL_35XX_RATE(1500000000, 250, 4, 0), + PLL_35XX_RATE(1400000000, 175, 3, 0), + PLL_35XX_RATE(1300000000, 325, 6, 0), + PLL_35XX_RATE(1200000000, 200, 4, 0), + PLL_35XX_RATE(1100000000, 275, 6, 0), + PLL_35XX_RATE(1000000000, 125, 3, 0), + PLL_35XX_RATE(900000000, 150, 4, 0), + PLL_35XX_RATE(800000000, 100, 3, 0), + PLL_35XX_RATE(700000000, 175, 3, 1), + PLL_35XX_RATE(600000000, 200, 4, 1), + PLL_35XX_RATE(500000000, 125, 3, 1), + PLL_35XX_RATE(400000000, 100, 3, 1), + PLL_35XX_RATE(300000000, 200, 4, 2), + PLL_35XX_RATE(200000000, 100, 3, 2), +}; + static struct samsung_pll_clock exynos5250_plls[nr_plls] __initdata = { - [apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", APLL_LOCK, - APLL_CON0, "fout_apll", NULL), - [mpll] = PLL_A(pll_35xx, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK, - MPLL_CON0, "fout_mpll", NULL), - [bpll] = PLL(pll_35xx, fout_bpll, "fout_bpll", "fin_pll", BPLL_LOCK, + [apll] = PLL_A(pll_35xx, CLK_FOUT_APLL, "fout_apll", "fin_pll", + APLL_LOCK, APLL_CON0, "fout_apll", NULL), + [mpll] = PLL_A(pll_35xx, CLK_FOUT_MPLL, "fout_mpll", "fin_pll", + MPLL_LOCK, MPLL_CON0, "fout_mpll", NULL), + [bpll] = PLL(pll_35xx, CLK_FOUT_BPLL, "fout_bpll", "fin_pll", BPLL_LOCK, BPLL_CON0, NULL), - [gpll] = PLL(pll_35xx, fout_gpll, "fout_gpll", "fin_pll", GPLL_LOCK, + [gpll] = PLL(pll_35xx, CLK_FOUT_GPLL, "fout_gpll", "fin_pll", GPLL_LOCK, GPLL_CON0, NULL), - [cpll] = PLL(pll_35xx, fout_cpll, "fout_cpll", "fin_pll", CPLL_LOCK, + [cpll] = PLL(pll_35xx, CLK_FOUT_CPLL, "fout_cpll", "fin_pll", CPLL_LOCK, CPLL_CON0, NULL), - [epll] = PLL(pll_36xx, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK, + [epll] = PLL(pll_36xx, CLK_FOUT_EPLL, "fout_epll", "fin_pll", EPLL_LOCK, EPLL_CON0, NULL), - [vpll] = PLL(pll_36xx, fout_vpll, "fout_vpll", "mout_vpllsrc", + [vpll] = PLL(pll_36xx, CLK_FOUT_VPLL, "fout_vpll", "mout_vpllsrc", VPLL_LOCK, VPLL_CON0, NULL), }; @@ -556,7 +655,7 @@ static void __init exynos5250_clk_init(struct device_node *np) panic("%s: unable to determine soc\n", __func__); } - samsung_clk_init(np, reg_base, nr_clks, + samsung_clk_init(np, reg_base, CLK_NR_CLKS, exynos5250_clk_regs, ARRAY_SIZE(exynos5250_clk_regs), NULL, 0); samsung_clk_of_register_fixed_ext(exynos5250_fixed_rate_ext_clks, @@ -565,8 +664,10 @@ static void __init exynos5250_clk_init(struct device_node *np) samsung_clk_register_mux(exynos5250_pll_pmux_clks, ARRAY_SIZE(exynos5250_pll_pmux_clks)); - if (_get_rate("fin_pll") == 24 * MHZ) + if (_get_rate("fin_pll") == 24 * MHZ) { exynos5250_plls[epll].rate_table = epll_24mhz_tbl; + exynos5250_plls[apll].rate_table = apll_24mhz_tbl; + } if (_get_rate("mout_vpllsrc") == 24 * MHZ) exynos5250_plls[vpll].rate_table = vpll_24mhz_tbl; @@ -585,6 +686,6 @@ static void __init exynos5250_clk_init(struct device_node *np) ARRAY_SIZE(exynos5250_gate_clks)); pr_info("Exynos5250: clock setup completed, armclk=%ld\n", - _get_rate("armclk")); + _get_rate("div_arm2")); } CLK_OF_DECLARE(exynos5250_clk, "samsung,exynos5250-clock", exynos5250_clk_init); diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 48c4a9350b91..ab4f2f7d88ef 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -10,6 +10,7 @@ * Common Clock Framework support for Exynos5420 SoC. */ +#include <dt-bindings/clock/exynos5420.h> #include <linux/clk.h> #include <linux/clkdev.h> #include <linux/clk-provider.h> @@ -107,48 +108,6 @@ enum exynos5420_plls { nr_plls /* number of PLLs */ }; -enum exynos5420_clks { - none, - - /* core clocks */ - fin_pll, fout_apll, fout_cpll, fout_dpll, fout_epll, fout_rpll, - fout_ipll, fout_spll, fout_vpll, fout_mpll, fout_bpll, fout_kpll, - - /* gate for special clocks (sclk) */ - sclk_uart0 = 128, sclk_uart1, sclk_uart2, sclk_uart3, sclk_mmc0, - sclk_mmc1, sclk_mmc2, sclk_spi0, sclk_spi1, sclk_spi2, sclk_i2s1, - sclk_i2s2, sclk_pcm1, sclk_pcm2, sclk_spdif, sclk_hdmi, sclk_pixel, - sclk_dp1, sclk_mipi1, sclk_fimd1, sclk_maudio0, sclk_maupcm0, - sclk_usbd300, sclk_usbd301, sclk_usbphy300, sclk_usbphy301, sclk_unipro, - sclk_pwm, sclk_gscl_wa, sclk_gscl_wb, sclk_hdmiphy, - - /* gate clocks */ - aclk66_peric = 256, uart0, uart1, uart2, uart3, i2c0, i2c1, i2c2, i2c3, - i2c4, i2c5, i2c6, i2c7, i2c_hdmi, tsadc, spi0, spi1, spi2, keyif, i2s1, - i2s2, pcm1, pcm2, pwm, spdif, i2c8, i2c9, i2c10, aclk66_psgen = 300, - chipid, sysreg, tzpc0, tzpc1, tzpc2, tzpc3, tzpc4, tzpc5, tzpc6, tzpc7, - tzpc8, tzpc9, hdmi_cec, seckey, mct, wdt, rtc, tmu, tmu_gpu, - pclk66_gpio = 330, aclk200_fsys2 = 350, mmc0, mmc1, mmc2, sromc, ufs, - aclk200_fsys = 360, tsi, pdma0, pdma1, rtic, usbh20, usbd300, usbd301, - aclk400_mscl = 380, mscl0, mscl1, mscl2, smmu_mscl0, smmu_mscl1, - smmu_mscl2, aclk333 = 400, mfc, smmu_mfcl, smmu_mfcr, - aclk200_disp1 = 410, dsim1, dp1, hdmi, aclk300_disp1 = 420, fimd1, - smmu_fimd1, aclk166 = 430, mixer, aclk266 = 440, rotator, mdma1, - smmu_rotator, smmu_mdma1, aclk300_jpeg = 450, jpeg, jpeg2, smmu_jpeg, - aclk300_gscl = 460, smmu_gscl0, smmu_gscl1, gscl_wa, gscl_wb, gscl0, - gscl1, clk_3aa, aclk266_g2d = 470, sss, slim_sss, mdma0, - aclk333_g2d = 480, g2d, aclk333_432_gscl = 490, smmu_3aa, smmu_fimcl0, - smmu_fimcl1, smmu_fimcl3, fimc_lite3, aclk_g3d = 500, g3d, smmu_mixer, - - /* mux clocks */ - mout_hdmi = 640, - - /* divider clocks */ - dout_pixel = 768, - - nr_clks, -}; - /* * list of controller registers to be saved and restored during a * suspend/resume cycle. @@ -298,225 +257,226 @@ PNAME(maudio0_p) = { "fin_pll", "maudio_clk", "sclk_dpll", "sclk_mpll", /* fixed rate clocks generated outside the soc */ static struct samsung_fixed_rate_clock exynos5420_fixed_rate_ext_clks[] __initdata = { - FRATE(fin_pll, "fin_pll", NULL, CLK_IS_ROOT, 0), + FRATE(CLK_FIN_PLL, "fin_pll", NULL, CLK_IS_ROOT, 0), }; /* fixed rate clocks generated inside the soc */ static struct samsung_fixed_rate_clock exynos5420_fixed_rate_clks[] __initdata = { - FRATE(sclk_hdmiphy, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 24000000), - FRATE(none, "sclk_pwi", NULL, CLK_IS_ROOT, 24000000), - FRATE(none, "sclk_usbh20", NULL, CLK_IS_ROOT, 48000000), - FRATE(none, "mphy_refclk_ixtal24", NULL, CLK_IS_ROOT, 48000000), - FRATE(none, "sclk_usbh20_scan_clk", NULL, CLK_IS_ROOT, 480000000), + FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 24000000), + FRATE(0, "sclk_pwi", NULL, CLK_IS_ROOT, 24000000), + FRATE(0, "sclk_usbh20", NULL, CLK_IS_ROOT, 48000000), + FRATE(0, "mphy_refclk_ixtal24", NULL, CLK_IS_ROOT, 48000000), + FRATE(0, "sclk_usbh20_scan_clk", NULL, CLK_IS_ROOT, 480000000), }; static struct samsung_fixed_factor_clock exynos5420_fixed_factor_clks[] __initdata = { - FFACTOR(none, "sclk_hsic_12m", "fin_pll", 1, 2, 0), + FFACTOR(0, "sclk_hsic_12m", "fin_pll", 1, 2, 0), }; static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { - MUX(none, "mout_mspll_kfc", mspll_cpu_p, SRC_TOP7, 8, 2), - MUX(none, "mout_mspll_cpu", mspll_cpu_p, SRC_TOP7, 12, 2), - MUX(none, "mout_apll", apll_p, SRC_CPU, 0, 1), - MUX(none, "mout_cpu", cpu_p, SRC_CPU, 16, 1), - MUX(none, "mout_kpll", kpll_p, SRC_KFC, 0, 1), - MUX(none, "mout_cpu_kfc", kfc_p, SRC_KFC, 16, 1), + MUX(0, "mout_mspll_kfc", mspll_cpu_p, SRC_TOP7, 8, 2), + MUX(0, "mout_mspll_cpu", mspll_cpu_p, SRC_TOP7, 12, 2), + MUX(0, "mout_apll", apll_p, SRC_CPU, 0, 1), + MUX(0, "mout_cpu", cpu_p, SRC_CPU, 16, 1), + MUX(0, "mout_kpll", kpll_p, SRC_KFC, 0, 1), + MUX(0, "mout_cpu_kfc", kfc_p, SRC_KFC, 16, 1), - MUX(none, "sclk_bpll", bpll_p, SRC_CDREX, 0, 1), + MUX(0, "sclk_bpll", bpll_p, SRC_CDREX, 0, 1), - MUX_A(none, "mout_aclk400_mscl", group1_p, + MUX_A(0, "mout_aclk400_mscl", group1_p, SRC_TOP0, 4, 2, "aclk400_mscl"), - MUX(none, "mout_aclk200", group1_p, SRC_TOP0, 8, 2), - MUX(none, "mout_aclk200_fsys2", group1_p, SRC_TOP0, 12, 2), - MUX(none, "mout_aclk200_fsys", group1_p, SRC_TOP0, 28, 2), - - MUX(none, "mout_aclk333_432_gscl", group4_p, SRC_TOP1, 0, 2), - MUX(none, "mout_aclk66", group1_p, SRC_TOP1, 8, 2), - MUX(none, "mout_aclk266", group1_p, SRC_TOP1, 20, 2), - MUX(none, "mout_aclk166", group1_p, SRC_TOP1, 24, 2), - MUX(none, "mout_aclk333", group1_p, SRC_TOP1, 28, 2), - - MUX(none, "mout_aclk333_g2d", group1_p, SRC_TOP2, 8, 2), - MUX(none, "mout_aclk266_g2d", group1_p, SRC_TOP2, 12, 2), - MUX(none, "mout_aclk_g3d", group5_p, SRC_TOP2, 16, 1), - MUX(none, "mout_aclk300_jpeg", group1_p, SRC_TOP2, 20, 2), - MUX(none, "mout_aclk300_disp1", group1_p, SRC_TOP2, 24, 2), - MUX(none, "mout_aclk300_gscl", group1_p, SRC_TOP2, 28, 2), - - MUX(none, "mout_user_aclk400_mscl", user_aclk400_mscl_p, + MUX(0, "mout_aclk200", group1_p, SRC_TOP0, 8, 2), + MUX(0, "mout_aclk200_fsys2", group1_p, SRC_TOP0, 12, 2), + MUX(0, "mout_aclk200_fsys", group1_p, SRC_TOP0, 28, 2), + + MUX(0, "mout_aclk333_432_gscl", group4_p, SRC_TOP1, 0, 2), + MUX(0, "mout_aclk66", group1_p, SRC_TOP1, 8, 2), + MUX(0, "mout_aclk266", group1_p, SRC_TOP1, 20, 2), + MUX(0, "mout_aclk166", group1_p, SRC_TOP1, 24, 2), + MUX(0, "mout_aclk333", group1_p, SRC_TOP1, 28, 2), + + MUX(0, "mout_aclk333_g2d", group1_p, SRC_TOP2, 8, 2), + MUX(0, "mout_aclk266_g2d", group1_p, SRC_TOP2, 12, 2), + MUX(0, "mout_aclk_g3d", group5_p, SRC_TOP2, 16, 1), + MUX(0, "mout_aclk300_jpeg", group1_p, SRC_TOP2, 20, 2), + MUX(0, "mout_aclk300_disp1", group1_p, SRC_TOP2, 24, 2), + MUX(0, "mout_aclk300_gscl", group1_p, SRC_TOP2, 28, 2), + + MUX(0, "mout_user_aclk400_mscl", user_aclk400_mscl_p, SRC_TOP3, 4, 1), - MUX_A(none, "mout_aclk200_disp1", aclk200_disp1_p, + MUX_A(0, "mout_aclk200_disp1", aclk200_disp1_p, SRC_TOP3, 8, 1, "aclk200_disp1"), - MUX(none, "mout_user_aclk200_fsys2", user_aclk200_fsys2_p, + MUX(0, "mout_user_aclk200_fsys2", user_aclk200_fsys2_p, SRC_TOP3, 12, 1), - MUX(none, "mout_user_aclk200_fsys", user_aclk200_fsys_p, + MUX(0, "mout_user_aclk200_fsys", user_aclk200_fsys_p, SRC_TOP3, 28, 1), - MUX(none, "mout_user_aclk333_432_gscl", user_aclk333_432_gscl_p, + MUX(0, "mout_user_aclk333_432_gscl", user_aclk333_432_gscl_p, SRC_TOP4, 0, 1), - MUX(none, "mout_aclk66_peric", aclk66_peric_p, SRC_TOP4, 8, 1), - MUX(none, "mout_user_aclk266", user_aclk266_p, SRC_TOP4, 20, 1), - MUX(none, "mout_user_aclk166", user_aclk166_p, SRC_TOP4, 24, 1), - MUX(none, "mout_user_aclk333", user_aclk333_p, SRC_TOP4, 28, 1), - - MUX(none, "mout_aclk66_psgen", aclk66_peric_p, SRC_TOP5, 4, 1), - MUX(none, "mout_user_aclk333_g2d", user_aclk333_g2d_p, SRC_TOP5, 8, 1), - MUX(none, "mout_user_aclk266_g2d", user_aclk266_g2d_p, SRC_TOP5, 12, 1), - MUX_A(none, "mout_user_aclk_g3d", user_aclk_g3d_p, + MUX(0, "mout_aclk66_peric", aclk66_peric_p, SRC_TOP4, 8, 1), + MUX(0, "mout_user_aclk266", user_aclk266_p, SRC_TOP4, 20, 1), + MUX(0, "mout_user_aclk166", user_aclk166_p, SRC_TOP4, 24, 1), + MUX(0, "mout_user_aclk333", user_aclk333_p, SRC_TOP4, 28, 1), + + MUX(0, "mout_aclk66_psgen", aclk66_peric_p, SRC_TOP5, 4, 1), + MUX(0, "mout_user_aclk333_g2d", user_aclk333_g2d_p, SRC_TOP5, 8, 1), + MUX(0, "mout_user_aclk266_g2d", user_aclk266_g2d_p, SRC_TOP5, 12, 1), + MUX_A(0, "mout_user_aclk_g3d", user_aclk_g3d_p, SRC_TOP5, 16, 1, "aclkg3d"), - MUX(none, "mout_user_aclk300_jpeg", user_aclk300_jpeg_p, + MUX(0, "mout_user_aclk300_jpeg", user_aclk300_jpeg_p, SRC_TOP5, 20, 1), - MUX(none, "mout_user_aclk300_disp1", user_aclk300_disp1_p, + MUX(0, "mout_user_aclk300_disp1", user_aclk300_disp1_p, SRC_TOP5, 24, 1), - MUX(none, "mout_user_aclk300_gscl", user_aclk300_gscl_p, + MUX(0, "mout_user_aclk300_gscl", user_aclk300_gscl_p, SRC_TOP5, 28, 1), - MUX(none, "sclk_mpll", mpll_p, SRC_TOP6, 0, 1), - MUX(none, "sclk_vpll", vpll_p, SRC_TOP6, 4, 1), - MUX(none, "sclk_spll", spll_p, SRC_TOP6, 8, 1), - MUX(none, "sclk_ipll", ipll_p, SRC_TOP6, 12, 1), - MUX(none, "sclk_rpll", rpll_p, SRC_TOP6, 16, 1), - MUX(none, "sclk_epll", epll_p, SRC_TOP6, 20, 1), - MUX(none, "sclk_dpll", dpll_p, SRC_TOP6, 24, 1), - MUX(none, "sclk_cpll", cpll_p, SRC_TOP6, 28, 1), - - MUX(none, "mout_sw_aclk400_mscl", sw_aclk400_mscl_p, SRC_TOP10, 4, 1), - MUX(none, "mout_sw_aclk200", sw_aclk200_p, SRC_TOP10, 8, 1), - MUX(none, "mout_sw_aclk200_fsys2", sw_aclk200_fsys2_p, + MUX(0, "sclk_mpll", mpll_p, SRC_TOP6, 0, 1), + MUX(0, "sclk_vpll", vpll_p, SRC_TOP6, 4, 1), + MUX(0, "sclk_spll", spll_p, SRC_TOP6, 8, 1), + MUX(0, "sclk_ipll", ipll_p, SRC_TOP6, 12, 1), + MUX(0, "sclk_rpll", rpll_p, SRC_TOP6, 16, 1), + MUX(0, "sclk_epll", epll_p, SRC_TOP6, 20, 1), + MUX(0, "sclk_dpll", dpll_p, SRC_TOP6, 24, 1), + MUX(0, "sclk_cpll", cpll_p, SRC_TOP6, 28, 1), + + MUX(0, "mout_sw_aclk400_mscl", sw_aclk400_mscl_p, SRC_TOP10, 4, 1), + MUX(0, "mout_sw_aclk200", sw_aclk200_p, SRC_TOP10, 8, 1), + MUX(0, "mout_sw_aclk200_fsys2", sw_aclk200_fsys2_p, SRC_TOP10, 12, 1), - MUX(none, "mout_sw_aclk200_fsys", sw_aclk200_fsys_p, SRC_TOP10, 28, 1), + MUX(0, "mout_sw_aclk200_fsys", sw_aclk200_fsys_p, SRC_TOP10, 28, 1), - MUX(none, "mout_sw_aclk333_432_gscl", sw_aclk333_432_gscl_p, + MUX(0, "mout_sw_aclk333_432_gscl", sw_aclk333_432_gscl_p, SRC_TOP11, 0, 1), - MUX(none, "mout_sw_aclk66", sw_aclk66_p, SRC_TOP11, 8, 1), - MUX(none, "mout_sw_aclk266", sw_aclk266_p, SRC_TOP11, 20, 1), - MUX(none, "mout_sw_aclk166", sw_aclk166_p, SRC_TOP11, 24, 1), - MUX(none, "mout_sw_aclk333", sw_aclk333_p, SRC_TOP11, 28, 1), - - MUX(none, "mout_sw_aclk333_g2d", sw_aclk333_g2d_p, SRC_TOP12, 8, 1), - MUX(none, "mout_sw_aclk266_g2d", sw_aclk266_g2d_p, SRC_TOP12, 12, 1), - MUX(none, "mout_sw_aclk_g3d", sw_aclk_g3d_p, SRC_TOP12, 16, 1), - MUX(none, "mout_sw_aclk300_jpeg", sw_aclk300_jpeg_p, SRC_TOP12, 20, 1), - MUX(none, "mout_sw_aclk300_disp1", sw_aclk300_disp1_p, + MUX(0, "mout_sw_aclk66", sw_aclk66_p, SRC_TOP11, 8, 1), + MUX(0, "mout_sw_aclk266", sw_aclk266_p, SRC_TOP11, 20, 1), + MUX(0, "mout_sw_aclk166", sw_aclk166_p, SRC_TOP11, 24, 1), + MUX(0, "mout_sw_aclk333", sw_aclk333_p, SRC_TOP11, 28, 1), + + MUX(0, "mout_sw_aclk333_g2d", sw_aclk333_g2d_p, SRC_TOP12, 8, 1), + MUX(0, "mout_sw_aclk266_g2d", sw_aclk266_g2d_p, SRC_TOP12, 12, 1), + MUX(0, "mout_sw_aclk_g3d", sw_aclk_g3d_p, SRC_TOP12, 16, 1), + MUX(0, "mout_sw_aclk300_jpeg", sw_aclk300_jpeg_p, SRC_TOP12, 20, 1), + MUX(0, "mout_sw_aclk300_disp1", sw_aclk300_disp1_p, SRC_TOP12, 24, 1), - MUX(none, "mout_sw_aclk300_gscl", sw_aclk300_gscl_p, SRC_TOP12, 28, 1), + MUX(0, "mout_sw_aclk300_gscl", sw_aclk300_gscl_p, SRC_TOP12, 28, 1), /* DISP1 Block */ - MUX(none, "mout_fimd1", group3_p, SRC_DISP10, 4, 1), - MUX(none, "mout_mipi1", group2_p, SRC_DISP10, 16, 3), - MUX(none, "mout_dp1", group2_p, SRC_DISP10, 20, 3), - MUX(none, "mout_pixel", group2_p, SRC_DISP10, 24, 3), - MUX(mout_hdmi, "mout_hdmi", hdmi_p, SRC_DISP10, 28, 1), + MUX(0, "mout_fimd1", group3_p, SRC_DISP10, 4, 1), + MUX(0, "mout_mipi1", group2_p, SRC_DISP10, 16, 3), + MUX(0, "mout_dp1", group2_p, SRC_DISP10, 20, 3), + MUX(0, "mout_pixel", group2_p, SRC_DISP10, 24, 3), + MUX(CLK_MOUT_HDMI, "mout_hdmi", hdmi_p, SRC_DISP10, 28, 1), /* MAU Block */ - MUX(none, "mout_maudio0", maudio0_p, SRC_MAU, 28, 3), + MUX(0, "mout_maudio0", maudio0_p, SRC_MAU, 28, 3), /* FSYS Block */ - MUX(none, "mout_usbd301", group2_p, SRC_FSYS, 4, 3), - MUX(none, "mout_mmc0", group2_p, SRC_FSYS, 8, 3), - MUX(none, "mout_mmc1", group2_p, SRC_FSYS, 12, 3), - MUX(none, "mout_mmc2", group2_p, SRC_FSYS, 16, 3), - MUX(none, "mout_usbd300", group2_p, SRC_FSYS, 20, 3), - MUX(none, "mout_unipro", group2_p, SRC_FSYS, 24, 3), + MUX(0, "mout_usbd301", group2_p, SRC_FSYS, 4, 3), + MUX(0, "mout_mmc0", group2_p, SRC_FSYS, 8, 3), + MUX(0, "mout_mmc1", group2_p, SRC_FSYS, 12, 3), + MUX(0, "mout_mmc2", group2_p, SRC_FSYS, 16, 3), + MUX(0, "mout_usbd300", group2_p, SRC_FSYS, 20, 3), + MUX(0, "mout_unipro", group2_p, SRC_FSYS, 24, 3), /* PERIC Block */ - MUX(none, "mout_uart0", group2_p, SRC_PERIC0, 4, 3), - MUX(none, "mout_uart1", group2_p, SRC_PERIC0, 8, 3), - MUX(none, "mout_uart2", group2_p, SRC_PERIC0, 12, 3), - MUX(none, "mout_uart3", group2_p, SRC_PERIC0, 16, 3), - MUX(none, "mout_pwm", group2_p, SRC_PERIC0, 24, 3), - MUX(none, "mout_spdif", spdif_p, SRC_PERIC0, 28, 3), - MUX(none, "mout_audio0", audio0_p, SRC_PERIC1, 8, 3), - MUX(none, "mout_audio1", audio1_p, SRC_PERIC1, 12, 3), - MUX(none, "mout_audio2", audio2_p, SRC_PERIC1, 16, 3), - MUX(none, "mout_spi0", group2_p, SRC_PERIC1, 20, 3), - MUX(none, "mout_spi1", group2_p, SRC_PERIC1, 24, 3), - MUX(none, "mout_spi2", group2_p, SRC_PERIC1, 28, 3), + MUX(0, "mout_uart0", group2_p, SRC_PERIC0, 4, 3), + MUX(0, "mout_uart1", group2_p, SRC_PERIC0, 8, 3), + MUX(0, "mout_uart2", group2_p, SRC_PERIC0, 12, 3), + MUX(0, "mout_uart3", group2_p, SRC_PERIC0, 16, 3), + MUX(0, "mout_pwm", group2_p, SRC_PERIC0, 24, 3), + MUX(0, "mout_spdif", spdif_p, SRC_PERIC0, 28, 3), + MUX(0, "mout_audio0", audio0_p, SRC_PERIC1, 8, 3), + MUX(0, "mout_audio1", audio1_p, SRC_PERIC1, 12, 3), + MUX(0, "mout_audio2", audio2_p, SRC_PERIC1, 16, 3), + MUX(0, "mout_spi0", group2_p, SRC_PERIC1, 20, 3), + MUX(0, "mout_spi1", group2_p, SRC_PERIC1, 24, 3), + MUX(0, "mout_spi2", group2_p, SRC_PERIC1, 28, 3), }; static struct samsung_div_clock exynos5420_div_clks[] __initdata = { - DIV(none, "div_arm", "mout_cpu", DIV_CPU0, 0, 3), - DIV(none, "sclk_apll", "mout_apll", DIV_CPU0, 24, 3), - DIV(none, "armclk2", "div_arm", DIV_CPU0, 28, 3), - DIV(none, "div_kfc", "mout_cpu_kfc", DIV_KFC0, 0, 3), - DIV(none, "sclk_kpll", "mout_kpll", DIV_KFC0, 24, 3), - - DIV(none, "dout_aclk400_mscl", "mout_aclk400_mscl", DIV_TOP0, 4, 3), - DIV(none, "dout_aclk200", "mout_aclk200", DIV_TOP0, 8, 3), - DIV(none, "dout_aclk200_fsys2", "mout_aclk200_fsys2", DIV_TOP0, 12, 3), - DIV(none, "dout_pclk200_fsys", "mout_pclk200_fsys", DIV_TOP0, 24, 3), - DIV(none, "dout_aclk200_fsys", "mout_aclk200_fsys", DIV_TOP0, 28, 3), - - DIV(none, "dout_aclk333_432_gscl", "mout_aclk333_432_gscl", + DIV(0, "div_arm", "mout_cpu", DIV_CPU0, 0, 3), + DIV(0, "sclk_apll", "mout_apll", DIV_CPU0, 24, 3), + DIV(0, "armclk2", "div_arm", DIV_CPU0, 28, 3), + DIV(0, "div_kfc", "mout_cpu_kfc", DIV_KFC0, 0, 3), + DIV(0, "sclk_kpll", "mout_kpll", DIV_KFC0, 24, 3), + + DIV(0, "dout_aclk400_mscl", "mout_aclk400_mscl", DIV_TOP0, 4, 3), + DIV(0, "dout_aclk200", "mout_aclk200", DIV_TOP0, 8, 3), + DIV(0, "dout_aclk200_fsys2", "mout_aclk200_fsys2", DIV_TOP0, 12, 3), + DIV(0, "dout_pclk200_fsys", "mout_pclk200_fsys", DIV_TOP0, 24, 3), + DIV(0, "dout_aclk200_fsys", "mout_aclk200_fsys", DIV_TOP0, 28, 3), + + DIV(0, "dout_aclk333_432_gscl", "mout_aclk333_432_gscl", DIV_TOP1, 0, 3), - DIV(none, "dout_aclk66", "mout_aclk66", DIV_TOP1, 8, 6), - DIV(none, "dout_aclk266", "mout_aclk266", DIV_TOP1, 20, 3), - DIV(none, "dout_aclk166", "mout_aclk166", DIV_TOP1, 24, 3), - DIV(none, "dout_aclk333", "mout_aclk333", DIV_TOP1, 28, 3), - - DIV(none, "dout_aclk333_g2d", "mout_aclk333_g2d", DIV_TOP2, 8, 3), - DIV(none, "dout_aclk266_g2d", "mout_aclk266_g2d", DIV_TOP2, 12, 3), - DIV(none, "dout_aclk_g3d", "mout_aclk_g3d", DIV_TOP2, 16, 3), - DIV(none, "dout_aclk300_jpeg", "mout_aclk300_jpeg", DIV_TOP2, 20, 3), - DIV_A(none, "dout_aclk300_disp1", "mout_aclk300_disp1", + DIV(0, "dout_aclk66", "mout_aclk66", DIV_TOP1, 8, 6), + DIV(0, "dout_aclk266", "mout_aclk266", DIV_TOP1, 20, 3), + DIV(0, "dout_aclk166", "mout_aclk166", DIV_TOP1, 24, 3), + DIV(0, "dout_aclk333", "mout_aclk333", DIV_TOP1, 28, 3), + + DIV(0, "dout_aclk333_g2d", "mout_aclk333_g2d", DIV_TOP2, 8, 3), + DIV(0, "dout_aclk266_g2d", "mout_aclk266_g2d", DIV_TOP2, 12, 3), + DIV(0, "dout_aclk_g3d", "mout_aclk_g3d", DIV_TOP2, 16, 3), + DIV(0, "dout_aclk300_jpeg", "mout_aclk300_jpeg", DIV_TOP2, 20, 3), + DIV_A(0, "dout_aclk300_disp1", "mout_aclk300_disp1", DIV_TOP2, 24, 3, "aclk300_disp1"), - DIV(none, "dout_aclk300_gscl", "mout_aclk300_gscl", DIV_TOP2, 28, 3), + DIV(0, "dout_aclk300_gscl", "mout_aclk300_gscl", DIV_TOP2, 28, 3), /* DISP1 Block */ - DIV(none, "dout_fimd1", "mout_fimd1", DIV_DISP10, 0, 4), - DIV(none, "dout_mipi1", "mout_mipi1", DIV_DISP10, 16, 8), - DIV(none, "dout_dp1", "mout_dp1", DIV_DISP10, 24, 4), - DIV(dout_pixel, "dout_hdmi_pixel", "mout_pixel", DIV_DISP10, 28, 4), + DIV(0, "dout_fimd1", "mout_fimd1", DIV_DISP10, 0, 4), + DIV(0, "dout_mipi1", "mout_mipi1", DIV_DISP10, 16, 8), + DIV(0, "dout_dp1", "mout_dp1", DIV_DISP10, 24, 4), + DIV(CLK_DOUT_PIXEL, "dout_hdmi_pixel", "mout_pixel", DIV_DISP10, 28, 4), /* Audio Block */ - DIV(none, "dout_maudio0", "mout_maudio0", DIV_MAU, 20, 4), - DIV(none, "dout_maupcm0", "dout_maudio0", DIV_MAU, 24, 8), + DIV(0, "dout_maudio0", "mout_maudio0", DIV_MAU, 20, 4), + DIV(0, "dout_maupcm0", "dout_maudio0", DIV_MAU, 24, 8), /* USB3.0 */ - DIV(none, "dout_usbphy301", "mout_usbd301", DIV_FSYS0, 12, 4), - DIV(none, "dout_usbphy300", "mout_usbd300", DIV_FSYS0, 16, 4), - DIV(none, "dout_usbd301", "mout_usbd301", DIV_FSYS0, 20, 4), - DIV(none, "dout_usbd300", "mout_usbd300", DIV_FSYS0, 24, 4), + DIV(0, "dout_usbphy301", "mout_usbd301", DIV_FSYS0, 12, 4), + DIV(0, "dout_usbphy300", "mout_usbd300", DIV_FSYS0, 16, 4), + DIV(0, "dout_usbd301", "mout_usbd301", DIV_FSYS0, 20, 4), + DIV(0, "dout_usbd300", "mout_usbd300", DIV_FSYS0, 24, 4), /* MMC */ - DIV(none, "dout_mmc0", "mout_mmc0", DIV_FSYS1, 0, 10), - DIV(none, "dout_mmc1", "mout_mmc1", DIV_FSYS1, 10, 10), - DIV(none, "dout_mmc2", "mout_mmc2", DIV_FSYS1, 20, 10), + DIV(0, "dout_mmc0", "mout_mmc0", DIV_FSYS1, 0, 10), + DIV(0, "dout_mmc1", "mout_mmc1", DIV_FSYS1, 10, 10), + DIV(0, "dout_mmc2", "mout_mmc2", DIV_FSYS1, 20, 10), - DIV(none, "dout_unipro", "mout_unipro", DIV_FSYS2, 24, 8), + DIV(0, "dout_unipro", "mout_unipro", DIV_FSYS2, 24, 8), /* UART and PWM */ - DIV(none, "dout_uart0", "mout_uart0", DIV_PERIC0, 8, 4), - DIV(none, "dout_uart1", "mout_uart1", DIV_PERIC0, 12, 4), - DIV(none, "dout_uart2", "mout_uart2", DIV_PERIC0, 16, 4), - DIV(none, "dout_uart3", "mout_uart3", DIV_PERIC0, 20, 4), - DIV(none, "dout_pwm", "mout_pwm", DIV_PERIC0, 28, 4), + DIV(0, "dout_uart0", "mout_uart0", DIV_PERIC0, 8, 4), + DIV(0, "dout_uart1", "mout_uart1", DIV_PERIC0, 12, 4), + DIV(0, "dout_uart2", "mout_uart2", DIV_PERIC0, 16, 4), + DIV(0, "dout_uart3", "mout_uart3", DIV_PERIC0, 20, 4), + DIV(0, "dout_pwm", "mout_pwm", DIV_PERIC0, 28, 4), /* SPI */ - DIV(none, "dout_spi0", "mout_spi0", DIV_PERIC1, 20, 4), - DIV(none, "dout_spi1", "mout_spi1", DIV_PERIC1, 24, 4), - DIV(none, "dout_spi2", "mout_spi2", DIV_PERIC1, 28, 4), + DIV(0, "dout_spi0", "mout_spi0", DIV_PERIC1, 20, 4), + DIV(0, "dout_spi1", "mout_spi1", DIV_PERIC1, 24, 4), + DIV(0, "dout_spi2", "mout_spi2", DIV_PERIC1, 28, 4), /* PCM */ - DIV(none, "dout_pcm1", "dout_audio1", DIV_PERIC2, 16, 8), - DIV(none, "dout_pcm2", "dout_audio2", DIV_PERIC2, 24, 8), + DIV(0, "dout_pcm1", "dout_audio1", DIV_PERIC2, 16, 8), + DIV(0, "dout_pcm2", "dout_audio2", DIV_PERIC2, 24, 8), /* Audio - I2S */ - DIV(none, "dout_i2s1", "dout_audio1", DIV_PERIC3, 6, 6), - DIV(none, "dout_i2s2", "dout_audio2", DIV_PERIC3, 12, 6), - DIV(none, "dout_audio0", "mout_audio0", DIV_PERIC3, 20, 4), - DIV(none, "dout_audio1", "mout_audio1", DIV_PERIC3, 24, 4), - DIV(none, "dout_audio2", "mout_audio2", DIV_PERIC3, 28, 4), + DIV(0, "dout_i2s1", "dout_audio1", DIV_PERIC3, 6, 6), + DIV(0, "dout_i2s2", "dout_audio2", DIV_PERIC3, 12, 6), + DIV(0, "dout_audio0", "mout_audio0", DIV_PERIC3, 20, 4), + DIV(0, "dout_audio1", "mout_audio1", DIV_PERIC3, 24, 4), + DIV(0, "dout_audio2", "mout_audio2", DIV_PERIC3, 28, 4), /* SPI Pre-Ratio */ - DIV(none, "dout_pre_spi0", "dout_spi0", DIV_PERIC4, 8, 8), - DIV(none, "dout_pre_spi1", "dout_spi1", DIV_PERIC4, 16, 8), - DIV(none, "dout_pre_spi2", "dout_spi2", DIV_PERIC4, 24, 8), + DIV(0, "dout_pre_spi0", "dout_spi0", DIV_PERIC4, 8, 8), + DIV(0, "dout_pre_spi1", "dout_spi1", DIV_PERIC4, 16, 8), + DIV(0, "dout_pre_spi2", "dout_spi2", DIV_PERIC4, 24, 8), }; static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { /* TODO: Re-verify the CG bits for all the gate clocks */ - GATE_A(mct, "pclk_st", "aclk66_psgen", GATE_BUS_PERIS1, 2, 0, 0, "mct"), + GATE_A(CLK_MCT, "pclk_st", "aclk66_psgen", GATE_BUS_PERIS1, 2, 0, 0, + "mct"), GATE(0, "aclk200_fsys", "mout_user_aclk200_fsys", GATE_BUS_FSYS0, 9, CLK_IGNORE_UNUSED, 0), @@ -545,217 +505,227 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE_BUS_TOP, 15, CLK_IGNORE_UNUSED, 0), /* sclk */ - GATE(sclk_uart0, "sclk_uart0", "dout_uart0", + GATE(CLK_SCLK_UART0, "sclk_uart0", "dout_uart0", GATE_TOP_SCLK_PERIC, 0, CLK_SET_RATE_PARENT, 0), - GATE(sclk_uart1, "sclk_uart1", "dout_uart1", + GATE(CLK_SCLK_UART1, "sclk_uart1", "dout_uart1", GATE_TOP_SCLK_PERIC, 1, CLK_SET_RATE_PARENT, 0), - GATE(sclk_uart2, "sclk_uart2", "dout_uart2", + GATE(CLK_SCLK_UART2, "sclk_uart2", "dout_uart2", GATE_TOP_SCLK_PERIC, 2, CLK_SET_RATE_PARENT, 0), - GATE(sclk_uart3, "sclk_uart3", "dout_uart3", + GATE(CLK_SCLK_UART3, "sclk_uart3", "dout_uart3", GATE_TOP_SCLK_PERIC, 3, CLK_SET_RATE_PARENT, 0), - GATE(sclk_spi0, "sclk_spi0", "dout_pre_spi0", + GATE(CLK_SCLK_SPI0, "sclk_spi0", "dout_pre_spi0", GATE_TOP_SCLK_PERIC, 6, CLK_SET_RATE_PARENT, 0), - GATE(sclk_spi1, "sclk_spi1", "dout_pre_spi1", + GATE(CLK_SCLK_SPI1, "sclk_spi1", "dout_pre_spi1", GATE_TOP_SCLK_PERIC, 7, CLK_SET_RATE_PARENT, 0), - GATE(sclk_spi2, "sclk_spi2", "dout_pre_spi2", + GATE(CLK_SCLK_SPI2, "sclk_spi2", "dout_pre_spi2", GATE_TOP_SCLK_PERIC, 8, CLK_SET_RATE_PARENT, 0), - GATE(sclk_spdif, "sclk_spdif", "mout_spdif", + GATE(CLK_SCLK_SPDIF, "sclk_spdif", "mout_spdif", GATE_TOP_SCLK_PERIC, 9, CLK_SET_RATE_PARENT, 0), - GATE(sclk_pwm, "sclk_pwm", "dout_pwm", + GATE(CLK_SCLK_PWM, "sclk_pwm", "dout_pwm", GATE_TOP_SCLK_PERIC, 11, CLK_SET_RATE_PARENT, 0), - GATE(sclk_pcm1, "sclk_pcm1", "dout_pcm1", + GATE(CLK_SCLK_PCM1, "sclk_pcm1", "dout_pcm1", GATE_TOP_SCLK_PERIC, 15, CLK_SET_RATE_PARENT, 0), - GATE(sclk_pcm2, "sclk_pcm2", "dout_pcm2", + GATE(CLK_SCLK_PCM2, "sclk_pcm2", "dout_pcm2", GATE_TOP_SCLK_PERIC, 16, CLK_SET_RATE_PARENT, 0), - GATE(sclk_i2s1, "sclk_i2s1", "dout_i2s1", + GATE(CLK_SCLK_I2S1, "sclk_i2s1", "dout_i2s1", GATE_TOP_SCLK_PERIC, 17, CLK_SET_RATE_PARENT, 0), - GATE(sclk_i2s2, "sclk_i2s2", "dout_i2s2", + GATE(CLK_SCLK_I2S2, "sclk_i2s2", "dout_i2s2", GATE_TOP_SCLK_PERIC, 18, CLK_SET_RATE_PARENT, 0), - GATE(sclk_mmc0, "sclk_mmc0", "dout_mmc0", + GATE(CLK_SCLK_MMC0, "sclk_mmc0", "dout_mmc0", GATE_TOP_SCLK_FSYS, 0, CLK_SET_RATE_PARENT, 0), - GATE(sclk_mmc1, "sclk_mmc1", "dout_mmc1", + GATE(CLK_SCLK_MMC1, "sclk_mmc1", "dout_mmc1", GATE_TOP_SCLK_FSYS, 1, CLK_SET_RATE_PARENT, 0), - GATE(sclk_mmc2, "sclk_mmc2", "dout_mmc2", + GATE(CLK_SCLK_MMC2, "sclk_mmc2", "dout_mmc2", GATE_TOP_SCLK_FSYS, 2, CLK_SET_RATE_PARENT, 0), - GATE(sclk_usbphy301, "sclk_usbphy301", "dout_usbphy301", + GATE(CLK_SCLK_USBPHY301, "sclk_usbphy301", "dout_usbphy301", GATE_TOP_SCLK_FSYS, 7, CLK_SET_RATE_PARENT, 0), - GATE(sclk_usbphy300, "sclk_usbphy300", "dout_usbphy300", + GATE(CLK_SCLK_USBPHY300, "sclk_usbphy300", "dout_usbphy300", GATE_TOP_SCLK_FSYS, 8, CLK_SET_RATE_PARENT, 0), - GATE(sclk_usbd300, "sclk_usbd300", "dout_usbd300", + GATE(CLK_SCLK_USBD300, "sclk_usbd300", "dout_usbd300", GATE_TOP_SCLK_FSYS, 9, CLK_SET_RATE_PARENT, 0), - GATE(sclk_usbd301, "sclk_usbd301", "dout_usbd301", + GATE(CLK_SCLK_USBD301, "sclk_usbd301", "dout_usbd301", GATE_TOP_SCLK_FSYS, 10, CLK_SET_RATE_PARENT, 0), - GATE(sclk_usbd301, "sclk_unipro", "dout_unipro", + GATE(CLK_SCLK_USBD301, "sclk_unipro", "dout_unipro", SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0), - GATE(sclk_gscl_wa, "sclk_gscl_wa", "aclK333_432_gscl", + GATE(CLK_SCLK_GSCL_WA, "sclk_gscl_wa", "aclK333_432_gscl", GATE_TOP_SCLK_GSCL, 6, CLK_SET_RATE_PARENT, 0), - GATE(sclk_gscl_wb, "sclk_gscl_wb", "aclk333_432_gscl", + GATE(CLK_SCLK_GSCL_WB, "sclk_gscl_wb", "aclk333_432_gscl", GATE_TOP_SCLK_GSCL, 7, CLK_SET_RATE_PARENT, 0), /* Display */ - GATE(sclk_fimd1, "sclk_fimd1", "dout_fimd1", + GATE(CLK_SCLK_FIMD1, "sclk_fimd1", "dout_fimd1", GATE_TOP_SCLK_DISP1, 0, CLK_SET_RATE_PARENT, 0), - GATE(sclk_mipi1, "sclk_mipi1", "dout_mipi1", + GATE(CLK_SCLK_MIPI1, "sclk_mipi1", "dout_mipi1", GATE_TOP_SCLK_DISP1, 3, CLK_SET_RATE_PARENT, 0), - GATE(sclk_hdmi, "sclk_hdmi", "mout_hdmi", + GATE(CLK_SCLK_HDMI, "sclk_hdmi", "mout_hdmi", GATE_TOP_SCLK_DISP1, 9, CLK_SET_RATE_PARENT, 0), - GATE(sclk_pixel, "sclk_pixel", "dout_hdmi_pixel", + GATE(CLK_SCLK_PIXEL, "sclk_pixel", "dout_hdmi_pixel", GATE_TOP_SCLK_DISP1, 10, CLK_SET_RATE_PARENT, 0), - GATE(sclk_dp1, "sclk_dp1", "dout_dp1", + GATE(CLK_SCLK_DP1, "sclk_dp1", "dout_dp1", GATE_TOP_SCLK_DISP1, 20, CLK_SET_RATE_PARENT, 0), /* Maudio Block */ - GATE(sclk_maudio0, "sclk_maudio0", "dout_maudio0", + GATE(CLK_SCLK_MAUDIO0, "sclk_maudio0", "dout_maudio0", GATE_TOP_SCLK_MAU, 0, CLK_SET_RATE_PARENT, 0), - GATE(sclk_maupcm0, "sclk_maupcm0", "dout_maupcm0", + GATE(CLK_SCLK_MAUPCM0, "sclk_maupcm0", "dout_maupcm0", GATE_TOP_SCLK_MAU, 1, CLK_SET_RATE_PARENT, 0), /* FSYS */ - GATE(tsi, "tsi", "aclk200_fsys", GATE_BUS_FSYS0, 0, 0, 0), - GATE(pdma0, "pdma0", "aclk200_fsys", GATE_BUS_FSYS0, 1, 0, 0), - GATE(pdma1, "pdma1", "aclk200_fsys", GATE_BUS_FSYS0, 2, 0, 0), - GATE(ufs, "ufs", "aclk200_fsys2", GATE_BUS_FSYS0, 3, 0, 0), - GATE(rtic, "rtic", "aclk200_fsys", GATE_BUS_FSYS0, 5, 0, 0), - GATE(mmc0, "mmc0", "aclk200_fsys2", GATE_BUS_FSYS0, 12, 0, 0), - GATE(mmc1, "mmc1", "aclk200_fsys2", GATE_BUS_FSYS0, 13, 0, 0), - GATE(mmc2, "mmc2", "aclk200_fsys2", GATE_BUS_FSYS0, 14, 0, 0), - GATE(sromc, "sromc", "aclk200_fsys2", + GATE(CLK_TSI, "tsi", "aclk200_fsys", GATE_BUS_FSYS0, 0, 0, 0), + GATE(CLK_PDMA0, "pdma0", "aclk200_fsys", GATE_BUS_FSYS0, 1, 0, 0), + GATE(CLK_PDMA1, "pdma1", "aclk200_fsys", GATE_BUS_FSYS0, 2, 0, 0), + GATE(CLK_UFS, "ufs", "aclk200_fsys2", GATE_BUS_FSYS0, 3, 0, 0), + GATE(CLK_RTIC, "rtic", "aclk200_fsys", GATE_BUS_FSYS0, 5, 0, 0), + GATE(CLK_MMC0, "mmc0", "aclk200_fsys2", GATE_BUS_FSYS0, 12, 0, 0), + GATE(CLK_MMC1, "mmc1", "aclk200_fsys2", GATE_BUS_FSYS0, 13, 0, 0), + GATE(CLK_MMC2, "mmc2", "aclk200_fsys2", GATE_BUS_FSYS0, 14, 0, 0), + GATE(CLK_SROMC, "sromc", "aclk200_fsys2", GATE_BUS_FSYS0, 19, CLK_IGNORE_UNUSED, 0), - GATE(usbh20, "usbh20", "aclk200_fsys", GATE_BUS_FSYS0, 20, 0, 0), - GATE(usbd300, "usbd300", "aclk200_fsys", GATE_BUS_FSYS0, 21, 0, 0), - GATE(usbd301, "usbd301", "aclk200_fsys", GATE_BUS_FSYS0, 28, 0, 0), + GATE(CLK_USBH20, "usbh20", "aclk200_fsys", GATE_BUS_FSYS0, 20, 0, 0), + GATE(CLK_USBD300, "usbd300", "aclk200_fsys", GATE_BUS_FSYS0, 21, 0, 0), + GATE(CLK_USBD301, "usbd301", "aclk200_fsys", GATE_BUS_FSYS0, 28, 0, 0), /* UART */ - GATE(uart0, "uart0", "aclk66_peric", GATE_BUS_PERIC, 4, 0, 0), - GATE(uart1, "uart1", "aclk66_peric", GATE_BUS_PERIC, 5, 0, 0), - GATE_A(uart2, "uart2", "aclk66_peric", + GATE(CLK_UART0, "uart0", "aclk66_peric", GATE_BUS_PERIC, 4, 0, 0), + GATE(CLK_UART1, "uart1", "aclk66_peric", GATE_BUS_PERIC, 5, 0, 0), + GATE_A(CLK_UART2, "uart2", "aclk66_peric", GATE_BUS_PERIC, 6, CLK_IGNORE_UNUSED, 0, "uart2"), - GATE(uart3, "uart3", "aclk66_peric", GATE_BUS_PERIC, 7, 0, 0), + GATE(CLK_UART3, "uart3", "aclk66_peric", GATE_BUS_PERIC, 7, 0, 0), /* I2C */ - GATE(i2c0, "i2c0", "aclk66_peric", GATE_BUS_PERIC, 9, 0, 0), - GATE(i2c1, "i2c1", "aclk66_peric", GATE_BUS_PERIC, 10, 0, 0), - GATE(i2c2, "i2c2", "aclk66_peric", GATE_BUS_PERIC, 11, 0, 0), - GATE(i2c3, "i2c3", "aclk66_peric", GATE_BUS_PERIC, 12, 0, 0), - GATE(i2c4, "i2c4", "aclk66_peric", GATE_BUS_PERIC, 13, 0, 0), - GATE(i2c5, "i2c5", "aclk66_peric", GATE_BUS_PERIC, 14, 0, 0), - GATE(i2c6, "i2c6", "aclk66_peric", GATE_BUS_PERIC, 15, 0, 0), - GATE(i2c7, "i2c7", "aclk66_peric", GATE_BUS_PERIC, 16, 0, 0), - GATE(i2c_hdmi, "i2c_hdmi", "aclk66_peric", GATE_BUS_PERIC, 17, 0, 0), - GATE(tsadc, "tsadc", "aclk66_peric", GATE_BUS_PERIC, 18, 0, 0), + GATE(CLK_I2C0, "i2c0", "aclk66_peric", GATE_BUS_PERIC, 9, 0, 0), + GATE(CLK_I2C1, "i2c1", "aclk66_peric", GATE_BUS_PERIC, 10, 0, 0), + GATE(CLK_I2C2, "i2c2", "aclk66_peric", GATE_BUS_PERIC, 11, 0, 0), + GATE(CLK_I2C3, "i2c3", "aclk66_peric", GATE_BUS_PERIC, 12, 0, 0), + GATE(CLK_I2C4, "i2c4", "aclk66_peric", GATE_BUS_PERIC, 13, 0, 0), + GATE(CLK_I2C5, "i2c5", "aclk66_peric", GATE_BUS_PERIC, 14, 0, 0), + GATE(CLK_I2C6, "i2c6", "aclk66_peric", GATE_BUS_PERIC, 15, 0, 0), + GATE(CLK_I2C7, "i2c7", "aclk66_peric", GATE_BUS_PERIC, 16, 0, 0), + GATE(CLK_I2C_HDMI, "i2c_hdmi", "aclk66_peric", GATE_BUS_PERIC, 17, 0, + 0), + GATE(CLK_TSADC, "tsadc", "aclk66_peric", GATE_BUS_PERIC, 18, 0, 0), /* SPI */ - GATE(spi0, "spi0", "aclk66_peric", GATE_BUS_PERIC, 19, 0, 0), - GATE(spi1, "spi1", "aclk66_peric", GATE_BUS_PERIC, 20, 0, 0), - GATE(spi2, "spi2", "aclk66_peric", GATE_BUS_PERIC, 21, 0, 0), - GATE(keyif, "keyif", "aclk66_peric", GATE_BUS_PERIC, 22, 0, 0), + GATE(CLK_SPI0, "spi0", "aclk66_peric", GATE_BUS_PERIC, 19, 0, 0), + GATE(CLK_SPI1, "spi1", "aclk66_peric", GATE_BUS_PERIC, 20, 0, 0), + GATE(CLK_SPI2, "spi2", "aclk66_peric", GATE_BUS_PERIC, 21, 0, 0), + GATE(CLK_KEYIF, "keyif", "aclk66_peric", GATE_BUS_PERIC, 22, 0, 0), /* I2S */ - GATE(i2s1, "i2s1", "aclk66_peric", GATE_BUS_PERIC, 23, 0, 0), - GATE(i2s2, "i2s2", "aclk66_peric", GATE_BUS_PERIC, 24, 0, 0), + GATE(CLK_I2S1, "i2s1", "aclk66_peric", GATE_BUS_PERIC, 23, 0, 0), + GATE(CLK_I2S2, "i2s2", "aclk66_peric", GATE_BUS_PERIC, 24, 0, 0), /* PCM */ - GATE(pcm1, "pcm1", "aclk66_peric", GATE_BUS_PERIC, 25, 0, 0), - GATE(pcm2, "pcm2", "aclk66_peric", GATE_BUS_PERIC, 26, 0, 0), + GATE(CLK_PCM1, "pcm1", "aclk66_peric", GATE_BUS_PERIC, 25, 0, 0), + GATE(CLK_PCM2, "pcm2", "aclk66_peric", GATE_BUS_PERIC, 26, 0, 0), /* PWM */ - GATE(pwm, "pwm", "aclk66_peric", GATE_BUS_PERIC, 27, 0, 0), + GATE(CLK_PWM, "pwm", "aclk66_peric", GATE_BUS_PERIC, 27, 0, 0), /* SPDIF */ - GATE(spdif, "spdif", "aclk66_peric", GATE_BUS_PERIC, 29, 0, 0), + GATE(CLK_SPDIF, "spdif", "aclk66_peric", GATE_BUS_PERIC, 29, 0, 0), - GATE(i2c8, "i2c8", "aclk66_peric", GATE_BUS_PERIC1, 0, 0, 0), - GATE(i2c9, "i2c9", "aclk66_peric", GATE_BUS_PERIC1, 1, 0, 0), - GATE(i2c10, "i2c10", "aclk66_peric", GATE_BUS_PERIC1, 2, 0, 0), + GATE(CLK_I2C8, "i2c8", "aclk66_peric", GATE_BUS_PERIC1, 0, 0, 0), + GATE(CLK_I2C9, "i2c9", "aclk66_peric", GATE_BUS_PERIC1, 1, 0, 0), + GATE(CLK_I2C10, "i2c10", "aclk66_peric", GATE_BUS_PERIC1, 2, 0, 0), - GATE(chipid, "chipid", "aclk66_psgen", + GATE(CLK_CHIPID, "chipid", "aclk66_psgen", GATE_BUS_PERIS0, 12, CLK_IGNORE_UNUSED, 0), - GATE(sysreg, "sysreg", "aclk66_psgen", + GATE(CLK_SYSREG, "sysreg", "aclk66_psgen", GATE_BUS_PERIS0, 13, CLK_IGNORE_UNUSED, 0), - GATE(tzpc0, "tzpc0", "aclk66_psgen", GATE_BUS_PERIS0, 18, 0, 0), - GATE(tzpc1, "tzpc1", "aclk66_psgen", GATE_BUS_PERIS0, 19, 0, 0), - GATE(tzpc2, "tzpc2", "aclk66_psgen", GATE_BUS_PERIS0, 20, 0, 0), - GATE(tzpc3, "tzpc3", "aclk66_psgen", GATE_BUS_PERIS0, 21, 0, 0), - GATE(tzpc4, "tzpc4", "aclk66_psgen", GATE_BUS_PERIS0, 22, 0, 0), - GATE(tzpc5, "tzpc5", "aclk66_psgen", GATE_BUS_PERIS0, 23, 0, 0), - GATE(tzpc6, "tzpc6", "aclk66_psgen", GATE_BUS_PERIS0, 24, 0, 0), - GATE(tzpc7, "tzpc7", "aclk66_psgen", GATE_BUS_PERIS0, 25, 0, 0), - GATE(tzpc8, "tzpc8", "aclk66_psgen", GATE_BUS_PERIS0, 26, 0, 0), - GATE(tzpc9, "tzpc9", "aclk66_psgen", GATE_BUS_PERIS0, 27, 0, 0), - - GATE(hdmi_cec, "hdmi_cec", "aclk66_psgen", GATE_BUS_PERIS1, 0, 0, 0), - GATE(seckey, "seckey", "aclk66_psgen", GATE_BUS_PERIS1, 1, 0, 0), - GATE(wdt, "wdt", "aclk66_psgen", GATE_BUS_PERIS1, 3, 0, 0), - GATE(rtc, "rtc", "aclk66_psgen", GATE_BUS_PERIS1, 4, 0, 0), - GATE(tmu, "tmu", "aclk66_psgen", GATE_BUS_PERIS1, 5, 0, 0), - GATE(tmu_gpu, "tmu_gpu", "aclk66_psgen", GATE_BUS_PERIS1, 6, 0, 0), - - GATE(gscl0, "gscl0", "aclk300_gscl", GATE_IP_GSCL0, 0, 0, 0), - GATE(gscl1, "gscl1", "aclk300_gscl", GATE_IP_GSCL0, 1, 0, 0), - GATE(clk_3aa, "clk_3aa", "aclk300_gscl", GATE_IP_GSCL0, 4, 0, 0), - - GATE(smmu_3aa, "smmu_3aa", "aclk333_432_gscl", GATE_IP_GSCL1, 2, 0, 0), - GATE(smmu_fimcl0, "smmu_fimcl0", "aclk333_432_gscl", + GATE(CLK_TZPC0, "tzpc0", "aclk66_psgen", GATE_BUS_PERIS0, 18, 0, 0), + GATE(CLK_TZPC1, "tzpc1", "aclk66_psgen", GATE_BUS_PERIS0, 19, 0, 0), + GATE(CLK_TZPC2, "tzpc2", "aclk66_psgen", GATE_BUS_PERIS0, 20, 0, 0), + GATE(CLK_TZPC3, "tzpc3", "aclk66_psgen", GATE_BUS_PERIS0, 21, 0, 0), + GATE(CLK_TZPC4, "tzpc4", "aclk66_psgen", GATE_BUS_PERIS0, 22, 0, 0), + GATE(CLK_TZPC5, "tzpc5", "aclk66_psgen", GATE_BUS_PERIS0, 23, 0, 0), + GATE(CLK_TZPC6, "tzpc6", "aclk66_psgen", GATE_BUS_PERIS0, 24, 0, 0), + GATE(CLK_TZPC7, "tzpc7", "aclk66_psgen", GATE_BUS_PERIS0, 25, 0, 0), + GATE(CLK_TZPC8, "tzpc8", "aclk66_psgen", GATE_BUS_PERIS0, 26, 0, 0), + GATE(CLK_TZPC9, "tzpc9", "aclk66_psgen", GATE_BUS_PERIS0, 27, 0, 0), + + GATE(CLK_HDMI_CEC, "hdmi_cec", "aclk66_psgen", GATE_BUS_PERIS1, 0, 0, + 0), + GATE(CLK_SECKEY, "seckey", "aclk66_psgen", GATE_BUS_PERIS1, 1, 0, 0), + GATE(CLK_WDT, "wdt", "aclk66_psgen", GATE_BUS_PERIS1, 3, 0, 0), + GATE(CLK_RTC, "rtc", "aclk66_psgen", GATE_BUS_PERIS1, 4, 0, 0), + GATE(CLK_TMU, "tmu", "aclk66_psgen", GATE_BUS_PERIS1, 5, 0, 0), + GATE(CLK_TMU_GPU, "tmu_gpu", "aclk66_psgen", GATE_BUS_PERIS1, 6, 0, 0), + + GATE(CLK_GSCL0, "gscl0", "aclk300_gscl", GATE_IP_GSCL0, 0, 0, 0), + GATE(CLK_GSCL1, "gscl1", "aclk300_gscl", GATE_IP_GSCL0, 1, 0, 0), + GATE(CLK_CLK_3AA, "clk_3aa", "aclk300_gscl", GATE_IP_GSCL0, 4, 0, 0), + + GATE(CLK_SMMU_3AA, "smmu_3aa", "aclk333_432_gscl", GATE_IP_GSCL1, 2, 0, + 0), + GATE(CLK_SMMU_FIMCL0, "smmu_fimcl0", "aclk333_432_gscl", GATE_IP_GSCL1, 3, 0, 0), - GATE(smmu_fimcl1, "smmu_fimcl1", "aclk333_432_gscl", + GATE(CLK_SMMU_FIMCL1, "smmu_fimcl1", "aclk333_432_gscl", GATE_IP_GSCL1, 4, 0, 0), - GATE(smmu_gscl0, "smmu_gscl0", "aclk300_gscl", GATE_IP_GSCL1, 6, 0, 0), - GATE(smmu_gscl1, "smmu_gscl1", "aclk300_gscl", GATE_IP_GSCL1, 7, 0, 0), - GATE(gscl_wa, "gscl_wa", "aclk300_gscl", GATE_IP_GSCL1, 12, 0, 0), - GATE(gscl_wb, "gscl_wb", "aclk300_gscl", GATE_IP_GSCL1, 13, 0, 0), - GATE(smmu_fimcl3, "smmu_fimcl3,", "aclk333_432_gscl", + GATE(CLK_SMMU_GSCL0, "smmu_gscl0", "aclk300_gscl", GATE_IP_GSCL1, 6, 0, + 0), + GATE(CLK_SMMU_GSCL1, "smmu_gscl1", "aclk300_gscl", GATE_IP_GSCL1, 7, 0, + 0), + GATE(CLK_GSCL_WA, "gscl_wa", "aclk300_gscl", GATE_IP_GSCL1, 12, 0, 0), + GATE(CLK_GSCL_WB, "gscl_wb", "aclk300_gscl", GATE_IP_GSCL1, 13, 0, 0), + GATE(CLK_SMMU_FIMCL3, "smmu_fimcl3,", "aclk333_432_gscl", GATE_IP_GSCL1, 16, 0, 0), - GATE(fimc_lite3, "fimc_lite3", "aclk333_432_gscl", + GATE(CLK_FIMC_LITE3, "fimc_lite3", "aclk333_432_gscl", GATE_IP_GSCL1, 17, 0, 0), - GATE(fimd1, "fimd1", "aclk300_disp1", GATE_IP_DISP1, 0, 0, 0), - GATE(dsim1, "dsim1", "aclk200_disp1", GATE_IP_DISP1, 3, 0, 0), - GATE(dp1, "dp1", "aclk200_disp1", GATE_IP_DISP1, 4, 0, 0), - GATE(mixer, "mixer", "aclk166", GATE_IP_DISP1, 5, 0, 0), - GATE(hdmi, "hdmi", "aclk200_disp1", GATE_IP_DISP1, 6, 0, 0), - GATE(smmu_fimd1, "smmu_fimd1", "aclk300_disp1", GATE_IP_DISP1, 8, 0, 0), - - GATE(mfc, "mfc", "aclk333", GATE_IP_MFC, 0, 0, 0), - GATE(smmu_mfcl, "smmu_mfcl", "aclk333", GATE_IP_MFC, 1, 0, 0), - GATE(smmu_mfcr, "smmu_mfcr", "aclk333", GATE_IP_MFC, 2, 0, 0), - - GATE(g3d, "g3d", "aclkg3d", GATE_IP_G3D, 9, 0, 0), - - GATE(rotator, "rotator", "aclk266", GATE_IP_GEN, 1, 0, 0), - GATE(jpeg, "jpeg", "aclk300_jpeg", GATE_IP_GEN, 2, 0, 0), - GATE(jpeg2, "jpeg2", "aclk300_jpeg", GATE_IP_GEN, 3, 0, 0), - GATE(mdma1, "mdma1", "aclk266", GATE_IP_GEN, 4, 0, 0), - GATE(smmu_rotator, "smmu_rotator", "aclk266", GATE_IP_GEN, 6, 0, 0), - GATE(smmu_jpeg, "smmu_jpeg", "aclk300_jpeg", GATE_IP_GEN, 7, 0, 0), - GATE(smmu_mdma1, "smmu_mdma1", "aclk266", GATE_IP_GEN, 9, 0, 0), - - GATE(mscl0, "mscl0", "aclk400_mscl", GATE_IP_MSCL, 0, 0, 0), - GATE(mscl1, "mscl1", "aclk400_mscl", GATE_IP_MSCL, 1, 0, 0), - GATE(mscl2, "mscl2", "aclk400_mscl", GATE_IP_MSCL, 2, 0, 0), - GATE(smmu_mscl0, "smmu_mscl0", "aclk400_mscl", GATE_IP_MSCL, 8, 0, 0), - GATE(smmu_mscl1, "smmu_mscl1", "aclk400_mscl", GATE_IP_MSCL, 9, 0, 0), - GATE(smmu_mscl2, "smmu_mscl2", "aclk400_mscl", GATE_IP_MSCL, 10, 0, 0), - GATE(smmu_mixer, "smmu_mixer", "aclk200_disp1", GATE_IP_DISP1, 9, 0, 0), + GATE(CLK_FIMD1, "fimd1", "aclk300_disp1", GATE_IP_DISP1, 0, 0, 0), + GATE(CLK_DSIM1, "dsim1", "aclk200_disp1", GATE_IP_DISP1, 3, 0, 0), + GATE(CLK_DP1, "dp1", "aclk200_disp1", GATE_IP_DISP1, 4, 0, 0), + GATE(CLK_MIXER, "mixer", "aclk166", GATE_IP_DISP1, 5, 0, 0), + GATE(CLK_HDMI, "hdmi", "aclk200_disp1", GATE_IP_DISP1, 6, 0, 0), + GATE(CLK_SMMU_FIMD1, "smmu_fimd1", "aclk300_disp1", GATE_IP_DISP1, 8, 0, + 0), + + GATE(CLK_MFC, "mfc", "aclk333", GATE_IP_MFC, 0, 0, 0), + GATE(CLK_SMMU_MFCL, "smmu_mfcl", "aclk333", GATE_IP_MFC, 1, 0, 0), + GATE(CLK_SMMU_MFCR, "smmu_mfcr", "aclk333", GATE_IP_MFC, 2, 0, 0), + + GATE(CLK_G3D, "g3d", "aclkg3d", GATE_IP_G3D, 9, 0, 0), + + GATE(CLK_ROTATOR, "rotator", "aclk266", GATE_IP_GEN, 1, 0, 0), + GATE(CLK_JPEG, "jpeg", "aclk300_jpeg", GATE_IP_GEN, 2, 0, 0), + GATE(CLK_JPEG2, "jpeg2", "aclk300_jpeg", GATE_IP_GEN, 3, 0, 0), + GATE(CLK_MDMA1, "mdma1", "aclk266", GATE_IP_GEN, 4, 0, 0), + GATE(CLK_SMMU_ROTATOR, "smmu_rotator", "aclk266", GATE_IP_GEN, 6, 0, 0), + GATE(CLK_SMMU_JPEG, "smmu_jpeg", "aclk300_jpeg", GATE_IP_GEN, 7, 0, 0), + GATE(CLK_SMMU_MDMA1, "smmu_mdma1", "aclk266", GATE_IP_GEN, 9, 0, 0), + + GATE(CLK_MSCL0, "mscl0", "aclk400_mscl", GATE_IP_MSCL, 0, 0, 0), + GATE(CLK_MSCL1, "mscl1", "aclk400_mscl", GATE_IP_MSCL, 1, 0, 0), + GATE(CLK_MSCL2, "mscl2", "aclk400_mscl", GATE_IP_MSCL, 2, 0, 0), + GATE(CLK_SMMU_MSCL0, "smmu_mscl0", "aclk400_mscl", GATE_IP_MSCL, 8, 0, + 0), + GATE(CLK_SMMU_MSCL1, "smmu_mscl1", "aclk400_mscl", GATE_IP_MSCL, 9, 0, + 0), + GATE(CLK_SMMU_MSCL2, "smmu_mscl2", "aclk400_mscl", GATE_IP_MSCL, 10, 0, + 0), + GATE(CLK_SMMU_MIXER, "smmu_mixer", "aclk200_disp1", GATE_IP_DISP1, 9, 0, + 0), }; static struct samsung_pll_clock exynos5420_plls[nr_plls] __initdata = { - [apll] = PLL(pll_2550, fout_apll, "fout_apll", "fin_pll", APLL_LOCK, + [apll] = PLL(pll_2550, CLK_FOUT_APLL, "fout_apll", "fin_pll", APLL_LOCK, APLL_CON0, NULL), - [cpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK, - MPLL_CON0, NULL), - [dpll] = PLL(pll_2550, fout_dpll, "fout_dpll", "fin_pll", DPLL_LOCK, + [cpll] = PLL(pll_2550, CLK_FOUT_CPLL, "fout_cpll", "fin_pll", CPLL_LOCK, + CPLL_CON0, NULL), + [dpll] = PLL(pll_2550, CLK_FOUT_DPLL, "fout_dpll", "fin_pll", DPLL_LOCK, DPLL_CON0, NULL), - [epll] = PLL(pll_2650, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK, + [epll] = PLL(pll_2650, CLK_FOUT_EPLL, "fout_epll", "fin_pll", EPLL_LOCK, EPLL_CON0, NULL), - [rpll] = PLL(pll_2650, fout_rpll, "fout_rpll", "fin_pll", RPLL_LOCK, + [rpll] = PLL(pll_2650, CLK_FOUT_RPLL, "fout_rpll", "fin_pll", RPLL_LOCK, RPLL_CON0, NULL), - [ipll] = PLL(pll_2550, fout_ipll, "fout_ipll", "fin_pll", IPLL_LOCK, + [ipll] = PLL(pll_2550, CLK_FOUT_IPLL, "fout_ipll", "fin_pll", IPLL_LOCK, IPLL_CON0, NULL), - [spll] = PLL(pll_2550, fout_spll, "fout_spll", "fin_pll", SPLL_LOCK, + [spll] = PLL(pll_2550, CLK_FOUT_SPLL, "fout_spll", "fin_pll", SPLL_LOCK, SPLL_CON0, NULL), - [vpll] = PLL(pll_2550, fout_vpll, "fout_vpll", "fin_pll", VPLL_LOCK, + [vpll] = PLL(pll_2550, CLK_FOUT_VPLL, "fout_vpll", "fin_pll", VPLL_LOCK, VPLL_CON0, NULL), - [mpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK, + [mpll] = PLL(pll_2550, CLK_FOUT_MPLL, "fout_mpll", "fin_pll", MPLL_LOCK, MPLL_CON0, NULL), - [bpll] = PLL(pll_2550, fout_bpll, "fout_bpll", "fin_pll", BPLL_LOCK, + [bpll] = PLL(pll_2550, CLK_FOUT_BPLL, "fout_bpll", "fin_pll", BPLL_LOCK, BPLL_CON0, NULL), - [kpll] = PLL(pll_2550, fout_kpll, "fout_kpll", "fin_pll", KPLL_LOCK, + [kpll] = PLL(pll_2550, CLK_FOUT_KPLL, "fout_kpll", "fin_pll", KPLL_LOCK, KPLL_CON0, NULL), }; @@ -777,7 +747,7 @@ static void __init exynos5420_clk_init(struct device_node *np) panic("%s: unable to determine soc\n", __func__); } - samsung_clk_init(np, reg_base, nr_clks, + samsung_clk_init(np, reg_base, CLK_NR_CLKS, exynos5420_clk_regs, ARRAY_SIZE(exynos5420_clk_regs), NULL, 0); samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks, diff --git a/drivers/clk/samsung/clk-exynos5440.c b/drivers/clk/samsung/clk-exynos5440.c index f8658945bfd2..cbc15b56891d 100644 --- a/drivers/clk/samsung/clk-exynos5440.c +++ b/drivers/clk/samsung/clk-exynos5440.c @@ -9,6 +9,7 @@ * Common Clock Framework support for Exynos5440 SoC. */ +#include <dt-bindings/clock/exynos5440.h> #include <linux/clk.h> #include <linux/clkdev.h> #include <linux/clk-provider.h> @@ -22,79 +23,65 @@ #define CPU_CLK_STATUS 0xfc #define MISC_DOUT1 0x558 -/* - * Let each supported clock get a unique id. This id is used to lookup the clock - * for device tree based platforms. - */ -enum exynos5440_clks { - none, xtal, arm_clk, - - spi_baud = 16, pb0_250, pr0_250, pr1_250, b_250, b_125, b_200, sata, - usb, gmac0, cs250, pb0_250_o, pr0_250_o, pr1_250_o, b_250_o, b_125_o, - b_200_o, sata_o, usb_o, gmac0_o, cs250_o, - - nr_clks, -}; - /* parent clock name list */ PNAME(mout_armclk_p) = { "cplla", "cpllb" }; PNAME(mout_spi_p) = { "div125", "div200" }; /* fixed rate clocks generated outside the soc */ static struct samsung_fixed_rate_clock exynos5440_fixed_rate_ext_clks[] __initdata = { - FRATE(none, "xtal", NULL, CLK_IS_ROOT, 0), + FRATE(0, "xtal", NULL, CLK_IS_ROOT, 0), }; /* fixed rate clocks */ static struct samsung_fixed_rate_clock exynos5440_fixed_rate_clks[] __initdata = { - FRATE(none, "ppll", NULL, CLK_IS_ROOT, 1000000000), - FRATE(none, "usb_phy0", NULL, CLK_IS_ROOT, 60000000), - FRATE(none, "usb_phy1", NULL, CLK_IS_ROOT, 60000000), - FRATE(none, "usb_ohci12", NULL, CLK_IS_ROOT, 12000000), - FRATE(none, "usb_ohci48", NULL, CLK_IS_ROOT, 48000000), + FRATE(0, "ppll", NULL, CLK_IS_ROOT, 1000000000), + FRATE(0, "usb_phy0", NULL, CLK_IS_ROOT, 60000000), + FRATE(0, "usb_phy1", NULL, CLK_IS_ROOT, 60000000), + FRATE(0, "usb_ohci12", NULL, CLK_IS_ROOT, 12000000), + FRATE(0, "usb_ohci48", NULL, CLK_IS_ROOT, 48000000), }; /* fixed factor clocks */ static struct samsung_fixed_factor_clock exynos5440_fixed_factor_clks[] __initdata = { - FFACTOR(none, "div250", "ppll", 1, 4, 0), - FFACTOR(none, "div200", "ppll", 1, 5, 0), - FFACTOR(none, "div125", "div250", 1, 2, 0), + FFACTOR(0, "div250", "ppll", 1, 4, 0), + FFACTOR(0, "div200", "ppll", 1, 5, 0), + FFACTOR(0, "div125", "div250", 1, 2, 0), }; /* mux clocks */ static struct samsung_mux_clock exynos5440_mux_clks[] __initdata = { - MUX(none, "mout_spi", mout_spi_p, MISC_DOUT1, 5, 1), - MUX_A(arm_clk, "arm_clk", mout_armclk_p, + MUX(0, "mout_spi", mout_spi_p, MISC_DOUT1, 5, 1), + MUX_A(CLK_ARM_CLK, "arm_clk", mout_armclk_p, CPU_CLK_STATUS, 0, 1, "armclk"), }; /* divider clocks */ static struct samsung_div_clock exynos5440_div_clks[] __initdata = { - DIV(spi_baud, "div_spi", "mout_spi", MISC_DOUT1, 3, 2), + DIV(CLK_SPI_BAUD, "div_spi", "mout_spi", MISC_DOUT1, 3, 2), }; /* gate clocks */ static struct samsung_gate_clock exynos5440_gate_clks[] __initdata = { - GATE(pb0_250, "pb0_250", "div250", CLKEN_OV_VAL, 3, 0, 0), - GATE(pr0_250, "pr0_250", "div250", CLKEN_OV_VAL, 4, 0, 0), - GATE(pr1_250, "pr1_250", "div250", CLKEN_OV_VAL, 5, 0, 0), - GATE(b_250, "b_250", "div250", CLKEN_OV_VAL, 9, 0, 0), - GATE(b_125, "b_125", "div125", CLKEN_OV_VAL, 10, 0, 0), - GATE(b_200, "b_200", "div200", CLKEN_OV_VAL, 11, 0, 0), - GATE(sata, "sata", "div200", CLKEN_OV_VAL, 12, 0, 0), - GATE(usb, "usb", "div200", CLKEN_OV_VAL, 13, 0, 0), - GATE(gmac0, "gmac0", "div200", CLKEN_OV_VAL, 14, 0, 0), - GATE(cs250, "cs250", "div250", CLKEN_OV_VAL, 19, 0, 0), - GATE(pb0_250_o, "pb0_250_o", "pb0_250", CLKEN_OV_VAL, 3, 0, 0), - GATE(pr0_250_o, "pr0_250_o", "pr0_250", CLKEN_OV_VAL, 4, 0, 0), - GATE(pr1_250_o, "pr1_250_o", "pr1_250", CLKEN_OV_VAL, 5, 0, 0), - GATE(b_250_o, "b_250_o", "b_250", CLKEN_OV_VAL, 9, 0, 0), - GATE(b_125_o, "b_125_o", "b_125", CLKEN_OV_VAL, 10, 0, 0), - GATE(b_200_o, "b_200_o", "b_200", CLKEN_OV_VAL, 11, 0, 0), - GATE(sata_o, "sata_o", "sata", CLKEN_OV_VAL, 12, 0, 0), - GATE(usb_o, "usb_o", "usb", CLKEN_OV_VAL, 13, 0, 0), - GATE(gmac0_o, "gmac0_o", "gmac", CLKEN_OV_VAL, 14, 0, 0), - GATE(cs250_o, "cs250_o", "cs250", CLKEN_OV_VAL, 19, 0, 0), + GATE(CLK_PB0_250, "pb0_250", "div250", CLKEN_OV_VAL, 3, 0, 0), + GATE(CLK_PR0_250, "pr0_250", "div250", CLKEN_OV_VAL, 4, 0, 0), + GATE(CLK_PR1_250, "pr1_250", "div250", CLKEN_OV_VAL, 5, 0, 0), + GATE(CLK_B_250, "b_250", "div250", CLKEN_OV_VAL, 9, 0, 0), + GATE(CLK_B_125, "b_125", "div125", CLKEN_OV_VAL, 10, 0, 0), + GATE(CLK_B_200, "b_200", "div200", CLKEN_OV_VAL, 11, 0, 0), + GATE(CLK_SATA, "sata", "div200", CLKEN_OV_VAL, 12, 0, 0), + GATE(CLK_USB, "usb", "div200", CLKEN_OV_VAL, 13, 0, 0), + GATE(CLK_GMAC0, "gmac0", "div200", CLKEN_OV_VAL, 14, 0, 0), + GATE(CLK_CS250, "cs250", "div250", CLKEN_OV_VAL, 19, 0, 0), + GATE(CLK_PB0_250_O, "pb0_250_o", "pb0_250", CLKEN_OV_VAL, 3, 0, 0), + GATE(CLK_PR0_250_O, "pr0_250_o", "pr0_250", CLKEN_OV_VAL, 4, 0, 0), + GATE(CLK_PR1_250_O, "pr1_250_o", "pr1_250", CLKEN_OV_VAL, 5, 0, 0), + GATE(CLK_B_250_O, "b_250_o", "b_250", CLKEN_OV_VAL, 9, 0, 0), + GATE(CLK_B_125_O, "b_125_o", "b_125", CLKEN_OV_VAL, 10, 0, 0), + GATE(CLK_B_200_O, "b_200_o", "b_200", CLKEN_OV_VAL, 11, 0, 0), + GATE(CLK_SATA_O, "sata_o", "sata", CLKEN_OV_VAL, 12, 0, 0), + GATE(CLK_USB_O, "usb_o", "usb", CLKEN_OV_VAL, 13, 0, 0), + GATE(CLK_GMAC0_O, "gmac0_o", "gmac", CLKEN_OV_VAL, 14, 0, 0), + GATE(CLK_CS250_O, "cs250_o", "cs250", CLKEN_OV_VAL, 19, 0, 0), }; static struct of_device_id ext_clk_match[] __initdata = { @@ -114,7 +101,7 @@ static void __init exynos5440_clk_init(struct device_node *np) return; } - samsung_clk_init(np, reg_base, nr_clks, NULL, 0, NULL, 0); + samsung_clk_init(np, reg_base, CLK_NR_CLKS, NULL, 0, NULL, 0); samsung_clk_of_register_fixed_ext(exynos5440_fixed_rate_ext_clks, ARRAY_SIZE(exynos5440_fixed_rate_ext_clks), ext_clk_match); diff --git a/drivers/clk/shmobile/Makefile b/drivers/clk/shmobile/Makefile index 706adc6ae70c..9ecef140dba7 100644 --- a/drivers/clk/shmobile/Makefile +++ b/drivers/clk/shmobile/Makefile @@ -1,7 +1,7 @@ +obj-$(CONFIG_ARCH_EMEV2) += clk-emev2.o obj-$(CONFIG_ARCH_R8A7790) += clk-rcar-gen2.o obj-$(CONFIG_ARCH_R8A7791) += clk-rcar-gen2.o obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += clk-div6.o obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += clk-mstp.o - # for emply built-in.o obj-n := dummy diff --git a/drivers/clk/shmobile/clk-emev2.c b/drivers/clk/shmobile/clk-emev2.c new file mode 100644 index 000000000000..6c7c929c7765 --- /dev/null +++ b/drivers/clk/shmobile/clk-emev2.c @@ -0,0 +1,104 @@ +/* + * EMMA Mobile EV2 common clock framework support + * + * Copyright (C) 2013 Takashi Yoshii <takashi.yoshii.ze@renesas.com> + * Copyright (C) 2012 Magnus Damm + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <linux/clk-provider.h> +#include <linux/clkdev.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/of_address.h> + +/* EMEV2 SMU registers */ +#define USIAU0_RSTCTRL 0x094 +#define USIBU1_RSTCTRL 0x0ac +#define USIBU2_RSTCTRL 0x0b0 +#define USIBU3_RSTCTRL 0x0b4 +#define STI_RSTCTRL 0x124 +#define STI_CLKSEL 0x688 + +static DEFINE_SPINLOCK(lock); + +/* not pretty, but hey */ +void __iomem *smu_base; + +static void __init emev2_smu_write(unsigned long value, int offs) +{ + BUG_ON(!smu_base || (offs >= PAGE_SIZE)); + writel_relaxed(value, smu_base + offs); +} + +static const struct of_device_id smu_id[] __initconst = { + { .compatible = "renesas,emev2-smu", }, + {}, +}; + +static void __init emev2_smu_init(void) +{ + struct device_node *np; + + np = of_find_matching_node(NULL, smu_id); + BUG_ON(!np); + smu_base = of_iomap(np, 0); + BUG_ON(!smu_base); + of_node_put(np); + + /* setup STI timer to run on 32.768 kHz and deassert reset */ + emev2_smu_write(0, STI_CLKSEL); + emev2_smu_write(1, STI_RSTCTRL); + + /* deassert reset for UART0->UART3 */ + emev2_smu_write(2, USIAU0_RSTCTRL); + emev2_smu_write(2, USIBU1_RSTCTRL); + emev2_smu_write(2, USIBU2_RSTCTRL); + emev2_smu_write(2, USIBU3_RSTCTRL); +} + +static void __init emev2_smu_clkdiv_init(struct device_node *np) +{ + u32 reg[2]; + struct clk *clk; + const char *parent_name = of_clk_get_parent_name(np, 0); + if (WARN_ON(of_property_read_u32_array(np, "reg", reg, 2))) + return; + if (!smu_base) + emev2_smu_init(); + clk = clk_register_divider(NULL, np->name, parent_name, 0, + smu_base + reg[0], reg[1], 8, 0, &lock); + of_clk_add_provider(np, of_clk_src_simple_get, clk); + clk_register_clkdev(clk, np->name, NULL); + pr_debug("## %s %s %p\n", __func__, np->name, clk); +} +CLK_OF_DECLARE(emev2_smu_clkdiv, "renesas,emev2-smu-clkdiv", + emev2_smu_clkdiv_init); + +static void __init emev2_smu_gclk_init(struct device_node *np) +{ + u32 reg[2]; + struct clk *clk; + const char *parent_name = of_clk_get_parent_name(np, 0); + if (WARN_ON(of_property_read_u32_array(np, "reg", reg, 2))) + return; + if (!smu_base) + emev2_smu_init(); + clk = clk_register_gate(NULL, np->name, parent_name, 0, + smu_base + reg[0], reg[1], 0, &lock); + of_clk_add_provider(np, of_clk_src_simple_get, clk); + clk_register_clkdev(clk, np->name, NULL); + pr_debug("## %s %s %p\n", __func__, np->name, clk); +} +CLK_OF_DECLARE(emev2_smu_gclk, "renesas,emev2-smu-gclk", emev2_smu_gclk_init); diff --git a/drivers/clk/shmobile/clk-mstp.c b/drivers/clk/shmobile/clk-mstp.c index e576b60de20e..42d5912b1d25 100644 --- a/drivers/clk/shmobile/clk-mstp.c +++ b/drivers/clk/shmobile/clk-mstp.c @@ -160,7 +160,7 @@ static void __init cpg_mstp_clocks_init(struct device_node *np) unsigned int i; group = kzalloc(sizeof(*group), GFP_KERNEL); - clks = kzalloc(MSTP_MAX_CLOCKS * sizeof(*clks), GFP_KERNEL); + clks = kmalloc(MSTP_MAX_CLOCKS * sizeof(*clks), GFP_KERNEL); if (group == NULL || clks == NULL) { kfree(group); kfree(clks); @@ -181,6 +181,9 @@ static void __init cpg_mstp_clocks_init(struct device_node *np) return; } + for (i = 0; i < MSTP_MAX_CLOCKS; ++i) + clks[i] = ERR_PTR(-ENOENT); + for (i = 0; i < MSTP_MAX_CLOCKS; ++i) { const char *parent_name; const char *name; @@ -205,10 +208,11 @@ static void __init cpg_mstp_clocks_init(struct device_node *np) continue; } - clks[clkidx] = cpg_mstp_clock_register(name, parent_name, i, - group); + clks[clkidx] = cpg_mstp_clock_register(name, parent_name, + clkidx, group); if (!IS_ERR(clks[clkidx])) { - group->data.clk_num = max(group->data.clk_num, clkidx); + group->data.clk_num = max(group->data.clk_num, + clkidx + 1); /* * Register a clkdev to let board code retrieve the * clock by name and register aliases for non-DT diff --git a/drivers/clk/sirf/Makefile b/drivers/clk/sirf/Makefile new file mode 100644 index 000000000000..36b8e203f6e7 --- /dev/null +++ b/drivers/clk/sirf/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for sirf specific clk +# + +obj-$(CONFIG_ARCH_SIRF) += clk-prima2.o clk-atlas6.o diff --git a/drivers/clk/sirf/atlas6.h b/drivers/clk/sirf/atlas6.h new file mode 100644 index 000000000000..376217f3bf8f --- /dev/null +++ b/drivers/clk/sirf/atlas6.h @@ -0,0 +1,31 @@ +#define SIRFSOC_CLKC_CLK_EN0 0x0000 +#define SIRFSOC_CLKC_CLK_EN1 0x0004 +#define SIRFSOC_CLKC_REF_CFG 0x0020 +#define SIRFSOC_CLKC_CPU_CFG 0x0024 +#define SIRFSOC_CLKC_MEM_CFG 0x0028 +#define SIRFSOC_CLKC_MEMDIV_CFG 0x002C +#define SIRFSOC_CLKC_SYS_CFG 0x0030 +#define SIRFSOC_CLKC_IO_CFG 0x0034 +#define SIRFSOC_CLKC_DSP_CFG 0x0038 +#define SIRFSOC_CLKC_GFX_CFG 0x003c +#define SIRFSOC_CLKC_MM_CFG 0x0040 +#define SIRFSOC_CLKC_GFX2D_CFG 0x0040 +#define SIRFSOC_CLKC_LCD_CFG 0x0044 +#define SIRFSOC_CLKC_MMC01_CFG 0x0048 +#define SIRFSOC_CLKC_MMC23_CFG 0x004C +#define SIRFSOC_CLKC_MMC45_CFG 0x0050 +#define SIRFSOC_CLKC_NAND_CFG 0x0054 +#define SIRFSOC_CLKC_NANDDIV_CFG 0x0058 +#define SIRFSOC_CLKC_PLL1_CFG0 0x0080 +#define SIRFSOC_CLKC_PLL2_CFG0 0x0084 +#define SIRFSOC_CLKC_PLL3_CFG0 0x0088 +#define SIRFSOC_CLKC_PLL1_CFG1 0x008c +#define SIRFSOC_CLKC_PLL2_CFG1 0x0090 +#define SIRFSOC_CLKC_PLL3_CFG1 0x0094 +#define SIRFSOC_CLKC_PLL1_CFG2 0x0098 +#define SIRFSOC_CLKC_PLL2_CFG2 0x009c +#define SIRFSOC_CLKC_PLL3_CFG2 0x00A0 +#define SIRFSOC_USBPHY_PLL_CTRL 0x0008 +#define SIRFSOC_USBPHY_PLL_POWERDOWN BIT(1) +#define SIRFSOC_USBPHY_PLL_BYPASS BIT(2) +#define SIRFSOC_USBPHY_PLL_LOCK BIT(3) diff --git a/drivers/clk/sirf/clk-atlas6.c b/drivers/clk/sirf/clk-atlas6.c new file mode 100644 index 000000000000..f9f4a15a64ab --- /dev/null +++ b/drivers/clk/sirf/clk-atlas6.c @@ -0,0 +1,152 @@ +/* + * Clock tree for CSR SiRFatlasVI + * + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#include <linux/module.h> +#include <linux/bitops.h> +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/clkdev.h> +#include <linux/clk-provider.h> +#include <linux/of_address.h> +#include <linux/syscore_ops.h> + +#include "atlas6.h" +#include "clk-common.c" + +static struct clk_dmn clk_mmc01 = { + .regofs = SIRFSOC_CLKC_MMC01_CFG, + .enable_bit = 59, + .hw = { + .init = &clk_mmc01_init, + }, +}; + +static struct clk_dmn clk_mmc23 = { + .regofs = SIRFSOC_CLKC_MMC23_CFG, + .enable_bit = 60, + .hw = { + .init = &clk_mmc23_init, + }, +}; + +static struct clk_dmn clk_mmc45 = { + .regofs = SIRFSOC_CLKC_MMC45_CFG, + .enable_bit = 61, + .hw = { + .init = &clk_mmc45_init, + }, +}; + +static struct clk_init_data clk_nand_init = { + .name = "nand", + .ops = &dmn_ops, + .parent_names = dmn_clk_parents, + .num_parents = ARRAY_SIZE(dmn_clk_parents), +}; + +static struct clk_dmn clk_nand = { + .regofs = SIRFSOC_CLKC_NAND_CFG, + .enable_bit = 34, + .hw = { + .init = &clk_nand_init, + }, +}; + +enum atlas6_clk_index { + /* 0 1 2 3 4 5 6 7 8 9 */ + rtc, osc, pll1, pll2, pll3, mem, sys, security, dsp, gps, + mf, io, cpu, uart0, uart1, uart2, tsc, i2c0, i2c1, spi0, + spi1, pwmc, efuse, pulse, dmac0, dmac1, nand, audio, usp0, usp1, + usp2, vip, gfx, gfx2d, lcd, vpp, mmc01, mmc23, mmc45, usbpll, + usb0, usb1, cphif, maxclk, +}; + +static __initdata struct clk_hw *atlas6_clk_hw_array[maxclk] = { + NULL, /* dummy */ + NULL, + &clk_pll1.hw, + &clk_pll2.hw, + &clk_pll3.hw, + &clk_mem.hw, + &clk_sys.hw, + &clk_security.hw, + &clk_dsp.hw, + &clk_gps.hw, + &clk_mf.hw, + &clk_io.hw, + &clk_cpu.hw, + &clk_uart0.hw, + &clk_uart1.hw, + &clk_uart2.hw, + &clk_tsc.hw, + &clk_i2c0.hw, + &clk_i2c1.hw, + &clk_spi0.hw, + &clk_spi1.hw, + &clk_pwmc.hw, + &clk_efuse.hw, + &clk_pulse.hw, + &clk_dmac0.hw, + &clk_dmac1.hw, + &clk_nand.hw, + &clk_audio.hw, + &clk_usp0.hw, + &clk_usp1.hw, + &clk_usp2.hw, + &clk_vip.hw, + &clk_gfx.hw, + &clk_gfx2d.hw, + &clk_lcd.hw, + &clk_vpp.hw, + &clk_mmc01.hw, + &clk_mmc23.hw, + &clk_mmc45.hw, + &usb_pll_clk_hw, + &clk_usb0.hw, + &clk_usb1.hw, + &clk_cphif.hw, +}; + +static struct clk *atlas6_clks[maxclk]; + +static void __init atlas6_clk_init(struct device_node *np) +{ + struct device_node *rscnp; + int i; + + rscnp = of_find_compatible_node(NULL, NULL, "sirf,prima2-rsc"); + sirfsoc_rsc_vbase = of_iomap(rscnp, 0); + if (!sirfsoc_rsc_vbase) + panic("unable to map rsc registers\n"); + of_node_put(rscnp); + + sirfsoc_clk_vbase = of_iomap(np, 0); + if (!sirfsoc_clk_vbase) + panic("unable to map clkc registers\n"); + + /* These are always available (RTC and 26MHz OSC)*/ + atlas6_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL, + CLK_IS_ROOT, 32768); + atlas6_clks[osc] = clk_register_fixed_rate(NULL, "osc", NULL, + CLK_IS_ROOT, 26000000); + + for (i = pll1; i < maxclk; i++) { + atlas6_clks[i] = clk_register(NULL, atlas6_clk_hw_array[i]); + BUG_ON(!atlas6_clks[i]); + } + clk_register_clkdev(atlas6_clks[cpu], NULL, "cpu"); + clk_register_clkdev(atlas6_clks[io], NULL, "io"); + clk_register_clkdev(atlas6_clks[mem], NULL, "mem"); + clk_register_clkdev(atlas6_clks[mem], NULL, "osc"); + + clk_data.clks = atlas6_clks; + clk_data.clk_num = maxclk; + + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); +} +CLK_OF_DECLARE(atlas6_clk, "sirf,atlas6-clkc", atlas6_clk_init); diff --git a/drivers/clk/clk-prima2.c b/drivers/clk/sirf/clk-common.c index 6c15e3316137..7dde6a82f514 100644 --- a/drivers/clk/clk-prima2.c +++ b/drivers/clk/sirf/clk-common.c @@ -1,51 +1,18 @@ /* - * Clock tree for CSR SiRFprimaII + * common clks module for all SiRF SoCs * * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. * * Licensed under GPLv2 or later. */ -#include <linux/module.h> -#include <linux/bitops.h> -#include <linux/io.h> -#include <linux/clk.h> -#include <linux/clkdev.h> -#include <linux/clk-provider.h> -#include <linux/of_address.h> -#include <linux/syscore_ops.h> - -#define SIRFSOC_CLKC_CLK_EN0 0x0000 -#define SIRFSOC_CLKC_CLK_EN1 0x0004 -#define SIRFSOC_CLKC_REF_CFG 0x0014 -#define SIRFSOC_CLKC_CPU_CFG 0x0018 -#define SIRFSOC_CLKC_MEM_CFG 0x001c -#define SIRFSOC_CLKC_SYS_CFG 0x0020 -#define SIRFSOC_CLKC_IO_CFG 0x0024 -#define SIRFSOC_CLKC_DSP_CFG 0x0028 -#define SIRFSOC_CLKC_GFX_CFG 0x002c -#define SIRFSOC_CLKC_MM_CFG 0x0030 -#define SIRFSOC_CLKC_LCD_CFG 0x0034 -#define SIRFSOC_CLKC_MMC_CFG 0x0038 -#define SIRFSOC_CLKC_PLL1_CFG0 0x0040 -#define SIRFSOC_CLKC_PLL2_CFG0 0x0044 -#define SIRFSOC_CLKC_PLL3_CFG0 0x0048 -#define SIRFSOC_CLKC_PLL1_CFG1 0x004c -#define SIRFSOC_CLKC_PLL2_CFG1 0x0050 -#define SIRFSOC_CLKC_PLL3_CFG1 0x0054 -#define SIRFSOC_CLKC_PLL1_CFG2 0x0058 -#define SIRFSOC_CLKC_PLL2_CFG2 0x005c -#define SIRFSOC_CLKC_PLL3_CFG2 0x0060 -#define SIRFSOC_USBPHY_PLL_CTRL 0x0008 -#define SIRFSOC_USBPHY_PLL_POWERDOWN BIT(1) -#define SIRFSOC_USBPHY_PLL_BYPASS BIT(2) -#define SIRFSOC_USBPHY_PLL_LOCK BIT(3) - -static void *sirfsoc_clk_vbase, *sirfsoc_rsc_vbase; - #define KHZ 1000 #define MHZ (KHZ * KHZ) +static void *sirfsoc_clk_vbase; +static void *sirfsoc_rsc_vbase; +static struct clk_onecell_data clk_data; + /* * SiRFprimaII clock controller * - 2 oscillators: osc-26MHz, rtc-32.768KHz @@ -127,6 +94,7 @@ static long pll_clk_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate) { unsigned long fin, nf, nr, od; + u64 dividend; /* * fout = fin * nf / (nr * od); @@ -147,7 +115,10 @@ static long pll_clk_round_rate(struct clk_hw *hw, unsigned long rate, nr = BIT(6); od = 1; - return fin * nf / (nr * od); + dividend = (u64)fin * nf; + do_div(dividend, nr * od); + + return (long)dividend; } static int pll_clk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -186,6 +157,30 @@ static int pll_clk_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } +static long cpu_clk_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + /* + * SiRF SoC has not cpu clock control, + * So bypass to it's parent pll. + */ + struct clk *parent_clk = clk_get_parent(hw->clk); + struct clk *pll_parent_clk = clk_get_parent(parent_clk); + unsigned long pll_parent_rate = clk_get_rate(pll_parent_clk); + return pll_clk_round_rate(__clk_get_hw(parent_clk), rate, &pll_parent_rate); +} + +static unsigned long cpu_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + /* + * SiRF SoC has not cpu clock control, + * So return the parent pll rate. + */ + struct clk *parent_clk = clk_get_parent(hw->clk); + return __clk_get_rate(parent_clk); +} + static struct clk_ops std_pll_ops = { .recalc_rate = pll_clk_recalc_rate, .round_rate = pll_clk_round_rate, @@ -403,6 +398,42 @@ static int dmn_clk_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } +static int cpu_clk_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + int ret1, ret2; + struct clk *cur_parent; + + if (rate == clk_get_rate(clk_pll1.hw.clk)) { + ret1 = clk_set_parent(hw->clk, clk_pll1.hw.clk); + return ret1; + } + + if (rate == clk_get_rate(clk_pll2.hw.clk)) { + ret1 = clk_set_parent(hw->clk, clk_pll2.hw.clk); + return ret1; + } + + if (rate == clk_get_rate(clk_pll3.hw.clk)) { + ret1 = clk_set_parent(hw->clk, clk_pll3.hw.clk); + return ret1; + } + + cur_parent = clk_get_parent(hw->clk); + + /* switch to tmp pll before setting parent clock's rate */ + if (cur_parent == clk_pll1.hw.clk) { + ret1 = clk_set_parent(hw->clk, clk_pll2.hw.clk); + BUG_ON(ret1); + } + + ret2 = clk_set_rate(clk_pll1.hw.clk, rate); + + ret1 = clk_set_parent(hw->clk, clk_pll1.hw.clk); + + return ret2 ? ret2 : ret1; +} + static struct clk_ops msi_ops = { .set_rate = dmn_clk_set_rate, .round_rate = dmn_clk_round_rate, @@ -457,6 +488,9 @@ static struct clk_dmn clk_io = { static struct clk_ops cpu_ops = { .set_parent = dmn_clk_set_parent, .get_parent = dmn_clk_get_parent, + .set_rate = cpu_clk_set_rate, + .round_rate = cpu_clk_round_rate, + .recalc_rate = cpu_clk_recalc_rate, }; static struct clk_init_data clk_cpu_init = { @@ -532,6 +566,11 @@ static struct clk_dmn clk_mm = { }, }; +/* + * for atlas6, gfx2d holds the bit of prima2's clk_mm + */ +#define clk_gfx2d clk_mm + static struct clk_init_data clk_lcd_init = { .name = "lcd", .ops = &dmn_ops, @@ -569,14 +608,6 @@ static struct clk_init_data clk_mmc01_init = { .num_parents = ARRAY_SIZE(dmn_clk_parents), }; -static struct clk_dmn clk_mmc01 = { - .regofs = SIRFSOC_CLKC_MMC_CFG, - .enable_bit = 59, - .hw = { - .init = &clk_mmc01_init, - }, -}; - static struct clk_init_data clk_mmc23_init = { .name = "mmc23", .ops = &dmn_ops, @@ -584,14 +615,6 @@ static struct clk_init_data clk_mmc23_init = { .num_parents = ARRAY_SIZE(dmn_clk_parents), }; -static struct clk_dmn clk_mmc23 = { - .regofs = SIRFSOC_CLKC_MMC_CFG, - .enable_bit = 60, - .hw = { - .init = &clk_mmc23_init, - }, -}; - static struct clk_init_data clk_mmc45_init = { .name = "mmc45", .ops = &dmn_ops, @@ -599,14 +622,6 @@ static struct clk_init_data clk_mmc45_init = { .num_parents = ARRAY_SIZE(dmn_clk_parents), }; -static struct clk_dmn clk_mmc45 = { - .regofs = SIRFSOC_CLKC_MMC_CFG, - .enable_bit = 61, - .hw = { - .init = &clk_mmc45_init, - }, -}; - /* * peripheral controllers in io domain */ @@ -667,6 +682,20 @@ static struct clk_ops ios_ops = { .disable = std_clk_disable, }; +static struct clk_init_data clk_cphif_init = { + .name = "cphif", + .ops = &ios_ops, + .parent_names = std_clk_io_parents, + .num_parents = ARRAY_SIZE(std_clk_io_parents), +}; + +static struct clk_std clk_cphif = { + .enable_bit = 20, + .hw = { + .init = &clk_cphif_init, + }, +}; + static struct clk_init_data clk_dmac0_init = { .name = "dmac0", .ops = &ios_ops, @@ -695,20 +724,6 @@ static struct clk_std clk_dmac1 = { }, }; -static struct clk_init_data clk_nand_init = { - .name = "nand", - .ops = &ios_ops, - .parent_names = std_clk_io_parents, - .num_parents = ARRAY_SIZE(std_clk_io_parents), -}; - -static struct clk_std clk_nand = { - .enable_bit = 34, - .hw = { - .init = &clk_nand_init, - }, -}; - static struct clk_init_data clk_audio_init = { .name = "audio", .ops = &ios_ops, @@ -970,7 +985,7 @@ static const char *std_clk_sys_parents[] = { }; static struct clk_init_data clk_security_init = { - .name = "mf", + .name = "security", .ops = &ios_ops, .parent_names = std_clk_sys_parents, .num_parents = ARRAY_SIZE(std_clk_sys_parents), @@ -1014,96 +1029,3 @@ static struct clk_std clk_usb1 = { .init = &clk_usb1_init, }, }; - -enum prima2_clk_index { - /* 0 1 2 3 4 5 6 7 8 9 */ - rtc, osc, pll1, pll2, pll3, mem, sys, security, dsp, gps, - mf, io, cpu, uart0, uart1, uart2, tsc, i2c0, i2c1, spi0, - spi1, pwmc, efuse, pulse, dmac0, dmac1, nand, audio, usp0, usp1, - usp2, vip, gfx, mm, lcd, vpp, mmc01, mmc23, mmc45, usbpll, - usb0, usb1, maxclk, -}; - -static struct clk_hw *prima2_clk_hw_array[maxclk] __initdata = { - NULL, /* dummy */ - NULL, - &clk_pll1.hw, - &clk_pll2.hw, - &clk_pll3.hw, - &clk_mem.hw, - &clk_sys.hw, - &clk_security.hw, - &clk_dsp.hw, - &clk_gps.hw, - &clk_mf.hw, - &clk_io.hw, - &clk_cpu.hw, - &clk_uart0.hw, - &clk_uart1.hw, - &clk_uart2.hw, - &clk_tsc.hw, - &clk_i2c0.hw, - &clk_i2c1.hw, - &clk_spi0.hw, - &clk_spi1.hw, - &clk_pwmc.hw, - &clk_efuse.hw, - &clk_pulse.hw, - &clk_dmac0.hw, - &clk_dmac1.hw, - &clk_nand.hw, - &clk_audio.hw, - &clk_usp0.hw, - &clk_usp1.hw, - &clk_usp2.hw, - &clk_vip.hw, - &clk_gfx.hw, - &clk_mm.hw, - &clk_lcd.hw, - &clk_vpp.hw, - &clk_mmc01.hw, - &clk_mmc23.hw, - &clk_mmc45.hw, - &usb_pll_clk_hw, - &clk_usb0.hw, - &clk_usb1.hw, -}; - -static struct clk *prima2_clks[maxclk]; -static struct clk_onecell_data clk_data; - -static void __init sirfsoc_clk_init(struct device_node *np) -{ - struct device_node *rscnp; - int i; - - rscnp = of_find_compatible_node(NULL, NULL, "sirf,prima2-rsc"); - sirfsoc_rsc_vbase = of_iomap(rscnp, 0); - if (!sirfsoc_rsc_vbase) - panic("unable to map rsc registers\n"); - of_node_put(rscnp); - - sirfsoc_clk_vbase = of_iomap(np, 0); - if (!sirfsoc_clk_vbase) - panic("unable to map clkc registers\n"); - - /* These are always available (RTC and 26MHz OSC)*/ - prima2_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL, - CLK_IS_ROOT, 32768); - prima2_clks[osc]= clk_register_fixed_rate(NULL, "osc", NULL, - CLK_IS_ROOT, 26000000); - - for (i = pll1; i < maxclk; i++) { - prima2_clks[i] = clk_register(NULL, prima2_clk_hw_array[i]); - BUG_ON(IS_ERR(prima2_clks[i])); - } - clk_register_clkdev(prima2_clks[cpu], NULL, "cpu"); - clk_register_clkdev(prima2_clks[io], NULL, "io"); - clk_register_clkdev(prima2_clks[mem], NULL, "mem"); - - clk_data.clks = prima2_clks; - clk_data.clk_num = maxclk; - - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); -} -CLK_OF_DECLARE(sirfsoc_clk, "sirf,prima2-clkc", sirfsoc_clk_init); diff --git a/drivers/clk/sirf/clk-prima2.c b/drivers/clk/sirf/clk-prima2.c new file mode 100644 index 000000000000..7adc5c70c7ff --- /dev/null +++ b/drivers/clk/sirf/clk-prima2.c @@ -0,0 +1,151 @@ +/* + * Clock tree for CSR SiRFprimaII + * + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#include <linux/module.h> +#include <linux/bitops.h> +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/clkdev.h> +#include <linux/clk-provider.h> +#include <linux/of_address.h> +#include <linux/syscore_ops.h> + +#include "prima2.h" +#include "clk-common.c" + +static struct clk_dmn clk_mmc01 = { + .regofs = SIRFSOC_CLKC_MMC_CFG, + .enable_bit = 59, + .hw = { + .init = &clk_mmc01_init, + }, +}; + +static struct clk_dmn clk_mmc23 = { + .regofs = SIRFSOC_CLKC_MMC_CFG, + .enable_bit = 60, + .hw = { + .init = &clk_mmc23_init, + }, +}; + +static struct clk_dmn clk_mmc45 = { + .regofs = SIRFSOC_CLKC_MMC_CFG, + .enable_bit = 61, + .hw = { + .init = &clk_mmc45_init, + }, +}; + +static struct clk_init_data clk_nand_init = { + .name = "nand", + .ops = &ios_ops, + .parent_names = std_clk_io_parents, + .num_parents = ARRAY_SIZE(std_clk_io_parents), +}; + +static struct clk_std clk_nand = { + .enable_bit = 34, + .hw = { + .init = &clk_nand_init, + }, +}; + +enum prima2_clk_index { + /* 0 1 2 3 4 5 6 7 8 9 */ + rtc, osc, pll1, pll2, pll3, mem, sys, security, dsp, gps, + mf, io, cpu, uart0, uart1, uart2, tsc, i2c0, i2c1, spi0, + spi1, pwmc, efuse, pulse, dmac0, dmac1, nand, audio, usp0, usp1, + usp2, vip, gfx, mm, lcd, vpp, mmc01, mmc23, mmc45, usbpll, + usb0, usb1, cphif, maxclk, +}; + +static __initdata struct clk_hw *prima2_clk_hw_array[maxclk] = { + NULL, /* dummy */ + NULL, + &clk_pll1.hw, + &clk_pll2.hw, + &clk_pll3.hw, + &clk_mem.hw, + &clk_sys.hw, + &clk_security.hw, + &clk_dsp.hw, + &clk_gps.hw, + &clk_mf.hw, + &clk_io.hw, + &clk_cpu.hw, + &clk_uart0.hw, + &clk_uart1.hw, + &clk_uart2.hw, + &clk_tsc.hw, + &clk_i2c0.hw, + &clk_i2c1.hw, + &clk_spi0.hw, + &clk_spi1.hw, + &clk_pwmc.hw, + &clk_efuse.hw, + &clk_pulse.hw, + &clk_dmac0.hw, + &clk_dmac1.hw, + &clk_nand.hw, + &clk_audio.hw, + &clk_usp0.hw, + &clk_usp1.hw, + &clk_usp2.hw, + &clk_vip.hw, + &clk_gfx.hw, + &clk_mm.hw, + &clk_lcd.hw, + &clk_vpp.hw, + &clk_mmc01.hw, + &clk_mmc23.hw, + &clk_mmc45.hw, + &usb_pll_clk_hw, + &clk_usb0.hw, + &clk_usb1.hw, + &clk_cphif.hw, +}; + +static struct clk *prima2_clks[maxclk]; + +static void __init prima2_clk_init(struct device_node *np) +{ + struct device_node *rscnp; + int i; + + rscnp = of_find_compatible_node(NULL, NULL, "sirf,prima2-rsc"); + sirfsoc_rsc_vbase = of_iomap(rscnp, 0); + if (!sirfsoc_rsc_vbase) + panic("unable to map rsc registers\n"); + of_node_put(rscnp); + + sirfsoc_clk_vbase = of_iomap(np, 0); + if (!sirfsoc_clk_vbase) + panic("unable to map clkc registers\n"); + + /* These are always available (RTC and 26MHz OSC)*/ + prima2_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL, + CLK_IS_ROOT, 32768); + prima2_clks[osc] = clk_register_fixed_rate(NULL, "osc", NULL, + CLK_IS_ROOT, 26000000); + + for (i = pll1; i < maxclk; i++) { + prima2_clks[i] = clk_register(NULL, prima2_clk_hw_array[i]); + BUG_ON(!prima2_clks[i]); + } + clk_register_clkdev(prima2_clks[cpu], NULL, "cpu"); + clk_register_clkdev(prima2_clks[io], NULL, "io"); + clk_register_clkdev(prima2_clks[mem], NULL, "mem"); + clk_register_clkdev(prima2_clks[mem], NULL, "osc"); + + clk_data.clks = prima2_clks; + clk_data.clk_num = maxclk; + + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); +} +CLK_OF_DECLARE(prima2_clk, "sirf,prima2-clkc", prima2_clk_init); diff --git a/drivers/clk/sirf/prima2.h b/drivers/clk/sirf/prima2.h new file mode 100644 index 000000000000..01bc3854a058 --- /dev/null +++ b/drivers/clk/sirf/prima2.h @@ -0,0 +1,25 @@ +#define SIRFSOC_CLKC_CLK_EN0 0x0000 +#define SIRFSOC_CLKC_CLK_EN1 0x0004 +#define SIRFSOC_CLKC_REF_CFG 0x0014 +#define SIRFSOC_CLKC_CPU_CFG 0x0018 +#define SIRFSOC_CLKC_MEM_CFG 0x001c +#define SIRFSOC_CLKC_SYS_CFG 0x0020 +#define SIRFSOC_CLKC_IO_CFG 0x0024 +#define SIRFSOC_CLKC_DSP_CFG 0x0028 +#define SIRFSOC_CLKC_GFX_CFG 0x002c +#define SIRFSOC_CLKC_MM_CFG 0x0030 +#define SIRFSOC_CLKC_LCD_CFG 0x0034 +#define SIRFSOC_CLKC_MMC_CFG 0x0038 +#define SIRFSOC_CLKC_PLL1_CFG0 0x0040 +#define SIRFSOC_CLKC_PLL2_CFG0 0x0044 +#define SIRFSOC_CLKC_PLL3_CFG0 0x0048 +#define SIRFSOC_CLKC_PLL1_CFG1 0x004c +#define SIRFSOC_CLKC_PLL2_CFG1 0x0050 +#define SIRFSOC_CLKC_PLL3_CFG1 0x0054 +#define SIRFSOC_CLKC_PLL1_CFG2 0x0058 +#define SIRFSOC_CLKC_PLL2_CFG2 0x005c +#define SIRFSOC_CLKC_PLL3_CFG2 0x0060 +#define SIRFSOC_USBPHY_PLL_CTRL 0x0008 +#define SIRFSOC_USBPHY_PLL_POWERDOWN BIT(1) +#define SIRFSOC_USBPHY_PLL_BYPASS BIT(2) +#define SIRFSOC_USBPHY_PLL_LOCK BIT(3) diff --git a/drivers/clk/socfpga/clk.c b/drivers/clk/socfpga/clk.c index 81dd31a686df..5983a26a8c5f 100644 --- a/drivers/clk/socfpga/clk.c +++ b/drivers/clk/socfpga/clk.c @@ -121,9 +121,7 @@ static __init struct clk *socfpga_clk_init(struct device_node *node, int rc; u32 fixed_div; - rc = of_property_read_u32(node, "reg", ®); - if (WARN_ON(rc)) - return NULL; + of_property_read_u32(node, "reg", ®); socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL); if (WARN_ON(!socfpga_clk)) @@ -292,7 +290,7 @@ static void __init socfpga_gate_clk_init(struct device_node *node, socfpga_clk->shift = div_reg[1]; socfpga_clk->width = div_reg[2]; } else { - socfpga_clk->div_reg = 0; + socfpga_clk->div_reg = NULL; } of_property_read_string(node, "clock-output-names", &clk_name); diff --git a/drivers/clk/spear/clk-frac-synth.c b/drivers/clk/spear/clk-frac-synth.c index 958aa3ad1d60..dffd4ce6c8b5 100644 --- a/drivers/clk/spear/clk-frac-synth.c +++ b/drivers/clk/spear/clk-frac-synth.c @@ -116,7 +116,7 @@ static int clk_frac_set_rate(struct clk_hw *hw, unsigned long drate, return 0; } -struct clk_ops clk_frac_ops = { +static struct clk_ops clk_frac_ops = { .recalc_rate = clk_frac_recalc_rate, .round_rate = clk_frac_round_rate, .set_rate = clk_frac_set_rate, diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c index 88523f91d9b7..9e232644f07e 100644 --- a/drivers/clk/sunxi/clk-factors.c +++ b/drivers/clk/sunxi/clk-factors.c @@ -30,17 +30,9 @@ * parent - fixed parent. No clk_set_parent support */ -struct clk_factors { - struct clk_hw hw; - void __iomem *reg; - struct clk_factors_config *config; - void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p); - spinlock_t *lock; -}; - #define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw) -#define SETMASK(len, pos) (((-1U) >> (31-len)) << (pos)) +#define SETMASK(len, pos) (((1U << (len)) - 1) << (pos)) #define CLRMASK(len, pos) (~(SETMASK(len, pos))) #define FACTOR_GET(bit, len, reg) (((reg) & SETMASK(len, bit)) >> (bit)) @@ -88,7 +80,7 @@ static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate, static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { - u8 n, k, m, p; + u8 n = 0, k = 0, m = 0, p = 0; u32 reg; struct clk_factors *factors = to_clk_factors(hw); struct clk_factors_config *config = factors->config; @@ -120,61 +112,8 @@ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } -static const struct clk_ops clk_factors_ops = { +const struct clk_ops clk_factors_ops = { .recalc_rate = clk_factors_recalc_rate, .round_rate = clk_factors_round_rate, .set_rate = clk_factors_set_rate, }; - -/** - * clk_register_factors - register a factors clock with - * the clock framework - * @dev: device registering this clock - * @name: name of this clock - * @parent_name: name of clock's parent - * @flags: framework-specific flags - * @reg: register address to adjust factors - * @config: shift and width of factors n, k, m and p - * @get_factors: function to calculate the factors for a given frequency - * @lock: shared register lock for this clock - */ -struct clk *clk_register_factors(struct device *dev, const char *name, - const char *parent_name, - unsigned long flags, void __iomem *reg, - struct clk_factors_config *config, - void (*get_factors)(u32 *rate, u32 parent, - u8 *n, u8 *k, u8 *m, u8 *p), - spinlock_t *lock) -{ - struct clk_factors *factors; - struct clk *clk; - struct clk_init_data init; - - /* allocate the factors */ - factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL); - if (!factors) { - pr_err("%s: could not allocate factors clk\n", __func__); - return ERR_PTR(-ENOMEM); - } - - init.name = name; - init.ops = &clk_factors_ops; - init.flags = flags; - init.parent_names = (parent_name ? &parent_name : NULL); - init.num_parents = (parent_name ? 1 : 0); - - /* struct clk_factors assignments */ - factors->reg = reg; - factors->config = config; - factors->lock = lock; - factors->hw.init = &init; - factors->get_factors = get_factors; - - /* register the clock */ - clk = clk_register(dev, &factors->hw); - - if (IS_ERR(clk)) - kfree(factors); - - return clk; -} diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h index f49851cc4380..02e1a43ebac7 100644 --- a/drivers/clk/sunxi/clk-factors.h +++ b/drivers/clk/sunxi/clk-factors.h @@ -17,11 +17,13 @@ struct clk_factors_config { u8 pwidth; }; -struct clk *clk_register_factors(struct device *dev, const char *name, - const char *parent_name, - unsigned long flags, void __iomem *reg, - struct clk_factors_config *config, - void (*get_factors) (u32 *rate, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p), - spinlock_t *lock); +struct clk_factors { + struct clk_hw hw; + void __iomem *reg; + struct clk_factors_config *config; + void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p); + spinlock_t *lock; +}; + +extern const struct clk_ops clk_factors_ops; #endif diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index 9bbd03514540..659e4ea31893 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -23,6 +23,9 @@ static DEFINE_SPINLOCK(clk_lock); +/* Maximum number of parents our clocks have */ +#define SUNXI_MAX_PARENTS 5 + /** * sun4i_osc_clk_setup() - Setup function for gatable oscillator */ @@ -37,18 +40,16 @@ static void __init sun4i_osc_clk_setup(struct device_node *node) const char *clk_name = node->name; u32 rate; + if (of_property_read_u32(node, "clock-frequency", &rate)) + return; + /* allocate fixed-rate and gate clock structs */ fixed = kzalloc(sizeof(struct clk_fixed_rate), GFP_KERNEL); if (!fixed) return; gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); - if (!gate) { - kfree(fixed); - return; - } - - if (of_property_read_u32(node, "clock-frequency", &rate)) - return; + if (!gate) + goto err_free_fixed; /* set up gate and fixed rate properties */ gate->reg = of_iomap(node, 0); @@ -63,10 +64,18 @@ static void __init sun4i_osc_clk_setup(struct device_node *node) &gate->hw, &clk_gate_ops, CLK_IS_ROOT); - if (!IS_ERR(clk)) { - of_clk_add_provider(node, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); - } + if (IS_ERR(clk)) + goto err_free_gate; + + of_clk_add_provider(node, of_clk_src_simple_get, clk); + clk_register_clkdev(clk, clk_name, NULL); + + return; + +err_free_gate: + kfree(gate); +err_free_fixed: + kfree(fixed); } CLK_OF_DECLARE(sun4i_osc, "allwinner,sun4i-osc-clk", sun4i_osc_clk_setup); @@ -209,6 +218,40 @@ static void sun6i_a31_get_pll1_factors(u32 *freq, u32 parent_rate, } /** + * sun4i_get_pll5_factors() - calculates n, k factors for PLL5 + * PLL5 rate is calculated as follows + * rate = parent_rate * n * (k + 1) + * parent_rate is always 24Mhz + */ + +static void sun4i_get_pll5_factors(u32 *freq, u32 parent_rate, + u8 *n, u8 *k, u8 *m, u8 *p) +{ + u8 div; + + /* Normalize value to a parent_rate multiple (24M) */ + div = *freq / parent_rate; + *freq = parent_rate * div; + + /* we were called to round the frequency, we can now return */ + if (n == NULL) + return; + + if (div < 31) + *k = 0; + else if (div / 2 < 31) + *k = 1; + else if (div / 3 < 31) + *k = 2; + else + *k = 3; + + *n = DIV_ROUND_UP(div, (*k+1)); +} + + + +/** * sun4i_get_apb1_factors() - calculates m, p factors for APB1 * APB1 rate is calculated as follows * rate = (parent_rate >> p) / (m + 1); @@ -252,10 +295,96 @@ static void sun4i_get_apb1_factors(u32 *freq, u32 parent_rate, /** + * sun4i_get_mod0_factors() - calculates m, n factors for MOD0-style clocks + * MMC rate is calculated as follows + * rate = (parent_rate >> p) / (m + 1); + */ + +static void sun4i_get_mod0_factors(u32 *freq, u32 parent_rate, + u8 *n, u8 *k, u8 *m, u8 *p) +{ + u8 div, calcm, calcp; + + /* These clocks can only divide, so we will never be able to achieve + * frequencies higher than the parent frequency */ + if (*freq > parent_rate) + *freq = parent_rate; + + div = parent_rate / *freq; + + if (div < 16) + calcp = 0; + else if (div / 2 < 16) + calcp = 1; + else if (div / 4 < 16) + calcp = 2; + else + calcp = 3; + + calcm = DIV_ROUND_UP(div, 1 << calcp); + + *freq = (parent_rate >> calcp) / calcm; + + /* we were called to round the frequency, we can now return */ + if (n == NULL) + return; + + *m = calcm - 1; + *p = calcp; +} + + + +/** + * sun7i_a20_get_out_factors() - calculates m, p factors for CLK_OUT_A/B + * CLK_OUT rate is calculated as follows + * rate = (parent_rate >> p) / (m + 1); + */ + +static void sun7i_a20_get_out_factors(u32 *freq, u32 parent_rate, + u8 *n, u8 *k, u8 *m, u8 *p) +{ + u8 div, calcm, calcp; + + /* These clocks can only divide, so we will never be able to achieve + * frequencies higher than the parent frequency */ + if (*freq > parent_rate) + *freq = parent_rate; + + div = parent_rate / *freq; + + if (div < 32) + calcp = 0; + else if (div / 2 < 32) + calcp = 1; + else if (div / 4 < 32) + calcp = 2; + else + calcp = 3; + + calcm = DIV_ROUND_UP(div, 1 << calcp); + + *freq = (parent_rate >> calcp) / calcm; + + /* we were called to round the frequency, we can now return */ + if (n == NULL) + return; + + *m = calcm - 1; + *p = calcp; +} + + + +/** * sunxi_factors_clk_setup() - Setup function for factor clocks */ +#define SUNXI_FACTORS_MUX_MASK 0x3 + struct factors_data { + int enable; + int mux; struct clk_factors_config *table; void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p); }; @@ -280,6 +409,13 @@ static struct clk_factors_config sun6i_a31_pll1_config = { .mwidth = 2, }; +static struct clk_factors_config sun4i_pll5_config = { + .nshift = 8, + .nwidth = 5, + .kshift = 4, + .kwidth = 2, +}; + static struct clk_factors_config sun4i_apb1_config = { .mshift = 0, .mwidth = 5, @@ -287,40 +423,143 @@ static struct clk_factors_config sun4i_apb1_config = { .pwidth = 2, }; +/* user manual says "n" but it's really "p" */ +static struct clk_factors_config sun4i_mod0_config = { + .mshift = 0, + .mwidth = 4, + .pshift = 16, + .pwidth = 2, +}; + +/* user manual says "n" but it's really "p" */ +static struct clk_factors_config sun7i_a20_out_config = { + .mshift = 8, + .mwidth = 5, + .pshift = 20, + .pwidth = 2, +}; + static const struct factors_data sun4i_pll1_data __initconst = { + .enable = 31, .table = &sun4i_pll1_config, .getter = sun4i_get_pll1_factors, }; static const struct factors_data sun6i_a31_pll1_data __initconst = { + .enable = 31, .table = &sun6i_a31_pll1_config, .getter = sun6i_a31_get_pll1_factors, }; +static const struct factors_data sun4i_pll5_data __initconst = { + .enable = 31, + .table = &sun4i_pll5_config, + .getter = sun4i_get_pll5_factors, +}; + static const struct factors_data sun4i_apb1_data __initconst = { .table = &sun4i_apb1_config, .getter = sun4i_get_apb1_factors, }; -static void __init sunxi_factors_clk_setup(struct device_node *node, - struct factors_data *data) +static const struct factors_data sun4i_mod0_data __initconst = { + .enable = 31, + .mux = 24, + .table = &sun4i_mod0_config, + .getter = sun4i_get_mod0_factors, +}; + +static const struct factors_data sun7i_a20_out_data __initconst = { + .enable = 31, + .mux = 24, + .table = &sun7i_a20_out_config, + .getter = sun7i_a20_get_out_factors, +}; + +static struct clk * __init sunxi_factors_clk_setup(struct device_node *node, + const struct factors_data *data) { struct clk *clk; + struct clk_factors *factors; + struct clk_gate *gate = NULL; + struct clk_mux *mux = NULL; + struct clk_hw *gate_hw = NULL; + struct clk_hw *mux_hw = NULL; const char *clk_name = node->name; - const char *parent; + const char *parents[SUNXI_MAX_PARENTS]; void *reg; + int i = 0; reg = of_iomap(node, 0); - parent = of_clk_get_parent_name(node, 0); + /* if we have a mux, we will have >1 parents */ + while (i < SUNXI_MAX_PARENTS && + (parents[i] = of_clk_get_parent_name(node, i)) != NULL) + i++; + + /* Nodes should be providing the name via clock-output-names + * but originally our dts didn't, and so we used node->name. + * The new, better nodes look like clk@deadbeef, so we pull the + * name just in this case */ + if (!strcmp("clk", clk_name)) { + of_property_read_string_index(node, "clock-output-names", + 0, &clk_name); + } + + factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL); + if (!factors) + return NULL; + + /* Add a gate if this factor clock can be gated */ + if (data->enable) { + gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); + if (!gate) { + kfree(factors); + return NULL; + } + + /* set up gate properties */ + gate->reg = reg; + gate->bit_idx = data->enable; + gate->lock = &clk_lock; + gate_hw = &gate->hw; + } + + /* Add a mux if this factor clock can be muxed */ + if (data->mux) { + mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); + if (!mux) { + kfree(factors); + kfree(gate); + return NULL; + } + + /* set up gate properties */ + mux->reg = reg; + mux->shift = data->mux; + mux->mask = SUNXI_FACTORS_MUX_MASK; + mux->lock = &clk_lock; + mux_hw = &mux->hw; + } - clk = clk_register_factors(NULL, clk_name, parent, 0, reg, - data->table, data->getter, &clk_lock); + /* set up factors properties */ + factors->reg = reg; + factors->config = data->table; + factors->get_factors = data->getter; + factors->lock = &clk_lock; + + clk = clk_register_composite(NULL, clk_name, + parents, i, + mux_hw, &clk_mux_ops, + &factors->hw, &clk_factors_ops, + gate_hw, &clk_gate_ops, 0); if (!IS_ERR(clk)) { of_clk_add_provider(node, of_clk_src_simple_get, clk); clk_register_clkdev(clk, clk_name, NULL); } + + return clk; } @@ -352,13 +591,14 @@ static void __init sunxi_mux_clk_setup(struct device_node *node, { struct clk *clk; const char *clk_name = node->name; - const char *parents[5]; + const char *parents[SUNXI_MAX_PARENTS]; void *reg; int i = 0; reg = of_iomap(node, 0); - while (i < 5 && (parents[i] = of_clk_get_parent_name(node, i)) != NULL) + while (i < SUNXI_MAX_PARENTS && + (parents[i] = of_clk_get_parent_name(node, i)) != NULL) i++; clk = clk_register_mux(NULL, clk_name, parents, i, @@ -555,11 +795,186 @@ static void __init sunxi_gates_clk_setup(struct device_node *node, of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); } + + +/** + * sunxi_divs_clk_setup() helper data + */ + +#define SUNXI_DIVS_MAX_QTY 2 +#define SUNXI_DIVISOR_WIDTH 2 + +struct divs_data { + const struct factors_data *factors; /* data for the factor clock */ + struct { + u8 fixed; /* is it a fixed divisor? if not... */ + struct clk_div_table *table; /* is it a table based divisor? */ + u8 shift; /* otherwise it's a normal divisor with this shift */ + u8 pow; /* is it power-of-two based? */ + u8 gate; /* is it independently gateable? */ + } div[SUNXI_DIVS_MAX_QTY]; +}; + +static struct clk_div_table pll6_sata_tbl[] = { + { .val = 0, .div = 6, }, + { .val = 1, .div = 12, }, + { .val = 2, .div = 18, }, + { .val = 3, .div = 24, }, + { } /* sentinel */ +}; + +static const struct divs_data pll5_divs_data __initconst = { + .factors = &sun4i_pll5_data, + .div = { + { .shift = 0, .pow = 0, }, /* M, DDR */ + { .shift = 16, .pow = 1, }, /* P, other */ + } +}; + +static const struct divs_data pll6_divs_data __initconst = { + .factors = &sun4i_pll5_data, + .div = { + { .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */ + { .fixed = 2 }, /* P, other */ + } +}; + +/** + * sunxi_divs_clk_setup() - Setup function for leaf divisors on clocks + * + * These clocks look something like this + * ________________________ + * | ___divisor 1---|----> to consumer + * parent >--| pll___/___divisor 2---|----> to consumer + * | \_______________|____> to consumer + * |________________________| + */ + +static void __init sunxi_divs_clk_setup(struct device_node *node, + struct divs_data *data) +{ + struct clk_onecell_data *clk_data; + const char *parent = node->name; + const char *clk_name; + struct clk **clks, *pclk; + struct clk_hw *gate_hw, *rate_hw; + const struct clk_ops *rate_ops; + struct clk_gate *gate = NULL; + struct clk_fixed_factor *fix_factor; + struct clk_divider *divider; + void *reg; + int i = 0; + int flags, clkflags; + + /* Set up factor clock that we will be dividing */ + pclk = sunxi_factors_clk_setup(node, data->factors); + + reg = of_iomap(node, 0); + + clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL); + if (!clk_data) + return; + + clks = kzalloc(SUNXI_DIVS_MAX_QTY * sizeof(struct clk *), GFP_KERNEL); + if (!clks) + goto free_clkdata; + + clk_data->clks = clks; + + /* It's not a good idea to have automatic reparenting changing + * our RAM clock! */ + clkflags = !strcmp("pll5", parent) ? 0 : CLK_SET_RATE_PARENT; + + for (i = 0; i < SUNXI_DIVS_MAX_QTY; i++) { + if (of_property_read_string_index(node, "clock-output-names", + i, &clk_name) != 0) + break; + + gate_hw = NULL; + rate_hw = NULL; + rate_ops = NULL; + + /* If this leaf clock can be gated, create a gate */ + if (data->div[i].gate) { + gate = kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) + goto free_clks; + + gate->reg = reg; + gate->bit_idx = data->div[i].gate; + gate->lock = &clk_lock; + + gate_hw = &gate->hw; + } + + /* Leaves can be fixed or configurable divisors */ + if (data->div[i].fixed) { + fix_factor = kzalloc(sizeof(*fix_factor), GFP_KERNEL); + if (!fix_factor) + goto free_gate; + + fix_factor->mult = 1; + fix_factor->div = data->div[i].fixed; + + rate_hw = &fix_factor->hw; + rate_ops = &clk_fixed_factor_ops; + } else { + divider = kzalloc(sizeof(*divider), GFP_KERNEL); + if (!divider) + goto free_gate; + + flags = data->div[i].pow ? CLK_DIVIDER_POWER_OF_TWO : 0; + + divider->reg = reg; + divider->shift = data->div[i].shift; + divider->width = SUNXI_DIVISOR_WIDTH; + divider->flags = flags; + divider->lock = &clk_lock; + divider->table = data->div[i].table; + + rate_hw = ÷r->hw; + rate_ops = &clk_divider_ops; + } + + /* Wrap the (potential) gate and the divisor on a composite + * clock to unify them */ + clks[i] = clk_register_composite(NULL, clk_name, &parent, 1, + NULL, NULL, + rate_hw, rate_ops, + gate_hw, &clk_gate_ops, + clkflags); + + WARN_ON(IS_ERR(clk_data->clks[i])); + clk_register_clkdev(clks[i], clk_name, NULL); + } + + /* The last clock available on the getter is the parent */ + clks[i++] = pclk; + + /* Adjust to the real max */ + clk_data->clk_num = i; + + of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); + + return; + +free_gate: + kfree(gate); +free_clks: + kfree(clks); +free_clkdata: + kfree(clk_data); +} + + + /* Matches for factors clocks */ static const struct of_device_id clk_factors_match[] __initconst = { {.compatible = "allwinner,sun4i-pll1-clk", .data = &sun4i_pll1_data,}, {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,}, {.compatible = "allwinner,sun4i-apb1-clk", .data = &sun4i_apb1_data,}, + {.compatible = "allwinner,sun4i-mod0-clk", .data = &sun4i_mod0_data,}, + {.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,}, {} }; @@ -572,6 +987,13 @@ static const struct of_device_id clk_div_match[] __initconst = { {} }; +/* Matches for divided outputs */ +static const struct of_device_id clk_divs_match[] __initconst = { + {.compatible = "allwinner,sun4i-pll5-clk", .data = &pll5_divs_data,}, + {.compatible = "allwinner,sun4i-pll6-clk", .data = &pll6_divs_data,}, + {} +}; + /* Matches for mux clocks */ static const struct of_device_id clk_mux_match[] __initconst = { {.compatible = "allwinner,sun4i-cpu-clk", .data = &sun4i_cpu_mux_data,}, @@ -616,7 +1038,32 @@ static void __init of_sunxi_table_clock_setup(const struct of_device_id *clk_mat } } -static void __init sunxi_init_clocks(struct device_node *np) +/** + * System clock protection + * + * By enabling these critical clocks, we prevent their accidental gating + * by the framework + */ +static void __init sunxi_clock_protect(void) +{ + struct clk *clk; + + /* memory bus clock - sun5i+ */ + clk = clk_get(NULL, "mbus"); + if (!IS_ERR(clk)) { + clk_prepare_enable(clk); + clk_put(clk); + } + + /* DDR clock - sun4i+ */ + clk = clk_get(NULL, "pll5_ddr"); + if (!IS_ERR(clk)) { + clk_prepare_enable(clk); + clk_put(clk); + } +} + +static void __init sunxi_init_clocks(void) { /* Register factor clocks */ of_sunxi_table_clock_setup(clk_factors_match, sunxi_factors_clk_setup); @@ -624,11 +1071,17 @@ static void __init sunxi_init_clocks(struct device_node *np) /* Register divider clocks */ of_sunxi_table_clock_setup(clk_div_match, sunxi_divider_clk_setup); + /* Register divided output clocks */ + of_sunxi_table_clock_setup(clk_divs_match, sunxi_divs_clk_setup); + /* Register mux clocks */ of_sunxi_table_clock_setup(clk_mux_match, sunxi_mux_clk_setup); /* Register gate clocks */ of_sunxi_table_clock_setup(clk_gates_match, sunxi_gates_clk_setup); + + /* Enable core system clocks */ + sunxi_clock_protect(); } CLK_OF_DECLARE(sun4i_a10_clk_init, "allwinner,sun4i-a10", sunxi_init_clocks); CLK_OF_DECLARE(sun5i_a10s_clk_init, "allwinner,sun5i-a10s", sunxi_init_clocks); diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c index c534043c0481..356e9b804421 100644 --- a/drivers/clk/tegra/clk-periph.c +++ b/drivers/clk/tegra/clk-periph.c @@ -122,7 +122,7 @@ const struct clk_ops tegra_clk_periph_ops = { .disable = clk_periph_disable, }; -const struct clk_ops tegra_clk_periph_nodiv_ops = { +static const struct clk_ops tegra_clk_periph_nodiv_ops = { .get_parent = clk_periph_get_parent, .set_parent = clk_periph_set_parent, .is_enabled = clk_periph_is_enabled, diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 2dd432266ef6..0d20241e0770 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -1433,7 +1433,7 @@ struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, } #if defined(CONFIG_ARCH_TEGRA_114_SOC) || defined(CONFIG_ARCH_TEGRA_124_SOC) -const struct clk_ops tegra_clk_pllxc_ops = { +static const struct clk_ops tegra_clk_pllxc_ops = { .is_enabled = clk_pll_is_enabled, .enable = clk_pll_iddq_enable, .disable = clk_pll_iddq_disable, @@ -1442,7 +1442,7 @@ const struct clk_ops tegra_clk_pllxc_ops = { .set_rate = clk_pllxc_set_rate, }; -const struct clk_ops tegra_clk_pllm_ops = { +static const struct clk_ops tegra_clk_pllm_ops = { .is_enabled = clk_pll_is_enabled, .enable = clk_pll_iddq_enable, .disable = clk_pll_iddq_disable, @@ -1451,7 +1451,7 @@ const struct clk_ops tegra_clk_pllm_ops = { .set_rate = clk_pllm_set_rate, }; -const struct clk_ops tegra_clk_pllc_ops = { +static const struct clk_ops tegra_clk_pllc_ops = { .is_enabled = clk_pll_is_enabled, .enable = clk_pllc_enable, .disable = clk_pllc_disable, @@ -1460,7 +1460,7 @@ const struct clk_ops tegra_clk_pllc_ops = { .set_rate = clk_pllc_set_rate, }; -const struct clk_ops tegra_clk_pllre_ops = { +static const struct clk_ops tegra_clk_pllre_ops = { .is_enabled = clk_pll_is_enabled, .enable = clk_pll_iddq_enable, .disable = clk_pll_iddq_disable, @@ -1469,7 +1469,7 @@ const struct clk_ops tegra_clk_pllre_ops = { .set_rate = clk_pllre_set_rate, }; -const struct clk_ops tegra_clk_plle_tegra114_ops = { +static const struct clk_ops tegra_clk_plle_tegra114_ops = { .is_enabled = clk_pll_is_enabled, .enable = clk_plle_tegra114_enable, .disable = clk_plle_tegra114_disable, @@ -1731,7 +1731,7 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name, #endif #ifdef CONFIG_ARCH_TEGRA_124_SOC -const struct clk_ops tegra_clk_pllss_ops = { +static const struct clk_ops tegra_clk_pllss_ops = { .is_enabled = clk_pll_is_enabled, .enable = clk_pll_iddq_enable, .disable = clk_pll_iddq_disable, diff --git a/drivers/clk/ux500/clk-prcmu.c b/drivers/clk/ux500/clk-prcmu.c index 293a28854417..e2d63bc47436 100644 --- a/drivers/clk/ux500/clk-prcmu.c +++ b/drivers/clk/ux500/clk-prcmu.c @@ -36,7 +36,7 @@ static int clk_prcmu_prepare(struct clk_hw *hw) if (!ret) clk->is_prepared = 1; - return ret;; + return ret; } static void clk_prcmu_unprepare(struct clk_hw *hw) diff --git a/drivers/clk/versatile/clk-sp810.c b/drivers/clk/versatile/clk-sp810.c index bf9b15a585e1..c6e86a9a2aa3 100644 --- a/drivers/clk/versatile/clk-sp810.c +++ b/drivers/clk/versatile/clk-sp810.c @@ -123,7 +123,7 @@ static const struct clk_ops clk_sp810_timerclken_ops = { .set_parent = clk_sp810_timerclken_set_parent, }; -struct clk *clk_sp810_timerclken_of_get(struct of_phandle_args *clkspec, +static struct clk *clk_sp810_timerclken_of_get(struct of_phandle_args *clkspec, void *data) { struct clk_sp810 *sp810 = data; diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c index 10772aa72e4e..09dd0173ea0a 100644 --- a/drivers/clk/zynq/clkc.c +++ b/drivers/clk/zynq/clkc.c @@ -102,9 +102,10 @@ static const char *swdt_ext_clk_input_names[] __initdata = {"swdt_ext_clk"}; static void __init zynq_clk_register_fclk(enum zynq_clk fclk, const char *clk_name, void __iomem *fclk_ctrl_reg, - const char **parents) + const char **parents, int enable) { struct clk *clk; + u32 enable_reg; char *mux_name; char *div0_name; char *div1_name; @@ -147,6 +148,12 @@ static void __init zynq_clk_register_fclk(enum zynq_clk fclk, clks[fclk] = clk_register_gate(NULL, clk_name, div1_name, CLK_SET_RATE_PARENT, fclk_gate_reg, 0, CLK_GATE_SET_TO_DISABLE, fclk_gate_lock); + enable_reg = readl(fclk_gate_reg) & 1; + if (enable && !enable_reg) { + if (clk_prepare_enable(clks[fclk])) + pr_warn("%s: FCLK%u enable failed\n", __func__, + fclk - fclk0); + } kfree(mux_name); kfree(div0_name); kfree(div1_name); @@ -213,6 +220,7 @@ static void __init zynq_clk_setup(struct device_node *np) int ret; struct clk *clk; char *clk_name; + unsigned int fclk_enable = 0; const char *clk_output_name[clk_max]; const char *cpu_parents[4]; const char *periph_parents[4]; @@ -238,6 +246,8 @@ static void __init zynq_clk_setup(struct device_node *np) periph_parents[2] = clk_output_name[armpll]; periph_parents[3] = clk_output_name[ddrpll]; + of_property_read_u32(np, "fclk-enable", &fclk_enable); + /* ps_clk */ ret = of_property_read_u32(np, "ps-clk-frequency", &tmp); if (ret) { @@ -340,10 +350,12 @@ static void __init zynq_clk_setup(struct device_node *np) clk_prepare_enable(clks[dci]); /* Peripheral clocks */ - for (i = fclk0; i <= fclk3; i++) + for (i = fclk0; i <= fclk3; i++) { + int enable = !!(fclk_enable & BIT(i - fclk0)); zynq_clk_register_fclk(i, clk_output_name[i], SLCR_FPGA0_CLK_CTRL + 0x10 * (i - fclk0), - periph_parents); + periph_parents, enable); + } zynq_clk_register_periph_clk(lqspi, 0, clk_output_name[lqspi], NULL, SLCR_LQSPI_CLK_CTRL, periph_parents, 0); diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 561bce8ffb1b..fdbdeae3900d 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -290,9 +290,11 @@ static int isp_xclk_init(struct isp_device *isp) struct clk_init_data init; unsigned int i; + for (i = 0; i < ARRAY_SIZE(isp->xclks); ++i) + isp->xclks[i].clk = ERR_PTR(-EINVAL); + for (i = 0; i < ARRAY_SIZE(isp->xclks); ++i) { struct isp_xclk *xclk = &isp->xclks[i]; - struct clk *clk; xclk->isp = isp; xclk->id = i == 0 ? ISP_XCLK_A : ISP_XCLK_B; @@ -305,10 +307,15 @@ static int isp_xclk_init(struct isp_device *isp) init.num_parents = 1; xclk->hw.init = &init; - - clk = devm_clk_register(isp->dev, &xclk->hw); - if (IS_ERR(clk)) - return PTR_ERR(clk); + /* + * The first argument is NULL in order to avoid circular + * reference, as this driver takes reference on the + * sensor subdevice modules and the sensors would take + * reference on this module through clk_get(). + */ + xclk->clk = clk_register(NULL, &xclk->hw); + if (IS_ERR(xclk->clk)) + return PTR_ERR(xclk->clk); if (pdata->xclks[i].con_id == NULL && pdata->xclks[i].dev_id == NULL) @@ -320,7 +327,7 @@ static int isp_xclk_init(struct isp_device *isp) xclk->lookup->con_id = pdata->xclks[i].con_id; xclk->lookup->dev_id = pdata->xclks[i].dev_id; - xclk->lookup->clk = clk; + xclk->lookup->clk = xclk->clk; clkdev_add(xclk->lookup); } @@ -335,6 +342,9 @@ static void isp_xclk_cleanup(struct isp_device *isp) for (i = 0; i < ARRAY_SIZE(isp->xclks); ++i) { struct isp_xclk *xclk = &isp->xclks[i]; + if (!IS_ERR(xclk->clk)) + clk_unregister(xclk->clk); + if (xclk->lookup) clkdev_drop(xclk->lookup); } diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h index ce65d3ae1aa7..d1e857e41731 100644 --- a/drivers/media/platform/omap3isp/isp.h +++ b/drivers/media/platform/omap3isp/isp.h @@ -135,6 +135,7 @@ struct isp_xclk { struct isp_device *isp; struct clk_hw hw; struct clk_lookup *lookup; + struct clk *clk; enum isp_xclk_id id; spinlock_t lock; /* Protects enabled and divider */ |