Merge branch 'v4.3-rc3-clk' of https://github.com/jamesjjliao/linux into clk-next
Pull mediatek clock support and fixes from James Liao:
"This is a collection of new Mediatek clocks support and fixes.
These patches come from Joe and me, including clock support for
subsystems, GPT and some minor fixes."
* 'v4.3-rc3-clk' of https://github.com/jamesjjliao/linux:
clk: mediatek: Add USB clock support in MT8173 APMIXEDSYS
clk: mediatek: Add subsystem clocks of MT8173
dt-bindings: ARM: Mediatek: Document devicetree bindings for clock controllers
clk: mediatek: Fix rate and dependency of MT8173 clocks
clk: mediatek: Add fixed clocks support for Mediatek SoC.
clk: mediatek: Add __initdata and __init for data and functions
clk: mediatek: Remove unused code from MT8173.
clk: mediatek: Removed unused dpi_ck clock from MT8173
clk: mediatek: add 13mhz clock for MT8173
diff --git a/Documentation/devicetree/bindings/clock/at91-clock.txt b/Documentation/devicetree/bindings/clock/at91-clock.txt
index 5ba6450..181bc8a 100644
--- a/Documentation/devicetree/bindings/clock/at91-clock.txt
+++ b/Documentation/devicetree/bindings/clock/at91-clock.txt
@@ -77,6 +77,9 @@
"atmel,sama5d4-clk-h32mx":
at91 h32mx clock
+ "atmel,sama5d2-clk-generated":
+ at91 generated clock
+
Required properties for SCKC node:
- reg : defines the IO memory reserved for the SCKC.
- #size-cells : shall be 0 (reg is used to encode clk id).
@@ -461,3 +464,35 @@
compatible = "atmel,sama5d4-clk-h32mx";
clocks = <&mck>;
};
+
+Required properties for generated clocks:
+- #size-cells : shall be 0 (reg is used to encode clk id).
+- #address-cells : shall be 1 (reg is used to encode clk id).
+- clocks : shall be the generated clock source phandles.
+ e.g. clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>, <&audio_pll_pmc>;
+- name: device tree node describing a specific generated clock.
+ * #clock-cells : from common clock binding; shall be set to 0.
+ * reg: peripheral id. See Atmel's datasheets to get a full
+ list of peripheral ids.
+ * atmel,clk-output-range : minimum and maximum clock frequency
+ (two u32 fields).
+
+For example:
+ gck {
+ compatible = "atmel,sama5d2-clk-generated";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>, <&audio_pll_pmc>;
+
+ tcb0_gclk: tcb0_gclk {
+ #clock-cells = <0>;
+ reg = <35>;
+ atmel,clk-output-range = <0 83000000>;
+ };
+
+ pwm_gclk: pwm_gclk {
+ #clock-cells = <0>;
+ reg = <38>;
+ atmel,clk-output-range = <0 83000000>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt
index 5ddb684..38dcf03 100644
--- a/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt
+++ b/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt
@@ -1,7 +1,7 @@
* Renesas CPG DIV6 Clock
The CPG DIV6 clocks are variable factor clocks provided by the Clock Pulse
-Generator (CPG). They clock input is divided by a configurable factor from 1
+Generator (CPG). Their clock input is divided by a configurable factor from 1
to 64.
Required Properties:
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 89a755b..9267300 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -102,6 +102,9 @@
config HAVE_AT91_H32MX
bool
+config HAVE_AT91_GENERATED_CLK
+ bool
+
config SOC_SAM_V4_V5
bool
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 42f7120..bd9f312 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -14,6 +14,7 @@
select HAVE_CLK_PREPARE
select CLKDEV_LOOKUP
select SRCU
+ select RATIONAL
---help---
The common clock framework is a single definition of struct
clk, useful across many platforms, as well as an
diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index 89a48a7..13e67bd 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -10,3 +10,4 @@
obj-$(CONFIG_HAVE_AT91_USB_CLK) += clk-usb.o
obj-$(CONFIG_HAVE_AT91_SMD) += clk-smd.o
obj-$(CONFIG_HAVE_AT91_H32MX) += clk-h32mx.o
+obj-$(CONFIG_HAVE_AT91_GENERATED_CLK) += clk-generated.o
diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c
new file mode 100644
index 0000000..abc8094
--- /dev/null
+++ b/drivers/clk/at91/clk-generated.c
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) 2015 Atmel Corporation,
+ * Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Based on clk-programmable & clk-peripheral drivers by Boris BREZILLON.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk/at91_pmc.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+
+#include "pmc.h"
+
+#define PERIPHERAL_MAX 64
+#define PERIPHERAL_ID_MIN 2
+
+#define GENERATED_SOURCE_MAX 6
+#define GENERATED_MAX_DIV 255
+
+struct clk_generated {
+ struct clk_hw hw;
+ struct at91_pmc *pmc;
+ struct clk_range range;
+ u32 id;
+ u32 gckdiv;
+ u8 parent_id;
+};
+
+#define to_clk_generated(hw) \
+ container_of(hw, struct clk_generated, hw)
+
+static int clk_generated_enable(struct clk_hw *hw)
+{
+ struct clk_generated *gck = to_clk_generated(hw);
+ struct at91_pmc *pmc = gck->pmc;
+ u32 tmp;
+
+ pr_debug("GCLK: %s, gckdiv = %d, parent id = %d\n",
+ __func__, gck->gckdiv, gck->parent_id);
+
+ pmc_lock(pmc);
+ pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK));
+ tmp = pmc_read(pmc, AT91_PMC_PCR) &
+ ~(AT91_PMC_PCR_GCKDIV_MASK | AT91_PMC_PCR_GCKCSS_MASK);
+ pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_GCKCSS(gck->parent_id)
+ | AT91_PMC_PCR_CMD
+ | AT91_PMC_PCR_GCKDIV(gck->gckdiv)
+ | AT91_PMC_PCR_GCKEN);
+ pmc_unlock(pmc);
+ return 0;
+}
+
+static void clk_generated_disable(struct clk_hw *hw)
+{
+ struct clk_generated *gck = to_clk_generated(hw);
+ struct at91_pmc *pmc = gck->pmc;
+ u32 tmp;
+
+ pmc_lock(pmc);
+ pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK));
+ tmp = pmc_read(pmc, AT91_PMC_PCR) & ~AT91_PMC_PCR_GCKEN;
+ pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_CMD);
+ pmc_unlock(pmc);
+}
+
+static int clk_generated_is_enabled(struct clk_hw *hw)
+{
+ struct clk_generated *gck = to_clk_generated(hw);
+ struct at91_pmc *pmc = gck->pmc;
+ int ret;
+
+ pmc_lock(pmc);
+ pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK));
+ ret = !!(pmc_read(pmc, AT91_PMC_PCR) & AT91_PMC_PCR_GCKEN);
+ pmc_unlock(pmc);
+
+ return ret;
+}
+
+static unsigned long
+clk_generated_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_generated *gck = to_clk_generated(hw);
+
+ return DIV_ROUND_CLOSEST(parent_rate, gck->gckdiv + 1);
+}
+
+static int clk_generated_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ struct clk_generated *gck = to_clk_generated(hw);
+ struct clk_hw *parent = NULL;
+ long best_rate = -EINVAL;
+ unsigned long tmp_rate, min_rate;
+ int best_diff = -1;
+ int tmp_diff;
+ int i;
+
+ for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
+ u32 div;
+ unsigned long parent_rate;
+
+ parent = clk_hw_get_parent_by_index(hw, i);
+ if (!parent)
+ continue;
+
+ parent_rate = clk_hw_get_rate(parent);
+ min_rate = DIV_ROUND_CLOSEST(parent_rate, GENERATED_MAX_DIV + 1);
+ if (!parent_rate ||
+ (gck->range.max && min_rate > gck->range.max))
+ continue;
+
+ for (div = 1; div < GENERATED_MAX_DIV + 2; div++) {
+ tmp_rate = DIV_ROUND_CLOSEST(parent_rate, div);
+ tmp_diff = abs(req->rate - tmp_rate);
+
+ if (best_diff < 0 || best_diff > tmp_diff) {
+ best_rate = tmp_rate;
+ best_diff = tmp_diff;
+ req->best_parent_rate = parent_rate;
+ req->best_parent_hw = parent;
+ }
+
+ if (!best_diff || tmp_rate < req->rate)
+ break;
+ }
+
+ if (!best_diff)
+ break;
+ }
+
+ pr_debug("GCLK: %s, best_rate = %ld, parent clk: %s @ %ld\n",
+ __func__, best_rate,
+ __clk_get_name((req->best_parent_hw)->clk),
+ req->best_parent_rate);
+
+ if (best_rate < 0)
+ return best_rate;
+
+ req->rate = best_rate;
+ return 0;
+}
+
+/* No modification of hardware as we have the flag CLK_SET_PARENT_GATE set */
+static int clk_generated_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct clk_generated *gck = to_clk_generated(hw);
+
+ if (index >= clk_hw_get_num_parents(hw))
+ return -EINVAL;
+
+ gck->parent_id = index;
+ return 0;
+}
+
+static u8 clk_generated_get_parent(struct clk_hw *hw)
+{
+ struct clk_generated *gck = to_clk_generated(hw);
+
+ return gck->parent_id;
+}
+
+/* No modification of hardware as we have the flag CLK_SET_RATE_GATE set */
+static int clk_generated_set_rate(struct clk_hw *hw,
+ unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_generated *gck = to_clk_generated(hw);
+ u32 div;
+
+ if (!rate)
+ return -EINVAL;
+
+ if (gck->range.max && rate > gck->range.max)
+ return -EINVAL;
+
+ div = DIV_ROUND_CLOSEST(parent_rate, rate);
+ if (div > GENERATED_MAX_DIV + 1 || !div)
+ return -EINVAL;
+
+ gck->gckdiv = div - 1;
+ return 0;
+}
+
+static const struct clk_ops generated_ops = {
+ .enable = clk_generated_enable,
+ .disable = clk_generated_disable,
+ .is_enabled = clk_generated_is_enabled,
+ .recalc_rate = clk_generated_recalc_rate,
+ .determine_rate = clk_generated_determine_rate,
+ .get_parent = clk_generated_get_parent,
+ .set_parent = clk_generated_set_parent,
+ .set_rate = clk_generated_set_rate,
+};
+
+/**
+ * clk_generated_startup - Initialize a given clock to its default parent and
+ * divisor parameter.
+ *
+ * @gck: Generated clock to set the startup parameters for.
+ *
+ * Take parameters from the hardware and update local clock configuration
+ * accordingly.
+ */
+static void clk_generated_startup(struct clk_generated *gck)
+{
+ struct at91_pmc *pmc = gck->pmc;
+ u32 tmp;
+
+ pmc_lock(pmc);
+ pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK));
+ tmp = pmc_read(pmc, AT91_PMC_PCR);
+ pmc_unlock(pmc);
+
+ gck->parent_id = (tmp & AT91_PMC_PCR_GCKCSS_MASK)
+ >> AT91_PMC_PCR_GCKCSS_OFFSET;
+ gck->gckdiv = (tmp & AT91_PMC_PCR_GCKDIV_MASK)
+ >> AT91_PMC_PCR_GCKDIV_OFFSET;
+}
+
+static struct clk * __init
+at91_clk_register_generated(struct at91_pmc *pmc, const char *name,
+ const char **parent_names, u8 num_parents,
+ u8 id, const struct clk_range *range)
+{
+ struct clk_generated *gck;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+ gck = kzalloc(sizeof(*gck), GFP_KERNEL);
+ if (!gck)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &generated_ops;
+ init.parent_names = parent_names;
+ init.num_parents = num_parents;
+ init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
+
+ gck->id = id;
+ gck->hw.init = &init;
+ gck->pmc = pmc;
+ gck->range = *range;
+
+ clk = clk_register(NULL, &gck->hw);
+ if (IS_ERR(clk))
+ kfree(gck);
+ else
+ clk_generated_startup(gck);
+
+ return clk;
+}
+
+void __init of_sama5d2_clk_generated_setup(struct device_node *np,
+ struct at91_pmc *pmc)
+{
+ int num;
+ u32 id;
+ const char *name;
+ struct clk *clk;
+ int num_parents;
+ const char *parent_names[GENERATED_SOURCE_MAX];
+ struct device_node *gcknp;
+ struct clk_range range = CLK_RANGE(0, 0);
+
+ num_parents = of_clk_get_parent_count(np);
+ if (num_parents <= 0 || num_parents > GENERATED_SOURCE_MAX)
+ return;
+
+ of_clk_parent_fill(np, parent_names, num_parents);
+
+ num = of_get_child_count(np);
+ if (!num || num > PERIPHERAL_MAX)
+ return;
+
+ for_each_child_of_node(np, gcknp) {
+ if (of_property_read_u32(gcknp, "reg", &id))
+ continue;
+
+ if (id < PERIPHERAL_ID_MIN || id >= PERIPHERAL_MAX)
+ continue;
+
+ if (of_property_read_string(np, "clock-output-names", &name))
+ name = gcknp->name;
+
+ of_at91_get_clk_range(gcknp, "atmel,clk-output-range",
+ &range);
+
+ clk = at91_clk_register_generated(pmc, name, parent_names,
+ num_parents, id, &range);
+ if (IS_ERR(clk))
+ continue;
+
+ of_clk_add_provider(gcknp, of_clk_src_simple_get, clk);
+ }
+}
diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c
index e4d7b57..58f3b56 100644
--- a/drivers/clk/at91/clk-peripheral.c
+++ b/drivers/clk/at91/clk-peripheral.c
@@ -161,14 +161,18 @@
{
struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw);
struct at91_pmc *pmc = periph->pmc;
+ u32 tmp;
if (periph->id < PERIPHERAL_ID_MIN)
return 0;
- pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID) |
- AT91_PMC_PCR_CMD |
- AT91_PMC_PCR_DIV(periph->div) |
- AT91_PMC_PCR_EN);
+ pmc_lock(pmc);
+ pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK));
+ tmp = pmc_read(pmc, AT91_PMC_PCR) & ~AT91_PMC_PCR_DIV_MASK;
+ pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_DIV(periph->div)
+ | AT91_PMC_PCR_CMD
+ | AT91_PMC_PCR_EN);
+ pmc_unlock(pmc);
return 0;
}
@@ -176,12 +180,16 @@
{
struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw);
struct at91_pmc *pmc = periph->pmc;
+ u32 tmp;
if (periph->id < PERIPHERAL_ID_MIN)
return;
- pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID) |
- AT91_PMC_PCR_CMD);
+ pmc_lock(pmc);
+ pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK));
+ tmp = pmc_read(pmc, AT91_PMC_PCR) & ~AT91_PMC_PCR_EN;
+ pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_CMD);
+ pmc_unlock(pmc);
}
static int clk_sam9x5_peripheral_is_enabled(struct clk_hw *hw)
@@ -194,7 +202,7 @@
return 1;
pmc_lock(pmc);
- pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID));
+ pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK));
ret = !!(pmc_read(pmc, AT91_PMC_PCR) & AT91_PMC_PCR_EN);
pmc_unlock(pmc);
@@ -213,7 +221,7 @@
return parent_rate;
pmc_lock(pmc);
- pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID));
+ pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK));
tmp = pmc_read(pmc, AT91_PMC_PCR);
pmc_unlock(pmc);
diff --git a/drivers/clk/at91/clk-system.c b/drivers/clk/at91/clk-system.c
index 58008b3..3f53143 100644
--- a/drivers/clk/at91/clk-system.c
+++ b/drivers/clk/at91/clk-system.c
@@ -138,7 +138,8 @@
clk = clk_register(NULL, &sys->hw);
if (IS_ERR(clk)) {
- free_irq(sys->irq, sys);
+ if (irq)
+ free_irq(sys->irq, sys);
kfree(sys);
}
diff --git a/drivers/clk/at91/clk-utmi.c b/drivers/clk/at91/clk-utmi.c
index 30dd697..ca561e9 100644
--- a/drivers/clk/at91/clk-utmi.c
+++ b/drivers/clk/at91/clk-utmi.c
@@ -47,7 +47,7 @@
{
struct clk_utmi *utmi = to_clk_utmi(hw);
struct at91_pmc *pmc = utmi->pmc;
- u32 tmp = at91_pmc_read(AT91_CKGR_UCKR) | AT91_PMC_UPLLEN |
+ u32 tmp = pmc_read(pmc, AT91_CKGR_UCKR) | AT91_PMC_UPLLEN |
AT91_PMC_UPLLCOUNT | AT91_PMC_BIASEN;
pmc_write(pmc, AT91_CKGR_UCKR, tmp);
@@ -73,7 +73,7 @@
{
struct clk_utmi *utmi = to_clk_utmi(hw);
struct at91_pmc *pmc = utmi->pmc;
- u32 tmp = at91_pmc_read(AT91_CKGR_UCKR) & ~AT91_PMC_UPLLEN;
+ u32 tmp = pmc_read(pmc, AT91_CKGR_UCKR) & ~AT91_PMC_UPLLEN;
pmc_write(pmc, AT91_CKGR_UCKR, tmp);
}
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index d1844f1..8476b57 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -206,6 +206,14 @@
AT91_PMC_MOSCRCS | AT91_PMC_CFDEV,
};
+static const struct at91_pmc_caps sama5d2_caps = {
+ .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY |
+ AT91_PMC_LOCKU | AT91_PMC_PCK0RDY |
+ AT91_PMC_PCK1RDY | AT91_PMC_PCK2RDY |
+ AT91_PMC_MOSCSELS | AT91_PMC_MOSCRCS |
+ AT91_PMC_CFDEV | AT91_PMC_GCKRDY,
+};
+
static const struct at91_pmc_caps sama5d3_caps = {
.available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY |
AT91_PMC_LOCKU | AT91_PMC_PCK0RDY |
@@ -369,6 +377,12 @@
.data = of_sama5d4_clk_h32mx_setup,
},
#endif
+#if defined(CONFIG_HAVE_AT91_GENERATED_CLK)
+ {
+ .compatible = "atmel,sama5d2-clk-generated",
+ .data = of_sama5d2_clk_generated_setup,
+ },
+#endif
{ /*sentinel*/ }
};
@@ -436,6 +450,13 @@
CLK_OF_DECLARE(at91sam9x5_clk_pmc, "atmel,at91sam9x5-pmc",
of_at91sam9x5_pmc_setup);
+static void __init of_sama5d2_pmc_setup(struct device_node *np)
+{
+ of_at91_pmc_setup(np, &sama5d2_caps);
+}
+CLK_OF_DECLARE(sama5d2_clk_pmc, "atmel,sama5d2-pmc",
+ of_sama5d2_pmc_setup);
+
static void __init of_sama5d3_pmc_setup(struct device_node *np)
{
of_at91_pmc_setup(np, &sama5d3_caps);
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index 8b87771..f657392 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -118,4 +118,7 @@
void of_sama5d4_clk_h32mx_setup(struct device_node *np,
struct at91_pmc *pmc);
+void of_sama5d2_clk_generated_setup(struct device_node *np,
+ struct at91_pmc *pmc);
+
#endif /* __PMC_H_ */
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index f24d0a1..3ace102 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -24,7 +24,7 @@
* Traits of this clock:
* prepare - clk_prepare only ensures that parents are prepared
* enable - clk_enable only ensures that parents are enabled
- * rate - rate is adjustable. clk->rate = DIV_ROUND_UP(parent->rate / divisor)
+ * rate - rate is adjustable. clk->rate = ceiling(parent->rate / divisor)
* parent - fixed parent. No clk_set_parent support
*/
@@ -132,7 +132,7 @@
return parent_rate;
}
- return DIV_ROUND_UP(parent_rate, div);
+ return DIV_ROUND_UP_ULL((u64)parent_rate, div);
}
EXPORT_SYMBOL_GPL(divider_recalc_rate);
@@ -210,7 +210,7 @@
unsigned long parent_rate, unsigned long rate,
unsigned long flags)
{
- int div = DIV_ROUND_UP(parent_rate, rate);
+ int div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
if (flags & CLK_DIVIDER_POWER_OF_TWO)
div = __roundup_pow_of_two(div);
@@ -227,7 +227,7 @@
int up, down;
unsigned long up_rate, down_rate;
- up = DIV_ROUND_UP(parent_rate, rate);
+ up = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
down = parent_rate / rate;
if (flags & CLK_DIVIDER_POWER_OF_TWO) {
@@ -238,8 +238,8 @@
down = _round_down_table(table, down);
}
- up_rate = DIV_ROUND_UP(parent_rate, up);
- down_rate = DIV_ROUND_UP(parent_rate, down);
+ up_rate = DIV_ROUND_UP_ULL((u64)parent_rate, up);
+ down_rate = DIV_ROUND_UP_ULL((u64)parent_rate, down);
return (rate - up_rate) <= (down_rate - rate) ? up : down;
}
@@ -318,7 +318,7 @@
}
parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw),
rate * i);
- now = DIV_ROUND_UP(parent_rate, i);
+ now = DIV_ROUND_UP_ULL((u64)parent_rate, i);
if (_is_best_div(rate, now, best, flags)) {
bestdiv = i;
best = now;
@@ -342,7 +342,7 @@
div = clk_divider_bestdiv(hw, rate, prate, table, width, flags);
- return DIV_ROUND_UP(*prate, div);
+ return DIV_ROUND_UP_ULL((u64)*prate, div);
}
EXPORT_SYMBOL_GPL(divider_round_rate);
@@ -358,7 +358,7 @@
bestdiv &= div_mask(divider->width);
bestdiv = _get_div(divider->table, bestdiv, divider->flags,
divider->width);
- return DIV_ROUND_UP(*prate, bestdiv);
+ return DIV_ROUND_UP_ULL((u64)*prate, bestdiv);
}
return divider_round_rate(hw, rate, prate, divider->table,
@@ -371,7 +371,7 @@
{
unsigned int div, value;
- div = DIV_ROUND_UP(parent_rate, rate);
+ div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
if (!_is_valid_div(table, div, flags))
return -EINVAL;
diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c
index e85f856..5c4955e 100644
--- a/drivers/clk/clk-fractional-divider.c
+++ b/drivers/clk/clk-fractional-divider.c
@@ -7,13 +7,14 @@
*
* Adjustable fractional divider clock implementation.
* Output rate = (m / n) * parent_rate.
+ * Uses rational best approximation algorithm.
*/
#include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/slab.h>
-#include <linux/gcd.h>
+#include <linux/rational.h>
#define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw)
@@ -22,7 +23,8 @@
{
struct clk_fractional_divider *fd = to_clk_fd(hw);
unsigned long flags = 0;
- u32 val, m, n;
+ unsigned long m, n;
+ u32 val;
u64 ret;
if (fd->lock)
@@ -50,23 +52,33 @@
}
static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *prate)
+ unsigned long *parent_rate)
{
struct clk_fractional_divider *fd = to_clk_fd(hw);
- unsigned maxn = (fd->nmask >> fd->nshift) + 1;
- unsigned div;
+ unsigned long scale;
+ unsigned long m, n;
+ u64 ret;
- if (!rate || rate >= *prate)
- return *prate;
+ if (!rate || rate >= *parent_rate)
+ return *parent_rate;
- div = gcd(*prate, rate);
+ /*
+ * Get rate closer to *parent_rate to guarantee there is no overflow
+ * for m and n. In the result it will be the nearest rate left shifted
+ * by (scale - fd->nwidth) bits.
+ */
+ scale = fls_long(*parent_rate / rate - 1);
+ if (scale > fd->nwidth)
+ rate <<= scale - fd->nwidth;
- while ((*prate / div) > maxn) {
- div <<= 1;
- rate <<= 1;
- }
+ rational_best_approximation(rate, *parent_rate,
+ GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
+ &m, &n);
- return rate;
+ ret = (u64)*parent_rate * m;
+ do_div(ret, n);
+
+ return ret;
}
static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -74,13 +86,12 @@
{
struct clk_fractional_divider *fd = to_clk_fd(hw);
unsigned long flags = 0;
- unsigned long div;
- unsigned n, m;
+ unsigned long m, n;
u32 val;
- div = gcd(parent_rate, rate);
- m = rate / div;
- n = parent_rate / div;
+ rational_best_approximation(rate, parent_rate,
+ GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
+ &m, &n);
if (fd->lock)
spin_lock_irqsave(fd->lock, flags);
@@ -128,9 +139,11 @@
fd->reg = reg;
fd->mshift = mshift;
- fd->mmask = (BIT(mwidth) - 1) << mshift;
+ fd->mwidth = mwidth;
+ fd->mmask = GENMASK(mwidth - 1, 0) << mshift;
fd->nshift = nshift;
- fd->nmask = (BIT(nwidth) - 1) << nshift;
+ fd->nwidth = nwidth;
+ fd->nmask = GENMASK(nwidth - 1, 0) << nshift;
fd->flags = clk_divider_flags;
fd->lock = lock;
fd->hw.init = &init;
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 0ebcf44..b005f66 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1685,7 +1685,7 @@
"%s: multi-parent clocks must implement .get_parent\n",
__func__);
goto out;
- };
+ }
/*
* Do our best to cache parent clocks in core->parents. This prevents
diff --git a/drivers/clk/hisilicon/clk-hi6220-stub.c b/drivers/clk/hisilicon/clk-hi6220-stub.c
index 2c4add1..8afb40e 100644
--- a/drivers/clk/hisilicon/clk-hi6220-stub.c
+++ b/drivers/clk/hisilicon/clk-hi6220-stub.c
@@ -230,7 +230,7 @@
if (IS_ERR(stub_clk->mbox)) {
dev_err(dev, "failed get mailbox channel\n");
return PTR_ERR(stub_clk->mbox);
- };
+ }
init.name = "acpu0";
init.ops = &hi6220_stub_clk_ops;
diff --git a/drivers/clk/imx/clk-pllv2.c b/drivers/clk/imx/clk-pllv2.c
index 20889d5..b18f875 100644
--- a/drivers/clk/imx/clk-pllv2.c
+++ b/drivers/clk/imx/clk-pllv2.c
@@ -77,7 +77,7 @@
static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate,
u32 dp_ctl, u32 dp_op, u32 dp_mfd, u32 dp_mfn)
{
- long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
+ long mfi, mfn, mfd, pdf, ref_clk;
unsigned long dbl;
s64 temp;
@@ -87,19 +87,15 @@
mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
mfi = (mfi <= 5) ? 5 : mfi;
mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
- mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
- /* Sign extend to 32-bits */
- if (mfn >= 0x04000000) {
- mfn |= 0xFC000000;
- mfn_abs = -mfn;
- }
+ mfn = dp_mfn & MXC_PLL_DP_MFN_MASK;
+ mfn = sign_extend32(mfn, 26);
ref_clk = 2 * parent_rate;
if (dbl != 0)
ref_clk *= 2;
ref_clk /= (pdf + 1);
- temp = (u64) ref_clk * mfn_abs;
+ temp = (u64) ref_clk * abs(mfn);
do_div(temp, mfd + 1);
if (mfn < 0)
temp = -temp;
diff --git a/drivers/clk/mvebu/common.c b/drivers/clk/mvebu/common.c
index 4a22429..28aac67 100644
--- a/drivers/clk/mvebu/common.c
+++ b/drivers/clk/mvebu/common.c
@@ -165,7 +165,7 @@
clk_data.clks[2+n] = clk_register_fixed_factor(NULL, rclk_name,
cpuclk_name, 0, mult, div);
WARN_ON(IS_ERR(clk_data.clks[2+n]));
- };
+ }
/* Register optional refclk */
if (desc->get_refclk_freq) {
diff --git a/drivers/clk/mxs/clk-frac.c b/drivers/clk/mxs/clk-frac.c
index 73f0240..f8dd10f 100644
--- a/drivers/clk/mxs/clk-frac.c
+++ b/drivers/clk/mxs/clk-frac.c
@@ -41,11 +41,13 @@
{
struct clk_frac *frac = to_clk_frac(hw);
u32 div;
+ u64 tmp_rate;
div = readl_relaxed(frac->reg) >> frac->shift;
div &= (1 << frac->width) - 1;
- return (parent_rate >> frac->width) * div;
+ tmp_rate = (u64)parent_rate * div;
+ return tmp_rate >> frac->width;
}
static long clk_frac_round_rate(struct clk_hw *hw, unsigned long rate,
@@ -54,7 +56,7 @@
struct clk_frac *frac = to_clk_frac(hw);
unsigned long parent_rate = *prate;
u32 div;
- u64 tmp;
+ u64 tmp, tmp_rate, result;
if (rate > parent_rate)
return -EINVAL;
@@ -67,7 +69,11 @@
if (!div)
return -EINVAL;
- return (parent_rate >> frac->width) * div;
+ tmp_rate = (u64)parent_rate * div;
+ result = tmp_rate >> frac->width;
+ if ((result << frac->width) < tmp_rate)
+ result += 1;
+ return result;
}
static int clk_frac_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 59d1666..47b988f 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -7,6 +7,7 @@
config APQ_GCC_8084
tristate "APQ8084 Global Clock Controller"
+ select QCOM_GDSC
depends on COMMON_CLK_QCOM
help
Support for the global clock controller on apq8084 devices.
@@ -16,6 +17,7 @@
config APQ_MMCC_8084
tristate "APQ8084 Multimedia Clock Controller"
select APQ_GCC_8084
+ select QCOM_GDSC
depends on COMMON_CLK_QCOM
help
Support for the multimedia clock controller on apq8084 devices.
@@ -39,6 +41,10 @@
Say Y if you want to use audio devices such as i2s, pcm,
S/PDIF, etc.
+config QCOM_GDSC
+ bool
+ select PM_GENERIC_DOMAINS if PM
+
config MSM_GCC_8660
tristate "MSM8660 Global Clock Controller"
depends on COMMON_CLK_QCOM
@@ -49,6 +55,7 @@
config MSM_GCC_8916
tristate "MSM8916 Global Clock Controller"
+ select QCOM_GDSC
depends on COMMON_CLK_QCOM
help
Support for the global clock controller on msm8916 devices.
@@ -83,6 +90,7 @@
config MSM_GCC_8974
tristate "MSM8974 Global Clock Controller"
+ select QCOM_GDSC
depends on COMMON_CLK_QCOM
help
Support for the global clock controller on msm8974 devices.
@@ -92,6 +100,7 @@
config MSM_MMCC_8974
tristate "MSM8974 Multimedia Clock Controller"
select MSM_GCC_8974
+ select QCOM_GDSC
depends on COMMON_CLK_QCOM
help
Support for the multimedia clock controller on msm8974 devices.
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 50b337a..fe62523 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -9,6 +9,7 @@
clk-qcom-y += clk-regmap-divider.o
clk-qcom-y += clk-regmap-mux.o
clk-qcom-y += reset.o
+clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o
obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o
obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o
diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h
index 56028bb..5012e5b 100644
--- a/drivers/clk/qcom/clk-rcg.h
+++ b/drivers/clk/qcom/clk-rcg.h
@@ -153,8 +153,8 @@
* @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
+ * @current_freq: last cached frequency when using branches with shared RCGs
* @clkr: regmap clock handle
- * @lock: register lock
*
*/
struct clk_rcg2 {
@@ -163,14 +163,17 @@
u8 hid_width;
const struct parent_map *parent_map;
const struct freq_tbl *freq_tbl;
+ unsigned long current_freq;
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;
+extern const struct clk_ops clk_rcg2_shared_ops;
extern const struct clk_ops clk_edp_pixel_ops;
extern const struct clk_ops clk_byte_ops;
+extern const struct clk_ops clk_byte2_ops;
extern const struct clk_ops clk_pixel_ops;
#endif
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index 9aec176..b544bb302 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -300,6 +300,85 @@
};
EXPORT_SYMBOL_GPL(clk_rcg2_ops);
+static int clk_rcg2_shared_force_enable(struct clk_hw *hw, unsigned long rate)
+{
+ struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+ const char *name = clk_hw_get_name(hw);
+ int ret, count;
+
+ /* force enable RCG */
+ ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CMD_REG,
+ CMD_ROOT_EN, CMD_ROOT_EN);
+ if (ret)
+ return ret;
+
+ /* wait for RCG to turn ON */
+ for (count = 500; count > 0; count--) {
+ ret = clk_rcg2_is_enabled(hw);
+ if (ret)
+ break;
+ udelay(1);
+ }
+ if (!count)
+ pr_err("%s: RCG did not turn on\n", name);
+
+ /* set clock rate */
+ ret = __clk_rcg2_set_rate(hw, rate);
+ if (ret)
+ return ret;
+
+ /* clear force enable RCG */
+ return regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CMD_REG,
+ CMD_ROOT_EN, 0);
+}
+
+static int clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+
+ /* cache the rate */
+ rcg->current_freq = rate;
+
+ if (!__clk_is_enabled(hw->clk))
+ return 0;
+
+ return clk_rcg2_shared_force_enable(hw, rcg->current_freq);
+}
+
+static unsigned long
+clk_rcg2_shared_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+ struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+
+ return rcg->current_freq = clk_rcg2_recalc_rate(hw, parent_rate);
+}
+
+static int clk_rcg2_shared_enable(struct clk_hw *hw)
+{
+ struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+
+ return clk_rcg2_shared_force_enable(hw, rcg->current_freq);
+}
+
+static void clk_rcg2_shared_disable(struct clk_hw *hw)
+{
+ struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+
+ /* switch to XO, which is the lowest entry in the freq table */
+ clk_rcg2_shared_set_rate(hw, rcg->freq_tbl[0].freq, 0);
+}
+
+const struct clk_ops clk_rcg2_shared_ops = {
+ .enable = clk_rcg2_shared_enable,
+ .disable = clk_rcg2_shared_disable,
+ .get_parent = clk_rcg2_get_parent,
+ .recalc_rate = clk_rcg2_shared_recalc_rate,
+ .determine_rate = clk_rcg2_determine_rate,
+ .set_rate = clk_rcg2_shared_set_rate,
+};
+EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops);
+
struct frac_entry {
int num;
int den;
@@ -485,6 +564,76 @@
};
EXPORT_SYMBOL_GPL(clk_byte_ops);
+static int clk_byte2_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+ unsigned long parent_rate, div;
+ u32 mask = BIT(rcg->hid_width) - 1;
+ struct clk_hw *p;
+ unsigned long rate = req->rate;
+
+ if (rate == 0)
+ return -EINVAL;
+
+ p = req->best_parent_hw;
+ req->best_parent_rate = parent_rate = clk_hw_round_rate(p, rate);
+
+ div = DIV_ROUND_UP((2 * parent_rate), rate) - 1;
+ div = min_t(u32, div, mask);
+
+ req->rate = calc_rate(parent_rate, 0, 0, 0, div);
+
+ return 0;
+}
+
+static int clk_byte2_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+ struct freq_tbl f = { 0 };
+ unsigned long div;
+ int i, num_parents = clk_hw_get_num_parents(hw);
+ u32 mask = BIT(rcg->hid_width) - 1;
+ u32 cfg;
+
+ div = DIV_ROUND_UP((2 * parent_rate), rate) - 1;
+ div = min_t(u32, div, mask);
+
+ f.pre_div = div;
+
+ regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg);
+ cfg &= CFG_SRC_SEL_MASK;
+ cfg >>= CFG_SRC_SEL_SHIFT;
+
+ for (i = 0; i < num_parents; i++) {
+ if (cfg == rcg->parent_map[i].cfg) {
+ f.src = rcg->parent_map[i].src;
+ return clk_rcg2_configure(rcg, &f);
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int clk_byte2_set_rate_and_parent(struct clk_hw *hw,
+ unsigned long rate, unsigned long parent_rate, u8 index)
+{
+ /* Read the hardware to determine parent during set_rate */
+ return clk_byte2_set_rate(hw, rate, parent_rate);
+}
+
+const struct clk_ops clk_byte2_ops = {
+ .is_enabled = clk_rcg2_is_enabled,
+ .get_parent = clk_rcg2_get_parent,
+ .set_parent = clk_rcg2_set_parent,
+ .recalc_rate = clk_rcg2_recalc_rate,
+ .set_rate = clk_byte2_set_rate,
+ .set_rate_and_parent = clk_byte2_set_rate_and_parent,
+ .determine_rate = clk_byte2_determine_rate,
+};
+EXPORT_SYMBOL_GPL(clk_byte2_ops);
+
static const struct frac_entry frac_table_pixel[] = {
{ 3, 8 },
{ 2, 9 },
@@ -496,14 +645,9 @@
static int clk_pixel_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
- struct clk_rcg2 *rcg = to_clk_rcg2(hw);
unsigned long request, src_rate;
int delta = 100000;
- const struct freq_tbl *f = rcg->freq_tbl;
const struct frac_entry *frac = frac_table_pixel;
- int index = qcom_find_src_index(hw, rcg->parent_map, f->src);
-
- req->best_parent_hw = clk_hw_get_parent_by_index(hw, index);
for (; frac->num; frac++) {
request = (req->rate * frac->den) / frac->num;
@@ -525,12 +669,23 @@
unsigned long parent_rate)
{
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
- struct freq_tbl f = *rcg->freq_tbl;
+ struct freq_tbl f = { 0 };
const struct frac_entry *frac = frac_table_pixel;
unsigned long request;
int delta = 100000;
u32 mask = BIT(rcg->hid_width) - 1;
- u32 hid_div;
+ u32 hid_div, cfg;
+ int i, num_parents = clk_hw_get_num_parents(hw);
+
+ regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg);
+ cfg &= CFG_SRC_SEL_MASK;
+ cfg >>= CFG_SRC_SEL_SHIFT;
+
+ for (i = 0; i < num_parents; i++)
+ if (cfg == rcg->parent_map[i].cfg) {
+ f.src = rcg->parent_map[i].src;
+ break;
+ }
for (; frac->num; frac++) {
request = (rate * frac->den) / frac->num;
@@ -555,7 +710,6 @@
static int clk_pixel_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate, u8 index)
{
- /* Parent index is set statically in frequency table */
return clk_pixel_set_rate(hw, rate, parent_rate);
}
diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c
index 2dedcee..1506928 100644
--- a/drivers/clk/qcom/common.c
+++ b/drivers/clk/qcom/common.c
@@ -22,6 +22,7 @@
#include "clk-rcg.h"
#include "clk-regmap.h"
#include "reset.h"
+#include "gdsc.h"
struct qcom_cc {
struct qcom_reset_controller reset;
@@ -121,8 +122,20 @@
ret = reset_controller_register(&reset->rcdev);
if (ret)
- of_clk_del_provider(dev->of_node);
+ goto err_reset;
+ if (desc->gdscs && desc->num_gdscs) {
+ ret = gdsc_register(dev, desc->gdscs, desc->num_gdscs,
+ &reset->rcdev, regmap);
+ if (ret)
+ goto err_pd;
+ }
+
+ return 0;
+err_pd:
+ reset_controller_unregister(&reset->rcdev);
+err_reset:
+ of_clk_del_provider(dev->of_node);
return ret;
}
EXPORT_SYMBOL_GPL(qcom_cc_really_probe);
@@ -141,6 +154,7 @@
void qcom_cc_remove(struct platform_device *pdev)
{
+ gdsc_unregister(&pdev->dev);
of_clk_del_provider(pdev->dev.of_node);
reset_controller_unregister(platform_get_drvdata(pdev));
}
diff --git a/drivers/clk/qcom/common.h b/drivers/clk/qcom/common.h
index 7a0e737..2892b71f 100644
--- a/drivers/clk/qcom/common.h
+++ b/drivers/clk/qcom/common.h
@@ -28,6 +28,8 @@
size_t num_clks;
const struct qcom_reset_map *resets;
size_t num_resets;
+ struct gdsc **gdscs;
+ size_t num_gdscs;
};
extern const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f,
diff --git a/drivers/clk/qcom/gcc-apq8084.c b/drivers/clk/qcom/gcc-apq8084.c
index 3563019..b88c401 100644
--- a/drivers/clk/qcom/gcc-apq8084.c
+++ b/drivers/clk/qcom/gcc-apq8084.c
@@ -31,6 +31,7 @@
#include "clk-rcg.h"
#include "clk-branch.h"
#include "reset.h"
+#include "gdsc.h"
enum {
P_XO,
@@ -3254,6 +3255,38 @@
},
};
+static struct gdsc usb_hs_hsic_gdsc = {
+ .gdscr = 0x404,
+ .pd = {
+ .name = "usb_hs_hsic",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc pcie0_gdsc = {
+ .gdscr = 0x1ac4,
+ .pd = {
+ .name = "pcie0",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc pcie1_gdsc = {
+ .gdscr = 0x1b44,
+ .pd = {
+ .name = "pcie1",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc usb30_gdsc = {
+ .gdscr = 0x1e84,
+ .pd = {
+ .name = "usb30",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
static struct clk_regmap *gcc_apq8084_clocks[] = {
[GPLL0] = &gpll0.clkr,
[GPLL0_VOTE] = &gpll0_vote,
@@ -3447,6 +3480,13 @@
[GCC_USB_HSIC_SYSTEM_CLK] = &gcc_usb_hsic_system_clk.clkr,
};
+static struct gdsc *gcc_apq8084_gdscs[] = {
+ [USB_HS_HSIC_GDSC] = &usb_hs_hsic_gdsc,
+ [PCIE0_GDSC] = &pcie0_gdsc,
+ [PCIE1_GDSC] = &pcie1_gdsc,
+ [USB30_GDSC] = &usb30_gdsc,
+};
+
static const struct qcom_reset_map gcc_apq8084_resets[] = {
[GCC_SYSTEM_NOC_BCR] = { 0x0100 },
[GCC_CONFIG_NOC_BCR] = { 0x0140 },
@@ -3555,6 +3595,8 @@
.num_clks = ARRAY_SIZE(gcc_apq8084_clocks),
.resets = gcc_apq8084_resets,
.num_resets = ARRAY_SIZE(gcc_apq8084_resets),
+ .gdscs = gcc_apq8084_gdscs,
+ .num_gdscs = ARRAY_SIZE(gcc_apq8084_gdscs),
};
static const struct of_device_id gcc_apq8084_match_table[] = {
diff --git a/drivers/clk/qcom/gcc-msm8916.c b/drivers/clk/qcom/gcc-msm8916.c
index 22a4e1e..f7aff81 100644
--- a/drivers/clk/qcom/gcc-msm8916.c
+++ b/drivers/clk/qcom/gcc-msm8916.c
@@ -31,6 +31,7 @@
#include "clk-rcg.h"
#include "clk-branch.h"
#include "reset.h"
+#include "gdsc.h"
enum {
P_XO,
@@ -44,6 +45,9 @@
P_SLEEP_CLK,
P_DSI0_PHYPLL_BYTE,
P_DSI0_PHYPLL_DSI,
+ P_EXT_PRI_I2S,
+ P_EXT_SEC_I2S,
+ P_EXT_MCLK,
};
static const struct parent_map gcc_xo_gpll0_map[] = {
@@ -190,6 +194,76 @@
"gpll2_vote",
};
+static const struct parent_map gcc_xo_gpll0_gpll1_sleep_map[] = {
+ { P_XO, 0 },
+ { P_GPLL0, 1 },
+ { P_GPLL1, 2 },
+ { P_SLEEP_CLK, 6 }
+};
+
+static const char * const gcc_xo_gpll0_gpll1_sleep[] = {
+ "xo",
+ "gpll0_vote",
+ "gpll1_vote",
+ "sleep_clk",
+};
+
+static const struct parent_map gcc_xo_gpll1_epi2s_emclk_sleep_map[] = {
+ { P_XO, 0 },
+ { P_GPLL1, 1 },
+ { P_EXT_PRI_I2S, 2 },
+ { P_EXT_MCLK, 3 },
+ { P_SLEEP_CLK, 6 }
+};
+
+static const char * const gcc_xo_gpll1_epi2s_emclk_sleep[] = {
+ "xo",
+ "gpll1_vote",
+ "ext_pri_i2s",
+ "ext_mclk",
+ "sleep_clk",
+};
+
+static const struct parent_map gcc_xo_gpll1_esi2s_emclk_sleep_map[] = {
+ { P_XO, 0 },
+ { P_GPLL1, 1 },
+ { P_EXT_SEC_I2S, 2 },
+ { P_EXT_MCLK, 3 },
+ { P_SLEEP_CLK, 6 }
+};
+
+static const char * const gcc_xo_gpll1_esi2s_emclk_sleep[] = {
+ "xo",
+ "gpll1_vote",
+ "ext_sec_i2s",
+ "ext_mclk",
+ "sleep_clk",
+};
+
+static const struct parent_map gcc_xo_sleep_map[] = {
+ { P_XO, 0 },
+ { P_SLEEP_CLK, 6 }
+};
+
+static const char * const gcc_xo_sleep[] = {
+ "xo",
+ "sleep_clk",
+};
+
+static const struct parent_map gcc_xo_gpll1_emclk_sleep_map[] = {
+ { P_XO, 0 },
+ { P_GPLL1, 1 },
+ { P_EXT_MCLK, 2 },
+ { P_SLEEP_CLK, 6 }
+};
+
+static const char * const gcc_xo_gpll1_emclk_sleep[] = {
+ "xo",
+ "gpll1_vote",
+ "ext_mclk",
+ "sleep_clk",
+};
+
#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
static struct clk_pll gpll0 = {
@@ -906,21 +980,15 @@
},
};
-static struct freq_tbl ftbl_gcc_mdss_byte0_clk[] = {
- { .src = P_DSI0_PHYPLL_BYTE },
- { }
-};
-
static struct clk_rcg2 byte0_clk_src = {
.cmd_rcgr = 0x4d044,
.hid_width = 5,
.parent_map = gcc_xo_gpll0a_dsibyte_map,
- .freq_tbl = ftbl_gcc_mdss_byte0_clk,
.clkr.hw.init = &(struct clk_init_data){
.name = "byte0_clk_src",
.parent_names = gcc_xo_gpll0a_dsibyte,
.num_parents = 3,
- .ops = &clk_byte_ops,
+ .ops = &clk_byte2_ops,
.flags = CLK_SET_RATE_PARENT,
},
};
@@ -968,17 +1036,11 @@
},
};
-static struct freq_tbl ftbl_gcc_mdss_pclk[] = {
- { .src = P_DSI0_PHYPLL_DSI },
- { }
-};
-
static struct clk_rcg2 pclk0_clk_src = {
.cmd_rcgr = 0x4d000,
.mnd_width = 8,
.hid_width = 5,
.parent_map = gcc_xo_gpll0a_dsiphy_map,
- .freq_tbl = ftbl_gcc_mdss_pclk,
.clkr.hw.init = &(struct clk_init_data){
.name = "pclk0_clk_src",
.parent_names = gcc_xo_gpll0a_dsiphy,
@@ -1094,6 +1156,30 @@
},
};
+static const struct freq_tbl ftbl_gcc_bimc_gpu_clk[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(100000000, P_GPLL0, 8, 0, 0),
+ F(200000000, P_GPLL0, 4, 0, 0),
+ F(266500000, P_BIMC, 4, 0, 0),
+ F(400000000, P_GPLL0, 2, 0, 0),
+ F(533000000, P_BIMC, 2, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 bimc_gpu_clk_src = {
+ .cmd_rcgr = 0x31028,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_bimc_map,
+ .freq_tbl = ftbl_gcc_bimc_gpu_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "bimc_gpu_clk_src",
+ .parent_names = gcc_xo_gpll0_bimc,
+ .num_parents = 3,
+ .flags = CLK_GET_RATE_NOCACHE,
+ .ops = &clk_rcg2_shared_ops,
+ },
+};
+
static const struct freq_tbl ftbl_gcc_usb_hs_system_clk[] = {
F(80000000, P_GPLL0, 10, 0, 0),
{ }
@@ -1112,6 +1198,305 @@
},
};
+static const struct freq_tbl ftbl_gcc_ultaudio_ahb_clk[] = {
+ F(3200000, P_XO, 6, 0, 0),
+ F(6400000, P_XO, 3, 0, 0),
+ F(9600000, P_XO, 2, 0, 0),
+ F(19200000, P_XO, 1, 0, 0),
+ F(40000000, P_GPLL0, 10, 1, 2),
+ F(66670000, P_GPLL0, 12, 0, 0),
+ F(80000000, P_GPLL0, 10, 0, 0),
+ F(100000000, P_GPLL0, 8, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 ultaudio_ahbfabric_clk_src = {
+ .cmd_rcgr = 0x1c010,
+ .hid_width = 5,
+ .mnd_width = 8,
+ .parent_map = gcc_xo_gpll0_gpll1_sleep_map,
+ .freq_tbl = ftbl_gcc_ultaudio_ahb_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "ultaudio_ahbfabric_clk_src",
+ .parent_names = gcc_xo_gpll0_gpll1_sleep,
+ .num_parents = 4,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_branch gcc_ultaudio_ahbfabric_ixfabric_clk = {
+ .halt_reg = 0x1c028,
+ .clkr = {
+ .enable_reg = 0x1c028,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ultaudio_ahbfabric_ixfabric_clk",
+ .parent_names = (const char *[]){
+ "ultaudio_ahbfabric_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_ultaudio_ahbfabric_ixfabric_lpm_clk = {
+ .halt_reg = 0x1c024,
+ .clkr = {
+ .enable_reg = 0x1c024,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ultaudio_ahbfabric_ixfabric_lpm_clk",
+ .parent_names = (const char *[]){
+ "ultaudio_ahbfabric_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_ultaudio_lpaif_i2s_clk[] = {
+ F(256000, P_XO, 5, 1, 15),
+ F(512000, P_XO, 5, 2, 15),
+ F(705600, P_GPLL1, 16, 1, 80),
+ F(768000, P_XO, 5, 1, 5),
+ F(800000, P_XO, 5, 5, 24),
+ F(1024000, P_GPLL1, 14, 1, 63),
+ F(1152000, P_XO, 1, 3, 50),
+ F(1411200, P_GPLL1, 16, 1, 40),
+ F(1536000, P_XO, 1, 2, 25),
+ F(1600000, P_XO, 12, 0, 0),
+ F(2048000, P_GPLL1, 9, 1, 49),
+ F(2400000, P_XO, 8, 0, 0),
+ F(2822400, P_GPLL1, 16, 1, 20),
+ F(3072000, P_GPLL1, 14, 1, 21),
+ F(4096000, P_GPLL1, 9, 2, 49),
+ F(4800000, P_XO, 4, 0, 0),
+ F(5644800, P_GPLL1, 16, 1, 10),
+ F(6144000, P_GPLL1, 7, 1, 21),
+ F(8192000, P_GPLL1, 9, 4, 49),
+ F(9600000, P_XO, 2, 0, 0),
+ F(11289600, P_GPLL1, 16, 1, 5),
+ F(12288000, P_GPLL1, 7, 2, 21),
+ { }
+};
+
+static struct clk_rcg2 ultaudio_lpaif_pri_i2s_clk_src = {
+ .cmd_rcgr = 0x1c054,
+ .hid_width = 5,
+ .mnd_width = 8,
+ .parent_map = gcc_xo_gpll1_epi2s_emclk_sleep_map,
+ .freq_tbl = ftbl_gcc_ultaudio_lpaif_i2s_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "ultaudio_lpaif_pri_i2s_clk_src",
+ .parent_names = gcc_xo_gpll1_epi2s_emclk_sleep,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_branch gcc_ultaudio_lpaif_pri_i2s_clk = {
+ .halt_reg = 0x1c068,
+ .clkr = {
+ .enable_reg = 0x1c068,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ultaudio_lpaif_pri_i2s_clk",
+ .parent_names = (const char *[]){
+ "ultaudio_lpaif_pri_i2s_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_rcg2 ultaudio_lpaif_sec_i2s_clk_src = {
+ .cmd_rcgr = 0x1c06c,
+ .hid_width = 5,
+ .mnd_width = 8,
+ .parent_map = gcc_xo_gpll1_esi2s_emclk_sleep_map,
+ .freq_tbl = ftbl_gcc_ultaudio_lpaif_i2s_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "ultaudio_lpaif_sec_i2s_clk_src",
+ .parent_names = gcc_xo_gpll1_esi2s_emclk_sleep,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_branch gcc_ultaudio_lpaif_sec_i2s_clk = {
+ .halt_reg = 0x1c080,
+ .clkr = {
+ .enable_reg = 0x1c080,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ultaudio_lpaif_sec_i2s_clk",
+ .parent_names = (const char *[]){
+ "ultaudio_lpaif_sec_i2s_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_rcg2 ultaudio_lpaif_aux_i2s_clk_src = {
+ .cmd_rcgr = 0x1c084,
+ .hid_width = 5,
+ .mnd_width = 8,
+ .parent_map = gcc_xo_gpll1_emclk_sleep_map,
+ .freq_tbl = ftbl_gcc_ultaudio_lpaif_i2s_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "ultaudio_lpaif_aux_i2s_clk_src",
+ .parent_names = gcc_xo_gpll1_esi2s_emclk_sleep,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_branch gcc_ultaudio_lpaif_aux_i2s_clk = {
+ .halt_reg = 0x1c098,
+ .clkr = {
+ .enable_reg = 0x1c098,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ultaudio_lpaif_aux_i2s_clk",
+ .parent_names = (const char *[]){
+ "ultaudio_lpaif_aux_i2s_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_ultaudio_xo_clk[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 ultaudio_xo_clk_src = {
+ .cmd_rcgr = 0x1c034,
+ .hid_width = 5,
+ .parent_map = gcc_xo_sleep_map,
+ .freq_tbl = ftbl_gcc_ultaudio_xo_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "ultaudio_xo_clk_src",
+ .parent_names = gcc_xo_sleep,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_branch gcc_ultaudio_avsync_xo_clk = {
+ .halt_reg = 0x1c04c,
+ .clkr = {
+ .enable_reg = 0x1c04c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ultaudio_avsync_xo_clk",
+ .parent_names = (const char *[]){
+ "ultaudio_xo_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_ultaudio_stc_xo_clk = {
+ .halt_reg = 0x1c050,
+ .clkr = {
+ .enable_reg = 0x1c050,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ultaudio_stc_xo_clk",
+ .parent_names = (const char *[]){
+ "ultaudio_xo_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static const struct freq_tbl ftbl_codec_clk[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(11289600, P_EXT_MCLK, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 codec_digcodec_clk_src = {
+ .cmd_rcgr = 0x1c09c,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll1_emclk_sleep_map,
+ .freq_tbl = ftbl_codec_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "codec_digcodec_clk_src",
+ .parent_names = gcc_xo_gpll1_emclk_sleep,
+ .num_parents = 4,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_branch gcc_codec_digcodec_clk = {
+ .halt_reg = 0x1c0b0,
+ .clkr = {
+ .enable_reg = 0x1c0b0,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ultaudio_codec_digcodec_clk",
+ .parent_names = (const char *[]){
+ "codec_digcodec_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_ultaudio_pcnoc_mport_clk = {
+ .halt_reg = 0x1c000,
+ .clkr = {
+ .enable_reg = 0x1c000,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ultaudio_pcnoc_mport_clk",
+ .parent_names = (const char *[]){
+ "pcnoc_bfdcd_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_ultaudio_pcnoc_sway_clk = {
+ .halt_reg = 0x1c004,
+ .clkr = {
+ .enable_reg = 0x1c004,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ultaudio_pcnoc_sway_clk",
+ .parent_names = (const char *[]){
+ "pcnoc_bfdcd_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
static const struct freq_tbl ftbl_gcc_venus0_vcodec0_clk[] = {
F(100000000, P_GPLL0, 8, 0, 0),
F(160000000, P_GPLL0, 5, 0, 0),
@@ -2358,6 +2743,51 @@
},
};
+static struct clk_rcg2 bimc_ddr_clk_src = {
+ .cmd_rcgr = 0x32004,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_bimc_map,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "bimc_ddr_clk_src",
+ .parent_names = gcc_xo_gpll0_bimc,
+ .num_parents = 3,
+ .ops = &clk_rcg2_ops,
+ .flags = CLK_GET_RATE_NOCACHE,
+ },
+};
+
+static struct clk_branch gcc_apss_tcu_clk = {
+ .halt_reg = 0x12018,
+ .clkr = {
+ .enable_reg = 0x4500c,
+ .enable_mask = BIT(1),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_apss_tcu_clk",
+ .parent_names = (const char *[]){
+ "bimc_ddr_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_gfx_tcu_clk = {
+ .halt_reg = 0x12020,
+ .clkr = {
+ .enable_reg = 0x4500c,
+ .enable_mask = BIT(2),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_gfx_tcu_clk",
+ .parent_names = (const char *[]){
+ "bimc_ddr_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
static struct clk_branch gcc_gtcu_ahb_clk = {
.halt_reg = 0x12044,
.clkr = {
@@ -2375,6 +2805,40 @@
},
};
+static struct clk_branch gcc_bimc_gfx_clk = {
+ .halt_reg = 0x31024,
+ .clkr = {
+ .enable_reg = 0x31024,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_bimc_gfx_clk",
+ .parent_names = (const char *[]){
+ "bimc_gpu_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_bimc_gpu_clk = {
+ .halt_reg = 0x31040,
+ .clkr = {
+ .enable_reg = 0x31040,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_bimc_gpu_clk",
+ .parent_names = (const char *[]){
+ "bimc_gpu_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
static struct clk_branch gcc_jpeg_tbu_clk = {
.halt_reg = 0x12034,
.clkr = {
@@ -2562,6 +3026,46 @@
},
};
+static struct gdsc venus_gdsc = {
+ .gdscr = 0x4c018,
+ .pd = {
+ .name = "venus",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc mdss_gdsc = {
+ .gdscr = 0x4d078,
+ .pd = {
+ .name = "mdss",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc jpeg_gdsc = {
+ .gdscr = 0x5701c,
+ .pd = {
+ .name = "jpeg",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc vfe_gdsc = {
+ .gdscr = 0x58034,
+ .pd = {
+ .name = "vfe",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc oxili_gdsc = {
+ .gdscr = 0x5901c,
+ .pd = {
+ .name = "oxili",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
static struct clk_regmap *gcc_msm8916_clocks[] = {
[GPLL0] = &gpll0.clkr,
[GPLL0_VOTE] = &gpll0_vote,
@@ -2701,6 +3205,36 @@
[GCC_VENUS0_AHB_CLK] = &gcc_venus0_ahb_clk.clkr,
[GCC_VENUS0_AXI_CLK] = &gcc_venus0_axi_clk.clkr,
[GCC_VENUS0_VCODEC0_CLK] = &gcc_venus0_vcodec0_clk.clkr,
+ [BIMC_DDR_CLK_SRC] = &bimc_ddr_clk_src.clkr,
+ [GCC_APSS_TCU_CLK] = &gcc_apss_tcu_clk.clkr,
+ [GCC_GFX_TCU_CLK] = &gcc_gfx_tcu_clk.clkr,
+ [BIMC_GPU_CLK_SRC] = &bimc_gpu_clk_src.clkr,
+ [GCC_BIMC_GFX_CLK] = &gcc_bimc_gfx_clk.clkr,
+ [GCC_BIMC_GPU_CLK] = &gcc_bimc_gpu_clk.clkr,
+ [ULTAUDIO_AHBFABRIC_CLK_SRC] = &ultaudio_ahbfabric_clk_src.clkr,
+ [ULTAUDIO_LPAIF_PRI_I2S_CLK_SRC] = &ultaudio_lpaif_pri_i2s_clk_src.clkr,
+ [ULTAUDIO_LPAIF_SEC_I2S_CLK_SRC] = &ultaudio_lpaif_sec_i2s_clk_src.clkr,
+ [ULTAUDIO_LPAIF_AUX_I2S_CLK_SRC] = &ultaudio_lpaif_aux_i2s_clk_src.clkr,
+ [ULTAUDIO_XO_CLK_SRC] = &ultaudio_xo_clk_src.clkr,
+ [CODEC_DIGCODEC_CLK_SRC] = &codec_digcodec_clk_src.clkr,
+ [GCC_ULTAUDIO_PCNOC_MPORT_CLK] = &gcc_ultaudio_pcnoc_mport_clk.clkr,
+ [GCC_ULTAUDIO_PCNOC_SWAY_CLK] = &gcc_ultaudio_pcnoc_sway_clk.clkr,
+ [GCC_ULTAUDIO_AVSYNC_XO_CLK] = &gcc_ultaudio_avsync_xo_clk.clkr,
+ [GCC_ULTAUDIO_STC_XO_CLK] = &gcc_ultaudio_stc_xo_clk.clkr,
+ [GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_CLK] = &gcc_ultaudio_ahbfabric_ixfabric_clk.clkr,
+ [GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_LPM_CLK] = &gcc_ultaudio_ahbfabric_ixfabric_lpm_clk.clkr,
+ [GCC_ULTAUDIO_LPAIF_PRI_I2S_CLK] = &gcc_ultaudio_lpaif_pri_i2s_clk.clkr,
+ [GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK] = &gcc_ultaudio_lpaif_sec_i2s_clk.clkr,
+ [GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK] = &gcc_ultaudio_lpaif_aux_i2s_clk.clkr,
+ [GCC_CODEC_DIGCODEC_CLK] = &gcc_codec_digcodec_clk.clkr,
+};
+
+static struct gdsc *gcc_msm8916_gdscs[] = {
+ [VENUS_GDSC] = &venus_gdsc,
+ [MDSS_GDSC] = &mdss_gdsc,
+ [JPEG_GDSC] = &jpeg_gdsc,
+ [VFE_GDSC] = &vfe_gdsc,
+ [OXILI_GDSC] = &oxili_gdsc,
};
static const struct qcom_reset_map gcc_msm8916_resets[] = {
@@ -2810,6 +3344,8 @@
.num_clks = ARRAY_SIZE(gcc_msm8916_clocks),
.resets = gcc_msm8916_resets,
.num_resets = ARRAY_SIZE(gcc_msm8916_resets),
+ .gdscs = gcc_msm8916_gdscs,
+ .num_gdscs = ARRAY_SIZE(gcc_msm8916_gdscs),
};
static const struct of_device_id gcc_msm8916_match_table[] = {
diff --git a/drivers/clk/qcom/gcc-msm8974.c b/drivers/clk/qcom/gcc-msm8974.c
index 2bcf875..ebad55c 100644
--- a/drivers/clk/qcom/gcc-msm8974.c
+++ b/drivers/clk/qcom/gcc-msm8974.c
@@ -31,6 +31,7 @@
#include "clk-rcg.h"
#include "clk-branch.h"
#include "reset.h"
+#include "gdsc.h"
enum {
P_XO,
@@ -2432,6 +2433,14 @@
},
};
+static struct gdsc usb_hs_hsic_gdsc = {
+ .gdscr = 0x404,
+ .pd = {
+ .name = "usb_hs_hsic",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
static struct clk_regmap *gcc_msm8974_clocks[] = {
[GPLL0] = &gpll0.clkr,
[GPLL0_VOTE] = &gpll0_vote,
@@ -2661,6 +2670,10 @@
[GCC_VENUS_RESTART] = { 0x1740 },
};
+static struct gdsc *gcc_msm8974_gdscs[] = {
+ [USB_HS_HSIC_GDSC] = &usb_hs_hsic_gdsc,
+};
+
static const struct regmap_config gcc_msm8974_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
@@ -2675,6 +2688,8 @@
.num_clks = ARRAY_SIZE(gcc_msm8974_clocks),
.resets = gcc_msm8974_resets,
.num_resets = ARRAY_SIZE(gcc_msm8974_resets),
+ .gdscs = gcc_msm8974_gdscs,
+ .num_gdscs = ARRAY_SIZE(gcc_msm8974_gdscs),
};
static const struct of_device_id gcc_msm8974_match_table[] = {
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
new file mode 100644
index 0000000..da9fad8
--- /dev/null
+++ b/drivers/clk/qcom/gdsc.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * 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/delay.h>
+#include <linux/err.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/pm_domain.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+#include <linux/slab.h>
+#include "gdsc.h"
+
+#define PWR_ON_MASK BIT(31)
+#define EN_REST_WAIT_MASK GENMASK_ULL(23, 20)
+#define EN_FEW_WAIT_MASK GENMASK_ULL(19, 16)
+#define CLK_DIS_WAIT_MASK GENMASK_ULL(15, 12)
+#define SW_OVERRIDE_MASK BIT(2)
+#define HW_CONTROL_MASK BIT(1)
+#define SW_COLLAPSE_MASK BIT(0)
+
+/* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */
+#define EN_REST_WAIT_VAL (0x2 << 20)
+#define EN_FEW_WAIT_VAL (0x8 << 16)
+#define CLK_DIS_WAIT_VAL (0x2 << 12)
+
+#define RETAIN_MEM BIT(14)
+#define RETAIN_PERIPH BIT(13)
+
+#define TIMEOUT_US 100
+
+#define domain_to_gdsc(domain) container_of(domain, struct gdsc, pd)
+
+static int gdsc_is_enabled(struct gdsc *sc)
+{
+ u32 val;
+ int ret;
+
+ ret = regmap_read(sc->regmap, sc->gdscr, &val);
+ if (ret)
+ return ret;
+
+ return !!(val & PWR_ON_MASK);
+}
+
+static int gdsc_toggle_logic(struct gdsc *sc, bool en)
+{
+ int ret;
+ u32 val = en ? 0 : SW_COLLAPSE_MASK;
+ u32 check = en ? PWR_ON_MASK : 0;
+ unsigned long timeout;
+
+ ret = regmap_update_bits(sc->regmap, sc->gdscr, SW_COLLAPSE_MASK, val);
+ if (ret)
+ return ret;
+
+ timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);
+ do {
+ ret = regmap_read(sc->regmap, sc->gdscr, &val);
+ if (ret)
+ return ret;
+
+ if ((val & PWR_ON_MASK) == check)
+ return 0;
+ } while (time_before(jiffies, timeout));
+
+ ret = regmap_read(sc->regmap, sc->gdscr, &val);
+ if (ret)
+ return ret;
+
+ if ((val & PWR_ON_MASK) == check)
+ return 0;
+
+ return -ETIMEDOUT;
+}
+
+static inline int gdsc_deassert_reset(struct gdsc *sc)
+{
+ int i;
+
+ for (i = 0; i < sc->reset_count; i++)
+ sc->rcdev->ops->deassert(sc->rcdev, sc->resets[i]);
+ return 0;
+}
+
+static inline int gdsc_assert_reset(struct gdsc *sc)
+{
+ int i;
+
+ for (i = 0; i < sc->reset_count; i++)
+ sc->rcdev->ops->assert(sc->rcdev, sc->resets[i]);
+ return 0;
+}
+
+static inline void gdsc_force_mem_on(struct gdsc *sc)
+{
+ int i;
+ u32 mask = RETAIN_MEM | RETAIN_PERIPH;
+
+ for (i = 0; i < sc->cxc_count; i++)
+ regmap_update_bits(sc->regmap, sc->cxcs[i], mask, mask);
+}
+
+static inline void gdsc_clear_mem_on(struct gdsc *sc)
+{
+ int i;
+ u32 mask = RETAIN_MEM | RETAIN_PERIPH;
+
+ for (i = 0; i < sc->cxc_count; i++)
+ regmap_update_bits(sc->regmap, sc->cxcs[i], mask, 0);
+}
+
+static int gdsc_enable(struct generic_pm_domain *domain)
+{
+ struct gdsc *sc = domain_to_gdsc(domain);
+ int ret;
+
+ if (sc->pwrsts == PWRSTS_ON)
+ return gdsc_deassert_reset(sc);
+
+ ret = gdsc_toggle_logic(sc, true);
+ if (ret)
+ return ret;
+
+ if (sc->pwrsts & PWRSTS_OFF)
+ gdsc_force_mem_on(sc);
+
+ /*
+ * If clocks to this power domain were already on, they will take an
+ * additional 4 clock cycles to re-enable after the power domain is
+ * enabled. Delay to account for this. A delay is also needed to ensure
+ * clocks are not enabled within 400ns of enabling power to the
+ * memories.
+ */
+ udelay(1);
+
+ return 0;
+}
+
+static int gdsc_disable(struct generic_pm_domain *domain)
+{
+ struct gdsc *sc = domain_to_gdsc(domain);
+
+ if (sc->pwrsts == PWRSTS_ON)
+ return gdsc_assert_reset(sc);
+
+ if (sc->pwrsts & PWRSTS_OFF)
+ gdsc_clear_mem_on(sc);
+
+ return gdsc_toggle_logic(sc, false);
+}
+
+static int gdsc_init(struct gdsc *sc)
+{
+ u32 mask, val;
+ int on, ret;
+
+ /*
+ * Disable HW trigger: collapse/restore occur based on registers writes.
+ * Disable SW override: Use hardware state-machine for sequencing.
+ * Configure wait time between states.
+ */
+ mask = HW_CONTROL_MASK | SW_OVERRIDE_MASK |
+ EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK;
+ val = EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL;
+ ret = regmap_update_bits(sc->regmap, sc->gdscr, mask, val);
+ if (ret)
+ return ret;
+
+ /* Force gdsc ON if only ON state is supported */
+ if (sc->pwrsts == PWRSTS_ON) {
+ ret = gdsc_toggle_logic(sc, true);
+ if (ret)
+ return ret;
+ }
+
+ on = gdsc_is_enabled(sc);
+ if (on < 0)
+ return on;
+
+ if (on || (sc->pwrsts & PWRSTS_RET))
+ gdsc_force_mem_on(sc);
+ else
+ gdsc_clear_mem_on(sc);
+
+ sc->pd.power_off = gdsc_disable;
+ sc->pd.power_on = gdsc_enable;
+ pm_genpd_init(&sc->pd, NULL, !on);
+
+ return 0;
+}
+
+int gdsc_register(struct device *dev, struct gdsc **scs, size_t num,
+ struct reset_controller_dev *rcdev, struct regmap *regmap)
+{
+ int i, ret;
+ struct genpd_onecell_data *data;
+
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->domains = devm_kcalloc(dev, num, sizeof(*data->domains),
+ GFP_KERNEL);
+ if (!data->domains)
+ return -ENOMEM;
+
+ data->num_domains = num;
+ for (i = 0; i < num; i++) {
+ if (!scs[i])
+ continue;
+ scs[i]->regmap = regmap;
+ scs[i]->rcdev = rcdev;
+ ret = gdsc_init(scs[i]);
+ if (ret)
+ return ret;
+ data->domains[i] = &scs[i]->pd;
+ }
+
+ return of_genpd_add_provider_onecell(dev->of_node, data);
+}
+
+void gdsc_unregister(struct device *dev)
+{
+ of_genpd_del_provider(dev->of_node);
+}
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
new file mode 100644
index 0000000..5ded268
--- /dev/null
+++ b/drivers/clk/qcom/gdsc.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * 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_GDSC_H__
+#define __QCOM_GDSC_H__
+
+#include <linux/err.h>
+#include <linux/pm_domain.h>
+
+struct regmap;
+struct reset_controller_dev;
+
+/* Powerdomain allowable state bitfields */
+#define PWRSTS_OFF BIT(0)
+#define PWRSTS_RET BIT(1)
+#define PWRSTS_ON BIT(2)
+#define PWRSTS_OFF_ON (PWRSTS_OFF | PWRSTS_ON)
+#define PWRSTS_RET_ON (PWRSTS_RET | PWRSTS_ON)
+
+/**
+ * struct gdsc - Globally Distributed Switch Controller
+ * @pd: generic power domain
+ * @regmap: regmap for MMIO accesses
+ * @gdscr: gsdc control register
+ * @cxcs: offsets of branch registers to toggle mem/periph bits in
+ * @cxc_count: number of @cxcs
+ * @pwrsts: Possible powerdomain power states
+ * @resets: ids of resets associated with this gdsc
+ * @reset_count: number of @resets
+ * @rcdev: reset controller
+ */
+struct gdsc {
+ struct generic_pm_domain pd;
+ struct regmap *regmap;
+ unsigned int gdscr;
+ unsigned int *cxcs;
+ unsigned int cxc_count;
+ const u8 pwrsts;
+ struct reset_controller_dev *rcdev;
+ unsigned int *resets;
+ unsigned int reset_count;
+};
+
+#ifdef CONFIG_QCOM_GDSC
+int gdsc_register(struct device *, struct gdsc **, size_t n,
+ struct reset_controller_dev *, struct regmap *);
+void gdsc_unregister(struct device *);
+#else
+static inline int gdsc_register(struct device *d, struct gdsc **g, size_t n,
+ struct reset_controller_dev *rcdev,
+ struct regmap *r)
+{
+ return -ENOSYS;
+}
+
+static inline void gdsc_unregister(struct device *d) {};
+#endif /* CONFIG_QCOM_GDSC */
+#endif /* __QCOM_GDSC_H__ */
diff --git a/drivers/clk/qcom/mmcc-apq8084.c b/drivers/clk/qcom/mmcc-apq8084.c
index f0ee6bd..aa3809d 100644
--- a/drivers/clk/qcom/mmcc-apq8084.c
+++ b/drivers/clk/qcom/mmcc-apq8084.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -26,6 +26,7 @@
#include "clk-rcg.h"
#include "clk-branch.h"
#include "reset.h"
+#include "gdsc.h"
enum {
P_XO,
@@ -571,17 +572,11 @@
},
};
-static struct freq_tbl pixel_freq_tbl[] = {
- { .src = P_DSI0PLL },
- { }
-};
-
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 = pixel_freq_tbl,
.clkr.hw.init = &(struct clk_init_data){
.name = "pclk0_clk_src",
.parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
@@ -596,7 +591,6 @@
.mnd_width = 8,
.hid_width = 5,
.parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
- .freq_tbl = pixel_freq_tbl,
.clkr.hw.init = &(struct clk_init_data){
.name = "pclk1_clk_src",
.parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
@@ -844,21 +838,15 @@
},
};
-static struct freq_tbl byte_freq_tbl[] = {
- { .src = P_DSI0PLL_BYTE },
- { }
-};
-
static struct clk_rcg2 byte0_clk_src = {
.cmd_rcgr = 0x2120,
.hid_width = 5,
.parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map,
- .freq_tbl = byte_freq_tbl,
.clkr.hw.init = &(struct clk_init_data){
.name = "byte0_clk_src",
.parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0,
.num_parents = 6,
- .ops = &clk_byte_ops,
+ .ops = &clk_byte2_ops,
.flags = CLK_SET_RATE_PARENT,
},
};
@@ -867,12 +855,11 @@
.cmd_rcgr = 0x2140,
.hid_width = 5,
.parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map,
- .freq_tbl = byte_freq_tbl,
.clkr.hw.init = &(struct clk_init_data){
.name = "byte1_clk_src",
.parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0,
.num_parents = 6,
- .ops = &clk_byte_ops,
+ .ops = &clk_byte2_ops,
.flags = CLK_SET_RATE_PARENT,
},
};
@@ -3077,6 +3064,76 @@
.aux_output_mask = BIT(1),
};
+static struct gdsc venus0_gdsc = {
+ .gdscr = 0x1024,
+ .pd = {
+ .name = "venus0",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc venus0_core0_gdsc = {
+ .gdscr = 0x1040,
+ .pd = {
+ .name = "venus0_core0",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc venus0_core1_gdsc = {
+ .gdscr = 0x1044,
+ .pd = {
+ .name = "venus0_core1",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc mdss_gdsc = {
+ .gdscr = 0x2304,
+ .cxcs = (unsigned int []){ 0x231c, 0x2320 },
+ .cxc_count = 2,
+ .pd = {
+ .name = "mdss",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc camss_jpeg_gdsc = {
+ .gdscr = 0x35a4,
+ .pd = {
+ .name = "camss_jpeg",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc camss_vfe_gdsc = {
+ .gdscr = 0x36a4,
+ .cxcs = (unsigned int []){ 0x36a8, 0x36ac, 0x36b0 },
+ .cxc_count = 3,
+ .pd = {
+ .name = "camss_vfe",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc oxili_gdsc = {
+ .gdscr = 0x4024,
+ .cxcs = (unsigned int []){ 0x4028 },
+ .cxc_count = 1,
+ .pd = {
+ .name = "oxili",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc oxilicx_gdsc = {
+ .gdscr = 0x4034,
+ .pd = {
+ .name = "oxilicx",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
static struct clk_regmap *mmcc_apq8084_clocks[] = {
[MMSS_AHB_CLK_SRC] = &mmss_ahb_clk_src.clkr,
[MMSS_AXI_CLK_SRC] = &mmss_axi_clk_src.clkr,
@@ -3294,6 +3351,17 @@
[MMSSNOCAXI_RESET] = { 0x5060 },
};
+static struct gdsc *mmcc_apq8084_gdscs[] = {
+ [VENUS0_GDSC] = &venus0_gdsc,
+ [VENUS0_CORE0_GDSC] = &venus0_core0_gdsc,
+ [VENUS0_CORE1_GDSC] = &venus0_core1_gdsc,
+ [MDSS_GDSC] = &mdss_gdsc,
+ [CAMSS_JPEG_GDSC] = &camss_jpeg_gdsc,
+ [CAMSS_VFE_GDSC] = &camss_vfe_gdsc,
+ [OXILI_GDSC] = &oxili_gdsc,
+ [OXILICX_GDSC] = &oxilicx_gdsc,
+};
+
static const struct regmap_config mmcc_apq8084_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
@@ -3308,6 +3376,8 @@
.num_clks = ARRAY_SIZE(mmcc_apq8084_clocks),
.resets = mmcc_apq8084_resets,
.num_resets = ARRAY_SIZE(mmcc_apq8084_resets),
+ .gdscs = mmcc_apq8084_gdscs,
+ .num_gdscs = ARRAY_SIZE(mmcc_apq8084_gdscs),
};
static const struct of_device_id mmcc_apq8084_match_table[] = {
diff --git a/drivers/clk/qcom/mmcc-msm8974.c b/drivers/clk/qcom/mmcc-msm8974.c
index 0987bf4..fe8320d 100644
--- a/drivers/clk/qcom/mmcc-msm8974.c
+++ b/drivers/clk/qcom/mmcc-msm8974.c
@@ -31,6 +31,7 @@
#include "clk-rcg.h"
#include "clk-branch.h"
#include "reset.h"
+#include "gdsc.h"
enum {
P_XO,
@@ -522,17 +523,11 @@
},
};
-static struct freq_tbl pixel_freq_tbl[] = {
- { .src = P_DSI0PLL },
- { }
-};
-
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 = pixel_freq_tbl,
.clkr.hw.init = &(struct clk_init_data){
.name = "pclk0_clk_src",
.parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
@@ -547,7 +542,6 @@
.mnd_width = 8,
.hid_width = 5,
.parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
- .freq_tbl = pixel_freq_tbl,
.clkr.hw.init = &(struct clk_init_data){
.name = "pclk1_clk_src",
.parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
@@ -785,7 +779,7 @@
.name = "byte0_clk_src",
.parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0,
.num_parents = 6,
- .ops = &clk_byte_ops,
+ .ops = &clk_byte2_ops,
.flags = CLK_SET_RATE_PARENT,
},
};
@@ -799,7 +793,7 @@
.name = "byte1_clk_src",
.parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0,
.num_parents = 6,
- .ops = &clk_byte_ops,
+ .ops = &clk_byte2_ops,
.flags = CLK_SET_RATE_PARENT,
},
};
@@ -2349,6 +2343,66 @@
.aux_output_mask = BIT(1),
};
+static struct gdsc venus0_gdsc = {
+ .gdscr = 0x1024,
+ .cxcs = (unsigned int []){ 0x1028 },
+ .cxc_count = 1,
+ .resets = (unsigned int []){ VENUS0_RESET },
+ .reset_count = 1,
+ .pd = {
+ .name = "venus0",
+ },
+ .pwrsts = PWRSTS_ON,
+};
+
+static struct gdsc mdss_gdsc = {
+ .gdscr = 0x2304,
+ .cxcs = (unsigned int []){ 0x231c, 0x2320 },
+ .cxc_count = 2,
+ .pd = {
+ .name = "mdss",
+ },
+ .pwrsts = PWRSTS_RET_ON,
+};
+
+static struct gdsc camss_jpeg_gdsc = {
+ .gdscr = 0x35a4,
+ .cxcs = (unsigned int []){ 0x35a8, 0x35ac, 0x35b0 },
+ .cxc_count = 3,
+ .pd = {
+ .name = "camss_jpeg",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc camss_vfe_gdsc = {
+ .gdscr = 0x36a4,
+ .cxcs = (unsigned int []){ 0x36a8, 0x36ac, 0x3704, 0x3714, 0x36b0 },
+ .cxc_count = 5,
+ .pd = {
+ .name = "camss_vfe",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc oxili_gdsc = {
+ .gdscr = 0x4024,
+ .cxcs = (unsigned int []){ 0x4028 },
+ .cxc_count = 1,
+ .pd = {
+ .name = "oxili",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc oxilicx_gdsc = {
+ .gdscr = 0x4034,
+ .pd = {
+ .name = "oxilicx",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
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,
@@ -2525,6 +2579,15 @@
[OCMEMNOC_RESET] = { 0x50b0 },
};
+static struct gdsc *mmcc_msm8974_gdscs[] = {
+ [VENUS0_GDSC] = &venus0_gdsc,
+ [MDSS_GDSC] = &mdss_gdsc,
+ [CAMSS_JPEG_GDSC] = &camss_jpeg_gdsc,
+ [CAMSS_VFE_GDSC] = &camss_vfe_gdsc,
+ [OXILI_GDSC] = &oxili_gdsc,
+ [OXILICX_GDSC] = &oxilicx_gdsc,
+};
+
static const struct regmap_config mmcc_msm8974_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
@@ -2539,6 +2602,8 @@
.num_clks = ARRAY_SIZE(mmcc_msm8974_clocks),
.resets = mmcc_msm8974_resets,
.num_resets = ARRAY_SIZE(mmcc_msm8974_resets),
+ .gdscs = mmcc_msm8974_gdscs,
+ .num_gdscs = ARRAY_SIZE(mmcc_msm8974_gdscs),
};
static const struct of_device_id mmcc_msm8974_match_table[] = {
diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c
index 9b61342..1c8162e 100644
--- a/drivers/clk/rockchip/clk-mmc-phase.c
+++ b/drivers/clk/rockchip/clk-mmc-phase.c
@@ -41,6 +41,8 @@
#define ROCKCHIP_MMC_DEGREE_MASK 0x3
#define ROCKCHIP_MMC_DELAYNUM_OFFSET 2
#define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
+#define ROCKCHIP_MMC_INIT_STATE_RESET 0x1
+#define ROCKCHIP_MMC_INIT_STATE_SHIFT 1
#define PSECS_PER_SEC 1000000000000LL
@@ -143,6 +145,15 @@
mmc_clock->reg = reg;
mmc_clock->shift = shift;
+ /*
+ * Assert init_state to soft reset the CLKGEN
+ * for mmc tuning phase and degree
+ */
+ if (mmc_clock->shift == ROCKCHIP_MMC_INIT_STATE_SHIFT)
+ writel(HIWORD_UPDATE(ROCKCHIP_MMC_INIT_STATE_RESET,
+ ROCKCHIP_MMC_INIT_STATE_RESET,
+ mmc_clock->shift), mmc_clock->reg);
+
clk = clk_register(NULL, &mmc_clock->hw);
if (IS_ERR(clk))
goto err_free;
diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
index 7737a1d..4881eb8 100644
--- a/drivers/clk/rockchip/clk-pll.c
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -126,11 +126,32 @@
#define RK3066_PLLCON3_PWRDOWN (1 << 1)
#define RK3066_PLLCON3_BYPASS (1 << 0)
+static void rockchip_rk3066_pll_get_params(struct rockchip_clk_pll *pll,
+ struct rockchip_pll_rate_table *rate)
+{
+ u32 pllcon;
+
+ pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
+ rate->nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT)
+ & RK3066_PLLCON0_NR_MASK) + 1;
+ rate->no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT)
+ & RK3066_PLLCON0_OD_MASK) + 1;
+
+ pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
+ rate->nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT)
+ & RK3066_PLLCON1_NF_MASK) + 1;
+
+ pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(2));
+ rate->nb = ((pllcon >> RK3066_PLLCON2_NB_SHIFT)
+ & RK3066_PLLCON2_NB_MASK) + 1;
+}
+
static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw,
unsigned long prate)
{
struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
- u64 nf, nr, no, rate64 = prate;
+ struct rockchip_pll_rate_table cur;
+ u64 rate64 = prate;
u32 pllcon;
pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(3));
@@ -140,53 +161,31 @@
return prate;
}
- pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
- nf = (pllcon >> RK3066_PLLCON1_NF_SHIFT) & RK3066_PLLCON1_NF_MASK;
+ rockchip_rk3066_pll_get_params(pll, &cur);
- pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
- nr = (pllcon >> RK3066_PLLCON0_NR_SHIFT) & RK3066_PLLCON0_NR_MASK;
- no = (pllcon >> RK3066_PLLCON0_OD_SHIFT) & RK3066_PLLCON0_OD_MASK;
-
- rate64 *= (nf + 1);
- do_div(rate64, nr + 1);
- do_div(rate64, no + 1);
+ rate64 *= cur.nf;
+ do_div(rate64, cur.nr);
+ do_div(rate64, cur.no);
return (unsigned long)rate64;
}
-static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
- unsigned long prate)
+static int rockchip_rk3066_pll_set_params(struct rockchip_clk_pll *pll,
+ const struct rockchip_pll_rate_table *rate)
{
- struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
- const struct rockchip_pll_rate_table *rate;
- unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate);
- struct regmap *grf = rockchip_clk_get_grf();
- struct clk_mux *pll_mux = &pll->pll_mux;
const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
+ struct clk_mux *pll_mux = &pll->pll_mux;
+ struct rockchip_pll_rate_table cur;
int rate_change_remuxed = 0;
int cur_parent;
int ret;
- if (IS_ERR(grf)) {
- pr_debug("%s: grf regmap not available, aborting rate change\n",
- __func__);
- return PTR_ERR(grf);
- }
-
- pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
- __func__, clk_hw_get_name(hw), old_rate, drate, prate);
-
- /* Get required rate settings from table */
- rate = rockchip_get_pll_settings(pll, drate);
- if (!rate) {
- pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
- drate, clk_hw_get_name(hw));
- return -EINVAL;
- }
-
pr_debug("%s: rate settings for %lu (nr, no, nf): (%d, %d, %d)\n",
__func__, rate->rate, rate->nr, rate->no, rate->nf);
+ rockchip_rk3066_pll_get_params(pll, &cur);
+ cur.rate = 0;
+
cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
if (cur_parent == PLL_MODE_NORM) {
pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
@@ -219,9 +218,9 @@
/* wait for the pll to lock */
ret = rockchip_pll_wait_lock(pll);
if (ret) {
- pr_warn("%s: pll did not lock, trying to restore old rate %lu\n",
- __func__, old_rate);
- rockchip_rk3066_pll_set_rate(hw, old_rate, prate);
+ pr_warn("%s: pll update unsucessful, trying to restore old params\n",
+ __func__);
+ rockchip_rk3066_pll_set_params(pll, &cur);
}
if (rate_change_remuxed)
@@ -230,6 +229,34 @@
return ret;
}
+static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
+ unsigned long prate)
+{
+ struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+ const struct rockchip_pll_rate_table *rate;
+ unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate);
+ struct regmap *grf = rockchip_clk_get_grf();
+
+ if (IS_ERR(grf)) {
+ pr_debug("%s: grf regmap not available, aborting rate change\n",
+ __func__);
+ return PTR_ERR(grf);
+ }
+
+ pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
+ __func__, clk_hw_get_name(hw), old_rate, drate, prate);
+
+ /* Get required rate settings from table */
+ rate = rockchip_get_pll_settings(pll, drate);
+ if (!rate) {
+ pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
+ drate, clk_hw_get_name(hw));
+ return -EINVAL;
+ }
+
+ return rockchip_rk3066_pll_set_params(pll, rate);
+}
+
static int rockchip_rk3066_pll_enable(struct clk_hw *hw)
{
struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
@@ -261,9 +288,8 @@
{
struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
const struct rockchip_pll_rate_table *rate;
- unsigned int nf, nr, no, nb;
+ struct rockchip_pll_rate_table cur;
unsigned long drate;
- u32 pllcon;
if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
return;
@@ -275,34 +301,21 @@
if (!rate)
return;
- pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
- nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT) & RK3066_PLLCON0_NR_MASK) + 1;
- no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT) & RK3066_PLLCON0_OD_MASK) + 1;
-
- pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
- nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT) & RK3066_PLLCON1_NF_MASK) + 1;
-
- pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(2));
- nb = ((pllcon >> RK3066_PLLCON2_NB_SHIFT) & RK3066_PLLCON2_NB_MASK) + 1;
+ rockchip_rk3066_pll_get_params(pll, &cur);
pr_debug("%s: pll %s@%lu: nr (%d:%d); no (%d:%d); nf(%d:%d), nb(%d:%d)\n",
- __func__, clk_hw_get_name(hw), drate, rate->nr, nr,
- rate->no, no, rate->nf, nf, rate->nb, nb);
- if (rate->nr != nr || rate->no != no || rate->nf != nf
- || rate->nb != nb) {
- struct clk_hw *parent = clk_hw_get_parent(hw);
- unsigned long prate;
+ __func__, clk_hw_get_name(hw), drate, rate->nr, cur.nr,
+ rate->no, cur.no, rate->nf, cur.nf, rate->nb, cur.nb);
+ if (rate->nr != cur.nr || rate->no != cur.no || rate->nf != cur.nf
+ || rate->nb != cur.nb) {
+ struct regmap *grf = rockchip_clk_get_grf();
- if (!parent) {
- pr_warn("%s: parent of %s not available\n",
- __func__, clk_hw_get_name(hw));
+ if (IS_ERR(grf))
return;
- }
pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
__func__, clk_hw_get_name(hw));
- prate = clk_hw_get_rate(parent);
- rockchip_rk3066_pll_set_rate(hw, drate, prate);
+ rockchip_rk3066_pll_set_params(pll, rate);
}
}
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index 2493881..be6c7fd 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -135,9 +135,11 @@
div->flags = div_flags;
div->reg = base + muxdiv_offset;
div->mshift = 16;
- div->mmask = 0xffff0000;
+ div->mwidth = 16;
+ div->mmask = GENMASK(div->mwidth - 1, 0) << div->mshift;
div->nshift = 0;
- div->nmask = 0xffff;
+ div->nwidth = 16;
+ div->nmask = GENMASK(div->nwidth - 1, 0) << div->nshift;
div->lock = lock;
div_ops = &clk_fractional_divider_ops;
diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index 7c1e1f5..2fe37f7 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -164,7 +164,7 @@
* the values for DIV_COPY and DIV_HPM dividers need not be set.
*/
div0 = cfg_data->div0;
- if (test_bit(CLK_CPU_HAS_DIV1, &cpuclk->flags)) {
+ if (cpuclk->flags & CLK_CPU_HAS_DIV1) {
div1 = cfg_data->div1;
if (readl(base + E4210_SRC_CPU) & E4210_MUX_HPM_MASK)
div1 = readl(base + E4210_DIV_CPU1) &
@@ -185,7 +185,7 @@
alt_div = DIV_ROUND_UP(alt_prate, tmp_rate) - 1;
WARN_ON(alt_div >= MAX_DIV);
- if (test_bit(CLK_CPU_NEEDS_DEBUG_ALT_DIV, &cpuclk->flags)) {
+ if (cpuclk->flags & CLK_CPU_NEEDS_DEBUG_ALT_DIV) {
/*
* In Exynos4210, ATB clock parent is also mout_core. So
* ATB clock also needs to be mantained at safe speed.
@@ -206,7 +206,7 @@
writel(div0, base + E4210_DIV_CPU0);
wait_until_divider_stable(base + E4210_DIV_STAT_CPU0, DIV_MASK_ALL);
- if (test_bit(CLK_CPU_HAS_DIV1, &cpuclk->flags)) {
+ if (cpuclk->flags & CLK_CPU_HAS_DIV1) {
writel(div1, base + E4210_DIV_CPU1);
wait_until_divider_stable(base + E4210_DIV_STAT_CPU1,
DIV_MASK_ALL);
@@ -225,7 +225,7 @@
unsigned long mux_reg;
/* find out the divider values to use for clock data */
- if (test_bit(CLK_CPU_NEEDS_DEBUG_ALT_DIV, &cpuclk->flags)) {
+ if (cpuclk->flags & CLK_CPU_NEEDS_DEBUG_ALT_DIV) {
while ((cfg_data->prate * 1000) != ndata->new_rate) {
if (cfg_data->prate == 0)
return -EINVAL;
@@ -240,7 +240,7 @@
writel(mux_reg & ~(1 << 16), base + E4210_SRC_CPU);
wait_until_mux_stable(base + E4210_STAT_CPU, 16, 1);
- if (test_bit(CLK_CPU_NEEDS_DEBUG_ALT_DIV, &cpuclk->flags)) {
+ if (cpuclk->flags & CLK_CPU_NEEDS_DEBUG_ALT_DIV) {
div |= (cfg_data->div0 & E4210_DIV0_ATB_MASK);
div_mask |= E4210_DIV0_ATB_MASK;
}
diff --git a/drivers/clk/samsung/clk-exynos7.c b/drivers/clk/samsung/clk-exynos7.c
index 8524e66..55f8e2e 100644
--- a/drivers/clk/samsung/clk-exynos7.c
+++ b/drivers/clk/samsung/clk-exynos7.c
@@ -32,39 +32,41 @@
#define DIV_TOPC0 0x0600
#define DIV_TOPC1 0x0604
#define DIV_TOPC3 0x060C
+#define ENABLE_ACLK_TOPC0 0x0800
#define ENABLE_ACLK_TOPC1 0x0804
+#define ENABLE_SCLK_TOPC1 0x0A04
static struct samsung_fixed_factor_clock topc_fixed_factor_clks[] __initdata = {
- FFACTOR(0, "ffac_topc_bus0_pll_div2", "mout_bus0_pll_ctrl", 1, 2, 0),
+ FFACTOR(0, "ffac_topc_bus0_pll_div2", "mout_topc_bus0_pll", 1, 2, 0),
FFACTOR(0, "ffac_topc_bus0_pll_div4",
"ffac_topc_bus0_pll_div2", 1, 2, 0),
- FFACTOR(0, "ffac_topc_bus1_pll_div2", "mout_bus1_pll_ctrl", 1, 2, 0),
- FFACTOR(0, "ffac_topc_cc_pll_div2", "mout_cc_pll_ctrl", 1, 2, 0),
- FFACTOR(0, "ffac_topc_mfc_pll_div2", "mout_mfc_pll_ctrl", 1, 2, 0),
+ FFACTOR(0, "ffac_topc_bus1_pll_div2", "mout_topc_bus1_pll", 1, 2, 0),
+ FFACTOR(0, "ffac_topc_cc_pll_div2", "mout_topc_cc_pll", 1, 2, 0),
+ FFACTOR(0, "ffac_topc_mfc_pll_div2", "mout_topc_mfc_pll", 1, 2, 0),
};
/* List of parent clocks for Muxes in CMU_TOPC */
-PNAME(mout_aud_pll_ctrl_p) = { "fin_pll", "fout_aud_pll" };
-PNAME(mout_bus0_pll_ctrl_p) = { "fin_pll", "fout_bus0_pll" };
-PNAME(mout_bus1_pll_ctrl_p) = { "fin_pll", "fout_bus1_pll" };
-PNAME(mout_cc_pll_ctrl_p) = { "fin_pll", "fout_cc_pll" };
-PNAME(mout_mfc_pll_ctrl_p) = { "fin_pll", "fout_mfc_pll" };
+PNAME(mout_topc_aud_pll_ctrl_p) = { "fin_pll", "fout_aud_pll" };
+PNAME(mout_topc_bus0_pll_ctrl_p) = { "fin_pll", "fout_bus0_pll" };
+PNAME(mout_topc_bus1_pll_ctrl_p) = { "fin_pll", "fout_bus1_pll" };
+PNAME(mout_topc_cc_pll_ctrl_p) = { "fin_pll", "fout_cc_pll" };
+PNAME(mout_topc_mfc_pll_ctrl_p) = { "fin_pll", "fout_mfc_pll" };
-PNAME(mout_topc_group2) = { "mout_sclk_bus0_pll_cmuc",
- "mout_sclk_bus1_pll_cmuc", "mout_sclk_cc_pll_cmuc",
- "mout_sclk_mfc_pll_cmuc" };
+PNAME(mout_topc_group2) = { "mout_topc_bus0_pll_half",
+ "mout_topc_bus1_pll_half", "mout_topc_cc_pll_half",
+ "mout_topc_mfc_pll_half" };
-PNAME(mout_sclk_bus0_pll_cmuc_p) = { "mout_bus0_pll_ctrl",
+PNAME(mout_topc_bus0_pll_half_p) = { "mout_topc_bus0_pll",
"ffac_topc_bus0_pll_div2", "ffac_topc_bus0_pll_div4"};
-PNAME(mout_sclk_bus1_pll_cmuc_p) = { "mout_bus1_pll_ctrl",
+PNAME(mout_topc_bus1_pll_half_p) = { "mout_topc_bus1_pll",
"ffac_topc_bus1_pll_div2"};
-PNAME(mout_sclk_cc_pll_cmuc_p) = { "mout_cc_pll_ctrl",
+PNAME(mout_topc_cc_pll_half_p) = { "mout_topc_cc_pll",
"ffac_topc_cc_pll_div2"};
-PNAME(mout_sclk_mfc_pll_cmuc_p) = { "mout_mfc_pll_ctrl",
+PNAME(mout_topc_mfc_pll_half_p) = { "mout_topc_mfc_pll",
"ffac_topc_mfc_pll_div2"};
-PNAME(mout_sclk_bus0_pll_out_p) = {"mout_bus0_pll_ctrl",
+PNAME(mout_topc_bus0_pll_out_p) = {"mout_topc_bus0_pll",
"ffac_topc_bus0_pll_div2"};
static unsigned long topc_clk_regs[] __initdata = {
@@ -88,23 +90,27 @@
};
static struct samsung_mux_clock topc_mux_clks[] __initdata = {
- MUX(0, "mout_bus0_pll_ctrl", mout_bus0_pll_ctrl_p, MUX_SEL_TOPC0, 0, 1),
- MUX(0, "mout_bus1_pll_ctrl", mout_bus1_pll_ctrl_p, MUX_SEL_TOPC0, 4, 1),
- MUX(0, "mout_cc_pll_ctrl", mout_cc_pll_ctrl_p, MUX_SEL_TOPC0, 8, 1),
- MUX(0, "mout_mfc_pll_ctrl", mout_mfc_pll_ctrl_p, MUX_SEL_TOPC0, 12, 1),
-
- MUX(0, "mout_sclk_bus0_pll_cmuc", mout_sclk_bus0_pll_cmuc_p,
+ MUX(0, "mout_topc_bus0_pll", mout_topc_bus0_pll_ctrl_p,
+ MUX_SEL_TOPC0, 0, 1),
+ MUX(0, "mout_topc_bus1_pll", mout_topc_bus1_pll_ctrl_p,
+ MUX_SEL_TOPC0, 4, 1),
+ MUX(0, "mout_topc_cc_pll", mout_topc_cc_pll_ctrl_p,
+ MUX_SEL_TOPC0, 8, 1),
+ MUX(0, "mout_topc_mfc_pll", mout_topc_mfc_pll_ctrl_p,
+ MUX_SEL_TOPC0, 12, 1),
+ MUX(0, "mout_topc_bus0_pll_half", mout_topc_bus0_pll_half_p,
MUX_SEL_TOPC0, 16, 2),
- MUX(0, "mout_sclk_bus1_pll_cmuc", mout_sclk_bus1_pll_cmuc_p,
+ MUX(0, "mout_topc_bus1_pll_half", mout_topc_bus1_pll_half_p,
MUX_SEL_TOPC0, 20, 1),
- MUX(0, "mout_sclk_cc_pll_cmuc", mout_sclk_cc_pll_cmuc_p,
+ MUX(0, "mout_topc_cc_pll_half", mout_topc_cc_pll_half_p,
MUX_SEL_TOPC0, 24, 1),
- MUX(0, "mout_sclk_mfc_pll_cmuc", mout_sclk_mfc_pll_cmuc_p,
+ MUX(0, "mout_topc_mfc_pll_half", mout_topc_mfc_pll_half_p,
MUX_SEL_TOPC0, 28, 1),
- MUX(0, "mout_sclk_bus0_pll_out", mout_sclk_bus0_pll_out_p,
+ MUX(0, "mout_topc_aud_pll", mout_topc_aud_pll_ctrl_p,
+ MUX_SEL_TOPC1, 0, 1),
+ MUX(0, "mout_topc_bus0_pll_out", mout_topc_bus0_pll_out_p,
MUX_SEL_TOPC1, 16, 1),
- MUX(0, "mout_aud_pll_ctrl", mout_aud_pll_ctrl_p, MUX_SEL_TOPC1, 0, 1),
MUX(0, "mout_aclk_ccore_133", mout_topc_group2, MUX_SEL_TOPC2, 4, 2),
@@ -121,16 +127,16 @@
DIV(DOUT_ACLK_PERIS, "dout_aclk_peris_66", "mout_aclk_peris_66",
DIV_TOPC1, 24, 4),
- DIV(DOUT_SCLK_BUS0_PLL, "dout_sclk_bus0_pll", "mout_sclk_bus0_pll_out",
- DIV_TOPC3, 0, 3),
- DIV(DOUT_SCLK_BUS1_PLL, "dout_sclk_bus1_pll", "mout_bus1_pll_ctrl",
- DIV_TOPC3, 8, 3),
- DIV(DOUT_SCLK_CC_PLL, "dout_sclk_cc_pll", "mout_cc_pll_ctrl",
- DIV_TOPC3, 12, 3),
- DIV(DOUT_SCLK_MFC_PLL, "dout_sclk_mfc_pll", "mout_mfc_pll_ctrl",
- DIV_TOPC3, 16, 3),
- DIV(DOUT_SCLK_AUD_PLL, "dout_sclk_aud_pll", "mout_aud_pll_ctrl",
- DIV_TOPC3, 28, 3),
+ DIV(DOUT_SCLK_BUS0_PLL, "dout_sclk_bus0_pll", "mout_topc_bus0_pll_out",
+ DIV_TOPC3, 0, 4),
+ DIV(DOUT_SCLK_BUS1_PLL, "dout_sclk_bus1_pll", "mout_topc_bus1_pll",
+ DIV_TOPC3, 8, 4),
+ DIV(DOUT_SCLK_CC_PLL, "dout_sclk_cc_pll", "mout_topc_cc_pll",
+ DIV_TOPC3, 12, 4),
+ DIV(DOUT_SCLK_MFC_PLL, "dout_sclk_mfc_pll", "mout_topc_mfc_pll",
+ DIV_TOPC3, 16, 4),
+ DIV(DOUT_SCLK_AUD_PLL, "dout_sclk_aud_pll", "mout_topc_aud_pll",
+ DIV_TOPC3, 28, 4),
};
static struct samsung_pll_rate_table pll1460x_24mhz_tbl[] __initdata = {
@@ -139,8 +145,33 @@
};
static struct samsung_gate_clock topc_gate_clks[] __initdata = {
+ GATE(ACLK_CCORE_133, "aclk_ccore_133", "dout_aclk_ccore_133",
+ ENABLE_ACLK_TOPC0, 4, 0, 0),
+
GATE(ACLK_MSCL_532, "aclk_mscl_532", "dout_aclk_mscl_532",
ENABLE_ACLK_TOPC1, 20, 0, 0),
+
+ GATE(ACLK_PERIS_66, "aclk_peris_66", "dout_aclk_peris_66",
+ ENABLE_ACLK_TOPC1, 24, 0, 0),
+
+ GATE(SCLK_AUD_PLL, "sclk_aud_pll", "dout_sclk_aud_pll",
+ ENABLE_SCLK_TOPC1, 20, 0, 0),
+ GATE(SCLK_MFC_PLL_B, "sclk_mfc_pll_b", "dout_sclk_mfc_pll",
+ ENABLE_SCLK_TOPC1, 17, 0, 0),
+ GATE(SCLK_MFC_PLL_A, "sclk_mfc_pll_a", "dout_sclk_mfc_pll",
+ ENABLE_SCLK_TOPC1, 16, 0, 0),
+ GATE(SCLK_BUS1_PLL_B, "sclk_bus1_pll_b", "dout_sclk_bus1_pll",
+ ENABLE_SCLK_TOPC1, 13, 0, 0),
+ GATE(SCLK_BUS1_PLL_A, "sclk_bus1_pll_a", "dout_sclk_bus1_pll",
+ ENABLE_SCLK_TOPC1, 12, 0, 0),
+ GATE(SCLK_BUS0_PLL_B, "sclk_bus0_pll_b", "dout_sclk_bus0_pll",
+ ENABLE_SCLK_TOPC1, 5, 0, 0),
+ GATE(SCLK_BUS0_PLL_A, "sclk_bus0_pll_a", "dout_sclk_bus0_pll",
+ ENABLE_SCLK_TOPC1, 4, 0, 0),
+ GATE(SCLK_CC_PLL_B, "sclk_cc_pll_b", "dout_sclk_cc_pll",
+ ENABLE_SCLK_TOPC1, 1, 0, 0),
+ GATE(SCLK_CC_PLL_A, "sclk_cc_pll_a", "dout_sclk_cc_pll",
+ ENABLE_SCLK_TOPC1, 0, 0, 0),
};
static struct samsung_pll_clock topc_pll_clks[] __initdata = {
@@ -193,36 +224,37 @@
#define DIV_TOP0_PERIC1 0x0634
#define DIV_TOP0_PERIC2 0x0638
#define DIV_TOP0_PERIC3 0x063C
+#define ENABLE_ACLK_TOP03 0x080C
#define ENABLE_SCLK_TOP0_PERIC0 0x0A30
#define ENABLE_SCLK_TOP0_PERIC1 0x0A34
#define ENABLE_SCLK_TOP0_PERIC2 0x0A38
#define ENABLE_SCLK_TOP0_PERIC3 0x0A3C
/* List of parent clocks for Muxes in CMU_TOP0 */
-PNAME(mout_bus0_pll_p) = { "fin_pll", "dout_sclk_bus0_pll" };
-PNAME(mout_bus1_pll_p) = { "fin_pll", "dout_sclk_bus1_pll" };
-PNAME(mout_cc_pll_p) = { "fin_pll", "dout_sclk_cc_pll" };
-PNAME(mout_mfc_pll_p) = { "fin_pll", "dout_sclk_mfc_pll" };
-PNAME(mout_aud_pll_p) = { "fin_pll", "dout_sclk_aud_pll" };
+PNAME(mout_top0_bus0_pll_user_p) = { "fin_pll", "sclk_bus0_pll_a" };
+PNAME(mout_top0_bus1_pll_user_p) = { "fin_pll", "sclk_bus1_pll_a" };
+PNAME(mout_top0_cc_pll_user_p) = { "fin_pll", "sclk_cc_pll_a" };
+PNAME(mout_top0_mfc_pll_user_p) = { "fin_pll", "sclk_mfc_pll_a" };
+PNAME(mout_top0_aud_pll_user_p) = { "fin_pll", "sclk_aud_pll" };
-PNAME(mout_top0_half_bus0_pll_p) = {"mout_top0_bus0_pll",
+PNAME(mout_top0_bus0_pll_half_p) = {"mout_top0_bus0_pll_user",
"ffac_top0_bus0_pll_div2"};
-PNAME(mout_top0_half_bus1_pll_p) = {"mout_top0_bus1_pll",
+PNAME(mout_top0_bus1_pll_half_p) = {"mout_top0_bus1_pll_user",
"ffac_top0_bus1_pll_div2"};
-PNAME(mout_top0_half_cc_pll_p) = {"mout_top0_cc_pll",
+PNAME(mout_top0_cc_pll_half_p) = {"mout_top0_cc_pll_user",
"ffac_top0_cc_pll_div2"};
-PNAME(mout_top0_half_mfc_pll_p) = {"mout_top0_mfc_pll",
+PNAME(mout_top0_mfc_pll_half_p) = {"mout_top0_mfc_pll_user",
"ffac_top0_mfc_pll_div2"};
-PNAME(mout_top0_group1) = {"mout_top0_half_bus0_pll",
- "mout_top0_half_bus1_pll", "mout_top0_half_cc_pll",
- "mout_top0_half_mfc_pll"};
+PNAME(mout_top0_group1) = {"mout_top0_bus0_pll_half",
+ "mout_top0_bus1_pll_half", "mout_top0_cc_pll_half",
+ "mout_top0_mfc_pll_half"};
PNAME(mout_top0_group3) = {"ioclk_audiocdclk0",
"ioclk_audiocdclk1", "ioclk_spdif_extclk",
- "mout_top0_aud_pll", "mout_top0_half_bus0_pll",
- "mout_top0_half_bus1_pll"};
-PNAME(mout_top0_group4) = {"ioclk_audiocdclk1", "mout_top0_aud_pll",
- "mout_top0_half_bus0_pll", "mout_top0_half_bus1_pll"};
+ "mout_top0_aud_pll_user", "mout_top0_bus0_pll_half",
+ "mout_top0_bus1_pll_half"};
+PNAME(mout_top0_group4) = {"ioclk_audiocdclk1", "mout_top0_aud_pll_user",
+ "mout_top0_bus0_pll_half", "mout_top0_bus1_pll_half"};
static unsigned long top0_clk_regs[] __initdata = {
MUX_SEL_TOP00,
@@ -244,19 +276,24 @@
};
static struct samsung_mux_clock top0_mux_clks[] __initdata = {
- MUX(0, "mout_top0_aud_pll", mout_aud_pll_p, MUX_SEL_TOP00, 0, 1),
- MUX(0, "mout_top0_mfc_pll", mout_mfc_pll_p, MUX_SEL_TOP00, 4, 1),
- MUX(0, "mout_top0_cc_pll", mout_cc_pll_p, MUX_SEL_TOP00, 8, 1),
- MUX(0, "mout_top0_bus1_pll", mout_bus1_pll_p, MUX_SEL_TOP00, 12, 1),
- MUX(0, "mout_top0_bus0_pll", mout_bus0_pll_p, MUX_SEL_TOP00, 16, 1),
+ MUX(0, "mout_top0_aud_pll_user", mout_top0_aud_pll_user_p,
+ MUX_SEL_TOP00, 0, 1),
+ MUX(0, "mout_top0_mfc_pll_user", mout_top0_mfc_pll_user_p,
+ MUX_SEL_TOP00, 4, 1),
+ MUX(0, "mout_top0_cc_pll_user", mout_top0_cc_pll_user_p,
+ MUX_SEL_TOP00, 8, 1),
+ MUX(0, "mout_top0_bus1_pll_user", mout_top0_bus1_pll_user_p,
+ MUX_SEL_TOP00, 12, 1),
+ MUX(0, "mout_top0_bus0_pll_user", mout_top0_bus0_pll_user_p,
+ MUX_SEL_TOP00, 16, 1),
- MUX(0, "mout_top0_half_mfc_pll", mout_top0_half_mfc_pll_p,
+ MUX(0, "mout_top0_mfc_pll_half", mout_top0_mfc_pll_half_p,
MUX_SEL_TOP01, 4, 1),
- MUX(0, "mout_top0_half_cc_pll", mout_top0_half_cc_pll_p,
+ MUX(0, "mout_top0_cc_pll_half", mout_top0_cc_pll_half_p,
MUX_SEL_TOP01, 8, 1),
- MUX(0, "mout_top0_half_bus1_pll", mout_top0_half_bus1_pll_p,
+ MUX(0, "mout_top0_bus1_pll_half", mout_top0_bus1_pll_half_p,
MUX_SEL_TOP01, 12, 1),
- MUX(0, "mout_top0_half_bus0_pll", mout_top0_half_bus0_pll_p,
+ MUX(0, "mout_top0_bus0_pll_half", mout_top0_bus0_pll_half_p,
MUX_SEL_TOP01, 16, 1),
MUX(0, "mout_aclk_peric1_66", mout_top0_group1, MUX_SEL_TOP03, 12, 2),
@@ -302,6 +339,11 @@
};
static struct samsung_gate_clock top0_gate_clks[] __initdata = {
+ GATE(CLK_ACLK_PERIC0_66, "aclk_peric0_66", "dout_aclk_peric0_66",
+ ENABLE_ACLK_TOP03, 20, CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_ACLK_PERIC1_66, "aclk_peric1_66", "dout_aclk_peric1_66",
+ ENABLE_ACLK_TOP03, 12, CLK_SET_RATE_PARENT, 0),
+
GATE(CLK_SCLK_SPDIF, "sclk_spdif", "dout_sclk_spdif",
ENABLE_SCLK_TOP0_PERIC0, 4, CLK_SET_RATE_PARENT, 0),
GATE(CLK_SCLK_PCM1, "sclk_pcm1", "dout_sclk_pcm1",
@@ -331,10 +373,12 @@
};
static struct samsung_fixed_factor_clock top0_fixed_factor_clks[] __initdata = {
- FFACTOR(0, "ffac_top0_bus0_pll_div2", "mout_top0_bus0_pll", 1, 2, 0),
- FFACTOR(0, "ffac_top0_bus1_pll_div2", "mout_top0_bus1_pll", 1, 2, 0),
- FFACTOR(0, "ffac_top0_cc_pll_div2", "mout_top0_cc_pll", 1, 2, 0),
- FFACTOR(0, "ffac_top0_mfc_pll_div2", "mout_top0_mfc_pll", 1, 2, 0),
+ FFACTOR(0, "ffac_top0_bus0_pll_div2", "mout_top0_bus0_pll_user",
+ 1, 2, 0),
+ FFACTOR(0, "ffac_top0_bus1_pll_div2", "mout_top0_bus1_pll_user",
+ 1, 2, 0),
+ FFACTOR(0, "ffac_top0_cc_pll_div2", "mout_top0_cc_pll_user", 1, 2, 0),
+ FFACTOR(0, "ffac_top0_mfc_pll_div2", "mout_top0_mfc_pll_user", 1, 2, 0),
};
static struct samsung_cmu_info top0_cmu_info __initdata = {
@@ -365,31 +409,34 @@
#define MUX_SEL_TOP13 0x020C
#define MUX_SEL_TOP1_FSYS0 0x0224
#define MUX_SEL_TOP1_FSYS1 0x0228
+#define MUX_SEL_TOP1_FSYS11 0x022C
#define DIV_TOP13 0x060C
#define DIV_TOP1_FSYS0 0x0624
#define DIV_TOP1_FSYS1 0x0628
+#define DIV_TOP1_FSYS11 0x062C
#define ENABLE_ACLK_TOP13 0x080C
#define ENABLE_SCLK_TOP1_FSYS0 0x0A24
#define ENABLE_SCLK_TOP1_FSYS1 0x0A28
+#define ENABLE_SCLK_TOP1_FSYS11 0x0A2C
/* List of parent clocks for Muxes in CMU_TOP1 */
-PNAME(mout_top1_bus0_pll_p) = { "fin_pll", "dout_sclk_bus0_pll" };
-PNAME(mout_top1_bus1_pll_p) = { "fin_pll", "dout_sclk_bus1_pll_b" };
-PNAME(mout_top1_cc_pll_p) = { "fin_pll", "dout_sclk_cc_pll_b" };
-PNAME(mout_top1_mfc_pll_p) = { "fin_pll", "dout_sclk_mfc_pll_b" };
+PNAME(mout_top1_bus0_pll_user_p) = { "fin_pll", "sclk_bus0_pll_b" };
+PNAME(mout_top1_bus1_pll_user_p) = { "fin_pll", "sclk_bus1_pll_b" };
+PNAME(mout_top1_cc_pll_user_p) = { "fin_pll", "sclk_cc_pll_b" };
+PNAME(mout_top1_mfc_pll_user_p) = { "fin_pll", "sclk_mfc_pll_b" };
-PNAME(mout_top1_half_bus0_pll_p) = {"mout_top1_bus0_pll",
+PNAME(mout_top1_bus0_pll_half_p) = {"mout_top1_bus0_pll_user",
"ffac_top1_bus0_pll_div2"};
-PNAME(mout_top1_half_bus1_pll_p) = {"mout_top1_bus1_pll",
+PNAME(mout_top1_bus1_pll_half_p) = {"mout_top1_bus1_pll_user",
"ffac_top1_bus1_pll_div2"};
-PNAME(mout_top1_half_cc_pll_p) = {"mout_top1_cc_pll",
+PNAME(mout_top1_cc_pll_half_p) = {"mout_top1_cc_pll_user",
"ffac_top1_cc_pll_div2"};
-PNAME(mout_top1_half_mfc_pll_p) = {"mout_top1_mfc_pll",
+PNAME(mout_top1_mfc_pll_half_p) = {"mout_top1_mfc_pll_user",
"ffac_top1_mfc_pll_div2"};
-PNAME(mout_top1_group1) = {"mout_top1_half_bus0_pll",
- "mout_top1_half_bus1_pll", "mout_top1_half_cc_pll",
- "mout_top1_half_mfc_pll"};
+PNAME(mout_top1_group1) = {"mout_top1_bus0_pll_half",
+ "mout_top1_bus1_pll_half", "mout_top1_cc_pll_half",
+ "mout_top1_mfc_pll_half"};
static unsigned long top1_clk_regs[] __initdata = {
MUX_SEL_TOP10,
@@ -397,40 +444,54 @@
MUX_SEL_TOP13,
MUX_SEL_TOP1_FSYS0,
MUX_SEL_TOP1_FSYS1,
+ MUX_SEL_TOP1_FSYS11,
DIV_TOP13,
DIV_TOP1_FSYS0,
DIV_TOP1_FSYS1,
+ DIV_TOP1_FSYS11,
ENABLE_ACLK_TOP13,
ENABLE_SCLK_TOP1_FSYS0,
ENABLE_SCLK_TOP1_FSYS1,
+ ENABLE_SCLK_TOP1_FSYS11,
};
static struct samsung_mux_clock top1_mux_clks[] __initdata = {
- MUX(0, "mout_top1_mfc_pll", mout_top1_mfc_pll_p, MUX_SEL_TOP10, 4, 1),
- MUX(0, "mout_top1_cc_pll", mout_top1_cc_pll_p, MUX_SEL_TOP10, 8, 1),
- MUX(0, "mout_top1_bus1_pll", mout_top1_bus1_pll_p,
+ MUX(0, "mout_top1_mfc_pll_user", mout_top1_mfc_pll_user_p,
+ MUX_SEL_TOP10, 4, 1),
+ MUX(0, "mout_top1_cc_pll_user", mout_top1_cc_pll_user_p,
+ MUX_SEL_TOP10, 8, 1),
+ MUX(0, "mout_top1_bus1_pll_user", mout_top1_bus1_pll_user_p,
MUX_SEL_TOP10, 12, 1),
- MUX(0, "mout_top1_bus0_pll", mout_top1_bus0_pll_p,
+ MUX(0, "mout_top1_bus0_pll_user", mout_top1_bus0_pll_user_p,
MUX_SEL_TOP10, 16, 1),
- MUX(0, "mout_top1_half_mfc_pll", mout_top1_half_mfc_pll_p,
+ MUX(0, "mout_top1_mfc_pll_half", mout_top1_mfc_pll_half_p,
MUX_SEL_TOP11, 4, 1),
- MUX(0, "mout_top1_half_cc_pll", mout_top1_half_cc_pll_p,
+ MUX(0, "mout_top1_cc_pll_half", mout_top1_cc_pll_half_p,
MUX_SEL_TOP11, 8, 1),
- MUX(0, "mout_top1_half_bus1_pll", mout_top1_half_bus1_pll_p,
+ MUX(0, "mout_top1_bus1_pll_half", mout_top1_bus1_pll_half_p,
MUX_SEL_TOP11, 12, 1),
- MUX(0, "mout_top1_half_bus0_pll", mout_top1_half_bus0_pll_p,
+ MUX(0, "mout_top1_bus0_pll_half", mout_top1_bus0_pll_half_p,
MUX_SEL_TOP11, 16, 1),
MUX(0, "mout_aclk_fsys1_200", mout_top1_group1, MUX_SEL_TOP13, 24, 2),
MUX(0, "mout_aclk_fsys0_200", mout_top1_group1, MUX_SEL_TOP13, 28, 2),
- MUX(0, "mout_sclk_mmc2", mout_top1_group1, MUX_SEL_TOP1_FSYS0, 24, 2),
+ MUX(0, "mout_sclk_phy_fsys0_26m", mout_top1_group1,
+ MUX_SEL_TOP1_FSYS0, 0, 2),
+ MUX(0, "mout_sclk_mmc2", mout_top1_group1, MUX_SEL_TOP1_FSYS0, 16, 2),
MUX(0, "mout_sclk_usbdrd300", mout_top1_group1,
MUX_SEL_TOP1_FSYS0, 28, 2),
- MUX(0, "mout_sclk_mmc1", mout_top1_group1, MUX_SEL_TOP1_FSYS1, 24, 2),
- MUX(0, "mout_sclk_mmc0", mout_top1_group1, MUX_SEL_TOP1_FSYS1, 28, 2),
+ MUX(0, "mout_sclk_phy_fsys1", mout_top1_group1,
+ MUX_SEL_TOP1_FSYS1, 0, 2),
+ MUX(0, "mout_sclk_ufsunipro20", mout_top1_group1,
+ MUX_SEL_TOP1_FSYS1, 16, 2),
+
+ MUX(0, "mout_sclk_mmc1", mout_top1_group1, MUX_SEL_TOP1_FSYS11, 0, 2),
+ MUX(0, "mout_sclk_mmc0", mout_top1_group1, MUX_SEL_TOP1_FSYS11, 12, 2),
+ MUX(0, "mout_sclk_phy_fsys1_26m", mout_top1_group1,
+ MUX_SEL_TOP1_FSYS11, 24, 2),
};
static struct samsung_div_clock top1_div_clks[] __initdata = {
@@ -439,34 +500,61 @@
DIV(DOUT_ACLK_FSYS0_200, "dout_aclk_fsys0_200", "mout_aclk_fsys0_200",
DIV_TOP13, 28, 4),
+ DIV(DOUT_SCLK_PHY_FSYS1, "dout_sclk_phy_fsys1",
+ "mout_sclk_phy_fsys1", DIV_TOP1_FSYS1, 0, 6),
+
+ DIV(DOUT_SCLK_UFSUNIPRO20, "dout_sclk_ufsunipro20",
+ "mout_sclk_ufsunipro20",
+ DIV_TOP1_FSYS1, 16, 6),
+
DIV(DOUT_SCLK_MMC2, "dout_sclk_mmc2", "mout_sclk_mmc2",
- DIV_TOP1_FSYS0, 24, 4),
+ DIV_TOP1_FSYS0, 16, 10),
DIV(0, "dout_sclk_usbdrd300", "mout_sclk_usbdrd300",
DIV_TOP1_FSYS0, 28, 4),
DIV(DOUT_SCLK_MMC1, "dout_sclk_mmc1", "mout_sclk_mmc1",
- DIV_TOP1_FSYS1, 24, 4),
+ DIV_TOP1_FSYS11, 0, 10),
DIV(DOUT_SCLK_MMC0, "dout_sclk_mmc0", "mout_sclk_mmc0",
- DIV_TOP1_FSYS1, 28, 4),
+ DIV_TOP1_FSYS11, 12, 10),
+
+ DIV(DOUT_SCLK_PHY_FSYS1_26M, "dout_sclk_phy_fsys1_26m",
+ "mout_sclk_phy_fsys1_26m", DIV_TOP1_FSYS11, 24, 6),
};
static struct samsung_gate_clock top1_gate_clks[] __initdata = {
GATE(CLK_SCLK_MMC2, "sclk_mmc2", "dout_sclk_mmc2",
- ENABLE_SCLK_TOP1_FSYS0, 24, CLK_SET_RATE_PARENT, 0),
+ ENABLE_SCLK_TOP1_FSYS0, 16, CLK_SET_RATE_PARENT, 0),
GATE(0, "sclk_usbdrd300", "dout_sclk_usbdrd300",
ENABLE_SCLK_TOP1_FSYS0, 28, 0, 0),
+ GATE(CLK_SCLK_PHY_FSYS1, "sclk_phy_fsys1", "dout_sclk_phy_fsys1",
+ ENABLE_SCLK_TOP1_FSYS1, 0, CLK_SET_RATE_PARENT, 0),
+
+ GATE(CLK_SCLK_UFSUNIPRO20, "sclk_ufsunipro20", "dout_sclk_ufsunipro20",
+ ENABLE_SCLK_TOP1_FSYS1, 16, CLK_SET_RATE_PARENT, 0),
+
GATE(CLK_SCLK_MMC1, "sclk_mmc1", "dout_sclk_mmc1",
- ENABLE_SCLK_TOP1_FSYS1, 24, CLK_SET_RATE_PARENT, 0),
+ ENABLE_SCLK_TOP1_FSYS11, 0, CLK_SET_RATE_PARENT, 0),
GATE(CLK_SCLK_MMC0, "sclk_mmc0", "dout_sclk_mmc0",
- ENABLE_SCLK_TOP1_FSYS1, 28, CLK_SET_RATE_PARENT, 0),
+ ENABLE_SCLK_TOP1_FSYS11, 12, CLK_SET_RATE_PARENT, 0),
+
+ GATE(CLK_ACLK_FSYS0_200, "aclk_fsys0_200", "dout_aclk_fsys0_200",
+ ENABLE_ACLK_TOP13, 28, CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_ACLK_FSYS1_200, "aclk_fsys1_200", "dout_aclk_fsys1_200",
+ ENABLE_ACLK_TOP13, 24, CLK_SET_RATE_PARENT, 0),
+
+ GATE(CLK_SCLK_PHY_FSYS1_26M, "sclk_phy_fsys1_26m",
+ "dout_sclk_phy_fsys1_26m", ENABLE_SCLK_TOP1_FSYS11,
+ 24, CLK_SET_RATE_PARENT, 0),
};
static struct samsung_fixed_factor_clock top1_fixed_factor_clks[] __initdata = {
- FFACTOR(0, "ffac_top1_bus0_pll_div2", "mout_top1_bus0_pll", 1, 2, 0),
- FFACTOR(0, "ffac_top1_bus1_pll_div2", "mout_top1_bus1_pll", 1, 2, 0),
- FFACTOR(0, "ffac_top1_cc_pll_div2", "mout_top1_cc_pll", 1, 2, 0),
- FFACTOR(0, "ffac_top1_mfc_pll_div2", "mout_top1_mfc_pll", 1, 2, 0),
+ FFACTOR(0, "ffac_top1_bus0_pll_div2", "mout_top1_bus0_pll_user",
+ 1, 2, 0),
+ FFACTOR(0, "ffac_top1_bus1_pll_div2", "mout_top1_bus1_pll_user",
+ 1, 2, 0),
+ FFACTOR(0, "ffac_top1_cc_pll_div2", "mout_top1_cc_pll_user", 1, 2, 0),
+ FFACTOR(0, "ffac_top1_mfc_pll_div2", "mout_top1_mfc_pll_user", 1, 2, 0),
};
static struct samsung_cmu_info top1_cmu_info __initdata = {
@@ -501,7 +589,7 @@
/*
* List of parent clocks for Muxes in CMU_CCORE
*/
-PNAME(mout_aclk_ccore_133_p) = { "fin_pll", "dout_aclk_ccore_133" };
+PNAME(mout_aclk_ccore_133_user_p) = { "fin_pll", "aclk_ccore_133" };
static unsigned long ccore_clk_regs[] __initdata = {
MUX_SEL_CCORE,
@@ -509,7 +597,7 @@
};
static struct samsung_mux_clock ccore_mux_clks[] __initdata = {
- MUX(0, "mout_aclk_ccore_133_user", mout_aclk_ccore_133_p,
+ MUX(0, "mout_aclk_ccore_133_user", mout_aclk_ccore_133_user_p,
MUX_SEL_CCORE, 1, 1),
};
@@ -542,8 +630,8 @@
#define ENABLE_SCLK_PERIC0 0x0A00
/* List of parent clocks for Muxes in CMU_PERIC0 */
-PNAME(mout_aclk_peric0_66_p) = { "fin_pll", "dout_aclk_peric0_66" };
-PNAME(mout_sclk_uart0_p) = { "fin_pll", "sclk_uart0" };
+PNAME(mout_aclk_peric0_66_user_p) = { "fin_pll", "aclk_peric0_66" };
+PNAME(mout_sclk_uart0_user_p) = { "fin_pll", "sclk_uart0" };
static unsigned long peric0_clk_regs[] __initdata = {
MUX_SEL_PERIC0,
@@ -552,9 +640,9 @@
};
static struct samsung_mux_clock peric0_mux_clks[] __initdata = {
- MUX(0, "mout_aclk_peric0_66_user", mout_aclk_peric0_66_p,
+ MUX(0, "mout_aclk_peric0_66_user", mout_aclk_peric0_66_user_p,
MUX_SEL_PERIC0, 0, 1),
- MUX(0, "mout_sclk_uart0_user", mout_sclk_uart0_p,
+ MUX(0, "mout_sclk_uart0_user", mout_sclk_uart0_user_p,
MUX_SEL_PERIC0, 16, 1),
};
@@ -611,15 +699,15 @@
exynos7_clk_peric0_init);
/* List of parent clocks for Muxes in CMU_PERIC1 */
-PNAME(mout_aclk_peric1_66_p) = { "fin_pll", "dout_aclk_peric1_66" };
-PNAME(mout_sclk_uart1_p) = { "fin_pll", "sclk_uart1" };
-PNAME(mout_sclk_uart2_p) = { "fin_pll", "sclk_uart2" };
-PNAME(mout_sclk_uart3_p) = { "fin_pll", "sclk_uart3" };
-PNAME(mout_sclk_spi0_p) = { "fin_pll", "sclk_spi0" };
-PNAME(mout_sclk_spi1_p) = { "fin_pll", "sclk_spi1" };
-PNAME(mout_sclk_spi2_p) = { "fin_pll", "sclk_spi2" };
-PNAME(mout_sclk_spi3_p) = { "fin_pll", "sclk_spi3" };
-PNAME(mout_sclk_spi4_p) = { "fin_pll", "sclk_spi4" };
+PNAME(mout_aclk_peric1_66_user_p) = { "fin_pll", "aclk_peric1_66" };
+PNAME(mout_sclk_uart1_user_p) = { "fin_pll", "sclk_uart1" };
+PNAME(mout_sclk_uart2_user_p) = { "fin_pll", "sclk_uart2" };
+PNAME(mout_sclk_uart3_user_p) = { "fin_pll", "sclk_uart3" };
+PNAME(mout_sclk_spi0_user_p) = { "fin_pll", "sclk_spi0" };
+PNAME(mout_sclk_spi1_user_p) = { "fin_pll", "sclk_spi1" };
+PNAME(mout_sclk_spi2_user_p) = { "fin_pll", "sclk_spi2" };
+PNAME(mout_sclk_spi3_user_p) = { "fin_pll", "sclk_spi3" };
+PNAME(mout_sclk_spi4_user_p) = { "fin_pll", "sclk_spi4" };
static unsigned long peric1_clk_regs[] __initdata = {
MUX_SEL_PERIC10,
@@ -630,24 +718,24 @@
};
static struct samsung_mux_clock peric1_mux_clks[] __initdata = {
- MUX(0, "mout_aclk_peric1_66_user", mout_aclk_peric1_66_p,
+ MUX(0, "mout_aclk_peric1_66_user", mout_aclk_peric1_66_user_p,
MUX_SEL_PERIC10, 0, 1),
- MUX_F(0, "mout_sclk_spi0_user", mout_sclk_spi0_p,
+ MUX_F(0, "mout_sclk_spi0_user", mout_sclk_spi0_user_p,
MUX_SEL_PERIC11, 0, 1, CLK_SET_RATE_PARENT, 0),
- MUX_F(0, "mout_sclk_spi1_user", mout_sclk_spi1_p,
+ MUX_F(0, "mout_sclk_spi1_user", mout_sclk_spi1_user_p,
MUX_SEL_PERIC11, 4, 1, CLK_SET_RATE_PARENT, 0),
- MUX_F(0, "mout_sclk_spi2_user", mout_sclk_spi2_p,
+ MUX_F(0, "mout_sclk_spi2_user", mout_sclk_spi2_user_p,
MUX_SEL_PERIC11, 8, 1, CLK_SET_RATE_PARENT, 0),
- MUX_F(0, "mout_sclk_spi3_user", mout_sclk_spi3_p,
+ MUX_F(0, "mout_sclk_spi3_user", mout_sclk_spi3_user_p,
MUX_SEL_PERIC11, 12, 1, CLK_SET_RATE_PARENT, 0),
- MUX_F(0, "mout_sclk_spi4_user", mout_sclk_spi4_p,
+ MUX_F(0, "mout_sclk_spi4_user", mout_sclk_spi4_user_p,
MUX_SEL_PERIC11, 16, 1, CLK_SET_RATE_PARENT, 0),
- MUX(0, "mout_sclk_uart1_user", mout_sclk_uart1_p,
+ MUX(0, "mout_sclk_uart1_user", mout_sclk_uart1_user_p,
MUX_SEL_PERIC11, 20, 1),
- MUX(0, "mout_sclk_uart2_user", mout_sclk_uart2_p,
+ MUX(0, "mout_sclk_uart2_user", mout_sclk_uart2_user_p,
MUX_SEL_PERIC11, 24, 1),
- MUX(0, "mout_sclk_uart3_user", mout_sclk_uart3_p,
+ MUX(0, "mout_sclk_uart3_user", mout_sclk_uart3_user_p,
MUX_SEL_PERIC11, 28, 1),
};
@@ -735,7 +823,7 @@
#define ENABLE_SCLK_PERIS_SECURE_CHIPID 0x0A10
/* List of parent clocks for Muxes in CMU_PERIS */
-PNAME(mout_aclk_peris_66_p) = { "fin_pll", "dout_aclk_peris_66" };
+PNAME(mout_aclk_peris_66_user_p) = { "fin_pll", "aclk_peris_66" };
static unsigned long peris_clk_regs[] __initdata = {
MUX_SEL_PERIS,
@@ -747,7 +835,7 @@
static struct samsung_mux_clock peris_mux_clks[] __initdata = {
MUX(0, "mout_aclk_peris_66_user",
- mout_aclk_peris_66_p, MUX_SEL_PERIS, 0, 1),
+ mout_aclk_peris_66_user_p, MUX_SEL_PERIS, 0, 1),
};
static struct samsung_gate_clock peris_gate_clks[] __initdata = {
@@ -795,17 +883,17 @@
/*
* List of parent clocks for Muxes in CMU_FSYS0
*/
-PNAME(mout_aclk_fsys0_200_p) = { "fin_pll", "dout_aclk_fsys0_200" };
-PNAME(mout_sclk_mmc2_p) = { "fin_pll", "sclk_mmc2" };
+PNAME(mout_aclk_fsys0_200_user_p) = { "fin_pll", "aclk_fsys0_200" };
+PNAME(mout_sclk_mmc2_user_p) = { "fin_pll", "sclk_mmc2" };
-PNAME(mout_sclk_usbdrd300_p) = { "fin_pll", "sclk_usbdrd300" };
-PNAME(mout_phyclk_usbdrd300_udrd30_phyclk_p) = { "fin_pll",
+PNAME(mout_sclk_usbdrd300_user_p) = { "fin_pll", "sclk_usbdrd300" };
+PNAME(mout_phyclk_usbdrd300_udrd30_phyclk_user_p) = { "fin_pll",
"phyclk_usbdrd300_udrd30_phyclock" };
-PNAME(mout_phyclk_usbdrd300_udrd30_pipe_pclk_p) = { "fin_pll",
+PNAME(mout_phyclk_usbdrd300_udrd30_pipe_pclk_user_p) = { "fin_pll",
"phyclk_usbdrd300_udrd30_pipe_pclk" };
/* fixed rate clocks used in the FSYS0 block */
-struct samsung_fixed_rate_clock fixed_rate_clks_fsys0[] __initdata = {
+static struct samsung_fixed_rate_clock fixed_rate_clks_fsys0[] __initdata = {
FRATE(0, "phyclk_usbdrd300_udrd30_phyclock", NULL,
CLK_IS_ROOT, 60000000),
FRATE(0, "phyclk_usbdrd300_udrd30_pipe_pclk", NULL,
@@ -824,29 +912,30 @@
};
static struct samsung_mux_clock fsys0_mux_clks[] __initdata = {
- MUX(0, "mout_aclk_fsys0_200_user", mout_aclk_fsys0_200_p,
+ MUX(0, "mout_aclk_fsys0_200_user", mout_aclk_fsys0_200_user_p,
MUX_SEL_FSYS00, 24, 1),
- MUX(0, "mout_sclk_mmc2_user", mout_sclk_mmc2_p, MUX_SEL_FSYS01, 24, 1),
- MUX(0, "mout_sclk_usbdrd300_user", mout_sclk_usbdrd300_p,
+ MUX(0, "mout_sclk_mmc2_user", mout_sclk_mmc2_user_p,
+ MUX_SEL_FSYS01, 24, 1),
+ MUX(0, "mout_sclk_usbdrd300_user", mout_sclk_usbdrd300_user_p,
MUX_SEL_FSYS01, 28, 1),
MUX(0, "mout_phyclk_usbdrd300_udrd30_pipe_pclk_user",
- mout_phyclk_usbdrd300_udrd30_pipe_pclk_p,
+ mout_phyclk_usbdrd300_udrd30_pipe_pclk_user_p,
MUX_SEL_FSYS02, 24, 1),
MUX(0, "mout_phyclk_usbdrd300_udrd30_phyclk_user",
- mout_phyclk_usbdrd300_udrd30_phyclk_p,
+ mout_phyclk_usbdrd300_udrd30_phyclk_user_p,
MUX_SEL_FSYS02, 28, 1),
};
static struct samsung_gate_clock fsys0_gate_clks[] __initdata = {
- GATE(ACLK_AXIUS_USBDRD30X_FSYS0X, "aclk_axius_usbdrd30x_fsys0x",
- "mout_aclk_fsys0_200_user",
- ENABLE_ACLK_FSYS00, 19, 0, 0),
GATE(ACLK_PDMA1, "aclk_pdma1", "mout_aclk_fsys0_200_user",
ENABLE_ACLK_FSYS00, 3, 0, 0),
GATE(ACLK_PDMA0, "aclk_pdma0", "mout_aclk_fsys0_200_user",
ENABLE_ACLK_FSYS00, 4, 0, 0),
+ GATE(ACLK_AXIUS_USBDRD30X_FSYS0X, "aclk_axius_usbdrd30x_fsys0x",
+ "mout_aclk_fsys0_200_user",
+ ENABLE_ACLK_FSYS00, 19, 0, 0),
GATE(ACLK_USBDRD300, "aclk_usbdrd300", "mout_aclk_fsys0_200_user",
ENABLE_ACLK_FSYS01, 29, 0, 0),
@@ -874,11 +963,13 @@
};
static struct samsung_cmu_info fsys0_cmu_info __initdata = {
+ .fixed_clks = fixed_rate_clks_fsys0,
+ .nr_fixed_clks = ARRAY_SIZE(fixed_rate_clks_fsys0),
.mux_clks = fsys0_mux_clks,
.nr_mux_clks = ARRAY_SIZE(fsys0_mux_clks),
.gate_clks = fsys0_gate_clks,
.nr_gate_clks = ARRAY_SIZE(fsys0_gate_clks),
- .nr_clk_ids = TOP1_NR_CLK,
+ .nr_clk_ids = FSYS0_NR_CLK,
.clk_regs = fsys0_clk_regs,
.nr_clk_regs = ARRAY_SIZE(fsys0_clk_regs),
};
@@ -894,42 +985,122 @@
/* Register Offset definitions for CMU_FSYS1 (0x156E0000) */
#define MUX_SEL_FSYS10 0x0200
#define MUX_SEL_FSYS11 0x0204
+#define MUX_SEL_FSYS12 0x0208
+#define DIV_FSYS1 0x0600
#define ENABLE_ACLK_FSYS1 0x0800
+#define ENABLE_PCLK_FSYS1 0x0900
+#define ENABLE_SCLK_FSYS11 0x0A04
+#define ENABLE_SCLK_FSYS12 0x0A08
+#define ENABLE_SCLK_FSYS13 0x0A0C
/*
* List of parent clocks for Muxes in CMU_FSYS1
*/
-PNAME(mout_aclk_fsys1_200_p) = { "fin_pll", "dout_aclk_fsys1_200" };
-PNAME(mout_sclk_mmc0_p) = { "fin_pll", "sclk_mmc0" };
-PNAME(mout_sclk_mmc1_p) = { "fin_pll", "sclk_mmc1" };
+PNAME(mout_aclk_fsys1_200_user_p) = { "fin_pll", "aclk_fsys1_200" };
+PNAME(mout_fsys1_group_p) = { "fin_pll", "fin_pll_26m",
+ "sclk_phy_fsys1_26m" };
+PNAME(mout_sclk_mmc0_user_p) = { "fin_pll", "sclk_mmc0" };
+PNAME(mout_sclk_mmc1_user_p) = { "fin_pll", "sclk_mmc1" };
+PNAME(mout_sclk_ufsunipro20_user_p) = { "fin_pll", "sclk_ufsunipro20" };
+PNAME(mout_phyclk_ufs20_tx0_user_p) = { "fin_pll", "phyclk_ufs20_tx0_symbol" };
+PNAME(mout_phyclk_ufs20_rx0_user_p) = { "fin_pll", "phyclk_ufs20_rx0_symbol" };
+PNAME(mout_phyclk_ufs20_rx1_user_p) = { "fin_pll", "phyclk_ufs20_rx1_symbol" };
+
+/* fixed rate clocks used in the FSYS1 block */
+static struct samsung_fixed_rate_clock fixed_rate_clks_fsys1[] __initdata = {
+ FRATE(PHYCLK_UFS20_TX0_SYMBOL, "phyclk_ufs20_tx0_symbol", NULL,
+ CLK_IS_ROOT, 300000000),
+ FRATE(PHYCLK_UFS20_RX0_SYMBOL, "phyclk_ufs20_rx0_symbol", NULL,
+ CLK_IS_ROOT, 300000000),
+ FRATE(PHYCLK_UFS20_RX1_SYMBOL, "phyclk_ufs20_rx1_symbol", NULL,
+ CLK_IS_ROOT, 300000000),
+};
static unsigned long fsys1_clk_regs[] __initdata = {
MUX_SEL_FSYS10,
MUX_SEL_FSYS11,
+ MUX_SEL_FSYS12,
+ DIV_FSYS1,
ENABLE_ACLK_FSYS1,
+ ENABLE_PCLK_FSYS1,
+ ENABLE_SCLK_FSYS11,
+ ENABLE_SCLK_FSYS12,
+ ENABLE_SCLK_FSYS13,
};
static struct samsung_mux_clock fsys1_mux_clks[] __initdata = {
- MUX(0, "mout_aclk_fsys1_200_user", mout_aclk_fsys1_200_p,
+ MUX(MOUT_FSYS1_PHYCLK_SEL1, "mout_fsys1_phyclk_sel1",
+ mout_fsys1_group_p, MUX_SEL_FSYS10, 16, 2),
+ MUX(0, "mout_fsys1_phyclk_sel0", mout_fsys1_group_p,
+ MUX_SEL_FSYS10, 20, 2),
+ MUX(0, "mout_aclk_fsys1_200_user", mout_aclk_fsys1_200_user_p,
MUX_SEL_FSYS10, 28, 1),
- MUX(0, "mout_sclk_mmc1_user", mout_sclk_mmc1_p, MUX_SEL_FSYS11, 24, 1),
- MUX(0, "mout_sclk_mmc0_user", mout_sclk_mmc0_p, MUX_SEL_FSYS11, 28, 1),
+ MUX(0, "mout_sclk_mmc1_user", mout_sclk_mmc1_user_p,
+ MUX_SEL_FSYS11, 24, 1),
+ MUX(0, "mout_sclk_mmc0_user", mout_sclk_mmc0_user_p,
+ MUX_SEL_FSYS11, 28, 1),
+ MUX(0, "mout_sclk_ufsunipro20_user", mout_sclk_ufsunipro20_user_p,
+ MUX_SEL_FSYS11, 20, 1),
+
+ MUX(0, "mout_phyclk_ufs20_rx1_symbol_user",
+ mout_phyclk_ufs20_rx1_user_p, MUX_SEL_FSYS12, 16, 1),
+ MUX(0, "mout_phyclk_ufs20_rx0_symbol_user",
+ mout_phyclk_ufs20_rx0_user_p, MUX_SEL_FSYS12, 24, 1),
+ MUX(0, "mout_phyclk_ufs20_tx0_symbol_user",
+ mout_phyclk_ufs20_tx0_user_p, MUX_SEL_FSYS12, 28, 1),
+};
+
+static struct samsung_div_clock fsys1_div_clks[] __initdata = {
+ DIV(DOUT_PCLK_FSYS1, "dout_pclk_fsys1", "mout_aclk_fsys1_200_user",
+ DIV_FSYS1, 0, 2),
};
static struct samsung_gate_clock fsys1_gate_clks[] __initdata = {
+ GATE(SCLK_UFSUNIPRO20_USER, "sclk_ufsunipro20_user",
+ "mout_sclk_ufsunipro20_user",
+ ENABLE_SCLK_FSYS11, 20, 0, 0),
+
GATE(ACLK_MMC1, "aclk_mmc1", "mout_aclk_fsys1_200_user",
ENABLE_ACLK_FSYS1, 29, 0, 0),
GATE(ACLK_MMC0, "aclk_mmc0", "mout_aclk_fsys1_200_user",
ENABLE_ACLK_FSYS1, 30, 0, 0),
+
+ GATE(ACLK_UFS20_LINK, "aclk_ufs20_link", "dout_pclk_fsys1",
+ ENABLE_ACLK_FSYS1, 31, 0, 0),
+ GATE(PCLK_GPIO_FSYS1, "pclk_gpio_fsys1", "mout_aclk_fsys1_200_user",
+ ENABLE_PCLK_FSYS1, 30, 0, 0),
+
+ GATE(PHYCLK_UFS20_RX1_SYMBOL_USER, "phyclk_ufs20_rx1_symbol_user",
+ "mout_phyclk_ufs20_rx1_symbol_user",
+ ENABLE_SCLK_FSYS12, 16, 0, 0),
+ GATE(PHYCLK_UFS20_RX0_SYMBOL_USER, "phyclk_ufs20_rx0_symbol_user",
+ "mout_phyclk_ufs20_rx0_symbol_user",
+ ENABLE_SCLK_FSYS12, 24, 0, 0),
+ GATE(PHYCLK_UFS20_TX0_SYMBOL_USER, "phyclk_ufs20_tx0_symbol_user",
+ "mout_phyclk_ufs20_tx0_symbol_user",
+ ENABLE_SCLK_FSYS12, 28, 0, 0),
+
+ GATE(OSCCLK_PHY_CLKOUT_EMBEDDED_COMBO_PHY,
+ "oscclk_phy_clkout_embedded_combo_phy",
+ "fin_pll",
+ ENABLE_SCLK_FSYS12, 4, CLK_IGNORE_UNUSED, 0),
+
+ GATE(SCLK_COMBO_PHY_EMBEDDED_26M, "sclk_combo_phy_embedded_26m",
+ "mout_fsys1_phyclk_sel1",
+ ENABLE_SCLK_FSYS13, 24, CLK_IGNORE_UNUSED, 0),
};
static struct samsung_cmu_info fsys1_cmu_info __initdata = {
+ .fixed_clks = fixed_rate_clks_fsys1,
+ .nr_fixed_clks = ARRAY_SIZE(fixed_rate_clks_fsys1),
.mux_clks = fsys1_mux_clks,
.nr_mux_clks = ARRAY_SIZE(fsys1_mux_clks),
+ .div_clks = fsys1_div_clks,
+ .nr_div_clks = ARRAY_SIZE(fsys1_div_clks),
.gate_clks = fsys1_gate_clks,
.nr_gate_clks = ARRAY_SIZE(fsys1_gate_clks),
- .nr_clk_ids = TOP1_NR_CLK,
+ .nr_clk_ids = FSYS1_NR_CLK,
.clk_regs = fsys1_clk_regs,
.nr_clk_regs = ARRAY_SIZE(fsys1_clk_regs),
};
diff --git a/drivers/clk/sirf/clk-atlas7.c b/drivers/clk/sirf/clk-atlas7.c
index a98e21f..957aae6 100644
--- a/drivers/clk/sirf/clk-atlas7.c
+++ b/drivers/clk/sirf/clk-atlas7.c
@@ -205,18 +205,11 @@
#define SIRFSOC_CLKC_LEAF_CLK_EN7_SET 0x0530
#define SIRFSOC_CLKC_LEAF_CLK_EN8_SET 0x0548
-
-static void __iomem *sirfsoc_clk_vbase;
-static struct clk_onecell_data clk_data;
-
-static const struct clk_div_table pll_div_table[] = {
- { .val = 0, .div = 1 },
- { .val = 1, .div = 2 },
- { .val = 2, .div = 4 },
- { .val = 3, .div = 8 },
- { .val = 4, .div = 16 },
- { .val = 5, .div = 32 },
-};
+#define SIRFSOC_NOC_CLK_IDLEREQ_SET 0x02D0
+#define SIRFSOC_NOC_CLK_IDLEREQ_CLR 0x02D4
+#define SIRFSOC_NOC_CLK_SLVRDY_SET 0x02E8
+#define SIRFSOC_NOC_CLK_SLVRDY_CLR 0x02EC
+#define SIRFSOC_NOC_CLK_IDLE_STATUS 0x02F4
struct clk_pll {
struct clk_hw hw;
@@ -231,10 +224,18 @@
};
#define to_dtoclk(_hw) container_of(_hw, struct clk_dto, hw)
+enum clk_unit_type {
+ CLK_UNIT_NOC_OTHER,
+ CLK_UNIT_NOC_CLOCK,
+ CLK_UNIT_NOC_SOCKET,
+};
+
struct clk_unit {
struct clk_hw hw;
u16 regofs;
u16 bit;
+ u32 type;
+ u8 idle_bit;
spinlock_t *lock;
};
#define to_unitclk(_hw) container_of(_hw, struct clk_unit, hw)
@@ -272,6 +273,8 @@
unsigned long flags;
u32 regofs;
u8 bit;
+ u32 type;
+ u8 idle_bit;
spinlock_t *lock;
};
@@ -284,6 +287,18 @@
spinlock_t *lock;
};
+static void __iomem *sirfsoc_clk_vbase;
+static struct clk_onecell_data clk_data;
+
+static const struct clk_div_table pll_div_table[] = {
+ { .val = 0, .div = 1 },
+ { .val = 1, .div = 2 },
+ { .val = 2, .div = 4 },
+ { .val = 3, .div = 8 },
+ { .val = 4, .div = 16 },
+ { .val = 5, .div = 32 },
+};
+
static DEFINE_SPINLOCK(cpupll_ctrl1_lock);
static DEFINE_SPINLOCK(mempll_ctrl1_lock);
static DEFINE_SPINLOCK(sys0pll_ctrl1_lock);
@@ -1040,148 +1055,148 @@
/* new unit should add start from the tail of list */
static struct atlas7_unit_init_data unit_list[] __initdata = {
/* unit_name, parent_name, flags, regofs, bit, lock */
- { 0, "audmscm_kas", "kas_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 0, &root0_gate_lock },
- { 1, "gnssm_gnss", "gnss_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 1, &root0_gate_lock },
- { 2, "gpum_gpu", "gpu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 2, &root0_gate_lock },
- { 3, "mediam_g2d", "g2d_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 3, &root0_gate_lock },
- { 4, "mediam_jpenc", "jpenc_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 4, &root0_gate_lock },
- { 5, "vdifm_disp0", "disp0_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 5, &root0_gate_lock },
- { 6, "vdifm_disp1", "disp1_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 6, &root0_gate_lock },
- { 7, "audmscm_i2s", "i2s_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 8, &root0_gate_lock },
- { 8, "audmscm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 11, &root0_gate_lock },
- { 9, "vdifm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 12, &root0_gate_lock },
- { 10, "gnssm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 13, &root0_gate_lock },
- { 11, "mediam_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 14, &root0_gate_lock },
- { 12, "btm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 17, &root0_gate_lock },
- { 13, "mediam_sdphy01", "sdphy01_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 18, &root0_gate_lock },
- { 14, "vdifm_sdphy23", "sdphy23_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 19, &root0_gate_lock },
- { 15, "vdifm_sdphy45", "sdphy45_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 20, &root0_gate_lock },
- { 16, "vdifm_sdphy67", "sdphy67_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 21, &root0_gate_lock },
- { 17, "audmscm_xin", "xin", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 22, &root0_gate_lock },
- { 18, "mediam_nand", "nand_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 27, &root0_gate_lock },
- { 19, "gnssm_sec", "sec_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 28, &root0_gate_lock },
- { 20, "cpum_cpu", "cpu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 29, &root0_gate_lock },
- { 21, "gnssm_xin", "xin", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 30, &root0_gate_lock },
- { 22, "vdifm_vip", "vip_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 31, &root0_gate_lock },
- { 23, "btm_btss", "btss_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 0, &root1_gate_lock },
- { 24, "mediam_usbphy", "usbphy_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 1, &root1_gate_lock },
- { 25, "rtcm_kas", "kas_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 2, &root1_gate_lock },
- { 26, "audmscm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 3, &root1_gate_lock },
- { 27, "vdifm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 4, &root1_gate_lock },
- { 28, "gnssm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 5, &root1_gate_lock },
- { 29, "mediam_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 6, &root1_gate_lock },
- { 30, "cpum_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 8, &root1_gate_lock },
- { 31, "gpum_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 9, &root1_gate_lock },
- { 32, "audmscm_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 11, &root1_gate_lock },
- { 33, "vdifm_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 12, &root1_gate_lock },
- { 34, "gnssm_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 13, &root1_gate_lock },
- { 35, "mediam_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 14, &root1_gate_lock },
- { 36, "ddrm_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 15, &root1_gate_lock },
- { 37, "cpum_tpiu", "tpiu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 16, &root1_gate_lock },
- { 38, "gpum_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 17, &root1_gate_lock },
- { 39, "gnssm_rgmii", "rgmii_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 20, &root1_gate_lock },
- { 40, "mediam_vdec", "vdec_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 21, &root1_gate_lock },
- { 41, "gpum_sdr", "sdr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 22, &root1_gate_lock },
- { 42, "vdifm_deint", "deint_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 23, &root1_gate_lock },
- { 43, "gnssm_can", "can_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 26, &root1_gate_lock },
- { 44, "mediam_usb", "usb_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 28, &root1_gate_lock },
- { 45, "gnssm_gmac", "gmac_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 29, &root1_gate_lock },
- { 46, "cvd_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 0, &leaf1_gate_lock },
- { 47, "timer_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 1, &leaf1_gate_lock },
- { 48, "pulse_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 2, &leaf1_gate_lock },
- { 49, "tsc_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 3, &leaf1_gate_lock },
- { 50, "tsc_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 21, &leaf1_gate_lock },
- { 51, "ioctop_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 4, &leaf1_gate_lock },
- { 52, "rsc_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 5, &leaf1_gate_lock },
- { 53, "dvm_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 6, &leaf1_gate_lock },
- { 54, "lvds_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 7, &leaf1_gate_lock },
- { 55, "kas_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 8, &leaf1_gate_lock },
- { 56, "ac97_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 9, &leaf1_gate_lock },
- { 57, "usp0_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 10, &leaf1_gate_lock },
- { 58, "usp1_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 11, &leaf1_gate_lock },
- { 59, "usp2_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 12, &leaf1_gate_lock },
- { 60, "dmac2_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 13, &leaf1_gate_lock },
- { 61, "dmac3_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 14, &leaf1_gate_lock },
- { 62, "audioif_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 15, &leaf1_gate_lock },
- { 63, "i2s1_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 17, &leaf1_gate_lock },
- { 64, "thaudmscm_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 22, &leaf1_gate_lock },
- { 65, "analogtest_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 23, &leaf1_gate_lock },
- { 66, "sys2pci_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 0, &leaf2_gate_lock },
- { 67, "pciarb_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 1, &leaf2_gate_lock },
- { 68, "pcicopy_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 2, &leaf2_gate_lock },
- { 69, "rom_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 3, &leaf2_gate_lock },
- { 70, "sdio23_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 4, &leaf2_gate_lock },
- { 71, "sdio45_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 5, &leaf2_gate_lock },
- { 72, "sdio67_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 6, &leaf2_gate_lock },
- { 73, "vip1_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 7, &leaf2_gate_lock },
- { 74, "vip1_vip", "vdifm_vip", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 16, &leaf2_gate_lock },
- { 75, "sdio23_sdphy23", "vdifm_sdphy23", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 8, &leaf2_gate_lock },
- { 76, "sdio45_sdphy45", "vdifm_sdphy45", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 9, &leaf2_gate_lock },
- { 77, "sdio67_sdphy67", "vdifm_sdphy67", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 10, &leaf2_gate_lock },
- { 78, "vpp0_disp0", "vdifm_disp0", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 11, &leaf2_gate_lock },
- { 79, "lcd0_disp0", "vdifm_disp0", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 12, &leaf2_gate_lock },
- { 80, "vpp1_disp1", "vdifm_disp1", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 13, &leaf2_gate_lock },
- { 81, "lcd1_disp1", "vdifm_disp1", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 14, &leaf2_gate_lock },
- { 82, "dcu_deint", "vdifm_deint", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 15, &leaf2_gate_lock },
- { 83, "vdifm_dapa_r_nocr", "vdifm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 17, &leaf2_gate_lock },
- { 84, "gpio1_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 18, &leaf2_gate_lock },
- { 85, "thvdifm_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 19, &leaf2_gate_lock },
- { 86, "gmac_rgmii", "gnssm_rgmii", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 0, &leaf3_gate_lock },
- { 87, "gmac_gmac", "gnssm_gmac", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 1, &leaf3_gate_lock },
- { 88, "uart1_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 2, &leaf3_gate_lock },
- { 89, "dmac0_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 3, &leaf3_gate_lock },
- { 90, "uart0_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 4, &leaf3_gate_lock },
- { 91, "uart2_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 5, &leaf3_gate_lock },
- { 92, "uart3_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 6, &leaf3_gate_lock },
- { 93, "uart4_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 7, &leaf3_gate_lock },
- { 94, "uart5_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 8, &leaf3_gate_lock },
- { 95, "spi1_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 9, &leaf3_gate_lock },
- { 96, "gnss_gnss", "gnssm_gnss", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 10, &leaf3_gate_lock },
- { 97, "canbus1_can", "gnssm_can", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 12, &leaf3_gate_lock },
- { 98, "ccsec_sec", "gnssm_sec", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 15, &leaf3_gate_lock },
- { 99, "ccpub_sec", "gnssm_sec", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 16, &leaf3_gate_lock },
- { 100, "gnssm_dapa_r_nocr", "gnssm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 13, &leaf3_gate_lock },
- { 101, "thgnssm_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 14, &leaf3_gate_lock },
- { 102, "media_vdec", "mediam_vdec", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 0, &leaf4_gate_lock },
- { 103, "media_jpenc", "mediam_jpenc", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 1, &leaf4_gate_lock },
- { 104, "g2d_g2d", "mediam_g2d", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 2, &leaf4_gate_lock },
- { 105, "i2c0_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 3, &leaf4_gate_lock },
- { 106, "i2c1_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 4, &leaf4_gate_lock },
- { 107, "gpio0_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 5, &leaf4_gate_lock },
- { 108, "nand_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 6, &leaf4_gate_lock },
- { 109, "sdio01_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 7, &leaf4_gate_lock },
- { 110, "sys2pci2_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 8, &leaf4_gate_lock },
- { 111, "sdio01_sdphy01", "mediam_sdphy01", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 9, &leaf4_gate_lock },
- { 112, "nand_nand", "mediam_nand", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 10, &leaf4_gate_lock },
- { 113, "usb0_usb", "mediam_usb", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 11, &leaf4_gate_lock },
- { 114, "usb1_usb", "mediam_usb", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 12, &leaf4_gate_lock },
- { 115, "usbphy0_usbphy", "mediam_usbphy", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 13, &leaf4_gate_lock },
- { 116, "usbphy1_usbphy", "mediam_usbphy", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 14, &leaf4_gate_lock },
- { 117, "thmediam_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 15, &leaf4_gate_lock },
- { 118, "memc_mem", "mempll_clk1", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 0, &leaf5_gate_lock },
- { 119, "dapa_mem", "mempll_clk1", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 1, &leaf5_gate_lock },
- { 120, "nocddrm_nocr", "ddrm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 2, &leaf5_gate_lock },
- { 121, "thddrm_nocr", "ddrm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 3, &leaf5_gate_lock },
- { 122, "spram1_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 0, &leaf6_gate_lock },
- { 123, "spram2_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 1, &leaf6_gate_lock },
- { 124, "coresight_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 2, &leaf6_gate_lock },
- { 125, "coresight_tpiu", "cpum_tpiu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 3, &leaf6_gate_lock },
- { 126, "graphic_gpu", "gpum_gpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 0, &leaf7_gate_lock },
- { 127, "vss_sdr", "gpum_sdr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 1, &leaf7_gate_lock },
- { 128, "thgpum_nocr", "gpum_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 2, &leaf7_gate_lock },
- { 129, "a7ca_btss", "btm_btss", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 1, &leaf8_gate_lock },
- { 130, "dmac4_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 2, &leaf8_gate_lock },
- { 131, "uart6_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 3, &leaf8_gate_lock },
- { 132, "usp3_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 4, &leaf8_gate_lock },
- { 133, "a7ca_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 5, &leaf8_gate_lock },
- { 134, "noc_btm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 6, &leaf8_gate_lock },
- { 135, "thbtm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 7, &leaf8_gate_lock },
- { 136, "btslow", "xinw_fixdiv_btslow", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 25, &root1_gate_lock },
- { 137, "a7ca_btslow", "btslow", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 0, &leaf8_gate_lock },
- { 138, "pwm_io", "io_mux", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 0, &leaf0_gate_lock },
- { 139, "pwm_xin", "xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 1, &leaf0_gate_lock },
- { 140, "pwm_xinw", "xinw", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 2, &leaf0_gate_lock },
- { 141, "thcgum_sys", "sys_mux", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 3, &leaf0_gate_lock },
+ { 0, "audmscm_kas", "kas_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 0, 0, 0, &root0_gate_lock },
+ { 1, "gnssm_gnss", "gnss_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 1, 0, 0, &root0_gate_lock },
+ { 2, "gpum_gpu", "gpu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 2, 0, 0, &root0_gate_lock },
+ { 3, "mediam_g2d", "g2d_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 3, 0, 0, &root0_gate_lock },
+ { 4, "mediam_jpenc", "jpenc_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 4, 0, 0, &root0_gate_lock },
+ { 5, "vdifm_disp0", "disp0_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 5, 0, 0, &root0_gate_lock },
+ { 6, "vdifm_disp1", "disp1_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 6, 0, 0, &root0_gate_lock },
+ { 7, "audmscm_i2s", "i2s_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 8, 0, 0, &root0_gate_lock },
+ { 8, "audmscm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 11, 0, 0, &root0_gate_lock },
+ { 9, "vdifm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 12, 0, 0, &root0_gate_lock },
+ { 10, "gnssm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 13, 0, 0, &root0_gate_lock },
+ { 11, "mediam_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 14, 0, 0, &root0_gate_lock },
+ { 12, "btm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 17, 0, 0, &root0_gate_lock },
+ { 13, "mediam_sdphy01", "sdphy01_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 18, 0, 0, &root0_gate_lock },
+ { 14, "vdifm_sdphy23", "sdphy23_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 19, 0, 0, &root0_gate_lock },
+ { 15, "vdifm_sdphy45", "sdphy45_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 20, 0, 0, &root0_gate_lock },
+ { 16, "vdifm_sdphy67", "sdphy67_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 21, 0, 0, &root0_gate_lock },
+ { 17, "audmscm_xin", "xin", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 22, 0, 0, &root0_gate_lock },
+ { 18, "mediam_nand", "nand_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 27, 0, 0, &root0_gate_lock },
+ { 19, "gnssm_sec", "sec_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 28, 0, 0, &root0_gate_lock },
+ { 20, "cpum_cpu", "cpu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 29, 0, 0, &root0_gate_lock },
+ { 21, "gnssm_xin", "xin", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 30, 0, 0, &root0_gate_lock },
+ { 22, "vdifm_vip", "vip_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 31, 0, 0, &root0_gate_lock },
+ { 23, "btm_btss", "btss_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 0, 0, 0, &root1_gate_lock },
+ { 24, "mediam_usbphy", "usbphy_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 1, 0, 0, &root1_gate_lock },
+ { 25, "rtcm_kas", "kas_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 2, 0, 0, &root1_gate_lock },
+ { 26, "audmscm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 3, 0, 0, &root1_gate_lock },
+ { 27, "vdifm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 4, 0, 0, &root1_gate_lock },
+ { 28, "gnssm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 5, 0, 0, &root1_gate_lock },
+ { 29, "mediam_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 6, 0, 0, &root1_gate_lock },
+ { 30, "cpum_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 8, 0, 0, &root1_gate_lock },
+ { 31, "gpum_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 9, 0, 0, &root1_gate_lock },
+ { 32, "audmscm_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 11, 0, 0, &root1_gate_lock },
+ { 33, "vdifm_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 12, 0, 0, &root1_gate_lock },
+ { 34, "gnssm_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 13, 0, 0, &root1_gate_lock },
+ { 35, "mediam_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 14, 0, 0, &root1_gate_lock },
+ { 36, "ddrm_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 15, 0, 0, &root1_gate_lock },
+ { 37, "cpum_tpiu", "tpiu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 16, 0, 0, &root1_gate_lock },
+ { 38, "gpum_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 17, 0, 0, &root1_gate_lock },
+ { 39, "gnssm_rgmii", "rgmii_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 20, 0, 0, &root1_gate_lock },
+ { 40, "mediam_vdec", "vdec_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 21, 0, 0, &root1_gate_lock },
+ { 41, "gpum_sdr", "sdr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 22, 0, 0, &root1_gate_lock },
+ { 42, "vdifm_deint", "deint_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 23, 0, 0, &root1_gate_lock },
+ { 43, "gnssm_can", "can_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 26, 0, 0, &root1_gate_lock },
+ { 44, "mediam_usb", "usb_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 28, 0, 0, &root1_gate_lock },
+ { 45, "gnssm_gmac", "gmac_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 29, 0, 0, &root1_gate_lock },
+ { 46, "cvd_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 0, CLK_UNIT_NOC_CLOCK, 4, &leaf1_gate_lock },
+ { 47, "timer_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 1, 0, 0, &leaf1_gate_lock },
+ { 48, "pulse_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 2, 0, 0, &leaf1_gate_lock },
+ { 49, "tsc_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 3, 0, 0, &leaf1_gate_lock },
+ { 50, "tsc_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 21, 0, 0, &leaf1_gate_lock },
+ { 51, "ioctop_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 4, 0, 0, &leaf1_gate_lock },
+ { 52, "rsc_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 5, 0, 0, &leaf1_gate_lock },
+ { 53, "dvm_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 6, CLK_UNIT_NOC_SOCKET, 7, &leaf1_gate_lock },
+ { 54, "lvds_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 7, CLK_UNIT_NOC_SOCKET, 8, &leaf1_gate_lock },
+ { 55, "kas_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 8, CLK_UNIT_NOC_CLOCK, 2, &leaf1_gate_lock },
+ { 56, "ac97_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 9, 0, 0, &leaf1_gate_lock },
+ { 57, "usp0_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 10, CLK_UNIT_NOC_SOCKET, 4, &leaf1_gate_lock },
+ { 58, "usp1_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 11, CLK_UNIT_NOC_SOCKET, 5, &leaf1_gate_lock },
+ { 59, "usp2_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 12, CLK_UNIT_NOC_SOCKET, 6, &leaf1_gate_lock },
+ { 60, "dmac2_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 13, CLK_UNIT_NOC_SOCKET, 1, &leaf1_gate_lock },
+ { 61, "dmac3_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 14, CLK_UNIT_NOC_SOCKET, 2, &leaf1_gate_lock },
+ { 62, "audioif_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 15, CLK_UNIT_NOC_SOCKET, 0, &leaf1_gate_lock },
+ { 63, "i2s1_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 17, CLK_UNIT_NOC_CLOCK, 2, &leaf1_gate_lock },
+ { 64, "thaudmscm_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 22, 0, 0, &leaf1_gate_lock },
+ { 65, "analogtest_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 23, 0, 0, &leaf1_gate_lock },
+ { 66, "sys2pci_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 0, CLK_UNIT_NOC_CLOCK, 20, &leaf2_gate_lock },
+ { 67, "pciarb_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 1, 0, 0, &leaf2_gate_lock },
+ { 68, "pcicopy_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 2, 0, 0, &leaf2_gate_lock },
+ { 69, "rom_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 3, 0, 0, &leaf2_gate_lock },
+ { 70, "sdio23_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 4, 0, 0, &leaf2_gate_lock },
+ { 71, "sdio45_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 5, 0, 0, &leaf2_gate_lock },
+ { 72, "sdio67_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 6, 0, 0, &leaf2_gate_lock },
+ { 73, "vip1_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 7, 0, 0, &leaf2_gate_lock },
+ { 74, "vip1_vip", "vdifm_vip", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 16, CLK_UNIT_NOC_CLOCK, 21, &leaf2_gate_lock },
+ { 75, "sdio23_sdphy23", "vdifm_sdphy23", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 8, 0, 0, &leaf2_gate_lock },
+ { 76, "sdio45_sdphy45", "vdifm_sdphy45", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 9, 0, 0, &leaf2_gate_lock },
+ { 77, "sdio67_sdphy67", "vdifm_sdphy67", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 10, 0, 0, &leaf2_gate_lock },
+ { 78, "vpp0_disp0", "vdifm_disp0", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 11, CLK_UNIT_NOC_CLOCK, 22, &leaf2_gate_lock },
+ { 79, "lcd0_disp0", "vdifm_disp0", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 12, CLK_UNIT_NOC_CLOCK, 18, &leaf2_gate_lock },
+ { 80, "vpp1_disp1", "vdifm_disp1", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 13, CLK_UNIT_NOC_CLOCK, 23, &leaf2_gate_lock },
+ { 81, "lcd1_disp1", "vdifm_disp1", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 14, CLK_UNIT_NOC_CLOCK, 19, &leaf2_gate_lock },
+ { 82, "dcu_deint", "vdifm_deint", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 15, CLK_UNIT_NOC_CLOCK, 17, &leaf2_gate_lock },
+ { 83, "vdifm_dapa_r_nocr", "vdifm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 17, 0, 0, &leaf2_gate_lock },
+ { 84, "gpio1_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 18, 0, 0, &leaf2_gate_lock },
+ { 85, "thvdifm_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 19, 0, 0, &leaf2_gate_lock },
+ { 86, "gmac_rgmii", "gnssm_rgmii", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 0, 0, 0, &leaf3_gate_lock },
+ { 87, "gmac_gmac", "gnssm_gmac", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 1, CLK_UNIT_NOC_CLOCK, 10, &leaf3_gate_lock },
+ { 88, "uart1_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 2, CLK_UNIT_NOC_SOCKET, 14, &leaf3_gate_lock },
+ { 89, "dmac0_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 3, CLK_UNIT_NOC_SOCKET, 11, &leaf3_gate_lock },
+ { 90, "uart0_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 4, CLK_UNIT_NOC_SOCKET, 13, &leaf3_gate_lock },
+ { 91, "uart2_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 5, CLK_UNIT_NOC_SOCKET, 15, &leaf3_gate_lock },
+ { 92, "uart3_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 6, CLK_UNIT_NOC_SOCKET, 16, &leaf3_gate_lock },
+ { 93, "uart4_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 7, CLK_UNIT_NOC_SOCKET, 17, &leaf3_gate_lock },
+ { 94, "uart5_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 8, CLK_UNIT_NOC_SOCKET, 18, &leaf3_gate_lock },
+ { 95, "spi1_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 9, CLK_UNIT_NOC_SOCKET, 12, &leaf3_gate_lock },
+ { 96, "gnss_gnss", "gnssm_gnss", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 10, 0, 0, &leaf3_gate_lock },
+ { 97, "canbus1_can", "gnssm_can", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 12, CLK_UNIT_NOC_CLOCK, 7, &leaf3_gate_lock },
+ { 98, "ccsec_sec", "gnssm_sec", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 15, CLK_UNIT_NOC_CLOCK, 9, &leaf3_gate_lock },
+ { 99, "ccpub_sec", "gnssm_sec", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 16, CLK_UNIT_NOC_CLOCK, 8, &leaf3_gate_lock },
+ { 100, "gnssm_dapa_r_nocr", "gnssm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 13, 0, 0, &leaf3_gate_lock },
+ { 101, "thgnssm_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 14, 0, 0, &leaf3_gate_lock },
+ { 102, "media_vdec", "mediam_vdec", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 0, CLK_UNIT_NOC_CLOCK, 3, &leaf4_gate_lock },
+ { 103, "media_jpenc", "mediam_jpenc", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 1, CLK_UNIT_NOC_CLOCK, 1, &leaf4_gate_lock },
+ { 104, "g2d_g2d", "mediam_g2d", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 2, CLK_UNIT_NOC_CLOCK, 12, &leaf4_gate_lock },
+ { 105, "i2c0_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 3, CLK_UNIT_NOC_SOCKET, 21, &leaf4_gate_lock },
+ { 106, "i2c1_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 4, CLK_UNIT_NOC_SOCKET, 20, &leaf4_gate_lock },
+ { 107, "gpio0_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 5, CLK_UNIT_NOC_SOCKET, 19, &leaf4_gate_lock },
+ { 108, "nand_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 6, 0, 0, &leaf4_gate_lock },
+ { 109, "sdio01_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 7, 0, 0, &leaf4_gate_lock },
+ { 110, "sys2pci2_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 8, CLK_UNIT_NOC_CLOCK, 13, &leaf4_gate_lock },
+ { 111, "sdio01_sdphy01", "mediam_sdphy01", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 9, 0, 0, &leaf4_gate_lock },
+ { 112, "nand_nand", "mediam_nand", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 10, CLK_UNIT_NOC_CLOCK, 14, &leaf4_gate_lock },
+ { 113, "usb0_usb", "mediam_usb", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 11, CLK_UNIT_NOC_CLOCK, 15, &leaf4_gate_lock },
+ { 114, "usb1_usb", "mediam_usb", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 12, CLK_UNIT_NOC_CLOCK, 16, &leaf4_gate_lock },
+ { 115, "usbphy0_usbphy", "mediam_usbphy", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 13, 0, 0, &leaf4_gate_lock },
+ { 116, "usbphy1_usbphy", "mediam_usbphy", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 14, 0, 0, &leaf4_gate_lock },
+ { 117, "thmediam_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 15, 0, 0, &leaf4_gate_lock },
+ { 118, "memc_mem", "mempll_clk1", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 0, 0, 0, &leaf5_gate_lock },
+ { 119, "dapa_mem", "mempll_clk1", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 1, 0, 0, &leaf5_gate_lock },
+ { 120, "nocddrm_nocr", "ddrm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 2, 0, 0, &leaf5_gate_lock },
+ { 121, "thddrm_nocr", "ddrm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 3, 0, 0, &leaf5_gate_lock },
+ { 122, "spram1_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 0, CLK_UNIT_NOC_SOCKET, 9, &leaf6_gate_lock },
+ { 123, "spram2_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 1, CLK_UNIT_NOC_SOCKET, 10, &leaf6_gate_lock },
+ { 124, "coresight_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 2, 0, 0, &leaf6_gate_lock },
+ { 125, "coresight_tpiu", "cpum_tpiu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 3, 0, 0, &leaf6_gate_lock },
+ { 126, "graphic_gpu", "gpum_gpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 0, CLK_UNIT_NOC_CLOCK, 0, &leaf7_gate_lock },
+ { 127, "vss_sdr", "gpum_sdr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 1, CLK_UNIT_NOC_CLOCK, 11, &leaf7_gate_lock },
+ { 128, "thgpum_nocr", "gpum_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 2, 0, 0, &leaf7_gate_lock },
+ { 129, "a7ca_btss", "btm_btss", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 1, 0, 0, &leaf8_gate_lock },
+ { 130, "dmac4_io", "a7ca_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 2, 0, 0, &leaf8_gate_lock },
+ { 131, "uart6_io", "dmac4_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 3, 0, 0, &leaf8_gate_lock },
+ { 132, "usp3_io", "dmac4_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 4, 0, 0, &leaf8_gate_lock },
+ { 133, "a7ca_io", "noc_btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 5, 0, 0, &leaf8_gate_lock },
+ { 134, "noc_btm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 6, 0, 0, &leaf8_gate_lock },
+ { 135, "thbtm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 7, 0, 0, &leaf8_gate_lock },
+ { 136, "btslow", "xinw_fixdiv_btslow", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 25, 0, 0, &root1_gate_lock },
+ { 137, "a7ca_btslow", "btslow", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 0, 0, 0, &leaf8_gate_lock },
+ { 138, "pwm_io", "io_mux", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 0, 0, 0, &leaf0_gate_lock },
+ { 139, "pwm_xin", "xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 1, 0, 0, &leaf0_gate_lock },
+ { 140, "pwm_xinw", "xinw", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 2, 0, 0, &leaf0_gate_lock },
+ { 141, "thcgum_sys", "sys_mux", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 3, 0, 0, &leaf0_gate_lock },
};
static struct clk *atlas7_clks[ARRAY_SIZE(unit_list) + ARRAY_SIZE(mux_list)];
@@ -1206,20 +1221,44 @@
spin_lock_irqsave(clk->lock, flags);
clkc_writel(BIT(clk->bit), reg);
+ if (clk->type == CLK_UNIT_NOC_CLOCK)
+ clkc_writel(BIT(clk->idle_bit), SIRFSOC_NOC_CLK_IDLEREQ_CLR);
+ else if (clk->type == CLK_UNIT_NOC_SOCKET)
+ clkc_writel(BIT(clk->idle_bit), SIRFSOC_NOC_CLK_SLVRDY_SET);
+
spin_unlock_irqrestore(clk->lock, flags);
return 0;
}
static void unit_clk_disable(struct clk_hw *hw)
{
- u32 reg;
+ u32 reg;
+ u32 i = 0;
struct clk_unit *clk = to_unitclk(hw);
unsigned long flags;
reg = clk->regofs + SIRFSOC_CLKC_ROOT_CLK_EN0_CLR - SIRFSOC_CLKC_ROOT_CLK_EN0_SET;
-
spin_lock_irqsave(clk->lock, flags);
+ if (clk->type == CLK_UNIT_NOC_CLOCK) {
+ clkc_writel(BIT(clk->idle_bit), SIRFSOC_NOC_CLK_IDLEREQ_SET);
+ while (!(clkc_readl(SIRFSOC_NOC_CLK_IDLE_STATUS) &
+ BIT(clk->idle_bit)) && (i++ < 100)) {
+ cpu_relax();
+ udelay(10);
+ }
+
+ if (i == 100) {
+ pr_err("unit NoC Clock disconnect Error:timeout\n");
+ /*once timeout, undo idlereq by CLR*/
+ clkc_writel(BIT(clk->idle_bit), SIRFSOC_NOC_CLK_IDLEREQ_CLR);
+ goto err;
+ }
+
+ } else if (clk->type == CLK_UNIT_NOC_SOCKET)
+ clkc_writel(BIT(clk->idle_bit), SIRFSOC_NOC_CLK_SLVRDY_CLR);
+
clkc_writel(BIT(clk->bit), reg);
+err:
spin_unlock_irqrestore(clk->lock, flags);
}
@@ -1232,7 +1271,7 @@
static struct clk * __init
atlas7_unit_clk_register(struct device *dev, const char *name,
const char * const parent_name, unsigned long flags,
- u32 regofs, u8 bit, spinlock_t *lock)
+ u32 regofs, u8 bit, u32 type, u8 idle_bit, spinlock_t *lock)
{
struct clk *clk;
struct clk_unit *unit;
@@ -1251,6 +1290,9 @@
unit->hw.init = &init;
unit->regofs = regofs;
unit->bit = bit;
+
+ unit->type = type;
+ unit->idle_bit = idle_bit;
unit->lock = lock;
clk = clk_register(dev, &unit->hw);
@@ -1624,7 +1666,7 @@
for (i = 0; i < ARRAY_SIZE(unit_list); i++) {
unit = &unit_list[i];
atlas7_clks[i] = atlas7_unit_clk_register(NULL, unit->unit_name, unit->parent_name,
- unit->flags, unit->regofs, unit->bit, unit->lock);
+ unit->flags, unit->regofs, unit->bit, unit->type, unit->idle_bit, unit->lock);
BUG_ON(!atlas7_clks[i]);
}
diff --git a/drivers/clk/st/clk-flexgen.c b/drivers/clk/st/clk-flexgen.c
index bd355ee..24d9959 100644
--- a/drivers/clk/st/clk-flexgen.c
+++ b/drivers/clk/st/clk-flexgen.c
@@ -268,6 +268,7 @@
int num_parents, i;
spinlock_t *rlock = NULL;
unsigned long flex_flags = 0;
+ int ret;
pnode = of_get_parent(np);
if (!pnode)
@@ -285,13 +286,13 @@
if (!clk_data)
goto err;
- clk_data->clk_num = of_property_count_strings(np ,
- "clock-output-names");
- if (clk_data->clk_num <= 0) {
+ ret = of_property_count_strings(np, "clock-output-names");
+ if (ret <= 0) {
pr_err("%s: Failed to get number of output clocks (%d)",
__func__, clk_data->clk_num);
goto err;
}
+ clk_data->clk_num = ret;
clk_data->clks = kcalloc(clk_data->clk_num, sizeof(struct clk *),
GFP_KERNEL);
diff --git a/drivers/clk/sunxi/clk-sun6i-apb0-gates.c b/drivers/clk/sunxi/clk-sun6i-apb0-gates.c
index 64f3e46..23d042a 100644
--- a/drivers/clk/sunxi/clk-sun6i-apb0-gates.c
+++ b/drivers/clk/sunxi/clk-sun6i-apb0-gates.c
@@ -34,6 +34,7 @@
{ .compatible = "allwinner,sun8i-a23-apb0-gates-clk", .data = &sun8i_a23_apb0_gates },
{ /* sentinel */ }
};
+MODULE_DEVICE_TABLE(of, sun6i_a31_apb0_gates_clk_dt_ids);
static int sun6i_a31_apb0_gates_clk_probe(struct platform_device *pdev)
{
diff --git a/drivers/clk/sunxi/clk-sun6i-apb0.c b/drivers/clk/sunxi/clk-sun6i-apb0.c
index 7076360..e703e18 100644
--- a/drivers/clk/sunxi/clk-sun6i-apb0.c
+++ b/drivers/clk/sunxi/clk-sun6i-apb0.c
@@ -61,6 +61,7 @@
{ .compatible = "allwinner,sun6i-a31-apb0-clk" },
{ /* sentinel */ }
};
+MODULE_DEVICE_TABLE(of, sun6i_a31_apb0_clk_dt_ids);
static struct platform_driver sun6i_a31_apb0_clk_driver = {
.driver = {
diff --git a/drivers/clk/sunxi/clk-sun6i-ar100.c b/drivers/clk/sunxi/clk-sun6i-ar100.c
index 806fd01..2088768 100644
--- a/drivers/clk/sunxi/clk-sun6i-ar100.c
+++ b/drivers/clk/sunxi/clk-sun6i-ar100.c
@@ -219,6 +219,7 @@
{ .compatible = "allwinner,sun6i-a31-ar100-clk" },
{ /* sentinel */ }
};
+MODULE_DEVICE_TABLE(of, sun6i_a31_ar100_clk_dt_ids);
static struct platform_driver sun6i_a31_ar100_clk_driver = {
.driver = {
diff --git a/drivers/clk/sunxi/clk-sun8i-apb0.c b/drivers/clk/sunxi/clk-sun8i-apb0.c
index 155d002..7ae5d2c 100644
--- a/drivers/clk/sunxi/clk-sun8i-apb0.c
+++ b/drivers/clk/sunxi/clk-sun8i-apb0.c
@@ -52,6 +52,7 @@
{ .compatible = "allwinner,sun8i-a23-apb0-clk" },
{ /* sentinel */ }
};
+MODULE_DEVICE_TABLE(of, sun8i_a23_apb0_clk_dt_ids);
static struct platform_driver sun8i_a23_apb0_clk_driver = {
.driver = {
diff --git a/drivers/clk/sunxi/clk-sun9i-mmc.c b/drivers/clk/sunxi/clk-sun9i-mmc.c
index 3436a948..a9b1761 100644
--- a/drivers/clk/sunxi/clk-sun9i-mmc.c
+++ b/drivers/clk/sunxi/clk-sun9i-mmc.c
@@ -204,6 +204,7 @@
{ .compatible = "allwinner,sun9i-a80-mmc-config-clk" },
{ /* sentinel */ }
};
+MODULE_DEVICE_TABLE(of, sun9i_a80_mmc_config_clk_dt_ids);
static struct platform_driver sun9i_a80_mmc_config_clk_driver = {
.driver = {
diff --git a/drivers/clk/ti/clk-3xxx.c b/drivers/clk/ti/clk-3xxx.c
index 676ee8f..8831e1a 100644
--- a/drivers/clk/ti/clk-3xxx.c
+++ b/drivers/clk/ti/clk-3xxx.c
@@ -374,7 +374,6 @@
DT_CLK(NULL, "gpio2_ick", "gpio2_ick"),
DT_CLK(NULL, "wdt3_ick", "wdt3_ick"),
DT_CLK(NULL, "uart3_ick", "uart3_ick"),
- DT_CLK(NULL, "uart4_ick", "uart4_ick"),
DT_CLK(NULL, "gpt9_ick", "gpt9_ick"),
DT_CLK(NULL, "gpt8_ick", "gpt8_ick"),
DT_CLK(NULL, "gpt7_ick", "gpt7_ick"),
@@ -519,6 +518,7 @@
static struct ti_dt_clk omap36xx_clks[] = {
DT_CLK(NULL, "omap_192m_alwon_fck", "omap_192m_alwon_fck"),
DT_CLK(NULL, "uart4_fck", "uart4_fck"),
+ DT_CLK(NULL, "uart4_ick", "uart4_ick"),
{ .node_name = NULL },
};
diff --git a/drivers/clk/ti/clk-7xx.c b/drivers/clk/ti/clk-7xx.c
index 9b5b289..a911d7d 100644
--- a/drivers/clk/ti/clk-7xx.c
+++ b/drivers/clk/ti/clk-7xx.c
@@ -18,7 +18,6 @@
#include "clock.h"
-#define DRA7_DPLL_ABE_DEFFREQ 180633600
#define DRA7_DPLL_GMAC_DEFFREQ 1000000000
#define DRA7_DPLL_USB_DEFFREQ 960000000
@@ -313,27 +312,12 @@
int __init dra7xx_dt_clk_init(void)
{
int rc;
- struct clk *abe_dpll_mux, *sys_clkin2, *dpll_ck, *hdcp_ck;
+ struct clk *dpll_ck, *hdcp_ck;
ti_dt_clocks_register(dra7xx_clks);
omap2_clk_disable_autoidle_all();
- abe_dpll_mux = clk_get_sys(NULL, "abe_dpll_sys_clk_mux");
- sys_clkin2 = clk_get_sys(NULL, "sys_clkin2");
- dpll_ck = clk_get_sys(NULL, "dpll_abe_ck");
-
- rc = clk_set_parent(abe_dpll_mux, sys_clkin2);
- if (!rc)
- rc = clk_set_rate(dpll_ck, DRA7_DPLL_ABE_DEFFREQ);
- if (rc)
- pr_err("%s: failed to configure ABE DPLL!\n", __func__);
-
- dpll_ck = clk_get_sys(NULL, "dpll_abe_m2x2_ck");
- rc = clk_set_rate(dpll_ck, DRA7_DPLL_ABE_DEFFREQ * 2);
- if (rc)
- pr_err("%s: failed to configure ABE DPLL m2x2!\n", __func__);
-
dpll_ck = clk_get_sys(NULL, "dpll_gmac_ck");
rc = clk_set_rate(dpll_ck, DRA7_DPLL_GMAC_DEFFREQ);
if (rc)
diff --git a/drivers/clk/ti/clkt_dflt.c b/drivers/clk/ti/clkt_dflt.c
index 90d7d8a..1ddc288 100644
--- a/drivers/clk/ti/clkt_dflt.c
+++ b/drivers/clk/ti/clkt_dflt.c
@@ -222,7 +222,7 @@
}
}
- if (unlikely(!clk->enable_reg)) {
+ if (unlikely(IS_ERR(clk->enable_reg))) {
pr_err("%s: %s missing enable_reg\n", __func__,
clk_hw_get_name(hw));
ret = -EINVAL;
@@ -264,7 +264,7 @@
u32 v;
clk = to_clk_hw_omap(hw);
- if (!clk->enable_reg) {
+ if (IS_ERR(clk->enable_reg)) {
/*
* 'independent' here refers to a clock which is not
* controlled by its parent.
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index 06324f1..df3eddf 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -224,10 +224,6 @@
if (IS_ERR(d->clk) || !old)
goto out;
- /* Not requesting clock rates below 1.8432Mhz */
- if (baud < 115200)
- baud = 115200;
-
clk_disable_unprepare(d->clk);
rate = clk_round_rate(d->clk, baud * 16);
ret = clk_set_rate(d->clk, rate);
diff --git a/include/dt-bindings/clock/at91.h b/include/dt-bindings/clock/at91.h
index 0b4cb99..ab3ee24 100644
--- a/include/dt-bindings/clock/at91.h
+++ b/include/dt-bindings/clock/at91.h
@@ -18,5 +18,6 @@
#define AT91_PMC_MOSCSELS 16 /* Main Oscillator Selection */
#define AT91_PMC_MOSCRCS 17 /* Main On-Chip RC */
#define AT91_PMC_CFDEV 18 /* Clock Failure Detector Event */
+#define AT91_PMC_GCKRDY 24 /* Generated Clocks */
#endif
diff --git a/include/dt-bindings/clock/exynos7-clk.h b/include/dt-bindings/clock/exynos7-clk.h
index e33c75a..10c5586 100644
--- a/include/dt-bindings/clock/exynos7-clk.h
+++ b/include/dt-bindings/clock/exynos7-clk.h
@@ -21,7 +21,18 @@
#define ACLK_MSCL_532 8
#define DOUT_SCLK_AUD_PLL 9
#define FOUT_AUD_PLL 10
-#define TOPC_NR_CLK 11
+#define SCLK_AUD_PLL 11
+#define SCLK_MFC_PLL_B 12
+#define SCLK_MFC_PLL_A 13
+#define SCLK_BUS1_PLL_B 14
+#define SCLK_BUS1_PLL_A 15
+#define SCLK_BUS0_PLL_B 16
+#define SCLK_BUS0_PLL_A 17
+#define SCLK_CC_PLL_B 18
+#define SCLK_CC_PLL_A 19
+#define ACLK_CCORE_133 20
+#define ACLK_PERIS_66 21
+#define TOPC_NR_CLK 22
/* TOP0 */
#define DOUT_ACLK_PERIC1 1
@@ -38,7 +49,9 @@
#define CLK_SCLK_SPDIF 12
#define CLK_SCLK_PCM1 13
#define CLK_SCLK_I2S1 14
-#define TOP0_NR_CLK 15
+#define CLK_ACLK_PERIC0_66 15
+#define CLK_ACLK_PERIC1_66 16
+#define TOP0_NR_CLK 17
/* TOP1 */
#define DOUT_ACLK_FSYS1_200 1
@@ -49,7 +62,16 @@
#define CLK_SCLK_MMC2 6
#define CLK_SCLK_MMC1 7
#define CLK_SCLK_MMC0 8
-#define TOP1_NR_CLK 9
+#define CLK_ACLK_FSYS0_200 9
+#define CLK_ACLK_FSYS1_200 10
+#define CLK_SCLK_PHY_FSYS1 11
+#define CLK_SCLK_PHY_FSYS1_26M 12
+#define MOUT_SCLK_UFSUNIPRO20 13
+#define DOUT_SCLK_UFSUNIPRO20 14
+#define CLK_SCLK_UFSUNIPRO20 15
+#define DOUT_SCLK_PHY_FSYS1 16
+#define DOUT_SCLK_PHY_FSYS1_26M 17
+#define TOP1_NR_CLK 18
/* CCORE */
#define PCLK_RTC 1
@@ -124,7 +146,20 @@
/* FSYS1 */
#define ACLK_MMC1 1
#define ACLK_MMC0 2
-#define FSYS1_NR_CLK 3
+#define PHYCLK_UFS20_TX0_SYMBOL 3
+#define PHYCLK_UFS20_RX0_SYMBOL 4
+#define PHYCLK_UFS20_RX1_SYMBOL 5
+#define ACLK_UFS20_LINK 6
+#define SCLK_UFSUNIPRO20_USER 7
+#define PHYCLK_UFS20_RX1_SYMBOL_USER 8
+#define PHYCLK_UFS20_RX0_SYMBOL_USER 9
+#define PHYCLK_UFS20_TX0_SYMBOL_USER 10
+#define OSCCLK_PHY_CLKOUT_EMBEDDED_COMBO_PHY 11
+#define SCLK_COMBO_PHY_EMBEDDED_26M 12
+#define DOUT_PCLK_FSYS1 13
+#define PCLK_GPIO_FSYS1 14
+#define MOUT_FSYS1_PHYCLK_SEL1 15
+#define FSYS1_NR_CLK 16
/* MSCL */
#define USERMUX_ACLK_MSCL_532 1
diff --git a/include/dt-bindings/clock/qcom,gcc-apq8084.h b/include/dt-bindings/clock/qcom,gcc-apq8084.h
index 2c0da56..5aa7ebe 100644
--- a/include/dt-bindings/clock/qcom,gcc-apq8084.h
+++ b/include/dt-bindings/clock/qcom,gcc-apq8084.h
@@ -348,4 +348,10 @@
#define GCC_PCIE_1_PIPE_CLK 331
#define GCC_PCIE_1_SLV_AXI_CLK 332
+/* gdscs */
+#define USB_HS_HSIC_GDSC 0
+#define PCIE0_GDSC 1
+#define PCIE1_GDSC 2
+#define USB30_GDSC 3
+
#endif
diff --git a/include/dt-bindings/clock/qcom,gcc-msm8916.h b/include/dt-bindings/clock/qcom,gcc-msm8916.h
index e430f64..257e2fb 100644
--- a/include/dt-bindings/clock/qcom,gcc-msm8916.h
+++ b/include/dt-bindings/clock/qcom,gcc-msm8916.h
@@ -152,5 +152,35 @@
#define GCC_VENUS0_AHB_CLK 135
#define GCC_VENUS0_AXI_CLK 136
#define GCC_VENUS0_VCODEC0_CLK 137
+#define BIMC_DDR_CLK_SRC 138
+#define GCC_APSS_TCU_CLK 139
+#define GCC_GFX_TCU_CLK 140
+#define BIMC_GPU_CLK_SRC 141
+#define GCC_BIMC_GFX_CLK 142
+#define GCC_BIMC_GPU_CLK 143
+#define ULTAUDIO_LPAIF_PRI_I2S_CLK_SRC 144
+#define ULTAUDIO_LPAIF_SEC_I2S_CLK_SRC 145
+#define ULTAUDIO_LPAIF_AUX_I2S_CLK_SRC 146
+#define ULTAUDIO_XO_CLK_SRC 147
+#define ULTAUDIO_AHBFABRIC_CLK_SRC 148
+#define CODEC_DIGCODEC_CLK_SRC 149
+#define GCC_ULTAUDIO_PCNOC_MPORT_CLK 150
+#define GCC_ULTAUDIO_PCNOC_SWAY_CLK 151
+#define GCC_ULTAUDIO_AVSYNC_XO_CLK 152
+#define GCC_ULTAUDIO_STC_XO_CLK 153
+#define GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_CLK 154
+#define GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_LPM_CLK 155
+#define GCC_ULTAUDIO_LPAIF_PRI_I2S_CLK 156
+#define GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK 157
+#define GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK 158
+#define GCC_CODEC_DIGCODEC_CLK 159
+
+/* Indexes for GDSCs */
+#define BIMC_GDSC 0
+#define VENUS_GDSC 1
+#define MDSS_GDSC 2
+#define JPEG_GDSC 3
+#define VFE_GDSC 4
+#define OXILI_GDSC 5
#endif
diff --git a/include/dt-bindings/clock/qcom,gcc-msm8974.h b/include/dt-bindings/clock/qcom,gcc-msm8974.h
index 51e51c8..81d32f6 100644
--- a/include/dt-bindings/clock/qcom,gcc-msm8974.h
+++ b/include/dt-bindings/clock/qcom,gcc-msm8974.h
@@ -321,4 +321,7 @@
#define GCC_SDCC1_CDCCAL_SLEEP_CLK 304
#define GCC_SDCC1_CDCCAL_FF_CLK 305
+/* gdscs */
+#define USB_HS_HSIC_GDSC 0
+
#endif
diff --git a/include/dt-bindings/clock/qcom,mmcc-apq8084.h b/include/dt-bindings/clock/qcom,mmcc-apq8084.h
index d72b5b3..03861e3 100644
--- a/include/dt-bindings/clock/qcom,mmcc-apq8084.h
+++ b/include/dt-bindings/clock/qcom,mmcc-apq8084.h
@@ -180,4 +180,14 @@
#define VPU_SLEEP_CLK 163
#define VPU_VDP_CLK 164
+/* GDSCs */
+#define VENUS0_GDSC 0
+#define VENUS0_CORE0_GDSC 1
+#define VENUS0_CORE1_GDSC 2
+#define MDSS_GDSC 3
+#define CAMSS_JPEG_GDSC 4
+#define CAMSS_VFE_GDSC 5
+#define OXILI_GDSC 6
+#define OXILICX_GDSC 7
+
#endif
diff --git a/include/dt-bindings/clock/qcom,mmcc-msm8974.h b/include/dt-bindings/clock/qcom,mmcc-msm8974.h
index 032ed87..28651e5 100644
--- a/include/dt-bindings/clock/qcom,mmcc-msm8974.h
+++ b/include/dt-bindings/clock/qcom,mmcc-msm8974.h
@@ -158,4 +158,12 @@
#define SPDM_RM_AXI 141
#define SPDM_RM_OCMEMNOC 142
+/* gdscs */
+#define VENUS0_GDSC 0
+#define MDSS_GDSC 1
+#define CAMSS_JPEG_GDSC 2
+#define CAMSS_VFE_GDSC 3
+#define OXILI_GDSC 4
+#define OXILICX_GDSC 5
+
#endif
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 3ecc07d..8ff43eb 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -500,13 +500,14 @@
*
* Clock with adjustable fractional divider affecting its output frequency.
*/
-
struct clk_fractional_divider {
struct clk_hw hw;
void __iomem *reg;
u8 mshift;
+ u8 mwidth;
u32 mmask;
u8 nshift;
+ u8 nwidth;
u32 nmask;
u8 flags;
spinlock_t *lock;
diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h
index 7669f76..1e69322 100644
--- a/include/linux/clk/at91_pmc.h
+++ b/include/linux/clk/at91_pmc.h
@@ -164,6 +164,7 @@
#define AT91_PMC_MOSCSELS (1 << 16) /* Main Oscillator Selection [some SAM9] */
#define AT91_PMC_MOSCRCS (1 << 17) /* Main On-Chip RC [some SAM9] */
#define AT91_PMC_CFDEV (1 << 18) /* Clock Failure Detector Event [some SAM9] */
+#define AT91_PMC_GCKRDY (1 << 24) /* Generated Clocks */
#define AT91_PMC_IMR 0x6c /* Interrupt Mask Register */
#define AT91_PMC_PLLICPR 0x80 /* PLL Charge Pump Current Register */
@@ -182,13 +183,18 @@
#define AT91_PMC_PCSR1 0x108 /* Peripheral Clock Enable Register 1 */
#define AT91_PMC_PCR 0x10c /* Peripheral Control Register [some SAM9 and SAMA5] */
-#define AT91_PMC_PCR_PID (0x3f << 0) /* Peripheral ID */
-#define AT91_PMC_PCR_CMD (0x1 << 12) /* Command (read=0, write=1) */
-#define AT91_PMC_PCR_DIV(n) ((n) << 16) /* Divisor Value */
-#define AT91_PMC_PCR_DIV0 0x0 /* Peripheral clock is MCK */
-#define AT91_PMC_PCR_DIV2 0x1 /* Peripheral clock is MCK/2 */
-#define AT91_PMC_PCR_DIV4 0x2 /* Peripheral clock is MCK/4 */
-#define AT91_PMC_PCR_DIV8 0x3 /* Peripheral clock is MCK/8 */
-#define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */
+#define AT91_PMC_PCR_PID_MASK 0x3f
+#define AT91_PMC_PCR_GCKCSS_OFFSET 8
+#define AT91_PMC_PCR_GCKCSS_MASK (0x7 << AT91_PMC_PCR_GCKCSS_OFFSET)
+#define AT91_PMC_PCR_GCKCSS(n) ((n) << AT91_PMC_PCR_GCKCSS_OFFSET) /* GCK Clock Source Selection */
+#define AT91_PMC_PCR_CMD (0x1 << 12) /* Command (read=0, write=1) */
+#define AT91_PMC_PCR_DIV_OFFSET 16
+#define AT91_PMC_PCR_DIV_MASK (0x3 << AT91_PMC_PCR_DIV_OFFSET)
+#define AT91_PMC_PCR_DIV(n) ((n) << AT91_PMC_PCR_DIV_OFFSET) /* Divisor Value */
+#define AT91_PMC_PCR_GCKDIV_OFFSET 20
+#define AT91_PMC_PCR_GCKDIV_MASK (0xff << AT91_PMC_PCR_GCKDIV_OFFSET)
+#define AT91_PMC_PCR_GCKDIV(n) ((n) << AT91_PMC_PCR_GCKDIV_OFFSET) /* Generated Clock Divisor Value */
+#define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */
+#define AT91_PMC_PCR_GCKEN (0x1 << 29) /* GCK Enable */
#endif