* [PATCH v6]: clk: Add common clock support for Mediatek MT8135 and MT8173
@ 2015-02-22 11:49 ` Sascha Hauer
0 siblings, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2015-02-22 11:49 UTC (permalink / raw)
To: Mike Turquette
Cc: Matthias Brugger, linux-arm-kernel, linux-kernel, linux-mediatek,
YH Chen, kernel, Yingjoe Chen, Eddie Huang, Henry Chen
This patchset contains the initial common clock support for Mediatek SoCs.
Mediatek SoC's clock architecture comprises of various PLLs, dividers, muxes
and clock gates.
Sascha
Changes in v2:
- Re-ordered patchset. Fold include/dt-bindings and DT document in 1st patch.
Changes in v3:
- Rebase to 3.19-rc1.
- Refine code. Remove unneed functions, debug logs and comments, and fine tune
error logs.
Changes in v4:
- Support MT8173 platform.
- Re-ordered patchset. driver/clk/Makefile in 2nd patch.
- Extract the common part definition(mtk_gate/mtk_pll/mtk_mux) from
clk-mt8135.c/clk-mt8173.c to clk-mtk.c.
- Refine code. Rmove unnessacary debug information and unsed defines,
add prefix "mtk_" for static functions.
- Remove flag CLK_IGNORE_UNUSED and set flag CLK_SET_RATE_PARENT on
gate/mux/fixed-factor.
- Use spin_lock_irqsave(&clk_ops_lock, flags) instead of mtk_clk_lock.
- Example above include a node for the clock controller itself, followed
by the i2c controller example above.
Changes in v5:
- Add reset controller support for pericfg/infracfg
- Use regmap for the gates
- remove now unnecessary spinlock for the gates
- Add PMIC wrapper support as of v3
Changes in v6:
- rework PLL support, only a fraction of original size now
- Move binding docs to Documentation/devicetree/bindings/arm/mediatek since
the units are not really clock specific (they contain reset controllers)
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v6]: clk: Add common clock support for Mediatek MT8135 and MT8173
@ 2015-02-22 11:49 ` Sascha Hauer
0 siblings, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2015-02-22 11:49 UTC (permalink / raw)
To: linux-arm-kernel
This patchset contains the initial common clock support for Mediatek SoCs.
Mediatek SoC's clock architecture comprises of various PLLs, dividers, muxes
and clock gates.
Sascha
Changes in v2:
- Re-ordered patchset. Fold include/dt-bindings and DT document in 1st patch.
Changes in v3:
- Rebase to 3.19-rc1.
- Refine code. Remove unneed functions, debug logs and comments, and fine tune
error logs.
Changes in v4:
- Support MT8173 platform.
- Re-ordered patchset. driver/clk/Makefile in 2nd patch.
- Extract the common part definition(mtk_gate/mtk_pll/mtk_mux) from
clk-mt8135.c/clk-mt8173.c to clk-mtk.c.
- Refine code. Rmove unnessacary debug information and unsed defines,
add prefix "mtk_" for static functions.
- Remove flag CLK_IGNORE_UNUSED and set flag CLK_SET_RATE_PARENT on
gate/mux/fixed-factor.
- Use spin_lock_irqsave(&clk_ops_lock, flags) instead of mtk_clk_lock.
- Example above include a node for the clock controller itself, followed
by the i2c controller example above.
Changes in v5:
- Add reset controller support for pericfg/infracfg
- Use regmap for the gates
- remove now unnecessary spinlock for the gates
- Add PMIC wrapper support as of v3
Changes in v6:
- rework PLL support, only a fraction of original size now
- Move binding docs to Documentation/devicetree/bindings/arm/mediatek since
the units are not really clock specific (they contain reset controllers)
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 1/5] clk: mediatek: Add initial common clock support for Mediatek SoCs.
2015-02-22 11:49 ` Sascha Hauer
@ 2015-02-22 11:49 ` Sascha Hauer
-1 siblings, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2015-02-22 11:49 UTC (permalink / raw)
To: Mike Turquette
Cc: Matthias Brugger, linux-arm-kernel, linux-kernel, linux-mediatek,
YH Chen, kernel, Yingjoe Chen, Eddie Huang, Henry Chen,
James Liao, Sascha Hauer
From: James Liao <jamesjj.liao@mediatek.com>
This patch adds common clock support for Mediatek SoCs, including plls,
muxes and clock gates.
Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/clk/Makefile | 1 +
drivers/clk/mediatek/Makefile | 1 +
drivers/clk/mediatek/clk-gate.c | 137 +++++++++++++++++
drivers/clk/mediatek/clk-gate.h | 49 ++++++
drivers/clk/mediatek/clk-mtk.c | 195 ++++++++++++++++++++++++
drivers/clk/mediatek/clk-mtk.h | 164 ++++++++++++++++++++
drivers/clk/mediatek/clk-pll.c | 330 ++++++++++++++++++++++++++++++++++++++++
7 files changed, 877 insertions(+)
create mode 100644 drivers/clk/mediatek/Makefile
create mode 100644 drivers/clk/mediatek/clk-gate.c
create mode 100644 drivers/clk/mediatek/clk-gate.h
create mode 100644 drivers/clk/mediatek/clk-mtk.c
create mode 100644 drivers/clk/mediatek/clk-mtk.h
create mode 100644 drivers/clk/mediatek/clk-pll.c
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index d5fba5b..ce6c250 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_ARCH_HI3xxx) += hisilicon/
obj-$(CONFIG_ARCH_HIP04) += hisilicon/
obj-$(CONFIG_ARCH_HIX5HD2) += hisilicon/
obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/
+obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
ifeq ($(CONFIG_COMMON_CLK), y)
obj-$(CONFIG_ARCH_MMP) += mmp/
endif
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
new file mode 100644
index 0000000..c384e97
--- /dev/null
+++ b/drivers/clk/mediatek/Makefile
@@ -0,0 +1 @@
+obj-y += clk-mtk.o clk-pll.o clk-gate.o
diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c
new file mode 100644
index 0000000..9d77ee3
--- /dev/null
+++ b/drivers/clk/mediatek/clk-gate.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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/of.h>
+#include <linux/of_address.h>
+
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/clkdev.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+static int mtk_cg_bit_is_cleared(struct clk_hw *hw)
+{
+ struct mtk_clk_gate *cg = to_clk_gate(hw);
+ u32 val;
+
+ regmap_read(cg->regmap, cg->sta_ofs, &val);
+
+ val &= BIT(cg->bit);
+
+ return val == 0;
+}
+
+static int mtk_cg_bit_is_set(struct clk_hw *hw)
+{
+ struct mtk_clk_gate *cg = to_clk_gate(hw);
+ u32 val;
+
+ regmap_read(cg->regmap, cg->sta_ofs, &val);
+
+ val &= BIT(cg->bit);
+
+ return val != 0;
+}
+
+static void mtk_cg_set_bit(struct clk_hw *hw)
+{
+ struct mtk_clk_gate *cg = to_clk_gate(hw);
+
+ regmap_write(cg->regmap, cg->set_ofs, BIT(cg->bit));
+}
+
+static void mtk_cg_clr_bit(struct clk_hw *hw)
+{
+ struct mtk_clk_gate *cg = to_clk_gate(hw);
+
+ regmap_write(cg->regmap, cg->clr_ofs, BIT(cg->bit));
+}
+
+static int mtk_cg_enable(struct clk_hw *hw)
+{
+ mtk_cg_clr_bit(hw);
+
+ return 0;
+}
+
+static void mtk_cg_disable(struct clk_hw *hw)
+{
+ mtk_cg_set_bit(hw);
+}
+
+static int mtk_cg_enable_inv(struct clk_hw *hw)
+{
+ mtk_cg_set_bit(hw);
+
+ return 0;
+}
+
+static void mtk_cg_disable_inv(struct clk_hw *hw)
+{
+ mtk_cg_clr_bit(hw);
+}
+
+const struct clk_ops mtk_clk_gate_ops_setclr = {
+ .is_enabled = mtk_cg_bit_is_cleared,
+ .enable = mtk_cg_enable,
+ .disable = mtk_cg_disable,
+};
+
+const struct clk_ops mtk_clk_gate_ops_setclr_inv = {
+ .is_enabled = mtk_cg_bit_is_set,
+ .enable = mtk_cg_enable_inv,
+ .disable = mtk_cg_disable_inv,
+};
+
+struct clk *mtk_clk_register_gate(
+ const char *name,
+ const char *parent_name,
+ struct regmap *regmap,
+ int set_ofs,
+ int clr_ofs,
+ int sta_ofs,
+ u8 bit,
+ const struct clk_ops *ops)
+{
+ struct mtk_clk_gate *cg;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ cg = kzalloc(sizeof(*cg), GFP_KERNEL);
+ if (!cg)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.flags = CLK_SET_RATE_PARENT;
+ init.parent_names = parent_name ? &parent_name : NULL;
+ init.num_parents = parent_name ? 1 : 0;
+ init.ops = ops;
+
+ cg->regmap = regmap;
+ cg->set_ofs = set_ofs;
+ cg->clr_ofs = clr_ofs;
+ cg->sta_ofs = sta_ofs;
+ cg->bit = bit;
+
+ cg->hw.init = &init;
+
+ clk = clk_register(NULL, &cg->hw);
+ if (IS_ERR(clk))
+ kfree(cg);
+
+ return clk;
+}
diff --git a/drivers/clk/mediatek/clk-gate.h b/drivers/clk/mediatek/clk-gate.h
new file mode 100644
index 0000000..6b6780b
--- /dev/null
+++ b/drivers/clk/mediatek/clk-gate.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 __DRV_CLK_GATE_H
+#define __DRV_CLK_GATE_H
+
+#include <linux/regmap.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+
+struct mtk_clk_gate {
+ struct clk_hw hw;
+ struct regmap *regmap;
+ int set_ofs;
+ int clr_ofs;
+ int sta_ofs;
+ u8 bit;
+};
+
+static inline struct mtk_clk_gate *to_clk_gate(struct clk_hw *hw)
+{
+ return container_of(hw, struct mtk_clk_gate, hw);
+}
+
+extern const struct clk_ops mtk_clk_gate_ops_setclr;
+extern const struct clk_ops mtk_clk_gate_ops_setclr_inv;
+
+struct clk *mtk_clk_register_gate(
+ const char *name,
+ const char *parent_name,
+ struct regmap *regmap,
+ int set_ofs,
+ int clr_ofs,
+ int sta_ofs,
+ u8 bit,
+ const struct clk_ops *ops);
+
+#endif /* __DRV_CLK_GATE_H */
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
new file mode 100644
index 0000000..aeb2cc0
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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/of.h>
+#include <linux/of_address.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/clkdev.h>
+#include <linux/mfd/syscon.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num)
+{
+ int i;
+ struct clk_onecell_data *clk_data;
+
+ clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
+ if (!clk_data)
+ return NULL;
+
+ clk_data->clks = kcalloc(clk_num, sizeof(*clk_data->clks), GFP_KERNEL);
+ if (!clk_data->clks)
+ goto err_out;
+
+ clk_data->clk_num = clk_num;
+
+ for (i = 0; i < clk_num; ++i)
+ clk_data->clks[i] = ERR_PTR(-ENOENT);
+
+ return clk_data;
+err_out:
+ kfree(clk_data);
+
+ return NULL;
+}
+
+void mtk_clk_register_factors(struct mtk_fixed_factor *clks, int num,
+ struct clk_onecell_data *clk_data)
+{
+ int i;
+ struct clk *clk;
+
+ for (i = 0; i < num; i++) {
+ struct mtk_fixed_factor *ff = &clks[i];
+
+ clk = clk_register_fixed_factor(NULL, ff->name, ff->parent_name,
+ CLK_SET_RATE_PARENT, ff->mult, ff->div);
+
+ if (IS_ERR(clk)) {
+ pr_err("Failed to register clk %s: %ld\n",
+ ff->name, PTR_ERR(clk));
+ continue;
+ }
+
+ if (clk_data)
+ clk_data->clks[ff->id] = clk;
+ }
+}
+
+int mtk_clk_register_gates(struct device_node *node, struct mtk_gate *clks, int num,
+ struct clk_onecell_data *clk_data)
+{
+ int i;
+ struct clk *clk;
+ struct regmap *regmap;
+
+ if (!clk_data)
+ return -ENOMEM;
+
+ regmap = syscon_node_to_regmap(node);
+ if (IS_ERR(regmap)) {
+ pr_err("Cannot find regmap for %s: %ld\n", node->full_name,
+ PTR_ERR(regmap));
+ return PTR_ERR(regmap);
+ }
+
+ for (i = 0; i < num; i++) {
+ struct mtk_gate *gate = &clks[i];
+
+ clk = mtk_clk_register_gate(gate->name, gate->parent_name,
+ regmap,
+ gate->regs->set_ofs,
+ gate->regs->clr_ofs,
+ gate->regs->sta_ofs,
+ gate->shift, gate->ops);
+
+ if (IS_ERR(clk)) {
+ pr_err("Failed to register clk %s: %ld\n",
+ gate->name, PTR_ERR(clk));
+ continue;
+ }
+
+ clk_data->clks[gate->id] = clk;
+ }
+
+ return 0;
+}
+
+struct clk *mtk_clk_register_composite(struct mtk_composite *mc, void __iomem *base,
+ spinlock_t *lock)
+{
+ struct clk *clk;
+ struct clk_mux *mux = NULL;
+ struct clk_gate *gate = NULL;
+ struct clk_divider *div = NULL;
+ struct clk_hw *mux_hw = NULL, *gate_hw = NULL, *div_hw = NULL;
+ const struct clk_ops *mux_ops = NULL, *gate_ops = NULL, *div_ops = NULL;
+ const char **parent_names;
+ int num_parents;
+ int ret;
+
+ if (mc->mux_shift >= 0) {
+ mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+ if (!mux)
+ return ERR_PTR(-ENOMEM);
+
+ mux->reg = base + mc->mux_reg;
+ mux->mask = BIT(mc->mux_width) - 1;
+ mux->shift = mc->mux_shift;
+ mux->lock = lock;
+
+ mux_hw = &mux->hw;
+ mux_ops = &clk_mux_ops;
+
+ parent_names = mc->parent_names;
+ num_parents = mc->num_parents;
+ } else {
+ parent_names = &mc->parent;
+ num_parents = 1;
+ }
+
+ if (mc->gate_shift >= 0) {
+ gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+ if (!gate) {
+ ret = -ENOMEM;
+ goto err_out;
+ }
+
+ gate->reg = base + mc->gate_reg;
+ gate->bit_idx = mc->gate_shift;
+ gate->flags = CLK_GATE_SET_TO_DISABLE;
+ gate->lock = lock;
+
+ gate_hw = &gate->hw;
+ gate_ops = &clk_gate_ops;
+ }
+
+ if (mc->divider_shift >= 0) {
+ div = kzalloc(sizeof(*div), GFP_KERNEL);
+ if (!div) {
+ ret = -ENOMEM;
+ goto err_out;
+ }
+
+ div->reg = base + mc->divider_reg;
+ div->shift = mc->divider_shift;
+ div->width = mc->divider_width;
+ div->lock = lock;
+
+ div_hw = &div->hw;
+ div_ops = &clk_divider_ops;
+ }
+
+ clk = clk_register_composite(NULL, mc->name, parent_names, num_parents,
+ mux_hw, mux_ops,
+ div_hw, div_ops,
+ gate_hw, gate_ops,
+ mc->flags);
+
+ if (IS_ERR(clk)) {
+ kfree(gate);
+ kfree(mux);
+ }
+
+ return clk;
+err_out:
+ kfree(mux);
+
+ return ERR_PTR(ret);
+}
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
new file mode 100644
index 0000000..c7c0d35
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 __DRV_CLK_MTK_H
+#define __DRV_CLK_MTK_H
+
+#include <linux/regmap.h>
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+
+#define MAX_MUX_GATE_BIT 31
+#define INVALID_MUX_GATE_BIT (MAX_MUX_GATE_BIT + 1)
+
+#define MHZ (1000 * 1000)
+
+struct mtk_fixed_factor {
+ int id;
+ const char *name;
+ const char *parent_name;
+ int mult;
+ int div;
+};
+
+#define FACTOR(_id, _name, _parent, _mult, _div) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .mult = _mult, \
+ .div = _div, \
+ }
+
+extern void mtk_clk_register_factors(struct mtk_fixed_factor *clks, int num,
+ struct clk_onecell_data *clk_data);
+
+struct mtk_composite {
+ int id;
+ const char *name;
+ const char **parent_names;
+ const char *parent;
+ unsigned flags;
+
+ uint32_t mux_reg;
+ uint32_t divider_reg;
+ uint32_t gate_reg;
+
+ signed char mux_shift;
+ signed char mux_width;
+ signed char gate_shift;
+
+ signed char divider_shift;
+ signed char divider_width;
+
+ signed char num_parents;
+};
+
+#define MUX_GATE(_id, _name, _parents, _reg, _shift, _width, _gate) { \
+ .id = _id, \
+ .name = _name, \
+ .mux_reg = _reg, \
+ .mux_shift = _shift, \
+ .mux_width = _width, \
+ .gate_reg = _reg, \
+ .gate_shift = _gate, \
+ .divider_shift = -1, \
+ .parent_names = _parents, \
+ .num_parents = ARRAY_SIZE(_parents), \
+ .flags = CLK_SET_RATE_PARENT, \
+ }
+
+#define MUX(_id, _name, _parents, _reg, _shift, _width) { \
+ .id = _id, \
+ .name = _name, \
+ .mux_reg = _reg, \
+ .mux_shift = _shift, \
+ .mux_width = _width, \
+ .gate_shift = -1, \
+ .divider_shift = -1, \
+ .parent_names = _parents, \
+ .num_parents = ARRAY_SIZE(_parents), \
+ .flags = CLK_SET_RATE_PARENT, \
+ }
+
+#define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, _div_width, _div_shift) { \
+ .id = _id, \
+ .parent = _parent, \
+ .name = _name, \
+ .divider_reg = _div_reg, \
+ .divider_shift = _div_shift, \
+ .divider_width = _div_width, \
+ .gate_reg = _gate_reg, \
+ .gate_shift = _gate_shift, \
+ .mux_shift = -1, \
+ .flags = 0, \
+ }
+
+struct clk *mtk_clk_register_composite(struct mtk_composite *mc, void __iomem *base,
+ spinlock_t *lock);
+
+struct mtk_gate_regs {
+ u32 sta_ofs;
+ u32 clr_ofs;
+ u32 set_ofs;
+};
+
+struct mtk_gate {
+ int id;
+ const char *name;
+ const char *parent_name;
+ struct mtk_gate_regs *regs;
+ int shift;
+ const struct clk_ops *ops;
+};
+
+int mtk_clk_register_gates(struct device_node *node, struct mtk_gate *clks, int num,
+ struct clk_onecell_data *clk_data);
+
+struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num);
+
+#define HAVE_RST_BAR BIT(0)
+
+struct mtk_pll_data {
+ int id;
+ const char *name;
+ uint32_t reg;
+ uint32_t pwr_reg;
+ uint32_t en_mask;
+ uint32_t pd_reg;
+ uint32_t tuner_reg;
+ int pd_shift;
+ unsigned int flags;
+ const struct clk_ops *ops;
+ u32 rst_bar_mask;
+ unsigned long fmax;
+ int pcwbits;
+ uint32_t pcw_reg;
+ int pcw_shift;
+};
+
+void __init mtk_clk_register_plls(struct device_node *node,
+ const struct mtk_pll_data *plls, int num_plls);
+
+#ifdef CONFIG_RESET_CONTROLLER
+void mtk_register_reset_controller(struct device_node *np,
+ unsigned int num_regs, int regofs);
+#else
+static inline void mtk_register_reset_controller(struct device_node *np,
+ unsigned int num_regs, int regofs)
+{
+}
+#endif
+
+#endif /* __DRV_CLK_MTK_H */
diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
new file mode 100644
index 0000000..06cd8c7
--- /dev/null
+++ b/drivers/clk/mediatek/clk-pll.c
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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/of.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/clkdev.h>
+#include <linux/delay.h>
+
+#include "clk-mtk.h"
+
+#define CON0_BASE_EN BIT(0)
+#define CON0_PWR_ON BIT(0)
+#define CON0_ISO_EN BIT(1)
+#define CON0_PCW_CHG BIT(31)
+
+#define AUDPLL_TUNER_EN BIT(31)
+
+/*
+ * MediaTek PLLs are configured through their pcw value. The pcw value describes
+ * a divider in the PLL feedback loop which consists of 7 bits for the integer
+ * part and the remaining bits (if present) for the fractional part. Also they
+ * have a 3 bit power-of-two post divider.
+ */
+
+struct mtk_clk_pll {
+ struct clk_hw hw;
+ void __iomem *base_addr;
+ void __iomem *pd_addr;
+ void __iomem *pwr_addr;
+ void __iomem *tuner_addr;
+ void __iomem *pcw_addr;
+ const struct mtk_pll_data *data;
+};
+
+static inline struct mtk_clk_pll *to_mtk_clk_pll(struct clk_hw *hw)
+{
+ return container_of(hw, struct mtk_clk_pll, hw);
+}
+
+static int mtk_pll_is_prepared(struct clk_hw *hw)
+{
+ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
+
+ return (readl(pll->base_addr) & CON0_BASE_EN) != 0;
+}
+
+static unsigned long __mtk_pll_recalc_rate(struct mtk_clk_pll *pll, u32 fin,
+ u32 pcw, int postdiv)
+{
+ int pcwbits = pll->data->pcwbits;
+ int pcwfbits;
+ u64 vco;
+ u8 c = 0;
+
+ /* The fractional part of the PLL divider. */
+ pcwfbits = pcwbits > 7 ? pcwbits - 7 : 0;
+
+ vco = (u64)fin * pcw;
+
+ if (pcwfbits && (vco & GENMASK(pcwfbits - 1, 0)))
+ c = 1;
+
+ vco >>= pcwfbits;
+
+ if (c)
+ ++vco;
+
+ return ((unsigned long)vco + postdiv - 1) / postdiv;
+}
+
+static void mtk_pll_set_rate_regs(struct clk_hw *hw, u32 pcw,
+ int postdiv)
+{
+ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
+ u32 con1, pd, val;
+ int pll_en;
+
+ /* set postdiv */
+ pd = readl(pll->pd_addr);
+ pd &= ~(0x7 << pll->data->pd_shift);
+ pd |= (ffs(postdiv) - 1) << pll->data->pd_shift;
+ writel(pd, pll->pd_addr);
+
+ pll_en = readl(pll->base_addr) & CON0_BASE_EN;
+
+ /* set pcw */
+ val = readl(pll->pcw_addr);
+
+ val &= ~GENMASK(pll->data->pcw_shift + pll->data->pcwbits - 1,
+ pll->data->pcw_shift);
+ val |= pcw << pll->data->pcw_shift;
+ writel(val, pll->pcw_addr);
+
+ con1 = readl(pll->base_addr + 4);
+
+ if (pll_en)
+ con1 |= CON0_PCW_CHG;
+
+ writel(con1, pll->base_addr + 4);
+ if (pll->tuner_addr)
+ writel(con1 + 1, pll->tuner_addr);
+
+ if (pll_en)
+ usleep_range(20, 1000);
+}
+
+/*
+ * mtk_pll_calc_values - calculate good values for a given input frequency.
+ * @pll: The pll
+ * @pcw: The pcw value (output)
+ * @postdiv: The post divider (output)
+ * @freq: The desired target frequency
+ * @fin: The input frequency
+ *
+ */
+static void mtk_pll_calc_values(struct mtk_clk_pll *pll, u32 *pcw, u32 *postdiv,
+ u32 freq, u32 fin)
+{
+ unsigned long fmin = 1000 * MHZ;
+ u64 _pcw;
+ u32 val;
+
+ if (freq > pll->data->fmax)
+ freq = pll->data->fmax;
+
+ for (val = 0; val < 4; val++) {
+ *postdiv = 1 << val;
+ if (freq * *postdiv >= fmin)
+ break;
+ }
+
+ /* _pcw = freq * postdiv / fin * 2^pcwfbits */
+ _pcw = ((u64)freq << val) << (pll->data->pcwbits - 7);
+ do_div(_pcw, fin);
+
+ *pcw = (u32)_pcw;
+}
+
+static int mtk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
+ u32 pcw = 0;
+ u32 postdiv;
+
+ mtk_pll_calc_values(pll, &pcw, &postdiv, rate, parent_rate);
+ mtk_pll_set_rate_regs(hw, pcw, postdiv);
+
+ return 0;
+}
+
+static unsigned long mtk_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
+ u32 postdiv;
+ u32 pcw;
+
+ postdiv = (readl(pll->pd_addr) >> pll->data->pd_shift) & 0x7;
+ postdiv = 1 << postdiv;
+
+ pcw = readl(pll->pcw_addr) >> pll->data->pcw_shift;
+ pcw &= GENMASK(pll->data->pcwbits - 1, 0);
+
+ return __mtk_pll_recalc_rate(pll, parent_rate, pcw, postdiv);
+}
+
+static long mtk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
+ u32 pcw = 0;
+ int postdiv;
+
+ mtk_pll_calc_values(pll, &pcw, &postdiv, rate, *prate);
+
+ return __mtk_pll_recalc_rate(pll, *prate, pcw, postdiv);
+}
+
+static int mtk_pll_prepare(struct clk_hw *hw)
+{
+ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
+ u32 r;
+
+ r = readl(pll->pwr_addr) | CON0_PWR_ON;
+ writel(r, pll->pwr_addr);
+ usleep_range(1, 100);
+
+ r = readl(pll->pwr_addr) & ~CON0_ISO_EN;
+ writel(r, pll->pwr_addr);
+ usleep_range(1, 100);
+
+ r = readl(pll->base_addr) | pll->data->en_mask;
+ writel(r, pll->base_addr);
+
+ if (pll->tuner_addr) {
+ r = readl(pll->tuner_addr) | AUDPLL_TUNER_EN;
+ writel(r, pll->tuner_addr);
+ }
+
+ usleep_range(20, 1000);
+
+ if (pll->data->flags & HAVE_RST_BAR) {
+ r = readl(pll->base_addr) | pll->data->rst_bar_mask;
+ writel(r, pll->base_addr);
+ }
+
+ return 0;
+}
+
+static void mtk_pll_unprepare(struct clk_hw *hw)
+{
+ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
+ u32 r;
+
+ if (pll->data->flags & HAVE_RST_BAR) {
+ r = readl(pll->base_addr) & ~pll->data->rst_bar_mask;
+ writel(r, pll->base_addr);
+ }
+
+ if (pll->tuner_addr) {
+ r = readl(pll->tuner_addr) & ~AUDPLL_TUNER_EN;
+ writel(r, pll->tuner_addr);
+ }
+
+ r = readl(pll->base_addr) & ~CON0_BASE_EN;
+ writel(r, pll->base_addr);
+
+ r = readl(pll->pwr_addr) | CON0_ISO_EN;
+ writel(r, pll->pwr_addr);
+
+ r = readl(pll->pwr_addr) & ~CON0_PWR_ON;
+ writel(r, pll->pwr_addr);
+}
+
+static const struct clk_ops mtk_pll_ops = {
+ .is_prepared = mtk_pll_is_prepared,
+ .prepare = mtk_pll_prepare,
+ .unprepare = mtk_pll_unprepare,
+ .recalc_rate = mtk_pll_recalc_rate,
+ .round_rate = mtk_pll_round_rate,
+ .set_rate = mtk_pll_set_rate,
+};
+
+static struct clk *mtk_clk_register_pll(const struct mtk_pll_data *data,
+ void __iomem *base)
+{
+ struct mtk_clk_pll *pll;
+ struct clk_init_data init;
+ struct clk *clk;
+ const char *parent_name = "clk26m";
+
+ pr_debug("%s(): name: %s\n", __func__, data->name);
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ pll->base_addr = base + data->reg;
+ pll->pwr_addr = base + data->pwr_reg;
+ pll->pd_addr = base + data->pd_reg;
+ pll->pcw_addr = base + data->pcw_reg;
+ if (data->tuner_reg)
+ pll->tuner_addr = base + data->tuner_reg;
+ pll->hw.init = &init;
+ pll->data = data;
+
+ init.name = data->name;
+ init.ops = &mtk_pll_ops;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ clk = clk_register(NULL, &pll->hw);
+
+ if (IS_ERR(clk))
+ kfree(pll);
+
+ return clk;
+}
+
+void __init mtk_clk_register_plls(struct device_node *node,
+ const struct mtk_pll_data *plls, int num_plls)
+{
+ struct clk_onecell_data *clk_data;
+ void __iomem *base;
+ int r, i;
+ struct clk *clk;
+
+ base = of_iomap(node, 0);
+ if (!base) {
+ pr_err("%s(): ioremap failed\n", __func__);
+ return;
+ }
+
+ clk_data = mtk_alloc_clk_data(num_plls);
+ if (!clk_data)
+ return;
+
+ for (i = 0; i < num_plls; i++) {
+ const struct mtk_pll_data *pll = &plls[i];
+
+ clk = mtk_clk_register_pll(pll, base);
+
+ if (IS_ERR(clk)) {
+ pr_err("Failed to register clk %s: %ld\n",
+ pll->name, PTR_ERR(clk));
+ continue;
+ }
+
+ clk_data->clks[pll->id] = clk;
+ }
+
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
+}
--
2.1.4
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 1/5] clk: mediatek: Add initial common clock support for Mediatek SoCs.
@ 2015-02-22 11:49 ` Sascha Hauer
0 siblings, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2015-02-22 11:49 UTC (permalink / raw)
To: linux-arm-kernel
From: James Liao <jamesjj.liao@mediatek.com>
This patch adds common clock support for Mediatek SoCs, including plls,
muxes and clock gates.
Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/clk/Makefile | 1 +
drivers/clk/mediatek/Makefile | 1 +
drivers/clk/mediatek/clk-gate.c | 137 +++++++++++++++++
drivers/clk/mediatek/clk-gate.h | 49 ++++++
drivers/clk/mediatek/clk-mtk.c | 195 ++++++++++++++++++++++++
drivers/clk/mediatek/clk-mtk.h | 164 ++++++++++++++++++++
drivers/clk/mediatek/clk-pll.c | 330 ++++++++++++++++++++++++++++++++++++++++
7 files changed, 877 insertions(+)
create mode 100644 drivers/clk/mediatek/Makefile
create mode 100644 drivers/clk/mediatek/clk-gate.c
create mode 100644 drivers/clk/mediatek/clk-gate.h
create mode 100644 drivers/clk/mediatek/clk-mtk.c
create mode 100644 drivers/clk/mediatek/clk-mtk.h
create mode 100644 drivers/clk/mediatek/clk-pll.c
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index d5fba5b..ce6c250 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_ARCH_HI3xxx) += hisilicon/
obj-$(CONFIG_ARCH_HIP04) += hisilicon/
obj-$(CONFIG_ARCH_HIX5HD2) += hisilicon/
obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/
+obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
ifeq ($(CONFIG_COMMON_CLK), y)
obj-$(CONFIG_ARCH_MMP) += mmp/
endif
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
new file mode 100644
index 0000000..c384e97
--- /dev/null
+++ b/drivers/clk/mediatek/Makefile
@@ -0,0 +1 @@
+obj-y += clk-mtk.o clk-pll.o clk-gate.o
diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c
new file mode 100644
index 0000000..9d77ee3
--- /dev/null
+++ b/drivers/clk/mediatek/clk-gate.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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/of.h>
+#include <linux/of_address.h>
+
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/clkdev.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+static int mtk_cg_bit_is_cleared(struct clk_hw *hw)
+{
+ struct mtk_clk_gate *cg = to_clk_gate(hw);
+ u32 val;
+
+ regmap_read(cg->regmap, cg->sta_ofs, &val);
+
+ val &= BIT(cg->bit);
+
+ return val == 0;
+}
+
+static int mtk_cg_bit_is_set(struct clk_hw *hw)
+{
+ struct mtk_clk_gate *cg = to_clk_gate(hw);
+ u32 val;
+
+ regmap_read(cg->regmap, cg->sta_ofs, &val);
+
+ val &= BIT(cg->bit);
+
+ return val != 0;
+}
+
+static void mtk_cg_set_bit(struct clk_hw *hw)
+{
+ struct mtk_clk_gate *cg = to_clk_gate(hw);
+
+ regmap_write(cg->regmap, cg->set_ofs, BIT(cg->bit));
+}
+
+static void mtk_cg_clr_bit(struct clk_hw *hw)
+{
+ struct mtk_clk_gate *cg = to_clk_gate(hw);
+
+ regmap_write(cg->regmap, cg->clr_ofs, BIT(cg->bit));
+}
+
+static int mtk_cg_enable(struct clk_hw *hw)
+{
+ mtk_cg_clr_bit(hw);
+
+ return 0;
+}
+
+static void mtk_cg_disable(struct clk_hw *hw)
+{
+ mtk_cg_set_bit(hw);
+}
+
+static int mtk_cg_enable_inv(struct clk_hw *hw)
+{
+ mtk_cg_set_bit(hw);
+
+ return 0;
+}
+
+static void mtk_cg_disable_inv(struct clk_hw *hw)
+{
+ mtk_cg_clr_bit(hw);
+}
+
+const struct clk_ops mtk_clk_gate_ops_setclr = {
+ .is_enabled = mtk_cg_bit_is_cleared,
+ .enable = mtk_cg_enable,
+ .disable = mtk_cg_disable,
+};
+
+const struct clk_ops mtk_clk_gate_ops_setclr_inv = {
+ .is_enabled = mtk_cg_bit_is_set,
+ .enable = mtk_cg_enable_inv,
+ .disable = mtk_cg_disable_inv,
+};
+
+struct clk *mtk_clk_register_gate(
+ const char *name,
+ const char *parent_name,
+ struct regmap *regmap,
+ int set_ofs,
+ int clr_ofs,
+ int sta_ofs,
+ u8 bit,
+ const struct clk_ops *ops)
+{
+ struct mtk_clk_gate *cg;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ cg = kzalloc(sizeof(*cg), GFP_KERNEL);
+ if (!cg)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.flags = CLK_SET_RATE_PARENT;
+ init.parent_names = parent_name ? &parent_name : NULL;
+ init.num_parents = parent_name ? 1 : 0;
+ init.ops = ops;
+
+ cg->regmap = regmap;
+ cg->set_ofs = set_ofs;
+ cg->clr_ofs = clr_ofs;
+ cg->sta_ofs = sta_ofs;
+ cg->bit = bit;
+
+ cg->hw.init = &init;
+
+ clk = clk_register(NULL, &cg->hw);
+ if (IS_ERR(clk))
+ kfree(cg);
+
+ return clk;
+}
diff --git a/drivers/clk/mediatek/clk-gate.h b/drivers/clk/mediatek/clk-gate.h
new file mode 100644
index 0000000..6b6780b
--- /dev/null
+++ b/drivers/clk/mediatek/clk-gate.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 __DRV_CLK_GATE_H
+#define __DRV_CLK_GATE_H
+
+#include <linux/regmap.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+
+struct mtk_clk_gate {
+ struct clk_hw hw;
+ struct regmap *regmap;
+ int set_ofs;
+ int clr_ofs;
+ int sta_ofs;
+ u8 bit;
+};
+
+static inline struct mtk_clk_gate *to_clk_gate(struct clk_hw *hw)
+{
+ return container_of(hw, struct mtk_clk_gate, hw);
+}
+
+extern const struct clk_ops mtk_clk_gate_ops_setclr;
+extern const struct clk_ops mtk_clk_gate_ops_setclr_inv;
+
+struct clk *mtk_clk_register_gate(
+ const char *name,
+ const char *parent_name,
+ struct regmap *regmap,
+ int set_ofs,
+ int clr_ofs,
+ int sta_ofs,
+ u8 bit,
+ const struct clk_ops *ops);
+
+#endif /* __DRV_CLK_GATE_H */
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
new file mode 100644
index 0000000..aeb2cc0
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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/of.h>
+#include <linux/of_address.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/clkdev.h>
+#include <linux/mfd/syscon.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num)
+{
+ int i;
+ struct clk_onecell_data *clk_data;
+
+ clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
+ if (!clk_data)
+ return NULL;
+
+ clk_data->clks = kcalloc(clk_num, sizeof(*clk_data->clks), GFP_KERNEL);
+ if (!clk_data->clks)
+ goto err_out;
+
+ clk_data->clk_num = clk_num;
+
+ for (i = 0; i < clk_num; ++i)
+ clk_data->clks[i] = ERR_PTR(-ENOENT);
+
+ return clk_data;
+err_out:
+ kfree(clk_data);
+
+ return NULL;
+}
+
+void mtk_clk_register_factors(struct mtk_fixed_factor *clks, int num,
+ struct clk_onecell_data *clk_data)
+{
+ int i;
+ struct clk *clk;
+
+ for (i = 0; i < num; i++) {
+ struct mtk_fixed_factor *ff = &clks[i];
+
+ clk = clk_register_fixed_factor(NULL, ff->name, ff->parent_name,
+ CLK_SET_RATE_PARENT, ff->mult, ff->div);
+
+ if (IS_ERR(clk)) {
+ pr_err("Failed to register clk %s: %ld\n",
+ ff->name, PTR_ERR(clk));
+ continue;
+ }
+
+ if (clk_data)
+ clk_data->clks[ff->id] = clk;
+ }
+}
+
+int mtk_clk_register_gates(struct device_node *node, struct mtk_gate *clks, int num,
+ struct clk_onecell_data *clk_data)
+{
+ int i;
+ struct clk *clk;
+ struct regmap *regmap;
+
+ if (!clk_data)
+ return -ENOMEM;
+
+ regmap = syscon_node_to_regmap(node);
+ if (IS_ERR(regmap)) {
+ pr_err("Cannot find regmap for %s: %ld\n", node->full_name,
+ PTR_ERR(regmap));
+ return PTR_ERR(regmap);
+ }
+
+ for (i = 0; i < num; i++) {
+ struct mtk_gate *gate = &clks[i];
+
+ clk = mtk_clk_register_gate(gate->name, gate->parent_name,
+ regmap,
+ gate->regs->set_ofs,
+ gate->regs->clr_ofs,
+ gate->regs->sta_ofs,
+ gate->shift, gate->ops);
+
+ if (IS_ERR(clk)) {
+ pr_err("Failed to register clk %s: %ld\n",
+ gate->name, PTR_ERR(clk));
+ continue;
+ }
+
+ clk_data->clks[gate->id] = clk;
+ }
+
+ return 0;
+}
+
+struct clk *mtk_clk_register_composite(struct mtk_composite *mc, void __iomem *base,
+ spinlock_t *lock)
+{
+ struct clk *clk;
+ struct clk_mux *mux = NULL;
+ struct clk_gate *gate = NULL;
+ struct clk_divider *div = NULL;
+ struct clk_hw *mux_hw = NULL, *gate_hw = NULL, *div_hw = NULL;
+ const struct clk_ops *mux_ops = NULL, *gate_ops = NULL, *div_ops = NULL;
+ const char **parent_names;
+ int num_parents;
+ int ret;
+
+ if (mc->mux_shift >= 0) {
+ mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+ if (!mux)
+ return ERR_PTR(-ENOMEM);
+
+ mux->reg = base + mc->mux_reg;
+ mux->mask = BIT(mc->mux_width) - 1;
+ mux->shift = mc->mux_shift;
+ mux->lock = lock;
+
+ mux_hw = &mux->hw;
+ mux_ops = &clk_mux_ops;
+
+ parent_names = mc->parent_names;
+ num_parents = mc->num_parents;
+ } else {
+ parent_names = &mc->parent;
+ num_parents = 1;
+ }
+
+ if (mc->gate_shift >= 0) {
+ gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+ if (!gate) {
+ ret = -ENOMEM;
+ goto err_out;
+ }
+
+ gate->reg = base + mc->gate_reg;
+ gate->bit_idx = mc->gate_shift;
+ gate->flags = CLK_GATE_SET_TO_DISABLE;
+ gate->lock = lock;
+
+ gate_hw = &gate->hw;
+ gate_ops = &clk_gate_ops;
+ }
+
+ if (mc->divider_shift >= 0) {
+ div = kzalloc(sizeof(*div), GFP_KERNEL);
+ if (!div) {
+ ret = -ENOMEM;
+ goto err_out;
+ }
+
+ div->reg = base + mc->divider_reg;
+ div->shift = mc->divider_shift;
+ div->width = mc->divider_width;
+ div->lock = lock;
+
+ div_hw = &div->hw;
+ div_ops = &clk_divider_ops;
+ }
+
+ clk = clk_register_composite(NULL, mc->name, parent_names, num_parents,
+ mux_hw, mux_ops,
+ div_hw, div_ops,
+ gate_hw, gate_ops,
+ mc->flags);
+
+ if (IS_ERR(clk)) {
+ kfree(gate);
+ kfree(mux);
+ }
+
+ return clk;
+err_out:
+ kfree(mux);
+
+ return ERR_PTR(ret);
+}
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
new file mode 100644
index 0000000..c7c0d35
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 __DRV_CLK_MTK_H
+#define __DRV_CLK_MTK_H
+
+#include <linux/regmap.h>
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+
+#define MAX_MUX_GATE_BIT 31
+#define INVALID_MUX_GATE_BIT (MAX_MUX_GATE_BIT + 1)
+
+#define MHZ (1000 * 1000)
+
+struct mtk_fixed_factor {
+ int id;
+ const char *name;
+ const char *parent_name;
+ int mult;
+ int div;
+};
+
+#define FACTOR(_id, _name, _parent, _mult, _div) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .mult = _mult, \
+ .div = _div, \
+ }
+
+extern void mtk_clk_register_factors(struct mtk_fixed_factor *clks, int num,
+ struct clk_onecell_data *clk_data);
+
+struct mtk_composite {
+ int id;
+ const char *name;
+ const char **parent_names;
+ const char *parent;
+ unsigned flags;
+
+ uint32_t mux_reg;
+ uint32_t divider_reg;
+ uint32_t gate_reg;
+
+ signed char mux_shift;
+ signed char mux_width;
+ signed char gate_shift;
+
+ signed char divider_shift;
+ signed char divider_width;
+
+ signed char num_parents;
+};
+
+#define MUX_GATE(_id, _name, _parents, _reg, _shift, _width, _gate) { \
+ .id = _id, \
+ .name = _name, \
+ .mux_reg = _reg, \
+ .mux_shift = _shift, \
+ .mux_width = _width, \
+ .gate_reg = _reg, \
+ .gate_shift = _gate, \
+ .divider_shift = -1, \
+ .parent_names = _parents, \
+ .num_parents = ARRAY_SIZE(_parents), \
+ .flags = CLK_SET_RATE_PARENT, \
+ }
+
+#define MUX(_id, _name, _parents, _reg, _shift, _width) { \
+ .id = _id, \
+ .name = _name, \
+ .mux_reg = _reg, \
+ .mux_shift = _shift, \
+ .mux_width = _width, \
+ .gate_shift = -1, \
+ .divider_shift = -1, \
+ .parent_names = _parents, \
+ .num_parents = ARRAY_SIZE(_parents), \
+ .flags = CLK_SET_RATE_PARENT, \
+ }
+
+#define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, _div_width, _div_shift) { \
+ .id = _id, \
+ .parent = _parent, \
+ .name = _name, \
+ .divider_reg = _div_reg, \
+ .divider_shift = _div_shift, \
+ .divider_width = _div_width, \
+ .gate_reg = _gate_reg, \
+ .gate_shift = _gate_shift, \
+ .mux_shift = -1, \
+ .flags = 0, \
+ }
+
+struct clk *mtk_clk_register_composite(struct mtk_composite *mc, void __iomem *base,
+ spinlock_t *lock);
+
+struct mtk_gate_regs {
+ u32 sta_ofs;
+ u32 clr_ofs;
+ u32 set_ofs;
+};
+
+struct mtk_gate {
+ int id;
+ const char *name;
+ const char *parent_name;
+ struct mtk_gate_regs *regs;
+ int shift;
+ const struct clk_ops *ops;
+};
+
+int mtk_clk_register_gates(struct device_node *node, struct mtk_gate *clks, int num,
+ struct clk_onecell_data *clk_data);
+
+struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num);
+
+#define HAVE_RST_BAR BIT(0)
+
+struct mtk_pll_data {
+ int id;
+ const char *name;
+ uint32_t reg;
+ uint32_t pwr_reg;
+ uint32_t en_mask;
+ uint32_t pd_reg;
+ uint32_t tuner_reg;
+ int pd_shift;
+ unsigned int flags;
+ const struct clk_ops *ops;
+ u32 rst_bar_mask;
+ unsigned long fmax;
+ int pcwbits;
+ uint32_t pcw_reg;
+ int pcw_shift;
+};
+
+void __init mtk_clk_register_plls(struct device_node *node,
+ const struct mtk_pll_data *plls, int num_plls);
+
+#ifdef CONFIG_RESET_CONTROLLER
+void mtk_register_reset_controller(struct device_node *np,
+ unsigned int num_regs, int regofs);
+#else
+static inline void mtk_register_reset_controller(struct device_node *np,
+ unsigned int num_regs, int regofs)
+{
+}
+#endif
+
+#endif /* __DRV_CLK_MTK_H */
diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
new file mode 100644
index 0000000..06cd8c7
--- /dev/null
+++ b/drivers/clk/mediatek/clk-pll.c
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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/of.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/clkdev.h>
+#include <linux/delay.h>
+
+#include "clk-mtk.h"
+
+#define CON0_BASE_EN BIT(0)
+#define CON0_PWR_ON BIT(0)
+#define CON0_ISO_EN BIT(1)
+#define CON0_PCW_CHG BIT(31)
+
+#define AUDPLL_TUNER_EN BIT(31)
+
+/*
+ * MediaTek PLLs are configured through their pcw value. The pcw value describes
+ * a divider in the PLL feedback loop which consists of 7 bits for the integer
+ * part and the remaining bits (if present) for the fractional part. Also they
+ * have a 3 bit power-of-two post divider.
+ */
+
+struct mtk_clk_pll {
+ struct clk_hw hw;
+ void __iomem *base_addr;
+ void __iomem *pd_addr;
+ void __iomem *pwr_addr;
+ void __iomem *tuner_addr;
+ void __iomem *pcw_addr;
+ const struct mtk_pll_data *data;
+};
+
+static inline struct mtk_clk_pll *to_mtk_clk_pll(struct clk_hw *hw)
+{
+ return container_of(hw, struct mtk_clk_pll, hw);
+}
+
+static int mtk_pll_is_prepared(struct clk_hw *hw)
+{
+ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
+
+ return (readl(pll->base_addr) & CON0_BASE_EN) != 0;
+}
+
+static unsigned long __mtk_pll_recalc_rate(struct mtk_clk_pll *pll, u32 fin,
+ u32 pcw, int postdiv)
+{
+ int pcwbits = pll->data->pcwbits;
+ int pcwfbits;
+ u64 vco;
+ u8 c = 0;
+
+ /* The fractional part of the PLL divider. */
+ pcwfbits = pcwbits > 7 ? pcwbits - 7 : 0;
+
+ vco = (u64)fin * pcw;
+
+ if (pcwfbits && (vco & GENMASK(pcwfbits - 1, 0)))
+ c = 1;
+
+ vco >>= pcwfbits;
+
+ if (c)
+ ++vco;
+
+ return ((unsigned long)vco + postdiv - 1) / postdiv;
+}
+
+static void mtk_pll_set_rate_regs(struct clk_hw *hw, u32 pcw,
+ int postdiv)
+{
+ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
+ u32 con1, pd, val;
+ int pll_en;
+
+ /* set postdiv */
+ pd = readl(pll->pd_addr);
+ pd &= ~(0x7 << pll->data->pd_shift);
+ pd |= (ffs(postdiv) - 1) << pll->data->pd_shift;
+ writel(pd, pll->pd_addr);
+
+ pll_en = readl(pll->base_addr) & CON0_BASE_EN;
+
+ /* set pcw */
+ val = readl(pll->pcw_addr);
+
+ val &= ~GENMASK(pll->data->pcw_shift + pll->data->pcwbits - 1,
+ pll->data->pcw_shift);
+ val |= pcw << pll->data->pcw_shift;
+ writel(val, pll->pcw_addr);
+
+ con1 = readl(pll->base_addr + 4);
+
+ if (pll_en)
+ con1 |= CON0_PCW_CHG;
+
+ writel(con1, pll->base_addr + 4);
+ if (pll->tuner_addr)
+ writel(con1 + 1, pll->tuner_addr);
+
+ if (pll_en)
+ usleep_range(20, 1000);
+}
+
+/*
+ * mtk_pll_calc_values - calculate good values for a given input frequency.
+ * @pll: The pll
+ * @pcw: The pcw value (output)
+ * @postdiv: The post divider (output)
+ * @freq: The desired target frequency
+ * @fin: The input frequency
+ *
+ */
+static void mtk_pll_calc_values(struct mtk_clk_pll *pll, u32 *pcw, u32 *postdiv,
+ u32 freq, u32 fin)
+{
+ unsigned long fmin = 1000 * MHZ;
+ u64 _pcw;
+ u32 val;
+
+ if (freq > pll->data->fmax)
+ freq = pll->data->fmax;
+
+ for (val = 0; val < 4; val++) {
+ *postdiv = 1 << val;
+ if (freq * *postdiv >= fmin)
+ break;
+ }
+
+ /* _pcw = freq * postdiv / fin * 2^pcwfbits */
+ _pcw = ((u64)freq << val) << (pll->data->pcwbits - 7);
+ do_div(_pcw, fin);
+
+ *pcw = (u32)_pcw;
+}
+
+static int mtk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
+ u32 pcw = 0;
+ u32 postdiv;
+
+ mtk_pll_calc_values(pll, &pcw, &postdiv, rate, parent_rate);
+ mtk_pll_set_rate_regs(hw, pcw, postdiv);
+
+ return 0;
+}
+
+static unsigned long mtk_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
+ u32 postdiv;
+ u32 pcw;
+
+ postdiv = (readl(pll->pd_addr) >> pll->data->pd_shift) & 0x7;
+ postdiv = 1 << postdiv;
+
+ pcw = readl(pll->pcw_addr) >> pll->data->pcw_shift;
+ pcw &= GENMASK(pll->data->pcwbits - 1, 0);
+
+ return __mtk_pll_recalc_rate(pll, parent_rate, pcw, postdiv);
+}
+
+static long mtk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
+ u32 pcw = 0;
+ int postdiv;
+
+ mtk_pll_calc_values(pll, &pcw, &postdiv, rate, *prate);
+
+ return __mtk_pll_recalc_rate(pll, *prate, pcw, postdiv);
+}
+
+static int mtk_pll_prepare(struct clk_hw *hw)
+{
+ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
+ u32 r;
+
+ r = readl(pll->pwr_addr) | CON0_PWR_ON;
+ writel(r, pll->pwr_addr);
+ usleep_range(1, 100);
+
+ r = readl(pll->pwr_addr) & ~CON0_ISO_EN;
+ writel(r, pll->pwr_addr);
+ usleep_range(1, 100);
+
+ r = readl(pll->base_addr) | pll->data->en_mask;
+ writel(r, pll->base_addr);
+
+ if (pll->tuner_addr) {
+ r = readl(pll->tuner_addr) | AUDPLL_TUNER_EN;
+ writel(r, pll->tuner_addr);
+ }
+
+ usleep_range(20, 1000);
+
+ if (pll->data->flags & HAVE_RST_BAR) {
+ r = readl(pll->base_addr) | pll->data->rst_bar_mask;
+ writel(r, pll->base_addr);
+ }
+
+ return 0;
+}
+
+static void mtk_pll_unprepare(struct clk_hw *hw)
+{
+ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
+ u32 r;
+
+ if (pll->data->flags & HAVE_RST_BAR) {
+ r = readl(pll->base_addr) & ~pll->data->rst_bar_mask;
+ writel(r, pll->base_addr);
+ }
+
+ if (pll->tuner_addr) {
+ r = readl(pll->tuner_addr) & ~AUDPLL_TUNER_EN;
+ writel(r, pll->tuner_addr);
+ }
+
+ r = readl(pll->base_addr) & ~CON0_BASE_EN;
+ writel(r, pll->base_addr);
+
+ r = readl(pll->pwr_addr) | CON0_ISO_EN;
+ writel(r, pll->pwr_addr);
+
+ r = readl(pll->pwr_addr) & ~CON0_PWR_ON;
+ writel(r, pll->pwr_addr);
+}
+
+static const struct clk_ops mtk_pll_ops = {
+ .is_prepared = mtk_pll_is_prepared,
+ .prepare = mtk_pll_prepare,
+ .unprepare = mtk_pll_unprepare,
+ .recalc_rate = mtk_pll_recalc_rate,
+ .round_rate = mtk_pll_round_rate,
+ .set_rate = mtk_pll_set_rate,
+};
+
+static struct clk *mtk_clk_register_pll(const struct mtk_pll_data *data,
+ void __iomem *base)
+{
+ struct mtk_clk_pll *pll;
+ struct clk_init_data init;
+ struct clk *clk;
+ const char *parent_name = "clk26m";
+
+ pr_debug("%s(): name: %s\n", __func__, data->name);
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ pll->base_addr = base + data->reg;
+ pll->pwr_addr = base + data->pwr_reg;
+ pll->pd_addr = base + data->pd_reg;
+ pll->pcw_addr = base + data->pcw_reg;
+ if (data->tuner_reg)
+ pll->tuner_addr = base + data->tuner_reg;
+ pll->hw.init = &init;
+ pll->data = data;
+
+ init.name = data->name;
+ init.ops = &mtk_pll_ops;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ clk = clk_register(NULL, &pll->hw);
+
+ if (IS_ERR(clk))
+ kfree(pll);
+
+ return clk;
+}
+
+void __init mtk_clk_register_plls(struct device_node *node,
+ const struct mtk_pll_data *plls, int num_plls)
+{
+ struct clk_onecell_data *clk_data;
+ void __iomem *base;
+ int r, i;
+ struct clk *clk;
+
+ base = of_iomap(node, 0);
+ if (!base) {
+ pr_err("%s(): ioremap failed\n", __func__);
+ return;
+ }
+
+ clk_data = mtk_alloc_clk_data(num_plls);
+ if (!clk_data)
+ return;
+
+ for (i = 0; i < num_plls; i++) {
+ const struct mtk_pll_data *pll = &plls[i];
+
+ clk = mtk_clk_register_pll(pll, base);
+
+ if (IS_ERR(clk)) {
+ pr_err("Failed to register clk %s: %ld\n",
+ pll->name, PTR_ERR(clk));
+ continue;
+ }
+
+ clk_data->clks[pll->id] = clk;
+ }
+
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
+}
--
2.1.4
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 2/5] clk: mediatek: Add reset controller support
2015-02-22 11:49 ` Sascha Hauer
@ 2015-02-22 11:49 ` Sascha Hauer
-1 siblings, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2015-02-22 11:49 UTC (permalink / raw)
To: Mike Turquette
Cc: Matthias Brugger, linux-arm-kernel, linux-kernel, linux-mediatek,
YH Chen, kernel, Yingjoe Chen, Eddie Huang, Henry Chen,
Sascha Hauer
The pericfg and infracfg units also provide reset lines to several
other SoC internal units. Add support for the reset controller.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/clk/mediatek/Makefile | 1 +
drivers/clk/mediatek/clk-mtk.h | 10 +++++
drivers/clk/mediatek/reset.c | 99 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 110 insertions(+)
create mode 100644 drivers/clk/mediatek/reset.c
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index c384e97..0b6f1c3 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -1 +1,2 @@
obj-y += clk-mtk.o clk-pll.o clk-gate.o
+obj-$(CONFIG_RESET_CONTROLLER) += reset.o
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index c7c0d35..fb61040 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -161,4 +161,14 @@ static inline void mtk_register_reset_controller(struct device_node *np,
}
#endif
+#ifdef CONFIG_RESET_CONTROLLER
+void mtk_register_reset_controller(struct device_node *np,
+ unsigned int num_regs, int regofs);
+#else
+static inline void mtk_register_reset_controller(struct device_node *np,
+ unsigned int num_regs, int regofs)
+{
+}
+#endif
+
#endif /* __DRV_CLK_MTK_H */
diff --git a/drivers/clk/mediatek/reset.c b/drivers/clk/mediatek/reset.c
new file mode 100644
index 0000000..3a85a53
--- /dev/null
+++ b/drivers/clk/mediatek/reset.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+#include <linux/slab.h>
+
+#include "clk-mtk.h"
+
+struct mtk_reset {
+ struct regmap *regmap;
+ int regofs;
+ struct reset_controller_dev rcdev;
+};
+
+static int mtk_reset_assert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
+
+ return regmap_update_bits(data->regmap, data->regofs + ((id / 32) << 2),
+ BIT(id % 32), ~0);
+}
+
+static int mtk_reset_deassert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
+
+ return regmap_update_bits(data->regmap, data->regofs + ((id / 32) << 2),
+ BIT(id % 32), 0);
+}
+
+static int mtk_reset(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ int ret;
+
+ ret = mtk_reset_assert(rcdev, id);
+ if (ret)
+ return ret;
+
+ return mtk_reset_deassert(rcdev, id);
+}
+
+static struct reset_control_ops mtk_reset_ops = {
+ .assert = mtk_reset_assert,
+ .deassert = mtk_reset_deassert,
+ .reset = mtk_reset,
+};
+
+void mtk_register_reset_controller(struct device_node *np,
+ unsigned int num_regs, int regofs)
+{
+ struct mtk_reset *data;
+ int ret;
+ struct regmap *regmap;
+
+ regmap = syscon_node_to_regmap(np);
+ if (IS_ERR(regmap)) {
+ pr_err("Cannot find regmap for %s: %ld\n", np->full_name,
+ PTR_ERR(regmap));
+ return;
+ }
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return;
+
+ data->regmap = regmap;
+ data->regofs = regofs;
+ data->rcdev.owner = THIS_MODULE;
+ data->rcdev.nr_resets = num_regs * 32;
+ data->rcdev.ops = &mtk_reset_ops;
+ data->rcdev.of_node = np;
+
+ ret = reset_controller_register(&data->rcdev);
+ if (ret) {
+ pr_err("could not register reset controller: %d\n", ret);
+ kfree(data);
+ return;
+ }
+}
--
2.1.4
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 2/5] clk: mediatek: Add reset controller support
@ 2015-02-22 11:49 ` Sascha Hauer
0 siblings, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2015-02-22 11:49 UTC (permalink / raw)
To: linux-arm-kernel
The pericfg and infracfg units also provide reset lines to several
other SoC internal units. Add support for the reset controller.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/clk/mediatek/Makefile | 1 +
drivers/clk/mediatek/clk-mtk.h | 10 +++++
drivers/clk/mediatek/reset.c | 99 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 110 insertions(+)
create mode 100644 drivers/clk/mediatek/reset.c
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index c384e97..0b6f1c3 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -1 +1,2 @@
obj-y += clk-mtk.o clk-pll.o clk-gate.o
+obj-$(CONFIG_RESET_CONTROLLER) += reset.o
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index c7c0d35..fb61040 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -161,4 +161,14 @@ static inline void mtk_register_reset_controller(struct device_node *np,
}
#endif
+#ifdef CONFIG_RESET_CONTROLLER
+void mtk_register_reset_controller(struct device_node *np,
+ unsigned int num_regs, int regofs);
+#else
+static inline void mtk_register_reset_controller(struct device_node *np,
+ unsigned int num_regs, int regofs)
+{
+}
+#endif
+
#endif /* __DRV_CLK_MTK_H */
diff --git a/drivers/clk/mediatek/reset.c b/drivers/clk/mediatek/reset.c
new file mode 100644
index 0000000..3a85a53
--- /dev/null
+++ b/drivers/clk/mediatek/reset.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+#include <linux/slab.h>
+
+#include "clk-mtk.h"
+
+struct mtk_reset {
+ struct regmap *regmap;
+ int regofs;
+ struct reset_controller_dev rcdev;
+};
+
+static int mtk_reset_assert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
+
+ return regmap_update_bits(data->regmap, data->regofs + ((id / 32) << 2),
+ BIT(id % 32), ~0);
+}
+
+static int mtk_reset_deassert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
+
+ return regmap_update_bits(data->regmap, data->regofs + ((id / 32) << 2),
+ BIT(id % 32), 0);
+}
+
+static int mtk_reset(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ int ret;
+
+ ret = mtk_reset_assert(rcdev, id);
+ if (ret)
+ return ret;
+
+ return mtk_reset_deassert(rcdev, id);
+}
+
+static struct reset_control_ops mtk_reset_ops = {
+ .assert = mtk_reset_assert,
+ .deassert = mtk_reset_deassert,
+ .reset = mtk_reset,
+};
+
+void mtk_register_reset_controller(struct device_node *np,
+ unsigned int num_regs, int regofs)
+{
+ struct mtk_reset *data;
+ int ret;
+ struct regmap *regmap;
+
+ regmap = syscon_node_to_regmap(np);
+ if (IS_ERR(regmap)) {
+ pr_err("Cannot find regmap for %s: %ld\n", np->full_name,
+ PTR_ERR(regmap));
+ return;
+ }
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return;
+
+ data->regmap = regmap;
+ data->regofs = regofs;
+ data->rcdev.owner = THIS_MODULE;
+ data->rcdev.nr_resets = num_regs * 32;
+ data->rcdev.ops = &mtk_reset_ops;
+ data->rcdev.of_node = np;
+
+ ret = reset_controller_register(&data->rcdev);
+ if (ret) {
+ pr_err("could not register reset controller: %d\n", ret);
+ kfree(data);
+ return;
+ }
+}
--
2.1.4
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 3/5] clk: mediatek: Add basic clocks for Mediatek MT8135.
2015-02-22 11:49 ` Sascha Hauer
@ 2015-02-22 11:49 ` Sascha Hauer
-1 siblings, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2015-02-22 11:49 UTC (permalink / raw)
To: Mike Turquette
Cc: Matthias Brugger, linux-arm-kernel, linux-kernel, linux-mediatek,
YH Chen, kernel, Yingjoe Chen, Eddie Huang, Henry Chen,
James Liao, Sascha Hauer
From: James Liao <jamesjj.liao@mediatek.com>
This patch adds basic clocks for MT8135, including TOPCKGEN, PLLs,
INFRA and PERI clocks.
Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/clk/mediatek/Makefile | 1 +
drivers/clk/mediatek/clk-mt8135.c | 634 +++++++++++++++++++++
include/dt-bindings/clock/mt8135-clk.h | 190 ++++++
.../dt-bindings/reset-controller/mt8135-resets.h | 64 +++
4 files changed, 889 insertions(+)
create mode 100644 drivers/clk/mediatek/clk-mt8135.c
create mode 100644 include/dt-bindings/clock/mt8135-clk.h
create mode 100644 include/dt-bindings/reset-controller/mt8135-resets.h
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 0b6f1c3..12ce576 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -1,2 +1,3 @@
obj-y += clk-mtk.o clk-pll.o clk-gate.o
obj-$(CONFIG_RESET_CONTROLLER) += reset.o
+obj-y += clk-mt8135.o
diff --git a/drivers/clk/mediatek/clk-mt8135.c b/drivers/clk/mediatek/clk-mt8135.c
new file mode 100644
index 0000000..6157447
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8135.c
@@ -0,0 +1,634 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/mfd/syscon.h>
+#include <dt-bindings/clock/mt8135-clk.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+static DEFINE_SPINLOCK(lock);
+
+static struct mtk_fixed_factor root_clk_alias[] __initdata = {
+ FACTOR(TOP_DSI0_LNTC_DSICLK, "dsi0_lntc_dsiclk", "clk_null", 1, 1),
+ FACTOR(TOP_HDMITX_CLKDIG_CTS, "hdmitx_clkdig_cts", "clk_null", 1, 1),
+ FACTOR(TOP_CLKPH_MCK, "clkph_mck", "clk_null", 1, 1),
+ FACTOR(TOP_CPUM_TCK_IN, "cpum_tck_in", "clk_null", 1, 1),
+};
+
+static struct mtk_fixed_factor top_divs[] __initdata = {
+ FACTOR(TOP_MAINPLL_806M, "mainpll_806m", "mainpll", 1, 2),
+ FACTOR(TOP_MAINPLL_537P3M, "mainpll_537p3m", "mainpll", 1, 3),
+ FACTOR(TOP_MAINPLL_322P4M, "mainpll_322p4m", "mainpll", 1, 5),
+ FACTOR(TOP_MAINPLL_230P3M, "mainpll_230p3m", "mainpll", 1, 7),
+
+ FACTOR(TOP_UNIVPLL_624M, "univpll_624m", "univpll", 1, 2),
+ FACTOR(TOP_UNIVPLL_416M, "univpll_416m", "univpll", 1, 3),
+ FACTOR(TOP_UNIVPLL_249P6M, "univpll_249p6m", "univpll", 1, 5),
+ FACTOR(TOP_UNIVPLL_178P3M, "univpll_178p3m", "univpll", 1, 7),
+ FACTOR(TOP_UNIVPLL_48M, "univpll_48m", "univpll", 1, 26),
+
+ FACTOR(TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2),
+ FACTOR(TOP_MMPLL_D3, "mmpll_d3", "mmpll", 1, 3),
+ FACTOR(TOP_MMPLL_D5, "mmpll_d5", "mmpll", 1, 5),
+ FACTOR(TOP_MMPLL_D7, "mmpll_d7", "mmpll", 1, 7),
+ FACTOR(TOP_MMPLL_D4, "mmpll_d4", "mmpll_d2", 1, 2),
+ FACTOR(TOP_MMPLL_D6, "mmpll_d6", "mmpll_d3", 1, 2),
+
+ FACTOR(TOP_SYSPLL_D2, "syspll_d2", "mainpll_806m", 1, 1),
+ FACTOR(TOP_SYSPLL_D4, "syspll_d4", "mainpll_806m", 1, 2),
+ FACTOR(TOP_SYSPLL_D6, "syspll_d6", "mainpll_806m", 1, 3),
+ FACTOR(TOP_SYSPLL_D8, "syspll_d8", "mainpll_806m", 1, 4),
+ FACTOR(TOP_SYSPLL_D10, "syspll_d10", "mainpll_806m", 1, 5),
+ FACTOR(TOP_SYSPLL_D12, "syspll_d12", "mainpll_806m", 1, 6),
+ FACTOR(TOP_SYSPLL_D16, "syspll_d16", "mainpll_806m", 1, 8),
+ FACTOR(TOP_SYSPLL_D24, "syspll_d24", "mainpll_806m", 1, 12),
+
+ FACTOR(TOP_SYSPLL_D3, "syspll_d3", "mainpll_537p3m", 1, 1),
+
+ FACTOR(TOP_SYSPLL_D2P5, "syspll_d2p5", "mainpll_322p4m", 2, 1),
+ FACTOR(TOP_SYSPLL_D5, "syspll_d5", "mainpll_322p4m", 1, 1),
+
+ FACTOR(TOP_SYSPLL_D3P5, "syspll_d3p5", "mainpll_230p3m", 2, 1),
+
+ FACTOR(TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_624m", 1, 2),
+ FACTOR(TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_624m", 1, 4),
+ FACTOR(TOP_UNIVPLL1_D6, "univpll1_d6", "univpll_624m", 1, 6),
+ FACTOR(TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_624m", 1, 8),
+ FACTOR(TOP_UNIVPLL1_D10, "univpll1_d10", "univpll_624m", 1, 10),
+
+ FACTOR(TOP_UNIVPLL2_D2, "univpll2_d2", "univpll_416m", 1, 2),
+ FACTOR(TOP_UNIVPLL2_D4, "univpll2_d4", "univpll_416m", 1, 4),
+ FACTOR(TOP_UNIVPLL2_D6, "univpll2_d6", "univpll_416m", 1, 6),
+ FACTOR(TOP_UNIVPLL2_D8, "univpll2_d8", "univpll_416m", 1, 8),
+
+ FACTOR(TOP_UNIVPLL_D3, "univpll_d3", "univpll_416m", 1, 1),
+ FACTOR(TOP_UNIVPLL_D5, "univpll_d5", "univpll_249p6m", 1, 1),
+ FACTOR(TOP_UNIVPLL_D7, "univpll_d7", "univpll_178p3m", 1, 1),
+ FACTOR(TOP_UNIVPLL_D10, "univpll_d10", "univpll_249p6m", 1, 5),
+ FACTOR(TOP_UNIVPLL_D26, "univpll_d26", "univpll_48m", 1, 1),
+
+ FACTOR(TOP_APLL_CK, "apll_ck", "audpll", 1, 1),
+ FACTOR(TOP_APLL_D4, "apll_d4", "audpll", 1, 4),
+ FACTOR(TOP_APLL_D8, "apll_d8", "audpll", 1, 8),
+ FACTOR(TOP_APLL_D16, "apll_d16", "audpll", 1, 16),
+ FACTOR(TOP_APLL_D24, "apll_d24", "audpll", 1, 24),
+
+ FACTOR(TOP_LVDSPLL_D2, "lvdspll_d2", "lvdspll", 1, 2),
+ FACTOR(TOP_LVDSPLL_D4, "lvdspll_d4", "lvdspll", 1, 4),
+ FACTOR(TOP_LVDSPLL_D8, "lvdspll_d8", "lvdspll", 1, 8),
+
+ FACTOR(TOP_LVDSTX_CLKDIG_CT, "lvdstx_clkdig_cts", "lvdspll", 1, 1),
+ FACTOR(TOP_VPLL_DPIX_CK, "vpll_dpix_ck", "lvdspll", 1, 1),
+
+ FACTOR(TOP_TVHDMI_H_CK, "tvhdmi_h_ck", "tvdpll", 1, 1),
+
+ FACTOR(TOP_HDMITX_CLKDIG_D2, "hdmitx_clkdig_d2", "hdmitx_clkdig_cts", 1, 2),
+ FACTOR(TOP_HDMITX_CLKDIG_D3, "hdmitx_clkdig_d3", "hdmitx_clkdig_cts", 1, 3),
+
+ FACTOR(TOP_TVHDMI_D2, "tvhdmi_d2", "tvhdmi_h_ck", 1, 2),
+ FACTOR(TOP_TVHDMI_D4, "tvhdmi_d4", "tvhdmi_h_ck", 1, 4),
+
+ FACTOR(TOP_MEMPLL_MCK_D4, "mempll_mck_d4", "clkph_mck", 1, 4),
+};
+
+static const char *axi_parents[] __initconst = {
+ "clk26m",
+ "syspll_d3",
+ "syspll_d4",
+ "syspll_d6",
+ "univpll_d5",
+ "univpll2_d2",
+ "syspll_d3p5"
+};
+
+static const char *smi_parents[] __initconst = {
+ "clk26m",
+ "clkph_mck",
+ "syspll_d2p5",
+ "syspll_d3",
+ "syspll_d8",
+ "univpll_d5",
+ "univpll1_d2",
+ "univpll1_d6",
+ "mmpll_d3",
+ "mmpll_d4",
+ "mmpll_d5",
+ "mmpll_d6",
+ "mmpll_d7",
+ "vdecpll",
+ "lvdspll"
+};
+
+static const char *mfg_parents[] __initconst = {
+ "clk26m",
+ "univpll1_d4",
+ "syspll_d2",
+ "syspll_d2p5",
+ "syspll_d3",
+ "univpll_d5",
+ "univpll1_d2",
+ "mmpll_d2",
+ "mmpll_d3",
+ "mmpll_d4",
+ "mmpll_d5",
+ "mmpll_d6",
+ "mmpll_d7"
+};
+
+static const char *irda_parents[] __initconst = {
+ "clk26m",
+ "univpll2_d8",
+ "univpll1_d6"
+};
+
+static const char *cam_parents[] __initconst = {
+ "clk26m",
+ "syspll_d3",
+ "syspll_d3p5",
+ "syspll_d4",
+ "univpll_d5",
+ "univpll2_d2",
+ "univpll_d7",
+ "univpll1_d4"
+};
+
+static const char *aud_intbus_parents[] __initconst = {
+ "clk26m",
+ "syspll_d6",
+ "univpll_d10"
+};
+
+static const char *jpg_parents[] __initconst = {
+ "clk26m",
+ "syspll_d5",
+ "syspll_d4",
+ "syspll_d3",
+ "univpll_d7",
+ "univpll2_d2",
+ "univpll_d5"
+};
+
+static const char *disp_parents[] __initconst = {
+ "clk26m",
+ "syspll_d3p5",
+ "syspll_d3",
+ "univpll2_d2",
+ "univpll_d5",
+ "univpll1_d2",
+ "lvdspll",
+ "vdecpll"
+};
+
+static const char *msdc30_parents[] __initconst = {
+ "clk26m",
+ "syspll_d6",
+ "syspll_d5",
+ "univpll1_d4",
+ "univpll2_d4",
+ "msdcpll"
+};
+
+static const char *usb20_parents[] __initconst = {
+ "clk26m",
+ "univpll2_d6",
+ "univpll1_d10"
+};
+
+static const char *venc_parents[] __initconst = {
+ "clk26m",
+ "syspll_d3",
+ "syspll_d8",
+ "univpll_d5",
+ "univpll1_d6",
+ "mmpll_d4",
+ "mmpll_d5",
+ "mmpll_d6"
+};
+
+static const char *spi_parents[] __initconst = {
+ "clk26m",
+ "syspll_d6",
+ "syspll_d8",
+ "syspll_d10",
+ "univpll1_d6",
+ "univpll1_d8"
+};
+
+static const char *uart_parents[] __initconst = {
+ "clk26m",
+ "univpll2_d8"
+};
+
+static const char *mem_parents[] __initconst = {
+ "clk26m",
+ "clkph_mck"
+};
+
+static const char *camtg_parents[] __initconst = {
+ "clk26m",
+ "univpll_d26",
+ "univpll1_d6",
+ "syspll_d16",
+ "syspll_d8"
+};
+
+static const char *audio_parents[] __initconst = {
+ "clk26m",
+ "syspll_d24"
+};
+
+static const char *fix_parents[] __initconst = {
+ "rtc32k",
+ "clk26m",
+ "univpll_d5",
+ "univpll_d7",
+ "univpll1_d2",
+ "univpll1_d4",
+ "univpll1_d6",
+ "univpll1_d8"
+};
+
+static const char *vdec_parents[] __initconst = {
+ "clk26m",
+ "vdecpll",
+ "clkph_mck",
+ "syspll_d2p5",
+ "syspll_d3",
+ "syspll_d3p5",
+ "syspll_d4",
+ "syspll_d5",
+ "syspll_d6",
+ "syspll_d8",
+ "univpll1_d2",
+ "univpll2_d2",
+ "univpll_d7",
+ "univpll_d10",
+ "univpll2_d4",
+ "lvdspll"
+};
+
+static const char *ddrphycfg_parents[] __initconst = {
+ "clk26m",
+ "axi_sel",
+ "syspll_d12"
+};
+
+static const char *dpilvds_parents[] __initconst = {
+ "clk26m",
+ "lvdspll",
+ "lvdspll_d2",
+ "lvdspll_d4",
+ "lvdspll_d8"
+};
+
+static const char *pmicspi_parents[] __initconst = {
+ "clk26m",
+ "univpll2_d6",
+ "syspll_d8",
+ "syspll_d10",
+ "univpll1_d10",
+ "mempll_mck_d4",
+ "univpll_d26",
+ "syspll_d24"
+};
+
+static const char *smi_mfg_as_parents[] __initconst = {
+ "clk26m",
+ "smi_sel",
+ "mfg_sel",
+ "mem_sel"
+};
+
+static const char *gcpu_parents[] __initconst = {
+ "clk26m",
+ "syspll_d4",
+ "univpll_d7",
+ "syspll_d5",
+ "syspll_d6"
+};
+
+static const char *dpi1_parents[] __initconst = {
+ "clk26m",
+ "tvhdmi_h_ck",
+ "tvhdmi_d2",
+ "tvhdmi_d4"
+};
+
+static const char *cci_parents[] __initconst = {
+ "clk26m",
+ "mainpll_537p3m",
+ "univpll_d3",
+ "syspll_d2p5",
+ "syspll_d3",
+ "syspll_d5"
+};
+
+static const char *apll_parents[] __initconst = {
+ "clk26m",
+ "apll_ck",
+ "apll_d4",
+ "apll_d8",
+ "apll_d16",
+ "apll_d24"
+};
+
+static const char *hdmipll_parents[] __initconst = {
+ "clk26m",
+ "hdmitx_clkdig_cts",
+ "hdmitx_clkdig_d2",
+ "hdmitx_clkdig_d3"
+};
+
+static struct mtk_composite top_muxes[] __initdata = {
+ /* CLK_CFG_0 */
+ MUX_GATE(TOP_AXI_SEL, "axi_sel", axi_parents,
+ 0x0140, 0, 3, INVALID_MUX_GATE_BIT),
+ MUX_GATE(TOP_SMI_SEL, "smi_sel", smi_parents, 0x0140, 8, 4, 15),
+ MUX_GATE(TOP_MFG_SEL, "mfg_sel", mfg_parents, 0x0140, 16, 4, 23),
+ MUX_GATE(TOP_IRDA_SEL, "irda_sel", irda_parents, 0x0140, 24, 2, 31),
+ /* CLK_CFG_1 */
+ MUX_GATE(TOP_CAM_SEL, "cam_sel", cam_parents, 0x0144, 0, 3, 7),
+ MUX_GATE(TOP_AUD_INTBUS_SEL, "aud_intbus_sel", aud_intbus_parents,
+ 0x0144, 8, 2, 15),
+ MUX_GATE(TOP_JPG_SEL, "jpg_sel", jpg_parents, 0x0144, 16, 3, 23),
+ MUX_GATE(TOP_DISP_SEL, "disp_sel", disp_parents, 0x0144, 24, 3, 31),
+ /* CLK_CFG_2 */
+ MUX_GATE(TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_parents, 0x0148, 0, 3, 7),
+ MUX_GATE(TOP_MSDC30_2_SEL, "msdc30_2_sel", msdc30_parents, 0x0148, 8, 3, 15),
+ MUX_GATE(TOP_MSDC30_3_SEL, "msdc30_3_sel", msdc30_parents, 0x0148, 16, 3, 23),
+ MUX_GATE(TOP_MSDC30_4_SEL, "msdc30_4_sel", msdc30_parents, 0x0148, 24, 3, 31),
+ /* CLK_CFG_3 */
+ MUX_GATE(TOP_USB20_SEL, "usb20_sel", usb20_parents, 0x014c, 0, 2, 7),
+ /* CLK_CFG_4 */
+ MUX_GATE(TOP_VENC_SEL, "venc_sel", venc_parents, 0x0150, 8, 3, 15),
+ MUX_GATE(TOP_SPI_SEL, "spi_sel", spi_parents, 0x0150, 16, 3, 23),
+ MUX_GATE(TOP_UART_SEL, "uart_sel", uart_parents, 0x0150, 24, 2, 31),
+ /* CLK_CFG_6 */
+ MUX_GATE(TOP_MEM_SEL, "mem_sel", mem_parents, 0x0158, 0, 2, 7),
+ MUX_GATE(TOP_CAMTG_SEL, "camtg_sel", camtg_parents, 0x0158, 8, 3, 15),
+ MUX_GATE(TOP_AUDIO_SEL, "audio_sel", audio_parents, 0x0158, 24, 2, 31),
+ /* CLK_CFG_7 */
+ MUX_GATE(TOP_FIX_SEL, "fix_sel", fix_parents, 0x015c, 0, 3, 7),
+ MUX_GATE(TOP_VDEC_SEL, "vdec_sel", vdec_parents, 0x015c, 8, 4, 15),
+ MUX_GATE(TOP_DDRPHYCFG_SEL, "ddrphycfg_sel", ddrphycfg_parents,
+ 0x015c, 16, 2, 23),
+ MUX_GATE(TOP_DPILVDS_SEL, "dpilvds_sel", dpilvds_parents, 0x015c, 24, 3, 31),
+ /* CLK_CFG_8 */
+ MUX_GATE(TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents, 0x0164, 0, 3, 7),
+ MUX_GATE(TOP_MSDC30_0_SEL, "msdc30_0_sel", msdc30_parents, 0x0164, 8, 3, 15),
+ MUX_GATE(TOP_SMI_MFG_AS_SEL, "smi_mfg_as_sel", smi_mfg_as_parents,
+ 0x0164, 16, 2, 23),
+ MUX_GATE(TOP_GCPU_SEL, "gcpu_sel", gcpu_parents, 0x0164, 24, 3, 31),
+ /* CLK_CFG_9 */
+ MUX_GATE(TOP_DPI1_SEL, "dpi1_sel", dpi1_parents, 0x0168, 0, 2, 7),
+ MUX_GATE(TOP_CCI_SEL, "cci_sel", cci_parents, 0x0168, 8, 3, 15),
+ MUX_GATE(TOP_APLL_SEL, "apll_sel", apll_parents, 0x0168, 16, 3, 23),
+ MUX_GATE(TOP_HDMIPLL_SEL, "hdmipll_sel", hdmipll_parents, 0x0168, 24, 2, 31),
+};
+
+static void __init mtk_init_clk_topckgen(void __iomem *top_base,
+ struct clk_onecell_data *clk_data)
+{
+ int i;
+ struct clk *clk;
+
+ for (i = 0; i < ARRAY_SIZE(top_muxes); i++) {
+ struct mtk_composite *mux = &top_muxes[i];
+
+ clk = mtk_clk_register_composite(mux, top_base, &lock);
+
+ if (IS_ERR(clk)) {
+ pr_err("Failed to register clk %s: %ld\n",
+ mux->name, PTR_ERR(clk));
+ continue;
+ }
+
+ if (clk_data)
+ clk_data->clks[mux->id] = clk;
+ }
+}
+
+static struct mtk_gate_regs infra_cg_regs = {
+ .set_ofs = 0x0040,
+ .clr_ofs = 0x0044,
+ .sta_ofs = 0x0048,
+};
+
+#define GATE_ICG(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &infra_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_setclr, \
+ }
+
+static struct mtk_gate infra_clks[] __initdata = {
+ GATE_ICG(INFRA_PMIC_WRAP_CK, "pmic_wrap_ck", "axi_sel", 23),
+ GATE_ICG(INFRA_PMICSPI_CK, "pmicspi_ck", "pmicspi_sel", 22),
+ GATE_ICG(INFRA_CCIF1_AP_CTRL, "ccif1_ap_ctrl", "axi_sel", 21),
+ GATE_ICG(INFRA_CCIF0_AP_CTRL, "ccif0_ap_ctrl", "axi_sel", 20),
+ GATE_ICG(INFRA_KP_CK, "kp_ck", "axi_sel", 16),
+ GATE_ICG(INFRA_CPUM_CK, "cpum_ck", "cpum_tck_in", 15),
+ GATE_ICG(INFRA_M4U_CK, "m4u_ck", "mem_sel", 8),
+ GATE_ICG(INFRA_MFGAXI_CK, "mfgaxi_ck", "axi_sel", 7),
+ GATE_ICG(INFRA_DEVAPC_CK, "devapc_ck", "axi_sel", 6),
+ GATE_ICG(INFRA_AUDIO_CK, "audio_ck", "aud_intbus_sel", 5),
+ GATE_ICG(INFRA_MFG_BUS_CK, "mfg_bus_ck", "axi_sel", 2),
+ GATE_ICG(INFRA_SMI_CK, "smi_ck", "smi_sel", 1),
+ GATE_ICG(INFRA_DBGCLK_CK, "dbgclk_ck", "axi_sel", 0),
+};
+
+static struct mtk_gate_regs peri0_cg_regs = {
+ .set_ofs = 0x0008,
+ .clr_ofs = 0x0010,
+ .sta_ofs = 0x0018,
+};
+
+static struct mtk_gate_regs peri1_cg_regs = {
+ .set_ofs = 0x000c,
+ .clr_ofs = 0x0014,
+ .sta_ofs = 0x001c,
+};
+
+#define GATE_PERI0(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &peri0_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_setclr, \
+ }
+
+#define GATE_PERI1(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &peri1_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_setclr, \
+ }
+
+static struct mtk_gate peri_clks[] __initdata = {
+ /* PERI0 */
+ GATE_PERI0(PERI_I2C5_CK, "i2c5_ck", "axi_sel", 31),
+ GATE_PERI0(PERI_I2C4_CK, "i2c4_ck", "axi_sel", 30),
+ GATE_PERI0(PERI_I2C3_CK, "i2c3_ck", "axi_sel", 29),
+ GATE_PERI0(PERI_I2C2_CK, "i2c2_ck", "axi_sel", 28),
+ GATE_PERI0(PERI_I2C1_CK, "i2c1_ck", "axi_sel", 27),
+ GATE_PERI0(PERI_I2C0_CK, "i2c0_ck", "axi_sel", 26),
+ GATE_PERI0(PERI_UART3_CK, "uart3_ck", "axi_sel", 25),
+ GATE_PERI0(PERI_UART2_CK, "uart2_ck", "axi_sel", 24),
+ GATE_PERI0(PERI_UART1_CK, "uart1_ck", "axi_sel", 23),
+ GATE_PERI0(PERI_UART0_CK, "uart0_ck", "axi_sel", 22),
+ GATE_PERI0(PERI_IRDA_CK, "irda_ck", "irda_sel", 21),
+ GATE_PERI0(PERI_NLI_CK, "nli_ck", "axi_sel", 20),
+ GATE_PERI0(PERI_MD_HIF_CK, "md_hif_ck", "axi_sel", 19),
+ GATE_PERI0(PERI_AP_HIF_CK, "ap_hif_ck", "axi_sel", 18),
+ GATE_PERI0(PERI_MSDC30_3_CK, "msdc30_3_ck", "msdc30_4_sel", 17),
+ GATE_PERI0(PERI_MSDC30_2_CK, "msdc30_2_ck", "msdc30_3_sel", 16),
+ GATE_PERI0(PERI_MSDC30_1_CK, "msdc30_1_ck", "msdc30_2_sel", 15),
+ GATE_PERI0(PERI_MSDC20_2_CK, "msdc20_2_ck", "msdc30_1_sel", 14),
+ GATE_PERI0(PERI_MSDC20_1_CK, "msdc20_1_ck", "msdc30_0_sel", 13),
+ GATE_PERI0(PERI_AP_DMA_CK, "ap_dma_ck", "axi_sel", 12),
+ GATE_PERI0(PERI_USB1_CK, "usb1_ck", "usb20_sel", 11),
+ GATE_PERI0(PERI_USB0_CK, "usb0_ck", "usb20_sel", 10),
+ GATE_PERI0(PERI_PWM_CK, "pwm_ck", "axi_sel", 9),
+ GATE_PERI0(PERI_PWM7_CK, "pwm7_ck", "axi_sel", 8),
+ GATE_PERI0(PERI_PWM6_CK, "pwm6_ck", "axi_sel", 7),
+ GATE_PERI0(PERI_PWM5_CK, "pwm5_ck", "axi_sel", 6),
+ GATE_PERI0(PERI_PWM4_CK, "pwm4_ck", "axi_sel", 5),
+ GATE_PERI0(PERI_PWM3_CK, "pwm3_ck", "axi_sel", 4),
+ GATE_PERI0(PERI_PWM2_CK, "pwm2_ck", "axi_sel", 3),
+ GATE_PERI0(PERI_PWM1_CK, "pwm1_ck", "axi_sel", 2),
+ GATE_PERI0(PERI_THERM_CK, "therm_ck", "axi_sel", 1),
+ GATE_PERI0(PERI_NFI_CK, "nfi_ck", "axi_sel", 0),
+ /* PERI1 */
+ GATE_PERI1(PERI_USBSLV_CK, "usbslv_ck", "axi_sel", 8),
+ GATE_PERI1(PERI_USB1_MCU_CK, "usb1_mcu_ck", "axi_sel", 7),
+ GATE_PERI1(PERI_USB0_MCU_CK, "usb0_mcu_ck", "axi_sel", 6),
+ GATE_PERI1(PERI_GCPU_CK, "gcpu_ck", "gcpu_sel", 5),
+ GATE_PERI1(PERI_FHCTL_CK, "fhctl_ck", "clk26m", 4),
+ GATE_PERI1(PERI_SPI1_CK, "spi1_ck", "spi_sel", 3),
+ GATE_PERI1(PERI_AUXADC_CK, "auxadc_ck", "clk26m", 2),
+ GATE_PERI1(PERI_PERI_PWRAP_CK, "peri_pwrap_ck", "axi_sel", 1),
+ GATE_PERI1(PERI_I2C6_CK, "i2c6_ck", "axi_sel", 0),
+};
+
+static void __init mtk_topckgen_init(struct device_node *node)
+{
+ struct clk_onecell_data *clk_data;
+ void __iomem *base;
+ int r;
+
+ base = of_iomap(node, 0);
+ if (!base) {
+ pr_err("%s(): ioremap failed\n", __func__);
+ return;
+ }
+
+ clk_data = mtk_alloc_clk_data(TOP_NR_CLK);
+
+ mtk_clk_register_factors(root_clk_alias, ARRAY_SIZE(root_clk_alias), clk_data);
+ mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
+ mtk_init_clk_topckgen(base, clk_data);
+
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
+}
+CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt8135-topckgen", mtk_topckgen_init);
+
+static void __init mtk_infrasys_init(struct device_node *node)
+{
+ struct clk_onecell_data *clk_data;
+ int r;
+
+ clk_data = mtk_alloc_clk_data(INFRA_NR_CLK);
+
+ mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
+ clk_data);
+
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
+
+ mtk_register_reset_controller(node, 2, 0x30);
+}
+CLK_OF_DECLARE(mtk_infrasys, "mediatek,mt8135-infracfg", mtk_infrasys_init);
+
+static void __init mtk_pericfg_init(struct device_node *node)
+{
+ struct clk_onecell_data *clk_data;
+ int r;
+
+ clk_data = mtk_alloc_clk_data(PERI_NR_CLK);
+
+ mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
+ clk_data);
+
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
+
+ mtk_register_reset_controller(node, 2, 0);
+}
+CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt8135-pericfg", mtk_pericfg_init);
+
+#define MT8135_PLL_FMAX (2000 * MHZ)
+#define CON0_MT8135_RST_BAR BIT(27)
+
+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) { \
+ .id = _id, \
+ .name = _name, \
+ .reg = _reg, \
+ .pwr_reg = _pwr_reg, \
+ .en_mask = _en_mask, \
+ .flags = _flags, \
+ .rst_bar_mask = CON0_MT8135_RST_BAR, \
+ .fmax = MT8135_PLL_FMAX, \
+ .pcwbits = _pcwbits, \
+ .pd_reg = _pd_reg, \
+ .pd_shift = _pd_shift, \
+ .tuner_reg = _tuner_reg, \
+ .pcw_reg = _pcw_reg, \
+ .pcw_shift = _pcw_shift, \
+ }
+
+static struct mtk_pll_data plls[] = {
+ PLL(APMIXED_ARMPLL1, "armpll1", 0x200, 0x218, 0x80000001, 0, 21, 0x204, 24, 0x0, 0x204, 0),
+ PLL(APMIXED_ARMPLL2, "armpll2", 0x2cc, 0x2e4, 0x80000001, 0, 21, 0x2d0, 24, 0x0, 0x2d0, 0),
+ PLL(APMIXED_MAINPLL, "mainpll", 0x21c, 0x234, 0xf0000001, HAVE_RST_BAR, 21, 0x21c, 6, 0x0, 0x220, 0),
+ PLL(APMIXED_UNIVPLL, "univpll", 0x238, 0x250, 0xf3000001, HAVE_RST_BAR, 7, 0x238, 6, 0x0, 0x238, 9),
+ PLL(APMIXED_MMPLL, "mmpll", 0x254, 0x26c, 0xf0000001, HAVE_RST_BAR, 21, 0x254, 6, 0x0, 0x258, 0),
+ PLL(APMIXED_MSDCPLL, "msdcpll", 0x278, 0x290, 0x80000001, 0, 21, 0x278, 6, 0x0, 0x27c, 0),
+ PLL(APMIXED_TVDPLL, "tvdpll", 0x294, 0x2ac, 0x80000001, 0, 31, 0x296, 6, 0x0, 0x298, 0),
+ PLL(APMIXED_LVDSPLL, "lvdspll", 0x2b0, 0x2c8, 0x80000001, 0, 21, 0x2b0, 6, 0x0, 0x2b4, 0),
+ PLL(APMIXED_AUDPLL, "audpll", 0x2e8, 0x300, 0x80000001, 0, 31, 0x2e8, 6, 0x2f8, 0x2ec, 0),
+ PLL(APMIXED_VDECPLL, "vdecpll", 0x304, 0x31c, 0x80000001, 0, 21, 0x2b0, 6, 0x0, 0x308, 0),
+};
+
+static void __init mtk_apmixedsys_init(struct device_node *node)
+{
+ mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls));
+}
+CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt8135-apmixedsys",
+ mtk_apmixedsys_init);
diff --git a/include/dt-bindings/clock/mt8135-clk.h b/include/dt-bindings/clock/mt8135-clk.h
new file mode 100644
index 0000000..8aea762
--- /dev/null
+++ b/include/dt-bindings/clock/mt8135-clk.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 _DT_BINDINGS_CLK_MT8135_H
+#define _DT_BINDINGS_CLK_MT8135_H
+
+/* TOPCKGEN */
+
+#define TOP_DSI0_LNTC_DSICLK 1
+#define TOP_HDMITX_CLKDIG_CTS 2
+#define TOP_CLKPH_MCK 3
+#define TOP_CPUM_TCK_IN 4
+#define TOP_MAINPLL_806M 5
+#define TOP_MAINPLL_537P3M 6
+#define TOP_MAINPLL_322P4M 7
+#define TOP_MAINPLL_230P3M 8
+#define TOP_UNIVPLL_624M 9
+#define TOP_UNIVPLL_416M 10
+#define TOP_UNIVPLL_249P6M 11
+#define TOP_UNIVPLL_178P3M 12
+#define TOP_UNIVPLL_48M 13
+#define TOP_MMPLL_D2 14
+#define TOP_MMPLL_D3 15
+#define TOP_MMPLL_D5 16
+#define TOP_MMPLL_D7 17
+#define TOP_MMPLL_D4 18
+#define TOP_MMPLL_D6 19
+#define TOP_SYSPLL_D2 20
+#define TOP_SYSPLL_D4 21
+#define TOP_SYSPLL_D6 22
+#define TOP_SYSPLL_D8 23
+#define TOP_SYSPLL_D10 24
+#define TOP_SYSPLL_D12 25
+#define TOP_SYSPLL_D16 26
+#define TOP_SYSPLL_D24 27
+#define TOP_SYSPLL_D3 28
+#define TOP_SYSPLL_D2P5 29
+#define TOP_SYSPLL_D5 30
+#define TOP_SYSPLL_D3P5 31
+#define TOP_UNIVPLL1_D2 32
+#define TOP_UNIVPLL1_D4 33
+#define TOP_UNIVPLL1_D6 34
+#define TOP_UNIVPLL1_D8 35
+#define TOP_UNIVPLL1_D10 36
+#define TOP_UNIVPLL2_D2 37
+#define TOP_UNIVPLL2_D4 38
+#define TOP_UNIVPLL2_D6 39
+#define TOP_UNIVPLL2_D8 40
+#define TOP_UNIVPLL_D3 41
+#define TOP_UNIVPLL_D5 42
+#define TOP_UNIVPLL_D7 43
+#define TOP_UNIVPLL_D10 44
+#define TOP_UNIVPLL_D26 45
+#define TOP_APLL_CK 46
+#define TOP_APLL_D4 47
+#define TOP_APLL_D8 48
+#define TOP_APLL_D16 49
+#define TOP_APLL_D24 50
+#define TOP_LVDSPLL_D2 51
+#define TOP_LVDSPLL_D4 52
+#define TOP_LVDSPLL_D8 53
+#define TOP_LVDSTX_CLKDIG_CT 54
+#define TOP_VPLL_DPIX_CK 55
+#define TOP_TVHDMI_H_CK 56
+#define TOP_HDMITX_CLKDIG_D2 57
+#define TOP_HDMITX_CLKDIG_D3 58
+#define TOP_TVHDMI_D2 59
+#define TOP_TVHDMI_D4 60
+#define TOP_MEMPLL_MCK_D4 61
+#define TOP_AXI_SEL 62
+#define TOP_SMI_SEL 63
+#define TOP_MFG_SEL 64
+#define TOP_IRDA_SEL 65
+#define TOP_CAM_SEL 66
+#define TOP_AUD_INTBUS_SEL 67
+#define TOP_JPG_SEL 68
+#define TOP_DISP_SEL 69
+#define TOP_MSDC30_1_SEL 70
+#define TOP_MSDC30_2_SEL 71
+#define TOP_MSDC30_3_SEL 72
+#define TOP_MSDC30_4_SEL 73
+#define TOP_USB20_SEL 74
+#define TOP_VENC_SEL 75
+#define TOP_SPI_SEL 76
+#define TOP_UART_SEL 77
+#define TOP_MEM_SEL 78
+#define TOP_CAMTG_SEL 79
+#define TOP_AUDIO_SEL 80
+#define TOP_FIX_SEL 81
+#define TOP_VDEC_SEL 82
+#define TOP_DDRPHYCFG_SEL 83
+#define TOP_DPILVDS_SEL 84
+#define TOP_PMICSPI_SEL 85
+#define TOP_MSDC30_0_SEL 86
+#define TOP_SMI_MFG_AS_SEL 87
+#define TOP_GCPU_SEL 88
+#define TOP_DPI1_SEL 89
+#define TOP_CCI_SEL 90
+#define TOP_APLL_SEL 91
+#define TOP_HDMIPLL_SEL 92
+#define TOP_NR_CLK 93
+
+/* APMIXED_SYS */
+
+#define APMIXED_ARMPLL1 1
+#define APMIXED_ARMPLL2 2
+#define APMIXED_MAINPLL 3
+#define APMIXED_UNIVPLL 4
+#define APMIXED_MMPLL 5
+#define APMIXED_MSDCPLL 6
+#define APMIXED_TVDPLL 7
+#define APMIXED_LVDSPLL 8
+#define APMIXED_AUDPLL 9
+#define APMIXED_VDECPLL 10
+#define APMIXED_NR_CLK 11
+
+/* INFRA_SYS */
+
+#define INFRA_PMIC_WRAP_CK 1
+#define INFRA_PMICSPI_CK 2
+#define INFRA_CCIF1_AP_CTRL 3
+#define INFRA_CCIF0_AP_CTRL 4
+#define INFRA_KP_CK 5
+#define INFRA_CPUM_CK 6
+#define INFRA_M4U_CK 7
+#define INFRA_MFGAXI_CK 8
+#define INFRA_DEVAPC_CK 9
+#define INFRA_AUDIO_CK 10
+#define INFRA_MFG_BUS_CK 11
+#define INFRA_SMI_CK 12
+#define INFRA_DBGCLK_CK 13
+#define INFRA_NR_CLK 14
+
+/* PERI_SYS */
+
+#define PERI_I2C5_CK 1
+#define PERI_I2C4_CK 2
+#define PERI_I2C3_CK 3
+#define PERI_I2C2_CK 4
+#define PERI_I2C1_CK 5
+#define PERI_I2C0_CK 6
+#define PERI_UART3_CK 7
+#define PERI_UART2_CK 8
+#define PERI_UART1_CK 9
+#define PERI_UART0_CK 10
+#define PERI_IRDA_CK 11
+#define PERI_NLI_CK 12
+#define PERI_MD_HIF_CK 13
+#define PERI_AP_HIF_CK 14
+#define PERI_MSDC30_3_CK 15
+#define PERI_MSDC30_2_CK 16
+#define PERI_MSDC30_1_CK 17
+#define PERI_MSDC20_2_CK 18
+#define PERI_MSDC20_1_CK 19
+#define PERI_AP_DMA_CK 20
+#define PERI_USB1_CK 21
+#define PERI_USB0_CK 22
+#define PERI_PWM_CK 23
+#define PERI_PWM7_CK 24
+#define PERI_PWM6_CK 25
+#define PERI_PWM5_CK 26
+#define PERI_PWM4_CK 27
+#define PERI_PWM3_CK 28
+#define PERI_PWM2_CK 29
+#define PERI_PWM1_CK 30
+#define PERI_THERM_CK 31
+#define PERI_NFI_CK 32
+#define PERI_USBSLV_CK 33
+#define PERI_USB1_MCU_CK 34
+#define PERI_USB0_MCU_CK 35
+#define PERI_GCPU_CK 36
+#define PERI_FHCTL_CK 37
+#define PERI_SPI1_CK 38
+#define PERI_AUXADC_CK 39
+#define PERI_PERI_PWRAP_CK 40
+#define PERI_I2C6_CK 41
+#define PERI_NR_CLK 42
+
+#endif /* _DT_BINDINGS_CLK_MT8135_H */
diff --git a/include/dt-bindings/reset-controller/mt8135-resets.h b/include/dt-bindings/reset-controller/mt8135-resets.h
new file mode 100644
index 0000000..1fb6295
--- /dev/null
+++ b/include/dt-bindings/reset-controller/mt8135-resets.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: Flora Fu, MediaTek
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 _DT_BINDINGS_RESET_CONTROLLER_MT8135
+#define _DT_BINDINGS_RESET_CONTROLLER_MT8135
+
+/* INFRACFG resets */
+#define MT8135_INFRA_EMI_REG_RST 0
+#define MT8135_INFRA_DRAMC0_A0_RST 1
+#define MT8135_INFRA_CCIF0_RST 2
+#define MT8135_INFRA_APCIRQ_EINT_RST 3
+#define MT8135_INFRA_APXGPT_RST 4
+#define MT8135_INFRA_SCPSYS_RST 5
+#define MT8135_INFRA_CCIF1_RST 6
+#define MT8135_INFRA_PMIC_WRAP_RST 7
+#define MT8135_INFRA_KP_RST 8
+#define MT8135_INFRA_EMI_RST 32
+#define MT8135_INFRA_DRAMC0_RST 34
+#define MT8135_INFRA_SMI_RST 35
+#define MT8135_INFRA_M4U_RST 36
+
+/* PERICFG resets */
+#define MT8135_PERI_UART0_SW_RST 0
+#define MT8135_PERI_UART1_SW_RST 1
+#define MT8135_PERI_UART2_SW_RST 2
+#define MT8135_PERI_UART3_SW_RST 3
+#define MT8135_PERI_IRDA_SW_RST 4
+#define MT8135_PERI_PTP_SW_RST 5
+#define MT8135_PERI_AP_HIF_SW_RST 6
+#define MT8135_PERI_GPCU_SW_RST 7
+#define MT8135_PERI_MD_HIF_SW_RST 8
+#define MT8135_PERI_NLI_SW_RST 9
+#define MT8135_PERI_AUXADC_SW_RST 10
+#define MT8135_PERI_DMA_SW_RST 11
+#define MT8135_PERI_NFI_SW_RST 14
+#define MT8135_PERI_PWM_SW_RST 15
+#define MT8135_PERI_THERM_SW_RST 16
+#define MT8135_PERI_MSDC0_SW_RST 17
+#define MT8135_PERI_MSDC1_SW_RST 18
+#define MT8135_PERI_MSDC2_SW_RST 19
+#define MT8135_PERI_MSDC3_SW_RST 20
+#define MT8135_PERI_I2C0_SW_RST 22
+#define MT8135_PERI_I2C1_SW_RST 23
+#define MT8135_PERI_I2C2_SW_RST 24
+#define MT8135_PERI_I2C3_SW_RST 25
+#define MT8135_PERI_I2C4_SW_RST 26
+#define MT8135_PERI_I2C5_SW_RST 27
+#define MT8135_PERI_I2C6_SW_RST 28
+#define MT8135_PERI_USB_SW_RST 29
+#define MT8135_PERI_SPI1_SW_RST 33
+#define MT8135_PERI_PWRAP_BRIDGE_SW_RST 34
+
+#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT8135 */
--
2.1.4
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 3/5] clk: mediatek: Add basic clocks for Mediatek MT8135.
@ 2015-02-22 11:49 ` Sascha Hauer
0 siblings, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2015-02-22 11:49 UTC (permalink / raw)
To: linux-arm-kernel
From: James Liao <jamesjj.liao@mediatek.com>
This patch adds basic clocks for MT8135, including TOPCKGEN, PLLs,
INFRA and PERI clocks.
Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/clk/mediatek/Makefile | 1 +
drivers/clk/mediatek/clk-mt8135.c | 634 +++++++++++++++++++++
include/dt-bindings/clock/mt8135-clk.h | 190 ++++++
.../dt-bindings/reset-controller/mt8135-resets.h | 64 +++
4 files changed, 889 insertions(+)
create mode 100644 drivers/clk/mediatek/clk-mt8135.c
create mode 100644 include/dt-bindings/clock/mt8135-clk.h
create mode 100644 include/dt-bindings/reset-controller/mt8135-resets.h
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 0b6f1c3..12ce576 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -1,2 +1,3 @@
obj-y += clk-mtk.o clk-pll.o clk-gate.o
obj-$(CONFIG_RESET_CONTROLLER) += reset.o
+obj-y += clk-mt8135.o
diff --git a/drivers/clk/mediatek/clk-mt8135.c b/drivers/clk/mediatek/clk-mt8135.c
new file mode 100644
index 0000000..6157447
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8135.c
@@ -0,0 +1,634 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/mfd/syscon.h>
+#include <dt-bindings/clock/mt8135-clk.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+static DEFINE_SPINLOCK(lock);
+
+static struct mtk_fixed_factor root_clk_alias[] __initdata = {
+ FACTOR(TOP_DSI0_LNTC_DSICLK, "dsi0_lntc_dsiclk", "clk_null", 1, 1),
+ FACTOR(TOP_HDMITX_CLKDIG_CTS, "hdmitx_clkdig_cts", "clk_null", 1, 1),
+ FACTOR(TOP_CLKPH_MCK, "clkph_mck", "clk_null", 1, 1),
+ FACTOR(TOP_CPUM_TCK_IN, "cpum_tck_in", "clk_null", 1, 1),
+};
+
+static struct mtk_fixed_factor top_divs[] __initdata = {
+ FACTOR(TOP_MAINPLL_806M, "mainpll_806m", "mainpll", 1, 2),
+ FACTOR(TOP_MAINPLL_537P3M, "mainpll_537p3m", "mainpll", 1, 3),
+ FACTOR(TOP_MAINPLL_322P4M, "mainpll_322p4m", "mainpll", 1, 5),
+ FACTOR(TOP_MAINPLL_230P3M, "mainpll_230p3m", "mainpll", 1, 7),
+
+ FACTOR(TOP_UNIVPLL_624M, "univpll_624m", "univpll", 1, 2),
+ FACTOR(TOP_UNIVPLL_416M, "univpll_416m", "univpll", 1, 3),
+ FACTOR(TOP_UNIVPLL_249P6M, "univpll_249p6m", "univpll", 1, 5),
+ FACTOR(TOP_UNIVPLL_178P3M, "univpll_178p3m", "univpll", 1, 7),
+ FACTOR(TOP_UNIVPLL_48M, "univpll_48m", "univpll", 1, 26),
+
+ FACTOR(TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2),
+ FACTOR(TOP_MMPLL_D3, "mmpll_d3", "mmpll", 1, 3),
+ FACTOR(TOP_MMPLL_D5, "mmpll_d5", "mmpll", 1, 5),
+ FACTOR(TOP_MMPLL_D7, "mmpll_d7", "mmpll", 1, 7),
+ FACTOR(TOP_MMPLL_D4, "mmpll_d4", "mmpll_d2", 1, 2),
+ FACTOR(TOP_MMPLL_D6, "mmpll_d6", "mmpll_d3", 1, 2),
+
+ FACTOR(TOP_SYSPLL_D2, "syspll_d2", "mainpll_806m", 1, 1),
+ FACTOR(TOP_SYSPLL_D4, "syspll_d4", "mainpll_806m", 1, 2),
+ FACTOR(TOP_SYSPLL_D6, "syspll_d6", "mainpll_806m", 1, 3),
+ FACTOR(TOP_SYSPLL_D8, "syspll_d8", "mainpll_806m", 1, 4),
+ FACTOR(TOP_SYSPLL_D10, "syspll_d10", "mainpll_806m", 1, 5),
+ FACTOR(TOP_SYSPLL_D12, "syspll_d12", "mainpll_806m", 1, 6),
+ FACTOR(TOP_SYSPLL_D16, "syspll_d16", "mainpll_806m", 1, 8),
+ FACTOR(TOP_SYSPLL_D24, "syspll_d24", "mainpll_806m", 1, 12),
+
+ FACTOR(TOP_SYSPLL_D3, "syspll_d3", "mainpll_537p3m", 1, 1),
+
+ FACTOR(TOP_SYSPLL_D2P5, "syspll_d2p5", "mainpll_322p4m", 2, 1),
+ FACTOR(TOP_SYSPLL_D5, "syspll_d5", "mainpll_322p4m", 1, 1),
+
+ FACTOR(TOP_SYSPLL_D3P5, "syspll_d3p5", "mainpll_230p3m", 2, 1),
+
+ FACTOR(TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_624m", 1, 2),
+ FACTOR(TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_624m", 1, 4),
+ FACTOR(TOP_UNIVPLL1_D6, "univpll1_d6", "univpll_624m", 1, 6),
+ FACTOR(TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_624m", 1, 8),
+ FACTOR(TOP_UNIVPLL1_D10, "univpll1_d10", "univpll_624m", 1, 10),
+
+ FACTOR(TOP_UNIVPLL2_D2, "univpll2_d2", "univpll_416m", 1, 2),
+ FACTOR(TOP_UNIVPLL2_D4, "univpll2_d4", "univpll_416m", 1, 4),
+ FACTOR(TOP_UNIVPLL2_D6, "univpll2_d6", "univpll_416m", 1, 6),
+ FACTOR(TOP_UNIVPLL2_D8, "univpll2_d8", "univpll_416m", 1, 8),
+
+ FACTOR(TOP_UNIVPLL_D3, "univpll_d3", "univpll_416m", 1, 1),
+ FACTOR(TOP_UNIVPLL_D5, "univpll_d5", "univpll_249p6m", 1, 1),
+ FACTOR(TOP_UNIVPLL_D7, "univpll_d7", "univpll_178p3m", 1, 1),
+ FACTOR(TOP_UNIVPLL_D10, "univpll_d10", "univpll_249p6m", 1, 5),
+ FACTOR(TOP_UNIVPLL_D26, "univpll_d26", "univpll_48m", 1, 1),
+
+ FACTOR(TOP_APLL_CK, "apll_ck", "audpll", 1, 1),
+ FACTOR(TOP_APLL_D4, "apll_d4", "audpll", 1, 4),
+ FACTOR(TOP_APLL_D8, "apll_d8", "audpll", 1, 8),
+ FACTOR(TOP_APLL_D16, "apll_d16", "audpll", 1, 16),
+ FACTOR(TOP_APLL_D24, "apll_d24", "audpll", 1, 24),
+
+ FACTOR(TOP_LVDSPLL_D2, "lvdspll_d2", "lvdspll", 1, 2),
+ FACTOR(TOP_LVDSPLL_D4, "lvdspll_d4", "lvdspll", 1, 4),
+ FACTOR(TOP_LVDSPLL_D8, "lvdspll_d8", "lvdspll", 1, 8),
+
+ FACTOR(TOP_LVDSTX_CLKDIG_CT, "lvdstx_clkdig_cts", "lvdspll", 1, 1),
+ FACTOR(TOP_VPLL_DPIX_CK, "vpll_dpix_ck", "lvdspll", 1, 1),
+
+ FACTOR(TOP_TVHDMI_H_CK, "tvhdmi_h_ck", "tvdpll", 1, 1),
+
+ FACTOR(TOP_HDMITX_CLKDIG_D2, "hdmitx_clkdig_d2", "hdmitx_clkdig_cts", 1, 2),
+ FACTOR(TOP_HDMITX_CLKDIG_D3, "hdmitx_clkdig_d3", "hdmitx_clkdig_cts", 1, 3),
+
+ FACTOR(TOP_TVHDMI_D2, "tvhdmi_d2", "tvhdmi_h_ck", 1, 2),
+ FACTOR(TOP_TVHDMI_D4, "tvhdmi_d4", "tvhdmi_h_ck", 1, 4),
+
+ FACTOR(TOP_MEMPLL_MCK_D4, "mempll_mck_d4", "clkph_mck", 1, 4),
+};
+
+static const char *axi_parents[] __initconst = {
+ "clk26m",
+ "syspll_d3",
+ "syspll_d4",
+ "syspll_d6",
+ "univpll_d5",
+ "univpll2_d2",
+ "syspll_d3p5"
+};
+
+static const char *smi_parents[] __initconst = {
+ "clk26m",
+ "clkph_mck",
+ "syspll_d2p5",
+ "syspll_d3",
+ "syspll_d8",
+ "univpll_d5",
+ "univpll1_d2",
+ "univpll1_d6",
+ "mmpll_d3",
+ "mmpll_d4",
+ "mmpll_d5",
+ "mmpll_d6",
+ "mmpll_d7",
+ "vdecpll",
+ "lvdspll"
+};
+
+static const char *mfg_parents[] __initconst = {
+ "clk26m",
+ "univpll1_d4",
+ "syspll_d2",
+ "syspll_d2p5",
+ "syspll_d3",
+ "univpll_d5",
+ "univpll1_d2",
+ "mmpll_d2",
+ "mmpll_d3",
+ "mmpll_d4",
+ "mmpll_d5",
+ "mmpll_d6",
+ "mmpll_d7"
+};
+
+static const char *irda_parents[] __initconst = {
+ "clk26m",
+ "univpll2_d8",
+ "univpll1_d6"
+};
+
+static const char *cam_parents[] __initconst = {
+ "clk26m",
+ "syspll_d3",
+ "syspll_d3p5",
+ "syspll_d4",
+ "univpll_d5",
+ "univpll2_d2",
+ "univpll_d7",
+ "univpll1_d4"
+};
+
+static const char *aud_intbus_parents[] __initconst = {
+ "clk26m",
+ "syspll_d6",
+ "univpll_d10"
+};
+
+static const char *jpg_parents[] __initconst = {
+ "clk26m",
+ "syspll_d5",
+ "syspll_d4",
+ "syspll_d3",
+ "univpll_d7",
+ "univpll2_d2",
+ "univpll_d5"
+};
+
+static const char *disp_parents[] __initconst = {
+ "clk26m",
+ "syspll_d3p5",
+ "syspll_d3",
+ "univpll2_d2",
+ "univpll_d5",
+ "univpll1_d2",
+ "lvdspll",
+ "vdecpll"
+};
+
+static const char *msdc30_parents[] __initconst = {
+ "clk26m",
+ "syspll_d6",
+ "syspll_d5",
+ "univpll1_d4",
+ "univpll2_d4",
+ "msdcpll"
+};
+
+static const char *usb20_parents[] __initconst = {
+ "clk26m",
+ "univpll2_d6",
+ "univpll1_d10"
+};
+
+static const char *venc_parents[] __initconst = {
+ "clk26m",
+ "syspll_d3",
+ "syspll_d8",
+ "univpll_d5",
+ "univpll1_d6",
+ "mmpll_d4",
+ "mmpll_d5",
+ "mmpll_d6"
+};
+
+static const char *spi_parents[] __initconst = {
+ "clk26m",
+ "syspll_d6",
+ "syspll_d8",
+ "syspll_d10",
+ "univpll1_d6",
+ "univpll1_d8"
+};
+
+static const char *uart_parents[] __initconst = {
+ "clk26m",
+ "univpll2_d8"
+};
+
+static const char *mem_parents[] __initconst = {
+ "clk26m",
+ "clkph_mck"
+};
+
+static const char *camtg_parents[] __initconst = {
+ "clk26m",
+ "univpll_d26",
+ "univpll1_d6",
+ "syspll_d16",
+ "syspll_d8"
+};
+
+static const char *audio_parents[] __initconst = {
+ "clk26m",
+ "syspll_d24"
+};
+
+static const char *fix_parents[] __initconst = {
+ "rtc32k",
+ "clk26m",
+ "univpll_d5",
+ "univpll_d7",
+ "univpll1_d2",
+ "univpll1_d4",
+ "univpll1_d6",
+ "univpll1_d8"
+};
+
+static const char *vdec_parents[] __initconst = {
+ "clk26m",
+ "vdecpll",
+ "clkph_mck",
+ "syspll_d2p5",
+ "syspll_d3",
+ "syspll_d3p5",
+ "syspll_d4",
+ "syspll_d5",
+ "syspll_d6",
+ "syspll_d8",
+ "univpll1_d2",
+ "univpll2_d2",
+ "univpll_d7",
+ "univpll_d10",
+ "univpll2_d4",
+ "lvdspll"
+};
+
+static const char *ddrphycfg_parents[] __initconst = {
+ "clk26m",
+ "axi_sel",
+ "syspll_d12"
+};
+
+static const char *dpilvds_parents[] __initconst = {
+ "clk26m",
+ "lvdspll",
+ "lvdspll_d2",
+ "lvdspll_d4",
+ "lvdspll_d8"
+};
+
+static const char *pmicspi_parents[] __initconst = {
+ "clk26m",
+ "univpll2_d6",
+ "syspll_d8",
+ "syspll_d10",
+ "univpll1_d10",
+ "mempll_mck_d4",
+ "univpll_d26",
+ "syspll_d24"
+};
+
+static const char *smi_mfg_as_parents[] __initconst = {
+ "clk26m",
+ "smi_sel",
+ "mfg_sel",
+ "mem_sel"
+};
+
+static const char *gcpu_parents[] __initconst = {
+ "clk26m",
+ "syspll_d4",
+ "univpll_d7",
+ "syspll_d5",
+ "syspll_d6"
+};
+
+static const char *dpi1_parents[] __initconst = {
+ "clk26m",
+ "tvhdmi_h_ck",
+ "tvhdmi_d2",
+ "tvhdmi_d4"
+};
+
+static const char *cci_parents[] __initconst = {
+ "clk26m",
+ "mainpll_537p3m",
+ "univpll_d3",
+ "syspll_d2p5",
+ "syspll_d3",
+ "syspll_d5"
+};
+
+static const char *apll_parents[] __initconst = {
+ "clk26m",
+ "apll_ck",
+ "apll_d4",
+ "apll_d8",
+ "apll_d16",
+ "apll_d24"
+};
+
+static const char *hdmipll_parents[] __initconst = {
+ "clk26m",
+ "hdmitx_clkdig_cts",
+ "hdmitx_clkdig_d2",
+ "hdmitx_clkdig_d3"
+};
+
+static struct mtk_composite top_muxes[] __initdata = {
+ /* CLK_CFG_0 */
+ MUX_GATE(TOP_AXI_SEL, "axi_sel", axi_parents,
+ 0x0140, 0, 3, INVALID_MUX_GATE_BIT),
+ MUX_GATE(TOP_SMI_SEL, "smi_sel", smi_parents, 0x0140, 8, 4, 15),
+ MUX_GATE(TOP_MFG_SEL, "mfg_sel", mfg_parents, 0x0140, 16, 4, 23),
+ MUX_GATE(TOP_IRDA_SEL, "irda_sel", irda_parents, 0x0140, 24, 2, 31),
+ /* CLK_CFG_1 */
+ MUX_GATE(TOP_CAM_SEL, "cam_sel", cam_parents, 0x0144, 0, 3, 7),
+ MUX_GATE(TOP_AUD_INTBUS_SEL, "aud_intbus_sel", aud_intbus_parents,
+ 0x0144, 8, 2, 15),
+ MUX_GATE(TOP_JPG_SEL, "jpg_sel", jpg_parents, 0x0144, 16, 3, 23),
+ MUX_GATE(TOP_DISP_SEL, "disp_sel", disp_parents, 0x0144, 24, 3, 31),
+ /* CLK_CFG_2 */
+ MUX_GATE(TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_parents, 0x0148, 0, 3, 7),
+ MUX_GATE(TOP_MSDC30_2_SEL, "msdc30_2_sel", msdc30_parents, 0x0148, 8, 3, 15),
+ MUX_GATE(TOP_MSDC30_3_SEL, "msdc30_3_sel", msdc30_parents, 0x0148, 16, 3, 23),
+ MUX_GATE(TOP_MSDC30_4_SEL, "msdc30_4_sel", msdc30_parents, 0x0148, 24, 3, 31),
+ /* CLK_CFG_3 */
+ MUX_GATE(TOP_USB20_SEL, "usb20_sel", usb20_parents, 0x014c, 0, 2, 7),
+ /* CLK_CFG_4 */
+ MUX_GATE(TOP_VENC_SEL, "venc_sel", venc_parents, 0x0150, 8, 3, 15),
+ MUX_GATE(TOP_SPI_SEL, "spi_sel", spi_parents, 0x0150, 16, 3, 23),
+ MUX_GATE(TOP_UART_SEL, "uart_sel", uart_parents, 0x0150, 24, 2, 31),
+ /* CLK_CFG_6 */
+ MUX_GATE(TOP_MEM_SEL, "mem_sel", mem_parents, 0x0158, 0, 2, 7),
+ MUX_GATE(TOP_CAMTG_SEL, "camtg_sel", camtg_parents, 0x0158, 8, 3, 15),
+ MUX_GATE(TOP_AUDIO_SEL, "audio_sel", audio_parents, 0x0158, 24, 2, 31),
+ /* CLK_CFG_7 */
+ MUX_GATE(TOP_FIX_SEL, "fix_sel", fix_parents, 0x015c, 0, 3, 7),
+ MUX_GATE(TOP_VDEC_SEL, "vdec_sel", vdec_parents, 0x015c, 8, 4, 15),
+ MUX_GATE(TOP_DDRPHYCFG_SEL, "ddrphycfg_sel", ddrphycfg_parents,
+ 0x015c, 16, 2, 23),
+ MUX_GATE(TOP_DPILVDS_SEL, "dpilvds_sel", dpilvds_parents, 0x015c, 24, 3, 31),
+ /* CLK_CFG_8 */
+ MUX_GATE(TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents, 0x0164, 0, 3, 7),
+ MUX_GATE(TOP_MSDC30_0_SEL, "msdc30_0_sel", msdc30_parents, 0x0164, 8, 3, 15),
+ MUX_GATE(TOP_SMI_MFG_AS_SEL, "smi_mfg_as_sel", smi_mfg_as_parents,
+ 0x0164, 16, 2, 23),
+ MUX_GATE(TOP_GCPU_SEL, "gcpu_sel", gcpu_parents, 0x0164, 24, 3, 31),
+ /* CLK_CFG_9 */
+ MUX_GATE(TOP_DPI1_SEL, "dpi1_sel", dpi1_parents, 0x0168, 0, 2, 7),
+ MUX_GATE(TOP_CCI_SEL, "cci_sel", cci_parents, 0x0168, 8, 3, 15),
+ MUX_GATE(TOP_APLL_SEL, "apll_sel", apll_parents, 0x0168, 16, 3, 23),
+ MUX_GATE(TOP_HDMIPLL_SEL, "hdmipll_sel", hdmipll_parents, 0x0168, 24, 2, 31),
+};
+
+static void __init mtk_init_clk_topckgen(void __iomem *top_base,
+ struct clk_onecell_data *clk_data)
+{
+ int i;
+ struct clk *clk;
+
+ for (i = 0; i < ARRAY_SIZE(top_muxes); i++) {
+ struct mtk_composite *mux = &top_muxes[i];
+
+ clk = mtk_clk_register_composite(mux, top_base, &lock);
+
+ if (IS_ERR(clk)) {
+ pr_err("Failed to register clk %s: %ld\n",
+ mux->name, PTR_ERR(clk));
+ continue;
+ }
+
+ if (clk_data)
+ clk_data->clks[mux->id] = clk;
+ }
+}
+
+static struct mtk_gate_regs infra_cg_regs = {
+ .set_ofs = 0x0040,
+ .clr_ofs = 0x0044,
+ .sta_ofs = 0x0048,
+};
+
+#define GATE_ICG(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &infra_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_setclr, \
+ }
+
+static struct mtk_gate infra_clks[] __initdata = {
+ GATE_ICG(INFRA_PMIC_WRAP_CK, "pmic_wrap_ck", "axi_sel", 23),
+ GATE_ICG(INFRA_PMICSPI_CK, "pmicspi_ck", "pmicspi_sel", 22),
+ GATE_ICG(INFRA_CCIF1_AP_CTRL, "ccif1_ap_ctrl", "axi_sel", 21),
+ GATE_ICG(INFRA_CCIF0_AP_CTRL, "ccif0_ap_ctrl", "axi_sel", 20),
+ GATE_ICG(INFRA_KP_CK, "kp_ck", "axi_sel", 16),
+ GATE_ICG(INFRA_CPUM_CK, "cpum_ck", "cpum_tck_in", 15),
+ GATE_ICG(INFRA_M4U_CK, "m4u_ck", "mem_sel", 8),
+ GATE_ICG(INFRA_MFGAXI_CK, "mfgaxi_ck", "axi_sel", 7),
+ GATE_ICG(INFRA_DEVAPC_CK, "devapc_ck", "axi_sel", 6),
+ GATE_ICG(INFRA_AUDIO_CK, "audio_ck", "aud_intbus_sel", 5),
+ GATE_ICG(INFRA_MFG_BUS_CK, "mfg_bus_ck", "axi_sel", 2),
+ GATE_ICG(INFRA_SMI_CK, "smi_ck", "smi_sel", 1),
+ GATE_ICG(INFRA_DBGCLK_CK, "dbgclk_ck", "axi_sel", 0),
+};
+
+static struct mtk_gate_regs peri0_cg_regs = {
+ .set_ofs = 0x0008,
+ .clr_ofs = 0x0010,
+ .sta_ofs = 0x0018,
+};
+
+static struct mtk_gate_regs peri1_cg_regs = {
+ .set_ofs = 0x000c,
+ .clr_ofs = 0x0014,
+ .sta_ofs = 0x001c,
+};
+
+#define GATE_PERI0(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &peri0_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_setclr, \
+ }
+
+#define GATE_PERI1(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &peri1_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_setclr, \
+ }
+
+static struct mtk_gate peri_clks[] __initdata = {
+ /* PERI0 */
+ GATE_PERI0(PERI_I2C5_CK, "i2c5_ck", "axi_sel", 31),
+ GATE_PERI0(PERI_I2C4_CK, "i2c4_ck", "axi_sel", 30),
+ GATE_PERI0(PERI_I2C3_CK, "i2c3_ck", "axi_sel", 29),
+ GATE_PERI0(PERI_I2C2_CK, "i2c2_ck", "axi_sel", 28),
+ GATE_PERI0(PERI_I2C1_CK, "i2c1_ck", "axi_sel", 27),
+ GATE_PERI0(PERI_I2C0_CK, "i2c0_ck", "axi_sel", 26),
+ GATE_PERI0(PERI_UART3_CK, "uart3_ck", "axi_sel", 25),
+ GATE_PERI0(PERI_UART2_CK, "uart2_ck", "axi_sel", 24),
+ GATE_PERI0(PERI_UART1_CK, "uart1_ck", "axi_sel", 23),
+ GATE_PERI0(PERI_UART0_CK, "uart0_ck", "axi_sel", 22),
+ GATE_PERI0(PERI_IRDA_CK, "irda_ck", "irda_sel", 21),
+ GATE_PERI0(PERI_NLI_CK, "nli_ck", "axi_sel", 20),
+ GATE_PERI0(PERI_MD_HIF_CK, "md_hif_ck", "axi_sel", 19),
+ GATE_PERI0(PERI_AP_HIF_CK, "ap_hif_ck", "axi_sel", 18),
+ GATE_PERI0(PERI_MSDC30_3_CK, "msdc30_3_ck", "msdc30_4_sel", 17),
+ GATE_PERI0(PERI_MSDC30_2_CK, "msdc30_2_ck", "msdc30_3_sel", 16),
+ GATE_PERI0(PERI_MSDC30_1_CK, "msdc30_1_ck", "msdc30_2_sel", 15),
+ GATE_PERI0(PERI_MSDC20_2_CK, "msdc20_2_ck", "msdc30_1_sel", 14),
+ GATE_PERI0(PERI_MSDC20_1_CK, "msdc20_1_ck", "msdc30_0_sel", 13),
+ GATE_PERI0(PERI_AP_DMA_CK, "ap_dma_ck", "axi_sel", 12),
+ GATE_PERI0(PERI_USB1_CK, "usb1_ck", "usb20_sel", 11),
+ GATE_PERI0(PERI_USB0_CK, "usb0_ck", "usb20_sel", 10),
+ GATE_PERI0(PERI_PWM_CK, "pwm_ck", "axi_sel", 9),
+ GATE_PERI0(PERI_PWM7_CK, "pwm7_ck", "axi_sel", 8),
+ GATE_PERI0(PERI_PWM6_CK, "pwm6_ck", "axi_sel", 7),
+ GATE_PERI0(PERI_PWM5_CK, "pwm5_ck", "axi_sel", 6),
+ GATE_PERI0(PERI_PWM4_CK, "pwm4_ck", "axi_sel", 5),
+ GATE_PERI0(PERI_PWM3_CK, "pwm3_ck", "axi_sel", 4),
+ GATE_PERI0(PERI_PWM2_CK, "pwm2_ck", "axi_sel", 3),
+ GATE_PERI0(PERI_PWM1_CK, "pwm1_ck", "axi_sel", 2),
+ GATE_PERI0(PERI_THERM_CK, "therm_ck", "axi_sel", 1),
+ GATE_PERI0(PERI_NFI_CK, "nfi_ck", "axi_sel", 0),
+ /* PERI1 */
+ GATE_PERI1(PERI_USBSLV_CK, "usbslv_ck", "axi_sel", 8),
+ GATE_PERI1(PERI_USB1_MCU_CK, "usb1_mcu_ck", "axi_sel", 7),
+ GATE_PERI1(PERI_USB0_MCU_CK, "usb0_mcu_ck", "axi_sel", 6),
+ GATE_PERI1(PERI_GCPU_CK, "gcpu_ck", "gcpu_sel", 5),
+ GATE_PERI1(PERI_FHCTL_CK, "fhctl_ck", "clk26m", 4),
+ GATE_PERI1(PERI_SPI1_CK, "spi1_ck", "spi_sel", 3),
+ GATE_PERI1(PERI_AUXADC_CK, "auxadc_ck", "clk26m", 2),
+ GATE_PERI1(PERI_PERI_PWRAP_CK, "peri_pwrap_ck", "axi_sel", 1),
+ GATE_PERI1(PERI_I2C6_CK, "i2c6_ck", "axi_sel", 0),
+};
+
+static void __init mtk_topckgen_init(struct device_node *node)
+{
+ struct clk_onecell_data *clk_data;
+ void __iomem *base;
+ int r;
+
+ base = of_iomap(node, 0);
+ if (!base) {
+ pr_err("%s(): ioremap failed\n", __func__);
+ return;
+ }
+
+ clk_data = mtk_alloc_clk_data(TOP_NR_CLK);
+
+ mtk_clk_register_factors(root_clk_alias, ARRAY_SIZE(root_clk_alias), clk_data);
+ mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
+ mtk_init_clk_topckgen(base, clk_data);
+
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
+}
+CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt8135-topckgen", mtk_topckgen_init);
+
+static void __init mtk_infrasys_init(struct device_node *node)
+{
+ struct clk_onecell_data *clk_data;
+ int r;
+
+ clk_data = mtk_alloc_clk_data(INFRA_NR_CLK);
+
+ mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
+ clk_data);
+
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
+
+ mtk_register_reset_controller(node, 2, 0x30);
+}
+CLK_OF_DECLARE(mtk_infrasys, "mediatek,mt8135-infracfg", mtk_infrasys_init);
+
+static void __init mtk_pericfg_init(struct device_node *node)
+{
+ struct clk_onecell_data *clk_data;
+ int r;
+
+ clk_data = mtk_alloc_clk_data(PERI_NR_CLK);
+
+ mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
+ clk_data);
+
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
+
+ mtk_register_reset_controller(node, 2, 0);
+}
+CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt8135-pericfg", mtk_pericfg_init);
+
+#define MT8135_PLL_FMAX (2000 * MHZ)
+#define CON0_MT8135_RST_BAR BIT(27)
+
+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) { \
+ .id = _id, \
+ .name = _name, \
+ .reg = _reg, \
+ .pwr_reg = _pwr_reg, \
+ .en_mask = _en_mask, \
+ .flags = _flags, \
+ .rst_bar_mask = CON0_MT8135_RST_BAR, \
+ .fmax = MT8135_PLL_FMAX, \
+ .pcwbits = _pcwbits, \
+ .pd_reg = _pd_reg, \
+ .pd_shift = _pd_shift, \
+ .tuner_reg = _tuner_reg, \
+ .pcw_reg = _pcw_reg, \
+ .pcw_shift = _pcw_shift, \
+ }
+
+static struct mtk_pll_data plls[] = {
+ PLL(APMIXED_ARMPLL1, "armpll1", 0x200, 0x218, 0x80000001, 0, 21, 0x204, 24, 0x0, 0x204, 0),
+ PLL(APMIXED_ARMPLL2, "armpll2", 0x2cc, 0x2e4, 0x80000001, 0, 21, 0x2d0, 24, 0x0, 0x2d0, 0),
+ PLL(APMIXED_MAINPLL, "mainpll", 0x21c, 0x234, 0xf0000001, HAVE_RST_BAR, 21, 0x21c, 6, 0x0, 0x220, 0),
+ PLL(APMIXED_UNIVPLL, "univpll", 0x238, 0x250, 0xf3000001, HAVE_RST_BAR, 7, 0x238, 6, 0x0, 0x238, 9),
+ PLL(APMIXED_MMPLL, "mmpll", 0x254, 0x26c, 0xf0000001, HAVE_RST_BAR, 21, 0x254, 6, 0x0, 0x258, 0),
+ PLL(APMIXED_MSDCPLL, "msdcpll", 0x278, 0x290, 0x80000001, 0, 21, 0x278, 6, 0x0, 0x27c, 0),
+ PLL(APMIXED_TVDPLL, "tvdpll", 0x294, 0x2ac, 0x80000001, 0, 31, 0x296, 6, 0x0, 0x298, 0),
+ PLL(APMIXED_LVDSPLL, "lvdspll", 0x2b0, 0x2c8, 0x80000001, 0, 21, 0x2b0, 6, 0x0, 0x2b4, 0),
+ PLL(APMIXED_AUDPLL, "audpll", 0x2e8, 0x300, 0x80000001, 0, 31, 0x2e8, 6, 0x2f8, 0x2ec, 0),
+ PLL(APMIXED_VDECPLL, "vdecpll", 0x304, 0x31c, 0x80000001, 0, 21, 0x2b0, 6, 0x0, 0x308, 0),
+};
+
+static void __init mtk_apmixedsys_init(struct device_node *node)
+{
+ mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls));
+}
+CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt8135-apmixedsys",
+ mtk_apmixedsys_init);
diff --git a/include/dt-bindings/clock/mt8135-clk.h b/include/dt-bindings/clock/mt8135-clk.h
new file mode 100644
index 0000000..8aea762
--- /dev/null
+++ b/include/dt-bindings/clock/mt8135-clk.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 _DT_BINDINGS_CLK_MT8135_H
+#define _DT_BINDINGS_CLK_MT8135_H
+
+/* TOPCKGEN */
+
+#define TOP_DSI0_LNTC_DSICLK 1
+#define TOP_HDMITX_CLKDIG_CTS 2
+#define TOP_CLKPH_MCK 3
+#define TOP_CPUM_TCK_IN 4
+#define TOP_MAINPLL_806M 5
+#define TOP_MAINPLL_537P3M 6
+#define TOP_MAINPLL_322P4M 7
+#define TOP_MAINPLL_230P3M 8
+#define TOP_UNIVPLL_624M 9
+#define TOP_UNIVPLL_416M 10
+#define TOP_UNIVPLL_249P6M 11
+#define TOP_UNIVPLL_178P3M 12
+#define TOP_UNIVPLL_48M 13
+#define TOP_MMPLL_D2 14
+#define TOP_MMPLL_D3 15
+#define TOP_MMPLL_D5 16
+#define TOP_MMPLL_D7 17
+#define TOP_MMPLL_D4 18
+#define TOP_MMPLL_D6 19
+#define TOP_SYSPLL_D2 20
+#define TOP_SYSPLL_D4 21
+#define TOP_SYSPLL_D6 22
+#define TOP_SYSPLL_D8 23
+#define TOP_SYSPLL_D10 24
+#define TOP_SYSPLL_D12 25
+#define TOP_SYSPLL_D16 26
+#define TOP_SYSPLL_D24 27
+#define TOP_SYSPLL_D3 28
+#define TOP_SYSPLL_D2P5 29
+#define TOP_SYSPLL_D5 30
+#define TOP_SYSPLL_D3P5 31
+#define TOP_UNIVPLL1_D2 32
+#define TOP_UNIVPLL1_D4 33
+#define TOP_UNIVPLL1_D6 34
+#define TOP_UNIVPLL1_D8 35
+#define TOP_UNIVPLL1_D10 36
+#define TOP_UNIVPLL2_D2 37
+#define TOP_UNIVPLL2_D4 38
+#define TOP_UNIVPLL2_D6 39
+#define TOP_UNIVPLL2_D8 40
+#define TOP_UNIVPLL_D3 41
+#define TOP_UNIVPLL_D5 42
+#define TOP_UNIVPLL_D7 43
+#define TOP_UNIVPLL_D10 44
+#define TOP_UNIVPLL_D26 45
+#define TOP_APLL_CK 46
+#define TOP_APLL_D4 47
+#define TOP_APLL_D8 48
+#define TOP_APLL_D16 49
+#define TOP_APLL_D24 50
+#define TOP_LVDSPLL_D2 51
+#define TOP_LVDSPLL_D4 52
+#define TOP_LVDSPLL_D8 53
+#define TOP_LVDSTX_CLKDIG_CT 54
+#define TOP_VPLL_DPIX_CK 55
+#define TOP_TVHDMI_H_CK 56
+#define TOP_HDMITX_CLKDIG_D2 57
+#define TOP_HDMITX_CLKDIG_D3 58
+#define TOP_TVHDMI_D2 59
+#define TOP_TVHDMI_D4 60
+#define TOP_MEMPLL_MCK_D4 61
+#define TOP_AXI_SEL 62
+#define TOP_SMI_SEL 63
+#define TOP_MFG_SEL 64
+#define TOP_IRDA_SEL 65
+#define TOP_CAM_SEL 66
+#define TOP_AUD_INTBUS_SEL 67
+#define TOP_JPG_SEL 68
+#define TOP_DISP_SEL 69
+#define TOP_MSDC30_1_SEL 70
+#define TOP_MSDC30_2_SEL 71
+#define TOP_MSDC30_3_SEL 72
+#define TOP_MSDC30_4_SEL 73
+#define TOP_USB20_SEL 74
+#define TOP_VENC_SEL 75
+#define TOP_SPI_SEL 76
+#define TOP_UART_SEL 77
+#define TOP_MEM_SEL 78
+#define TOP_CAMTG_SEL 79
+#define TOP_AUDIO_SEL 80
+#define TOP_FIX_SEL 81
+#define TOP_VDEC_SEL 82
+#define TOP_DDRPHYCFG_SEL 83
+#define TOP_DPILVDS_SEL 84
+#define TOP_PMICSPI_SEL 85
+#define TOP_MSDC30_0_SEL 86
+#define TOP_SMI_MFG_AS_SEL 87
+#define TOP_GCPU_SEL 88
+#define TOP_DPI1_SEL 89
+#define TOP_CCI_SEL 90
+#define TOP_APLL_SEL 91
+#define TOP_HDMIPLL_SEL 92
+#define TOP_NR_CLK 93
+
+/* APMIXED_SYS */
+
+#define APMIXED_ARMPLL1 1
+#define APMIXED_ARMPLL2 2
+#define APMIXED_MAINPLL 3
+#define APMIXED_UNIVPLL 4
+#define APMIXED_MMPLL 5
+#define APMIXED_MSDCPLL 6
+#define APMIXED_TVDPLL 7
+#define APMIXED_LVDSPLL 8
+#define APMIXED_AUDPLL 9
+#define APMIXED_VDECPLL 10
+#define APMIXED_NR_CLK 11
+
+/* INFRA_SYS */
+
+#define INFRA_PMIC_WRAP_CK 1
+#define INFRA_PMICSPI_CK 2
+#define INFRA_CCIF1_AP_CTRL 3
+#define INFRA_CCIF0_AP_CTRL 4
+#define INFRA_KP_CK 5
+#define INFRA_CPUM_CK 6
+#define INFRA_M4U_CK 7
+#define INFRA_MFGAXI_CK 8
+#define INFRA_DEVAPC_CK 9
+#define INFRA_AUDIO_CK 10
+#define INFRA_MFG_BUS_CK 11
+#define INFRA_SMI_CK 12
+#define INFRA_DBGCLK_CK 13
+#define INFRA_NR_CLK 14
+
+/* PERI_SYS */
+
+#define PERI_I2C5_CK 1
+#define PERI_I2C4_CK 2
+#define PERI_I2C3_CK 3
+#define PERI_I2C2_CK 4
+#define PERI_I2C1_CK 5
+#define PERI_I2C0_CK 6
+#define PERI_UART3_CK 7
+#define PERI_UART2_CK 8
+#define PERI_UART1_CK 9
+#define PERI_UART0_CK 10
+#define PERI_IRDA_CK 11
+#define PERI_NLI_CK 12
+#define PERI_MD_HIF_CK 13
+#define PERI_AP_HIF_CK 14
+#define PERI_MSDC30_3_CK 15
+#define PERI_MSDC30_2_CK 16
+#define PERI_MSDC30_1_CK 17
+#define PERI_MSDC20_2_CK 18
+#define PERI_MSDC20_1_CK 19
+#define PERI_AP_DMA_CK 20
+#define PERI_USB1_CK 21
+#define PERI_USB0_CK 22
+#define PERI_PWM_CK 23
+#define PERI_PWM7_CK 24
+#define PERI_PWM6_CK 25
+#define PERI_PWM5_CK 26
+#define PERI_PWM4_CK 27
+#define PERI_PWM3_CK 28
+#define PERI_PWM2_CK 29
+#define PERI_PWM1_CK 30
+#define PERI_THERM_CK 31
+#define PERI_NFI_CK 32
+#define PERI_USBSLV_CK 33
+#define PERI_USB1_MCU_CK 34
+#define PERI_USB0_MCU_CK 35
+#define PERI_GCPU_CK 36
+#define PERI_FHCTL_CK 37
+#define PERI_SPI1_CK 38
+#define PERI_AUXADC_CK 39
+#define PERI_PERI_PWRAP_CK 40
+#define PERI_I2C6_CK 41
+#define PERI_NR_CLK 42
+
+#endif /* _DT_BINDINGS_CLK_MT8135_H */
diff --git a/include/dt-bindings/reset-controller/mt8135-resets.h b/include/dt-bindings/reset-controller/mt8135-resets.h
new file mode 100644
index 0000000..1fb6295
--- /dev/null
+++ b/include/dt-bindings/reset-controller/mt8135-resets.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: Flora Fu, MediaTek
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 _DT_BINDINGS_RESET_CONTROLLER_MT8135
+#define _DT_BINDINGS_RESET_CONTROLLER_MT8135
+
+/* INFRACFG resets */
+#define MT8135_INFRA_EMI_REG_RST 0
+#define MT8135_INFRA_DRAMC0_A0_RST 1
+#define MT8135_INFRA_CCIF0_RST 2
+#define MT8135_INFRA_APCIRQ_EINT_RST 3
+#define MT8135_INFRA_APXGPT_RST 4
+#define MT8135_INFRA_SCPSYS_RST 5
+#define MT8135_INFRA_CCIF1_RST 6
+#define MT8135_INFRA_PMIC_WRAP_RST 7
+#define MT8135_INFRA_KP_RST 8
+#define MT8135_INFRA_EMI_RST 32
+#define MT8135_INFRA_DRAMC0_RST 34
+#define MT8135_INFRA_SMI_RST 35
+#define MT8135_INFRA_M4U_RST 36
+
+/* PERICFG resets */
+#define MT8135_PERI_UART0_SW_RST 0
+#define MT8135_PERI_UART1_SW_RST 1
+#define MT8135_PERI_UART2_SW_RST 2
+#define MT8135_PERI_UART3_SW_RST 3
+#define MT8135_PERI_IRDA_SW_RST 4
+#define MT8135_PERI_PTP_SW_RST 5
+#define MT8135_PERI_AP_HIF_SW_RST 6
+#define MT8135_PERI_GPCU_SW_RST 7
+#define MT8135_PERI_MD_HIF_SW_RST 8
+#define MT8135_PERI_NLI_SW_RST 9
+#define MT8135_PERI_AUXADC_SW_RST 10
+#define MT8135_PERI_DMA_SW_RST 11
+#define MT8135_PERI_NFI_SW_RST 14
+#define MT8135_PERI_PWM_SW_RST 15
+#define MT8135_PERI_THERM_SW_RST 16
+#define MT8135_PERI_MSDC0_SW_RST 17
+#define MT8135_PERI_MSDC1_SW_RST 18
+#define MT8135_PERI_MSDC2_SW_RST 19
+#define MT8135_PERI_MSDC3_SW_RST 20
+#define MT8135_PERI_I2C0_SW_RST 22
+#define MT8135_PERI_I2C1_SW_RST 23
+#define MT8135_PERI_I2C2_SW_RST 24
+#define MT8135_PERI_I2C3_SW_RST 25
+#define MT8135_PERI_I2C4_SW_RST 26
+#define MT8135_PERI_I2C5_SW_RST 27
+#define MT8135_PERI_I2C6_SW_RST 28
+#define MT8135_PERI_USB_SW_RST 29
+#define MT8135_PERI_SPI1_SW_RST 33
+#define MT8135_PERI_PWRAP_BRIDGE_SW_RST 34
+
+#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT8135 */
--
2.1.4
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 4/5] clk: mediatek: Add basic clocks for Mediatek MT8173.
2015-02-22 11:49 ` Sascha Hauer
@ 2015-02-22 11:49 ` Sascha Hauer
-1 siblings, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2015-02-22 11:49 UTC (permalink / raw)
To: Mike Turquette
Cc: Matthias Brugger, linux-arm-kernel, linux-kernel, linux-mediatek,
YH Chen, kernel, Yingjoe Chen, Eddie Huang, Henry Chen,
James Liao, Sascha Hauer
From: James Liao <jamesjj.liao@mediatek.com>
This patch adds basic clocks for MT8173, including TOPCKGEN, PLLs,
INFRA and PERI clocks.
Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/clk/mediatek/Makefile | 1 +
drivers/clk/mediatek/clk-mt8173.c | 820 +++++++++++++++++++++
include/dt-bindings/clock/mt8173-clk.h | 231 ++++++
.../dt-bindings/reset-controller/mt8173-resets.h | 63 ++
4 files changed, 1115 insertions(+)
create mode 100644 drivers/clk/mediatek/clk-mt8173.c
create mode 100644 include/dt-bindings/clock/mt8173-clk.h
create mode 100644 include/dt-bindings/reset-controller/mt8173-resets.h
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 12ce576..8e4b2a4 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -1,3 +1,4 @@
obj-y += clk-mtk.o clk-pll.o clk-gate.o
obj-$(CONFIG_RESET_CONTROLLER) += reset.o
obj-y += clk-mt8135.o
+obj-y += clk-mt8173.o
diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
new file mode 100644
index 0000000..014e552
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8173.c
@@ -0,0 +1,820 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/mfd/syscon.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt8173-clk.h>
+
+static DEFINE_SPINLOCK(lock);
+
+static struct mtk_fixed_factor root_clk_alias[] __initdata = {
+ FACTOR(TOP_CLKPH_MCK_O, "clkph_mck_o", "clk_null", 1, 1),
+ FACTOR(TOP_DPI_CK, "dpi_ck", "clk_null", 1, 1),
+ FACTOR(TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk_null", 1, 1),
+ FACTOR(TOP_HDMITX_DIG_CTS, "hdmitx_dig_cts", "clk_null", 1, 1),
+};
+
+static struct mtk_fixed_factor top_divs[] __initdata = {
+ FACTOR(TOP_ARMCA7PLL_754M, "armca7pll_754m", "armca7pll", 1, 2),
+ FACTOR(TOP_ARMCA7PLL_502M, "armca7pll_502m", "armca7pll", 1, 3),
+
+ FACTOR(TOP_MAIN_H546M, "main_h546m", "mainpll", 1, 2),
+ FACTOR(TOP_MAIN_H364M, "main_h364m", "mainpll", 1, 3),
+ FACTOR(TOP_MAIN_H218P4M, "main_h218p4m", "mainpll", 1, 5),
+ FACTOR(TOP_MAIN_H156M, "main_h156m", "mainpll", 1, 7),
+
+ FACTOR(TOP_TVDPLL_445P5M, "tvdpll_445p5m", "tvdpll", 1, 4),
+ FACTOR(TOP_TVDPLL_594M, "tvdpll_594m", "tvdpll", 1, 3),
+
+ FACTOR(TOP_UNIV_624M, "univ_624m", "univpll", 1, 2),
+ FACTOR(TOP_UNIV_416M, "univ_416m", "univpll", 1, 3),
+ FACTOR(TOP_UNIV_249P6M, "univ_249p6m", "univpll", 1, 5),
+ FACTOR(TOP_UNIV_178P3M, "univ_178p3m", "univpll", 1, 7),
+ FACTOR(TOP_UNIV_48M, "univ_48m", "univpll", 1, 26),
+
+ FACTOR(TOP_CLKRTC_EXT, "clkrtc_ext", "clk32k", 1, 1),
+ FACTOR(TOP_CLKRTC_INT, "clkrtc_int", "clk26m", 1, 793),
+ FACTOR(TOP_FPC_CK, "fpc_ck", "clk26m", 1, 1),
+
+ FACTOR(TOP_HDMITXPLL_D2, "hdmitxpll_d2", "hdmitx_dig_cts", 1, 2),
+ FACTOR(TOP_HDMITXPLL_D3, "hdmitxpll_d3", "hdmitx_dig_cts", 1, 3),
+
+ FACTOR(TOP_ARMCA7PLL_D2, "armca7pll_d2", "armca7pll_754m", 1, 1),
+ FACTOR(TOP_ARMCA7PLL_D3, "armca7pll_d3", "armca7pll_502m", 1, 1),
+
+ FACTOR(TOP_APLL1_CK, "apll1_ck", "apll1", 1, 1),
+ FACTOR(TOP_APLL2_CK, "apll2_ck", "apll2", 1, 1),
+
+ FACTOR(TOP_DMPLL_CK, "dmpll_ck", "clkph_mck_o", 1, 1),
+ FACTOR(TOP_DMPLL_D2, "dmpll_d2", "clkph_mck_o", 1, 2),
+ FACTOR(TOP_DMPLL_D4, "dmpll_d4", "clkph_mck_o", 1, 4),
+ FACTOR(TOP_DMPLL_D8, "dmpll_d8", "clkph_mck_o", 1, 8),
+ FACTOR(TOP_DMPLL_D16, "dmpll_d16", "clkph_mck_o", 1, 16),
+
+ FACTOR(TOP_LVDSPLL_D2, "lvdspll_d2", "lvdspll", 1, 2),
+ FACTOR(TOP_LVDSPLL_D4, "lvdspll_d4", "lvdspll", 1, 4),
+ FACTOR(TOP_LVDSPLL_D8, "lvdspll_d8", "lvdspll", 1, 8),
+
+ FACTOR(TOP_MMPLL_CK, "mmpll_ck", "mmpll", 1, 1),
+ FACTOR(TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2),
+
+ FACTOR(TOP_MSDCPLL_CK, "msdcpll_ck", "msdcpll", 1, 1),
+ FACTOR(TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2),
+ FACTOR(TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll", 1, 4),
+ FACTOR(TOP_MSDCPLL2_CK, "msdcpll2_ck", "msdcpll2", 1, 1),
+ FACTOR(TOP_MSDCPLL2_D2, "msdcpll2_d2", "msdcpll2", 1, 2),
+ FACTOR(TOP_MSDCPLL2_D4, "msdcpll2_d4", "msdcpll2", 1, 4),
+
+ FACTOR(TOP_SYSPLL_D2, "syspll_d2", "main_h546m", 1, 1),
+ FACTOR(TOP_SYSPLL1_D2, "syspll1_d2", "main_h546m", 1, 2),
+ FACTOR(TOP_SYSPLL1_D4, "syspll1_d4", "main_h546m", 1, 4),
+ FACTOR(TOP_SYSPLL1_D8, "syspll1_d8", "main_h546m", 1, 8),
+ FACTOR(TOP_SYSPLL1_D16, "syspll1_d16", "main_h546m", 1, 16),
+ FACTOR(TOP_SYSPLL_D3, "syspll_d3", "main_h364m", 1, 1),
+ FACTOR(TOP_SYSPLL2_D2, "syspll2_d2", "main_h364m", 1, 2),
+ FACTOR(TOP_SYSPLL2_D4, "syspll2_d4", "main_h364m", 1, 4),
+ FACTOR(TOP_SYSPLL_D5, "syspll_d5", "main_h218p4m", 1, 1),
+ FACTOR(TOP_SYSPLL3_D2, "syspll3_d2", "main_h218p4m", 1, 2),
+ FACTOR(TOP_SYSPLL3_D4, "syspll3_d4", "main_h218p4m", 1, 4),
+ FACTOR(TOP_SYSPLL_D7, "syspll_d7", "main_h156m", 1, 1),
+ FACTOR(TOP_SYSPLL4_D2, "syspll4_d2", "main_h156m", 1, 2),
+ FACTOR(TOP_SYSPLL4_D4, "syspll4_d4", "main_h156m", 1, 4),
+
+ FACTOR(TOP_TVDPLL_CK, "tvdpll_ck", "tvdpll_594m", 1, 1),
+ FACTOR(TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll_594m", 1, 2),
+ FACTOR(TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll_594m", 1, 4),
+ FACTOR(TOP_TVDPLL_D8, "tvdpll_d8", "tvdpll_594m", 1, 8),
+ FACTOR(TOP_TVDPLL_D16, "tvdpll_d16", "tvdpll_594m", 1, 16),
+
+ FACTOR(TOP_UNIVPLL_D2, "univpll_d2", "univ_624m", 1, 1),
+ FACTOR(TOP_UNIVPLL1_D2, "univpll1_d2", "univ_624m", 1, 2),
+ FACTOR(TOP_UNIVPLL1_D4, "univpll1_d4", "univ_624m", 1, 4),
+ FACTOR(TOP_UNIVPLL1_D8, "univpll1_d8", "univ_624m", 1, 8),
+ FACTOR(TOP_UNIVPLL_D3, "univpll_d3", "univ_416m", 1, 1),
+ FACTOR(TOP_UNIVPLL2_D2, "univpll2_d2", "univ_416m", 1, 2),
+ FACTOR(TOP_UNIVPLL2_D4, "univpll2_d4", "univ_416m", 1, 4),
+ FACTOR(TOP_UNIVPLL2_D8, "univpll2_d8", "univ_416m", 1, 8),
+ FACTOR(TOP_UNIVPLL_D5, "univpll_d5", "univ_249p6m", 1, 1),
+ FACTOR(TOP_UNIVPLL3_D2, "univpll3_d2", "univ_249p6m", 1, 2),
+ FACTOR(TOP_UNIVPLL3_D4, "univpll3_d4", "univ_249p6m", 1, 4),
+ FACTOR(TOP_UNIVPLL3_D8, "univpll3_d8", "univ_249p6m", 1, 8),
+ FACTOR(TOP_UNIVPLL_D7, "univpll_d7", "univ_178p3m", 1, 1),
+ FACTOR(TOP_UNIVPLL_D26, "univpll_d26", "univ_48m", 1, 1),
+ FACTOR(TOP_UNIVPLL_D52, "univpll_d52", "univ_48m", 1, 2),
+
+ FACTOR(TOP_VCODECPLL_CK, "vcodecpll_ck", "vcodecpll", 1, 3),
+ FACTOR(TOP_VCODECPLL_370P5, "vcodecpll_370p5", "vcodecpll", 1, 4),
+
+ FACTOR(TOP_VENCPLL_CK, "vencpll_ck", "vencpll", 1, 1),
+ FACTOR(TOP_VENCPLL_D2, "vencpll_d2", "vencpll", 1, 2),
+ FACTOR(TOP_VENCPLL_D4, "vencpll_d4", "vencpll", 1, 4),
+};
+
+static const char *axi_parents[] __initconst = {
+ "clk26m",
+ "syspll1_d2",
+ "syspll_d5",
+ "syspll1_d4",
+ "univpll_d5",
+ "univpll2_d2",
+ "dmpll_d2",
+ "dmpll_d4"
+};
+
+static const char *mem_parents[] __initconst = {
+ "clk26m",
+ "dmpll_ck"
+};
+
+static const char *ddrphycfg_parents[] __initconst = {
+ "clk26m",
+ "syspll1_d8"
+};
+
+static const char *mm_parents[] __initconst = {
+ "clk26m",
+ "vencpll_d2",
+ "main_h364m",
+ "syspll1_d2",
+ "syspll_d5",
+ "syspll1_d4",
+ "univpll1_d2",
+ "univpll2_d2",
+ "dmpll_d2"
+};
+
+static const char *pwm_parents[] __initconst = {
+ "clk26m",
+ "univpll2_d4",
+ "univpll3_d2",
+ "univpll1_d4"
+};
+
+static const char *vdec_parents[] __initconst = {
+ "clk26m",
+ "vcodecpll_ck",
+ "tvdpll_445p5m",
+ "univpll_d3",
+ "vencpll_d2",
+ "syspll_d3",
+ "univpll1_d2",
+ "mmpll_d2",
+ "dmpll_d2",
+ "dmpll_d4"
+};
+
+static const char *venc_parents[] __initconst = {
+ "clk26m",
+ "vcodecpll_ck",
+ "tvdpll_445p5m",
+ "univpll_d3",
+ "vencpll_d2",
+ "syspll_d3",
+ "univpll1_d2",
+ "univpll2_d2",
+ "dmpll_d2",
+ "dmpll_d4"
+};
+
+static const char *mfg_parents[] __initconst = {
+ "clk26m",
+ "mmpll_ck",
+ "dmpll_ck",
+ "clk26m",
+ "clk26m",
+ "clk26m",
+ "clk26m",
+ "clk26m",
+ "clk26m",
+ "syspll_d3",
+ "syspll1_d2",
+ "syspll_d5",
+ "univpll_d3",
+ "univpll1_d2",
+ "univpll_d5",
+ "univpll2_d2"
+};
+
+static const char *camtg_parents[] __initconst = {
+ "clk26m",
+ "univpll_d26",
+ "univpll2_d2",
+ "syspll3_d2",
+ "syspll3_d4",
+ "univpll1_d4"
+};
+
+static const char *uart_parents[] __initconst = {
+ "clk26m",
+ "univpll2_d8"
+};
+
+static const char *spi_parents[] __initconst = {
+ "clk26m",
+ "syspll3_d2",
+ "syspll1_d4",
+ "syspll4_d2",
+ "univpll3_d2",
+ "univpll2_d4",
+ "univpll1_d8"
+};
+
+static const char *usb20_parents[] __initconst = {
+ "clk26m",
+ "univpll1_d8",
+ "univpll3_d4"
+};
+
+static const char *usb30_parents[] __initconst = {
+ "clk26m",
+ "univpll3_d2",
+ "usb_syspll_125m",
+ "univpll2_d4"
+};
+
+static const char *msdc50_0_h_parents[] __initconst = {
+ "clk26m",
+ "syspll1_d2",
+ "syspll2_d2",
+ "syspll4_d2",
+ "univpll_d5",
+ "univpll1_d4"
+};
+
+static const char *msdc50_0_parents[] __initconst = {
+ "clk26m",
+ "msdcpll_ck",
+ "msdcpll_d2",
+ "univpll1_d4",
+ "syspll2_d2",
+ "syspll_d7",
+ "msdcpll_d4",
+ "vencpll_d4",
+ "tvdpll_ck",
+ "univpll_d2",
+ "univpll1_d2",
+ "mmpll_ck",
+ "msdcpll2_ck",
+ "msdcpll2_d2",
+ "msdcpll2_d4"
+};
+
+static const char *msdc30_1_parents[] __initconst = {
+ "clk26m",
+ "univpll2_d2",
+ "msdcpll_d4",
+ "univpll1_d4",
+ "syspll2_d2",
+ "syspll_d7",
+ "univpll_d7",
+ "vencpll_d4"
+};
+
+static const char *msdc30_2_parents[] __initconst = {
+ "clk26m",
+ "univpll2_d2",
+ "msdcpll_d4",
+ "univpll1_d4",
+ "syspll2_d2",
+ "syspll_d7",
+ "univpll_d7",
+ "vencpll_d2"
+};
+
+static const char *msdc30_3_parents[] __initconst = {
+ "clk26m",
+ "msdcpll2_ck",
+ "msdcpll2_d2",
+ "univpll2_d2",
+ "msdcpll2_d4",
+ "msdcpll_d4",
+ "univpll1_d4",
+ "syspll2_d2",
+ "syspll_d7",
+ "univpll_d7",
+ "vencpll_d4",
+ "msdcpll_ck",
+ "msdcpll_d2",
+ "msdcpll_d4"
+};
+
+static const char *audio_parents[] __initconst = {
+ "clk26m",
+ "syspll3_d4",
+ "syspll4_d4",
+ "syspll1_d16"
+};
+
+static const char *aud_intbus_parents[] __initconst = {
+ "clk26m",
+ "syspll1_d4",
+ "syspll4_d2",
+ "univpll3_d2",
+ "univpll2_d8",
+ "dmpll_d4",
+ "dmpll_d8"
+};
+
+static const char *pmicspi_parents[] __initconst = {
+ "clk26m",
+ "syspll1_d8",
+ "syspll3_d4",
+ "syspll1_d16",
+ "univpll3_d4",
+ "univpll_d26",
+ "dmpll_d8",
+ "dmpll_d16"
+};
+
+static const char *scp_parents[] __initconst = {
+ "clk26m",
+ "syspll1_d2",
+ "univpll_d5",
+ "syspll_d5",
+ "dmpll_d2",
+ "dmpll_d4"
+};
+
+static const char *atb_parents[] __initconst = {
+ "clk26m",
+ "syspll1_d2",
+ "univpll_d5",
+ "dmpll_d2"
+};
+
+static const char *venc_lt_parents[] __initconst = {
+ "clk26m",
+ "univpll_d3",
+ "vcodecpll_ck",
+ "tvdpll_445p5m",
+ "vencpll_d2",
+ "syspll_d3",
+ "univpll1_d2",
+ "univpll2_d2",
+ "syspll1_d2",
+ "univpll_d5",
+ "vcodecpll_370p5",
+ "dmpll_ck"
+};
+
+static const char *dpi0_parents[] __initconst = {
+ "clk26m",
+ "tvdpll_d2",
+ "tvdpll_d4",
+ "clk26m",
+ "clk26m",
+ "tvdpll_d8",
+ "tvdpll_d16"
+};
+
+static const char *irda_parents[] __initconst = {
+ "clk26m",
+ "univpll2_d4",
+ "syspll2_d4"
+};
+
+static const char *cci400_parents[] __initconst = {
+ "clk26m",
+ "vencpll_ck",
+ "armca7pll_754m",
+ "armca7pll_502m",
+ "univpll_d2",
+ "syspll_d2",
+ "msdcpll_ck",
+ "dmpll_ck"
+};
+
+static const char *aud_1_parents[] __initconst = {
+ "clk26m",
+ "apll1_ck",
+ "univpll2_d4",
+ "univpll2_d8"
+};
+
+static const char *aud_2_parents[] __initconst = {
+ "clk26m",
+ "apll2_ck",
+ "univpll2_d4",
+ "univpll2_d8"
+};
+
+static const char *mem_mfg_in_parents[] __initconst = {
+ "clk26m",
+ "mmpll_ck",
+ "dmpll_ck",
+ "clk26m"
+};
+
+static const char *axi_mfg_in_parents[] __initconst = {
+ "clk26m",
+ "axi_sel",
+ "dmpll_d2"
+};
+
+static const char *scam_parents[] __initconst = {
+ "clk26m",
+ "syspll3_d2",
+ "univpll2_d4",
+ "dmpll_d4"
+};
+
+static const char *spinfi_ifr_parents[] __initconst = {
+ "clk26m",
+ "univpll2_d8",
+ "univpll3_d4",
+ "syspll4_d2",
+ "univpll2_d4",
+ "univpll3_d2",
+ "syspll1_d4",
+ "univpll1_d4"
+};
+
+static const char *hdmi_parents[] __initconst = {
+ "clk26m",
+ "hdmitx_dig_cts",
+ "hdmitxpll_d2",
+ "hdmitxpll_d3"
+};
+
+static const char *dpilvds_parents[] __initconst = {
+ "clk26m",
+ "lvdspll",
+ "lvdspll_d2",
+ "lvdspll_d4",
+ "lvdspll_d8",
+ "fpc_ck"
+};
+
+static const char *msdc50_2_h_parents[] __initconst = {
+ "clk26m",
+ "syspll1_d2",
+ "syspll2_d2",
+ "syspll4_d2",
+ "univpll_d5",
+ "univpll1_d4"
+};
+
+static const char *hdcp_parents[] __initconst = {
+ "clk26m",
+ "syspll4_d2",
+ "syspll3_d4",
+ "univpll2_d4"
+};
+
+static const char *hdcp_24m_parents[] __initconst = {
+ "clk26m",
+ "univpll_d26",
+ "univpll_d52",
+ "univpll2_d8"
+};
+
+static const char *rtc_parents[] __initconst = {
+ "clkrtc_int",
+ "clkrtc_ext",
+ "clk26m",
+ "univpll3_d8"
+};
+
+static const char *i2s0_m_ck_parents[] __initconst = {
+ "apll1_div1",
+ "apll2_div1"
+};
+
+static const char *i2s1_m_ck_parents[] __initconst = {
+ "apll1_div2",
+ "apll2_div2"
+};
+
+static const char *i2s2_m_ck_parents[] __initconst = {
+ "apll1_div3",
+ "apll2_div3"
+};
+
+static const char *i2s3_m_ck_parents[] __initconst = {
+ "apll1_div4",
+ "apll2_div4"
+};
+
+static const char *i2s3_b_ck_parents[] __initconst = {
+ "apll1_div5",
+ "apll2_div5"
+};
+
+static struct mtk_composite top_muxes[] __initdata = {
+ /* CLK_CFG_0 */
+ MUX(TOP_AXI_SEL, "axi_sel", axi_parents, 0x0040, 0, 3),
+ MUX(TOP_MEM_SEL, "mem_sel", mem_parents, 0x0040, 8, 1),
+ MUX_GATE(TOP_DDRPHYCFG_SEL, "ddrphycfg_sel", ddrphycfg_parents, 0x0040, 16, 1, 23),
+ MUX_GATE(TOP_MM_SEL, "mm_sel", mm_parents, 0x0040, 24, 4, 31),
+ /* CLK_CFG_1 */
+ MUX_GATE(TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x0050, 0, 2, 7),
+ MUX_GATE(TOP_VDEC_SEL, "vdec_sel", vdec_parents, 0x0050, 8, 4, 15),
+ MUX_GATE(TOP_VENC_SEL, "venc_sel", venc_parents, 0x0050, 16, 4, 23),
+ MUX_GATE(TOP_MFG_SEL, "mfg_sel", mfg_parents, 0x0050, 24, 4, 31),
+ /* CLK_CFG_2 */
+ MUX_GATE(TOP_CAMTG_SEL, "camtg_sel", camtg_parents, 0x0060, 0, 3, 7),
+ MUX_GATE(TOP_UART_SEL, "uart_sel", uart_parents, 0x0060, 8, 1, 15),
+ MUX_GATE(TOP_SPI_SEL, "spi_sel", spi_parents, 0x0060, 16, 3, 23),
+ MUX_GATE(TOP_USB20_SEL, "usb20_sel", usb20_parents, 0x0060, 24, 2, 31),
+ /* CLK_CFG_3 */
+ MUX_GATE(TOP_USB30_SEL, "usb30_sel", usb30_parents, 0x0070, 0, 2, 7),
+ MUX_GATE(TOP_MSDC50_0_H_SEL, "msdc50_0_h_sel", msdc50_0_h_parents, 0x0070, 8, 3, 15),
+ MUX_GATE(TOP_MSDC50_0_SEL, "msdc50_0_sel", msdc50_0_parents, 0x0070, 16, 4, 23),
+ MUX_GATE(TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_1_parents, 0x0070, 24, 3, 31),
+ /* CLK_CFG_4 */
+ MUX_GATE(TOP_MSDC30_2_SEL, "msdc30_2_sel", msdc30_2_parents, 0x0080, 0, 3, 7),
+ MUX_GATE(TOP_MSDC30_3_SEL, "msdc30_3_sel", msdc30_3_parents, 0x0080, 8, 4, 15),
+ MUX_GATE(TOP_AUDIO_SEL, "audio_sel", audio_parents, 0x0080, 16, 2, 23),
+ MUX_GATE(TOP_AUD_INTBUS_SEL, "aud_intbus_sel", aud_intbus_parents, 0x0080, 24, 3, 31),
+ /* CLK_CFG_5 */
+ MUX_GATE(TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents, 0x0090, 0, 3, 7 /* 7:5 */),
+ MUX_GATE(TOP_SCP_SEL, "scp_sel", scp_parents, 0x0090, 8, 3, 15),
+ MUX_GATE(TOP_ATB_SEL, "atb_sel", atb_parents, 0x0090, 16, 2, 23),
+ MUX_GATE(TOP_VENC_LT_SEL, "venclt_sel", venc_lt_parents, 0x0090, 24, 4, 31),
+ /* CLK_CFG_6 */
+ MUX_GATE(TOP_DPI0_SEL, "dpi0_sel", dpi0_parents, 0x00a0, 0, 3, 7),
+ MUX_GATE(TOP_IRDA_SEL, "irda_sel", irda_parents, 0x00a0, 8, 2, 15),
+ MUX_GATE(TOP_CCI400_SEL, "cci400_sel", cci400_parents, 0x00a0, 16, 3, 23),
+ MUX_GATE(TOP_AUD_1_SEL, "aud_1_sel", aud_1_parents, 0x00a0, 24, 2, 31),
+ /* CLK_CFG_7 */
+ MUX_GATE(TOP_AUD_2_SEL, "aud_2_sel", aud_2_parents, 0x00b0, 0, 2, 7),
+ MUX_GATE(TOP_MEM_MFG_IN_SEL, "mem_mfg_in_sel", mem_mfg_in_parents, 0x00b0, 8, 2, 15),
+ MUX_GATE(TOP_AXI_MFG_IN_SEL, "axi_mfg_in_sel", axi_mfg_in_parents, 0x00b0, 16, 2, 23),
+ MUX_GATE(TOP_SCAM_SEL, "scam_sel", scam_parents, 0x00b0, 24, 2, 31),
+ /* CLK_CFG_12 */
+ MUX_GATE(TOP_SPINFI_IFR_SEL, "spinfi_ifr_sel", spinfi_ifr_parents, 0x00c0, 0, 3, 7),
+ MUX_GATE(TOP_HDMI_SEL, "hdmi_sel", hdmi_parents, 0x00c0, 8, 2, 15),
+ MUX_GATE(TOP_DPILVDS_SEL, "dpilvds_sel", dpilvds_parents, 0x00c0, 24, 3, 31),
+ /* CLK_CFG_13 */
+ MUX_GATE(TOP_MSDC50_2_H_SEL, "msdc50_2_h_sel", msdc50_2_h_parents, 0x00d0, 0, 3, 7),
+ MUX_GATE(TOP_HDCP_SEL, "hdcp_sel", hdcp_parents, 0x00d0, 8, 2, 15),
+ MUX_GATE(TOP_HDCP_24M_SEL, "hdcp_24m_sel", hdcp_24m_parents, 0x00d0, 16, 2, 23),
+ MUX(TOP_RTC_SEL, "rtc_sel", rtc_parents, 0x00d0, 24, 2),
+
+ DIV_GATE(TOP_APLL1_DIV0, "apll1_div0", "aud_1_sel", 0x12c, 8, 0x120, 4, 24),
+ DIV_GATE(TOP_APLL1_DIV1, "apll1_div1", "aud_1_sel", 0x12c, 9, 0x124, 8, 0),
+ DIV_GATE(TOP_APLL1_DIV2, "apll1_div2", "aud_1_sel", 0x12c, 10, 0x124, 8, 8),
+ DIV_GATE(TOP_APLL1_DIV3, "apll1_div3", "aud_1_sel", 0x12c, 11, 0x124, 8, 16),
+ DIV_GATE(TOP_APLL1_DIV4, "apll1_div4", "aud_1_sel", 0x12c, 12, 0x124, 8, 24),
+ DIV_GATE(TOP_APLL1_DIV5, "apll1_div5", "aud_1_sel", 0x12c, 13, 0x12c, 4, 0),
+
+ DIV_GATE(TOP_APLL2_DIV0, "apll2_div0", "aud_2_sel", 0x12c, 16, 0x120, 4, 28),
+ DIV_GATE(TOP_APLL2_DIV1, "apll2_div1", "aud_2_sel", 0x12c, 17, 0x128, 8, 0),
+ DIV_GATE(TOP_APLL2_DIV2, "apll2_div2", "aud_2_sel", 0x12c, 18, 0x128, 8, 8),
+ DIV_GATE(TOP_APLL2_DIV3, "apll2_div3", "aud_2_sel", 0x12c, 19, 0x128, 8, 16),
+ DIV_GATE(TOP_APLL2_DIV4, "apll2_div4", "aud_2_sel", 0x12c, 20, 0x128, 8, 24),
+ DIV_GATE(TOP_APLL2_DIV5, "apll2_div5", "aud_2_sel", 0x12c, 21, 0x12c, 4, 4),
+
+ MUX(TOP_I2S0_M_CK_SEL, "i2s0_m_ck_sel", i2s0_m_ck_parents, 0x120, 4, 1),
+ MUX(TOP_I2S1_M_CK_SEL, "i2s1_m_ck_sel", i2s1_m_ck_parents, 0x120, 5, 1),
+ MUX(TOP_I2S2_M_CK_SEL, "i2s2_m_ck_sel", i2s2_m_ck_parents, 0x120, 6, 1),
+ MUX(TOP_I2S3_M_CK_SEL, "i2s3_m_ck_sel", i2s3_m_ck_parents, 0x120, 7, 1),
+ MUX(TOP_I2S3_B_CK_SEL, "i2s3_b_ck_sel", i2s3_b_ck_parents, 0x120, 8, 1),
+};
+
+static void __init mtk_init_clk_topckgen(void __iomem *top_base,
+ struct clk_onecell_data *clk_data)
+{
+ int i;
+ struct clk *clk;
+
+ for (i = 0; i < ARRAY_SIZE(top_muxes); i++) {
+ struct mtk_composite *mux = &top_muxes[i];
+
+ clk = mtk_clk_register_composite(mux, top_base, &lock);
+
+ if (IS_ERR(clk)) {
+ pr_err("Failed to register clk %s: %ld\n",
+ mux->name, PTR_ERR(clk));
+ continue;
+ }
+
+ if (clk_data)
+ clk_data->clks[mux->id] = clk;
+ }
+}
+
+static struct mtk_gate_regs infra_cg_regs = {
+ .set_ofs = 0x0040,
+ .clr_ofs = 0x0044,
+ .sta_ofs = 0x0048,
+};
+
+#define GATE_ICG(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &infra_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_setclr, \
+ }
+
+static struct mtk_gate infra_clks[] __initdata = {
+ GATE_ICG(INFRA_DBGCLK, "infra_dbgclk", "axi_sel", 0),
+ GATE_ICG(INFRA_SMI, "infra_smi", "mm_sel", 1),
+ GATE_ICG(INFRA_AUDIO, "infra_audio", "aud_intbus_sel", 5),
+ GATE_ICG(INFRA_GCE, "infra_gce", "axi_sel", 6),
+ GATE_ICG(INFRA_L2C_SRAM, "infra_l2c_sram", "axi_sel", 7),
+ GATE_ICG(INFRA_M4U, "infra_m4u", "mem_sel", 8),
+ GATE_ICG(INFRA_CPUM, "infra_cpum", "clk_null", 15),
+ GATE_ICG(INFRA_KP, "infra_kp", "axi_sel", 16),
+ GATE_ICG(INFRA_CEC, "infra_cec", "clk26m", 18),
+ GATE_ICG(INFRA_PMICSPI, "infra_pmicspi", "pmicspi_sel", 22),
+ GATE_ICG(INFRA_PMICWRAP, "infra_pmicwrap", "axi_sel", 23),
+};
+
+static struct mtk_gate_regs peri0_cg_regs = {
+ .set_ofs = 0x0008,
+ .clr_ofs = 0x0010,
+ .sta_ofs = 0x0018,
+};
+
+static struct mtk_gate_regs peri1_cg_regs = {
+ .set_ofs = 0x000c,
+ .clr_ofs = 0x0014,
+ .sta_ofs = 0x001c,
+};
+
+#define GATE_PERI0(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &peri0_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_setclr, \
+ }
+
+#define GATE_PERI1(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &peri1_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_setclr, \
+ }
+
+static struct mtk_gate peri_clks[] __initdata = {
+ /* PERI0 */
+ GATE_PERI0(PERI_NFI, "peri_nfi", "axi_sel", 0),
+ GATE_PERI0(PERI_THERM, "peri_therm", "axi_sel", 1),
+ GATE_PERI0(PERI_PWM1, "peri_pwm1", "axi_sel", 2),
+ GATE_PERI0(PERI_PWM2, "peri_pwm2", "axi_sel", 3),
+ GATE_PERI0(PERI_PWM3, "peri_pwm3", "axi_sel", 4),
+ GATE_PERI0(PERI_PWM4, "peri_pwm4", "axi_sel", 5),
+ GATE_PERI0(PERI_PWM5, "peri_pwm5", "axi_sel", 6),
+ GATE_PERI0(PERI_PWM6, "peri_pwm6", "axi_sel", 7),
+ GATE_PERI0(PERI_PWM7, "peri_pwm7", "axi_sel", 8),
+ GATE_PERI0(PERI_PWM, "peri_pwm", "axi_sel", 9),
+ GATE_PERI0(PERI_USB0, "peri_usb0", "usb20_sel", 10),
+ GATE_PERI0(PERI_USB1, "peri_usb1", "usb20_sel", 11),
+ GATE_PERI0(PERI_AP_DMA, "peri_ap_dma", "axi_sel", 12),
+ GATE_PERI0(PERI_MSDC30_0, "peri_msdc30_0", "msdc50_0_sel", 13),
+ GATE_PERI0(PERI_MSDC30_1, "peri_msdc30_1", "msdc30_1_sel", 14),
+ GATE_PERI0(PERI_MSDC30_2, "peri_msdc30_2", "msdc30_2_sel", 15),
+ GATE_PERI0(PERI_MSDC30_3, "peri_msdc30_3", "msdc30_3_sel", 16),
+ GATE_PERI0(PERI_NLI_ARB, "peri_nli_arb", "axi_sel", 17),
+ GATE_PERI0(PERI_IRDA, "peri_irda", "irda_sel", 18),
+ GATE_PERI0(PERI_UART0, "peri_uart0", "uart_sel", 19),
+ GATE_PERI0(PERI_UART1, "peri_uart1", "uart_sel", 20),
+ GATE_PERI0(PERI_UART2, "peri_uart2", "uart_sel", 21),
+ GATE_PERI0(PERI_UART3, "peri_uart3", "uart_sel", 22),
+ GATE_PERI0(PERI_I2C0, "peri_i2c0", "axi_sel", 23),
+ GATE_PERI0(PERI_I2C1, "peri_i2c1", "axi_sel", 24),
+ GATE_PERI0(PERI_I2C2, "peri_i2c2", "axi_sel", 25),
+ GATE_PERI0(PERI_I2C3, "peri_i2c3", "axi_sel", 26),
+ GATE_PERI0(PERI_I2C4, "peri_i2c4", "axi_sel", 27),
+ GATE_PERI0(PERI_AUXADC, "peri_auxadc", "clk26m", 28),
+ GATE_PERI0(PERI_SPI0, "peri_spi0", "spi_sel", 29),
+ GATE_PERI0(PERI_I2C5, "peri_i2c5", "axi_sel", 30),
+ GATE_PERI0(PERI_NFIECC, "peri_nfiecc", "axi_sel", 31),
+ /* PERI1 */
+ GATE_PERI1(PERI_SPI, "peri_spi", "spi_sel", 0),
+ GATE_PERI1(PERI_IRRX, "peri_irrx", "spi_sel", 1),
+ GATE_PERI1(PERI_I2C6, "peri_i2c6", "axi_sel", 2),
+};
+
+static void __init mtk_topckgen_init(struct device_node *node)
+{
+ struct clk_onecell_data *clk_data;
+ void __iomem *base;
+ int r;
+
+ base = of_iomap(node, 0);
+ if (!base) {
+ pr_err("%s(): ioremap failed\n", __func__);
+ return;
+ }
+
+ clk_data = mtk_alloc_clk_data(TOP_NR_CLK);
+
+ mtk_clk_register_factors(root_clk_alias, ARRAY_SIZE(root_clk_alias), clk_data);
+ mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
+ mtk_init_clk_topckgen(base, clk_data);
+
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
+}
+CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt8173-topckgen", mtk_topckgen_init);
+
+static void __init mtk_infrasys_init(struct device_node *node)
+{
+ struct clk_onecell_data *clk_data;
+ int r;
+
+ clk_data = mtk_alloc_clk_data(INFRA_NR_CLK);
+
+ mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
+ clk_data);
+
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
+
+ mtk_register_reset_controller(node, 2, 0x30);
+}
+CLK_OF_DECLARE(mtk_infrasys, "mediatek,mt8173-infracfg", mtk_infrasys_init);
+
+static void __init mtk_pericfg_init(struct device_node *node)
+{
+ struct clk_onecell_data *clk_data;
+ int r;
+
+ clk_data = mtk_alloc_clk_data(PERI_NR_CLK);
+
+ mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
+ clk_data);
+
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
+
+ mtk_register_reset_controller(node, 2, 0);
+}
+CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt8173-pericfg", mtk_pericfg_init);
+
+#define MT8173_PLL_FMAX (3000UL * MHZ)
+
+#define CON0_MT8173_RST_BAR BIT(24)
+
+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, _pd_shift, \
+ _tuner_reg, _pcw_reg, _pcw_shift) { \
+ .id = _id, \
+ .name = _name, \
+ .reg = _reg, \
+ .pwr_reg = _pwr_reg, \
+ .en_mask = _en_mask, \
+ .flags = _flags, \
+ .rst_bar_mask = CON0_MT8173_RST_BAR, \
+ .fmax = MT8173_PLL_FMAX, \
+ .pcwbits = _pcwbits, \
+ .pd_reg = _pd_reg, \
+ .pd_shift = _pd_shift, \
+ .tuner_reg = _tuner_reg, \
+ .pcw_reg = _pcw_reg, \
+ .pcw_shift = _pcw_shift, \
+ }
+
+static const struct mtk_pll_data plls[] = {
+ PLL(APMIXED_ARMCA15PLL, "armca15pll", 0x200, 0x20c, 0x00000001, 0, 21, 0x204, 24, 0x0, 0x204, 0),
+ PLL(APMIXED_ARMCA7PLL, "armca7pll", 0x210, 0x21c, 0x00000001, 0, 21, 0x214, 24, 0x0, 0x214, 0),
+ PLL(APMIXED_MAINPLL, "mainpll", 0x220, 0x22c, 0xf0000101, HAVE_RST_BAR, 21, 0x220, 4, 0x0, 0x224, 0),
+ PLL(APMIXED_UNIVPLL, "univpll", 0x230, 0x23c, 0xfe000001, HAVE_RST_BAR, 7, 0x230, 4, 0x0, 0x234, 14),
+ PLL(APMIXED_MMPLL, "mmpll", 0x240, 0x24c, 0x00000001, 0, 21, 0x244, 24, 0x0, 0x244, 0),
+ PLL(APMIXED_MSDCPLL, "msdcpll", 0x250, 0x25c, 0x00000001, 0, 21, 0x250, 4, 0x0, 0x254, 0),
+ PLL(APMIXED_VENCPLL, "vencpll", 0x260, 0x26c, 0x00000001, 0, 21, 0x260, 4, 0x0, 0x264, 0),
+ PLL(APMIXED_TVDPLL, "tvdpll", 0x270, 0x27c, 0x00000001, 0, 21, 0x270, 4, 0x0, 0x274, 0),
+ PLL(APMIXED_MPLL, "mpll", 0x280, 0x28c, 0x00000001, 0, 21, 0x280, 4, 0x0, 0x284, 0),
+ PLL(APMIXED_VCODECPLL, "vcodecpll", 0x290, 0x29c, 0x00000001, 0, 21, 0x290, 4, 0x0, 0x294, 0),
+ PLL(APMIXED_APLL1, "apll1", 0x2a0, 0x2b0, 0x00000001, 0, 31, 0x2a0, 4, 0x2a4, 0x2a4, 0),
+ PLL(APMIXED_APLL2, "apll2", 0x2b4, 0x2c4, 0x00000001, 0, 31, 0x2b4, 4, 0x2b8, 0x2b8, 0),
+ PLL(APMIXED_LVDSPLL, "lvdspll", 0x2d0, 0x2dc, 0x00000001, 0, 21, 0x2d0, 4, 0x0, 0x2d4, 0),
+ PLL(APMIXED_MSDCPLL2, "msdcpll2", 0x2f0, 0x2fc, 0x00000001, 0, 21, 0x2f0, 4, 0x0, 0x2f4, 0),
+};
+
+static void __init mtk_apmixedsys_init(struct device_node *node)
+{
+ mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls));
+}
+CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt8173-apmixedsys",
+ mtk_apmixedsys_init);
diff --git a/include/dt-bindings/clock/mt8173-clk.h b/include/dt-bindings/clock/mt8173-clk.h
new file mode 100644
index 0000000..e648b28
--- /dev/null
+++ b/include/dt-bindings/clock/mt8173-clk.h
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 _DT_BINDINGS_CLK_MT8173_H
+#define _DT_BINDINGS_CLK_MT8173_H
+
+/* TOPCKGEN */
+
+#define TOP_CLKPH_MCK_O 1
+#define TOP_DPI_CK 2
+#define TOP_USB_SYSPLL_125M 3
+#define TOP_HDMITX_DIG_CTS 4
+#define TOP_ARMCA7PLL_754M 5
+#define TOP_ARMCA7PLL_502M 6
+#define TOP_MAIN_H546M 7
+#define TOP_MAIN_H364M 8
+#define TOP_MAIN_H218P4M 9
+#define TOP_MAIN_H156M 10
+#define TOP_TVDPLL_445P5M 11
+#define TOP_TVDPLL_594M 12
+#define TOP_UNIV_624M 13
+#define TOP_UNIV_416M 14
+#define TOP_UNIV_249P6M 15
+#define TOP_UNIV_178P3M 16
+#define TOP_UNIV_48M 17
+#define TOP_CLKRTC_EXT 18
+#define TOP_CLKRTC_INT 19
+#define TOP_FPC_CK 20
+#define TOP_HDMITXPLL_D2 21
+#define TOP_HDMITXPLL_D3 22
+#define TOP_ARMCA7PLL_D2 23
+#define TOP_ARMCA7PLL_D3 24
+#define TOP_APLL1_CK 25
+#define TOP_APLL2_CK 26
+#define TOP_DMPLL_CK 27
+#define TOP_DMPLL_D2 28
+#define TOP_DMPLL_D4 29
+#define TOP_DMPLL_D8 30
+#define TOP_DMPLL_D16 31
+#define TOP_LVDSPLL_D2 32
+#define TOP_LVDSPLL_D4 33
+#define TOP_LVDSPLL_D8 34
+#define TOP_MMPLL_CK 35
+#define TOP_MMPLL_D2 36
+#define TOP_MSDCPLL_CK 37
+#define TOP_MSDCPLL_D2 38
+#define TOP_MSDCPLL_D4 39
+#define TOP_MSDCPLL2_CK 40
+#define TOP_MSDCPLL2_D2 41
+#define TOP_MSDCPLL2_D4 42
+#define TOP_SYSPLL_D2 43
+#define TOP_SYSPLL1_D2 44
+#define TOP_SYSPLL1_D4 45
+#define TOP_SYSPLL1_D8 46
+#define TOP_SYSPLL1_D16 47
+#define TOP_SYSPLL_D3 48
+#define TOP_SYSPLL2_D2 49
+#define TOP_SYSPLL2_D4 50
+#define TOP_SYSPLL_D5 51
+#define TOP_SYSPLL3_D2 52
+#define TOP_SYSPLL3_D4 53
+#define TOP_SYSPLL_D7 54
+#define TOP_SYSPLL4_D2 55
+#define TOP_SYSPLL4_D4 56
+#define TOP_TVDPLL_CK 57
+#define TOP_TVDPLL_D2 58
+#define TOP_TVDPLL_D4 59
+#define TOP_TVDPLL_D8 60
+#define TOP_TVDPLL_D16 61
+#define TOP_UNIVPLL_D2 62
+#define TOP_UNIVPLL1_D2 63
+#define TOP_UNIVPLL1_D4 64
+#define TOP_UNIVPLL1_D8 65
+#define TOP_UNIVPLL_D3 66
+#define TOP_UNIVPLL2_D2 67
+#define TOP_UNIVPLL2_D4 68
+#define TOP_UNIVPLL2_D8 69
+#define TOP_UNIVPLL_D5 70
+#define TOP_UNIVPLL3_D2 71
+#define TOP_UNIVPLL3_D4 72
+#define TOP_UNIVPLL3_D8 73
+#define TOP_UNIVPLL_D7 74
+#define TOP_UNIVPLL_D26 75
+#define TOP_UNIVPLL_D52 76
+#define TOP_VCODECPLL_CK 77
+#define TOP_VCODECPLL_370P5 78
+#define TOP_VENCPLL_CK 79
+#define TOP_VENCPLL_D2 80
+#define TOP_VENCPLL_D4 81
+#define TOP_AXI_SEL 82
+#define TOP_MEM_SEL 83
+#define TOP_DDRPHYCFG_SEL 84
+#define TOP_MM_SEL 85
+#define TOP_PWM_SEL 86
+#define TOP_VDEC_SEL 87
+#define TOP_VENC_SEL 88
+#define TOP_MFG_SEL 89
+#define TOP_CAMTG_SEL 90
+#define TOP_UART_SEL 91
+#define TOP_SPI_SEL 92
+#define TOP_USB20_SEL 93
+#define TOP_USB30_SEL 94
+#define TOP_MSDC50_0_H_SEL 95
+#define TOP_MSDC50_0_SEL 96
+#define TOP_MSDC30_1_SEL 97
+#define TOP_MSDC30_2_SEL 98
+#define TOP_MSDC30_3_SEL 99
+#define TOP_AUDIO_SEL 100
+#define TOP_AUD_INTBUS_SEL 101
+#define TOP_PMICSPI_SEL 102
+#define TOP_SCP_SEL 103
+#define TOP_ATB_SEL 104
+#define TOP_VENC_LT_SEL 105
+#define TOP_DPI0_SEL 106
+#define TOP_IRDA_SEL 107
+#define TOP_CCI400_SEL 108
+#define TOP_AUD_1_SEL 109
+#define TOP_AUD_2_SEL 110
+#define TOP_MEM_MFG_IN_SEL 111
+#define TOP_AXI_MFG_IN_SEL 112
+#define TOP_SCAM_SEL 113
+#define TOP_SPINFI_IFR_SEL 114
+#define TOP_HDMI_SEL 115
+#define TOP_DPILVDS_SEL 116
+#define TOP_MSDC50_2_H_SEL 117
+#define TOP_HDCP_SEL 118
+#define TOP_HDCP_24M_SEL 119
+#define TOP_RTC_SEL 120
+#define TOP_APLL1_DIV0 121
+#define TOP_APLL1_DIV1 122
+#define TOP_APLL1_DIV2 123
+#define TOP_APLL1_DIV3 124
+#define TOP_APLL1_DIV4 125
+#define TOP_APLL1_DIV5 126
+#define TOP_APLL2_DIV0 127
+#define TOP_APLL2_DIV1 128
+#define TOP_APLL2_DIV2 129
+#define TOP_APLL2_DIV3 130
+#define TOP_APLL2_DIV4 131
+#define TOP_APLL2_DIV5 132
+#define TOP_I2S0_M_CK_SEL 133
+#define TOP_I2S1_M_CK_SEL 134
+#define TOP_I2S2_M_CK_SEL 135
+#define TOP_I2S3_M_CK_SEL 136
+#define TOP_I2S3_B_CK_SEL 137
+#define TOP_NR_CLK 138
+
+/* APMIXED_SYS */
+
+#define APMIXED_ARMCA15PLL 1
+#define APMIXED_ARMCA7PLL 2
+#define APMIXED_MAINPLL 3
+#define APMIXED_UNIVPLL 4
+#define APMIXED_MMPLL 5
+#define APMIXED_MSDCPLL 6
+#define APMIXED_VENCPLL 7
+#define APMIXED_TVDPLL 8
+#define APMIXED_MPLL 9
+#define APMIXED_VCODECPLL 10
+#define APMIXED_APLL1 11
+#define APMIXED_APLL2 12
+#define APMIXED_LVDSPLL 13
+#define APMIXED_MSDCPLL2 14
+#define APMIXED_NR_CLK 15
+
+/* INFRA_SYS */
+
+#define INFRA_DBGCLK 1
+#define INFRA_SMI 2
+#define INFRA_AUDIO 3
+#define INFRA_GCE 4
+#define INFRA_L2C_SRAM 5
+#define INFRA_M4U 6
+#define INFRA_CPUM 7
+#define INFRA_KP 8
+#define INFRA_CEC 9
+#define INFRA_PMICSPI 10
+#define INFRA_PMICWRAP 11
+#define INFRA_NR_CLK 12
+
+/* PERI_SYS */
+
+#define PERI_NFI 1
+#define PERI_THERM 2
+#define PERI_PWM1 3
+#define PERI_PWM2 4
+#define PERI_PWM3 5
+#define PERI_PWM4 6
+#define PERI_PWM5 7
+#define PERI_PWM6 8
+#define PERI_PWM7 9
+#define PERI_PWM 10
+#define PERI_USB0 11
+#define PERI_USB1 12
+#define PERI_AP_DMA 13
+#define PERI_MSDC30_0 14
+#define PERI_MSDC30_1 15
+#define PERI_MSDC30_2 16
+#define PERI_MSDC30_3 17
+#define PERI_NLI_ARB 18
+#define PERI_IRDA 19
+#define PERI_UART0 20
+#define PERI_UART1 21
+#define PERI_UART2 22
+#define PERI_UART3 23
+#define PERI_I2C0 24
+#define PERI_I2C1 25
+#define PERI_I2C2 26
+#define PERI_I2C3 27
+#define PERI_I2C4 28
+#define PERI_AUXADC 29
+#define PERI_SPI0 30
+#define PERI_I2C5 31
+#define PERI_NFIECC 32
+#define PERI_SPI 33
+#define PERI_IRRX 34
+#define PERI_I2C6 35
+#define PERI_NR_CLK 36
+
+#endif /* _DT_BINDINGS_CLK_MT8173_H */
diff --git a/include/dt-bindings/reset-controller/mt8173-resets.h b/include/dt-bindings/reset-controller/mt8173-resets.h
new file mode 100644
index 0000000..9464b37
--- /dev/null
+++ b/include/dt-bindings/reset-controller/mt8173-resets.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: Flora Fu, MediaTek
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 _DT_BINDINGS_RESET_CONTROLLER_MT8173
+#define _DT_BINDINGS_RESET_CONTROLLER_MT8173
+
+/* INFRACFG resets */
+#define MT8173_INFRA_EMI_REG_RST 0
+#define MT8173_INFRA_DRAMC0_A0_RST 1
+#define MT8173_INFRA_APCIRQ_EINT_RST 3
+#define MT8173_INFRA_APXGPT_RST 4
+#define MT8173_INFRA_SCPSYS_RST 5
+#define MT8173_INFRA_KP_RST 6
+#define MT8173_INFRA_PMIC_WRAP_RST 7
+#define MT8173_INFRA_MPIP_RST 8
+#define MT8173_INFRA_CEC_RST 9
+#define MT8173_INFRA_EMI_RST 32
+#define MT8173_INFRA_DRAMC0_RST 34
+#define MT8173_INFRA_APMIXEDSYS_RST 35
+#define MT8173_INFRA_MIPI_DSI_RST 36
+#define MT8173_INFRA_TRNG_RST 37
+#define MT8173_INFRA_SYSIRQ_RST 38
+#define MT8173_INFRA_MIPI_CSI_RST 39
+#define MT8173_INFRA_GCE_FAXI_RST 40
+#define MT8173_INFRA_MMIOMMURST 47
+
+
+/* PERICFG resets */
+#define MT8173_PERI_UART0_SW_RST 0
+#define MT8173_PERI_UART1_SW_RST 1
+#define MT8173_PERI_UART2_SW_RST 2
+#define MT8173_PERI_UART3_SW_RST 3
+#define MT8173_PERI_IRRX_SW_RST 4
+#define MT8173_PERI_PWM_SW_RST 8
+#define MT8173_PERI_AUXADC_SW_RST 10
+#define MT8173_PERI_DMA_SW_RST 11
+#define MT8173_PERI_I2C6_SW_RST 13
+#define MT8173_PERI_NFI_SW_RST 14
+#define MT8173_PERI_THERM_SW_RST 16
+#define MT8173_PERI_MSDC2_SW_RST 17
+#define MT8173_PERI_MSDC3_SW_RST 18
+#define MT8173_PERI_MSDC0_SW_RST 19
+#define MT8173_PERI_MSDC1_SW_RST 20
+#define MT8173_PERI_I2C0_SW_RST 22
+#define MT8173_PERI_I2C1_SW_RST 23
+#define MT8173_PERI_I2C2_SW_RST 24
+#define MT8173_PERI_I2C3_SW_RST 25
+#define MT8173_PERI_I2C4_SW_RST 26
+#define MT8173_PERI_HDMI_SW_RST 29
+#define MT8173_PERI_SPI0_SW_RST 33
+
+#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT8173 */
--
2.1.4
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 4/5] clk: mediatek: Add basic clocks for Mediatek MT8173.
@ 2015-02-22 11:49 ` Sascha Hauer
0 siblings, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2015-02-22 11:49 UTC (permalink / raw)
To: linux-arm-kernel
From: James Liao <jamesjj.liao@mediatek.com>
This patch adds basic clocks for MT8173, including TOPCKGEN, PLLs,
INFRA and PERI clocks.
Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/clk/mediatek/Makefile | 1 +
drivers/clk/mediatek/clk-mt8173.c | 820 +++++++++++++++++++++
include/dt-bindings/clock/mt8173-clk.h | 231 ++++++
.../dt-bindings/reset-controller/mt8173-resets.h | 63 ++
4 files changed, 1115 insertions(+)
create mode 100644 drivers/clk/mediatek/clk-mt8173.c
create mode 100644 include/dt-bindings/clock/mt8173-clk.h
create mode 100644 include/dt-bindings/reset-controller/mt8173-resets.h
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 12ce576..8e4b2a4 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -1,3 +1,4 @@
obj-y += clk-mtk.o clk-pll.o clk-gate.o
obj-$(CONFIG_RESET_CONTROLLER) += reset.o
obj-y += clk-mt8135.o
+obj-y += clk-mt8173.o
diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
new file mode 100644
index 0000000..014e552
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8173.c
@@ -0,0 +1,820 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/mfd/syscon.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt8173-clk.h>
+
+static DEFINE_SPINLOCK(lock);
+
+static struct mtk_fixed_factor root_clk_alias[] __initdata = {
+ FACTOR(TOP_CLKPH_MCK_O, "clkph_mck_o", "clk_null", 1, 1),
+ FACTOR(TOP_DPI_CK, "dpi_ck", "clk_null", 1, 1),
+ FACTOR(TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk_null", 1, 1),
+ FACTOR(TOP_HDMITX_DIG_CTS, "hdmitx_dig_cts", "clk_null", 1, 1),
+};
+
+static struct mtk_fixed_factor top_divs[] __initdata = {
+ FACTOR(TOP_ARMCA7PLL_754M, "armca7pll_754m", "armca7pll", 1, 2),
+ FACTOR(TOP_ARMCA7PLL_502M, "armca7pll_502m", "armca7pll", 1, 3),
+
+ FACTOR(TOP_MAIN_H546M, "main_h546m", "mainpll", 1, 2),
+ FACTOR(TOP_MAIN_H364M, "main_h364m", "mainpll", 1, 3),
+ FACTOR(TOP_MAIN_H218P4M, "main_h218p4m", "mainpll", 1, 5),
+ FACTOR(TOP_MAIN_H156M, "main_h156m", "mainpll", 1, 7),
+
+ FACTOR(TOP_TVDPLL_445P5M, "tvdpll_445p5m", "tvdpll", 1, 4),
+ FACTOR(TOP_TVDPLL_594M, "tvdpll_594m", "tvdpll", 1, 3),
+
+ FACTOR(TOP_UNIV_624M, "univ_624m", "univpll", 1, 2),
+ FACTOR(TOP_UNIV_416M, "univ_416m", "univpll", 1, 3),
+ FACTOR(TOP_UNIV_249P6M, "univ_249p6m", "univpll", 1, 5),
+ FACTOR(TOP_UNIV_178P3M, "univ_178p3m", "univpll", 1, 7),
+ FACTOR(TOP_UNIV_48M, "univ_48m", "univpll", 1, 26),
+
+ FACTOR(TOP_CLKRTC_EXT, "clkrtc_ext", "clk32k", 1, 1),
+ FACTOR(TOP_CLKRTC_INT, "clkrtc_int", "clk26m", 1, 793),
+ FACTOR(TOP_FPC_CK, "fpc_ck", "clk26m", 1, 1),
+
+ FACTOR(TOP_HDMITXPLL_D2, "hdmitxpll_d2", "hdmitx_dig_cts", 1, 2),
+ FACTOR(TOP_HDMITXPLL_D3, "hdmitxpll_d3", "hdmitx_dig_cts", 1, 3),
+
+ FACTOR(TOP_ARMCA7PLL_D2, "armca7pll_d2", "armca7pll_754m", 1, 1),
+ FACTOR(TOP_ARMCA7PLL_D3, "armca7pll_d3", "armca7pll_502m", 1, 1),
+
+ FACTOR(TOP_APLL1_CK, "apll1_ck", "apll1", 1, 1),
+ FACTOR(TOP_APLL2_CK, "apll2_ck", "apll2", 1, 1),
+
+ FACTOR(TOP_DMPLL_CK, "dmpll_ck", "clkph_mck_o", 1, 1),
+ FACTOR(TOP_DMPLL_D2, "dmpll_d2", "clkph_mck_o", 1, 2),
+ FACTOR(TOP_DMPLL_D4, "dmpll_d4", "clkph_mck_o", 1, 4),
+ FACTOR(TOP_DMPLL_D8, "dmpll_d8", "clkph_mck_o", 1, 8),
+ FACTOR(TOP_DMPLL_D16, "dmpll_d16", "clkph_mck_o", 1, 16),
+
+ FACTOR(TOP_LVDSPLL_D2, "lvdspll_d2", "lvdspll", 1, 2),
+ FACTOR(TOP_LVDSPLL_D4, "lvdspll_d4", "lvdspll", 1, 4),
+ FACTOR(TOP_LVDSPLL_D8, "lvdspll_d8", "lvdspll", 1, 8),
+
+ FACTOR(TOP_MMPLL_CK, "mmpll_ck", "mmpll", 1, 1),
+ FACTOR(TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2),
+
+ FACTOR(TOP_MSDCPLL_CK, "msdcpll_ck", "msdcpll", 1, 1),
+ FACTOR(TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2),
+ FACTOR(TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll", 1, 4),
+ FACTOR(TOP_MSDCPLL2_CK, "msdcpll2_ck", "msdcpll2", 1, 1),
+ FACTOR(TOP_MSDCPLL2_D2, "msdcpll2_d2", "msdcpll2", 1, 2),
+ FACTOR(TOP_MSDCPLL2_D4, "msdcpll2_d4", "msdcpll2", 1, 4),
+
+ FACTOR(TOP_SYSPLL_D2, "syspll_d2", "main_h546m", 1, 1),
+ FACTOR(TOP_SYSPLL1_D2, "syspll1_d2", "main_h546m", 1, 2),
+ FACTOR(TOP_SYSPLL1_D4, "syspll1_d4", "main_h546m", 1, 4),
+ FACTOR(TOP_SYSPLL1_D8, "syspll1_d8", "main_h546m", 1, 8),
+ FACTOR(TOP_SYSPLL1_D16, "syspll1_d16", "main_h546m", 1, 16),
+ FACTOR(TOP_SYSPLL_D3, "syspll_d3", "main_h364m", 1, 1),
+ FACTOR(TOP_SYSPLL2_D2, "syspll2_d2", "main_h364m", 1, 2),
+ FACTOR(TOP_SYSPLL2_D4, "syspll2_d4", "main_h364m", 1, 4),
+ FACTOR(TOP_SYSPLL_D5, "syspll_d5", "main_h218p4m", 1, 1),
+ FACTOR(TOP_SYSPLL3_D2, "syspll3_d2", "main_h218p4m", 1, 2),
+ FACTOR(TOP_SYSPLL3_D4, "syspll3_d4", "main_h218p4m", 1, 4),
+ FACTOR(TOP_SYSPLL_D7, "syspll_d7", "main_h156m", 1, 1),
+ FACTOR(TOP_SYSPLL4_D2, "syspll4_d2", "main_h156m", 1, 2),
+ FACTOR(TOP_SYSPLL4_D4, "syspll4_d4", "main_h156m", 1, 4),
+
+ FACTOR(TOP_TVDPLL_CK, "tvdpll_ck", "tvdpll_594m", 1, 1),
+ FACTOR(TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll_594m", 1, 2),
+ FACTOR(TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll_594m", 1, 4),
+ FACTOR(TOP_TVDPLL_D8, "tvdpll_d8", "tvdpll_594m", 1, 8),
+ FACTOR(TOP_TVDPLL_D16, "tvdpll_d16", "tvdpll_594m", 1, 16),
+
+ FACTOR(TOP_UNIVPLL_D2, "univpll_d2", "univ_624m", 1, 1),
+ FACTOR(TOP_UNIVPLL1_D2, "univpll1_d2", "univ_624m", 1, 2),
+ FACTOR(TOP_UNIVPLL1_D4, "univpll1_d4", "univ_624m", 1, 4),
+ FACTOR(TOP_UNIVPLL1_D8, "univpll1_d8", "univ_624m", 1, 8),
+ FACTOR(TOP_UNIVPLL_D3, "univpll_d3", "univ_416m", 1, 1),
+ FACTOR(TOP_UNIVPLL2_D2, "univpll2_d2", "univ_416m", 1, 2),
+ FACTOR(TOP_UNIVPLL2_D4, "univpll2_d4", "univ_416m", 1, 4),
+ FACTOR(TOP_UNIVPLL2_D8, "univpll2_d8", "univ_416m", 1, 8),
+ FACTOR(TOP_UNIVPLL_D5, "univpll_d5", "univ_249p6m", 1, 1),
+ FACTOR(TOP_UNIVPLL3_D2, "univpll3_d2", "univ_249p6m", 1, 2),
+ FACTOR(TOP_UNIVPLL3_D4, "univpll3_d4", "univ_249p6m", 1, 4),
+ FACTOR(TOP_UNIVPLL3_D8, "univpll3_d8", "univ_249p6m", 1, 8),
+ FACTOR(TOP_UNIVPLL_D7, "univpll_d7", "univ_178p3m", 1, 1),
+ FACTOR(TOP_UNIVPLL_D26, "univpll_d26", "univ_48m", 1, 1),
+ FACTOR(TOP_UNIVPLL_D52, "univpll_d52", "univ_48m", 1, 2),
+
+ FACTOR(TOP_VCODECPLL_CK, "vcodecpll_ck", "vcodecpll", 1, 3),
+ FACTOR(TOP_VCODECPLL_370P5, "vcodecpll_370p5", "vcodecpll", 1, 4),
+
+ FACTOR(TOP_VENCPLL_CK, "vencpll_ck", "vencpll", 1, 1),
+ FACTOR(TOP_VENCPLL_D2, "vencpll_d2", "vencpll", 1, 2),
+ FACTOR(TOP_VENCPLL_D4, "vencpll_d4", "vencpll", 1, 4),
+};
+
+static const char *axi_parents[] __initconst = {
+ "clk26m",
+ "syspll1_d2",
+ "syspll_d5",
+ "syspll1_d4",
+ "univpll_d5",
+ "univpll2_d2",
+ "dmpll_d2",
+ "dmpll_d4"
+};
+
+static const char *mem_parents[] __initconst = {
+ "clk26m",
+ "dmpll_ck"
+};
+
+static const char *ddrphycfg_parents[] __initconst = {
+ "clk26m",
+ "syspll1_d8"
+};
+
+static const char *mm_parents[] __initconst = {
+ "clk26m",
+ "vencpll_d2",
+ "main_h364m",
+ "syspll1_d2",
+ "syspll_d5",
+ "syspll1_d4",
+ "univpll1_d2",
+ "univpll2_d2",
+ "dmpll_d2"
+};
+
+static const char *pwm_parents[] __initconst = {
+ "clk26m",
+ "univpll2_d4",
+ "univpll3_d2",
+ "univpll1_d4"
+};
+
+static const char *vdec_parents[] __initconst = {
+ "clk26m",
+ "vcodecpll_ck",
+ "tvdpll_445p5m",
+ "univpll_d3",
+ "vencpll_d2",
+ "syspll_d3",
+ "univpll1_d2",
+ "mmpll_d2",
+ "dmpll_d2",
+ "dmpll_d4"
+};
+
+static const char *venc_parents[] __initconst = {
+ "clk26m",
+ "vcodecpll_ck",
+ "tvdpll_445p5m",
+ "univpll_d3",
+ "vencpll_d2",
+ "syspll_d3",
+ "univpll1_d2",
+ "univpll2_d2",
+ "dmpll_d2",
+ "dmpll_d4"
+};
+
+static const char *mfg_parents[] __initconst = {
+ "clk26m",
+ "mmpll_ck",
+ "dmpll_ck",
+ "clk26m",
+ "clk26m",
+ "clk26m",
+ "clk26m",
+ "clk26m",
+ "clk26m",
+ "syspll_d3",
+ "syspll1_d2",
+ "syspll_d5",
+ "univpll_d3",
+ "univpll1_d2",
+ "univpll_d5",
+ "univpll2_d2"
+};
+
+static const char *camtg_parents[] __initconst = {
+ "clk26m",
+ "univpll_d26",
+ "univpll2_d2",
+ "syspll3_d2",
+ "syspll3_d4",
+ "univpll1_d4"
+};
+
+static const char *uart_parents[] __initconst = {
+ "clk26m",
+ "univpll2_d8"
+};
+
+static const char *spi_parents[] __initconst = {
+ "clk26m",
+ "syspll3_d2",
+ "syspll1_d4",
+ "syspll4_d2",
+ "univpll3_d2",
+ "univpll2_d4",
+ "univpll1_d8"
+};
+
+static const char *usb20_parents[] __initconst = {
+ "clk26m",
+ "univpll1_d8",
+ "univpll3_d4"
+};
+
+static const char *usb30_parents[] __initconst = {
+ "clk26m",
+ "univpll3_d2",
+ "usb_syspll_125m",
+ "univpll2_d4"
+};
+
+static const char *msdc50_0_h_parents[] __initconst = {
+ "clk26m",
+ "syspll1_d2",
+ "syspll2_d2",
+ "syspll4_d2",
+ "univpll_d5",
+ "univpll1_d4"
+};
+
+static const char *msdc50_0_parents[] __initconst = {
+ "clk26m",
+ "msdcpll_ck",
+ "msdcpll_d2",
+ "univpll1_d4",
+ "syspll2_d2",
+ "syspll_d7",
+ "msdcpll_d4",
+ "vencpll_d4",
+ "tvdpll_ck",
+ "univpll_d2",
+ "univpll1_d2",
+ "mmpll_ck",
+ "msdcpll2_ck",
+ "msdcpll2_d2",
+ "msdcpll2_d4"
+};
+
+static const char *msdc30_1_parents[] __initconst = {
+ "clk26m",
+ "univpll2_d2",
+ "msdcpll_d4",
+ "univpll1_d4",
+ "syspll2_d2",
+ "syspll_d7",
+ "univpll_d7",
+ "vencpll_d4"
+};
+
+static const char *msdc30_2_parents[] __initconst = {
+ "clk26m",
+ "univpll2_d2",
+ "msdcpll_d4",
+ "univpll1_d4",
+ "syspll2_d2",
+ "syspll_d7",
+ "univpll_d7",
+ "vencpll_d2"
+};
+
+static const char *msdc30_3_parents[] __initconst = {
+ "clk26m",
+ "msdcpll2_ck",
+ "msdcpll2_d2",
+ "univpll2_d2",
+ "msdcpll2_d4",
+ "msdcpll_d4",
+ "univpll1_d4",
+ "syspll2_d2",
+ "syspll_d7",
+ "univpll_d7",
+ "vencpll_d4",
+ "msdcpll_ck",
+ "msdcpll_d2",
+ "msdcpll_d4"
+};
+
+static const char *audio_parents[] __initconst = {
+ "clk26m",
+ "syspll3_d4",
+ "syspll4_d4",
+ "syspll1_d16"
+};
+
+static const char *aud_intbus_parents[] __initconst = {
+ "clk26m",
+ "syspll1_d4",
+ "syspll4_d2",
+ "univpll3_d2",
+ "univpll2_d8",
+ "dmpll_d4",
+ "dmpll_d8"
+};
+
+static const char *pmicspi_parents[] __initconst = {
+ "clk26m",
+ "syspll1_d8",
+ "syspll3_d4",
+ "syspll1_d16",
+ "univpll3_d4",
+ "univpll_d26",
+ "dmpll_d8",
+ "dmpll_d16"
+};
+
+static const char *scp_parents[] __initconst = {
+ "clk26m",
+ "syspll1_d2",
+ "univpll_d5",
+ "syspll_d5",
+ "dmpll_d2",
+ "dmpll_d4"
+};
+
+static const char *atb_parents[] __initconst = {
+ "clk26m",
+ "syspll1_d2",
+ "univpll_d5",
+ "dmpll_d2"
+};
+
+static const char *venc_lt_parents[] __initconst = {
+ "clk26m",
+ "univpll_d3",
+ "vcodecpll_ck",
+ "tvdpll_445p5m",
+ "vencpll_d2",
+ "syspll_d3",
+ "univpll1_d2",
+ "univpll2_d2",
+ "syspll1_d2",
+ "univpll_d5",
+ "vcodecpll_370p5",
+ "dmpll_ck"
+};
+
+static const char *dpi0_parents[] __initconst = {
+ "clk26m",
+ "tvdpll_d2",
+ "tvdpll_d4",
+ "clk26m",
+ "clk26m",
+ "tvdpll_d8",
+ "tvdpll_d16"
+};
+
+static const char *irda_parents[] __initconst = {
+ "clk26m",
+ "univpll2_d4",
+ "syspll2_d4"
+};
+
+static const char *cci400_parents[] __initconst = {
+ "clk26m",
+ "vencpll_ck",
+ "armca7pll_754m",
+ "armca7pll_502m",
+ "univpll_d2",
+ "syspll_d2",
+ "msdcpll_ck",
+ "dmpll_ck"
+};
+
+static const char *aud_1_parents[] __initconst = {
+ "clk26m",
+ "apll1_ck",
+ "univpll2_d4",
+ "univpll2_d8"
+};
+
+static const char *aud_2_parents[] __initconst = {
+ "clk26m",
+ "apll2_ck",
+ "univpll2_d4",
+ "univpll2_d8"
+};
+
+static const char *mem_mfg_in_parents[] __initconst = {
+ "clk26m",
+ "mmpll_ck",
+ "dmpll_ck",
+ "clk26m"
+};
+
+static const char *axi_mfg_in_parents[] __initconst = {
+ "clk26m",
+ "axi_sel",
+ "dmpll_d2"
+};
+
+static const char *scam_parents[] __initconst = {
+ "clk26m",
+ "syspll3_d2",
+ "univpll2_d4",
+ "dmpll_d4"
+};
+
+static const char *spinfi_ifr_parents[] __initconst = {
+ "clk26m",
+ "univpll2_d8",
+ "univpll3_d4",
+ "syspll4_d2",
+ "univpll2_d4",
+ "univpll3_d2",
+ "syspll1_d4",
+ "univpll1_d4"
+};
+
+static const char *hdmi_parents[] __initconst = {
+ "clk26m",
+ "hdmitx_dig_cts",
+ "hdmitxpll_d2",
+ "hdmitxpll_d3"
+};
+
+static const char *dpilvds_parents[] __initconst = {
+ "clk26m",
+ "lvdspll",
+ "lvdspll_d2",
+ "lvdspll_d4",
+ "lvdspll_d8",
+ "fpc_ck"
+};
+
+static const char *msdc50_2_h_parents[] __initconst = {
+ "clk26m",
+ "syspll1_d2",
+ "syspll2_d2",
+ "syspll4_d2",
+ "univpll_d5",
+ "univpll1_d4"
+};
+
+static const char *hdcp_parents[] __initconst = {
+ "clk26m",
+ "syspll4_d2",
+ "syspll3_d4",
+ "univpll2_d4"
+};
+
+static const char *hdcp_24m_parents[] __initconst = {
+ "clk26m",
+ "univpll_d26",
+ "univpll_d52",
+ "univpll2_d8"
+};
+
+static const char *rtc_parents[] __initconst = {
+ "clkrtc_int",
+ "clkrtc_ext",
+ "clk26m",
+ "univpll3_d8"
+};
+
+static const char *i2s0_m_ck_parents[] __initconst = {
+ "apll1_div1",
+ "apll2_div1"
+};
+
+static const char *i2s1_m_ck_parents[] __initconst = {
+ "apll1_div2",
+ "apll2_div2"
+};
+
+static const char *i2s2_m_ck_parents[] __initconst = {
+ "apll1_div3",
+ "apll2_div3"
+};
+
+static const char *i2s3_m_ck_parents[] __initconst = {
+ "apll1_div4",
+ "apll2_div4"
+};
+
+static const char *i2s3_b_ck_parents[] __initconst = {
+ "apll1_div5",
+ "apll2_div5"
+};
+
+static struct mtk_composite top_muxes[] __initdata = {
+ /* CLK_CFG_0 */
+ MUX(TOP_AXI_SEL, "axi_sel", axi_parents, 0x0040, 0, 3),
+ MUX(TOP_MEM_SEL, "mem_sel", mem_parents, 0x0040, 8, 1),
+ MUX_GATE(TOP_DDRPHYCFG_SEL, "ddrphycfg_sel", ddrphycfg_parents, 0x0040, 16, 1, 23),
+ MUX_GATE(TOP_MM_SEL, "mm_sel", mm_parents, 0x0040, 24, 4, 31),
+ /* CLK_CFG_1 */
+ MUX_GATE(TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x0050, 0, 2, 7),
+ MUX_GATE(TOP_VDEC_SEL, "vdec_sel", vdec_parents, 0x0050, 8, 4, 15),
+ MUX_GATE(TOP_VENC_SEL, "venc_sel", venc_parents, 0x0050, 16, 4, 23),
+ MUX_GATE(TOP_MFG_SEL, "mfg_sel", mfg_parents, 0x0050, 24, 4, 31),
+ /* CLK_CFG_2 */
+ MUX_GATE(TOP_CAMTG_SEL, "camtg_sel", camtg_parents, 0x0060, 0, 3, 7),
+ MUX_GATE(TOP_UART_SEL, "uart_sel", uart_parents, 0x0060, 8, 1, 15),
+ MUX_GATE(TOP_SPI_SEL, "spi_sel", spi_parents, 0x0060, 16, 3, 23),
+ MUX_GATE(TOP_USB20_SEL, "usb20_sel", usb20_parents, 0x0060, 24, 2, 31),
+ /* CLK_CFG_3 */
+ MUX_GATE(TOP_USB30_SEL, "usb30_sel", usb30_parents, 0x0070, 0, 2, 7),
+ MUX_GATE(TOP_MSDC50_0_H_SEL, "msdc50_0_h_sel", msdc50_0_h_parents, 0x0070, 8, 3, 15),
+ MUX_GATE(TOP_MSDC50_0_SEL, "msdc50_0_sel", msdc50_0_parents, 0x0070, 16, 4, 23),
+ MUX_GATE(TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_1_parents, 0x0070, 24, 3, 31),
+ /* CLK_CFG_4 */
+ MUX_GATE(TOP_MSDC30_2_SEL, "msdc30_2_sel", msdc30_2_parents, 0x0080, 0, 3, 7),
+ MUX_GATE(TOP_MSDC30_3_SEL, "msdc30_3_sel", msdc30_3_parents, 0x0080, 8, 4, 15),
+ MUX_GATE(TOP_AUDIO_SEL, "audio_sel", audio_parents, 0x0080, 16, 2, 23),
+ MUX_GATE(TOP_AUD_INTBUS_SEL, "aud_intbus_sel", aud_intbus_parents, 0x0080, 24, 3, 31),
+ /* CLK_CFG_5 */
+ MUX_GATE(TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents, 0x0090, 0, 3, 7 /* 7:5 */),
+ MUX_GATE(TOP_SCP_SEL, "scp_sel", scp_parents, 0x0090, 8, 3, 15),
+ MUX_GATE(TOP_ATB_SEL, "atb_sel", atb_parents, 0x0090, 16, 2, 23),
+ MUX_GATE(TOP_VENC_LT_SEL, "venclt_sel", venc_lt_parents, 0x0090, 24, 4, 31),
+ /* CLK_CFG_6 */
+ MUX_GATE(TOP_DPI0_SEL, "dpi0_sel", dpi0_parents, 0x00a0, 0, 3, 7),
+ MUX_GATE(TOP_IRDA_SEL, "irda_sel", irda_parents, 0x00a0, 8, 2, 15),
+ MUX_GATE(TOP_CCI400_SEL, "cci400_sel", cci400_parents, 0x00a0, 16, 3, 23),
+ MUX_GATE(TOP_AUD_1_SEL, "aud_1_sel", aud_1_parents, 0x00a0, 24, 2, 31),
+ /* CLK_CFG_7 */
+ MUX_GATE(TOP_AUD_2_SEL, "aud_2_sel", aud_2_parents, 0x00b0, 0, 2, 7),
+ MUX_GATE(TOP_MEM_MFG_IN_SEL, "mem_mfg_in_sel", mem_mfg_in_parents, 0x00b0, 8, 2, 15),
+ MUX_GATE(TOP_AXI_MFG_IN_SEL, "axi_mfg_in_sel", axi_mfg_in_parents, 0x00b0, 16, 2, 23),
+ MUX_GATE(TOP_SCAM_SEL, "scam_sel", scam_parents, 0x00b0, 24, 2, 31),
+ /* CLK_CFG_12 */
+ MUX_GATE(TOP_SPINFI_IFR_SEL, "spinfi_ifr_sel", spinfi_ifr_parents, 0x00c0, 0, 3, 7),
+ MUX_GATE(TOP_HDMI_SEL, "hdmi_sel", hdmi_parents, 0x00c0, 8, 2, 15),
+ MUX_GATE(TOP_DPILVDS_SEL, "dpilvds_sel", dpilvds_parents, 0x00c0, 24, 3, 31),
+ /* CLK_CFG_13 */
+ MUX_GATE(TOP_MSDC50_2_H_SEL, "msdc50_2_h_sel", msdc50_2_h_parents, 0x00d0, 0, 3, 7),
+ MUX_GATE(TOP_HDCP_SEL, "hdcp_sel", hdcp_parents, 0x00d0, 8, 2, 15),
+ MUX_GATE(TOP_HDCP_24M_SEL, "hdcp_24m_sel", hdcp_24m_parents, 0x00d0, 16, 2, 23),
+ MUX(TOP_RTC_SEL, "rtc_sel", rtc_parents, 0x00d0, 24, 2),
+
+ DIV_GATE(TOP_APLL1_DIV0, "apll1_div0", "aud_1_sel", 0x12c, 8, 0x120, 4, 24),
+ DIV_GATE(TOP_APLL1_DIV1, "apll1_div1", "aud_1_sel", 0x12c, 9, 0x124, 8, 0),
+ DIV_GATE(TOP_APLL1_DIV2, "apll1_div2", "aud_1_sel", 0x12c, 10, 0x124, 8, 8),
+ DIV_GATE(TOP_APLL1_DIV3, "apll1_div3", "aud_1_sel", 0x12c, 11, 0x124, 8, 16),
+ DIV_GATE(TOP_APLL1_DIV4, "apll1_div4", "aud_1_sel", 0x12c, 12, 0x124, 8, 24),
+ DIV_GATE(TOP_APLL1_DIV5, "apll1_div5", "aud_1_sel", 0x12c, 13, 0x12c, 4, 0),
+
+ DIV_GATE(TOP_APLL2_DIV0, "apll2_div0", "aud_2_sel", 0x12c, 16, 0x120, 4, 28),
+ DIV_GATE(TOP_APLL2_DIV1, "apll2_div1", "aud_2_sel", 0x12c, 17, 0x128, 8, 0),
+ DIV_GATE(TOP_APLL2_DIV2, "apll2_div2", "aud_2_sel", 0x12c, 18, 0x128, 8, 8),
+ DIV_GATE(TOP_APLL2_DIV3, "apll2_div3", "aud_2_sel", 0x12c, 19, 0x128, 8, 16),
+ DIV_GATE(TOP_APLL2_DIV4, "apll2_div4", "aud_2_sel", 0x12c, 20, 0x128, 8, 24),
+ DIV_GATE(TOP_APLL2_DIV5, "apll2_div5", "aud_2_sel", 0x12c, 21, 0x12c, 4, 4),
+
+ MUX(TOP_I2S0_M_CK_SEL, "i2s0_m_ck_sel", i2s0_m_ck_parents, 0x120, 4, 1),
+ MUX(TOP_I2S1_M_CK_SEL, "i2s1_m_ck_sel", i2s1_m_ck_parents, 0x120, 5, 1),
+ MUX(TOP_I2S2_M_CK_SEL, "i2s2_m_ck_sel", i2s2_m_ck_parents, 0x120, 6, 1),
+ MUX(TOP_I2S3_M_CK_SEL, "i2s3_m_ck_sel", i2s3_m_ck_parents, 0x120, 7, 1),
+ MUX(TOP_I2S3_B_CK_SEL, "i2s3_b_ck_sel", i2s3_b_ck_parents, 0x120, 8, 1),
+};
+
+static void __init mtk_init_clk_topckgen(void __iomem *top_base,
+ struct clk_onecell_data *clk_data)
+{
+ int i;
+ struct clk *clk;
+
+ for (i = 0; i < ARRAY_SIZE(top_muxes); i++) {
+ struct mtk_composite *mux = &top_muxes[i];
+
+ clk = mtk_clk_register_composite(mux, top_base, &lock);
+
+ if (IS_ERR(clk)) {
+ pr_err("Failed to register clk %s: %ld\n",
+ mux->name, PTR_ERR(clk));
+ continue;
+ }
+
+ if (clk_data)
+ clk_data->clks[mux->id] = clk;
+ }
+}
+
+static struct mtk_gate_regs infra_cg_regs = {
+ .set_ofs = 0x0040,
+ .clr_ofs = 0x0044,
+ .sta_ofs = 0x0048,
+};
+
+#define GATE_ICG(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &infra_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_setclr, \
+ }
+
+static struct mtk_gate infra_clks[] __initdata = {
+ GATE_ICG(INFRA_DBGCLK, "infra_dbgclk", "axi_sel", 0),
+ GATE_ICG(INFRA_SMI, "infra_smi", "mm_sel", 1),
+ GATE_ICG(INFRA_AUDIO, "infra_audio", "aud_intbus_sel", 5),
+ GATE_ICG(INFRA_GCE, "infra_gce", "axi_sel", 6),
+ GATE_ICG(INFRA_L2C_SRAM, "infra_l2c_sram", "axi_sel", 7),
+ GATE_ICG(INFRA_M4U, "infra_m4u", "mem_sel", 8),
+ GATE_ICG(INFRA_CPUM, "infra_cpum", "clk_null", 15),
+ GATE_ICG(INFRA_KP, "infra_kp", "axi_sel", 16),
+ GATE_ICG(INFRA_CEC, "infra_cec", "clk26m", 18),
+ GATE_ICG(INFRA_PMICSPI, "infra_pmicspi", "pmicspi_sel", 22),
+ GATE_ICG(INFRA_PMICWRAP, "infra_pmicwrap", "axi_sel", 23),
+};
+
+static struct mtk_gate_regs peri0_cg_regs = {
+ .set_ofs = 0x0008,
+ .clr_ofs = 0x0010,
+ .sta_ofs = 0x0018,
+};
+
+static struct mtk_gate_regs peri1_cg_regs = {
+ .set_ofs = 0x000c,
+ .clr_ofs = 0x0014,
+ .sta_ofs = 0x001c,
+};
+
+#define GATE_PERI0(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &peri0_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_setclr, \
+ }
+
+#define GATE_PERI1(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &peri1_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_setclr, \
+ }
+
+static struct mtk_gate peri_clks[] __initdata = {
+ /* PERI0 */
+ GATE_PERI0(PERI_NFI, "peri_nfi", "axi_sel", 0),
+ GATE_PERI0(PERI_THERM, "peri_therm", "axi_sel", 1),
+ GATE_PERI0(PERI_PWM1, "peri_pwm1", "axi_sel", 2),
+ GATE_PERI0(PERI_PWM2, "peri_pwm2", "axi_sel", 3),
+ GATE_PERI0(PERI_PWM3, "peri_pwm3", "axi_sel", 4),
+ GATE_PERI0(PERI_PWM4, "peri_pwm4", "axi_sel", 5),
+ GATE_PERI0(PERI_PWM5, "peri_pwm5", "axi_sel", 6),
+ GATE_PERI0(PERI_PWM6, "peri_pwm6", "axi_sel", 7),
+ GATE_PERI0(PERI_PWM7, "peri_pwm7", "axi_sel", 8),
+ GATE_PERI0(PERI_PWM, "peri_pwm", "axi_sel", 9),
+ GATE_PERI0(PERI_USB0, "peri_usb0", "usb20_sel", 10),
+ GATE_PERI0(PERI_USB1, "peri_usb1", "usb20_sel", 11),
+ GATE_PERI0(PERI_AP_DMA, "peri_ap_dma", "axi_sel", 12),
+ GATE_PERI0(PERI_MSDC30_0, "peri_msdc30_0", "msdc50_0_sel", 13),
+ GATE_PERI0(PERI_MSDC30_1, "peri_msdc30_1", "msdc30_1_sel", 14),
+ GATE_PERI0(PERI_MSDC30_2, "peri_msdc30_2", "msdc30_2_sel", 15),
+ GATE_PERI0(PERI_MSDC30_3, "peri_msdc30_3", "msdc30_3_sel", 16),
+ GATE_PERI0(PERI_NLI_ARB, "peri_nli_arb", "axi_sel", 17),
+ GATE_PERI0(PERI_IRDA, "peri_irda", "irda_sel", 18),
+ GATE_PERI0(PERI_UART0, "peri_uart0", "uart_sel", 19),
+ GATE_PERI0(PERI_UART1, "peri_uart1", "uart_sel", 20),
+ GATE_PERI0(PERI_UART2, "peri_uart2", "uart_sel", 21),
+ GATE_PERI0(PERI_UART3, "peri_uart3", "uart_sel", 22),
+ GATE_PERI0(PERI_I2C0, "peri_i2c0", "axi_sel", 23),
+ GATE_PERI0(PERI_I2C1, "peri_i2c1", "axi_sel", 24),
+ GATE_PERI0(PERI_I2C2, "peri_i2c2", "axi_sel", 25),
+ GATE_PERI0(PERI_I2C3, "peri_i2c3", "axi_sel", 26),
+ GATE_PERI0(PERI_I2C4, "peri_i2c4", "axi_sel", 27),
+ GATE_PERI0(PERI_AUXADC, "peri_auxadc", "clk26m", 28),
+ GATE_PERI0(PERI_SPI0, "peri_spi0", "spi_sel", 29),
+ GATE_PERI0(PERI_I2C5, "peri_i2c5", "axi_sel", 30),
+ GATE_PERI0(PERI_NFIECC, "peri_nfiecc", "axi_sel", 31),
+ /* PERI1 */
+ GATE_PERI1(PERI_SPI, "peri_spi", "spi_sel", 0),
+ GATE_PERI1(PERI_IRRX, "peri_irrx", "spi_sel", 1),
+ GATE_PERI1(PERI_I2C6, "peri_i2c6", "axi_sel", 2),
+};
+
+static void __init mtk_topckgen_init(struct device_node *node)
+{
+ struct clk_onecell_data *clk_data;
+ void __iomem *base;
+ int r;
+
+ base = of_iomap(node, 0);
+ if (!base) {
+ pr_err("%s(): ioremap failed\n", __func__);
+ return;
+ }
+
+ clk_data = mtk_alloc_clk_data(TOP_NR_CLK);
+
+ mtk_clk_register_factors(root_clk_alias, ARRAY_SIZE(root_clk_alias), clk_data);
+ mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
+ mtk_init_clk_topckgen(base, clk_data);
+
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
+}
+CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt8173-topckgen", mtk_topckgen_init);
+
+static void __init mtk_infrasys_init(struct device_node *node)
+{
+ struct clk_onecell_data *clk_data;
+ int r;
+
+ clk_data = mtk_alloc_clk_data(INFRA_NR_CLK);
+
+ mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
+ clk_data);
+
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
+
+ mtk_register_reset_controller(node, 2, 0x30);
+}
+CLK_OF_DECLARE(mtk_infrasys, "mediatek,mt8173-infracfg", mtk_infrasys_init);
+
+static void __init mtk_pericfg_init(struct device_node *node)
+{
+ struct clk_onecell_data *clk_data;
+ int r;
+
+ clk_data = mtk_alloc_clk_data(PERI_NR_CLK);
+
+ mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
+ clk_data);
+
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
+
+ mtk_register_reset_controller(node, 2, 0);
+}
+CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt8173-pericfg", mtk_pericfg_init);
+
+#define MT8173_PLL_FMAX (3000UL * MHZ)
+
+#define CON0_MT8173_RST_BAR BIT(24)
+
+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, _pd_shift, \
+ _tuner_reg, _pcw_reg, _pcw_shift) { \
+ .id = _id, \
+ .name = _name, \
+ .reg = _reg, \
+ .pwr_reg = _pwr_reg, \
+ .en_mask = _en_mask, \
+ .flags = _flags, \
+ .rst_bar_mask = CON0_MT8173_RST_BAR, \
+ .fmax = MT8173_PLL_FMAX, \
+ .pcwbits = _pcwbits, \
+ .pd_reg = _pd_reg, \
+ .pd_shift = _pd_shift, \
+ .tuner_reg = _tuner_reg, \
+ .pcw_reg = _pcw_reg, \
+ .pcw_shift = _pcw_shift, \
+ }
+
+static const struct mtk_pll_data plls[] = {
+ PLL(APMIXED_ARMCA15PLL, "armca15pll", 0x200, 0x20c, 0x00000001, 0, 21, 0x204, 24, 0x0, 0x204, 0),
+ PLL(APMIXED_ARMCA7PLL, "armca7pll", 0x210, 0x21c, 0x00000001, 0, 21, 0x214, 24, 0x0, 0x214, 0),
+ PLL(APMIXED_MAINPLL, "mainpll", 0x220, 0x22c, 0xf0000101, HAVE_RST_BAR, 21, 0x220, 4, 0x0, 0x224, 0),
+ PLL(APMIXED_UNIVPLL, "univpll", 0x230, 0x23c, 0xfe000001, HAVE_RST_BAR, 7, 0x230, 4, 0x0, 0x234, 14),
+ PLL(APMIXED_MMPLL, "mmpll", 0x240, 0x24c, 0x00000001, 0, 21, 0x244, 24, 0x0, 0x244, 0),
+ PLL(APMIXED_MSDCPLL, "msdcpll", 0x250, 0x25c, 0x00000001, 0, 21, 0x250, 4, 0x0, 0x254, 0),
+ PLL(APMIXED_VENCPLL, "vencpll", 0x260, 0x26c, 0x00000001, 0, 21, 0x260, 4, 0x0, 0x264, 0),
+ PLL(APMIXED_TVDPLL, "tvdpll", 0x270, 0x27c, 0x00000001, 0, 21, 0x270, 4, 0x0, 0x274, 0),
+ PLL(APMIXED_MPLL, "mpll", 0x280, 0x28c, 0x00000001, 0, 21, 0x280, 4, 0x0, 0x284, 0),
+ PLL(APMIXED_VCODECPLL, "vcodecpll", 0x290, 0x29c, 0x00000001, 0, 21, 0x290, 4, 0x0, 0x294, 0),
+ PLL(APMIXED_APLL1, "apll1", 0x2a0, 0x2b0, 0x00000001, 0, 31, 0x2a0, 4, 0x2a4, 0x2a4, 0),
+ PLL(APMIXED_APLL2, "apll2", 0x2b4, 0x2c4, 0x00000001, 0, 31, 0x2b4, 4, 0x2b8, 0x2b8, 0),
+ PLL(APMIXED_LVDSPLL, "lvdspll", 0x2d0, 0x2dc, 0x00000001, 0, 21, 0x2d0, 4, 0x0, 0x2d4, 0),
+ PLL(APMIXED_MSDCPLL2, "msdcpll2", 0x2f0, 0x2fc, 0x00000001, 0, 21, 0x2f0, 4, 0x0, 0x2f4, 0),
+};
+
+static void __init mtk_apmixedsys_init(struct device_node *node)
+{
+ mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls));
+}
+CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt8173-apmixedsys",
+ mtk_apmixedsys_init);
diff --git a/include/dt-bindings/clock/mt8173-clk.h b/include/dt-bindings/clock/mt8173-clk.h
new file mode 100644
index 0000000..e648b28
--- /dev/null
+++ b/include/dt-bindings/clock/mt8173-clk.h
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 _DT_BINDINGS_CLK_MT8173_H
+#define _DT_BINDINGS_CLK_MT8173_H
+
+/* TOPCKGEN */
+
+#define TOP_CLKPH_MCK_O 1
+#define TOP_DPI_CK 2
+#define TOP_USB_SYSPLL_125M 3
+#define TOP_HDMITX_DIG_CTS 4
+#define TOP_ARMCA7PLL_754M 5
+#define TOP_ARMCA7PLL_502M 6
+#define TOP_MAIN_H546M 7
+#define TOP_MAIN_H364M 8
+#define TOP_MAIN_H218P4M 9
+#define TOP_MAIN_H156M 10
+#define TOP_TVDPLL_445P5M 11
+#define TOP_TVDPLL_594M 12
+#define TOP_UNIV_624M 13
+#define TOP_UNIV_416M 14
+#define TOP_UNIV_249P6M 15
+#define TOP_UNIV_178P3M 16
+#define TOP_UNIV_48M 17
+#define TOP_CLKRTC_EXT 18
+#define TOP_CLKRTC_INT 19
+#define TOP_FPC_CK 20
+#define TOP_HDMITXPLL_D2 21
+#define TOP_HDMITXPLL_D3 22
+#define TOP_ARMCA7PLL_D2 23
+#define TOP_ARMCA7PLL_D3 24
+#define TOP_APLL1_CK 25
+#define TOP_APLL2_CK 26
+#define TOP_DMPLL_CK 27
+#define TOP_DMPLL_D2 28
+#define TOP_DMPLL_D4 29
+#define TOP_DMPLL_D8 30
+#define TOP_DMPLL_D16 31
+#define TOP_LVDSPLL_D2 32
+#define TOP_LVDSPLL_D4 33
+#define TOP_LVDSPLL_D8 34
+#define TOP_MMPLL_CK 35
+#define TOP_MMPLL_D2 36
+#define TOP_MSDCPLL_CK 37
+#define TOP_MSDCPLL_D2 38
+#define TOP_MSDCPLL_D4 39
+#define TOP_MSDCPLL2_CK 40
+#define TOP_MSDCPLL2_D2 41
+#define TOP_MSDCPLL2_D4 42
+#define TOP_SYSPLL_D2 43
+#define TOP_SYSPLL1_D2 44
+#define TOP_SYSPLL1_D4 45
+#define TOP_SYSPLL1_D8 46
+#define TOP_SYSPLL1_D16 47
+#define TOP_SYSPLL_D3 48
+#define TOP_SYSPLL2_D2 49
+#define TOP_SYSPLL2_D4 50
+#define TOP_SYSPLL_D5 51
+#define TOP_SYSPLL3_D2 52
+#define TOP_SYSPLL3_D4 53
+#define TOP_SYSPLL_D7 54
+#define TOP_SYSPLL4_D2 55
+#define TOP_SYSPLL4_D4 56
+#define TOP_TVDPLL_CK 57
+#define TOP_TVDPLL_D2 58
+#define TOP_TVDPLL_D4 59
+#define TOP_TVDPLL_D8 60
+#define TOP_TVDPLL_D16 61
+#define TOP_UNIVPLL_D2 62
+#define TOP_UNIVPLL1_D2 63
+#define TOP_UNIVPLL1_D4 64
+#define TOP_UNIVPLL1_D8 65
+#define TOP_UNIVPLL_D3 66
+#define TOP_UNIVPLL2_D2 67
+#define TOP_UNIVPLL2_D4 68
+#define TOP_UNIVPLL2_D8 69
+#define TOP_UNIVPLL_D5 70
+#define TOP_UNIVPLL3_D2 71
+#define TOP_UNIVPLL3_D4 72
+#define TOP_UNIVPLL3_D8 73
+#define TOP_UNIVPLL_D7 74
+#define TOP_UNIVPLL_D26 75
+#define TOP_UNIVPLL_D52 76
+#define TOP_VCODECPLL_CK 77
+#define TOP_VCODECPLL_370P5 78
+#define TOP_VENCPLL_CK 79
+#define TOP_VENCPLL_D2 80
+#define TOP_VENCPLL_D4 81
+#define TOP_AXI_SEL 82
+#define TOP_MEM_SEL 83
+#define TOP_DDRPHYCFG_SEL 84
+#define TOP_MM_SEL 85
+#define TOP_PWM_SEL 86
+#define TOP_VDEC_SEL 87
+#define TOP_VENC_SEL 88
+#define TOP_MFG_SEL 89
+#define TOP_CAMTG_SEL 90
+#define TOP_UART_SEL 91
+#define TOP_SPI_SEL 92
+#define TOP_USB20_SEL 93
+#define TOP_USB30_SEL 94
+#define TOP_MSDC50_0_H_SEL 95
+#define TOP_MSDC50_0_SEL 96
+#define TOP_MSDC30_1_SEL 97
+#define TOP_MSDC30_2_SEL 98
+#define TOP_MSDC30_3_SEL 99
+#define TOP_AUDIO_SEL 100
+#define TOP_AUD_INTBUS_SEL 101
+#define TOP_PMICSPI_SEL 102
+#define TOP_SCP_SEL 103
+#define TOP_ATB_SEL 104
+#define TOP_VENC_LT_SEL 105
+#define TOP_DPI0_SEL 106
+#define TOP_IRDA_SEL 107
+#define TOP_CCI400_SEL 108
+#define TOP_AUD_1_SEL 109
+#define TOP_AUD_2_SEL 110
+#define TOP_MEM_MFG_IN_SEL 111
+#define TOP_AXI_MFG_IN_SEL 112
+#define TOP_SCAM_SEL 113
+#define TOP_SPINFI_IFR_SEL 114
+#define TOP_HDMI_SEL 115
+#define TOP_DPILVDS_SEL 116
+#define TOP_MSDC50_2_H_SEL 117
+#define TOP_HDCP_SEL 118
+#define TOP_HDCP_24M_SEL 119
+#define TOP_RTC_SEL 120
+#define TOP_APLL1_DIV0 121
+#define TOP_APLL1_DIV1 122
+#define TOP_APLL1_DIV2 123
+#define TOP_APLL1_DIV3 124
+#define TOP_APLL1_DIV4 125
+#define TOP_APLL1_DIV5 126
+#define TOP_APLL2_DIV0 127
+#define TOP_APLL2_DIV1 128
+#define TOP_APLL2_DIV2 129
+#define TOP_APLL2_DIV3 130
+#define TOP_APLL2_DIV4 131
+#define TOP_APLL2_DIV5 132
+#define TOP_I2S0_M_CK_SEL 133
+#define TOP_I2S1_M_CK_SEL 134
+#define TOP_I2S2_M_CK_SEL 135
+#define TOP_I2S3_M_CK_SEL 136
+#define TOP_I2S3_B_CK_SEL 137
+#define TOP_NR_CLK 138
+
+/* APMIXED_SYS */
+
+#define APMIXED_ARMCA15PLL 1
+#define APMIXED_ARMCA7PLL 2
+#define APMIXED_MAINPLL 3
+#define APMIXED_UNIVPLL 4
+#define APMIXED_MMPLL 5
+#define APMIXED_MSDCPLL 6
+#define APMIXED_VENCPLL 7
+#define APMIXED_TVDPLL 8
+#define APMIXED_MPLL 9
+#define APMIXED_VCODECPLL 10
+#define APMIXED_APLL1 11
+#define APMIXED_APLL2 12
+#define APMIXED_LVDSPLL 13
+#define APMIXED_MSDCPLL2 14
+#define APMIXED_NR_CLK 15
+
+/* INFRA_SYS */
+
+#define INFRA_DBGCLK 1
+#define INFRA_SMI 2
+#define INFRA_AUDIO 3
+#define INFRA_GCE 4
+#define INFRA_L2C_SRAM 5
+#define INFRA_M4U 6
+#define INFRA_CPUM 7
+#define INFRA_KP 8
+#define INFRA_CEC 9
+#define INFRA_PMICSPI 10
+#define INFRA_PMICWRAP 11
+#define INFRA_NR_CLK 12
+
+/* PERI_SYS */
+
+#define PERI_NFI 1
+#define PERI_THERM 2
+#define PERI_PWM1 3
+#define PERI_PWM2 4
+#define PERI_PWM3 5
+#define PERI_PWM4 6
+#define PERI_PWM5 7
+#define PERI_PWM6 8
+#define PERI_PWM7 9
+#define PERI_PWM 10
+#define PERI_USB0 11
+#define PERI_USB1 12
+#define PERI_AP_DMA 13
+#define PERI_MSDC30_0 14
+#define PERI_MSDC30_1 15
+#define PERI_MSDC30_2 16
+#define PERI_MSDC30_3 17
+#define PERI_NLI_ARB 18
+#define PERI_IRDA 19
+#define PERI_UART0 20
+#define PERI_UART1 21
+#define PERI_UART2 22
+#define PERI_UART3 23
+#define PERI_I2C0 24
+#define PERI_I2C1 25
+#define PERI_I2C2 26
+#define PERI_I2C3 27
+#define PERI_I2C4 28
+#define PERI_AUXADC 29
+#define PERI_SPI0 30
+#define PERI_I2C5 31
+#define PERI_NFIECC 32
+#define PERI_SPI 33
+#define PERI_IRRX 34
+#define PERI_I2C6 35
+#define PERI_NR_CLK 36
+
+#endif /* _DT_BINDINGS_CLK_MT8173_H */
diff --git a/include/dt-bindings/reset-controller/mt8173-resets.h b/include/dt-bindings/reset-controller/mt8173-resets.h
new file mode 100644
index 0000000..9464b37
--- /dev/null
+++ b/include/dt-bindings/reset-controller/mt8173-resets.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: Flora Fu, MediaTek
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 _DT_BINDINGS_RESET_CONTROLLER_MT8173
+#define _DT_BINDINGS_RESET_CONTROLLER_MT8173
+
+/* INFRACFG resets */
+#define MT8173_INFRA_EMI_REG_RST 0
+#define MT8173_INFRA_DRAMC0_A0_RST 1
+#define MT8173_INFRA_APCIRQ_EINT_RST 3
+#define MT8173_INFRA_APXGPT_RST 4
+#define MT8173_INFRA_SCPSYS_RST 5
+#define MT8173_INFRA_KP_RST 6
+#define MT8173_INFRA_PMIC_WRAP_RST 7
+#define MT8173_INFRA_MPIP_RST 8
+#define MT8173_INFRA_CEC_RST 9
+#define MT8173_INFRA_EMI_RST 32
+#define MT8173_INFRA_DRAMC0_RST 34
+#define MT8173_INFRA_APMIXEDSYS_RST 35
+#define MT8173_INFRA_MIPI_DSI_RST 36
+#define MT8173_INFRA_TRNG_RST 37
+#define MT8173_INFRA_SYSIRQ_RST 38
+#define MT8173_INFRA_MIPI_CSI_RST 39
+#define MT8173_INFRA_GCE_FAXI_RST 40
+#define MT8173_INFRA_MMIOMMURST 47
+
+
+/* PERICFG resets */
+#define MT8173_PERI_UART0_SW_RST 0
+#define MT8173_PERI_UART1_SW_RST 1
+#define MT8173_PERI_UART2_SW_RST 2
+#define MT8173_PERI_UART3_SW_RST 3
+#define MT8173_PERI_IRRX_SW_RST 4
+#define MT8173_PERI_PWM_SW_RST 8
+#define MT8173_PERI_AUXADC_SW_RST 10
+#define MT8173_PERI_DMA_SW_RST 11
+#define MT8173_PERI_I2C6_SW_RST 13
+#define MT8173_PERI_NFI_SW_RST 14
+#define MT8173_PERI_THERM_SW_RST 16
+#define MT8173_PERI_MSDC2_SW_RST 17
+#define MT8173_PERI_MSDC3_SW_RST 18
+#define MT8173_PERI_MSDC0_SW_RST 19
+#define MT8173_PERI_MSDC1_SW_RST 20
+#define MT8173_PERI_I2C0_SW_RST 22
+#define MT8173_PERI_I2C1_SW_RST 23
+#define MT8173_PERI_I2C2_SW_RST 24
+#define MT8173_PERI_I2C3_SW_RST 25
+#define MT8173_PERI_I2C4_SW_RST 26
+#define MT8173_PERI_HDMI_SW_RST 29
+#define MT8173_PERI_SPI0_SW_RST 33
+
+#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT8173 */
--
2.1.4
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 5/5] dt-bindings: ARM: Mediatek: Document devicetree bindings for clock/reset controllers
2015-02-22 11:49 ` Sascha Hauer
@ 2015-02-22 11:49 ` Sascha Hauer
-1 siblings, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2015-02-22 11:49 UTC (permalink / raw)
To: Mike Turquette
Cc: Matthias Brugger, linux-arm-kernel, linux-kernel, linux-mediatek,
YH Chen, kernel, Yingjoe Chen, Eddie Huang, Henry Chen,
Sascha Hauer
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
.../bindings/arm/mediatek/mediatek,apmixedsys.txt | 23 +++++++++++++++++
.../bindings/arm/mediatek/mediatek,infracfg.txt | 30 ++++++++++++++++++++++
.../bindings/arm/mediatek/mediatek,pericfg.txt | 30 ++++++++++++++++++++++
.../bindings/arm/mediatek/mediatek,topckgen.txt | 23 +++++++++++++++++
4 files changed, 106 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
new file mode 100644
index 0000000..5af6d73
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
@@ -0,0 +1,23 @@
+Mediatek apmixedsys controller
+==============================
+
+The Mediatek apmixedsys controller provides the PLLs to the system.
+
+Required Properties:
+
+- compatible: Should be:
+ - "mediatek,mt8135-apmixedsys"
+ - "mediatek,mt8173-apmixedsys"
+- #clock-cells: Must be 1
+
+The apmixedsys controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+apmixedsys: apmixedsys@10209000 {
+ compatible = "mediatek,mt8173-apmixedsys";
+ reg = <0 0x10209000 0 0x1000>;
+ #clock-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
new file mode 100644
index 0000000..684da473
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
@@ -0,0 +1,30 @@
+Mediatek infracfg controller
+============================
+
+The Mediatek infracfg controller provides various clocks and reset
+outputs to the system.
+
+Required Properties:
+
+- compatible: Should be:
+ - "mediatek,mt8135-infracfg", "syscon"
+ - "mediatek,mt8173-infracfg", "syscon"
+- #clock-cells: Must be 1
+- #reset-cells: Must be 1
+
+The infracfg controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+Also it uses the common reset controller binding from
+Documentation/devicetree/bindings/reset/reset.txt.
+The available reset outputs are defined in
+dt-bindings/reset-controller/mt*-resets.h
+
+Example:
+
+infracfg: infracfg@10001000 {
+ compatible = "mediatek,mt8173-infracfg", "syscon";
+ reg = <0 0x10001000 0 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
new file mode 100644
index 0000000..fdb45c6
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
@@ -0,0 +1,30 @@
+Mediatek pericfg controller
+===========================
+
+The Mediatek pericfg controller provides various clocks and reset
+outputs to the system.
+
+Required Properties:
+
+- compatible: Should be:
+ - "mediatek,mt8135-pericfg", "syscon"
+ - "mediatek,mt8173-pericfg", "syscon"
+- #clock-cells: Must be 1
+- #reset-cells: Must be 1
+
+The pericfg controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+Also it uses the common reset controller binding from
+Documentation/devicetree/bindings/reset/reset.txt.
+The available reset outputs are defined in
+dt-bindings/reset-controller/mt*-resets.h
+
+Example:
+
+pericfg: pericfg@10003000 {
+ compatible = "mediatek,mt8173-pericfg", "syscon";
+ reg = <0 0x10003000 0 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
new file mode 100644
index 0000000..a425248
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
@@ -0,0 +1,23 @@
+Mediatek topckgen controller
+============================
+
+The Mediatek topckgen controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be:
+ - "mediatek,mt8135-topckgen"
+ - "mediatek,mt8173-topckgen"
+- #clock-cells: Must be 1
+
+The topckgen controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+topckgen: topckgen@10000000 {
+ compatible = "mediatek,mt8173-topckgen";
+ reg = <0 0x10000000 0 0x1000>;
+ #clock-cells = <1>;
+};
--
2.1.4
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 5/5] dt-bindings: ARM: Mediatek: Document devicetree bindings for clock/reset controllers
@ 2015-02-22 11:49 ` Sascha Hauer
0 siblings, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2015-02-22 11:49 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
.../bindings/arm/mediatek/mediatek,apmixedsys.txt | 23 +++++++++++++++++
.../bindings/arm/mediatek/mediatek,infracfg.txt | 30 ++++++++++++++++++++++
.../bindings/arm/mediatek/mediatek,pericfg.txt | 30 ++++++++++++++++++++++
.../bindings/arm/mediatek/mediatek,topckgen.txt | 23 +++++++++++++++++
4 files changed, 106 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
new file mode 100644
index 0000000..5af6d73
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
@@ -0,0 +1,23 @@
+Mediatek apmixedsys controller
+==============================
+
+The Mediatek apmixedsys controller provides the PLLs to the system.
+
+Required Properties:
+
+- compatible: Should be:
+ - "mediatek,mt8135-apmixedsys"
+ - "mediatek,mt8173-apmixedsys"
+- #clock-cells: Must be 1
+
+The apmixedsys controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+apmixedsys: apmixedsys at 10209000 {
+ compatible = "mediatek,mt8173-apmixedsys";
+ reg = <0 0x10209000 0 0x1000>;
+ #clock-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
new file mode 100644
index 0000000..684da473
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
@@ -0,0 +1,30 @@
+Mediatek infracfg controller
+============================
+
+The Mediatek infracfg controller provides various clocks and reset
+outputs to the system.
+
+Required Properties:
+
+- compatible: Should be:
+ - "mediatek,mt8135-infracfg", "syscon"
+ - "mediatek,mt8173-infracfg", "syscon"
+- #clock-cells: Must be 1
+- #reset-cells: Must be 1
+
+The infracfg controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+Also it uses the common reset controller binding from
+Documentation/devicetree/bindings/reset/reset.txt.
+The available reset outputs are defined in
+dt-bindings/reset-controller/mt*-resets.h
+
+Example:
+
+infracfg: infracfg at 10001000 {
+ compatible = "mediatek,mt8173-infracfg", "syscon";
+ reg = <0 0x10001000 0 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
new file mode 100644
index 0000000..fdb45c6
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
@@ -0,0 +1,30 @@
+Mediatek pericfg controller
+===========================
+
+The Mediatek pericfg controller provides various clocks and reset
+outputs to the system.
+
+Required Properties:
+
+- compatible: Should be:
+ - "mediatek,mt8135-pericfg", "syscon"
+ - "mediatek,mt8173-pericfg", "syscon"
+- #clock-cells: Must be 1
+- #reset-cells: Must be 1
+
+The pericfg controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+Also it uses the common reset controller binding from
+Documentation/devicetree/bindings/reset/reset.txt.
+The available reset outputs are defined in
+dt-bindings/reset-controller/mt*-resets.h
+
+Example:
+
+pericfg: pericfg at 10003000 {
+ compatible = "mediatek,mt8173-pericfg", "syscon";
+ reg = <0 0x10003000 0 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
new file mode 100644
index 0000000..a425248
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
@@ -0,0 +1,23 @@
+Mediatek topckgen controller
+============================
+
+The Mediatek topckgen controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be:
+ - "mediatek,mt8135-topckgen"
+ - "mediatek,mt8173-topckgen"
+- #clock-cells: Must be 1
+
+The topckgen controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+topckgen: topckgen at 10000000 {
+ compatible = "mediatek,mt8173-topckgen";
+ reg = <0 0x10000000 0 0x1000>;
+ #clock-cells = <1>;
+};
--
2.1.4
^ permalink raw reply related [flat|nested] 30+ messages in thread
* Re: [PATCH v6]: clk: Add common clock support for Mediatek MT8135 and MT8173
2015-02-22 11:49 ` Sascha Hauer
@ 2015-03-09 6:15 ` Sascha Hauer
-1 siblings, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2015-03-09 6:15 UTC (permalink / raw)
To: Mike Turquette
Cc: YH Chen, linux-kernel, Henry Chen, linux-mediatek, kernel,
Matthias Brugger, Yingjoe Chen, Eddie Huang, linux-arm-kernel
Hi Mike,
On Sun, Feb 22, 2015 at 12:49:20PM +0100, Sascha Hauer wrote:
> This patchset contains the initial common clock support for Mediatek SoCs.
> Mediatek SoC's clock architecture comprises of various PLLs, dividers, muxes
> and clock gates.
Are these patches ok now? If yes, please pull:
The following changes since commit c517d838eb7d07bbe9507871fab3931deccff539:
Linux 4.0-rc1 (2015-02-22 18:21:14 -0800)
are available in the git repository at:
git://git.pengutronix.de/git/imx/linux-2.6.git tags/mtk-clk-v6
for you to fetch changes up to edfdf5ab89af79d2f9a21fefdcfa5e89e8598d53:
dt-bindings: ARM: Mediatek: Document devicetree bindings for clock/reset controllers (2015-03-09 06:41:24 +0100)
----------------------------------------------------------------
MTK clock support v6
----------------------------------------------------------------
James Liao (3):
clk: mediatek: Add initial common clock support for Mediatek SoCs.
clk: mediatek: Add basic clocks for Mediatek MT8135.
clk: mediatek: Add basic clocks for Mediatek MT8173.
Sascha Hauer (2):
clk: mediatek: Add reset controller support
dt-bindings: ARM: Mediatek: Document devicetree bindings for clock/reset controllers
.../bindings/arm/mediatek/mediatek,apmixedsys.txt | 23 +
.../bindings/arm/mediatek/mediatek,infracfg.txt | 30 +
.../bindings/arm/mediatek/mediatek,pericfg.txt | 30 +
.../bindings/arm/mediatek/mediatek,topckgen.txt | 23 +
drivers/clk/Makefile | 1 +
drivers/clk/mediatek/Makefile | 4 +
drivers/clk/mediatek/clk-gate.c | 137 ++++
drivers/clk/mediatek/clk-gate.h | 49 ++
drivers/clk/mediatek/clk-mt8135.c | 634 ++++++++++++++++
drivers/clk/mediatek/clk-mt8173.c | 820 +++++++++++++++++++++
drivers/clk/mediatek/clk-mtk.c | 195 +++++
drivers/clk/mediatek/clk-mtk.h | 174 +++++
drivers/clk/mediatek/clk-pll.c | 330 +++++++++
drivers/clk/mediatek/reset.c | 99 +++
include/dt-bindings/clock/mt8135-clk.h | 190 +++++
include/dt-bindings/clock/mt8173-clk.h | 231 ++++++
.../dt-bindings/reset-controller/mt8135-resets.h | 64 ++
.../dt-bindings/reset-controller/mt8173-resets.h | 63 ++
18 files changed, 3097 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
create mode 100644 drivers/clk/mediatek/Makefile
create mode 100644 drivers/clk/mediatek/clk-gate.c
create mode 100644 drivers/clk/mediatek/clk-gate.h
create mode 100644 drivers/clk/mediatek/clk-mt8135.c
create mode 100644 drivers/clk/mediatek/clk-mt8173.c
create mode 100644 drivers/clk/mediatek/clk-mtk.c
create mode 100644 drivers/clk/mediatek/clk-mtk.h
create mode 100644 drivers/clk/mediatek/clk-pll.c
create mode 100644 drivers/clk/mediatek/reset.c
create mode 100644 include/dt-bindings/clock/mt8135-clk.h
create mode 100644 include/dt-bindings/clock/mt8173-clk.h
create mode 100644 include/dt-bindings/reset-controller/mt8135-resets.h
create mode 100644 include/dt-bindings/reset-controller/mt8173-resets.h
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v6]: clk: Add common clock support for Mediatek MT8135 and MT8173
@ 2015-03-09 6:15 ` Sascha Hauer
0 siblings, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2015-03-09 6:15 UTC (permalink / raw)
To: linux-arm-kernel
Hi Mike,
On Sun, Feb 22, 2015 at 12:49:20PM +0100, Sascha Hauer wrote:
> This patchset contains the initial common clock support for Mediatek SoCs.
> Mediatek SoC's clock architecture comprises of various PLLs, dividers, muxes
> and clock gates.
Are these patches ok now? If yes, please pull:
The following changes since commit c517d838eb7d07bbe9507871fab3931deccff539:
Linux 4.0-rc1 (2015-02-22 18:21:14 -0800)
are available in the git repository at:
git://git.pengutronix.de/git/imx/linux-2.6.git tags/mtk-clk-v6
for you to fetch changes up to edfdf5ab89af79d2f9a21fefdcfa5e89e8598d53:
dt-bindings: ARM: Mediatek: Document devicetree bindings for clock/reset controllers (2015-03-09 06:41:24 +0100)
----------------------------------------------------------------
MTK clock support v6
----------------------------------------------------------------
James Liao (3):
clk: mediatek: Add initial common clock support for Mediatek SoCs.
clk: mediatek: Add basic clocks for Mediatek MT8135.
clk: mediatek: Add basic clocks for Mediatek MT8173.
Sascha Hauer (2):
clk: mediatek: Add reset controller support
dt-bindings: ARM: Mediatek: Document devicetree bindings for clock/reset controllers
.../bindings/arm/mediatek/mediatek,apmixedsys.txt | 23 +
.../bindings/arm/mediatek/mediatek,infracfg.txt | 30 +
.../bindings/arm/mediatek/mediatek,pericfg.txt | 30 +
.../bindings/arm/mediatek/mediatek,topckgen.txt | 23 +
drivers/clk/Makefile | 1 +
drivers/clk/mediatek/Makefile | 4 +
drivers/clk/mediatek/clk-gate.c | 137 ++++
drivers/clk/mediatek/clk-gate.h | 49 ++
drivers/clk/mediatek/clk-mt8135.c | 634 ++++++++++++++++
drivers/clk/mediatek/clk-mt8173.c | 820 +++++++++++++++++++++
drivers/clk/mediatek/clk-mtk.c | 195 +++++
drivers/clk/mediatek/clk-mtk.h | 174 +++++
drivers/clk/mediatek/clk-pll.c | 330 +++++++++
drivers/clk/mediatek/reset.c | 99 +++
include/dt-bindings/clock/mt8135-clk.h | 190 +++++
include/dt-bindings/clock/mt8173-clk.h | 231 ++++++
.../dt-bindings/reset-controller/mt8135-resets.h | 64 ++
.../dt-bindings/reset-controller/mt8173-resets.h | 63 ++
18 files changed, 3097 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
create mode 100644 drivers/clk/mediatek/Makefile
create mode 100644 drivers/clk/mediatek/clk-gate.c
create mode 100644 drivers/clk/mediatek/clk-gate.h
create mode 100644 drivers/clk/mediatek/clk-mt8135.c
create mode 100644 drivers/clk/mediatek/clk-mt8173.c
create mode 100644 drivers/clk/mediatek/clk-mtk.c
create mode 100644 drivers/clk/mediatek/clk-mtk.h
create mode 100644 drivers/clk/mediatek/clk-pll.c
create mode 100644 drivers/clk/mediatek/reset.c
create mode 100644 include/dt-bindings/clock/mt8135-clk.h
create mode 100644 include/dt-bindings/clock/mt8173-clk.h
create mode 100644 include/dt-bindings/reset-controller/mt8135-resets.h
create mode 100644 include/dt-bindings/reset-controller/mt8173-resets.h
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 3/5] clk: mediatek: Add basic clocks for Mediatek MT8135.
2015-02-22 11:49 ` Sascha Hauer
@ 2015-03-13 7:44 ` Henry Chen
-1 siblings, 0 replies; 30+ messages in thread
From: Henry Chen @ 2015-03-13 7:44 UTC (permalink / raw)
To: Sascha Hauer
Cc: Mike Turquette, Matthias Brugger, linux-arm-kernel, linux-kernel,
linux-mediatek, YH Chen, kernel, Yingjoe Chen, Eddie Huang,
James Liao
On Sun, 2015-02-22 at 12:49 +0100, Sascha Hauer wrote:
> +#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) { \
> + .id = _id, \
> + .name = _name, \
> + .reg = _reg, \
> + .pwr_reg = _pwr_reg, \
> + .en_mask = _en_mask, \
> + .flags = _flags, \
> + .rst_bar_mask = CON0_MT8135_RST_BAR, \
> + .fmax = MT8135_PLL_FMAX, \
> + .pcwbits = _pcwbits, \
> + .pd_reg = _pd_reg, \
> + .pd_shift = _pd_shift, \
> + .tuner_reg = _tuner_reg, \
> + .pcw_reg = _pcw_reg, \
> + .pcw_shift = _pcw_shift, \
> + }
> +
> +static struct mtk_pll_data plls[] = {
> + PLL(APMIXED_ARMPLL1, "armpll1", 0x200, 0x218, 0x80000001, 0, 21, 0x204, 24, 0x0, 0x204, 0),
> + PLL(APMIXED_ARMPLL2, "armpll2", 0x2cc, 0x2e4, 0x80000001, 0, 21, 0x2d0, 24, 0x0, 0x2d0, 0),
> + PLL(APMIXED_MAINPLL, "mainpll", 0x21c, 0x234, 0xf0000001, HAVE_RST_BAR, 21, 0x21c, 6, 0x0, 0x220, 0),
> + PLL(APMIXED_UNIVPLL, "univpll", 0x238, 0x250, 0xf3000001, HAVE_RST_BAR, 7, 0x238, 6, 0x0, 0x238, 9),
> + PLL(APMIXED_MMPLL, "mmpll", 0x254, 0x26c, 0xf0000001, HAVE_RST_BAR, 21, 0x254, 6, 0x0, 0x258, 0),
> + PLL(APMIXED_MSDCPLL, "msdcpll", 0x278, 0x290, 0x80000001, 0, 21, 0x278, 6, 0x0, 0x27c, 0),
> + PLL(APMIXED_TVDPLL, "tvdpll", 0x294, 0x2ac, 0x80000001, 0, 31, 0x296, 6, 0x0, 0x298, 0),
Hi Sasha,
The pd_reg of tvdpll should be 0x294.
Henry
> + PLL(APMIXED_LVDSPLL, "lvdspll", 0x2b0, 0x2c8, 0x80000001, 0, 21, 0x2b0, 6, 0x0, 0x2b4, 0),
> + PLL(APMIXED_AUDPLL, "audpll", 0x2e8, 0x300, 0x80000001, 0, 31, 0x2e8, 6, 0x2f8, 0x2ec, 0),
> + PLL(APMIXED_VDECPLL, "vdecpll", 0x304, 0x31c, 0x80000001, 0, 21, 0x2b0, 6, 0x0, 0x308, 0),
> +};
> 15
> +#define TOP_MMPLL_D5 16
> +#define TOP_MMPLL_D7 17
> +#define TOP_MMPLL_D4 18
> +#define TOP_MMPLL_D6 19
> +#define TOP_SYSPLL_D2 20
> +#define TOP_SYSPLL_D4 21
> +#define TOP_SYSPLL_D6 22
> +#define TOP_SYSPLL_D8 23
> +#define TOP_SYSPLL_D10 24
> +#define TOP_SYSPLL_D12 25
> +#define TOP_SYSPLL_D16 26
> +#define TOP_SYSPLL_D24 27
> +#define TOP_SYSPLL_D3 28
> +#define TOP_SYSPLL_D2P5 29
> +#define TOP_SYSPLL_D5 30
> +#define TOP_SYSPLL_D3P5 31
> +#define TOP_UNIVPLL1_D2 32
> +#define TOP_UNIVPLL1_D4 33
> +#define TOP_UNIVPLL1_D6 34
> +#define TOP_UNIVPLL1_D8 35
> +#define TOP_UNIVPLL1_D10 36
> +#define TOP_UNIVPLL2_D2 37
> +#define TOP_UNIVPLL2_D4 38
> +#define TOP_UNIVPLL2_D6 39
> +#define TOP_UNIVPLL2_D8 40
> +#define TOP_UNIVPLL_D3 41
> +#define TOP_UNIVPLL_D5 42
> +#define TOP_UNIVPLL_D7 43
> +#define TOP_UNIVPLL_D10 44
> +#define TOP_UNIVPLL_D26 45
> +#define TOP_APLL_CK 46
> +#define TOP_APLL_D4 47
> +#define TOP_APLL_D8 48
> +#define TOP_APLL_D16 49
> +#define TOP_APLL_D24 50
> +#define TOP_LVDSPLL_D2 51
> +#define TOP_LVDSPLL_D4 52
> +#define TOP_LVDSPLL_D8 53
> +#define TOP_LVDSTX_CLKDIG_CT 54
> +#define TOP_VPLL_DPIX_CK 55
> +#define TOP_TVHDMI_H_CK 56
> +#define TOP_HDMITX_CLKDIG_D2 57
> +#define TOP_HDMITX_CLKDIG_D3 58
> +#define TOP_TVHDMI_D2 59
> +#define TOP_TVHDMI_D4 60
> +#define TOP_MEMPLL_MCK_D4 61
> +#define TOP_AXI_SEL 62
> +#define TOP_SMI_SEL 63
> +#define TOP_MFG_SEL 64
> +#define TOP_IRDA_SEL 65
> +#define TOP_CAM_SEL 66
> +#define TOP_AUD_INTBUS_SEL 67
> +#define TOP_JPG_SEL 68
> +#define TOP_DISP_SEL 69
> +#define TOP_MSDC30_1_SEL 70
> +#define TOP_MSDC30_2_SEL 71
> +#define TOP_MSDC30_3_SEL 72
> +#define TOP_MSDC30_4_SEL 73
> +#define TOP_USB20_SEL 74
> +#define TOP_VENC_SEL 75
> +#define TOP_SPI_SEL 76
> +#define TOP_UART_SEL 77
> +#define TOP_MEM_SEL 78
> +#define TOP_CAMTG_SEL 79
> +#define TOP_AUDIO_SEL 80
> +#define TOP_FIX_SEL 81
> +#define TOP_VDEC_SEL 82
> +#define TOP_DDRPHYCFG_SEL 83
> +#define TOP_DPILVDS_SEL 84
> +#define TOP_PMICSPI_SEL 85
> +#define TOP_MSDC30_0_SEL 86
> +#define TOP_SMI_MFG_AS_SEL 87
> +#define TOP_GCPU_SEL 88
> +#define TOP_DPI1_SEL 89
> +#define TOP_CCI_SEL 90
> +#define TOP_APLL_SEL 91
> +#define TOP_HDMIPLL_SEL 92
> +#define TOP_NR_CLK 93
> +
> +/* APMIXED_SYS */
> +
> +#define APMIXED_ARMPLL1 1
> +#define APMIXED_ARMPLL2 2
> +#define APMIXED_MAINPLL 3
> +#define APMIXED_UNIVPLL 4
> +#define APMIXED_MMPLL 5
> +#define APMIXED_MSDCPLL 6
> +#define APMIXED_TVDPLL 7
> +#define APMIXED_LVDSPLL 8
> +#define APMIXED_AUDPLL 9
> +#define APMIXED_VDECPLL 10
> +#define APMIXED_NR_CLK 11
> +
> +/* INFRA_SYS */
> +
> +#define INFRA_PMIC_WRAP_CK 1
> +#define INFRA_PMICSPI_CK 2
> +#define INFRA_CCIF1_AP_CTRL 3
> +#define INFRA_CCIF0_AP_CTRL 4
> +#define INFRA_KP_CK 5
> +#define INFRA_CPUM_CK 6
> +#define INFRA_M4U_CK 7
> +#define INFRA_MFGAXI_CK 8
> +#define INFRA_DEVAPC_CK 9
> +#define INFRA_AUDIO_CK 10
> +#define INFRA_MFG_BUS_CK 11
> +#define INFRA_SMI_CK 12
> +#define INFRA_DBGCLK_CK 13
> +#define INFRA_NR_CLK 14
> +
> +/* PERI_SYS */
> +
> +#define PERI_I2C5_CK 1
> +#define PERI_I2C4_CK 2
> +#define PERI_I2C3_CK 3
> +#define PERI_I2C2_CK 4
> +#define PERI_I2C1_CK 5
> +#define PERI_I2C0_CK 6
> +#define PERI_UART3_CK 7
> +#define PERI_UART2_CK 8
> +#define PERI_UART1_CK 9
> +#define PERI_UART0_CK 10
> +#define PERI_IRDA_CK 11
> +#define PERI_NLI_CK 12
> +#define PERI_MD_HIF_CK 13
> +#define PERI_AP_HIF_CK 14
> +#define PERI_MSDC30_3_CK 15
> +#define PERI_MSDC30_2_CK 16
> +#define PERI_MSDC30_1_CK 17
> +#define PERI_MSDC20_2_CK 18
> +#define PERI_MSDC20_1_CK 19
> +#define PERI_AP_DMA_CK 20
> +#define PERI_USB1_CK 21
> +#define PERI_USB0_CK 22
> +#define PERI_PWM_CK 23
> +#define PERI_PWM7_CK 24
> +#define PERI_PWM6_CK 25
> +#define PERI_PWM5_CK 26
> +#define PERI_PWM4_CK 27
> +#define PERI_PWM3_CK 28
> +#define PERI_PWM2_CK 29
> +#define PERI_PWM1_CK 30
> +#define PERI_THERM_CK 31
> +#define PERI_NFI_CK 32
> +#define PERI_USBSLV_CK 33
> +#define PERI_USB1_MCU_CK 34
> +#define PERI_USB0_MCU_CK 35
> +#define PERI_GCPU_CK 36
> +#define PERI_FHCTL_CK 37
> +#define PERI_SPI1_CK 38
> +#define PERI_AUXADC_CK 39
> +#define PERI_PERI_PWRAP_CK 40
> +#define PERI_I2C6_CK 41
> +#define PERI_NR_CLK 42
> +
> +#endif /* _DT_BINDINGS_CLK_MT8135_H */
> diff --git a/include/dt-bindings/reset-controller/mt8135-resets.h b/include/dt-bindings/reset-controller/mt8135-resets.h
> new file mode 100644
> index 0000000..1fb6295
> --- /dev/null
> +++ b/include/dt-bindings/reset-controller/mt8135-resets.h
> @@ -0,0 +1,64 @@
> +/*
> + * Copyright (c) 2014 MediaTek Inc.
> + * Author: Flora Fu, MediaTek
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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 _DT_BINDINGS_RESET_CONTROLLER_MT8135
> +#define _DT_BINDINGS_RESET_CONTROLLER_MT8135
> +
> +/* INFRACFG resets */
> +#define MT8135_INFRA_EMI_REG_RST 0
> +#define MT8135_INFRA_DRAMC0_A0_RST 1
> +#define MT8135_INFRA_CCIF0_RST 2
> +#define MT8135_INFRA_APCIRQ_EINT_RST 3
> +#define MT8135_INFRA_APXGPT_RST 4
> +#define MT8135_INFRA_SCPSYS_RST 5
> +#define MT8135_INFRA_CCIF1_RST 6
> +#define MT8135_INFRA_PMIC_WRAP_RST 7
> +#define MT8135_INFRA_KP_RST 8
> +#define MT8135_INFRA_EMI_RST 32
> +#define MT8135_INFRA_DRAMC0_RST 34
> +#define MT8135_INFRA_SMI_RST 35
> +#define MT8135_INFRA_M4U_RST 36
> +
> +/* PERICFG resets */
> +#define MT8135_PERI_UART0_SW_RST 0
> +#define MT8135_PERI_UART1_SW_RST 1
> +#define MT8135_PERI_UART2_SW_RST 2
> +#define MT8135_PERI_UART3_SW_RST 3
> +#define MT8135_PERI_IRDA_SW_RST 4
> +#define MT8135_PERI_PTP_SW_RST 5
> +#define MT8135_PERI_AP_HIF_SW_RST 6
> +#define MT8135_PERI_GPCU_SW_RST 7
> +#define MT8135_PERI_MD_HIF_SW_RST 8
> +#define MT8135_PERI_NLI_SW_RST 9
> +#define MT8135_PERI_AUXADC_SW_RST 10
> +#define MT8135_PERI_DMA_SW_RST 11
> +#define MT8135_PERI_NFI_SW_RST 14
> +#define MT8135_PERI_PWM_SW_RST 15
> +#define MT8135_PERI_THERM_SW_RST 16
> +#define MT8135_PERI_MSDC0_SW_RST 17
> +#define MT8135_PERI_MSDC1_SW_RST 18
> +#define MT8135_PERI_MSDC2_SW_RST 19
> +#define MT8135_PERI_MSDC3_SW_RST 20
> +#define MT8135_PERI_I2C0_SW_RST 22
> +#define MT8135_PERI_I2C1_SW_RST 23
> +#define MT8135_PERI_I2C2_SW_RST 24
> +#define MT8135_PERI_I2C3_SW_RST 25
> +#define MT8135_PERI_I2C4_SW_RST 26
> +#define MT8135_PERI_I2C5_SW_RST 27
> +#define MT8135_PERI_I2C6_SW_RST 28
> +#define MT8135_PERI_USB_SW_RST 29
> +#define MT8135_PERI_SPI1_SW_RST 33
> +#define MT8135_PERI_PWRAP_BRIDGE_SW_RST 34
> +
> +#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT8135 */
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 3/5] clk: mediatek: Add basic clocks for Mediatek MT8135.
@ 2015-03-13 7:44 ` Henry Chen
0 siblings, 0 replies; 30+ messages in thread
From: Henry Chen @ 2015-03-13 7:44 UTC (permalink / raw)
To: linux-arm-kernel
On Sun, 2015-02-22 at 12:49 +0100, Sascha Hauer wrote:
> +#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) { \
> + .id = _id, \
> + .name = _name, \
> + .reg = _reg, \
> + .pwr_reg = _pwr_reg, \
> + .en_mask = _en_mask, \
> + .flags = _flags, \
> + .rst_bar_mask = CON0_MT8135_RST_BAR, \
> + .fmax = MT8135_PLL_FMAX, \
> + .pcwbits = _pcwbits, \
> + .pd_reg = _pd_reg, \
> + .pd_shift = _pd_shift, \
> + .tuner_reg = _tuner_reg, \
> + .pcw_reg = _pcw_reg, \
> + .pcw_shift = _pcw_shift, \
> + }
> +
> +static struct mtk_pll_data plls[] = {
> + PLL(APMIXED_ARMPLL1, "armpll1", 0x200, 0x218, 0x80000001, 0, 21, 0x204, 24, 0x0, 0x204, 0),
> + PLL(APMIXED_ARMPLL2, "armpll2", 0x2cc, 0x2e4, 0x80000001, 0, 21, 0x2d0, 24, 0x0, 0x2d0, 0),
> + PLL(APMIXED_MAINPLL, "mainpll", 0x21c, 0x234, 0xf0000001, HAVE_RST_BAR, 21, 0x21c, 6, 0x0, 0x220, 0),
> + PLL(APMIXED_UNIVPLL, "univpll", 0x238, 0x250, 0xf3000001, HAVE_RST_BAR, 7, 0x238, 6, 0x0, 0x238, 9),
> + PLL(APMIXED_MMPLL, "mmpll", 0x254, 0x26c, 0xf0000001, HAVE_RST_BAR, 21, 0x254, 6, 0x0, 0x258, 0),
> + PLL(APMIXED_MSDCPLL, "msdcpll", 0x278, 0x290, 0x80000001, 0, 21, 0x278, 6, 0x0, 0x27c, 0),
> + PLL(APMIXED_TVDPLL, "tvdpll", 0x294, 0x2ac, 0x80000001, 0, 31, 0x296, 6, 0x0, 0x298, 0),
Hi Sasha,
The pd_reg of tvdpll should be 0x294.
Henry
> + PLL(APMIXED_LVDSPLL, "lvdspll", 0x2b0, 0x2c8, 0x80000001, 0, 21, 0x2b0, 6, 0x0, 0x2b4, 0),
> + PLL(APMIXED_AUDPLL, "audpll", 0x2e8, 0x300, 0x80000001, 0, 31, 0x2e8, 6, 0x2f8, 0x2ec, 0),
> + PLL(APMIXED_VDECPLL, "vdecpll", 0x304, 0x31c, 0x80000001, 0, 21, 0x2b0, 6, 0x0, 0x308, 0),
> +};
> 15
> +#define TOP_MMPLL_D5 16
> +#define TOP_MMPLL_D7 17
> +#define TOP_MMPLL_D4 18
> +#define TOP_MMPLL_D6 19
> +#define TOP_SYSPLL_D2 20
> +#define TOP_SYSPLL_D4 21
> +#define TOP_SYSPLL_D6 22
> +#define TOP_SYSPLL_D8 23
> +#define TOP_SYSPLL_D10 24
> +#define TOP_SYSPLL_D12 25
> +#define TOP_SYSPLL_D16 26
> +#define TOP_SYSPLL_D24 27
> +#define TOP_SYSPLL_D3 28
> +#define TOP_SYSPLL_D2P5 29
> +#define TOP_SYSPLL_D5 30
> +#define TOP_SYSPLL_D3P5 31
> +#define TOP_UNIVPLL1_D2 32
> +#define TOP_UNIVPLL1_D4 33
> +#define TOP_UNIVPLL1_D6 34
> +#define TOP_UNIVPLL1_D8 35
> +#define TOP_UNIVPLL1_D10 36
> +#define TOP_UNIVPLL2_D2 37
> +#define TOP_UNIVPLL2_D4 38
> +#define TOP_UNIVPLL2_D6 39
> +#define TOP_UNIVPLL2_D8 40
> +#define TOP_UNIVPLL_D3 41
> +#define TOP_UNIVPLL_D5 42
> +#define TOP_UNIVPLL_D7 43
> +#define TOP_UNIVPLL_D10 44
> +#define TOP_UNIVPLL_D26 45
> +#define TOP_APLL_CK 46
> +#define TOP_APLL_D4 47
> +#define TOP_APLL_D8 48
> +#define TOP_APLL_D16 49
> +#define TOP_APLL_D24 50
> +#define TOP_LVDSPLL_D2 51
> +#define TOP_LVDSPLL_D4 52
> +#define TOP_LVDSPLL_D8 53
> +#define TOP_LVDSTX_CLKDIG_CT 54
> +#define TOP_VPLL_DPIX_CK 55
> +#define TOP_TVHDMI_H_CK 56
> +#define TOP_HDMITX_CLKDIG_D2 57
> +#define TOP_HDMITX_CLKDIG_D3 58
> +#define TOP_TVHDMI_D2 59
> +#define TOP_TVHDMI_D4 60
> +#define TOP_MEMPLL_MCK_D4 61
> +#define TOP_AXI_SEL 62
> +#define TOP_SMI_SEL 63
> +#define TOP_MFG_SEL 64
> +#define TOP_IRDA_SEL 65
> +#define TOP_CAM_SEL 66
> +#define TOP_AUD_INTBUS_SEL 67
> +#define TOP_JPG_SEL 68
> +#define TOP_DISP_SEL 69
> +#define TOP_MSDC30_1_SEL 70
> +#define TOP_MSDC30_2_SEL 71
> +#define TOP_MSDC30_3_SEL 72
> +#define TOP_MSDC30_4_SEL 73
> +#define TOP_USB20_SEL 74
> +#define TOP_VENC_SEL 75
> +#define TOP_SPI_SEL 76
> +#define TOP_UART_SEL 77
> +#define TOP_MEM_SEL 78
> +#define TOP_CAMTG_SEL 79
> +#define TOP_AUDIO_SEL 80
> +#define TOP_FIX_SEL 81
> +#define TOP_VDEC_SEL 82
> +#define TOP_DDRPHYCFG_SEL 83
> +#define TOP_DPILVDS_SEL 84
> +#define TOP_PMICSPI_SEL 85
> +#define TOP_MSDC30_0_SEL 86
> +#define TOP_SMI_MFG_AS_SEL 87
> +#define TOP_GCPU_SEL 88
> +#define TOP_DPI1_SEL 89
> +#define TOP_CCI_SEL 90
> +#define TOP_APLL_SEL 91
> +#define TOP_HDMIPLL_SEL 92
> +#define TOP_NR_CLK 93
> +
> +/* APMIXED_SYS */
> +
> +#define APMIXED_ARMPLL1 1
> +#define APMIXED_ARMPLL2 2
> +#define APMIXED_MAINPLL 3
> +#define APMIXED_UNIVPLL 4
> +#define APMIXED_MMPLL 5
> +#define APMIXED_MSDCPLL 6
> +#define APMIXED_TVDPLL 7
> +#define APMIXED_LVDSPLL 8
> +#define APMIXED_AUDPLL 9
> +#define APMIXED_VDECPLL 10
> +#define APMIXED_NR_CLK 11
> +
> +/* INFRA_SYS */
> +
> +#define INFRA_PMIC_WRAP_CK 1
> +#define INFRA_PMICSPI_CK 2
> +#define INFRA_CCIF1_AP_CTRL 3
> +#define INFRA_CCIF0_AP_CTRL 4
> +#define INFRA_KP_CK 5
> +#define INFRA_CPUM_CK 6
> +#define INFRA_M4U_CK 7
> +#define INFRA_MFGAXI_CK 8
> +#define INFRA_DEVAPC_CK 9
> +#define INFRA_AUDIO_CK 10
> +#define INFRA_MFG_BUS_CK 11
> +#define INFRA_SMI_CK 12
> +#define INFRA_DBGCLK_CK 13
> +#define INFRA_NR_CLK 14
> +
> +/* PERI_SYS */
> +
> +#define PERI_I2C5_CK 1
> +#define PERI_I2C4_CK 2
> +#define PERI_I2C3_CK 3
> +#define PERI_I2C2_CK 4
> +#define PERI_I2C1_CK 5
> +#define PERI_I2C0_CK 6
> +#define PERI_UART3_CK 7
> +#define PERI_UART2_CK 8
> +#define PERI_UART1_CK 9
> +#define PERI_UART0_CK 10
> +#define PERI_IRDA_CK 11
> +#define PERI_NLI_CK 12
> +#define PERI_MD_HIF_CK 13
> +#define PERI_AP_HIF_CK 14
> +#define PERI_MSDC30_3_CK 15
> +#define PERI_MSDC30_2_CK 16
> +#define PERI_MSDC30_1_CK 17
> +#define PERI_MSDC20_2_CK 18
> +#define PERI_MSDC20_1_CK 19
> +#define PERI_AP_DMA_CK 20
> +#define PERI_USB1_CK 21
> +#define PERI_USB0_CK 22
> +#define PERI_PWM_CK 23
> +#define PERI_PWM7_CK 24
> +#define PERI_PWM6_CK 25
> +#define PERI_PWM5_CK 26
> +#define PERI_PWM4_CK 27
> +#define PERI_PWM3_CK 28
> +#define PERI_PWM2_CK 29
> +#define PERI_PWM1_CK 30
> +#define PERI_THERM_CK 31
> +#define PERI_NFI_CK 32
> +#define PERI_USBSLV_CK 33
> +#define PERI_USB1_MCU_CK 34
> +#define PERI_USB0_MCU_CK 35
> +#define PERI_GCPU_CK 36
> +#define PERI_FHCTL_CK 37
> +#define PERI_SPI1_CK 38
> +#define PERI_AUXADC_CK 39
> +#define PERI_PERI_PWRAP_CK 40
> +#define PERI_I2C6_CK 41
> +#define PERI_NR_CLK 42
> +
> +#endif /* _DT_BINDINGS_CLK_MT8135_H */
> diff --git a/include/dt-bindings/reset-controller/mt8135-resets.h b/include/dt-bindings/reset-controller/mt8135-resets.h
> new file mode 100644
> index 0000000..1fb6295
> --- /dev/null
> +++ b/include/dt-bindings/reset-controller/mt8135-resets.h
> @@ -0,0 +1,64 @@
> +/*
> + * Copyright (c) 2014 MediaTek Inc.
> + * Author: Flora Fu, MediaTek
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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 _DT_BINDINGS_RESET_CONTROLLER_MT8135
> +#define _DT_BINDINGS_RESET_CONTROLLER_MT8135
> +
> +/* INFRACFG resets */
> +#define MT8135_INFRA_EMI_REG_RST 0
> +#define MT8135_INFRA_DRAMC0_A0_RST 1
> +#define MT8135_INFRA_CCIF0_RST 2
> +#define MT8135_INFRA_APCIRQ_EINT_RST 3
> +#define MT8135_INFRA_APXGPT_RST 4
> +#define MT8135_INFRA_SCPSYS_RST 5
> +#define MT8135_INFRA_CCIF1_RST 6
> +#define MT8135_INFRA_PMIC_WRAP_RST 7
> +#define MT8135_INFRA_KP_RST 8
> +#define MT8135_INFRA_EMI_RST 32
> +#define MT8135_INFRA_DRAMC0_RST 34
> +#define MT8135_INFRA_SMI_RST 35
> +#define MT8135_INFRA_M4U_RST 36
> +
> +/* PERICFG resets */
> +#define MT8135_PERI_UART0_SW_RST 0
> +#define MT8135_PERI_UART1_SW_RST 1
> +#define MT8135_PERI_UART2_SW_RST 2
> +#define MT8135_PERI_UART3_SW_RST 3
> +#define MT8135_PERI_IRDA_SW_RST 4
> +#define MT8135_PERI_PTP_SW_RST 5
> +#define MT8135_PERI_AP_HIF_SW_RST 6
> +#define MT8135_PERI_GPCU_SW_RST 7
> +#define MT8135_PERI_MD_HIF_SW_RST 8
> +#define MT8135_PERI_NLI_SW_RST 9
> +#define MT8135_PERI_AUXADC_SW_RST 10
> +#define MT8135_PERI_DMA_SW_RST 11
> +#define MT8135_PERI_NFI_SW_RST 14
> +#define MT8135_PERI_PWM_SW_RST 15
> +#define MT8135_PERI_THERM_SW_RST 16
> +#define MT8135_PERI_MSDC0_SW_RST 17
> +#define MT8135_PERI_MSDC1_SW_RST 18
> +#define MT8135_PERI_MSDC2_SW_RST 19
> +#define MT8135_PERI_MSDC3_SW_RST 20
> +#define MT8135_PERI_I2C0_SW_RST 22
> +#define MT8135_PERI_I2C1_SW_RST 23
> +#define MT8135_PERI_I2C2_SW_RST 24
> +#define MT8135_PERI_I2C3_SW_RST 25
> +#define MT8135_PERI_I2C4_SW_RST 26
> +#define MT8135_PERI_I2C5_SW_RST 27
> +#define MT8135_PERI_I2C6_SW_RST 28
> +#define MT8135_PERI_USB_SW_RST 29
> +#define MT8135_PERI_SPI1_SW_RST 33
> +#define MT8135_PERI_PWRAP_BRIDGE_SW_RST 34
> +
> +#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT8135 */
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 1/5] clk: mediatek: Add initial common clock support for Mediatek SoCs.
2015-02-22 11:49 ` Sascha Hauer
@ 2015-03-13 16:46 ` Matthias Brugger
-1 siblings, 0 replies; 30+ messages in thread
From: Matthias Brugger @ 2015-03-13 16:46 UTC (permalink / raw)
To: Sascha Hauer, Mike Turquette
Cc: linux-arm-kernel, linux-kernel, linux-mediatek, YH Chen, kernel,
Yingjoe Chen, Eddie Huang, Henry Chen, James Liao
On 22/02/15 12:49, Sascha Hauer wrote:
> From: James Liao <jamesjj.liao@mediatek.com>
> diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
> new file mode 100644
> index 0000000..c7c0d35
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-mtk.h
[...]
> +void __init mtk_clk_register_plls(struct device_node *node,
> + const struct mtk_pll_data *plls, int num_plls);
> +
> +#ifdef CONFIG_RESET_CONTROLLER
> +void mtk_register_reset_controller(struct device_node *np,
> + unsigned int num_regs, int regofs);
> +#else
> +static inline void mtk_register_reset_controller(struct device_node *np,
> + unsigned int num_regs, int regofs)
> +{
> +}
> +#endif
This lines should only be added once in [2/5], compiling ends with:
In file included from drivers/clk/mediatek/clk-mtk.c:24:0:
drivers/clk/mediatek/clk-mtk.h:168:20: error: redefinition of ‘mtk_register_reset_controller’
drivers/clk/mediatek/clk-mtk.h:158:20: note: previous definition of ‘mtk_register_reset_controller’ was here
Cheers,
Matthias
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 1/5] clk: mediatek: Add initial common clock support for Mediatek SoCs.
@ 2015-03-13 16:46 ` Matthias Brugger
0 siblings, 0 replies; 30+ messages in thread
From: Matthias Brugger @ 2015-03-13 16:46 UTC (permalink / raw)
To: linux-arm-kernel
On 22/02/15 12:49, Sascha Hauer wrote:
> From: James Liao <jamesjj.liao@mediatek.com>
> diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
> new file mode 100644
> index 0000000..c7c0d35
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-mtk.h
[...]
> +void __init mtk_clk_register_plls(struct device_node *node,
> + const struct mtk_pll_data *plls, int num_plls);
> +
> +#ifdef CONFIG_RESET_CONTROLLER
> +void mtk_register_reset_controller(struct device_node *np,
> + unsigned int num_regs, int regofs);
> +#else
> +static inline void mtk_register_reset_controller(struct device_node *np,
> + unsigned int num_regs, int regofs)
> +{
> +}
> +#endif
This lines should only be added once in [2/5], compiling ends with:
In file included from drivers/clk/mediatek/clk-mtk.c:24:0:
drivers/clk/mediatek/clk-mtk.h:168:20: error: redefinition of ?mtk_register_reset_controller?
drivers/clk/mediatek/clk-mtk.h:158:20: note: previous definition of ?mtk_register_reset_controller? was here
Cheers,
Matthias
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 3/5] clk: mediatek: Add basic clocks for Mediatek MT8135.
2015-02-22 11:49 ` Sascha Hauer
(?)
@ 2015-03-15 16:27 ` Daniel Kurtz
-1 siblings, 0 replies; 30+ messages in thread
From: Daniel Kurtz @ 2015-03-15 16:27 UTC (permalink / raw)
To: Sascha Hauer
Cc: Mike Turquette, James Liao, YH Chen, linux-kernel, Henry Chen,
linux-mediatek, Sasha Hauer, Matthias Brugger, Yingjoe Chen,
Eddie Huang, linux-arm-kernel
Hi Sascha,
Drive-by review...
On Sun, Feb 22, 2015 at 7:49 PM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> From: James Liao <jamesjj.liao@mediatek.com>
>
> This patch adds basic clocks for MT8135, including TOPCKGEN, PLLs,
> INFRA and PERI clocks.
>
> Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
> Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
> drivers/clk/mediatek/Makefile | 1 +
> drivers/clk/mediatek/clk-mt8135.c | 634 +++++++++++++++++++++
> include/dt-bindings/clock/mt8135-clk.h | 190 ++++++
> .../dt-bindings/reset-controller/mt8135-resets.h | 64 +++
> 4 files changed, 889 insertions(+)
> create mode 100644 drivers/clk/mediatek/clk-mt8135.c
> create mode 100644 include/dt-bindings/clock/mt8135-clk.h
> create mode 100644 include/dt-bindings/reset-controller/mt8135-resets.h
>
> diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
> index 0b6f1c3..12ce576 100644
> --- a/drivers/clk/mediatek/Makefile
> +++ b/drivers/clk/mediatek/Makefile
> @@ -1,2 +1,3 @@
> obj-y += clk-mtk.o clk-pll.o clk-gate.o
> obj-$(CONFIG_RESET_CONTROLLER) += reset.o
> +obj-y += clk-mt8135.o
> diff --git a/drivers/clk/mediatek/clk-mt8135.c b/drivers/clk/mediatek/clk-mt8135.c
> new file mode 100644
> index 0000000..6157447
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-mt8135.c
> @@ -0,0 +1,634 @@
> +/*
> + * Copyright (c) 2014 MediaTek Inc.
> + * Author: James Liao <jamesjj.liao@mediatek.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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/of.h>
> +#include <linux/of_address.h>
> +#include <linux/slab.h>
> +#include <linux/mfd/syscon.h>
> +#include <dt-bindings/clock/mt8135-clk.h>
> +
> +#include "clk-mtk.h"
> +#include "clk-gate.h"
> +
> +static DEFINE_SPINLOCK(lock);
> +
> +static struct mtk_fixed_factor root_clk_alias[] __initdata = {
Any reason you can't use "static const" here, and on all of the other
static constant structures/arrays throughout this patch.
Thanks,
-Dan
> + FACTOR(TOP_DSI0_LNTC_DSICLK, "dsi0_lntc_dsiclk", "clk_null", 1, 1),
> + FACTOR(TOP_HDMITX_CLKDIG_CTS, "hdmitx_clkdig_cts", "clk_null", 1, 1),
> + FACTOR(TOP_CLKPH_MCK, "clkph_mck", "clk_null", 1, 1),
> + FACTOR(TOP_CPUM_TCK_IN, "cpum_tck_in", "clk_null", 1, 1),
> +};
> +
> +static struct mtk_fixed_factor top_divs[] __initdata = {
> + FACTOR(TOP_MAINPLL_806M, "mainpll_806m", "mainpll", 1, 2),
> + FACTOR(TOP_MAINPLL_537P3M, "mainpll_537p3m", "mainpll", 1, 3),
> + FACTOR(TOP_MAINPLL_322P4M, "mainpll_322p4m", "mainpll", 1, 5),
> + FACTOR(TOP_MAINPLL_230P3M, "mainpll_230p3m", "mainpll", 1, 7),
> +
> + FACTOR(TOP_UNIVPLL_624M, "univpll_624m", "univpll", 1, 2),
> + FACTOR(TOP_UNIVPLL_416M, "univpll_416m", "univpll", 1, 3),
> + FACTOR(TOP_UNIVPLL_249P6M, "univpll_249p6m", "univpll", 1, 5),
> + FACTOR(TOP_UNIVPLL_178P3M, "univpll_178p3m", "univpll", 1, 7),
> + FACTOR(TOP_UNIVPLL_48M, "univpll_48m", "univpll", 1, 26),
> +
> + FACTOR(TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2),
> + FACTOR(TOP_MMPLL_D3, "mmpll_d3", "mmpll", 1, 3),
> + FACTOR(TOP_MMPLL_D5, "mmpll_d5", "mmpll", 1, 5),
> + FACTOR(TOP_MMPLL_D7, "mmpll_d7", "mmpll", 1, 7),
> + FACTOR(TOP_MMPLL_D4, "mmpll_d4", "mmpll_d2", 1, 2),
> + FACTOR(TOP_MMPLL_D6, "mmpll_d6", "mmpll_d3", 1, 2),
> +
> + FACTOR(TOP_SYSPLL_D2, "syspll_d2", "mainpll_806m", 1, 1),
> + FACTOR(TOP_SYSPLL_D4, "syspll_d4", "mainpll_806m", 1, 2),
> + FACTOR(TOP_SYSPLL_D6, "syspll_d6", "mainpll_806m", 1, 3),
> + FACTOR(TOP_SYSPLL_D8, "syspll_d8", "mainpll_806m", 1, 4),
> + FACTOR(TOP_SYSPLL_D10, "syspll_d10", "mainpll_806m", 1, 5),
> + FACTOR(TOP_SYSPLL_D12, "syspll_d12", "mainpll_806m", 1, 6),
> + FACTOR(TOP_SYSPLL_D16, "syspll_d16", "mainpll_806m", 1, 8),
> + FACTOR(TOP_SYSPLL_D24, "syspll_d24", "mainpll_806m", 1, 12),
> +
> + FACTOR(TOP_SYSPLL_D3, "syspll_d3", "mainpll_537p3m", 1, 1),
> +
> + FACTOR(TOP_SYSPLL_D2P5, "syspll_d2p5", "mainpll_322p4m", 2, 1),
> + FACTOR(TOP_SYSPLL_D5, "syspll_d5", "mainpll_322p4m", 1, 1),
> +
> + FACTOR(TOP_SYSPLL_D3P5, "syspll_d3p5", "mainpll_230p3m", 2, 1),
> +
> + FACTOR(TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_624m", 1, 2),
> + FACTOR(TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_624m", 1, 4),
> + FACTOR(TOP_UNIVPLL1_D6, "univpll1_d6", "univpll_624m", 1, 6),
> + FACTOR(TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_624m", 1, 8),
> + FACTOR(TOP_UNIVPLL1_D10, "univpll1_d10", "univpll_624m", 1, 10),
> +
> + FACTOR(TOP_UNIVPLL2_D2, "univpll2_d2", "univpll_416m", 1, 2),
> + FACTOR(TOP_UNIVPLL2_D4, "univpll2_d4", "univpll_416m", 1, 4),
> + FACTOR(TOP_UNIVPLL2_D6, "univpll2_d6", "univpll_416m", 1, 6),
> + FACTOR(TOP_UNIVPLL2_D8, "univpll2_d8", "univpll_416m", 1, 8),
> +
> + FACTOR(TOP_UNIVPLL_D3, "univpll_d3", "univpll_416m", 1, 1),
> + FACTOR(TOP_UNIVPLL_D5, "univpll_d5", "univpll_249p6m", 1, 1),
> + FACTOR(TOP_UNIVPLL_D7, "univpll_d7", "univpll_178p3m", 1, 1),
> + FACTOR(TOP_UNIVPLL_D10, "univpll_d10", "univpll_249p6m", 1, 5),
> + FACTOR(TOP_UNIVPLL_D26, "univpll_d26", "univpll_48m", 1, 1),
> +
> + FACTOR(TOP_APLL_CK, "apll_ck", "audpll", 1, 1),
> + FACTOR(TOP_APLL_D4, "apll_d4", "audpll", 1, 4),
> + FACTOR(TOP_APLL_D8, "apll_d8", "audpll", 1, 8),
> + FACTOR(TOP_APLL_D16, "apll_d16", "audpll", 1, 16),
> + FACTOR(TOP_APLL_D24, "apll_d24", "audpll", 1, 24),
> +
> + FACTOR(TOP_LVDSPLL_D2, "lvdspll_d2", "lvdspll", 1, 2),
> + FACTOR(TOP_LVDSPLL_D4, "lvdspll_d4", "lvdspll", 1, 4),
> + FACTOR(TOP_LVDSPLL_D8, "lvdspll_d8", "lvdspll", 1, 8),
> +
> + FACTOR(TOP_LVDSTX_CLKDIG_CT, "lvdstx_clkdig_cts", "lvdspll", 1, 1),
> + FACTOR(TOP_VPLL_DPIX_CK, "vpll_dpix_ck", "lvdspll", 1, 1),
> +
> + FACTOR(TOP_TVHDMI_H_CK, "tvhdmi_h_ck", "tvdpll", 1, 1),
> +
> + FACTOR(TOP_HDMITX_CLKDIG_D2, "hdmitx_clkdig_d2", "hdmitx_clkdig_cts", 1, 2),
> + FACTOR(TOP_HDMITX_CLKDIG_D3, "hdmitx_clkdig_d3", "hdmitx_clkdig_cts", 1, 3),
> +
> + FACTOR(TOP_TVHDMI_D2, "tvhdmi_d2", "tvhdmi_h_ck", 1, 2),
> + FACTOR(TOP_TVHDMI_D4, "tvhdmi_d4", "tvhdmi_h_ck", 1, 4),
> +
> + FACTOR(TOP_MEMPLL_MCK_D4, "mempll_mck_d4", "clkph_mck", 1, 4),
> +};
> +
> +static const char *axi_parents[] __initconst = {
> + "clk26m",
> + "syspll_d3",
> + "syspll_d4",
> + "syspll_d6",
> + "univpll_d5",
> + "univpll2_d2",
> + "syspll_d3p5"
> +};
> +
> +static const char *smi_parents[] __initconst = {
> + "clk26m",
> + "clkph_mck",
> + "syspll_d2p5",
> + "syspll_d3",
> + "syspll_d8",
> + "univpll_d5",
> + "univpll1_d2",
> + "univpll1_d6",
> + "mmpll_d3",
> + "mmpll_d4",
> + "mmpll_d5",
> + "mmpll_d6",
> + "mmpll_d7",
> + "vdecpll",
> + "lvdspll"
> +};
> +
> +static const char *mfg_parents[] __initconst = {
> + "clk26m",
> + "univpll1_d4",
> + "syspll_d2",
> + "syspll_d2p5",
> + "syspll_d3",
> + "univpll_d5",
> + "univpll1_d2",
> + "mmpll_d2",
> + "mmpll_d3",
> + "mmpll_d4",
> + "mmpll_d5",
> + "mmpll_d6",
> + "mmpll_d7"
> +};
> +
> +static const char *irda_parents[] __initconst = {
> + "clk26m",
> + "univpll2_d8",
> + "univpll1_d6"
> +};
> +
> +static const char *cam_parents[] __initconst = {
> + "clk26m",
> + "syspll_d3",
> + "syspll_d3p5",
> + "syspll_d4",
> + "univpll_d5",
> + "univpll2_d2",
> + "univpll_d7",
> + "univpll1_d4"
> +};
> +
> +static const char *aud_intbus_parents[] __initconst = {
> + "clk26m",
> + "syspll_d6",
> + "univpll_d10"
> +};
> +
> +static const char *jpg_parents[] __initconst = {
> + "clk26m",
> + "syspll_d5",
> + "syspll_d4",
> + "syspll_d3",
> + "univpll_d7",
> + "univpll2_d2",
> + "univpll_d5"
> +};
> +
> +static const char *disp_parents[] __initconst = {
> + "clk26m",
> + "syspll_d3p5",
> + "syspll_d3",
> + "univpll2_d2",
> + "univpll_d5",
> + "univpll1_d2",
> + "lvdspll",
> + "vdecpll"
> +};
> +
> +static const char *msdc30_parents[] __initconst = {
> + "clk26m",
> + "syspll_d6",
> + "syspll_d5",
> + "univpll1_d4",
> + "univpll2_d4",
> + "msdcpll"
> +};
> +
> +static const char *usb20_parents[] __initconst = {
> + "clk26m",
> + "univpll2_d6",
> + "univpll1_d10"
> +};
> +
> +static const char *venc_parents[] __initconst = {
> + "clk26m",
> + "syspll_d3",
> + "syspll_d8",
> + "univpll_d5",
> + "univpll1_d6",
> + "mmpll_d4",
> + "mmpll_d5",
> + "mmpll_d6"
> +};
> +
> +static const char *spi_parents[] __initconst = {
> + "clk26m",
> + "syspll_d6",
> + "syspll_d8",
> + "syspll_d10",
> + "univpll1_d6",
> + "univpll1_d8"
> +};
> +
> +static const char *uart_parents[] __initconst = {
> + "clk26m",
> + "univpll2_d8"
> +};
> +
> +static const char *mem_parents[] __initconst = {
> + "clk26m",
> + "clkph_mck"
> +};
> +
> +static const char *camtg_parents[] __initconst = {
> + "clk26m",
> + "univpll_d26",
> + "univpll1_d6",
> + "syspll_d16",
> + "syspll_d8"
> +};
> +
> +static const char *audio_parents[] __initconst = {
> + "clk26m",
> + "syspll_d24"
> +};
> +
> +static const char *fix_parents[] __initconst = {
> + "rtc32k",
> + "clk26m",
> + "univpll_d5",
> + "univpll_d7",
> + "univpll1_d2",
> + "univpll1_d4",
> + "univpll1_d6",
> + "univpll1_d8"
> +};
> +
> +static const char *vdec_parents[] __initconst = {
> + "clk26m",
> + "vdecpll",
> + "clkph_mck",
> + "syspll_d2p5",
> + "syspll_d3",
> + "syspll_d3p5",
> + "syspll_d4",
> + "syspll_d5",
> + "syspll_d6",
> + "syspll_d8",
> + "univpll1_d2",
> + "univpll2_d2",
> + "univpll_d7",
> + "univpll_d10",
> + "univpll2_d4",
> + "lvdspll"
> +};
> +
> +static const char *ddrphycfg_parents[] __initconst = {
> + "clk26m",
> + "axi_sel",
> + "syspll_d12"
> +};
> +
> +static const char *dpilvds_parents[] __initconst = {
> + "clk26m",
> + "lvdspll",
> + "lvdspll_d2",
> + "lvdspll_d4",
> + "lvdspll_d8"
> +};
> +
> +static const char *pmicspi_parents[] __initconst = {
> + "clk26m",
> + "univpll2_d6",
> + "syspll_d8",
> + "syspll_d10",
> + "univpll1_d10",
> + "mempll_mck_d4",
> + "univpll_d26",
> + "syspll_d24"
> +};
> +
> +static const char *smi_mfg_as_parents[] __initconst = {
> + "clk26m",
> + "smi_sel",
> + "mfg_sel",
> + "mem_sel"
> +};
> +
> +static const char *gcpu_parents[] __initconst = {
> + "clk26m",
> + "syspll_d4",
> + "univpll_d7",
> + "syspll_d5",
> + "syspll_d6"
> +};
> +
> +static const char *dpi1_parents[] __initconst = {
> + "clk26m",
> + "tvhdmi_h_ck",
> + "tvhdmi_d2",
> + "tvhdmi_d4"
> +};
> +
> +static const char *cci_parents[] __initconst = {
> + "clk26m",
> + "mainpll_537p3m",
> + "univpll_d3",
> + "syspll_d2p5",
> + "syspll_d3",
> + "syspll_d5"
> +};
> +
> +static const char *apll_parents[] __initconst = {
> + "clk26m",
> + "apll_ck",
> + "apll_d4",
> + "apll_d8",
> + "apll_d16",
> + "apll_d24"
> +};
> +
> +static const char *hdmipll_parents[] __initconst = {
> + "clk26m",
> + "hdmitx_clkdig_cts",
> + "hdmitx_clkdig_d2",
> + "hdmitx_clkdig_d3"
> +};
> +
> +static struct mtk_composite top_muxes[] __initdata = {
> + /* CLK_CFG_0 */
> + MUX_GATE(TOP_AXI_SEL, "axi_sel", axi_parents,
> + 0x0140, 0, 3, INVALID_MUX_GATE_BIT),
> + MUX_GATE(TOP_SMI_SEL, "smi_sel", smi_parents, 0x0140, 8, 4, 15),
> + MUX_GATE(TOP_MFG_SEL, "mfg_sel", mfg_parents, 0x0140, 16, 4, 23),
> + MUX_GATE(TOP_IRDA_SEL, "irda_sel", irda_parents, 0x0140, 24, 2, 31),
> + /* CLK_CFG_1 */
> + MUX_GATE(TOP_CAM_SEL, "cam_sel", cam_parents, 0x0144, 0, 3, 7),
> + MUX_GATE(TOP_AUD_INTBUS_SEL, "aud_intbus_sel", aud_intbus_parents,
> + 0x0144, 8, 2, 15),
> + MUX_GATE(TOP_JPG_SEL, "jpg_sel", jpg_parents, 0x0144, 16, 3, 23),
> + MUX_GATE(TOP_DISP_SEL, "disp_sel", disp_parents, 0x0144, 24, 3, 31),
> + /* CLK_CFG_2 */
> + MUX_GATE(TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_parents, 0x0148, 0, 3, 7),
> + MUX_GATE(TOP_MSDC30_2_SEL, "msdc30_2_sel", msdc30_parents, 0x0148, 8, 3, 15),
> + MUX_GATE(TOP_MSDC30_3_SEL, "msdc30_3_sel", msdc30_parents, 0x0148, 16, 3, 23),
> + MUX_GATE(TOP_MSDC30_4_SEL, "msdc30_4_sel", msdc30_parents, 0x0148, 24, 3, 31),
> + /* CLK_CFG_3 */
> + MUX_GATE(TOP_USB20_SEL, "usb20_sel", usb20_parents, 0x014c, 0, 2, 7),
> + /* CLK_CFG_4 */
> + MUX_GATE(TOP_VENC_SEL, "venc_sel", venc_parents, 0x0150, 8, 3, 15),
> + MUX_GATE(TOP_SPI_SEL, "spi_sel", spi_parents, 0x0150, 16, 3, 23),
> + MUX_GATE(TOP_UART_SEL, "uart_sel", uart_parents, 0x0150, 24, 2, 31),
> + /* CLK_CFG_6 */
> + MUX_GATE(TOP_MEM_SEL, "mem_sel", mem_parents, 0x0158, 0, 2, 7),
> + MUX_GATE(TOP_CAMTG_SEL, "camtg_sel", camtg_parents, 0x0158, 8, 3, 15),
> + MUX_GATE(TOP_AUDIO_SEL, "audio_sel", audio_parents, 0x0158, 24, 2, 31),
> + /* CLK_CFG_7 */
> + MUX_GATE(TOP_FIX_SEL, "fix_sel", fix_parents, 0x015c, 0, 3, 7),
> + MUX_GATE(TOP_VDEC_SEL, "vdec_sel", vdec_parents, 0x015c, 8, 4, 15),
> + MUX_GATE(TOP_DDRPHYCFG_SEL, "ddrphycfg_sel", ddrphycfg_parents,
> + 0x015c, 16, 2, 23),
> + MUX_GATE(TOP_DPILVDS_SEL, "dpilvds_sel", dpilvds_parents, 0x015c, 24, 3, 31),
> + /* CLK_CFG_8 */
> + MUX_GATE(TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents, 0x0164, 0, 3, 7),
> + MUX_GATE(TOP_MSDC30_0_SEL, "msdc30_0_sel", msdc30_parents, 0x0164, 8, 3, 15),
> + MUX_GATE(TOP_SMI_MFG_AS_SEL, "smi_mfg_as_sel", smi_mfg_as_parents,
> + 0x0164, 16, 2, 23),
> + MUX_GATE(TOP_GCPU_SEL, "gcpu_sel", gcpu_parents, 0x0164, 24, 3, 31),
> + /* CLK_CFG_9 */
> + MUX_GATE(TOP_DPI1_SEL, "dpi1_sel", dpi1_parents, 0x0168, 0, 2, 7),
> + MUX_GATE(TOP_CCI_SEL, "cci_sel", cci_parents, 0x0168, 8, 3, 15),
> + MUX_GATE(TOP_APLL_SEL, "apll_sel", apll_parents, 0x0168, 16, 3, 23),
> + MUX_GATE(TOP_HDMIPLL_SEL, "hdmipll_sel", hdmipll_parents, 0x0168, 24, 2, 31),
> +};
> +
> +static void __init mtk_init_clk_topckgen(void __iomem *top_base,
> + struct clk_onecell_data *clk_data)
> +{
> + int i;
> + struct clk *clk;
> +
> + for (i = 0; i < ARRAY_SIZE(top_muxes); i++) {
> + struct mtk_composite *mux = &top_muxes[i];
> +
> + clk = mtk_clk_register_composite(mux, top_base, &lock);
> +
> + if (IS_ERR(clk)) {
> + pr_err("Failed to register clk %s: %ld\n",
> + mux->name, PTR_ERR(clk));
> + continue;
> + }
> +
> + if (clk_data)
> + clk_data->clks[mux->id] = clk;
> + }
> +}
> +
> +static struct mtk_gate_regs infra_cg_regs = {
> + .set_ofs = 0x0040,
> + .clr_ofs = 0x0044,
> + .sta_ofs = 0x0048,
> +};
> +
> +#define GATE_ICG(_id, _name, _parent, _shift) { \
> + .id = _id, \
> + .name = _name, \
> + .parent_name = _parent, \
> + .regs = &infra_cg_regs, \
> + .shift = _shift, \
> + .ops = &mtk_clk_gate_ops_setclr, \
> + }
> +
> +static struct mtk_gate infra_clks[] __initdata = {
> + GATE_ICG(INFRA_PMIC_WRAP_CK, "pmic_wrap_ck", "axi_sel", 23),
> + GATE_ICG(INFRA_PMICSPI_CK, "pmicspi_ck", "pmicspi_sel", 22),
> + GATE_ICG(INFRA_CCIF1_AP_CTRL, "ccif1_ap_ctrl", "axi_sel", 21),
> + GATE_ICG(INFRA_CCIF0_AP_CTRL, "ccif0_ap_ctrl", "axi_sel", 20),
> + GATE_ICG(INFRA_KP_CK, "kp_ck", "axi_sel", 16),
> + GATE_ICG(INFRA_CPUM_CK, "cpum_ck", "cpum_tck_in", 15),
> + GATE_ICG(INFRA_M4U_CK, "m4u_ck", "mem_sel", 8),
> + GATE_ICG(INFRA_MFGAXI_CK, "mfgaxi_ck", "axi_sel", 7),
> + GATE_ICG(INFRA_DEVAPC_CK, "devapc_ck", "axi_sel", 6),
> + GATE_ICG(INFRA_AUDIO_CK, "audio_ck", "aud_intbus_sel", 5),
> + GATE_ICG(INFRA_MFG_BUS_CK, "mfg_bus_ck", "axi_sel", 2),
> + GATE_ICG(INFRA_SMI_CK, "smi_ck", "smi_sel", 1),
> + GATE_ICG(INFRA_DBGCLK_CK, "dbgclk_ck", "axi_sel", 0),
> +};
> +
> +static struct mtk_gate_regs peri0_cg_regs = {
> + .set_ofs = 0x0008,
> + .clr_ofs = 0x0010,
> + .sta_ofs = 0x0018,
> +};
> +
> +static struct mtk_gate_regs peri1_cg_regs = {
> + .set_ofs = 0x000c,
> + .clr_ofs = 0x0014,
> + .sta_ofs = 0x001c,
> +};
> +
> +#define GATE_PERI0(_id, _name, _parent, _shift) { \
> + .id = _id, \
> + .name = _name, \
> + .parent_name = _parent, \
> + .regs = &peri0_cg_regs, \
> + .shift = _shift, \
> + .ops = &mtk_clk_gate_ops_setclr, \
> + }
> +
> +#define GATE_PERI1(_id, _name, _parent, _shift) { \
> + .id = _id, \
> + .name = _name, \
> + .parent_name = _parent, \
> + .regs = &peri1_cg_regs, \
> + .shift = _shift, \
> + .ops = &mtk_clk_gate_ops_setclr, \
> + }
> +
> +static struct mtk_gate peri_clks[] __initdata = {
> + /* PERI0 */
> + GATE_PERI0(PERI_I2C5_CK, "i2c5_ck", "axi_sel", 31),
> + GATE_PERI0(PERI_I2C4_CK, "i2c4_ck", "axi_sel", 30),
> + GATE_PERI0(PERI_I2C3_CK, "i2c3_ck", "axi_sel", 29),
> + GATE_PERI0(PERI_I2C2_CK, "i2c2_ck", "axi_sel", 28),
> + GATE_PERI0(PERI_I2C1_CK, "i2c1_ck", "axi_sel", 27),
> + GATE_PERI0(PERI_I2C0_CK, "i2c0_ck", "axi_sel", 26),
> + GATE_PERI0(PERI_UART3_CK, "uart3_ck", "axi_sel", 25),
> + GATE_PERI0(PERI_UART2_CK, "uart2_ck", "axi_sel", 24),
> + GATE_PERI0(PERI_UART1_CK, "uart1_ck", "axi_sel", 23),
> + GATE_PERI0(PERI_UART0_CK, "uart0_ck", "axi_sel", 22),
> + GATE_PERI0(PERI_IRDA_CK, "irda_ck", "irda_sel", 21),
> + GATE_PERI0(PERI_NLI_CK, "nli_ck", "axi_sel", 20),
> + GATE_PERI0(PERI_MD_HIF_CK, "md_hif_ck", "axi_sel", 19),
> + GATE_PERI0(PERI_AP_HIF_CK, "ap_hif_ck", "axi_sel", 18),
> + GATE_PERI0(PERI_MSDC30_3_CK, "msdc30_3_ck", "msdc30_4_sel", 17),
> + GATE_PERI0(PERI_MSDC30_2_CK, "msdc30_2_ck", "msdc30_3_sel", 16),
> + GATE_PERI0(PERI_MSDC30_1_CK, "msdc30_1_ck", "msdc30_2_sel", 15),
> + GATE_PERI0(PERI_MSDC20_2_CK, "msdc20_2_ck", "msdc30_1_sel", 14),
> + GATE_PERI0(PERI_MSDC20_1_CK, "msdc20_1_ck", "msdc30_0_sel", 13),
> + GATE_PERI0(PERI_AP_DMA_CK, "ap_dma_ck", "axi_sel", 12),
> + GATE_PERI0(PERI_USB1_CK, "usb1_ck", "usb20_sel", 11),
> + GATE_PERI0(PERI_USB0_CK, "usb0_ck", "usb20_sel", 10),
> + GATE_PERI0(PERI_PWM_CK, "pwm_ck", "axi_sel", 9),
> + GATE_PERI0(PERI_PWM7_CK, "pwm7_ck", "axi_sel", 8),
> + GATE_PERI0(PERI_PWM6_CK, "pwm6_ck", "axi_sel", 7),
> + GATE_PERI0(PERI_PWM5_CK, "pwm5_ck", "axi_sel", 6),
> + GATE_PERI0(PERI_PWM4_CK, "pwm4_ck", "axi_sel", 5),
> + GATE_PERI0(PERI_PWM3_CK, "pwm3_ck", "axi_sel", 4),
> + GATE_PERI0(PERI_PWM2_CK, "pwm2_ck", "axi_sel", 3),
> + GATE_PERI0(PERI_PWM1_CK, "pwm1_ck", "axi_sel", 2),
> + GATE_PERI0(PERI_THERM_CK, "therm_ck", "axi_sel", 1),
> + GATE_PERI0(PERI_NFI_CK, "nfi_ck", "axi_sel", 0),
> + /* PERI1 */
> + GATE_PERI1(PERI_USBSLV_CK, "usbslv_ck", "axi_sel", 8),
> + GATE_PERI1(PERI_USB1_MCU_CK, "usb1_mcu_ck", "axi_sel", 7),
> + GATE_PERI1(PERI_USB0_MCU_CK, "usb0_mcu_ck", "axi_sel", 6),
> + GATE_PERI1(PERI_GCPU_CK, "gcpu_ck", "gcpu_sel", 5),
> + GATE_PERI1(PERI_FHCTL_CK, "fhctl_ck", "clk26m", 4),
> + GATE_PERI1(PERI_SPI1_CK, "spi1_ck", "spi_sel", 3),
> + GATE_PERI1(PERI_AUXADC_CK, "auxadc_ck", "clk26m", 2),
> + GATE_PERI1(PERI_PERI_PWRAP_CK, "peri_pwrap_ck", "axi_sel", 1),
> + GATE_PERI1(PERI_I2C6_CK, "i2c6_ck", "axi_sel", 0),
> +};
> +
> +static void __init mtk_topckgen_init(struct device_node *node)
> +{
> + struct clk_onecell_data *clk_data;
> + void __iomem *base;
> + int r;
> +
> + base = of_iomap(node, 0);
> + if (!base) {
> + pr_err("%s(): ioremap failed\n", __func__);
> + return;
> + }
> +
> + clk_data = mtk_alloc_clk_data(TOP_NR_CLK);
> +
> + mtk_clk_register_factors(root_clk_alias, ARRAY_SIZE(root_clk_alias), clk_data);
> + mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
> + mtk_init_clk_topckgen(base, clk_data);
> +
> + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> + if (r)
> + pr_err("%s(): could not register clock provider: %d\n",
> + __func__, r);
> +}
> +CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt8135-topckgen", mtk_topckgen_init);
> +
> +static void __init mtk_infrasys_init(struct device_node *node)
> +{
> + struct clk_onecell_data *clk_data;
> + int r;
> +
> + clk_data = mtk_alloc_clk_data(INFRA_NR_CLK);
> +
> + mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
> + clk_data);
> +
> + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> + if (r)
> + pr_err("%s(): could not register clock provider: %d\n",
> + __func__, r);
> +
> + mtk_register_reset_controller(node, 2, 0x30);
> +}
> +CLK_OF_DECLARE(mtk_infrasys, "mediatek,mt8135-infracfg", mtk_infrasys_init);
> +
> +static void __init mtk_pericfg_init(struct device_node *node)
> +{
> + struct clk_onecell_data *clk_data;
> + int r;
> +
> + clk_data = mtk_alloc_clk_data(PERI_NR_CLK);
> +
> + mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
> + clk_data);
> +
> + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> + if (r)
> + pr_err("%s(): could not register clock provider: %d\n",
> + __func__, r);
> +
> + mtk_register_reset_controller(node, 2, 0);
> +}
> +CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt8135-pericfg", mtk_pericfg_init);
> +
> +#define MT8135_PLL_FMAX (2000 * MHZ)
> +#define CON0_MT8135_RST_BAR BIT(27)
> +
> +#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) { \
> + .id = _id, \
> + .name = _name, \
> + .reg = _reg, \
> + .pwr_reg = _pwr_reg, \
> + .en_mask = _en_mask, \
> + .flags = _flags, \
> + .rst_bar_mask = CON0_MT8135_RST_BAR, \
> + .fmax = MT8135_PLL_FMAX, \
> + .pcwbits = _pcwbits, \
> + .pd_reg = _pd_reg, \
> + .pd_shift = _pd_shift, \
> + .tuner_reg = _tuner_reg, \
> + .pcw_reg = _pcw_reg, \
> + .pcw_shift = _pcw_shift, \
> + }
> +
> +static struct mtk_pll_data plls[] = {
> + PLL(APMIXED_ARMPLL1, "armpll1", 0x200, 0x218, 0x80000001, 0, 21, 0x204, 24, 0x0, 0x204, 0),
> + PLL(APMIXED_ARMPLL2, "armpll2", 0x2cc, 0x2e4, 0x80000001, 0, 21, 0x2d0, 24, 0x0, 0x2d0, 0),
> + PLL(APMIXED_MAINPLL, "mainpll", 0x21c, 0x234, 0xf0000001, HAVE_RST_BAR, 21, 0x21c, 6, 0x0, 0x220, 0),
> + PLL(APMIXED_UNIVPLL, "univpll", 0x238, 0x250, 0xf3000001, HAVE_RST_BAR, 7, 0x238, 6, 0x0, 0x238, 9),
> + PLL(APMIXED_MMPLL, "mmpll", 0x254, 0x26c, 0xf0000001, HAVE_RST_BAR, 21, 0x254, 6, 0x0, 0x258, 0),
> + PLL(APMIXED_MSDCPLL, "msdcpll", 0x278, 0x290, 0x80000001, 0, 21, 0x278, 6, 0x0, 0x27c, 0),
> + PLL(APMIXED_TVDPLL, "tvdpll", 0x294, 0x2ac, 0x80000001, 0, 31, 0x296, 6, 0x0, 0x298, 0),
> + PLL(APMIXED_LVDSPLL, "lvdspll", 0x2b0, 0x2c8, 0x80000001, 0, 21, 0x2b0, 6, 0x0, 0x2b4, 0),
> + PLL(APMIXED_AUDPLL, "audpll", 0x2e8, 0x300, 0x80000001, 0, 31, 0x2e8, 6, 0x2f8, 0x2ec, 0),
> + PLL(APMIXED_VDECPLL, "vdecpll", 0x304, 0x31c, 0x80000001, 0, 21, 0x2b0, 6, 0x0, 0x308, 0),
> +};
> +
> +static void __init mtk_apmixedsys_init(struct device_node *node)
> +{
> + mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls));
> +}
> +CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt8135-apmixedsys",
> + mtk_apmixedsys_init);
> diff --git a/include/dt-bindings/clock/mt8135-clk.h b/include/dt-bindings/clock/mt8135-clk.h
> new file mode 100644
> index 0000000..8aea762
> --- /dev/null
> +++ b/include/dt-bindings/clock/mt8135-clk.h
> @@ -0,0 +1,190 @@
> +/*
> + * Copyright (c) 2014 MediaTek Inc.
> + * Author: James Liao <jamesjj.liao@mediatek.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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 _DT_BINDINGS_CLK_MT8135_H
> +#define _DT_BINDINGS_CLK_MT8135_H
> +
> +/* TOPCKGEN */
> +
> +#define TOP_DSI0_LNTC_DSICLK 1
> +#define TOP_HDMITX_CLKDIG_CTS 2
> +#define TOP_CLKPH_MCK 3
> +#define TOP_CPUM_TCK_IN 4
> +#define TOP_MAINPLL_806M 5
> +#define TOP_MAINPLL_537P3M 6
> +#define TOP_MAINPLL_322P4M 7
> +#define TOP_MAINPLL_230P3M 8
> +#define TOP_UNIVPLL_624M 9
> +#define TOP_UNIVPLL_416M 10
> +#define TOP_UNIVPLL_249P6M 11
> +#define TOP_UNIVPLL_178P3M 12
> +#define TOP_UNIVPLL_48M 13
> +#define TOP_MMPLL_D2 14
> +#define TOP_MMPLL_D3 15
> +#define TOP_MMPLL_D5 16
> +#define TOP_MMPLL_D7 17
> +#define TOP_MMPLL_D4 18
> +#define TOP_MMPLL_D6 19
> +#define TOP_SYSPLL_D2 20
> +#define TOP_SYSPLL_D4 21
> +#define TOP_SYSPLL_D6 22
> +#define TOP_SYSPLL_D8 23
> +#define TOP_SYSPLL_D10 24
> +#define TOP_SYSPLL_D12 25
> +#define TOP_SYSPLL_D16 26
> +#define TOP_SYSPLL_D24 27
> +#define TOP_SYSPLL_D3 28
> +#define TOP_SYSPLL_D2P5 29
> +#define TOP_SYSPLL_D5 30
> +#define TOP_SYSPLL_D3P5 31
> +#define TOP_UNIVPLL1_D2 32
> +#define TOP_UNIVPLL1_D4 33
> +#define TOP_UNIVPLL1_D6 34
> +#define TOP_UNIVPLL1_D8 35
> +#define TOP_UNIVPLL1_D10 36
> +#define TOP_UNIVPLL2_D2 37
> +#define TOP_UNIVPLL2_D4 38
> +#define TOP_UNIVPLL2_D6 39
> +#define TOP_UNIVPLL2_D8 40
> +#define TOP_UNIVPLL_D3 41
> +#define TOP_UNIVPLL_D5 42
> +#define TOP_UNIVPLL_D7 43
> +#define TOP_UNIVPLL_D10 44
> +#define TOP_UNIVPLL_D26 45
> +#define TOP_APLL_CK 46
> +#define TOP_APLL_D4 47
> +#define TOP_APLL_D8 48
> +#define TOP_APLL_D16 49
> +#define TOP_APLL_D24 50
> +#define TOP_LVDSPLL_D2 51
> +#define TOP_LVDSPLL_D4 52
> +#define TOP_LVDSPLL_D8 53
> +#define TOP_LVDSTX_CLKDIG_CT 54
> +#define TOP_VPLL_DPIX_CK 55
> +#define TOP_TVHDMI_H_CK 56
> +#define TOP_HDMITX_CLKDIG_D2 57
> +#define TOP_HDMITX_CLKDIG_D3 58
> +#define TOP_TVHDMI_D2 59
> +#define TOP_TVHDMI_D4 60
> +#define TOP_MEMPLL_MCK_D4 61
> +#define TOP_AXI_SEL 62
> +#define TOP_SMI_SEL 63
> +#define TOP_MFG_SEL 64
> +#define TOP_IRDA_SEL 65
> +#define TOP_CAM_SEL 66
> +#define TOP_AUD_INTBUS_SEL 67
> +#define TOP_JPG_SEL 68
> +#define TOP_DISP_SEL 69
> +#define TOP_MSDC30_1_SEL 70
> +#define TOP_MSDC30_2_SEL 71
> +#define TOP_MSDC30_3_SEL 72
> +#define TOP_MSDC30_4_SEL 73
> +#define TOP_USB20_SEL 74
> +#define TOP_VENC_SEL 75
> +#define TOP_SPI_SEL 76
> +#define TOP_UART_SEL 77
> +#define TOP_MEM_SEL 78
> +#define TOP_CAMTG_SEL 79
> +#define TOP_AUDIO_SEL 80
> +#define TOP_FIX_SEL 81
> +#define TOP_VDEC_SEL 82
> +#define TOP_DDRPHYCFG_SEL 83
> +#define TOP_DPILVDS_SEL 84
> +#define TOP_PMICSPI_SEL 85
> +#define TOP_MSDC30_0_SEL 86
> +#define TOP_SMI_MFG_AS_SEL 87
> +#define TOP_GCPU_SEL 88
> +#define TOP_DPI1_SEL 89
> +#define TOP_CCI_SEL 90
> +#define TOP_APLL_SEL 91
> +#define TOP_HDMIPLL_SEL 92
> +#define TOP_NR_CLK 93
> +
> +/* APMIXED_SYS */
> +
> +#define APMIXED_ARMPLL1 1
> +#define APMIXED_ARMPLL2 2
> +#define APMIXED_MAINPLL 3
> +#define APMIXED_UNIVPLL 4
> +#define APMIXED_MMPLL 5
> +#define APMIXED_MSDCPLL 6
> +#define APMIXED_TVDPLL 7
> +#define APMIXED_LVDSPLL 8
> +#define APMIXED_AUDPLL 9
> +#define APMIXED_VDECPLL 10
> +#define APMIXED_NR_CLK 11
> +
> +/* INFRA_SYS */
> +
> +#define INFRA_PMIC_WRAP_CK 1
> +#define INFRA_PMICSPI_CK 2
> +#define INFRA_CCIF1_AP_CTRL 3
> +#define INFRA_CCIF0_AP_CTRL 4
> +#define INFRA_KP_CK 5
> +#define INFRA_CPUM_CK 6
> +#define INFRA_M4U_CK 7
> +#define INFRA_MFGAXI_CK 8
> +#define INFRA_DEVAPC_CK 9
> +#define INFRA_AUDIO_CK 10
> +#define INFRA_MFG_BUS_CK 11
> +#define INFRA_SMI_CK 12
> +#define INFRA_DBGCLK_CK 13
> +#define INFRA_NR_CLK 14
> +
> +/* PERI_SYS */
> +
> +#define PERI_I2C5_CK 1
> +#define PERI_I2C4_CK 2
> +#define PERI_I2C3_CK 3
> +#define PERI_I2C2_CK 4
> +#define PERI_I2C1_CK 5
> +#define PERI_I2C0_CK 6
> +#define PERI_UART3_CK 7
> +#define PERI_UART2_CK 8
> +#define PERI_UART1_CK 9
> +#define PERI_UART0_CK 10
> +#define PERI_IRDA_CK 11
> +#define PERI_NLI_CK 12
> +#define PERI_MD_HIF_CK 13
> +#define PERI_AP_HIF_CK 14
> +#define PERI_MSDC30_3_CK 15
> +#define PERI_MSDC30_2_CK 16
> +#define PERI_MSDC30_1_CK 17
> +#define PERI_MSDC20_2_CK 18
> +#define PERI_MSDC20_1_CK 19
> +#define PERI_AP_DMA_CK 20
> +#define PERI_USB1_CK 21
> +#define PERI_USB0_CK 22
> +#define PERI_PWM_CK 23
> +#define PERI_PWM7_CK 24
> +#define PERI_PWM6_CK 25
> +#define PERI_PWM5_CK 26
> +#define PERI_PWM4_CK 27
> +#define PERI_PWM3_CK 28
> +#define PERI_PWM2_CK 29
> +#define PERI_PWM1_CK 30
> +#define PERI_THERM_CK 31
> +#define PERI_NFI_CK 32
> +#define PERI_USBSLV_CK 33
> +#define PERI_USB1_MCU_CK 34
> +#define PERI_USB0_MCU_CK 35
> +#define PERI_GCPU_CK 36
> +#define PERI_FHCTL_CK 37
> +#define PERI_SPI1_CK 38
> +#define PERI_AUXADC_CK 39
> +#define PERI_PERI_PWRAP_CK 40
> +#define PERI_I2C6_CK 41
> +#define PERI_NR_CLK 42
> +
> +#endif /* _DT_BINDINGS_CLK_MT8135_H */
> diff --git a/include/dt-bindings/reset-controller/mt8135-resets.h b/include/dt-bindings/reset-controller/mt8135-resets.h
> new file mode 100644
> index 0000000..1fb6295
> --- /dev/null
> +++ b/include/dt-bindings/reset-controller/mt8135-resets.h
> @@ -0,0 +1,64 @@
> +/*
> + * Copyright (c) 2014 MediaTek Inc.
> + * Author: Flora Fu, MediaTek
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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 _DT_BINDINGS_RESET_CONTROLLER_MT8135
> +#define _DT_BINDINGS_RESET_CONTROLLER_MT8135
> +
> +/* INFRACFG resets */
> +#define MT8135_INFRA_EMI_REG_RST 0
> +#define MT8135_INFRA_DRAMC0_A0_RST 1
> +#define MT8135_INFRA_CCIF0_RST 2
> +#define MT8135_INFRA_APCIRQ_EINT_RST 3
> +#define MT8135_INFRA_APXGPT_RST 4
> +#define MT8135_INFRA_SCPSYS_RST 5
> +#define MT8135_INFRA_CCIF1_RST 6
> +#define MT8135_INFRA_PMIC_WRAP_RST 7
> +#define MT8135_INFRA_KP_RST 8
> +#define MT8135_INFRA_EMI_RST 32
> +#define MT8135_INFRA_DRAMC0_RST 34
> +#define MT8135_INFRA_SMI_RST 35
> +#define MT8135_INFRA_M4U_RST 36
> +
> +/* PERICFG resets */
> +#define MT8135_PERI_UART0_SW_RST 0
> +#define MT8135_PERI_UART1_SW_RST 1
> +#define MT8135_PERI_UART2_SW_RST 2
> +#define MT8135_PERI_UART3_SW_RST 3
> +#define MT8135_PERI_IRDA_SW_RST 4
> +#define MT8135_PERI_PTP_SW_RST 5
> +#define MT8135_PERI_AP_HIF_SW_RST 6
> +#define MT8135_PERI_GPCU_SW_RST 7
> +#define MT8135_PERI_MD_HIF_SW_RST 8
> +#define MT8135_PERI_NLI_SW_RST 9
> +#define MT8135_PERI_AUXADC_SW_RST 10
> +#define MT8135_PERI_DMA_SW_RST 11
> +#define MT8135_PERI_NFI_SW_RST 14
> +#define MT8135_PERI_PWM_SW_RST 15
> +#define MT8135_PERI_THERM_SW_RST 16
> +#define MT8135_PERI_MSDC0_SW_RST 17
> +#define MT8135_PERI_MSDC1_SW_RST 18
> +#define MT8135_PERI_MSDC2_SW_RST 19
> +#define MT8135_PERI_MSDC3_SW_RST 20
> +#define MT8135_PERI_I2C0_SW_RST 22
> +#define MT8135_PERI_I2C1_SW_RST 23
> +#define MT8135_PERI_I2C2_SW_RST 24
> +#define MT8135_PERI_I2C3_SW_RST 25
> +#define MT8135_PERI_I2C4_SW_RST 26
> +#define MT8135_PERI_I2C5_SW_RST 27
> +#define MT8135_PERI_I2C6_SW_RST 28
> +#define MT8135_PERI_USB_SW_RST 29
> +#define MT8135_PERI_SPI1_SW_RST 33
> +#define MT8135_PERI_PWRAP_BRIDGE_SW_RST 34
> +
> +#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT8135 */
> --
> 2.1.4
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 3/5] clk: mediatek: Add basic clocks for Mediatek MT8135.
@ 2015-03-15 16:27 ` Daniel Kurtz
0 siblings, 0 replies; 30+ messages in thread
From: Daniel Kurtz @ 2015-03-15 16:27 UTC (permalink / raw)
To: Sascha Hauer
Cc: Mike Turquette, James Liao, YH Chen, linux-kernel, Henry Chen,
linux-mediatek, Sasha Hauer, Matthias Brugger, Yingjoe Chen,
Eddie Huang, linux-arm-kernel
Hi Sascha,
Drive-by review...
On Sun, Feb 22, 2015 at 7:49 PM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> From: James Liao <jamesjj.liao@mediatek.com>
>
> This patch adds basic clocks for MT8135, including TOPCKGEN, PLLs,
> INFRA and PERI clocks.
>
> Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
> Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
> drivers/clk/mediatek/Makefile | 1 +
> drivers/clk/mediatek/clk-mt8135.c | 634 +++++++++++++++++++++
> include/dt-bindings/clock/mt8135-clk.h | 190 ++++++
> .../dt-bindings/reset-controller/mt8135-resets.h | 64 +++
> 4 files changed, 889 insertions(+)
> create mode 100644 drivers/clk/mediatek/clk-mt8135.c
> create mode 100644 include/dt-bindings/clock/mt8135-clk.h
> create mode 100644 include/dt-bindings/reset-controller/mt8135-resets.h
>
> diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
> index 0b6f1c3..12ce576 100644
> --- a/drivers/clk/mediatek/Makefile
> +++ b/drivers/clk/mediatek/Makefile
> @@ -1,2 +1,3 @@
> obj-y += clk-mtk.o clk-pll.o clk-gate.o
> obj-$(CONFIG_RESET_CONTROLLER) += reset.o
> +obj-y += clk-mt8135.o
> diff --git a/drivers/clk/mediatek/clk-mt8135.c b/drivers/clk/mediatek/clk-mt8135.c
> new file mode 100644
> index 0000000..6157447
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-mt8135.c
> @@ -0,0 +1,634 @@
> +/*
> + * Copyright (c) 2014 MediaTek Inc.
> + * Author: James Liao <jamesjj.liao@mediatek.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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/of.h>
> +#include <linux/of_address.h>
> +#include <linux/slab.h>
> +#include <linux/mfd/syscon.h>
> +#include <dt-bindings/clock/mt8135-clk.h>
> +
> +#include "clk-mtk.h"
> +#include "clk-gate.h"
> +
> +static DEFINE_SPINLOCK(lock);
> +
> +static struct mtk_fixed_factor root_clk_alias[] __initdata = {
Any reason you can't use "static const" here, and on all of the other
static constant structures/arrays throughout this patch.
Thanks,
-Dan
> + FACTOR(TOP_DSI0_LNTC_DSICLK, "dsi0_lntc_dsiclk", "clk_null", 1, 1),
> + FACTOR(TOP_HDMITX_CLKDIG_CTS, "hdmitx_clkdig_cts", "clk_null", 1, 1),
> + FACTOR(TOP_CLKPH_MCK, "clkph_mck", "clk_null", 1, 1),
> + FACTOR(TOP_CPUM_TCK_IN, "cpum_tck_in", "clk_null", 1, 1),
> +};
> +
> +static struct mtk_fixed_factor top_divs[] __initdata = {
> + FACTOR(TOP_MAINPLL_806M, "mainpll_806m", "mainpll", 1, 2),
> + FACTOR(TOP_MAINPLL_537P3M, "mainpll_537p3m", "mainpll", 1, 3),
> + FACTOR(TOP_MAINPLL_322P4M, "mainpll_322p4m", "mainpll", 1, 5),
> + FACTOR(TOP_MAINPLL_230P3M, "mainpll_230p3m", "mainpll", 1, 7),
> +
> + FACTOR(TOP_UNIVPLL_624M, "univpll_624m", "univpll", 1, 2),
> + FACTOR(TOP_UNIVPLL_416M, "univpll_416m", "univpll", 1, 3),
> + FACTOR(TOP_UNIVPLL_249P6M, "univpll_249p6m", "univpll", 1, 5),
> + FACTOR(TOP_UNIVPLL_178P3M, "univpll_178p3m", "univpll", 1, 7),
> + FACTOR(TOP_UNIVPLL_48M, "univpll_48m", "univpll", 1, 26),
> +
> + FACTOR(TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2),
> + FACTOR(TOP_MMPLL_D3, "mmpll_d3", "mmpll", 1, 3),
> + FACTOR(TOP_MMPLL_D5, "mmpll_d5", "mmpll", 1, 5),
> + FACTOR(TOP_MMPLL_D7, "mmpll_d7", "mmpll", 1, 7),
> + FACTOR(TOP_MMPLL_D4, "mmpll_d4", "mmpll_d2", 1, 2),
> + FACTOR(TOP_MMPLL_D6, "mmpll_d6", "mmpll_d3", 1, 2),
> +
> + FACTOR(TOP_SYSPLL_D2, "syspll_d2", "mainpll_806m", 1, 1),
> + FACTOR(TOP_SYSPLL_D4, "syspll_d4", "mainpll_806m", 1, 2),
> + FACTOR(TOP_SYSPLL_D6, "syspll_d6", "mainpll_806m", 1, 3),
> + FACTOR(TOP_SYSPLL_D8, "syspll_d8", "mainpll_806m", 1, 4),
> + FACTOR(TOP_SYSPLL_D10, "syspll_d10", "mainpll_806m", 1, 5),
> + FACTOR(TOP_SYSPLL_D12, "syspll_d12", "mainpll_806m", 1, 6),
> + FACTOR(TOP_SYSPLL_D16, "syspll_d16", "mainpll_806m", 1, 8),
> + FACTOR(TOP_SYSPLL_D24, "syspll_d24", "mainpll_806m", 1, 12),
> +
> + FACTOR(TOP_SYSPLL_D3, "syspll_d3", "mainpll_537p3m", 1, 1),
> +
> + FACTOR(TOP_SYSPLL_D2P5, "syspll_d2p5", "mainpll_322p4m", 2, 1),
> + FACTOR(TOP_SYSPLL_D5, "syspll_d5", "mainpll_322p4m", 1, 1),
> +
> + FACTOR(TOP_SYSPLL_D3P5, "syspll_d3p5", "mainpll_230p3m", 2, 1),
> +
> + FACTOR(TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_624m", 1, 2),
> + FACTOR(TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_624m", 1, 4),
> + FACTOR(TOP_UNIVPLL1_D6, "univpll1_d6", "univpll_624m", 1, 6),
> + FACTOR(TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_624m", 1, 8),
> + FACTOR(TOP_UNIVPLL1_D10, "univpll1_d10", "univpll_624m", 1, 10),
> +
> + FACTOR(TOP_UNIVPLL2_D2, "univpll2_d2", "univpll_416m", 1, 2),
> + FACTOR(TOP_UNIVPLL2_D4, "univpll2_d4", "univpll_416m", 1, 4),
> + FACTOR(TOP_UNIVPLL2_D6, "univpll2_d6", "univpll_416m", 1, 6),
> + FACTOR(TOP_UNIVPLL2_D8, "univpll2_d8", "univpll_416m", 1, 8),
> +
> + FACTOR(TOP_UNIVPLL_D3, "univpll_d3", "univpll_416m", 1, 1),
> + FACTOR(TOP_UNIVPLL_D5, "univpll_d5", "univpll_249p6m", 1, 1),
> + FACTOR(TOP_UNIVPLL_D7, "univpll_d7", "univpll_178p3m", 1, 1),
> + FACTOR(TOP_UNIVPLL_D10, "univpll_d10", "univpll_249p6m", 1, 5),
> + FACTOR(TOP_UNIVPLL_D26, "univpll_d26", "univpll_48m", 1, 1),
> +
> + FACTOR(TOP_APLL_CK, "apll_ck", "audpll", 1, 1),
> + FACTOR(TOP_APLL_D4, "apll_d4", "audpll", 1, 4),
> + FACTOR(TOP_APLL_D8, "apll_d8", "audpll", 1, 8),
> + FACTOR(TOP_APLL_D16, "apll_d16", "audpll", 1, 16),
> + FACTOR(TOP_APLL_D24, "apll_d24", "audpll", 1, 24),
> +
> + FACTOR(TOP_LVDSPLL_D2, "lvdspll_d2", "lvdspll", 1, 2),
> + FACTOR(TOP_LVDSPLL_D4, "lvdspll_d4", "lvdspll", 1, 4),
> + FACTOR(TOP_LVDSPLL_D8, "lvdspll_d8", "lvdspll", 1, 8),
> +
> + FACTOR(TOP_LVDSTX_CLKDIG_CT, "lvdstx_clkdig_cts", "lvdspll", 1, 1),
> + FACTOR(TOP_VPLL_DPIX_CK, "vpll_dpix_ck", "lvdspll", 1, 1),
> +
> + FACTOR(TOP_TVHDMI_H_CK, "tvhdmi_h_ck", "tvdpll", 1, 1),
> +
> + FACTOR(TOP_HDMITX_CLKDIG_D2, "hdmitx_clkdig_d2", "hdmitx_clkdig_cts", 1, 2),
> + FACTOR(TOP_HDMITX_CLKDIG_D3, "hdmitx_clkdig_d3", "hdmitx_clkdig_cts", 1, 3),
> +
> + FACTOR(TOP_TVHDMI_D2, "tvhdmi_d2", "tvhdmi_h_ck", 1, 2),
> + FACTOR(TOP_TVHDMI_D4, "tvhdmi_d4", "tvhdmi_h_ck", 1, 4),
> +
> + FACTOR(TOP_MEMPLL_MCK_D4, "mempll_mck_d4", "clkph_mck", 1, 4),
> +};
> +
> +static const char *axi_parents[] __initconst = {
> + "clk26m",
> + "syspll_d3",
> + "syspll_d4",
> + "syspll_d6",
> + "univpll_d5",
> + "univpll2_d2",
> + "syspll_d3p5"
> +};
> +
> +static const char *smi_parents[] __initconst = {
> + "clk26m",
> + "clkph_mck",
> + "syspll_d2p5",
> + "syspll_d3",
> + "syspll_d8",
> + "univpll_d5",
> + "univpll1_d2",
> + "univpll1_d6",
> + "mmpll_d3",
> + "mmpll_d4",
> + "mmpll_d5",
> + "mmpll_d6",
> + "mmpll_d7",
> + "vdecpll",
> + "lvdspll"
> +};
> +
> +static const char *mfg_parents[] __initconst = {
> + "clk26m",
> + "univpll1_d4",
> + "syspll_d2",
> + "syspll_d2p5",
> + "syspll_d3",
> + "univpll_d5",
> + "univpll1_d2",
> + "mmpll_d2",
> + "mmpll_d3",
> + "mmpll_d4",
> + "mmpll_d5",
> + "mmpll_d6",
> + "mmpll_d7"
> +};
> +
> +static const char *irda_parents[] __initconst = {
> + "clk26m",
> + "univpll2_d8",
> + "univpll1_d6"
> +};
> +
> +static const char *cam_parents[] __initconst = {
> + "clk26m",
> + "syspll_d3",
> + "syspll_d3p5",
> + "syspll_d4",
> + "univpll_d5",
> + "univpll2_d2",
> + "univpll_d7",
> + "univpll1_d4"
> +};
> +
> +static const char *aud_intbus_parents[] __initconst = {
> + "clk26m",
> + "syspll_d6",
> + "univpll_d10"
> +};
> +
> +static const char *jpg_parents[] __initconst = {
> + "clk26m",
> + "syspll_d5",
> + "syspll_d4",
> + "syspll_d3",
> + "univpll_d7",
> + "univpll2_d2",
> + "univpll_d5"
> +};
> +
> +static const char *disp_parents[] __initconst = {
> + "clk26m",
> + "syspll_d3p5",
> + "syspll_d3",
> + "univpll2_d2",
> + "univpll_d5",
> + "univpll1_d2",
> + "lvdspll",
> + "vdecpll"
> +};
> +
> +static const char *msdc30_parents[] __initconst = {
> + "clk26m",
> + "syspll_d6",
> + "syspll_d5",
> + "univpll1_d4",
> + "univpll2_d4",
> + "msdcpll"
> +};
> +
> +static const char *usb20_parents[] __initconst = {
> + "clk26m",
> + "univpll2_d6",
> + "univpll1_d10"
> +};
> +
> +static const char *venc_parents[] __initconst = {
> + "clk26m",
> + "syspll_d3",
> + "syspll_d8",
> + "univpll_d5",
> + "univpll1_d6",
> + "mmpll_d4",
> + "mmpll_d5",
> + "mmpll_d6"
> +};
> +
> +static const char *spi_parents[] __initconst = {
> + "clk26m",
> + "syspll_d6",
> + "syspll_d8",
> + "syspll_d10",
> + "univpll1_d6",
> + "univpll1_d8"
> +};
> +
> +static const char *uart_parents[] __initconst = {
> + "clk26m",
> + "univpll2_d8"
> +};
> +
> +static const char *mem_parents[] __initconst = {
> + "clk26m",
> + "clkph_mck"
> +};
> +
> +static const char *camtg_parents[] __initconst = {
> + "clk26m",
> + "univpll_d26",
> + "univpll1_d6",
> + "syspll_d16",
> + "syspll_d8"
> +};
> +
> +static const char *audio_parents[] __initconst = {
> + "clk26m",
> + "syspll_d24"
> +};
> +
> +static const char *fix_parents[] __initconst = {
> + "rtc32k",
> + "clk26m",
> + "univpll_d5",
> + "univpll_d7",
> + "univpll1_d2",
> + "univpll1_d4",
> + "univpll1_d6",
> + "univpll1_d8"
> +};
> +
> +static const char *vdec_parents[] __initconst = {
> + "clk26m",
> + "vdecpll",
> + "clkph_mck",
> + "syspll_d2p5",
> + "syspll_d3",
> + "syspll_d3p5",
> + "syspll_d4",
> + "syspll_d5",
> + "syspll_d6",
> + "syspll_d8",
> + "univpll1_d2",
> + "univpll2_d2",
> + "univpll_d7",
> + "univpll_d10",
> + "univpll2_d4",
> + "lvdspll"
> +};
> +
> +static const char *ddrphycfg_parents[] __initconst = {
> + "clk26m",
> + "axi_sel",
> + "syspll_d12"
> +};
> +
> +static const char *dpilvds_parents[] __initconst = {
> + "clk26m",
> + "lvdspll",
> + "lvdspll_d2",
> + "lvdspll_d4",
> + "lvdspll_d8"
> +};
> +
> +static const char *pmicspi_parents[] __initconst = {
> + "clk26m",
> + "univpll2_d6",
> + "syspll_d8",
> + "syspll_d10",
> + "univpll1_d10",
> + "mempll_mck_d4",
> + "univpll_d26",
> + "syspll_d24"
> +};
> +
> +static const char *smi_mfg_as_parents[] __initconst = {
> + "clk26m",
> + "smi_sel",
> + "mfg_sel",
> + "mem_sel"
> +};
> +
> +static const char *gcpu_parents[] __initconst = {
> + "clk26m",
> + "syspll_d4",
> + "univpll_d7",
> + "syspll_d5",
> + "syspll_d6"
> +};
> +
> +static const char *dpi1_parents[] __initconst = {
> + "clk26m",
> + "tvhdmi_h_ck",
> + "tvhdmi_d2",
> + "tvhdmi_d4"
> +};
> +
> +static const char *cci_parents[] __initconst = {
> + "clk26m",
> + "mainpll_537p3m",
> + "univpll_d3",
> + "syspll_d2p5",
> + "syspll_d3",
> + "syspll_d5"
> +};
> +
> +static const char *apll_parents[] __initconst = {
> + "clk26m",
> + "apll_ck",
> + "apll_d4",
> + "apll_d8",
> + "apll_d16",
> + "apll_d24"
> +};
> +
> +static const char *hdmipll_parents[] __initconst = {
> + "clk26m",
> + "hdmitx_clkdig_cts",
> + "hdmitx_clkdig_d2",
> + "hdmitx_clkdig_d3"
> +};
> +
> +static struct mtk_composite top_muxes[] __initdata = {
> + /* CLK_CFG_0 */
> + MUX_GATE(TOP_AXI_SEL, "axi_sel", axi_parents,
> + 0x0140, 0, 3, INVALID_MUX_GATE_BIT),
> + MUX_GATE(TOP_SMI_SEL, "smi_sel", smi_parents, 0x0140, 8, 4, 15),
> + MUX_GATE(TOP_MFG_SEL, "mfg_sel", mfg_parents, 0x0140, 16, 4, 23),
> + MUX_GATE(TOP_IRDA_SEL, "irda_sel", irda_parents, 0x0140, 24, 2, 31),
> + /* CLK_CFG_1 */
> + MUX_GATE(TOP_CAM_SEL, "cam_sel", cam_parents, 0x0144, 0, 3, 7),
> + MUX_GATE(TOP_AUD_INTBUS_SEL, "aud_intbus_sel", aud_intbus_parents,
> + 0x0144, 8, 2, 15),
> + MUX_GATE(TOP_JPG_SEL, "jpg_sel", jpg_parents, 0x0144, 16, 3, 23),
> + MUX_GATE(TOP_DISP_SEL, "disp_sel", disp_parents, 0x0144, 24, 3, 31),
> + /* CLK_CFG_2 */
> + MUX_GATE(TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_parents, 0x0148, 0, 3, 7),
> + MUX_GATE(TOP_MSDC30_2_SEL, "msdc30_2_sel", msdc30_parents, 0x0148, 8, 3, 15),
> + MUX_GATE(TOP_MSDC30_3_SEL, "msdc30_3_sel", msdc30_parents, 0x0148, 16, 3, 23),
> + MUX_GATE(TOP_MSDC30_4_SEL, "msdc30_4_sel", msdc30_parents, 0x0148, 24, 3, 31),
> + /* CLK_CFG_3 */
> + MUX_GATE(TOP_USB20_SEL, "usb20_sel", usb20_parents, 0x014c, 0, 2, 7),
> + /* CLK_CFG_4 */
> + MUX_GATE(TOP_VENC_SEL, "venc_sel", venc_parents, 0x0150, 8, 3, 15),
> + MUX_GATE(TOP_SPI_SEL, "spi_sel", spi_parents, 0x0150, 16, 3, 23),
> + MUX_GATE(TOP_UART_SEL, "uart_sel", uart_parents, 0x0150, 24, 2, 31),
> + /* CLK_CFG_6 */
> + MUX_GATE(TOP_MEM_SEL, "mem_sel", mem_parents, 0x0158, 0, 2, 7),
> + MUX_GATE(TOP_CAMTG_SEL, "camtg_sel", camtg_parents, 0x0158, 8, 3, 15),
> + MUX_GATE(TOP_AUDIO_SEL, "audio_sel", audio_parents, 0x0158, 24, 2, 31),
> + /* CLK_CFG_7 */
> + MUX_GATE(TOP_FIX_SEL, "fix_sel", fix_parents, 0x015c, 0, 3, 7),
> + MUX_GATE(TOP_VDEC_SEL, "vdec_sel", vdec_parents, 0x015c, 8, 4, 15),
> + MUX_GATE(TOP_DDRPHYCFG_SEL, "ddrphycfg_sel", ddrphycfg_parents,
> + 0x015c, 16, 2, 23),
> + MUX_GATE(TOP_DPILVDS_SEL, "dpilvds_sel", dpilvds_parents, 0x015c, 24, 3, 31),
> + /* CLK_CFG_8 */
> + MUX_GATE(TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents, 0x0164, 0, 3, 7),
> + MUX_GATE(TOP_MSDC30_0_SEL, "msdc30_0_sel", msdc30_parents, 0x0164, 8, 3, 15),
> + MUX_GATE(TOP_SMI_MFG_AS_SEL, "smi_mfg_as_sel", smi_mfg_as_parents,
> + 0x0164, 16, 2, 23),
> + MUX_GATE(TOP_GCPU_SEL, "gcpu_sel", gcpu_parents, 0x0164, 24, 3, 31),
> + /* CLK_CFG_9 */
> + MUX_GATE(TOP_DPI1_SEL, "dpi1_sel", dpi1_parents, 0x0168, 0, 2, 7),
> + MUX_GATE(TOP_CCI_SEL, "cci_sel", cci_parents, 0x0168, 8, 3, 15),
> + MUX_GATE(TOP_APLL_SEL, "apll_sel", apll_parents, 0x0168, 16, 3, 23),
> + MUX_GATE(TOP_HDMIPLL_SEL, "hdmipll_sel", hdmipll_parents, 0x0168, 24, 2, 31),
> +};
> +
> +static void __init mtk_init_clk_topckgen(void __iomem *top_base,
> + struct clk_onecell_data *clk_data)
> +{
> + int i;
> + struct clk *clk;
> +
> + for (i = 0; i < ARRAY_SIZE(top_muxes); i++) {
> + struct mtk_composite *mux = &top_muxes[i];
> +
> + clk = mtk_clk_register_composite(mux, top_base, &lock);
> +
> + if (IS_ERR(clk)) {
> + pr_err("Failed to register clk %s: %ld\n",
> + mux->name, PTR_ERR(clk));
> + continue;
> + }
> +
> + if (clk_data)
> + clk_data->clks[mux->id] = clk;
> + }
> +}
> +
> +static struct mtk_gate_regs infra_cg_regs = {
> + .set_ofs = 0x0040,
> + .clr_ofs = 0x0044,
> + .sta_ofs = 0x0048,
> +};
> +
> +#define GATE_ICG(_id, _name, _parent, _shift) { \
> + .id = _id, \
> + .name = _name, \
> + .parent_name = _parent, \
> + .regs = &infra_cg_regs, \
> + .shift = _shift, \
> + .ops = &mtk_clk_gate_ops_setclr, \
> + }
> +
> +static struct mtk_gate infra_clks[] __initdata = {
> + GATE_ICG(INFRA_PMIC_WRAP_CK, "pmic_wrap_ck", "axi_sel", 23),
> + GATE_ICG(INFRA_PMICSPI_CK, "pmicspi_ck", "pmicspi_sel", 22),
> + GATE_ICG(INFRA_CCIF1_AP_CTRL, "ccif1_ap_ctrl", "axi_sel", 21),
> + GATE_ICG(INFRA_CCIF0_AP_CTRL, "ccif0_ap_ctrl", "axi_sel", 20),
> + GATE_ICG(INFRA_KP_CK, "kp_ck", "axi_sel", 16),
> + GATE_ICG(INFRA_CPUM_CK, "cpum_ck", "cpum_tck_in", 15),
> + GATE_ICG(INFRA_M4U_CK, "m4u_ck", "mem_sel", 8),
> + GATE_ICG(INFRA_MFGAXI_CK, "mfgaxi_ck", "axi_sel", 7),
> + GATE_ICG(INFRA_DEVAPC_CK, "devapc_ck", "axi_sel", 6),
> + GATE_ICG(INFRA_AUDIO_CK, "audio_ck", "aud_intbus_sel", 5),
> + GATE_ICG(INFRA_MFG_BUS_CK, "mfg_bus_ck", "axi_sel", 2),
> + GATE_ICG(INFRA_SMI_CK, "smi_ck", "smi_sel", 1),
> + GATE_ICG(INFRA_DBGCLK_CK, "dbgclk_ck", "axi_sel", 0),
> +};
> +
> +static struct mtk_gate_regs peri0_cg_regs = {
> + .set_ofs = 0x0008,
> + .clr_ofs = 0x0010,
> + .sta_ofs = 0x0018,
> +};
> +
> +static struct mtk_gate_regs peri1_cg_regs = {
> + .set_ofs = 0x000c,
> + .clr_ofs = 0x0014,
> + .sta_ofs = 0x001c,
> +};
> +
> +#define GATE_PERI0(_id, _name, _parent, _shift) { \
> + .id = _id, \
> + .name = _name, \
> + .parent_name = _parent, \
> + .regs = &peri0_cg_regs, \
> + .shift = _shift, \
> + .ops = &mtk_clk_gate_ops_setclr, \
> + }
> +
> +#define GATE_PERI1(_id, _name, _parent, _shift) { \
> + .id = _id, \
> + .name = _name, \
> + .parent_name = _parent, \
> + .regs = &peri1_cg_regs, \
> + .shift = _shift, \
> + .ops = &mtk_clk_gate_ops_setclr, \
> + }
> +
> +static struct mtk_gate peri_clks[] __initdata = {
> + /* PERI0 */
> + GATE_PERI0(PERI_I2C5_CK, "i2c5_ck", "axi_sel", 31),
> + GATE_PERI0(PERI_I2C4_CK, "i2c4_ck", "axi_sel", 30),
> + GATE_PERI0(PERI_I2C3_CK, "i2c3_ck", "axi_sel", 29),
> + GATE_PERI0(PERI_I2C2_CK, "i2c2_ck", "axi_sel", 28),
> + GATE_PERI0(PERI_I2C1_CK, "i2c1_ck", "axi_sel", 27),
> + GATE_PERI0(PERI_I2C0_CK, "i2c0_ck", "axi_sel", 26),
> + GATE_PERI0(PERI_UART3_CK, "uart3_ck", "axi_sel", 25),
> + GATE_PERI0(PERI_UART2_CK, "uart2_ck", "axi_sel", 24),
> + GATE_PERI0(PERI_UART1_CK, "uart1_ck", "axi_sel", 23),
> + GATE_PERI0(PERI_UART0_CK, "uart0_ck", "axi_sel", 22),
> + GATE_PERI0(PERI_IRDA_CK, "irda_ck", "irda_sel", 21),
> + GATE_PERI0(PERI_NLI_CK, "nli_ck", "axi_sel", 20),
> + GATE_PERI0(PERI_MD_HIF_CK, "md_hif_ck", "axi_sel", 19),
> + GATE_PERI0(PERI_AP_HIF_CK, "ap_hif_ck", "axi_sel", 18),
> + GATE_PERI0(PERI_MSDC30_3_CK, "msdc30_3_ck", "msdc30_4_sel", 17),
> + GATE_PERI0(PERI_MSDC30_2_CK, "msdc30_2_ck", "msdc30_3_sel", 16),
> + GATE_PERI0(PERI_MSDC30_1_CK, "msdc30_1_ck", "msdc30_2_sel", 15),
> + GATE_PERI0(PERI_MSDC20_2_CK, "msdc20_2_ck", "msdc30_1_sel", 14),
> + GATE_PERI0(PERI_MSDC20_1_CK, "msdc20_1_ck", "msdc30_0_sel", 13),
> + GATE_PERI0(PERI_AP_DMA_CK, "ap_dma_ck", "axi_sel", 12),
> + GATE_PERI0(PERI_USB1_CK, "usb1_ck", "usb20_sel", 11),
> + GATE_PERI0(PERI_USB0_CK, "usb0_ck", "usb20_sel", 10),
> + GATE_PERI0(PERI_PWM_CK, "pwm_ck", "axi_sel", 9),
> + GATE_PERI0(PERI_PWM7_CK, "pwm7_ck", "axi_sel", 8),
> + GATE_PERI0(PERI_PWM6_CK, "pwm6_ck", "axi_sel", 7),
> + GATE_PERI0(PERI_PWM5_CK, "pwm5_ck", "axi_sel", 6),
> + GATE_PERI0(PERI_PWM4_CK, "pwm4_ck", "axi_sel", 5),
> + GATE_PERI0(PERI_PWM3_CK, "pwm3_ck", "axi_sel", 4),
> + GATE_PERI0(PERI_PWM2_CK, "pwm2_ck", "axi_sel", 3),
> + GATE_PERI0(PERI_PWM1_CK, "pwm1_ck", "axi_sel", 2),
> + GATE_PERI0(PERI_THERM_CK, "therm_ck", "axi_sel", 1),
> + GATE_PERI0(PERI_NFI_CK, "nfi_ck", "axi_sel", 0),
> + /* PERI1 */
> + GATE_PERI1(PERI_USBSLV_CK, "usbslv_ck", "axi_sel", 8),
> + GATE_PERI1(PERI_USB1_MCU_CK, "usb1_mcu_ck", "axi_sel", 7),
> + GATE_PERI1(PERI_USB0_MCU_CK, "usb0_mcu_ck", "axi_sel", 6),
> + GATE_PERI1(PERI_GCPU_CK, "gcpu_ck", "gcpu_sel", 5),
> + GATE_PERI1(PERI_FHCTL_CK, "fhctl_ck", "clk26m", 4),
> + GATE_PERI1(PERI_SPI1_CK, "spi1_ck", "spi_sel", 3),
> + GATE_PERI1(PERI_AUXADC_CK, "auxadc_ck", "clk26m", 2),
> + GATE_PERI1(PERI_PERI_PWRAP_CK, "peri_pwrap_ck", "axi_sel", 1),
> + GATE_PERI1(PERI_I2C6_CK, "i2c6_ck", "axi_sel", 0),
> +};
> +
> +static void __init mtk_topckgen_init(struct device_node *node)
> +{
> + struct clk_onecell_data *clk_data;
> + void __iomem *base;
> + int r;
> +
> + base = of_iomap(node, 0);
> + if (!base) {
> + pr_err("%s(): ioremap failed\n", __func__);
> + return;
> + }
> +
> + clk_data = mtk_alloc_clk_data(TOP_NR_CLK);
> +
> + mtk_clk_register_factors(root_clk_alias, ARRAY_SIZE(root_clk_alias), clk_data);
> + mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
> + mtk_init_clk_topckgen(base, clk_data);
> +
> + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> + if (r)
> + pr_err("%s(): could not register clock provider: %d\n",
> + __func__, r);
> +}
> +CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt8135-topckgen", mtk_topckgen_init);
> +
> +static void __init mtk_infrasys_init(struct device_node *node)
> +{
> + struct clk_onecell_data *clk_data;
> + int r;
> +
> + clk_data = mtk_alloc_clk_data(INFRA_NR_CLK);
> +
> + mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
> + clk_data);
> +
> + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> + if (r)
> + pr_err("%s(): could not register clock provider: %d\n",
> + __func__, r);
> +
> + mtk_register_reset_controller(node, 2, 0x30);
> +}
> +CLK_OF_DECLARE(mtk_infrasys, "mediatek,mt8135-infracfg", mtk_infrasys_init);
> +
> +static void __init mtk_pericfg_init(struct device_node *node)
> +{
> + struct clk_onecell_data *clk_data;
> + int r;
> +
> + clk_data = mtk_alloc_clk_data(PERI_NR_CLK);
> +
> + mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
> + clk_data);
> +
> + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> + if (r)
> + pr_err("%s(): could not register clock provider: %d\n",
> + __func__, r);
> +
> + mtk_register_reset_controller(node, 2, 0);
> +}
> +CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt8135-pericfg", mtk_pericfg_init);
> +
> +#define MT8135_PLL_FMAX (2000 * MHZ)
> +#define CON0_MT8135_RST_BAR BIT(27)
> +
> +#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) { \
> + .id = _id, \
> + .name = _name, \
> + .reg = _reg, \
> + .pwr_reg = _pwr_reg, \
> + .en_mask = _en_mask, \
> + .flags = _flags, \
> + .rst_bar_mask = CON0_MT8135_RST_BAR, \
> + .fmax = MT8135_PLL_FMAX, \
> + .pcwbits = _pcwbits, \
> + .pd_reg = _pd_reg, \
> + .pd_shift = _pd_shift, \
> + .tuner_reg = _tuner_reg, \
> + .pcw_reg = _pcw_reg, \
> + .pcw_shift = _pcw_shift, \
> + }
> +
> +static struct mtk_pll_data plls[] = {
> + PLL(APMIXED_ARMPLL1, "armpll1", 0x200, 0x218, 0x80000001, 0, 21, 0x204, 24, 0x0, 0x204, 0),
> + PLL(APMIXED_ARMPLL2, "armpll2", 0x2cc, 0x2e4, 0x80000001, 0, 21, 0x2d0, 24, 0x0, 0x2d0, 0),
> + PLL(APMIXED_MAINPLL, "mainpll", 0x21c, 0x234, 0xf0000001, HAVE_RST_BAR, 21, 0x21c, 6, 0x0, 0x220, 0),
> + PLL(APMIXED_UNIVPLL, "univpll", 0x238, 0x250, 0xf3000001, HAVE_RST_BAR, 7, 0x238, 6, 0x0, 0x238, 9),
> + PLL(APMIXED_MMPLL, "mmpll", 0x254, 0x26c, 0xf0000001, HAVE_RST_BAR, 21, 0x254, 6, 0x0, 0x258, 0),
> + PLL(APMIXED_MSDCPLL, "msdcpll", 0x278, 0x290, 0x80000001, 0, 21, 0x278, 6, 0x0, 0x27c, 0),
> + PLL(APMIXED_TVDPLL, "tvdpll", 0x294, 0x2ac, 0x80000001, 0, 31, 0x296, 6, 0x0, 0x298, 0),
> + PLL(APMIXED_LVDSPLL, "lvdspll", 0x2b0, 0x2c8, 0x80000001, 0, 21, 0x2b0, 6, 0x0, 0x2b4, 0),
> + PLL(APMIXED_AUDPLL, "audpll", 0x2e8, 0x300, 0x80000001, 0, 31, 0x2e8, 6, 0x2f8, 0x2ec, 0),
> + PLL(APMIXED_VDECPLL, "vdecpll", 0x304, 0x31c, 0x80000001, 0, 21, 0x2b0, 6, 0x0, 0x308, 0),
> +};
> +
> +static void __init mtk_apmixedsys_init(struct device_node *node)
> +{
> + mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls));
> +}
> +CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt8135-apmixedsys",
> + mtk_apmixedsys_init);
> diff --git a/include/dt-bindings/clock/mt8135-clk.h b/include/dt-bindings/clock/mt8135-clk.h
> new file mode 100644
> index 0000000..8aea762
> --- /dev/null
> +++ b/include/dt-bindings/clock/mt8135-clk.h
> @@ -0,0 +1,190 @@
> +/*
> + * Copyright (c) 2014 MediaTek Inc.
> + * Author: James Liao <jamesjj.liao@mediatek.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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 _DT_BINDINGS_CLK_MT8135_H
> +#define _DT_BINDINGS_CLK_MT8135_H
> +
> +/* TOPCKGEN */
> +
> +#define TOP_DSI0_LNTC_DSICLK 1
> +#define TOP_HDMITX_CLKDIG_CTS 2
> +#define TOP_CLKPH_MCK 3
> +#define TOP_CPUM_TCK_IN 4
> +#define TOP_MAINPLL_806M 5
> +#define TOP_MAINPLL_537P3M 6
> +#define TOP_MAINPLL_322P4M 7
> +#define TOP_MAINPLL_230P3M 8
> +#define TOP_UNIVPLL_624M 9
> +#define TOP_UNIVPLL_416M 10
> +#define TOP_UNIVPLL_249P6M 11
> +#define TOP_UNIVPLL_178P3M 12
> +#define TOP_UNIVPLL_48M 13
> +#define TOP_MMPLL_D2 14
> +#define TOP_MMPLL_D3 15
> +#define TOP_MMPLL_D5 16
> +#define TOP_MMPLL_D7 17
> +#define TOP_MMPLL_D4 18
> +#define TOP_MMPLL_D6 19
> +#define TOP_SYSPLL_D2 20
> +#define TOP_SYSPLL_D4 21
> +#define TOP_SYSPLL_D6 22
> +#define TOP_SYSPLL_D8 23
> +#define TOP_SYSPLL_D10 24
> +#define TOP_SYSPLL_D12 25
> +#define TOP_SYSPLL_D16 26
> +#define TOP_SYSPLL_D24 27
> +#define TOP_SYSPLL_D3 28
> +#define TOP_SYSPLL_D2P5 29
> +#define TOP_SYSPLL_D5 30
> +#define TOP_SYSPLL_D3P5 31
> +#define TOP_UNIVPLL1_D2 32
> +#define TOP_UNIVPLL1_D4 33
> +#define TOP_UNIVPLL1_D6 34
> +#define TOP_UNIVPLL1_D8 35
> +#define TOP_UNIVPLL1_D10 36
> +#define TOP_UNIVPLL2_D2 37
> +#define TOP_UNIVPLL2_D4 38
> +#define TOP_UNIVPLL2_D6 39
> +#define TOP_UNIVPLL2_D8 40
> +#define TOP_UNIVPLL_D3 41
> +#define TOP_UNIVPLL_D5 42
> +#define TOP_UNIVPLL_D7 43
> +#define TOP_UNIVPLL_D10 44
> +#define TOP_UNIVPLL_D26 45
> +#define TOP_APLL_CK 46
> +#define TOP_APLL_D4 47
> +#define TOP_APLL_D8 48
> +#define TOP_APLL_D16 49
> +#define TOP_APLL_D24 50
> +#define TOP_LVDSPLL_D2 51
> +#define TOP_LVDSPLL_D4 52
> +#define TOP_LVDSPLL_D8 53
> +#define TOP_LVDSTX_CLKDIG_CT 54
> +#define TOP_VPLL_DPIX_CK 55
> +#define TOP_TVHDMI_H_CK 56
> +#define TOP_HDMITX_CLKDIG_D2 57
> +#define TOP_HDMITX_CLKDIG_D3 58
> +#define TOP_TVHDMI_D2 59
> +#define TOP_TVHDMI_D4 60
> +#define TOP_MEMPLL_MCK_D4 61
> +#define TOP_AXI_SEL 62
> +#define TOP_SMI_SEL 63
> +#define TOP_MFG_SEL 64
> +#define TOP_IRDA_SEL 65
> +#define TOP_CAM_SEL 66
> +#define TOP_AUD_INTBUS_SEL 67
> +#define TOP_JPG_SEL 68
> +#define TOP_DISP_SEL 69
> +#define TOP_MSDC30_1_SEL 70
> +#define TOP_MSDC30_2_SEL 71
> +#define TOP_MSDC30_3_SEL 72
> +#define TOP_MSDC30_4_SEL 73
> +#define TOP_USB20_SEL 74
> +#define TOP_VENC_SEL 75
> +#define TOP_SPI_SEL 76
> +#define TOP_UART_SEL 77
> +#define TOP_MEM_SEL 78
> +#define TOP_CAMTG_SEL 79
> +#define TOP_AUDIO_SEL 80
> +#define TOP_FIX_SEL 81
> +#define TOP_VDEC_SEL 82
> +#define TOP_DDRPHYCFG_SEL 83
> +#define TOP_DPILVDS_SEL 84
> +#define TOP_PMICSPI_SEL 85
> +#define TOP_MSDC30_0_SEL 86
> +#define TOP_SMI_MFG_AS_SEL 87
> +#define TOP_GCPU_SEL 88
> +#define TOP_DPI1_SEL 89
> +#define TOP_CCI_SEL 90
> +#define TOP_APLL_SEL 91
> +#define TOP_HDMIPLL_SEL 92
> +#define TOP_NR_CLK 93
> +
> +/* APMIXED_SYS */
> +
> +#define APMIXED_ARMPLL1 1
> +#define APMIXED_ARMPLL2 2
> +#define APMIXED_MAINPLL 3
> +#define APMIXED_UNIVPLL 4
> +#define APMIXED_MMPLL 5
> +#define APMIXED_MSDCPLL 6
> +#define APMIXED_TVDPLL 7
> +#define APMIXED_LVDSPLL 8
> +#define APMIXED_AUDPLL 9
> +#define APMIXED_VDECPLL 10
> +#define APMIXED_NR_CLK 11
> +
> +/* INFRA_SYS */
> +
> +#define INFRA_PMIC_WRAP_CK 1
> +#define INFRA_PMICSPI_CK 2
> +#define INFRA_CCIF1_AP_CTRL 3
> +#define INFRA_CCIF0_AP_CTRL 4
> +#define INFRA_KP_CK 5
> +#define INFRA_CPUM_CK 6
> +#define INFRA_M4U_CK 7
> +#define INFRA_MFGAXI_CK 8
> +#define INFRA_DEVAPC_CK 9
> +#define INFRA_AUDIO_CK 10
> +#define INFRA_MFG_BUS_CK 11
> +#define INFRA_SMI_CK 12
> +#define INFRA_DBGCLK_CK 13
> +#define INFRA_NR_CLK 14
> +
> +/* PERI_SYS */
> +
> +#define PERI_I2C5_CK 1
> +#define PERI_I2C4_CK 2
> +#define PERI_I2C3_CK 3
> +#define PERI_I2C2_CK 4
> +#define PERI_I2C1_CK 5
> +#define PERI_I2C0_CK 6
> +#define PERI_UART3_CK 7
> +#define PERI_UART2_CK 8
> +#define PERI_UART1_CK 9
> +#define PERI_UART0_CK 10
> +#define PERI_IRDA_CK 11
> +#define PERI_NLI_CK 12
> +#define PERI_MD_HIF_CK 13
> +#define PERI_AP_HIF_CK 14
> +#define PERI_MSDC30_3_CK 15
> +#define PERI_MSDC30_2_CK 16
> +#define PERI_MSDC30_1_CK 17
> +#define PERI_MSDC20_2_CK 18
> +#define PERI_MSDC20_1_CK 19
> +#define PERI_AP_DMA_CK 20
> +#define PERI_USB1_CK 21
> +#define PERI_USB0_CK 22
> +#define PERI_PWM_CK 23
> +#define PERI_PWM7_CK 24
> +#define PERI_PWM6_CK 25
> +#define PERI_PWM5_CK 26
> +#define PERI_PWM4_CK 27
> +#define PERI_PWM3_CK 28
> +#define PERI_PWM2_CK 29
> +#define PERI_PWM1_CK 30
> +#define PERI_THERM_CK 31
> +#define PERI_NFI_CK 32
> +#define PERI_USBSLV_CK 33
> +#define PERI_USB1_MCU_CK 34
> +#define PERI_USB0_MCU_CK 35
> +#define PERI_GCPU_CK 36
> +#define PERI_FHCTL_CK 37
> +#define PERI_SPI1_CK 38
> +#define PERI_AUXADC_CK 39
> +#define PERI_PERI_PWRAP_CK 40
> +#define PERI_I2C6_CK 41
> +#define PERI_NR_CLK 42
> +
> +#endif /* _DT_BINDINGS_CLK_MT8135_H */
> diff --git a/include/dt-bindings/reset-controller/mt8135-resets.h b/include/dt-bindings/reset-controller/mt8135-resets.h
> new file mode 100644
> index 0000000..1fb6295
> --- /dev/null
> +++ b/include/dt-bindings/reset-controller/mt8135-resets.h
> @@ -0,0 +1,64 @@
> +/*
> + * Copyright (c) 2014 MediaTek Inc.
> + * Author: Flora Fu, MediaTek
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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 _DT_BINDINGS_RESET_CONTROLLER_MT8135
> +#define _DT_BINDINGS_RESET_CONTROLLER_MT8135
> +
> +/* INFRACFG resets */
> +#define MT8135_INFRA_EMI_REG_RST 0
> +#define MT8135_INFRA_DRAMC0_A0_RST 1
> +#define MT8135_INFRA_CCIF0_RST 2
> +#define MT8135_INFRA_APCIRQ_EINT_RST 3
> +#define MT8135_INFRA_APXGPT_RST 4
> +#define MT8135_INFRA_SCPSYS_RST 5
> +#define MT8135_INFRA_CCIF1_RST 6
> +#define MT8135_INFRA_PMIC_WRAP_RST 7
> +#define MT8135_INFRA_KP_RST 8
> +#define MT8135_INFRA_EMI_RST 32
> +#define MT8135_INFRA_DRAMC0_RST 34
> +#define MT8135_INFRA_SMI_RST 35
> +#define MT8135_INFRA_M4U_RST 36
> +
> +/* PERICFG resets */
> +#define MT8135_PERI_UART0_SW_RST 0
> +#define MT8135_PERI_UART1_SW_RST 1
> +#define MT8135_PERI_UART2_SW_RST 2
> +#define MT8135_PERI_UART3_SW_RST 3
> +#define MT8135_PERI_IRDA_SW_RST 4
> +#define MT8135_PERI_PTP_SW_RST 5
> +#define MT8135_PERI_AP_HIF_SW_RST 6
> +#define MT8135_PERI_GPCU_SW_RST 7
> +#define MT8135_PERI_MD_HIF_SW_RST 8
> +#define MT8135_PERI_NLI_SW_RST 9
> +#define MT8135_PERI_AUXADC_SW_RST 10
> +#define MT8135_PERI_DMA_SW_RST 11
> +#define MT8135_PERI_NFI_SW_RST 14
> +#define MT8135_PERI_PWM_SW_RST 15
> +#define MT8135_PERI_THERM_SW_RST 16
> +#define MT8135_PERI_MSDC0_SW_RST 17
> +#define MT8135_PERI_MSDC1_SW_RST 18
> +#define MT8135_PERI_MSDC2_SW_RST 19
> +#define MT8135_PERI_MSDC3_SW_RST 20
> +#define MT8135_PERI_I2C0_SW_RST 22
> +#define MT8135_PERI_I2C1_SW_RST 23
> +#define MT8135_PERI_I2C2_SW_RST 24
> +#define MT8135_PERI_I2C3_SW_RST 25
> +#define MT8135_PERI_I2C4_SW_RST 26
> +#define MT8135_PERI_I2C5_SW_RST 27
> +#define MT8135_PERI_I2C6_SW_RST 28
> +#define MT8135_PERI_USB_SW_RST 29
> +#define MT8135_PERI_SPI1_SW_RST 33
> +#define MT8135_PERI_PWRAP_BRIDGE_SW_RST 34
> +
> +#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT8135 */
> --
> 2.1.4
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 3/5] clk: mediatek: Add basic clocks for Mediatek MT8135.
@ 2015-03-15 16:27 ` Daniel Kurtz
0 siblings, 0 replies; 30+ messages in thread
From: Daniel Kurtz @ 2015-03-15 16:27 UTC (permalink / raw)
To: linux-arm-kernel
Hi Sascha,
Drive-by review...
On Sun, Feb 22, 2015 at 7:49 PM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> From: James Liao <jamesjj.liao@mediatek.com>
>
> This patch adds basic clocks for MT8135, including TOPCKGEN, PLLs,
> INFRA and PERI clocks.
>
> Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
> Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
> drivers/clk/mediatek/Makefile | 1 +
> drivers/clk/mediatek/clk-mt8135.c | 634 +++++++++++++++++++++
> include/dt-bindings/clock/mt8135-clk.h | 190 ++++++
> .../dt-bindings/reset-controller/mt8135-resets.h | 64 +++
> 4 files changed, 889 insertions(+)
> create mode 100644 drivers/clk/mediatek/clk-mt8135.c
> create mode 100644 include/dt-bindings/clock/mt8135-clk.h
> create mode 100644 include/dt-bindings/reset-controller/mt8135-resets.h
>
> diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
> index 0b6f1c3..12ce576 100644
> --- a/drivers/clk/mediatek/Makefile
> +++ b/drivers/clk/mediatek/Makefile
> @@ -1,2 +1,3 @@
> obj-y += clk-mtk.o clk-pll.o clk-gate.o
> obj-$(CONFIG_RESET_CONTROLLER) += reset.o
> +obj-y += clk-mt8135.o
> diff --git a/drivers/clk/mediatek/clk-mt8135.c b/drivers/clk/mediatek/clk-mt8135.c
> new file mode 100644
> index 0000000..6157447
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-mt8135.c
> @@ -0,0 +1,634 @@
> +/*
> + * Copyright (c) 2014 MediaTek Inc.
> + * Author: James Liao <jamesjj.liao@mediatek.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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/of.h>
> +#include <linux/of_address.h>
> +#include <linux/slab.h>
> +#include <linux/mfd/syscon.h>
> +#include <dt-bindings/clock/mt8135-clk.h>
> +
> +#include "clk-mtk.h"
> +#include "clk-gate.h"
> +
> +static DEFINE_SPINLOCK(lock);
> +
> +static struct mtk_fixed_factor root_clk_alias[] __initdata = {
Any reason you can't use "static const" here, and on all of the other
static constant structures/arrays throughout this patch.
Thanks,
-Dan
> + FACTOR(TOP_DSI0_LNTC_DSICLK, "dsi0_lntc_dsiclk", "clk_null", 1, 1),
> + FACTOR(TOP_HDMITX_CLKDIG_CTS, "hdmitx_clkdig_cts", "clk_null", 1, 1),
> + FACTOR(TOP_CLKPH_MCK, "clkph_mck", "clk_null", 1, 1),
> + FACTOR(TOP_CPUM_TCK_IN, "cpum_tck_in", "clk_null", 1, 1),
> +};
> +
> +static struct mtk_fixed_factor top_divs[] __initdata = {
> + FACTOR(TOP_MAINPLL_806M, "mainpll_806m", "mainpll", 1, 2),
> + FACTOR(TOP_MAINPLL_537P3M, "mainpll_537p3m", "mainpll", 1, 3),
> + FACTOR(TOP_MAINPLL_322P4M, "mainpll_322p4m", "mainpll", 1, 5),
> + FACTOR(TOP_MAINPLL_230P3M, "mainpll_230p3m", "mainpll", 1, 7),
> +
> + FACTOR(TOP_UNIVPLL_624M, "univpll_624m", "univpll", 1, 2),
> + FACTOR(TOP_UNIVPLL_416M, "univpll_416m", "univpll", 1, 3),
> + FACTOR(TOP_UNIVPLL_249P6M, "univpll_249p6m", "univpll", 1, 5),
> + FACTOR(TOP_UNIVPLL_178P3M, "univpll_178p3m", "univpll", 1, 7),
> + FACTOR(TOP_UNIVPLL_48M, "univpll_48m", "univpll", 1, 26),
> +
> + FACTOR(TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2),
> + FACTOR(TOP_MMPLL_D3, "mmpll_d3", "mmpll", 1, 3),
> + FACTOR(TOP_MMPLL_D5, "mmpll_d5", "mmpll", 1, 5),
> + FACTOR(TOP_MMPLL_D7, "mmpll_d7", "mmpll", 1, 7),
> + FACTOR(TOP_MMPLL_D4, "mmpll_d4", "mmpll_d2", 1, 2),
> + FACTOR(TOP_MMPLL_D6, "mmpll_d6", "mmpll_d3", 1, 2),
> +
> + FACTOR(TOP_SYSPLL_D2, "syspll_d2", "mainpll_806m", 1, 1),
> + FACTOR(TOP_SYSPLL_D4, "syspll_d4", "mainpll_806m", 1, 2),
> + FACTOR(TOP_SYSPLL_D6, "syspll_d6", "mainpll_806m", 1, 3),
> + FACTOR(TOP_SYSPLL_D8, "syspll_d8", "mainpll_806m", 1, 4),
> + FACTOR(TOP_SYSPLL_D10, "syspll_d10", "mainpll_806m", 1, 5),
> + FACTOR(TOP_SYSPLL_D12, "syspll_d12", "mainpll_806m", 1, 6),
> + FACTOR(TOP_SYSPLL_D16, "syspll_d16", "mainpll_806m", 1, 8),
> + FACTOR(TOP_SYSPLL_D24, "syspll_d24", "mainpll_806m", 1, 12),
> +
> + FACTOR(TOP_SYSPLL_D3, "syspll_d3", "mainpll_537p3m", 1, 1),
> +
> + FACTOR(TOP_SYSPLL_D2P5, "syspll_d2p5", "mainpll_322p4m", 2, 1),
> + FACTOR(TOP_SYSPLL_D5, "syspll_d5", "mainpll_322p4m", 1, 1),
> +
> + FACTOR(TOP_SYSPLL_D3P5, "syspll_d3p5", "mainpll_230p3m", 2, 1),
> +
> + FACTOR(TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_624m", 1, 2),
> + FACTOR(TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_624m", 1, 4),
> + FACTOR(TOP_UNIVPLL1_D6, "univpll1_d6", "univpll_624m", 1, 6),
> + FACTOR(TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_624m", 1, 8),
> + FACTOR(TOP_UNIVPLL1_D10, "univpll1_d10", "univpll_624m", 1, 10),
> +
> + FACTOR(TOP_UNIVPLL2_D2, "univpll2_d2", "univpll_416m", 1, 2),
> + FACTOR(TOP_UNIVPLL2_D4, "univpll2_d4", "univpll_416m", 1, 4),
> + FACTOR(TOP_UNIVPLL2_D6, "univpll2_d6", "univpll_416m", 1, 6),
> + FACTOR(TOP_UNIVPLL2_D8, "univpll2_d8", "univpll_416m", 1, 8),
> +
> + FACTOR(TOP_UNIVPLL_D3, "univpll_d3", "univpll_416m", 1, 1),
> + FACTOR(TOP_UNIVPLL_D5, "univpll_d5", "univpll_249p6m", 1, 1),
> + FACTOR(TOP_UNIVPLL_D7, "univpll_d7", "univpll_178p3m", 1, 1),
> + FACTOR(TOP_UNIVPLL_D10, "univpll_d10", "univpll_249p6m", 1, 5),
> + FACTOR(TOP_UNIVPLL_D26, "univpll_d26", "univpll_48m", 1, 1),
> +
> + FACTOR(TOP_APLL_CK, "apll_ck", "audpll", 1, 1),
> + FACTOR(TOP_APLL_D4, "apll_d4", "audpll", 1, 4),
> + FACTOR(TOP_APLL_D8, "apll_d8", "audpll", 1, 8),
> + FACTOR(TOP_APLL_D16, "apll_d16", "audpll", 1, 16),
> + FACTOR(TOP_APLL_D24, "apll_d24", "audpll", 1, 24),
> +
> + FACTOR(TOP_LVDSPLL_D2, "lvdspll_d2", "lvdspll", 1, 2),
> + FACTOR(TOP_LVDSPLL_D4, "lvdspll_d4", "lvdspll", 1, 4),
> + FACTOR(TOP_LVDSPLL_D8, "lvdspll_d8", "lvdspll", 1, 8),
> +
> + FACTOR(TOP_LVDSTX_CLKDIG_CT, "lvdstx_clkdig_cts", "lvdspll", 1, 1),
> + FACTOR(TOP_VPLL_DPIX_CK, "vpll_dpix_ck", "lvdspll", 1, 1),
> +
> + FACTOR(TOP_TVHDMI_H_CK, "tvhdmi_h_ck", "tvdpll", 1, 1),
> +
> + FACTOR(TOP_HDMITX_CLKDIG_D2, "hdmitx_clkdig_d2", "hdmitx_clkdig_cts", 1, 2),
> + FACTOR(TOP_HDMITX_CLKDIG_D3, "hdmitx_clkdig_d3", "hdmitx_clkdig_cts", 1, 3),
> +
> + FACTOR(TOP_TVHDMI_D2, "tvhdmi_d2", "tvhdmi_h_ck", 1, 2),
> + FACTOR(TOP_TVHDMI_D4, "tvhdmi_d4", "tvhdmi_h_ck", 1, 4),
> +
> + FACTOR(TOP_MEMPLL_MCK_D4, "mempll_mck_d4", "clkph_mck", 1, 4),
> +};
> +
> +static const char *axi_parents[] __initconst = {
> + "clk26m",
> + "syspll_d3",
> + "syspll_d4",
> + "syspll_d6",
> + "univpll_d5",
> + "univpll2_d2",
> + "syspll_d3p5"
> +};
> +
> +static const char *smi_parents[] __initconst = {
> + "clk26m",
> + "clkph_mck",
> + "syspll_d2p5",
> + "syspll_d3",
> + "syspll_d8",
> + "univpll_d5",
> + "univpll1_d2",
> + "univpll1_d6",
> + "mmpll_d3",
> + "mmpll_d4",
> + "mmpll_d5",
> + "mmpll_d6",
> + "mmpll_d7",
> + "vdecpll",
> + "lvdspll"
> +};
> +
> +static const char *mfg_parents[] __initconst = {
> + "clk26m",
> + "univpll1_d4",
> + "syspll_d2",
> + "syspll_d2p5",
> + "syspll_d3",
> + "univpll_d5",
> + "univpll1_d2",
> + "mmpll_d2",
> + "mmpll_d3",
> + "mmpll_d4",
> + "mmpll_d5",
> + "mmpll_d6",
> + "mmpll_d7"
> +};
> +
> +static const char *irda_parents[] __initconst = {
> + "clk26m",
> + "univpll2_d8",
> + "univpll1_d6"
> +};
> +
> +static const char *cam_parents[] __initconst = {
> + "clk26m",
> + "syspll_d3",
> + "syspll_d3p5",
> + "syspll_d4",
> + "univpll_d5",
> + "univpll2_d2",
> + "univpll_d7",
> + "univpll1_d4"
> +};
> +
> +static const char *aud_intbus_parents[] __initconst = {
> + "clk26m",
> + "syspll_d6",
> + "univpll_d10"
> +};
> +
> +static const char *jpg_parents[] __initconst = {
> + "clk26m",
> + "syspll_d5",
> + "syspll_d4",
> + "syspll_d3",
> + "univpll_d7",
> + "univpll2_d2",
> + "univpll_d5"
> +};
> +
> +static const char *disp_parents[] __initconst = {
> + "clk26m",
> + "syspll_d3p5",
> + "syspll_d3",
> + "univpll2_d2",
> + "univpll_d5",
> + "univpll1_d2",
> + "lvdspll",
> + "vdecpll"
> +};
> +
> +static const char *msdc30_parents[] __initconst = {
> + "clk26m",
> + "syspll_d6",
> + "syspll_d5",
> + "univpll1_d4",
> + "univpll2_d4",
> + "msdcpll"
> +};
> +
> +static const char *usb20_parents[] __initconst = {
> + "clk26m",
> + "univpll2_d6",
> + "univpll1_d10"
> +};
> +
> +static const char *venc_parents[] __initconst = {
> + "clk26m",
> + "syspll_d3",
> + "syspll_d8",
> + "univpll_d5",
> + "univpll1_d6",
> + "mmpll_d4",
> + "mmpll_d5",
> + "mmpll_d6"
> +};
> +
> +static const char *spi_parents[] __initconst = {
> + "clk26m",
> + "syspll_d6",
> + "syspll_d8",
> + "syspll_d10",
> + "univpll1_d6",
> + "univpll1_d8"
> +};
> +
> +static const char *uart_parents[] __initconst = {
> + "clk26m",
> + "univpll2_d8"
> +};
> +
> +static const char *mem_parents[] __initconst = {
> + "clk26m",
> + "clkph_mck"
> +};
> +
> +static const char *camtg_parents[] __initconst = {
> + "clk26m",
> + "univpll_d26",
> + "univpll1_d6",
> + "syspll_d16",
> + "syspll_d8"
> +};
> +
> +static const char *audio_parents[] __initconst = {
> + "clk26m",
> + "syspll_d24"
> +};
> +
> +static const char *fix_parents[] __initconst = {
> + "rtc32k",
> + "clk26m",
> + "univpll_d5",
> + "univpll_d7",
> + "univpll1_d2",
> + "univpll1_d4",
> + "univpll1_d6",
> + "univpll1_d8"
> +};
> +
> +static const char *vdec_parents[] __initconst = {
> + "clk26m",
> + "vdecpll",
> + "clkph_mck",
> + "syspll_d2p5",
> + "syspll_d3",
> + "syspll_d3p5",
> + "syspll_d4",
> + "syspll_d5",
> + "syspll_d6",
> + "syspll_d8",
> + "univpll1_d2",
> + "univpll2_d2",
> + "univpll_d7",
> + "univpll_d10",
> + "univpll2_d4",
> + "lvdspll"
> +};
> +
> +static const char *ddrphycfg_parents[] __initconst = {
> + "clk26m",
> + "axi_sel",
> + "syspll_d12"
> +};
> +
> +static const char *dpilvds_parents[] __initconst = {
> + "clk26m",
> + "lvdspll",
> + "lvdspll_d2",
> + "lvdspll_d4",
> + "lvdspll_d8"
> +};
> +
> +static const char *pmicspi_parents[] __initconst = {
> + "clk26m",
> + "univpll2_d6",
> + "syspll_d8",
> + "syspll_d10",
> + "univpll1_d10",
> + "mempll_mck_d4",
> + "univpll_d26",
> + "syspll_d24"
> +};
> +
> +static const char *smi_mfg_as_parents[] __initconst = {
> + "clk26m",
> + "smi_sel",
> + "mfg_sel",
> + "mem_sel"
> +};
> +
> +static const char *gcpu_parents[] __initconst = {
> + "clk26m",
> + "syspll_d4",
> + "univpll_d7",
> + "syspll_d5",
> + "syspll_d6"
> +};
> +
> +static const char *dpi1_parents[] __initconst = {
> + "clk26m",
> + "tvhdmi_h_ck",
> + "tvhdmi_d2",
> + "tvhdmi_d4"
> +};
> +
> +static const char *cci_parents[] __initconst = {
> + "clk26m",
> + "mainpll_537p3m",
> + "univpll_d3",
> + "syspll_d2p5",
> + "syspll_d3",
> + "syspll_d5"
> +};
> +
> +static const char *apll_parents[] __initconst = {
> + "clk26m",
> + "apll_ck",
> + "apll_d4",
> + "apll_d8",
> + "apll_d16",
> + "apll_d24"
> +};
> +
> +static const char *hdmipll_parents[] __initconst = {
> + "clk26m",
> + "hdmitx_clkdig_cts",
> + "hdmitx_clkdig_d2",
> + "hdmitx_clkdig_d3"
> +};
> +
> +static struct mtk_composite top_muxes[] __initdata = {
> + /* CLK_CFG_0 */
> + MUX_GATE(TOP_AXI_SEL, "axi_sel", axi_parents,
> + 0x0140, 0, 3, INVALID_MUX_GATE_BIT),
> + MUX_GATE(TOP_SMI_SEL, "smi_sel", smi_parents, 0x0140, 8, 4, 15),
> + MUX_GATE(TOP_MFG_SEL, "mfg_sel", mfg_parents, 0x0140, 16, 4, 23),
> + MUX_GATE(TOP_IRDA_SEL, "irda_sel", irda_parents, 0x0140, 24, 2, 31),
> + /* CLK_CFG_1 */
> + MUX_GATE(TOP_CAM_SEL, "cam_sel", cam_parents, 0x0144, 0, 3, 7),
> + MUX_GATE(TOP_AUD_INTBUS_SEL, "aud_intbus_sel", aud_intbus_parents,
> + 0x0144, 8, 2, 15),
> + MUX_GATE(TOP_JPG_SEL, "jpg_sel", jpg_parents, 0x0144, 16, 3, 23),
> + MUX_GATE(TOP_DISP_SEL, "disp_sel", disp_parents, 0x0144, 24, 3, 31),
> + /* CLK_CFG_2 */
> + MUX_GATE(TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_parents, 0x0148, 0, 3, 7),
> + MUX_GATE(TOP_MSDC30_2_SEL, "msdc30_2_sel", msdc30_parents, 0x0148, 8, 3, 15),
> + MUX_GATE(TOP_MSDC30_3_SEL, "msdc30_3_sel", msdc30_parents, 0x0148, 16, 3, 23),
> + MUX_GATE(TOP_MSDC30_4_SEL, "msdc30_4_sel", msdc30_parents, 0x0148, 24, 3, 31),
> + /* CLK_CFG_3 */
> + MUX_GATE(TOP_USB20_SEL, "usb20_sel", usb20_parents, 0x014c, 0, 2, 7),
> + /* CLK_CFG_4 */
> + MUX_GATE(TOP_VENC_SEL, "venc_sel", venc_parents, 0x0150, 8, 3, 15),
> + MUX_GATE(TOP_SPI_SEL, "spi_sel", spi_parents, 0x0150, 16, 3, 23),
> + MUX_GATE(TOP_UART_SEL, "uart_sel", uart_parents, 0x0150, 24, 2, 31),
> + /* CLK_CFG_6 */
> + MUX_GATE(TOP_MEM_SEL, "mem_sel", mem_parents, 0x0158, 0, 2, 7),
> + MUX_GATE(TOP_CAMTG_SEL, "camtg_sel", camtg_parents, 0x0158, 8, 3, 15),
> + MUX_GATE(TOP_AUDIO_SEL, "audio_sel", audio_parents, 0x0158, 24, 2, 31),
> + /* CLK_CFG_7 */
> + MUX_GATE(TOP_FIX_SEL, "fix_sel", fix_parents, 0x015c, 0, 3, 7),
> + MUX_GATE(TOP_VDEC_SEL, "vdec_sel", vdec_parents, 0x015c, 8, 4, 15),
> + MUX_GATE(TOP_DDRPHYCFG_SEL, "ddrphycfg_sel", ddrphycfg_parents,
> + 0x015c, 16, 2, 23),
> + MUX_GATE(TOP_DPILVDS_SEL, "dpilvds_sel", dpilvds_parents, 0x015c, 24, 3, 31),
> + /* CLK_CFG_8 */
> + MUX_GATE(TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents, 0x0164, 0, 3, 7),
> + MUX_GATE(TOP_MSDC30_0_SEL, "msdc30_0_sel", msdc30_parents, 0x0164, 8, 3, 15),
> + MUX_GATE(TOP_SMI_MFG_AS_SEL, "smi_mfg_as_sel", smi_mfg_as_parents,
> + 0x0164, 16, 2, 23),
> + MUX_GATE(TOP_GCPU_SEL, "gcpu_sel", gcpu_parents, 0x0164, 24, 3, 31),
> + /* CLK_CFG_9 */
> + MUX_GATE(TOP_DPI1_SEL, "dpi1_sel", dpi1_parents, 0x0168, 0, 2, 7),
> + MUX_GATE(TOP_CCI_SEL, "cci_sel", cci_parents, 0x0168, 8, 3, 15),
> + MUX_GATE(TOP_APLL_SEL, "apll_sel", apll_parents, 0x0168, 16, 3, 23),
> + MUX_GATE(TOP_HDMIPLL_SEL, "hdmipll_sel", hdmipll_parents, 0x0168, 24, 2, 31),
> +};
> +
> +static void __init mtk_init_clk_topckgen(void __iomem *top_base,
> + struct clk_onecell_data *clk_data)
> +{
> + int i;
> + struct clk *clk;
> +
> + for (i = 0; i < ARRAY_SIZE(top_muxes); i++) {
> + struct mtk_composite *mux = &top_muxes[i];
> +
> + clk = mtk_clk_register_composite(mux, top_base, &lock);
> +
> + if (IS_ERR(clk)) {
> + pr_err("Failed to register clk %s: %ld\n",
> + mux->name, PTR_ERR(clk));
> + continue;
> + }
> +
> + if (clk_data)
> + clk_data->clks[mux->id] = clk;
> + }
> +}
> +
> +static struct mtk_gate_regs infra_cg_regs = {
> + .set_ofs = 0x0040,
> + .clr_ofs = 0x0044,
> + .sta_ofs = 0x0048,
> +};
> +
> +#define GATE_ICG(_id, _name, _parent, _shift) { \
> + .id = _id, \
> + .name = _name, \
> + .parent_name = _parent, \
> + .regs = &infra_cg_regs, \
> + .shift = _shift, \
> + .ops = &mtk_clk_gate_ops_setclr, \
> + }
> +
> +static struct mtk_gate infra_clks[] __initdata = {
> + GATE_ICG(INFRA_PMIC_WRAP_CK, "pmic_wrap_ck", "axi_sel", 23),
> + GATE_ICG(INFRA_PMICSPI_CK, "pmicspi_ck", "pmicspi_sel", 22),
> + GATE_ICG(INFRA_CCIF1_AP_CTRL, "ccif1_ap_ctrl", "axi_sel", 21),
> + GATE_ICG(INFRA_CCIF0_AP_CTRL, "ccif0_ap_ctrl", "axi_sel", 20),
> + GATE_ICG(INFRA_KP_CK, "kp_ck", "axi_sel", 16),
> + GATE_ICG(INFRA_CPUM_CK, "cpum_ck", "cpum_tck_in", 15),
> + GATE_ICG(INFRA_M4U_CK, "m4u_ck", "mem_sel", 8),
> + GATE_ICG(INFRA_MFGAXI_CK, "mfgaxi_ck", "axi_sel", 7),
> + GATE_ICG(INFRA_DEVAPC_CK, "devapc_ck", "axi_sel", 6),
> + GATE_ICG(INFRA_AUDIO_CK, "audio_ck", "aud_intbus_sel", 5),
> + GATE_ICG(INFRA_MFG_BUS_CK, "mfg_bus_ck", "axi_sel", 2),
> + GATE_ICG(INFRA_SMI_CK, "smi_ck", "smi_sel", 1),
> + GATE_ICG(INFRA_DBGCLK_CK, "dbgclk_ck", "axi_sel", 0),
> +};
> +
> +static struct mtk_gate_regs peri0_cg_regs = {
> + .set_ofs = 0x0008,
> + .clr_ofs = 0x0010,
> + .sta_ofs = 0x0018,
> +};
> +
> +static struct mtk_gate_regs peri1_cg_regs = {
> + .set_ofs = 0x000c,
> + .clr_ofs = 0x0014,
> + .sta_ofs = 0x001c,
> +};
> +
> +#define GATE_PERI0(_id, _name, _parent, _shift) { \
> + .id = _id, \
> + .name = _name, \
> + .parent_name = _parent, \
> + .regs = &peri0_cg_regs, \
> + .shift = _shift, \
> + .ops = &mtk_clk_gate_ops_setclr, \
> + }
> +
> +#define GATE_PERI1(_id, _name, _parent, _shift) { \
> + .id = _id, \
> + .name = _name, \
> + .parent_name = _parent, \
> + .regs = &peri1_cg_regs, \
> + .shift = _shift, \
> + .ops = &mtk_clk_gate_ops_setclr, \
> + }
> +
> +static struct mtk_gate peri_clks[] __initdata = {
> + /* PERI0 */
> + GATE_PERI0(PERI_I2C5_CK, "i2c5_ck", "axi_sel", 31),
> + GATE_PERI0(PERI_I2C4_CK, "i2c4_ck", "axi_sel", 30),
> + GATE_PERI0(PERI_I2C3_CK, "i2c3_ck", "axi_sel", 29),
> + GATE_PERI0(PERI_I2C2_CK, "i2c2_ck", "axi_sel", 28),
> + GATE_PERI0(PERI_I2C1_CK, "i2c1_ck", "axi_sel", 27),
> + GATE_PERI0(PERI_I2C0_CK, "i2c0_ck", "axi_sel", 26),
> + GATE_PERI0(PERI_UART3_CK, "uart3_ck", "axi_sel", 25),
> + GATE_PERI0(PERI_UART2_CK, "uart2_ck", "axi_sel", 24),
> + GATE_PERI0(PERI_UART1_CK, "uart1_ck", "axi_sel", 23),
> + GATE_PERI0(PERI_UART0_CK, "uart0_ck", "axi_sel", 22),
> + GATE_PERI0(PERI_IRDA_CK, "irda_ck", "irda_sel", 21),
> + GATE_PERI0(PERI_NLI_CK, "nli_ck", "axi_sel", 20),
> + GATE_PERI0(PERI_MD_HIF_CK, "md_hif_ck", "axi_sel", 19),
> + GATE_PERI0(PERI_AP_HIF_CK, "ap_hif_ck", "axi_sel", 18),
> + GATE_PERI0(PERI_MSDC30_3_CK, "msdc30_3_ck", "msdc30_4_sel", 17),
> + GATE_PERI0(PERI_MSDC30_2_CK, "msdc30_2_ck", "msdc30_3_sel", 16),
> + GATE_PERI0(PERI_MSDC30_1_CK, "msdc30_1_ck", "msdc30_2_sel", 15),
> + GATE_PERI0(PERI_MSDC20_2_CK, "msdc20_2_ck", "msdc30_1_sel", 14),
> + GATE_PERI0(PERI_MSDC20_1_CK, "msdc20_1_ck", "msdc30_0_sel", 13),
> + GATE_PERI0(PERI_AP_DMA_CK, "ap_dma_ck", "axi_sel", 12),
> + GATE_PERI0(PERI_USB1_CK, "usb1_ck", "usb20_sel", 11),
> + GATE_PERI0(PERI_USB0_CK, "usb0_ck", "usb20_sel", 10),
> + GATE_PERI0(PERI_PWM_CK, "pwm_ck", "axi_sel", 9),
> + GATE_PERI0(PERI_PWM7_CK, "pwm7_ck", "axi_sel", 8),
> + GATE_PERI0(PERI_PWM6_CK, "pwm6_ck", "axi_sel", 7),
> + GATE_PERI0(PERI_PWM5_CK, "pwm5_ck", "axi_sel", 6),
> + GATE_PERI0(PERI_PWM4_CK, "pwm4_ck", "axi_sel", 5),
> + GATE_PERI0(PERI_PWM3_CK, "pwm3_ck", "axi_sel", 4),
> + GATE_PERI0(PERI_PWM2_CK, "pwm2_ck", "axi_sel", 3),
> + GATE_PERI0(PERI_PWM1_CK, "pwm1_ck", "axi_sel", 2),
> + GATE_PERI0(PERI_THERM_CK, "therm_ck", "axi_sel", 1),
> + GATE_PERI0(PERI_NFI_CK, "nfi_ck", "axi_sel", 0),
> + /* PERI1 */
> + GATE_PERI1(PERI_USBSLV_CK, "usbslv_ck", "axi_sel", 8),
> + GATE_PERI1(PERI_USB1_MCU_CK, "usb1_mcu_ck", "axi_sel", 7),
> + GATE_PERI1(PERI_USB0_MCU_CK, "usb0_mcu_ck", "axi_sel", 6),
> + GATE_PERI1(PERI_GCPU_CK, "gcpu_ck", "gcpu_sel", 5),
> + GATE_PERI1(PERI_FHCTL_CK, "fhctl_ck", "clk26m", 4),
> + GATE_PERI1(PERI_SPI1_CK, "spi1_ck", "spi_sel", 3),
> + GATE_PERI1(PERI_AUXADC_CK, "auxadc_ck", "clk26m", 2),
> + GATE_PERI1(PERI_PERI_PWRAP_CK, "peri_pwrap_ck", "axi_sel", 1),
> + GATE_PERI1(PERI_I2C6_CK, "i2c6_ck", "axi_sel", 0),
> +};
> +
> +static void __init mtk_topckgen_init(struct device_node *node)
> +{
> + struct clk_onecell_data *clk_data;
> + void __iomem *base;
> + int r;
> +
> + base = of_iomap(node, 0);
> + if (!base) {
> + pr_err("%s(): ioremap failed\n", __func__);
> + return;
> + }
> +
> + clk_data = mtk_alloc_clk_data(TOP_NR_CLK);
> +
> + mtk_clk_register_factors(root_clk_alias, ARRAY_SIZE(root_clk_alias), clk_data);
> + mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
> + mtk_init_clk_topckgen(base, clk_data);
> +
> + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> + if (r)
> + pr_err("%s(): could not register clock provider: %d\n",
> + __func__, r);
> +}
> +CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt8135-topckgen", mtk_topckgen_init);
> +
> +static void __init mtk_infrasys_init(struct device_node *node)
> +{
> + struct clk_onecell_data *clk_data;
> + int r;
> +
> + clk_data = mtk_alloc_clk_data(INFRA_NR_CLK);
> +
> + mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
> + clk_data);
> +
> + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> + if (r)
> + pr_err("%s(): could not register clock provider: %d\n",
> + __func__, r);
> +
> + mtk_register_reset_controller(node, 2, 0x30);
> +}
> +CLK_OF_DECLARE(mtk_infrasys, "mediatek,mt8135-infracfg", mtk_infrasys_init);
> +
> +static void __init mtk_pericfg_init(struct device_node *node)
> +{
> + struct clk_onecell_data *clk_data;
> + int r;
> +
> + clk_data = mtk_alloc_clk_data(PERI_NR_CLK);
> +
> + mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
> + clk_data);
> +
> + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> + if (r)
> + pr_err("%s(): could not register clock provider: %d\n",
> + __func__, r);
> +
> + mtk_register_reset_controller(node, 2, 0);
> +}
> +CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt8135-pericfg", mtk_pericfg_init);
> +
> +#define MT8135_PLL_FMAX (2000 * MHZ)
> +#define CON0_MT8135_RST_BAR BIT(27)
> +
> +#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) { \
> + .id = _id, \
> + .name = _name, \
> + .reg = _reg, \
> + .pwr_reg = _pwr_reg, \
> + .en_mask = _en_mask, \
> + .flags = _flags, \
> + .rst_bar_mask = CON0_MT8135_RST_BAR, \
> + .fmax = MT8135_PLL_FMAX, \
> + .pcwbits = _pcwbits, \
> + .pd_reg = _pd_reg, \
> + .pd_shift = _pd_shift, \
> + .tuner_reg = _tuner_reg, \
> + .pcw_reg = _pcw_reg, \
> + .pcw_shift = _pcw_shift, \
> + }
> +
> +static struct mtk_pll_data plls[] = {
> + PLL(APMIXED_ARMPLL1, "armpll1", 0x200, 0x218, 0x80000001, 0, 21, 0x204, 24, 0x0, 0x204, 0),
> + PLL(APMIXED_ARMPLL2, "armpll2", 0x2cc, 0x2e4, 0x80000001, 0, 21, 0x2d0, 24, 0x0, 0x2d0, 0),
> + PLL(APMIXED_MAINPLL, "mainpll", 0x21c, 0x234, 0xf0000001, HAVE_RST_BAR, 21, 0x21c, 6, 0x0, 0x220, 0),
> + PLL(APMIXED_UNIVPLL, "univpll", 0x238, 0x250, 0xf3000001, HAVE_RST_BAR, 7, 0x238, 6, 0x0, 0x238, 9),
> + PLL(APMIXED_MMPLL, "mmpll", 0x254, 0x26c, 0xf0000001, HAVE_RST_BAR, 21, 0x254, 6, 0x0, 0x258, 0),
> + PLL(APMIXED_MSDCPLL, "msdcpll", 0x278, 0x290, 0x80000001, 0, 21, 0x278, 6, 0x0, 0x27c, 0),
> + PLL(APMIXED_TVDPLL, "tvdpll", 0x294, 0x2ac, 0x80000001, 0, 31, 0x296, 6, 0x0, 0x298, 0),
> + PLL(APMIXED_LVDSPLL, "lvdspll", 0x2b0, 0x2c8, 0x80000001, 0, 21, 0x2b0, 6, 0x0, 0x2b4, 0),
> + PLL(APMIXED_AUDPLL, "audpll", 0x2e8, 0x300, 0x80000001, 0, 31, 0x2e8, 6, 0x2f8, 0x2ec, 0),
> + PLL(APMIXED_VDECPLL, "vdecpll", 0x304, 0x31c, 0x80000001, 0, 21, 0x2b0, 6, 0x0, 0x308, 0),
> +};
> +
> +static void __init mtk_apmixedsys_init(struct device_node *node)
> +{
> + mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls));
> +}
> +CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt8135-apmixedsys",
> + mtk_apmixedsys_init);
> diff --git a/include/dt-bindings/clock/mt8135-clk.h b/include/dt-bindings/clock/mt8135-clk.h
> new file mode 100644
> index 0000000..8aea762
> --- /dev/null
> +++ b/include/dt-bindings/clock/mt8135-clk.h
> @@ -0,0 +1,190 @@
> +/*
> + * Copyright (c) 2014 MediaTek Inc.
> + * Author: James Liao <jamesjj.liao@mediatek.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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 _DT_BINDINGS_CLK_MT8135_H
> +#define _DT_BINDINGS_CLK_MT8135_H
> +
> +/* TOPCKGEN */
> +
> +#define TOP_DSI0_LNTC_DSICLK 1
> +#define TOP_HDMITX_CLKDIG_CTS 2
> +#define TOP_CLKPH_MCK 3
> +#define TOP_CPUM_TCK_IN 4
> +#define TOP_MAINPLL_806M 5
> +#define TOP_MAINPLL_537P3M 6
> +#define TOP_MAINPLL_322P4M 7
> +#define TOP_MAINPLL_230P3M 8
> +#define TOP_UNIVPLL_624M 9
> +#define TOP_UNIVPLL_416M 10
> +#define TOP_UNIVPLL_249P6M 11
> +#define TOP_UNIVPLL_178P3M 12
> +#define TOP_UNIVPLL_48M 13
> +#define TOP_MMPLL_D2 14
> +#define TOP_MMPLL_D3 15
> +#define TOP_MMPLL_D5 16
> +#define TOP_MMPLL_D7 17
> +#define TOP_MMPLL_D4 18
> +#define TOP_MMPLL_D6 19
> +#define TOP_SYSPLL_D2 20
> +#define TOP_SYSPLL_D4 21
> +#define TOP_SYSPLL_D6 22
> +#define TOP_SYSPLL_D8 23
> +#define TOP_SYSPLL_D10 24
> +#define TOP_SYSPLL_D12 25
> +#define TOP_SYSPLL_D16 26
> +#define TOP_SYSPLL_D24 27
> +#define TOP_SYSPLL_D3 28
> +#define TOP_SYSPLL_D2P5 29
> +#define TOP_SYSPLL_D5 30
> +#define TOP_SYSPLL_D3P5 31
> +#define TOP_UNIVPLL1_D2 32
> +#define TOP_UNIVPLL1_D4 33
> +#define TOP_UNIVPLL1_D6 34
> +#define TOP_UNIVPLL1_D8 35
> +#define TOP_UNIVPLL1_D10 36
> +#define TOP_UNIVPLL2_D2 37
> +#define TOP_UNIVPLL2_D4 38
> +#define TOP_UNIVPLL2_D6 39
> +#define TOP_UNIVPLL2_D8 40
> +#define TOP_UNIVPLL_D3 41
> +#define TOP_UNIVPLL_D5 42
> +#define TOP_UNIVPLL_D7 43
> +#define TOP_UNIVPLL_D10 44
> +#define TOP_UNIVPLL_D26 45
> +#define TOP_APLL_CK 46
> +#define TOP_APLL_D4 47
> +#define TOP_APLL_D8 48
> +#define TOP_APLL_D16 49
> +#define TOP_APLL_D24 50
> +#define TOP_LVDSPLL_D2 51
> +#define TOP_LVDSPLL_D4 52
> +#define TOP_LVDSPLL_D8 53
> +#define TOP_LVDSTX_CLKDIG_CT 54
> +#define TOP_VPLL_DPIX_CK 55
> +#define TOP_TVHDMI_H_CK 56
> +#define TOP_HDMITX_CLKDIG_D2 57
> +#define TOP_HDMITX_CLKDIG_D3 58
> +#define TOP_TVHDMI_D2 59
> +#define TOP_TVHDMI_D4 60
> +#define TOP_MEMPLL_MCK_D4 61
> +#define TOP_AXI_SEL 62
> +#define TOP_SMI_SEL 63
> +#define TOP_MFG_SEL 64
> +#define TOP_IRDA_SEL 65
> +#define TOP_CAM_SEL 66
> +#define TOP_AUD_INTBUS_SEL 67
> +#define TOP_JPG_SEL 68
> +#define TOP_DISP_SEL 69
> +#define TOP_MSDC30_1_SEL 70
> +#define TOP_MSDC30_2_SEL 71
> +#define TOP_MSDC30_3_SEL 72
> +#define TOP_MSDC30_4_SEL 73
> +#define TOP_USB20_SEL 74
> +#define TOP_VENC_SEL 75
> +#define TOP_SPI_SEL 76
> +#define TOP_UART_SEL 77
> +#define TOP_MEM_SEL 78
> +#define TOP_CAMTG_SEL 79
> +#define TOP_AUDIO_SEL 80
> +#define TOP_FIX_SEL 81
> +#define TOP_VDEC_SEL 82
> +#define TOP_DDRPHYCFG_SEL 83
> +#define TOP_DPILVDS_SEL 84
> +#define TOP_PMICSPI_SEL 85
> +#define TOP_MSDC30_0_SEL 86
> +#define TOP_SMI_MFG_AS_SEL 87
> +#define TOP_GCPU_SEL 88
> +#define TOP_DPI1_SEL 89
> +#define TOP_CCI_SEL 90
> +#define TOP_APLL_SEL 91
> +#define TOP_HDMIPLL_SEL 92
> +#define TOP_NR_CLK 93
> +
> +/* APMIXED_SYS */
> +
> +#define APMIXED_ARMPLL1 1
> +#define APMIXED_ARMPLL2 2
> +#define APMIXED_MAINPLL 3
> +#define APMIXED_UNIVPLL 4
> +#define APMIXED_MMPLL 5
> +#define APMIXED_MSDCPLL 6
> +#define APMIXED_TVDPLL 7
> +#define APMIXED_LVDSPLL 8
> +#define APMIXED_AUDPLL 9
> +#define APMIXED_VDECPLL 10
> +#define APMIXED_NR_CLK 11
> +
> +/* INFRA_SYS */
> +
> +#define INFRA_PMIC_WRAP_CK 1
> +#define INFRA_PMICSPI_CK 2
> +#define INFRA_CCIF1_AP_CTRL 3
> +#define INFRA_CCIF0_AP_CTRL 4
> +#define INFRA_KP_CK 5
> +#define INFRA_CPUM_CK 6
> +#define INFRA_M4U_CK 7
> +#define INFRA_MFGAXI_CK 8
> +#define INFRA_DEVAPC_CK 9
> +#define INFRA_AUDIO_CK 10
> +#define INFRA_MFG_BUS_CK 11
> +#define INFRA_SMI_CK 12
> +#define INFRA_DBGCLK_CK 13
> +#define INFRA_NR_CLK 14
> +
> +/* PERI_SYS */
> +
> +#define PERI_I2C5_CK 1
> +#define PERI_I2C4_CK 2
> +#define PERI_I2C3_CK 3
> +#define PERI_I2C2_CK 4
> +#define PERI_I2C1_CK 5
> +#define PERI_I2C0_CK 6
> +#define PERI_UART3_CK 7
> +#define PERI_UART2_CK 8
> +#define PERI_UART1_CK 9
> +#define PERI_UART0_CK 10
> +#define PERI_IRDA_CK 11
> +#define PERI_NLI_CK 12
> +#define PERI_MD_HIF_CK 13
> +#define PERI_AP_HIF_CK 14
> +#define PERI_MSDC30_3_CK 15
> +#define PERI_MSDC30_2_CK 16
> +#define PERI_MSDC30_1_CK 17
> +#define PERI_MSDC20_2_CK 18
> +#define PERI_MSDC20_1_CK 19
> +#define PERI_AP_DMA_CK 20
> +#define PERI_USB1_CK 21
> +#define PERI_USB0_CK 22
> +#define PERI_PWM_CK 23
> +#define PERI_PWM7_CK 24
> +#define PERI_PWM6_CK 25
> +#define PERI_PWM5_CK 26
> +#define PERI_PWM4_CK 27
> +#define PERI_PWM3_CK 28
> +#define PERI_PWM2_CK 29
> +#define PERI_PWM1_CK 30
> +#define PERI_THERM_CK 31
> +#define PERI_NFI_CK 32
> +#define PERI_USBSLV_CK 33
> +#define PERI_USB1_MCU_CK 34
> +#define PERI_USB0_MCU_CK 35
> +#define PERI_GCPU_CK 36
> +#define PERI_FHCTL_CK 37
> +#define PERI_SPI1_CK 38
> +#define PERI_AUXADC_CK 39
> +#define PERI_PERI_PWRAP_CK 40
> +#define PERI_I2C6_CK 41
> +#define PERI_NR_CLK 42
> +
> +#endif /* _DT_BINDINGS_CLK_MT8135_H */
> diff --git a/include/dt-bindings/reset-controller/mt8135-resets.h b/include/dt-bindings/reset-controller/mt8135-resets.h
> new file mode 100644
> index 0000000..1fb6295
> --- /dev/null
> +++ b/include/dt-bindings/reset-controller/mt8135-resets.h
> @@ -0,0 +1,64 @@
> +/*
> + * Copyright (c) 2014 MediaTek Inc.
> + * Author: Flora Fu, MediaTek
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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 _DT_BINDINGS_RESET_CONTROLLER_MT8135
> +#define _DT_BINDINGS_RESET_CONTROLLER_MT8135
> +
> +/* INFRACFG resets */
> +#define MT8135_INFRA_EMI_REG_RST 0
> +#define MT8135_INFRA_DRAMC0_A0_RST 1
> +#define MT8135_INFRA_CCIF0_RST 2
> +#define MT8135_INFRA_APCIRQ_EINT_RST 3
> +#define MT8135_INFRA_APXGPT_RST 4
> +#define MT8135_INFRA_SCPSYS_RST 5
> +#define MT8135_INFRA_CCIF1_RST 6
> +#define MT8135_INFRA_PMIC_WRAP_RST 7
> +#define MT8135_INFRA_KP_RST 8
> +#define MT8135_INFRA_EMI_RST 32
> +#define MT8135_INFRA_DRAMC0_RST 34
> +#define MT8135_INFRA_SMI_RST 35
> +#define MT8135_INFRA_M4U_RST 36
> +
> +/* PERICFG resets */
> +#define MT8135_PERI_UART0_SW_RST 0
> +#define MT8135_PERI_UART1_SW_RST 1
> +#define MT8135_PERI_UART2_SW_RST 2
> +#define MT8135_PERI_UART3_SW_RST 3
> +#define MT8135_PERI_IRDA_SW_RST 4
> +#define MT8135_PERI_PTP_SW_RST 5
> +#define MT8135_PERI_AP_HIF_SW_RST 6
> +#define MT8135_PERI_GPCU_SW_RST 7
> +#define MT8135_PERI_MD_HIF_SW_RST 8
> +#define MT8135_PERI_NLI_SW_RST 9
> +#define MT8135_PERI_AUXADC_SW_RST 10
> +#define MT8135_PERI_DMA_SW_RST 11
> +#define MT8135_PERI_NFI_SW_RST 14
> +#define MT8135_PERI_PWM_SW_RST 15
> +#define MT8135_PERI_THERM_SW_RST 16
> +#define MT8135_PERI_MSDC0_SW_RST 17
> +#define MT8135_PERI_MSDC1_SW_RST 18
> +#define MT8135_PERI_MSDC2_SW_RST 19
> +#define MT8135_PERI_MSDC3_SW_RST 20
> +#define MT8135_PERI_I2C0_SW_RST 22
> +#define MT8135_PERI_I2C1_SW_RST 23
> +#define MT8135_PERI_I2C2_SW_RST 24
> +#define MT8135_PERI_I2C3_SW_RST 25
> +#define MT8135_PERI_I2C4_SW_RST 26
> +#define MT8135_PERI_I2C5_SW_RST 27
> +#define MT8135_PERI_I2C6_SW_RST 28
> +#define MT8135_PERI_USB_SW_RST 29
> +#define MT8135_PERI_SPI1_SW_RST 33
> +#define MT8135_PERI_PWRAP_BRIDGE_SW_RST 34
> +
> +#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT8135 */
> --
> 2.1.4
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 3/5] clk: mediatek: Add basic clocks for Mediatek MT8135.
2015-03-15 16:27 ` Daniel Kurtz
(?)
@ 2015-03-16 5:33 ` Sascha Hauer
-1 siblings, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2015-03-16 5:33 UTC (permalink / raw)
To: Daniel Kurtz
Cc: Mike Turquette, James Liao, YH Chen, linux-kernel, Henry Chen,
linux-mediatek, Sasha Hauer, Matthias Brugger, Yingjoe Chen,
Eddie Huang, linux-arm-kernel
On Mon, Mar 16, 2015 at 12:27:20AM +0800, Daniel Kurtz wrote:
> Hi Sascha,
>
> Drive-by review...
>
> On Sun, Feb 22, 2015 at 7:49 PM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > From: James Liao <jamesjj.liao@mediatek.com>
> >
> > This patch adds basic clocks for MT8135, including TOPCKGEN, PLLs,
> > INFRA and PERI clocks.
> >
> > Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
> > Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
> > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > ---
> > drivers/clk/mediatek/Makefile | 1 +
> > drivers/clk/mediatek/clk-mt8135.c | 634 +++++++++++++++++++++
> > include/dt-bindings/clock/mt8135-clk.h | 190 ++++++
> > .../dt-bindings/reset-controller/mt8135-resets.h | 64 +++
> > 4 files changed, 889 insertions(+)
> > create mode 100644 drivers/clk/mediatek/clk-mt8135.c
> > create mode 100644 include/dt-bindings/clock/mt8135-clk.h
> > create mode 100644 include/dt-bindings/reset-controller/mt8135-resets.h
> >
> > diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
> > index 0b6f1c3..12ce576 100644
> > --- a/drivers/clk/mediatek/Makefile
> > +++ b/drivers/clk/mediatek/Makefile
> > @@ -1,2 +1,3 @@
> > obj-y += clk-mtk.o clk-pll.o clk-gate.o
> > obj-$(CONFIG_RESET_CONTROLLER) += reset.o
> > +obj-y += clk-mt8135.o
> > diff --git a/drivers/clk/mediatek/clk-mt8135.c b/drivers/clk/mediatek/clk-mt8135.c
> > new file mode 100644
> > index 0000000..6157447
> > --- /dev/null
> > +++ b/drivers/clk/mediatek/clk-mt8135.c
> > @@ -0,0 +1,634 @@
> > +/*
> > + * Copyright (c) 2014 MediaTek Inc.
> > + * Author: James Liao <jamesjj.liao@mediatek.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * 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/of.h>
> > +#include <linux/of_address.h>
> > +#include <linux/slab.h>
> > +#include <linux/mfd/syscon.h>
> > +#include <dt-bindings/clock/mt8135-clk.h>
> > +
> > +#include "clk-mtk.h"
> > +#include "clk-gate.h"
> > +
> > +static DEFINE_SPINLOCK(lock);
> > +
>
> > +static struct mtk_fixed_factor root_clk_alias[] __initdata = {
>
> Any reason you can't use "static const" here, and on all of the other
> static constant structures/arrays throughout this patch.
No, there is no reason. Changed it. Thanks
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 3/5] clk: mediatek: Add basic clocks for Mediatek MT8135.
@ 2015-03-16 5:33 ` Sascha Hauer
0 siblings, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2015-03-16 5:33 UTC (permalink / raw)
To: Daniel Kurtz
Cc: Mike Turquette, James Liao, YH Chen, linux-kernel, Henry Chen,
linux-mediatek, Sasha Hauer, Matthias Brugger, Yingjoe Chen,
Eddie Huang, linux-arm-kernel
On Mon, Mar 16, 2015 at 12:27:20AM +0800, Daniel Kurtz wrote:
> Hi Sascha,
>
> Drive-by review...
>
> On Sun, Feb 22, 2015 at 7:49 PM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > From: James Liao <jamesjj.liao@mediatek.com>
> >
> > This patch adds basic clocks for MT8135, including TOPCKGEN, PLLs,
> > INFRA and PERI clocks.
> >
> > Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
> > Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
> > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > ---
> > drivers/clk/mediatek/Makefile | 1 +
> > drivers/clk/mediatek/clk-mt8135.c | 634 +++++++++++++++++++++
> > include/dt-bindings/clock/mt8135-clk.h | 190 ++++++
> > .../dt-bindings/reset-controller/mt8135-resets.h | 64 +++
> > 4 files changed, 889 insertions(+)
> > create mode 100644 drivers/clk/mediatek/clk-mt8135.c
> > create mode 100644 include/dt-bindings/clock/mt8135-clk.h
> > create mode 100644 include/dt-bindings/reset-controller/mt8135-resets.h
> >
> > diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
> > index 0b6f1c3..12ce576 100644
> > --- a/drivers/clk/mediatek/Makefile
> > +++ b/drivers/clk/mediatek/Makefile
> > @@ -1,2 +1,3 @@
> > obj-y += clk-mtk.o clk-pll.o clk-gate.o
> > obj-$(CONFIG_RESET_CONTROLLER) += reset.o
> > +obj-y += clk-mt8135.o
> > diff --git a/drivers/clk/mediatek/clk-mt8135.c b/drivers/clk/mediatek/clk-mt8135.c
> > new file mode 100644
> > index 0000000..6157447
> > --- /dev/null
> > +++ b/drivers/clk/mediatek/clk-mt8135.c
> > @@ -0,0 +1,634 @@
> > +/*
> > + * Copyright (c) 2014 MediaTek Inc.
> > + * Author: James Liao <jamesjj.liao@mediatek.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * 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/of.h>
> > +#include <linux/of_address.h>
> > +#include <linux/slab.h>
> > +#include <linux/mfd/syscon.h>
> > +#include <dt-bindings/clock/mt8135-clk.h>
> > +
> > +#include "clk-mtk.h"
> > +#include "clk-gate.h"
> > +
> > +static DEFINE_SPINLOCK(lock);
> > +
>
> > +static struct mtk_fixed_factor root_clk_alias[] __initdata = {
>
> Any reason you can't use "static const" here, and on all of the other
> static constant structures/arrays throughout this patch.
No, there is no reason. Changed it. Thanks
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 3/5] clk: mediatek: Add basic clocks for Mediatek MT8135.
@ 2015-03-16 5:33 ` Sascha Hauer
0 siblings, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2015-03-16 5:33 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Mar 16, 2015 at 12:27:20AM +0800, Daniel Kurtz wrote:
> Hi Sascha,
>
> Drive-by review...
>
> On Sun, Feb 22, 2015 at 7:49 PM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > From: James Liao <jamesjj.liao@mediatek.com>
> >
> > This patch adds basic clocks for MT8135, including TOPCKGEN, PLLs,
> > INFRA and PERI clocks.
> >
> > Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
> > Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
> > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > ---
> > drivers/clk/mediatek/Makefile | 1 +
> > drivers/clk/mediatek/clk-mt8135.c | 634 +++++++++++++++++++++
> > include/dt-bindings/clock/mt8135-clk.h | 190 ++++++
> > .../dt-bindings/reset-controller/mt8135-resets.h | 64 +++
> > 4 files changed, 889 insertions(+)
> > create mode 100644 drivers/clk/mediatek/clk-mt8135.c
> > create mode 100644 include/dt-bindings/clock/mt8135-clk.h
> > create mode 100644 include/dt-bindings/reset-controller/mt8135-resets.h
> >
> > diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
> > index 0b6f1c3..12ce576 100644
> > --- a/drivers/clk/mediatek/Makefile
> > +++ b/drivers/clk/mediatek/Makefile
> > @@ -1,2 +1,3 @@
> > obj-y += clk-mtk.o clk-pll.o clk-gate.o
> > obj-$(CONFIG_RESET_CONTROLLER) += reset.o
> > +obj-y += clk-mt8135.o
> > diff --git a/drivers/clk/mediatek/clk-mt8135.c b/drivers/clk/mediatek/clk-mt8135.c
> > new file mode 100644
> > index 0000000..6157447
> > --- /dev/null
> > +++ b/drivers/clk/mediatek/clk-mt8135.c
> > @@ -0,0 +1,634 @@
> > +/*
> > + * Copyright (c) 2014 MediaTek Inc.
> > + * Author: James Liao <jamesjj.liao@mediatek.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * 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/of.h>
> > +#include <linux/of_address.h>
> > +#include <linux/slab.h>
> > +#include <linux/mfd/syscon.h>
> > +#include <dt-bindings/clock/mt8135-clk.h>
> > +
> > +#include "clk-mtk.h"
> > +#include "clk-gate.h"
> > +
> > +static DEFINE_SPINLOCK(lock);
> > +
>
> > +static struct mtk_fixed_factor root_clk_alias[] __initdata = {
>
> Any reason you can't use "static const" here, and on all of the other
> static constant structures/arrays throughout this patch.
No, there is no reason. Changed it. Thanks
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 3/5] clk: mediatek: Add basic clocks for Mediatek MT8135.
2015-03-13 7:44 ` Henry Chen
@ 2015-03-16 5:33 ` Sascha Hauer
-1 siblings, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2015-03-16 5:33 UTC (permalink / raw)
To: Henry Chen
Cc: Mike Turquette, Matthias Brugger, linux-arm-kernel, linux-kernel,
linux-mediatek, YH Chen, kernel, Yingjoe Chen, Eddie Huang,
James Liao
On Fri, Mar 13, 2015 at 03:44:30PM +0800, Henry Chen wrote:
> On Sun, 2015-02-22 at 12:49 +0100, Sascha Hauer wrote:
> > +#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) { \
> > + .id = _id, \
> > + .name = _name, \
> > + .reg = _reg, \
> > + .pwr_reg = _pwr_reg, \
> > + .en_mask = _en_mask, \
> > + .flags = _flags, \
> > + .rst_bar_mask = CON0_MT8135_RST_BAR, \
> > + .fmax = MT8135_PLL_FMAX, \
> > + .pcwbits = _pcwbits, \
> > + .pd_reg = _pd_reg, \
> > + .pd_shift = _pd_shift, \
> > + .tuner_reg = _tuner_reg, \
> > + .pcw_reg = _pcw_reg, \
> > + .pcw_shift = _pcw_shift, \
> > + }
> > +
> > +static struct mtk_pll_data plls[] = {
> > + PLL(APMIXED_ARMPLL1, "armpll1", 0x200, 0x218, 0x80000001, 0, 21, 0x204, 24, 0x0, 0x204, 0),
> > + PLL(APMIXED_ARMPLL2, "armpll2", 0x2cc, 0x2e4, 0x80000001, 0, 21, 0x2d0, 24, 0x0, 0x2d0, 0),
> > + PLL(APMIXED_MAINPLL, "mainpll", 0x21c, 0x234, 0xf0000001, HAVE_RST_BAR, 21, 0x21c, 6, 0x0, 0x220, 0),
> > + PLL(APMIXED_UNIVPLL, "univpll", 0x238, 0x250, 0xf3000001, HAVE_RST_BAR, 7, 0x238, 6, 0x0, 0x238, 9),
> > + PLL(APMIXED_MMPLL, "mmpll", 0x254, 0x26c, 0xf0000001, HAVE_RST_BAR, 21, 0x254, 6, 0x0, 0x258, 0),
> > + PLL(APMIXED_MSDCPLL, "msdcpll", 0x278, 0x290, 0x80000001, 0, 21, 0x278, 6, 0x0, 0x27c, 0),
> > + PLL(APMIXED_TVDPLL, "tvdpll", 0x294, 0x2ac, 0x80000001, 0, 31, 0x296, 6, 0x0, 0x298, 0),
>
> Hi Sasha,
>
> The pd_reg of tvdpll should be 0x294.
Fixed, thanks
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 3/5] clk: mediatek: Add basic clocks for Mediatek MT8135.
@ 2015-03-16 5:33 ` Sascha Hauer
0 siblings, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2015-03-16 5:33 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Mar 13, 2015 at 03:44:30PM +0800, Henry Chen wrote:
> On Sun, 2015-02-22 at 12:49 +0100, Sascha Hauer wrote:
> > +#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) { \
> > + .id = _id, \
> > + .name = _name, \
> > + .reg = _reg, \
> > + .pwr_reg = _pwr_reg, \
> > + .en_mask = _en_mask, \
> > + .flags = _flags, \
> > + .rst_bar_mask = CON0_MT8135_RST_BAR, \
> > + .fmax = MT8135_PLL_FMAX, \
> > + .pcwbits = _pcwbits, \
> > + .pd_reg = _pd_reg, \
> > + .pd_shift = _pd_shift, \
> > + .tuner_reg = _tuner_reg, \
> > + .pcw_reg = _pcw_reg, \
> > + .pcw_shift = _pcw_shift, \
> > + }
> > +
> > +static struct mtk_pll_data plls[] = {
> > + PLL(APMIXED_ARMPLL1, "armpll1", 0x200, 0x218, 0x80000001, 0, 21, 0x204, 24, 0x0, 0x204, 0),
> > + PLL(APMIXED_ARMPLL2, "armpll2", 0x2cc, 0x2e4, 0x80000001, 0, 21, 0x2d0, 24, 0x0, 0x2d0, 0),
> > + PLL(APMIXED_MAINPLL, "mainpll", 0x21c, 0x234, 0xf0000001, HAVE_RST_BAR, 21, 0x21c, 6, 0x0, 0x220, 0),
> > + PLL(APMIXED_UNIVPLL, "univpll", 0x238, 0x250, 0xf3000001, HAVE_RST_BAR, 7, 0x238, 6, 0x0, 0x238, 9),
> > + PLL(APMIXED_MMPLL, "mmpll", 0x254, 0x26c, 0xf0000001, HAVE_RST_BAR, 21, 0x254, 6, 0x0, 0x258, 0),
> > + PLL(APMIXED_MSDCPLL, "msdcpll", 0x278, 0x290, 0x80000001, 0, 21, 0x278, 6, 0x0, 0x27c, 0),
> > + PLL(APMIXED_TVDPLL, "tvdpll", 0x294, 0x2ac, 0x80000001, 0, 31, 0x296, 6, 0x0, 0x298, 0),
>
> Hi Sasha,
>
> The pd_reg of tvdpll should be 0x294.
Fixed, thanks
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 1/5] clk: mediatek: Add initial common clock support for Mediatek SoCs.
2015-03-13 16:46 ` Matthias Brugger
@ 2015-03-16 5:34 ` Sascha Hauer
-1 siblings, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2015-03-16 5:34 UTC (permalink / raw)
To: Matthias Brugger
Cc: Mike Turquette, linux-arm-kernel, linux-kernel, linux-mediatek,
YH Chen, kernel, Yingjoe Chen, Eddie Huang, Henry Chen,
James Liao
On Fri, Mar 13, 2015 at 05:46:32PM +0100, Matthias Brugger wrote:
>
>
> On 22/02/15 12:49, Sascha Hauer wrote:
> > From: James Liao <jamesjj.liao@mediatek.com>
>
> > diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
> > new file mode 100644
> > index 0000000..c7c0d35
> > --- /dev/null
> > +++ b/drivers/clk/mediatek/clk-mtk.h
>
> [...]
>
> > +void __init mtk_clk_register_plls(struct device_node *node,
> > + const struct mtk_pll_data *plls, int num_plls);
> > +
> > +#ifdef CONFIG_RESET_CONTROLLER
> > +void mtk_register_reset_controller(struct device_node *np,
> > + unsigned int num_regs, int regofs);
> > +#else
> > +static inline void mtk_register_reset_controller(struct device_node *np,
> > + unsigned int num_regs, int regofs)
> > +{
> > +}
> > +#endif
>
> This lines should only be added once in [2/5], compiling ends with:
>
> In file included from drivers/clk/mediatek/clk-mtk.c:24:0:
> drivers/clk/mediatek/clk-mtk.h:168:20: error: redefinition of ‘mtk_register_reset_controller’
> drivers/clk/mediatek/clk-mtk.h:158:20: note: previous definition of ‘mtk_register_reset_controller’ was here
Hm, seems to be a rebase accident. Fixed, thanks
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 1/5] clk: mediatek: Add initial common clock support for Mediatek SoCs.
@ 2015-03-16 5:34 ` Sascha Hauer
0 siblings, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2015-03-16 5:34 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Mar 13, 2015 at 05:46:32PM +0100, Matthias Brugger wrote:
>
>
> On 22/02/15 12:49, Sascha Hauer wrote:
> > From: James Liao <jamesjj.liao@mediatek.com>
>
> > diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
> > new file mode 100644
> > index 0000000..c7c0d35
> > --- /dev/null
> > +++ b/drivers/clk/mediatek/clk-mtk.h
>
> [...]
>
> > +void __init mtk_clk_register_plls(struct device_node *node,
> > + const struct mtk_pll_data *plls, int num_plls);
> > +
> > +#ifdef CONFIG_RESET_CONTROLLER
> > +void mtk_register_reset_controller(struct device_node *np,
> > + unsigned int num_regs, int regofs);
> > +#else
> > +static inline void mtk_register_reset_controller(struct device_node *np,
> > + unsigned int num_regs, int regofs)
> > +{
> > +}
> > +#endif
>
> This lines should only be added once in [2/5], compiling ends with:
>
> In file included from drivers/clk/mediatek/clk-mtk.c:24:0:
> drivers/clk/mediatek/clk-mtk.h:168:20: error: redefinition of ?mtk_register_reset_controller?
> drivers/clk/mediatek/clk-mtk.h:158:20: note: previous definition of ?mtk_register_reset_controller? was here
Hm, seems to be a rebase accident. Fixed, thanks
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 2/5] clk: mediatek: Add reset controller support
2015-03-16 5:55 [PATCH v7]: " Sascha Hauer
@ 2015-03-16 5:55 ` Sascha Hauer
0 siblings, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2015-03-16 5:55 UTC (permalink / raw)
To: Mike Turquette
Cc: YH Chen, linux-kernel, Henry Chen, linux-mediatek, kernel,
Matthias Brugger, Yingjoe Chen, Eddie Huang, linux-arm-kernel,
Sascha Hauer
The pericfg and infracfg units also provide reset lines to several
other SoC internal units. Add support for the reset controller.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/clk/mediatek/Makefile | 1 +
drivers/clk/mediatek/clk-mtk.h | 10 +++++
drivers/clk/mediatek/reset.c | 99 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 110 insertions(+)
create mode 100644 drivers/clk/mediatek/reset.c
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index c384e97..0b6f1c3 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -1 +1,2 @@
obj-y += clk-mtk.o clk-pll.o clk-gate.o
+obj-$(CONFIG_RESET_CONTROLLER) += reset.o
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index c660a9e..fc98101 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -152,4 +152,14 @@ void __init mtk_clk_register_plls(struct device_node *node,
const struct mtk_pll_data *plls, int num_plls,
struct clk_onecell_data *clk_data);
+#ifdef CONFIG_RESET_CONTROLLER
+void mtk_register_reset_controller(struct device_node *np,
+ unsigned int num_regs, int regofs);
+#else
+static inline void mtk_register_reset_controller(struct device_node *np,
+ unsigned int num_regs, int regofs)
+{
+}
+#endif
+
#endif /* __DRV_CLK_MTK_H */
diff --git a/drivers/clk/mediatek/reset.c b/drivers/clk/mediatek/reset.c
new file mode 100644
index 0000000..3a85a53
--- /dev/null
+++ b/drivers/clk/mediatek/reset.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+#include <linux/slab.h>
+
+#include "clk-mtk.h"
+
+struct mtk_reset {
+ struct regmap *regmap;
+ int regofs;
+ struct reset_controller_dev rcdev;
+};
+
+static int mtk_reset_assert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
+
+ return regmap_update_bits(data->regmap, data->regofs + ((id / 32) << 2),
+ BIT(id % 32), ~0);
+}
+
+static int mtk_reset_deassert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
+
+ return regmap_update_bits(data->regmap, data->regofs + ((id / 32) << 2),
+ BIT(id % 32), 0);
+}
+
+static int mtk_reset(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ int ret;
+
+ ret = mtk_reset_assert(rcdev, id);
+ if (ret)
+ return ret;
+
+ return mtk_reset_deassert(rcdev, id);
+}
+
+static struct reset_control_ops mtk_reset_ops = {
+ .assert = mtk_reset_assert,
+ .deassert = mtk_reset_deassert,
+ .reset = mtk_reset,
+};
+
+void mtk_register_reset_controller(struct device_node *np,
+ unsigned int num_regs, int regofs)
+{
+ struct mtk_reset *data;
+ int ret;
+ struct regmap *regmap;
+
+ regmap = syscon_node_to_regmap(np);
+ if (IS_ERR(regmap)) {
+ pr_err("Cannot find regmap for %s: %ld\n", np->full_name,
+ PTR_ERR(regmap));
+ return;
+ }
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return;
+
+ data->regmap = regmap;
+ data->regofs = regofs;
+ data->rcdev.owner = THIS_MODULE;
+ data->rcdev.nr_resets = num_regs * 32;
+ data->rcdev.ops = &mtk_reset_ops;
+ data->rcdev.of_node = np;
+
+ ret = reset_controller_register(&data->rcdev);
+ if (ret) {
+ pr_err("could not register reset controller: %d\n", ret);
+ kfree(data);
+ return;
+ }
+}
--
2.1.4
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 2/5] clk: mediatek: Add reset controller support
@ 2015-03-16 5:55 ` Sascha Hauer
0 siblings, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2015-03-16 5:55 UTC (permalink / raw)
To: linux-arm-kernel
The pericfg and infracfg units also provide reset lines to several
other SoC internal units. Add support for the reset controller.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/clk/mediatek/Makefile | 1 +
drivers/clk/mediatek/clk-mtk.h | 10 +++++
drivers/clk/mediatek/reset.c | 99 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 110 insertions(+)
create mode 100644 drivers/clk/mediatek/reset.c
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index c384e97..0b6f1c3 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -1 +1,2 @@
obj-y += clk-mtk.o clk-pll.o clk-gate.o
+obj-$(CONFIG_RESET_CONTROLLER) += reset.o
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index c660a9e..fc98101 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -152,4 +152,14 @@ void __init mtk_clk_register_plls(struct device_node *node,
const struct mtk_pll_data *plls, int num_plls,
struct clk_onecell_data *clk_data);
+#ifdef CONFIG_RESET_CONTROLLER
+void mtk_register_reset_controller(struct device_node *np,
+ unsigned int num_regs, int regofs);
+#else
+static inline void mtk_register_reset_controller(struct device_node *np,
+ unsigned int num_regs, int regofs)
+{
+}
+#endif
+
#endif /* __DRV_CLK_MTK_H */
diff --git a/drivers/clk/mediatek/reset.c b/drivers/clk/mediatek/reset.c
new file mode 100644
index 0000000..3a85a53
--- /dev/null
+++ b/drivers/clk/mediatek/reset.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+#include <linux/slab.h>
+
+#include "clk-mtk.h"
+
+struct mtk_reset {
+ struct regmap *regmap;
+ int regofs;
+ struct reset_controller_dev rcdev;
+};
+
+static int mtk_reset_assert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
+
+ return regmap_update_bits(data->regmap, data->regofs + ((id / 32) << 2),
+ BIT(id % 32), ~0);
+}
+
+static int mtk_reset_deassert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
+
+ return regmap_update_bits(data->regmap, data->regofs + ((id / 32) << 2),
+ BIT(id % 32), 0);
+}
+
+static int mtk_reset(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ int ret;
+
+ ret = mtk_reset_assert(rcdev, id);
+ if (ret)
+ return ret;
+
+ return mtk_reset_deassert(rcdev, id);
+}
+
+static struct reset_control_ops mtk_reset_ops = {
+ .assert = mtk_reset_assert,
+ .deassert = mtk_reset_deassert,
+ .reset = mtk_reset,
+};
+
+void mtk_register_reset_controller(struct device_node *np,
+ unsigned int num_regs, int regofs)
+{
+ struct mtk_reset *data;
+ int ret;
+ struct regmap *regmap;
+
+ regmap = syscon_node_to_regmap(np);
+ if (IS_ERR(regmap)) {
+ pr_err("Cannot find regmap for %s: %ld\n", np->full_name,
+ PTR_ERR(regmap));
+ return;
+ }
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return;
+
+ data->regmap = regmap;
+ data->regofs = regofs;
+ data->rcdev.owner = THIS_MODULE;
+ data->rcdev.nr_resets = num_regs * 32;
+ data->rcdev.ops = &mtk_reset_ops;
+ data->rcdev.of_node = np;
+
+ ret = reset_controller_register(&data->rcdev);
+ if (ret) {
+ pr_err("could not register reset controller: %d\n", ret);
+ kfree(data);
+ return;
+ }
+}
--
2.1.4
^ permalink raw reply related [flat|nested] 30+ messages in thread
end of thread, other threads:[~2015-03-16 5:56 UTC | newest]
Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-22 11:49 [PATCH v6]: clk: Add common clock support for Mediatek MT8135 and MT8173 Sascha Hauer
2015-02-22 11:49 ` Sascha Hauer
2015-02-22 11:49 ` [PATCH 1/5] clk: mediatek: Add initial common clock support for Mediatek SoCs Sascha Hauer
2015-02-22 11:49 ` Sascha Hauer
2015-03-13 16:46 ` Matthias Brugger
2015-03-13 16:46 ` Matthias Brugger
2015-03-16 5:34 ` Sascha Hauer
2015-03-16 5:34 ` Sascha Hauer
2015-02-22 11:49 ` [PATCH 2/5] clk: mediatek: Add reset controller support Sascha Hauer
2015-02-22 11:49 ` Sascha Hauer
2015-02-22 11:49 ` [PATCH 3/5] clk: mediatek: Add basic clocks for Mediatek MT8135 Sascha Hauer
2015-02-22 11:49 ` Sascha Hauer
2015-03-13 7:44 ` Henry Chen
2015-03-13 7:44 ` Henry Chen
2015-03-16 5:33 ` Sascha Hauer
2015-03-16 5:33 ` Sascha Hauer
2015-03-15 16:27 ` Daniel Kurtz
2015-03-15 16:27 ` Daniel Kurtz
2015-03-15 16:27 ` Daniel Kurtz
2015-03-16 5:33 ` Sascha Hauer
2015-03-16 5:33 ` Sascha Hauer
2015-03-16 5:33 ` Sascha Hauer
2015-02-22 11:49 ` [PATCH 4/5] clk: mediatek: Add basic clocks for Mediatek MT8173 Sascha Hauer
2015-02-22 11:49 ` Sascha Hauer
2015-02-22 11:49 ` [PATCH 5/5] dt-bindings: ARM: Mediatek: Document devicetree bindings for clock/reset controllers Sascha Hauer
2015-02-22 11:49 ` Sascha Hauer
2015-03-09 6:15 ` [PATCH v6]: clk: Add common clock support for Mediatek MT8135 and MT8173 Sascha Hauer
2015-03-09 6:15 ` Sascha Hauer
2015-03-16 5:55 [PATCH v7]: " Sascha Hauer
2015-03-16 5:55 ` [PATCH 2/5] clk: mediatek: Add reset controller support Sascha Hauer
2015-03-16 5:55 ` Sascha Hauer
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.