All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/10] Add Basic SoC support for MT6797
@ 2017-02-06 12:15 ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-06 12:15 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: CC Hwang, Loda Chou, Miles Chen, Jades Shih, Yingjoe Chen,
	My Chuang, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, Marc Zyngier, Thomas Gleixner, Will Deacon,
	Stephen Boyd, linux-clk, Chieh-Jay Liu

This patch set adds basic SoC support for mediatek's first 10-core
chip, X20, also known as MT6797.

- based on 4.10-rc2
- support multiple base address for sysirq
- support common clk

Changes since v1:
- add multiple base addresses support, v1 only allow 2 bases
- clean up clk driver


Kevin-CW Chen (2):
  dt-bindings: arm: mediatek: document clk bindings for MT6797
  clk: mediatek: add clk support for MT6797

Mars Cheng (8):
  Document: DT: mediatek: multiple base address support for sysirq
  irqchip: mtk-sysirq: extend intpol base to arbitrary number
  Document: DT: Add bindings for mediatek MT6797 SoC Platform
  arm64: dts: mediatek: add mt6797 support
  soc: mediatek: refine scysys for mediatek platforms
  soc: mediatek: add MT6797 power dt-bindings
  soc: mediatek: add MT6797 scysys support
  arm64: dts: mediatek: add clk nodes for MT6797

 Documentation/devicetree/bindings/arm/mediatek.txt |    4 +
 .../bindings/arm/mediatek/mediatek,apmixedsys.txt  |    1 +
 .../bindings/arm/mediatek/mediatek,imgsys.txt      |    1 +
 .../bindings/arm/mediatek/mediatek,infracfg.txt    |    1 +
 .../bindings/arm/mediatek/mediatek,mmsys.txt       |    1 +
 .../bindings/arm/mediatek/mediatek,topckgen.txt    |    1 +
 .../bindings/arm/mediatek/mediatek,vdecsys.txt     |    1 +
 .../bindings/arm/mediatek/mediatek,vencsys.txt     |    3 +-
 .../interrupt-controller/mediatek,sysirq.txt       |   14 +-
 .../devicetree/bindings/serial/mtk-uart.txt        |    1 +
 .../devicetree/bindings/soc/mediatek/scpsys.txt    |    6 +-
 arch/arm64/boot/dts/mediatek/Makefile              |    1 +
 arch/arm64/boot/dts/mediatek/mt6797-evb.dts        |   36 +
 arch/arm64/boot/dts/mediatek/mt6797.dtsi           |  250 +++++++
 drivers/clk/mediatek/Kconfig                       |   33 +
 drivers/clk/mediatek/Makefile                      |    5 +
 drivers/clk/mediatek/clk-mt6797-img.c              |   76 +++
 drivers/clk/mediatek/clk-mt6797-mm.c               |  136 ++++
 drivers/clk/mediatek/clk-mt6797-vdec.c             |   93 +++
 drivers/clk/mediatek/clk-mt6797-venc.c             |   78 +++
 drivers/clk/mediatek/clk-mt6797.c                  |  716 ++++++++++++++++++++
 drivers/irqchip/irq-mtk-sysirq.c                   |   71 +-
 drivers/soc/mediatek/mtk-scpsys.c                  |  149 +++-
 include/dt-bindings/clock/mt6797-clk.h             |  281 ++++++++
 include/dt-bindings/power/mt6797-power.h           |   30 +
 25 files changed, 1956 insertions(+), 33 deletions(-)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt6797-evb.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt6797.dtsi
 create mode 100644 drivers/clk/mediatek/clk-mt6797-img.c
 create mode 100644 drivers/clk/mediatek/clk-mt6797-mm.c
 create mode 100644 drivers/clk/mediatek/clk-mt6797-vdec.c
 create mode 100644 drivers/clk/mediatek/clk-mt6797-venc.c
 create mode 100644 drivers/clk/mediatek/clk-mt6797.c
 create mode 100644 include/dt-bindings/clock/mt6797-clk.h
 create mode 100644 include/dt-bindings/power/mt6797-power.h

--
1.7.9.5

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH v2 00/10] Add Basic SoC support for MT6797
@ 2017-02-06 12:15 ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-06 12:15 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: CC Hwang, Loda Chou, Miles Chen, Jades Shih, Yingjoe Chen,
	My Chuang, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	wsd_upstream-NuS5LvNUpcJWk0Htik3J/w, Marc Zyngier,
	Thomas Gleixner, Will Deacon, Stephen Boyd,
	linux-clk-u79uwXL29TY76Z2rM5mHXA, Chieh-Jay Liu

This patch set adds basic SoC support for mediatek's first 10-core
chip, X20, also known as MT6797.

- based on 4.10-rc2
- support multiple base address for sysirq
- support common clk

Changes since v1:
- add multiple base addresses support, v1 only allow 2 bases
- clean up clk driver


Kevin-CW Chen (2):
  dt-bindings: arm: mediatek: document clk bindings for MT6797
  clk: mediatek: add clk support for MT6797

Mars Cheng (8):
  Document: DT: mediatek: multiple base address support for sysirq
  irqchip: mtk-sysirq: extend intpol base to arbitrary number
  Document: DT: Add bindings for mediatek MT6797 SoC Platform
  arm64: dts: mediatek: add mt6797 support
  soc: mediatek: refine scysys for mediatek platforms
  soc: mediatek: add MT6797 power dt-bindings
  soc: mediatek: add MT6797 scysys support
  arm64: dts: mediatek: add clk nodes for MT6797

 Documentation/devicetree/bindings/arm/mediatek.txt |    4 +
 .../bindings/arm/mediatek/mediatek,apmixedsys.txt  |    1 +
 .../bindings/arm/mediatek/mediatek,imgsys.txt      |    1 +
 .../bindings/arm/mediatek/mediatek,infracfg.txt    |    1 +
 .../bindings/arm/mediatek/mediatek,mmsys.txt       |    1 +
 .../bindings/arm/mediatek/mediatek,topckgen.txt    |    1 +
 .../bindings/arm/mediatek/mediatek,vdecsys.txt     |    1 +
 .../bindings/arm/mediatek/mediatek,vencsys.txt     |    3 +-
 .../interrupt-controller/mediatek,sysirq.txt       |   14 +-
 .../devicetree/bindings/serial/mtk-uart.txt        |    1 +
 .../devicetree/bindings/soc/mediatek/scpsys.txt    |    6 +-
 arch/arm64/boot/dts/mediatek/Makefile              |    1 +
 arch/arm64/boot/dts/mediatek/mt6797-evb.dts        |   36 +
 arch/arm64/boot/dts/mediatek/mt6797.dtsi           |  250 +++++++
 drivers/clk/mediatek/Kconfig                       |   33 +
 drivers/clk/mediatek/Makefile                      |    5 +
 drivers/clk/mediatek/clk-mt6797-img.c              |   76 +++
 drivers/clk/mediatek/clk-mt6797-mm.c               |  136 ++++
 drivers/clk/mediatek/clk-mt6797-vdec.c             |   93 +++
 drivers/clk/mediatek/clk-mt6797-venc.c             |   78 +++
 drivers/clk/mediatek/clk-mt6797.c                  |  716 ++++++++++++++++++++
 drivers/irqchip/irq-mtk-sysirq.c                   |   71 +-
 drivers/soc/mediatek/mtk-scpsys.c                  |  149 +++-
 include/dt-bindings/clock/mt6797-clk.h             |  281 ++++++++
 include/dt-bindings/power/mt6797-power.h           |   30 +
 25 files changed, 1956 insertions(+), 33 deletions(-)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt6797-evb.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt6797.dtsi
 create mode 100644 drivers/clk/mediatek/clk-mt6797-img.c
 create mode 100644 drivers/clk/mediatek/clk-mt6797-mm.c
 create mode 100644 drivers/clk/mediatek/clk-mt6797-vdec.c
 create mode 100644 drivers/clk/mediatek/clk-mt6797-venc.c
 create mode 100644 drivers/clk/mediatek/clk-mt6797.c
 create mode 100644 include/dt-bindings/clock/mt6797-clk.h
 create mode 100644 include/dt-bindings/power/mt6797-power.h

--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH v2 01/10] Document: DT: mediatek: multiple base address support for sysirq
  2017-02-06 12:15 ` Mars Cheng
@ 2017-02-06 12:15   ` Mars Cheng
  -1 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-06 12:15 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: CC Hwang, Loda Chou, Miles Chen, Jades Shih, Yingjoe Chen,
	My Chuang, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, Marc Zyngier, Thomas Gleixner, Will Deacon,
	Stephen Boyd, linux-clk, Chieh-Jay Liu, Mars Cheng

This describes how to specify multiple base addresses for sysirq
in mediatek platforms.

Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
---
 .../interrupt-controller/mediatek,sysirq.txt       |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt b/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt
index 9d1d72c..1718454 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt
@@ -18,16 +18,21 @@ Required properties:
 	"mediatek,mt2701-sysirq"
 - interrupt-controller : Identifies the node as an interrupt controller
 - #interrupt-cells : Use the same format as specified by GIC in arm,gic.txt.
+- #intpol-bases: Indicate how many base addresses to be used, default is 1.
 - interrupt-parent: phandle of irq parent for sysirq. The parent must
   use the same interrupt-cells format as GIC.
 - reg: Physical base address of the intpol registers and length of memory
-  mapped region.
+  mapped region. Could be multiple bases here. Ex: mt6797 needs 2 reg, others
+  need 1. If not set, the default is 1.
 
 Example:
-	sysirq: interrupt-controller@10200100 {
-		compatible = "mediatek,mt6589-sysirq", "mediatek,mt6577-sysirq";
+	sysirq: intpol-controller@10200620 {
+		compatible = "mediatek,mt6797-sysirq",
+			     "mediatek,mt6577-sysirq";
 		interrupt-controller;
 		#interrupt-cells = <3>;
+		#intpol-bases = <2>;
 		interrupt-parent = <&gic>;
-		reg = <0 0x10200100 0 0x1c>;
+		reg = <0 0x10220620 0 0x20>,
+		      <0 0x10220690 0 0x10>;
 	};
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 01/10] Document: DT: mediatek: multiple base address support for sysirq
@ 2017-02-06 12:15   ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-06 12:15 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: CC Hwang, Loda Chou, Miles Chen, Jades Shih, Yingjoe Chen,
	My Chuang, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, Marc Zyngier, Thomas Gleixner, Will Deacon,
	Stephen Boyd, linux-clk, Chieh-Jay Liu, Mars Cheng

This describes how to specify multiple base addresses for sysirq
in mediatek platforms.

Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
---
 .../interrupt-controller/mediatek,sysirq.txt       |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt b/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt
index 9d1d72c..1718454 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt
@@ -18,16 +18,21 @@ Required properties:
 	"mediatek,mt2701-sysirq"
 - interrupt-controller : Identifies the node as an interrupt controller
 - #interrupt-cells : Use the same format as specified by GIC in arm,gic.txt.
+- #intpol-bases: Indicate how many base addresses to be used, default is 1.
 - interrupt-parent: phandle of irq parent for sysirq. The parent must
   use the same interrupt-cells format as GIC.
 - reg: Physical base address of the intpol registers and length of memory
-  mapped region.
+  mapped region. Could be multiple bases here. Ex: mt6797 needs 2 reg, others
+  need 1. If not set, the default is 1.
 
 Example:
-	sysirq: interrupt-controller@10200100 {
-		compatible = "mediatek,mt6589-sysirq", "mediatek,mt6577-sysirq";
+	sysirq: intpol-controller@10200620 {
+		compatible = "mediatek,mt6797-sysirq",
+			     "mediatek,mt6577-sysirq";
 		interrupt-controller;
 		#interrupt-cells = <3>;
+		#intpol-bases = <2>;
 		interrupt-parent = <&gic>;
-		reg = <0 0x10200100 0 0x1c>;
+		reg = <0 0x10220620 0 0x20>,
+		      <0 0x10220690 0 0x10>;
 	};
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 02/10] irqchip: mtk-sysirq: extend intpol base to arbitrary number
@ 2017-02-06 12:15   ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-06 12:15 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: CC Hwang, Loda Chou, Miles Chen, Jades Shih, Yingjoe Chen,
	My Chuang, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, Marc Zyngier, Thomas Gleixner, Will Deacon,
	Stephen Boyd, linux-clk, Chieh-Jay Liu, Mars Cheng

Originally driver only supports one base. However, MT6797 has
more than one bases to configure interrupt polarity. To support
possible design change, here comes a solution to use arbitrary
number of bases.

Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
---
 drivers/irqchip/irq-mtk-sysirq.c |   71 +++++++++++++++++++++++++++-----------
 1 file changed, 50 insertions(+), 21 deletions(-)

diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c
index 63ac73b..2645706 100644
--- a/drivers/irqchip/irq-mtk-sysirq.c
+++ b/drivers/irqchip/irq-mtk-sysirq.c
@@ -24,7 +24,9 @@
 
 struct mtk_sysirq_chip_data {
 	spinlock_t lock;
-	void __iomem *intpol_base;
+	u32 nr_intpol_bases;
+	void __iomem **intpol_bases;
+	u32 *intpol_words;
 };
 
 static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
@@ -33,13 +35,15 @@ static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
 	struct mtk_sysirq_chip_data *chip_data = data->chip_data;
 	u32 offset, reg_index, value;
 	unsigned long flags;
-	int ret;
+	int ret, i;
 
 	offset = hwirq & 0x1f;
 	reg_index = hwirq >> 5;
+	for (i = 0; reg_index >= chip_data->intpol_words[i]; i++)
+		reg_index -= chip_data->intpol_words[i];
 
 	spin_lock_irqsave(&chip_data->lock, flags);
-	value = readl_relaxed(chip_data->intpol_base + reg_index * 4);
+	value = readl_relaxed(chip_data->intpol_bases[i] + reg_index * 4);
 	if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_EDGE_FALLING) {
 		if (type == IRQ_TYPE_LEVEL_LOW)
 			type = IRQ_TYPE_LEVEL_HIGH;
@@ -49,7 +53,8 @@ static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
 	} else {
 		value &= ~(1 << offset);
 	}
-	writel(value, chip_data->intpol_base + reg_index * 4);
+
+	writel(value, chip_data->intpol_bases[i] + reg_index * 4);
 
 	data = data->parent_data;
 	ret = data->chip->irq_set_type(data, type);
@@ -124,8 +129,7 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
 {
 	struct irq_domain *domain, *domain_parent;
 	struct mtk_sysirq_chip_data *chip_data;
-	int ret, size, intpol_num;
-	struct resource res;
+	int ret, size, intpol_num = 0, nr_intpol_bases, i;
 
 	domain_parent = irq_find_host(parent);
 	if (!domain_parent) {
@@ -133,36 +137,61 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
 		return -EINVAL;
 	}
 
-	ret = of_address_to_resource(node, 0, &res);
-	if (ret)
-		return ret;
-
 	chip_data = kzalloc(sizeof(*chip_data), GFP_KERNEL);
 	if (!chip_data)
 		return -ENOMEM;
 
-	size = resource_size(&res);
-	intpol_num = size * 8;
-	chip_data->intpol_base = ioremap(res.start, size);
-	if (!chip_data->intpol_base) {
-		pr_err("mtk_sysirq: unable to map sysirq register\n");
-		ret = -ENXIO;
-		goto out_free;
+	if (of_property_read_u32(node, "#intpol-bases", &nr_intpol_bases))
+		nr_intpol_bases = 1;
+
+	chip_data->intpol_words =
+		kcalloc(nr_intpol_bases, sizeof(u32), GFP_KERNEL);
+	if (!chip_data->intpol_words) {
+		ret = -ENOMEM;
+		goto out_free_chip;
+	}
+
+	chip_data->intpol_bases =
+		kcalloc(nr_intpol_bases, sizeof(void __iomem *), GFP_KERNEL);
+	if (!chip_data->intpol_bases) {
+		ret = -ENOMEM;
+		goto out_free_intpol_words;
+	}
+
+	for (i = 0; i < nr_intpol_bases; i++) {
+		struct resource res;
+
+		ret = of_address_to_resource(node, i, &res);
+		size = resource_size(&res);
+		intpol_num += size * 8;
+		chip_data->intpol_words[i] = size / 4;
+		chip_data->intpol_bases[i] = of_iomap(node, i);
+		if (ret || !chip_data->intpol_bases[i]) {
+			pr_err("%s: couldn't map region %d\n",
+			       node->full_name, i);
+			ret = -ENODEV;
+			goto out_free_intpol;
+		}
 	}
 
 	domain = irq_domain_add_hierarchy(domain_parent, 0, intpol_num, node,
 					  &sysirq_domain_ops, chip_data);
 	if (!domain) {
 		ret = -ENOMEM;
-		goto out_unmap;
+		goto out_free_intpol;
 	}
 	spin_lock_init(&chip_data->lock);
 
 	return 0;
 
-out_unmap:
-	iounmap(chip_data->intpol_base);
-out_free:
+out_free_intpol:
+	for (i = 0; i < nr_intpol_bases; i++)
+		if (chip_data->intpol_bases[i])
+			iounmap(chip_data->intpol_bases[i]);
+	kfree(chip_data->intpol_bases);
+out_free_intpol_words:
+	kfree(chip_data->intpol_words);
+out_free_chip:
 	kfree(chip_data);
 	return ret;
 }
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 02/10] irqchip: mtk-sysirq: extend intpol base to arbitrary number
@ 2017-02-06 12:15   ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-06 12:15 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, CC Hwang,
	wsd_upstream-NuS5LvNUpcJWk0Htik3J/w, Marc Zyngier, Will Deacon,
	Mars Cheng, Loda Chou, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	Jades Shih, linux-clk-u79uwXL29TY76Z2rM5mHXA, Miles Chen,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, My Chuang,
	Yingjoe Chen, Thomas Gleixner, Stephen Boyd, Chieh-Jay Liu

Originally driver only supports one base. However, MT6797 has
more than one bases to configure interrupt polarity. To support
possible design change, here comes a solution to use arbitrary
number of bases.

Signed-off-by: Mars Cheng <mars.cheng-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
---
 drivers/irqchip/irq-mtk-sysirq.c |   71 +++++++++++++++++++++++++++-----------
 1 file changed, 50 insertions(+), 21 deletions(-)

diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c
index 63ac73b..2645706 100644
--- a/drivers/irqchip/irq-mtk-sysirq.c
+++ b/drivers/irqchip/irq-mtk-sysirq.c
@@ -24,7 +24,9 @@
 
 struct mtk_sysirq_chip_data {
 	spinlock_t lock;
-	void __iomem *intpol_base;
+	u32 nr_intpol_bases;
+	void __iomem **intpol_bases;
+	u32 *intpol_words;
 };
 
 static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
@@ -33,13 +35,15 @@ static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
 	struct mtk_sysirq_chip_data *chip_data = data->chip_data;
 	u32 offset, reg_index, value;
 	unsigned long flags;
-	int ret;
+	int ret, i;
 
 	offset = hwirq & 0x1f;
 	reg_index = hwirq >> 5;
+	for (i = 0; reg_index >= chip_data->intpol_words[i]; i++)
+		reg_index -= chip_data->intpol_words[i];
 
 	spin_lock_irqsave(&chip_data->lock, flags);
-	value = readl_relaxed(chip_data->intpol_base + reg_index * 4);
+	value = readl_relaxed(chip_data->intpol_bases[i] + reg_index * 4);
 	if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_EDGE_FALLING) {
 		if (type == IRQ_TYPE_LEVEL_LOW)
 			type = IRQ_TYPE_LEVEL_HIGH;
@@ -49,7 +53,8 @@ static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
 	} else {
 		value &= ~(1 << offset);
 	}
-	writel(value, chip_data->intpol_base + reg_index * 4);
+
+	writel(value, chip_data->intpol_bases[i] + reg_index * 4);
 
 	data = data->parent_data;
 	ret = data->chip->irq_set_type(data, type);
@@ -124,8 +129,7 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
 {
 	struct irq_domain *domain, *domain_parent;
 	struct mtk_sysirq_chip_data *chip_data;
-	int ret, size, intpol_num;
-	struct resource res;
+	int ret, size, intpol_num = 0, nr_intpol_bases, i;
 
 	domain_parent = irq_find_host(parent);
 	if (!domain_parent) {
@@ -133,36 +137,61 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
 		return -EINVAL;
 	}
 
-	ret = of_address_to_resource(node, 0, &res);
-	if (ret)
-		return ret;
-
 	chip_data = kzalloc(sizeof(*chip_data), GFP_KERNEL);
 	if (!chip_data)
 		return -ENOMEM;
 
-	size = resource_size(&res);
-	intpol_num = size * 8;
-	chip_data->intpol_base = ioremap(res.start, size);
-	if (!chip_data->intpol_base) {
-		pr_err("mtk_sysirq: unable to map sysirq register\n");
-		ret = -ENXIO;
-		goto out_free;
+	if (of_property_read_u32(node, "#intpol-bases", &nr_intpol_bases))
+		nr_intpol_bases = 1;
+
+	chip_data->intpol_words =
+		kcalloc(nr_intpol_bases, sizeof(u32), GFP_KERNEL);
+	if (!chip_data->intpol_words) {
+		ret = -ENOMEM;
+		goto out_free_chip;
+	}
+
+	chip_data->intpol_bases =
+		kcalloc(nr_intpol_bases, sizeof(void __iomem *), GFP_KERNEL);
+	if (!chip_data->intpol_bases) {
+		ret = -ENOMEM;
+		goto out_free_intpol_words;
+	}
+
+	for (i = 0; i < nr_intpol_bases; i++) {
+		struct resource res;
+
+		ret = of_address_to_resource(node, i, &res);
+		size = resource_size(&res);
+		intpol_num += size * 8;
+		chip_data->intpol_words[i] = size / 4;
+		chip_data->intpol_bases[i] = of_iomap(node, i);
+		if (ret || !chip_data->intpol_bases[i]) {
+			pr_err("%s: couldn't map region %d\n",
+			       node->full_name, i);
+			ret = -ENODEV;
+			goto out_free_intpol;
+		}
 	}
 
 	domain = irq_domain_add_hierarchy(domain_parent, 0, intpol_num, node,
 					  &sysirq_domain_ops, chip_data);
 	if (!domain) {
 		ret = -ENOMEM;
-		goto out_unmap;
+		goto out_free_intpol;
 	}
 	spin_lock_init(&chip_data->lock);
 
 	return 0;
 
-out_unmap:
-	iounmap(chip_data->intpol_base);
-out_free:
+out_free_intpol:
+	for (i = 0; i < nr_intpol_bases; i++)
+		if (chip_data->intpol_bases[i])
+			iounmap(chip_data->intpol_bases[i]);
+	kfree(chip_data->intpol_bases);
+out_free_intpol_words:
+	kfree(chip_data->intpol_words);
+out_free_chip:
 	kfree(chip_data);
 	return ret;
 }
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 03/10] Document: DT: Add bindings for mediatek MT6797 SoC Platform
@ 2017-02-06 12:15   ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-06 12:15 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: CC Hwang, Loda Chou, Miles Chen, Jades Shih, Yingjoe Chen,
	My Chuang, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, Marc Zyngier, Thomas Gleixner, Will Deacon,
	Stephen Boyd, linux-clk, Chieh-Jay Liu, Mars Cheng

This adds dt-binding documentation for Mediatek MT6797. Only
include very basic items, gic, uart timer and cpu.

Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
---
 Documentation/devicetree/bindings/arm/mediatek.txt |    4 ++++
 .../interrupt-controller/mediatek,sysirq.txt       |    1 +
 .../devicetree/bindings/serial/mtk-uart.txt        |    1 +
 3 files changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek.txt b/Documentation/devicetree/bindings/arm/mediatek.txt
index c860b24..2d3344d 100644
--- a/Documentation/devicetree/bindings/arm/mediatek.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek.txt
@@ -12,6 +12,7 @@ compatible: Must contain one of
    "mediatek,mt6592"
    "mediatek,mt6755"
    "mediatek,mt6795"
+   "mediatek,mt6797"
    "mediatek,mt7623"
    "mediatek,mt8127"
    "mediatek,mt8135"
@@ -38,6 +39,9 @@ Supported boards:
 - Evaluation board for MT6795(Helio X10):
     Required root node properties:
       - compatible = "mediatek,mt6795-evb", "mediatek,mt6795";
+- Evaluation board for MT6797(Helio X20):
+    Required root node properties:
+      - compatible = "mediatek,mt6797-evb", "mediatek,mt6797";
 - Evaluation board for MT7623:
     Required root node properties:
       - compatible = "mediatek,mt7623-evb", "mediatek,mt7623";
diff --git a/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt b/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt
index 1718454..9e537d6 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt
@@ -9,6 +9,7 @@ Required properties:
 	"mediatek,mt8135-sysirq"
 	"mediatek,mt8127-sysirq"
 	"mediatek,mt6795-sysirq"
+	"mediatek,mt6797-sysirq"
 	"mediatek,mt6755-sysirq"
 	"mediatek,mt6592-sysirq"
 	"mediatek,mt6589-sysirq"
diff --git a/Documentation/devicetree/bindings/serial/mtk-uart.txt b/Documentation/devicetree/bindings/serial/mtk-uart.txt
index 0015c72..5b8513d 100644
--- a/Documentation/devicetree/bindings/serial/mtk-uart.txt
+++ b/Documentation/devicetree/bindings/serial/mtk-uart.txt
@@ -8,6 +8,7 @@ Required properties:
   * "mediatek,mt6589-uart" for MT6589 compatible UARTS
   * "mediatek,mt6755-uart" for MT6755 compatible UARTS
   * "mediatek,mt6795-uart" for MT6795 compatible UARTS
+  * "mediatek,mt6797-uart" for MT6797 compatible UARTS
   * "mediatek,mt7623-uart" for MT7623 compatible UARTS
   * "mediatek,mt8127-uart" for MT8127 compatible UARTS
   * "mediatek,mt8135-uart" for MT8135 compatible UARTS
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 03/10] Document: DT: Add bindings for mediatek MT6797 SoC Platform
@ 2017-02-06 12:15   ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-06 12:15 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, CC Hwang,
	wsd_upstream-NuS5LvNUpcJWk0Htik3J/w, Marc Zyngier, Will Deacon,
	Mars Cheng, Loda Chou, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	Jades Shih, linux-clk-u79uwXL29TY76Z2rM5mHXA, Miles Chen,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, My Chuang,
	Yingjoe Chen, Thomas Gleixner, Stephen Boyd, Chieh-Jay Liu

This adds dt-binding documentation for Mediatek MT6797. Only
include very basic items, gic, uart timer and cpu.

Signed-off-by: Mars Cheng <mars.cheng-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
---
 Documentation/devicetree/bindings/arm/mediatek.txt |    4 ++++
 .../interrupt-controller/mediatek,sysirq.txt       |    1 +
 .../devicetree/bindings/serial/mtk-uart.txt        |    1 +
 3 files changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek.txt b/Documentation/devicetree/bindings/arm/mediatek.txt
index c860b24..2d3344d 100644
--- a/Documentation/devicetree/bindings/arm/mediatek.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek.txt
@@ -12,6 +12,7 @@ compatible: Must contain one of
    "mediatek,mt6592"
    "mediatek,mt6755"
    "mediatek,mt6795"
+   "mediatek,mt6797"
    "mediatek,mt7623"
    "mediatek,mt8127"
    "mediatek,mt8135"
@@ -38,6 +39,9 @@ Supported boards:
 - Evaluation board for MT6795(Helio X10):
     Required root node properties:
       - compatible = "mediatek,mt6795-evb", "mediatek,mt6795";
+- Evaluation board for MT6797(Helio X20):
+    Required root node properties:
+      - compatible = "mediatek,mt6797-evb", "mediatek,mt6797";
 - Evaluation board for MT7623:
     Required root node properties:
       - compatible = "mediatek,mt7623-evb", "mediatek,mt7623";
diff --git a/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt b/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt
index 1718454..9e537d6 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt
@@ -9,6 +9,7 @@ Required properties:
 	"mediatek,mt8135-sysirq"
 	"mediatek,mt8127-sysirq"
 	"mediatek,mt6795-sysirq"
+	"mediatek,mt6797-sysirq"
 	"mediatek,mt6755-sysirq"
 	"mediatek,mt6592-sysirq"
 	"mediatek,mt6589-sysirq"
diff --git a/Documentation/devicetree/bindings/serial/mtk-uart.txt b/Documentation/devicetree/bindings/serial/mtk-uart.txt
index 0015c72..5b8513d 100644
--- a/Documentation/devicetree/bindings/serial/mtk-uart.txt
+++ b/Documentation/devicetree/bindings/serial/mtk-uart.txt
@@ -8,6 +8,7 @@ Required properties:
   * "mediatek,mt6589-uart" for MT6589 compatible UARTS
   * "mediatek,mt6755-uart" for MT6755 compatible UARTS
   * "mediatek,mt6795-uart" for MT6795 compatible UARTS
+  * "mediatek,mt6797-uart" for MT6797 compatible UARTS
   * "mediatek,mt7623-uart" for MT7623 compatible UARTS
   * "mediatek,mt8127-uart" for MT8127 compatible UARTS
   * "mediatek,mt8135-uart" for MT8135 compatible UARTS
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 04/10] arm64: dts: mediatek: add mt6797 support
@ 2017-02-06 12:15   ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-06 12:15 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: CC Hwang, Loda Chou, Miles Chen, Jades Shih, Yingjoe Chen,
	My Chuang, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, Marc Zyngier, Thomas Gleixner, Will Deacon,
	Stephen Boyd, linux-clk, Chieh-Jay Liu, Mars Cheng

This adds basic chip support for MT6797 SoC.

Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/Makefile       |    1 +
 arch/arm64/boot/dts/mediatek/mt6797-evb.dts |   36 ++++++
 arch/arm64/boot/dts/mediatek/mt6797.dtsi    |  187 +++++++++++++++++++++++++++
 3 files changed, 224 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt6797-evb.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt6797.dtsi

diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index 9fbfd32..015eb07 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -1,5 +1,6 @@
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt6755-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt6795-evb.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-evb.dtb
 
 always		:= $(dtb-y)
diff --git a/arch/arm64/boot/dts/mediatek/mt6797-evb.dts b/arch/arm64/boot/dts/mediatek/mt6797-evb.dts
new file mode 100644
index 0000000..c79109c
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt6797-evb.dts
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Mars.C <mars.cheng@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.
+ */
+
+/dts-v1/;
+#include "mt6797.dtsi"
+
+/ {
+	model = "MediaTek MT6797 Evaluation Board";
+	compatible = "mediatek,mt6797-evb", "mediatek,mt6797";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	memory@40000000 {
+		device_type = "memory";
+		reg = <0 0x40000000 0 0x1e800000>;
+	};
+
+	chosen {};
+};
+
+&uart0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt6797.dtsi b/arch/arm64/boot/dts/mediatek/mt6797.dtsi
new file mode 100644
index 0000000..da3a6ff
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt6797.dtsi
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Mars.C <mars.cheng@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,
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	compatible = "mediatek,mt6797";
+	interrupt-parent = <&sysirq>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	psci {
+		compatible = "arm,psci-0.2";
+		method = "smc";
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x000>;
+		};
+
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x001>;
+		};
+
+		cpu2: cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x002>;
+		};
+
+		cpu3: cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x003>;
+		};
+
+		cpu4: cpu@100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x100>;
+		};
+
+		cpu5: cpu@101 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x101>;
+		};
+
+		cpu6: cpu@102 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x102>;
+		};
+
+		cpu7: cpu@103 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x103>;
+		};
+
+		cpu8: cpu@200 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a72";
+			enable-method = "psci";
+			reg = <0x200>;
+		};
+
+		cpu9: cpu@201 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a72";
+			enable-method = "psci";
+			reg = <0x201>;
+		};
+	};
+
+	clk26m: oscillator@0 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <26000000>;
+		clock-output-names = "clk26m";
+	};
+
+	clk32k: oscillator@1 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32000>;
+		clock-output-names = "clk32k";
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 13
+			     (GIC_CPU_MASK_SIMPLE(10) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14
+			     (GIC_CPU_MASK_SIMPLE(10) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11
+			     (GIC_CPU_MASK_SIMPLE(10) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10
+			     (GIC_CPU_MASK_SIMPLE(10) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+
+	sysirq: intpol-controller@10200620 {
+		compatible = "mediatek,mt6797-sysirq",
+			     "mediatek,mt6577-sysirq";
+		interrupt-controller;
+		#interrupt-cells = <3>;
+		#intpol-bases = <2>;
+		interrupt-parent = <&gic>;
+		reg = <0 0x10220620 0 0x20>,
+		      <0 0x10220690 0 0x10>;
+	};
+
+	uart0: serial@11002000 {
+		compatible = "mediatek,mt6797-uart",
+			     "mediatek,mt6577-uart";
+		reg = <0 0x11002000 0 0x400>;
+		interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&clk26m>;
+		status = "disabled";
+	};
+
+	uart1: serial@11003000 {
+		compatible = "mediatek,mt6797-uart",
+			     "mediatek,mt6577-uart";
+		reg = <0 0x11003000 0 0x400>;
+		interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&clk26m>;
+		status = "disabled";
+	};
+
+	uart2: serial@11004000 {
+		compatible = "mediatek,mt6797-uart",
+			     "mediatek,mt6577-uart";
+		reg = <0 0x11004000 0 0x400>;
+		interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&clk26m>;
+		status = "disabled";
+	};
+
+	uart3: serial@11005000 {
+		compatible = "mediatek,mt6797-uart",
+			     "mediatek,mt6577-uart";
+		reg = <0 0x11005000 0 0x400>;
+		interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&clk26m>;
+		status = "disabled";
+	};
+
+	gic: interrupt-controller@19000000 {
+		compatible = "arm,gic-v3";
+		#interrupt-cells = <3>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-controller;
+		reg = <0 0x19000000 0 0x10000>,    /* GICD */
+		      <0 0x19200000 0 0x200000>,   /* GICR */
+		      <0 0x10240000 0 0x2000>;     /* GICC */
+	};
+};
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 04/10] arm64: dts: mediatek: add mt6797 support
@ 2017-02-06 12:15   ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-06 12:15 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, CC Hwang,
	wsd_upstream-NuS5LvNUpcJWk0Htik3J/w, Marc Zyngier, Will Deacon,
	Mars Cheng, Loda Chou, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	Jades Shih, linux-clk-u79uwXL29TY76Z2rM5mHXA, Miles Chen,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, My Chuang,
	Yingjoe Chen, Thomas Gleixner, Stephen Boyd, Chieh-Jay Liu

This adds basic chip support for MT6797 SoC.

Signed-off-by: Mars Cheng <mars.cheng-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
---
 arch/arm64/boot/dts/mediatek/Makefile       |    1 +
 arch/arm64/boot/dts/mediatek/mt6797-evb.dts |   36 ++++++
 arch/arm64/boot/dts/mediatek/mt6797.dtsi    |  187 +++++++++++++++++++++++++++
 3 files changed, 224 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt6797-evb.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt6797.dtsi

diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index 9fbfd32..015eb07 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -1,5 +1,6 @@
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt6755-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt6795-evb.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-evb.dtb
 
 always		:= $(dtb-y)
diff --git a/arch/arm64/boot/dts/mediatek/mt6797-evb.dts b/arch/arm64/boot/dts/mediatek/mt6797-evb.dts
new file mode 100644
index 0000000..c79109c
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt6797-evb.dts
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Mars.C <mars.cheng-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/dts-v1/;
+#include "mt6797.dtsi"
+
+/ {
+	model = "MediaTek MT6797 Evaluation Board";
+	compatible = "mediatek,mt6797-evb", "mediatek,mt6797";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	memory@40000000 {
+		device_type = "memory";
+		reg = <0 0x40000000 0 0x1e800000>;
+	};
+
+	chosen {};
+};
+
+&uart0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt6797.dtsi b/arch/arm64/boot/dts/mediatek/mt6797.dtsi
new file mode 100644
index 0000000..da3a6ff
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt6797.dtsi
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Mars.C <mars.cheng-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	compatible = "mediatek,mt6797";
+	interrupt-parent = <&sysirq>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	psci {
+		compatible = "arm,psci-0.2";
+		method = "smc";
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x000>;
+		};
+
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x001>;
+		};
+
+		cpu2: cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x002>;
+		};
+
+		cpu3: cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x003>;
+		};
+
+		cpu4: cpu@100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x100>;
+		};
+
+		cpu5: cpu@101 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x101>;
+		};
+
+		cpu6: cpu@102 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x102>;
+		};
+
+		cpu7: cpu@103 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x103>;
+		};
+
+		cpu8: cpu@200 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a72";
+			enable-method = "psci";
+			reg = <0x200>;
+		};
+
+		cpu9: cpu@201 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a72";
+			enable-method = "psci";
+			reg = <0x201>;
+		};
+	};
+
+	clk26m: oscillator@0 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <26000000>;
+		clock-output-names = "clk26m";
+	};
+
+	clk32k: oscillator@1 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32000>;
+		clock-output-names = "clk32k";
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 13
+			     (GIC_CPU_MASK_SIMPLE(10) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14
+			     (GIC_CPU_MASK_SIMPLE(10) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11
+			     (GIC_CPU_MASK_SIMPLE(10) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10
+			     (GIC_CPU_MASK_SIMPLE(10) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+
+	sysirq: intpol-controller@10200620 {
+		compatible = "mediatek,mt6797-sysirq",
+			     "mediatek,mt6577-sysirq";
+		interrupt-controller;
+		#interrupt-cells = <3>;
+		#intpol-bases = <2>;
+		interrupt-parent = <&gic>;
+		reg = <0 0x10220620 0 0x20>,
+		      <0 0x10220690 0 0x10>;
+	};
+
+	uart0: serial@11002000 {
+		compatible = "mediatek,mt6797-uart",
+			     "mediatek,mt6577-uart";
+		reg = <0 0x11002000 0 0x400>;
+		interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&clk26m>;
+		status = "disabled";
+	};
+
+	uart1: serial@11003000 {
+		compatible = "mediatek,mt6797-uart",
+			     "mediatek,mt6577-uart";
+		reg = <0 0x11003000 0 0x400>;
+		interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&clk26m>;
+		status = "disabled";
+	};
+
+	uart2: serial@11004000 {
+		compatible = "mediatek,mt6797-uart",
+			     "mediatek,mt6577-uart";
+		reg = <0 0x11004000 0 0x400>;
+		interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&clk26m>;
+		status = "disabled";
+	};
+
+	uart3: serial@11005000 {
+		compatible = "mediatek,mt6797-uart",
+			     "mediatek,mt6577-uart";
+		reg = <0 0x11005000 0 0x400>;
+		interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&clk26m>;
+		status = "disabled";
+	};
+
+	gic: interrupt-controller@19000000 {
+		compatible = "arm,gic-v3";
+		#interrupt-cells = <3>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-controller;
+		reg = <0 0x19000000 0 0x10000>,    /* GICD */
+		      <0 0x19200000 0 0x200000>,   /* GICR */
+		      <0 0x10240000 0 0x2000>;     /* GICC */
+	};
+};
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 05/10] dt-bindings: arm: mediatek: document clk bindings for MT6797
  2017-02-06 12:15 ` Mars Cheng
@ 2017-02-06 12:15   ` Mars Cheng
  -1 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-06 12:15 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: CC Hwang, Loda Chou, Miles Chen, Jades Shih, Yingjoe Chen,
	My Chuang, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, Marc Zyngier, Thomas Gleixner, Will Deacon,
	Stephen Boyd, linux-clk, Chieh-Jay Liu, Kevin-CW Chen,
	Mars Cheng

From: Kevin-CW Chen <kevin-cw.chen@mediatek.com>

This patch adds the binding documentation for apmixedsys, imgsys,
infracfg, mmsys, topckgen, vdecsys and vencsys for MT6797.

Signed-off-by: Kevin-CW Chen <kevin-cw.chen@mediatek.com>
Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
---
 .../bindings/arm/mediatek/mediatek,apmixedsys.txt  |    1 +
 .../bindings/arm/mediatek/mediatek,imgsys.txt      |    1 +
 .../bindings/arm/mediatek/mediatek,infracfg.txt    |    1 +
 .../bindings/arm/mediatek/mediatek,mmsys.txt       |    1 +
 .../bindings/arm/mediatek/mediatek,topckgen.txt    |    1 +
 .../bindings/arm/mediatek/mediatek,vdecsys.txt     |    1 +
 .../bindings/arm/mediatek/mediatek,vencsys.txt     |    3 ++-
 7 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
index cb0054a..cd977db 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
@@ -7,6 +7,7 @@ Required Properties:

 - compatible: Should be one of:
 	- "mediatek,mt2701-apmixedsys"
+	- "mediatek,mt6797-apmixedsys"
 	- "mediatek,mt8135-apmixedsys"
 	- "mediatek,mt8173-apmixedsys"
 - #clock-cells: Must be 1
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
index f6a9166..047b11a 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
@@ -7,6 +7,7 @@ Required Properties:

 - compatible: Should be one of:
 	- "mediatek,mt2701-imgsys", "syscon"
+	- "mediatek,mt6797-imgsys", "syscon"
 	- "mediatek,mt8173-imgsys", "syscon"
 - #clock-cells: Must be 1
 
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
index 1620ec2..58d58e2 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
@@ -8,6 +8,7 @@ Required Properties:
 
 - compatible: Should be one of:
 	- "mediatek,mt2701-infracfg", "syscon"
+	- "mediatek,mt6797-infracfg", "syscon"
 	- "mediatek,mt8135-infracfg", "syscon"
 	- "mediatek,mt8173-infracfg", "syscon"
 - #clock-cells: Must be 1
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
index 67dd2e4..70529e0 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
@@ -7,6 +7,7 @@ Required Properties:
 
 - compatible: Should be one of:
 	- "mediatek,mt2701-mmsys", "syscon"
+	- "mediatek,mt6797-mmsys", "syscon"
 	- "mediatek,mt8173-mmsys", "syscon"
 - #clock-cells: Must be 1
 
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
index 9f2fe78..ec93ecb 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
@@ -7,6 +7,7 @@ Required Properties:
 
 - compatible: Should be one of:
 	- "mediatek,mt2701-topckgen"
+	- "mediatek,mt6797-topckgen"
 	- "mediatek,mt8135-topckgen"
 	- "mediatek,mt8173-topckgen"
 - #clock-cells: Must be 1
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
index 2440f73..d150104 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
@@ -7,6 +7,7 @@ Required Properties:
 
 - compatible: Should be one of:
 	- "mediatek,mt2701-vdecsys", "syscon"
+	- "mediatek,mt6797-vdecsys", "syscon"
 	- "mediatek,mt8173-vdecsys", "syscon"
 - #clock-cells: Must be 1
 
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt
index 5bb2866..8a93be6 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt
@@ -5,7 +5,8 @@ The Mediatek vencsys controller provides various clocks to the system.
 
 Required Properties:
 
-- compatible: Should be:
+- compatible: Should be one of:
+	- "mediatek,mt6797-vencsys", "syscon"
 	- "mediatek,mt8173-vencsys", "syscon"
 - #clock-cells: Must be 1
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 05/10] dt-bindings: arm: mediatek: document clk bindings for MT6797
@ 2017-02-06 12:15   ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-06 12:15 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: CC Hwang, Loda Chou, Miles Chen, Jades Shih, Yingjoe Chen,
	My Chuang, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, Marc Zyngier, Thomas Gleixner, Will Deacon,
	Stephen Boyd, linux-clk, Chieh-Jay Liu, Kevin-CW Chen,
	Mars Cheng

From: Kevin-CW Chen <kevin-cw.chen@mediatek.com>

This patch adds the binding documentation for apmixedsys, imgsys,
infracfg, mmsys, topckgen, vdecsys and vencsys for MT6797.

Signed-off-by: Kevin-CW Chen <kevin-cw.chen@mediatek.com>
Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
---
 .../bindings/arm/mediatek/mediatek,apmixedsys.txt  |    1 +
 .../bindings/arm/mediatek/mediatek,imgsys.txt      |    1 +
 .../bindings/arm/mediatek/mediatek,infracfg.txt    |    1 +
 .../bindings/arm/mediatek/mediatek,mmsys.txt       |    1 +
 .../bindings/arm/mediatek/mediatek,topckgen.txt    |    1 +
 .../bindings/arm/mediatek/mediatek,vdecsys.txt     |    1 +
 .../bindings/arm/mediatek/mediatek,vencsys.txt     |    3 ++-
 7 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
index cb0054a..cd977db 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
@@ -7,6 +7,7 @@ Required Properties:

 - compatible: Should be one of:
 	- "mediatek,mt2701-apmixedsys"
+	- "mediatek,mt6797-apmixedsys"
 	- "mediatek,mt8135-apmixedsys"
 	- "mediatek,mt8173-apmixedsys"
 - #clock-cells: Must be 1
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
index f6a9166..047b11a 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
@@ -7,6 +7,7 @@ Required Properties:

 - compatible: Should be one of:
 	- "mediatek,mt2701-imgsys", "syscon"
+	- "mediatek,mt6797-imgsys", "syscon"
 	- "mediatek,mt8173-imgsys", "syscon"
 - #clock-cells: Must be 1
 
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
index 1620ec2..58d58e2 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
@@ -8,6 +8,7 @@ Required Properties:
 
 - compatible: Should be one of:
 	- "mediatek,mt2701-infracfg", "syscon"
+	- "mediatek,mt6797-infracfg", "syscon"
 	- "mediatek,mt8135-infracfg", "syscon"
 	- "mediatek,mt8173-infracfg", "syscon"
 - #clock-cells: Must be 1
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
index 67dd2e4..70529e0 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
@@ -7,6 +7,7 @@ Required Properties:
 
 - compatible: Should be one of:
 	- "mediatek,mt2701-mmsys", "syscon"
+	- "mediatek,mt6797-mmsys", "syscon"
 	- "mediatek,mt8173-mmsys", "syscon"
 - #clock-cells: Must be 1
 
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
index 9f2fe78..ec93ecb 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
@@ -7,6 +7,7 @@ Required Properties:
 
 - compatible: Should be one of:
 	- "mediatek,mt2701-topckgen"
+	- "mediatek,mt6797-topckgen"
 	- "mediatek,mt8135-topckgen"
 	- "mediatek,mt8173-topckgen"
 - #clock-cells: Must be 1
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
index 2440f73..d150104 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
@@ -7,6 +7,7 @@ Required Properties:
 
 - compatible: Should be one of:
 	- "mediatek,mt2701-vdecsys", "syscon"
+	- "mediatek,mt6797-vdecsys", "syscon"
 	- "mediatek,mt8173-vdecsys", "syscon"
 - #clock-cells: Must be 1
 
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt
index 5bb2866..8a93be6 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt
@@ -5,7 +5,8 @@ The Mediatek vencsys controller provides various clocks to the system.
 
 Required Properties:
 
-- compatible: Should be:
+- compatible: Should be one of:
+	- "mediatek,mt6797-vencsys", "syscon"
 	- "mediatek,mt8173-vencsys", "syscon"
 - #clock-cells: Must be 1
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 06/10] clk: mediatek: add clk support for MT6797
  2017-02-06 12:15 ` Mars Cheng
@ 2017-02-06 12:15   ` Mars Cheng
  -1 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-06 12:15 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: CC Hwang, Loda Chou, Miles Chen, Jades Shih, Yingjoe Chen,
	My Chuang, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, Marc Zyngier, Thomas Gleixner, Will Deacon,
	Stephen Boyd, linux-clk, Chieh-Jay Liu, Kevin-CW Chen,
	Mars Cheng

From: Kevin-CW Chen <kevin-cw.chen@mediatek.com>

Add MT6797 clock support, include topckgen, apmixedsys, infracfg
and subsystem clocks

Signed-off-by: Kevin-CW Chen <kevin-cw.chen@mediatek.com>
Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
---
 drivers/clk/mediatek/Kconfig           |   33 ++
 drivers/clk/mediatek/Makefile          |    5 +
 drivers/clk/mediatek/clk-mt6797-img.c  |   76 ++++
 drivers/clk/mediatek/clk-mt6797-mm.c   |  136 ++++++
 drivers/clk/mediatek/clk-mt6797-vdec.c |   93 +++++
 drivers/clk/mediatek/clk-mt6797-venc.c |   78 ++++
 drivers/clk/mediatek/clk-mt6797.c      |  716 ++++++++++++++++++++++++++++++++
 include/dt-bindings/clock/mt6797-clk.h |  281 +++++++++++++
 8 files changed, 1418 insertions(+)
 create mode 100644 drivers/clk/mediatek/clk-mt6797-img.c
 create mode 100644 drivers/clk/mediatek/clk-mt6797-mm.c
 create mode 100644 drivers/clk/mediatek/clk-mt6797-vdec.c
 create mode 100644 drivers/clk/mediatek/clk-mt6797-venc.c
 create mode 100644 drivers/clk/mediatek/clk-mt6797.c
 create mode 100644 include/dt-bindings/clock/mt6797-clk.h

diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
index 0bd631a..4b91eed 100644
--- a/drivers/clk/mediatek/Kconfig
+++ b/drivers/clk/mediatek/Kconfig
@@ -49,6 +49,39 @@ config COMMON_CLK_MT2701_BDPSYS
 	---help---
 	  This driver supports Mediatek MT2701 bdpsys clocks.

+config COMMON_CLK_MT6797
+       bool "Clock driver for Mediatek MT6797"
+       depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
+       select COMMON_CLK_MEDIATEK
+       default ARCH_MEDIATEK && ARM64
+       ---help---
+         This driver supports Mediatek MT6797 basic clocks.
+
+config COMMON_CLK_MT6797_MMSYS
+       bool "Clock driver for Mediatek MT6797 mmsys"
+       depends on COMMON_CLK_MT6797
+       ---help---
+         This driver supports Mediatek MT6797 mmsys clocks.
+
+config COMMON_CLK_MT6797_IMGSYS
+       bool "Clock driver for Mediatek MT6797 imgsys"
+       depends on COMMON_CLK_MT6797
+       ---help---
+         This driver supports Mediatek MT6797 imgsys clocks.
+
+config COMMON_CLK_MT6797_VDECSYS
+       bool "Clock driver for Mediatek MT6797 vdecsys"
+       depends on COMMON_CLK_MT6797
+       ---help---
+         This driver supports Mediatek MT6797 vdecsys clocks.
+
+config COMMON_CLK_MT6797_VENCSYS
+       bool "Clock driver for Mediatek MT6797 vencsys"
+       depends on COMMON_CLK_MT6797
+       ---help---
+         This driver supports Mediatek MT6797 vencsys clocks.
+
+
 config COMMON_CLK_MT8135
 	bool "Clock driver for Mediatek MT8135"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 19ae7ef..5c3afb8 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -1,5 +1,10 @@
 obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o
 obj-$(CONFIG_RESET_CONTROLLER) += reset.o
+obj-$(CONFIG_COMMON_CLK_MT6797) += clk-mt6797.o
+obj-$(CONFIG_COMMON_CLK_MT6797_IMGSYS) += clk-mt6797-img.o
+obj-$(CONFIG_COMMON_CLK_MT6797_MMSYS) += clk-mt6797-mm.o
+obj-$(CONFIG_COMMON_CLK_MT6797_VDECSYS) += clk-mt6797-vdec.o
+obj-$(CONFIG_COMMON_CLK_MT6797_VENCSYS) += clk-mt6797-venc.o
 obj-$(CONFIG_COMMON_CLK_MT2701) += clk-mt2701.o
 obj-$(CONFIG_COMMON_CLK_MT2701_BDPSYS) += clk-mt2701-bdp.o
 obj-$(CONFIG_COMMON_CLK_MT2701_ETHSYS) += clk-mt2701-eth.o
diff --git a/drivers/clk/mediatek/clk-mt6797-img.c b/drivers/clk/mediatek/clk-mt6797-img.c
new file mode 100644
index 0000000..94cc480
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt6797-img.c
@@ -0,0 +1,76 @@
+/* Copyright (c) 2017 MediaTek Inc.
+ * Author: Kevin Chen <kevin-cw.chen@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/clk-provider.h>
+#include <linux/platform_device.h>
+#include <dt-bindings/clock/mt6797-clk.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+static const struct mtk_gate_regs img_cg_regs = {
+	.set_ofs = 0x0004,
+	.clr_ofs = 0x0008,
+	.sta_ofs = 0x0000,
+};
+
+#define GATE_IMG(_id, _name, _parent, _shift) {		\
+		.id = _id,				\
+		.name = _name,				\
+		.parent_name = _parent,			\
+		.regs = &img_cg_regs,			\
+		.shift = _shift,			\
+		.ops = &mtk_clk_gate_ops_setclr,	\
+	}
+
+static const struct mtk_gate img_clks[] = {
+	GATE_IMG(CLK_IMG_FDVT, "img_fdvt", "mm_sel", 11),
+	GATE_IMG(CLK_IMG_DPE, "img_dpe", "mm_sel", 10),
+	GATE_IMG(CLK_IMG_DIP, "img_dip", "mm_sel", 6),
+	GATE_IMG(CLK_IMG_LARB6, "img_larb6", "mm_sel", 0),
+};
+
+static const struct of_device_id of_match_clk_mt6797_img[] = {
+	{ .compatible = "mediatek,mt6797-imgsys", },
+	{}
+};
+
+static int clk_mt6797_img_probe(struct platform_device *pdev)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+	struct device_node *node = pdev->dev.of_node;
+
+	clk_data = mtk_alloc_clk_data(CLK_IMG_NR);
+
+	mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks),
+			       clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		dev_err(&pdev->dev,
+			"could not register clock provider: %s: %d\n",
+			pdev->name, r);
+
+	return r;
+}
+
+static struct platform_driver clk_mt6797_img_drv = {
+	.probe = clk_mt6797_img_probe,
+	.driver = {
+		.name = "clk-mt6797-img",
+		.of_match_table = of_match_clk_mt6797_img,
+	},
+};
+
+builtin_platform_driver(clk_mt6797_img_drv);
diff --git a/drivers/clk/mediatek/clk-mt6797-mm.c b/drivers/clk/mediatek/clk-mt6797-mm.c
new file mode 100644
index 0000000..c57d3ee
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt6797-mm.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Kevin Chen <kevin-cw.chen@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/clk-provider.h>
+#include <linux/platform_device.h>
+#include <dt-bindings/clock/mt6797-clk.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+static const struct mtk_gate_regs mm0_cg_regs = {
+	.set_ofs = 0x0104,
+	.clr_ofs = 0x0108,
+	.sta_ofs = 0x0100,
+};
+
+static const struct mtk_gate_regs mm1_cg_regs = {
+	.set_ofs = 0x0114,
+	.clr_ofs = 0x0118,
+	.sta_ofs = 0x0110,
+};
+
+#define GATE_MM0(_id, _name, _parent, _shift) {			\
+	.id = _id,					\
+	.name = _name,					\
+	.parent_name = _parent,				\
+	.regs = &mm0_cg_regs,				\
+	.shift = _shift,				\
+	.ops = &mtk_clk_gate_ops_setclr,		\
+}
+
+#define GATE_MM1(_id, _name, _parent, _shift) {			\
+	.id = _id,					\
+	.name = _name,					\
+	.parent_name = _parent,				\
+	.regs = &mm1_cg_regs,				\
+	.shift = _shift,				\
+	.ops = &mtk_clk_gate_ops_setclr,		\
+}
+
+static const struct mtk_gate mm_clks[] = {
+	GATE_MM0(CLK_MM_SMI_COMMON, "mm_smi_common", "mm_sel", 0),
+	GATE_MM0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1),
+	GATE_MM0(CLK_MM_SMI_LARB5, "mm_smi_larb5", "mm_sel", 2),
+	GATE_MM0(CLK_MM_CAM_MDP, "mm_cam_mdp", "mm_sel", 3),
+	GATE_MM0(CLK_MM_MDP_RDMA0, "mm_mdp_rdma0", "mm_sel", 4),
+	GATE_MM0(CLK_MM_MDP_RDMA1, "mm_mdp_rdma1", "mm_sel", 5),
+	GATE_MM0(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "mm_sel", 6),
+	GATE_MM0(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "mm_sel", 7),
+	GATE_MM0(CLK_MM_MDP_RSZ2, "mm_mdp_rsz2", "mm_sel", 8),
+	GATE_MM0(CLK_MM_MDP_TDSHP, "mm_mdp_tdshp", "mm_sel", 9),
+	GATE_MM0(CLK_MM_MDP_COLOR, "mm_mdp_color", "mm_sel", 10),
+	GATE_MM0(CLK_MM_MDP_WDMA, "mm_mdp_wdma", "mm_sel", 11),
+	GATE_MM0(CLK_MM_MDP_WROT0, "mm_mdp_wrot0", "mm_sel", 12),
+	GATE_MM0(CLK_MM_MDP_WROT1, "mm_mdp_wrot1", "mm_sel", 13),
+	GATE_MM0(CLK_MM_FAKE_ENG, "mm_fake_eng", "mm_sel", 14),
+	GATE_MM0(CLK_MM_DISP_OVL0, "mm_disp_ovl0", "mm_sel", 15),
+	GATE_MM0(CLK_MM_DISP_OVL1, "mm_disp_ovl1", "mm_sel", 16),
+	GATE_MM0(CLK_MM_DISP_OVL0_2L, "mm_disp_ovl0_2l", "mm_sel", 17),
+	GATE_MM0(CLK_MM_DISP_OVL1_2L, "mm_disp_ovl1_2l", "mm_sel", 18),
+	GATE_MM0(CLK_MM_DISP_RDMA0, "mm_disp_rdma0", "mm_sel", 19),
+	GATE_MM0(CLK_MM_DISP_RDMA1, "mm_disp_rdma1", "mm_sel", 20),
+	GATE_MM0(CLK_MM_DISP_WDMA0, "mm_disp_wdma0", "mm_sel", 21),
+	GATE_MM0(CLK_MM_DISP_WDMA1, "mm_disp_wdma1", "mm_sel", 22),
+	GATE_MM0(CLK_MM_DISP_COLOR, "mm_disp_color", "mm_sel", 23),
+	GATE_MM0(CLK_MM_DISP_CCORR, "mm_disp_ccorr", "mm_sel", 24),
+	GATE_MM0(CLK_MM_DISP_AAL, "mm_disp_aal", "mm_sel", 25),
+	GATE_MM0(CLK_MM_DISP_GAMMA, "mm_disp_gamma", "mm_sel", 26),
+	GATE_MM0(CLK_MM_DISP_OD, "mm_disp_od", "mm_sel", 27),
+	GATE_MM0(CLK_MM_DISP_DITHER, "mm_disp_dither", "mm_sel", 28),
+	GATE_MM0(CLK_MM_DISP_UFOE, "mm_disp_ufoe", "mm_sel", 29),
+	GATE_MM0(CLK_MM_DISP_DSC, "mm_disp_dsc", "mm_sel", 30),
+	GATE_MM0(CLK_MM_DISP_SPLIT, "mm_disp_split", "mm_sel", 31),
+	GATE_MM1(CLK_MM_DSI0_MM_CLOCK, "mm_dsi0_mm_clock", "mm_sel", 0),
+	GATE_MM1(CLK_MM_DSI1_MM_CLOCK, "mm_dsi1_mm_clock", "mm_sel", 2),
+	GATE_MM1(CLK_MM_DPI_MM_CLOCK, "mm_dpi_mm_clock", "mm_sel", 4),
+	GATE_MM1(CLK_MM_DPI_INTERFACE_CLOCK, "mm_dpi_interface_clock",
+		 "dpi0_sel", 5),
+	GATE_MM1(CLK_MM_LARB4_AXI_ASIF_MM_CLOCK, "mm_larb4_axi_asif_mm_clock",
+		 "mm_sel", 6),
+	GATE_MM1(CLK_MM_LARB4_AXI_ASIF_MJC_CLOCK, "mm_larb4_axi_asif_mjc_clock",
+		 "mjc_sel", 7),
+	GATE_MM1(CLK_MM_DISP_OVL0_MOUT_CLOCK, "mm_disp_ovl0_mout_clock",
+		 "mm_sel", 8),
+	GATE_MM1(CLK_MM_FAKE_ENG2, "mm_fake_eng2", "mm_sel", 9),
+	GATE_MM1(CLK_MM_DSI0_INTERFACE_CLOCK, "mm_dsi0_interface_clock",
+		 "clk26m", 1),
+	GATE_MM1(CLK_MM_DSI1_INTERFACE_CLOCK, "mm_dsi1_interface_clock",
+		 "clk26m", 3),
+};
+
+static const struct of_device_id of_match_clk_mt6797_mm[] = {
+	{ .compatible = "mediatek,mt6797-mmsys", },
+	{}
+};
+
+static int clk_mt6797_mm_probe(struct platform_device *pdev)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+	struct device_node *node = pdev->dev.of_node;
+
+	clk_data = mtk_alloc_clk_data(CLK_MM_NR);
+
+	mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks),
+			       clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		dev_err(&pdev->dev,
+			"could not register clock provider: %s: %d\n",
+			pdev->name, r);
+
+	return r;
+}
+
+static struct platform_driver clk_mt6797_mm_drv = {
+	.probe = clk_mt6797_mm_probe,
+	.driver = {
+		.name = "clk-mt6797-mm",
+		.of_match_table = of_match_clk_mt6797_mm,
+	},
+};
+
+builtin_platform_driver(clk_mt6797_mm_drv);
diff --git a/drivers/clk/mediatek/clk-mt6797-vdec.c b/drivers/clk/mediatek/clk-mt6797-vdec.c
new file mode 100644
index 0000000..7c402ca
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt6797-vdec.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Kevin-CW Chen <kevin-cw.chen@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/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt6797-clk.h>
+
+static const struct mtk_gate_regs vdec0_cg_regs = {
+	.set_ofs = 0x0000,
+	.clr_ofs = 0x0004,
+	.sta_ofs = 0x0000,
+};
+
+static const struct mtk_gate_regs vdec1_cg_regs = {
+	.set_ofs = 0x0008,
+	.clr_ofs = 0x000c,
+	.sta_ofs = 0x0008,
+};
+
+#define GATE_VDEC0(_id, _name, _parent, _shift) {		\
+	.id = _id,					\
+	.name = _name,					\
+	.parent_name = _parent,				\
+	.regs = &vdec0_cg_regs,				\
+	.shift = _shift,				\
+	.ops = &mtk_clk_gate_ops_setclr_inv,		\
+}
+
+#define GATE_VDEC1(_id, _name, _parent, _shift) {		\
+	.id = _id,					\
+	.name = _name,					\
+	.parent_name = _parent,				\
+	.regs = &vdec1_cg_regs,				\
+	.shift = _shift,				\
+	.ops = &mtk_clk_gate_ops_setclr_inv,		\
+}
+
+static const struct mtk_gate vdec_clks[] = {
+	GATE_VDEC0(CLK_VDEC_CKEN_ENG, "vdec_cken_eng", "vdec_sel", 8),
+	GATE_VDEC0(CLK_VDEC_ACTIVE, "vdec_active", "vdec_sel", 4),
+	GATE_VDEC0(CLK_VDEC_CKEN, "vdec_cken", "vdec_sel", 0),
+	GATE_VDEC1(CLK_VDEC_LARB1_CKEN, "vdec_larb1_cken", "mm_sel", 0),
+};
+
+static const struct of_device_id of_match_clk_mt6797_vdec[] = {
+	{ .compatible = "mediatek,mt6797-vdecsys", },
+	{}
+};
+
+static int clk_mt6797_vdec_probe(struct platform_device *pdev)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+	struct device_node *node = pdev->dev.of_node;
+
+	clk_data = mtk_alloc_clk_data(CLK_VDEC_NR);
+
+	mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks),
+			       clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		dev_err(&pdev->dev,
+			"could not register clock provider: %s: %d\n",
+			pdev->name, r);
+
+	return r;
+}
+
+static struct platform_driver clk_mt6797_vdec_drv = {
+	.probe = clk_mt6797_vdec_probe,
+	.driver = {
+		.name = "clk-mt6797-vdec",
+		.of_match_table = of_match_clk_mt6797_vdec,
+	},
+};
+
+builtin_platform_driver(clk_mt6797_vdec_drv);
diff --git a/drivers/clk/mediatek/clk-mt6797-venc.c b/drivers/clk/mediatek/clk-mt6797-venc.c
new file mode 100644
index 0000000..e73d517
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt6797-venc.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Kevin Chen <kevin-cw.chen@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/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt6797-clk.h>
+
+static const struct mtk_gate_regs venc_cg_regs = {
+	.set_ofs = 0x0004,
+	.clr_ofs = 0x0008,
+	.sta_ofs = 0x0000,
+};
+
+#define GATE_VENC(_id, _name, _parent, _shift) {	\
+		.id = _id,				\
+		.name = _name,				\
+		.parent_name = _parent,			\
+		.regs = &venc_cg_regs,			\
+		.shift = _shift,			\
+		.ops = &mtk_clk_gate_ops_setclr_inv,	\
+	}
+
+static const struct mtk_gate venc_clks[] = {
+	GATE_VENC(CLK_VENC_0, "venc_0", "mm_sel", 0),
+	GATE_VENC(CLK_VENC_1, "venc_1", "venc_sel", 4),
+	GATE_VENC(CLK_VENC_2, "venc_2", "venc_sel", 8),
+	GATE_VENC(CLK_VENC_3, "venc_3", "venc_sel", 12),
+};
+
+static const struct of_device_id of_match_clk_mt6797_venc[] = {
+	{ .compatible = "mediatek,mt6797-vencsys", },
+	{}
+};
+
+static int clk_mt6797_venc_probe(struct platform_device *pdev)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+	struct device_node *node = pdev->dev.of_node;
+
+	clk_data = mtk_alloc_clk_data(CLK_VENC_NR);
+
+	mtk_clk_register_gates(node, venc_clks, ARRAY_SIZE(venc_clks),
+			       clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		dev_err(&pdev->dev,
+			"could not register clock provider: %s: %d\n",
+			pdev->name, r);
+
+	return r;
+}
+
+static struct platform_driver clk_mt6797_venc_drv = {
+	.probe = clk_mt6797_venc_probe,
+	.driver = {
+		.name = "clk-mt6797-venc",
+		.of_match_table = of_match_clk_mt6797_venc,
+	},
+};
+
+builtin_platform_driver(clk_mt6797_venc_drv);
diff --git a/drivers/clk/mediatek/clk-mt6797.c b/drivers/clk/mediatek/clk-mt6797.c
new file mode 100644
index 0000000..7ebb7f1
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt6797.c
@@ -0,0 +1,716 @@
+/*
+ * Copyright (c) 2016 MediaTek Inc.
+ * Author: Kevin Chen <kevin-cw.chen@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/clk.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt6797-clk.h>
+
+/*
+ * For some clocks, we don't care what their actual rates are. And these
+ * clocks may change their rate on different products or different scenarios.
+ * So we model these clocks' rate as 0, to denote it's not an actual rate.
+ */
+
+static DEFINE_SPINLOCK(mt6797_clk_lock);
+
+static const struct mtk_fixed_factor top_fixed_divs[] = {
+	FACTOR(CLK_TOP_SYSPLL_CK, "syspll_ck", "mainpll", 1, 1),
+	FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "mainpll", 1, 2),
+	FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "syspll_d2", 1, 2),
+	FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "syspll_d2", 1, 4),
+	FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "syspll_d2", 1, 8),
+	FACTOR(CLK_TOP_SYSPLL1_D16, "syspll1_d16", "syspll_d2", 1, 16),
+	FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "mainpll", 1, 3),
+	FACTOR(CLK_TOP_SYSPLL_D3_D3, "syspll_d3_d3", "syspll_d3", 1, 3),
+	FACTOR(CLK_TOP_SYSPLL2_D2, "syspll2_d2", "syspll_d3", 1, 2),
+	FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "syspll_d3", 1, 4),
+	FACTOR(CLK_TOP_SYSPLL2_D8, "syspll2_d8", "syspll_d3", 1, 8),
+	FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll", 1, 5),
+	FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "syspll_d5", 1, 2),
+	FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "syspll_d5", 1, 4),
+	FACTOR(CLK_TOP_SYSPLL_D7, "syspll_d7", "mainpll", 1, 7),
+	FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "syspll_d7", 1, 2),
+	FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "syspll_d7", 1, 4),
+	FACTOR(CLK_TOP_UNIVPLL_CK, "univpll_ck", "univpll", 1, 1),
+	FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll", 1, 7),
+	FACTOR(CLK_TOP_UNIVPLL_D26, "univpll_d26", "univpll", 1, 26),
+	FACTOR(CLK_TOP_SSUSB_PHY_48M_CK, "ssusb_phy_48m_ck", "univpll", 1, 1),
+	FACTOR(CLK_TOP_USB_PHY48M_CK, "usb_phy48m_ck", "univpll", 1, 1),
+	FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll", 1, 2),
+	FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_d2", 1, 2),
+	FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_d2", 1, 4),
+	FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_d2", 1, 8),
+	FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll", 1, 3),
+	FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll", 1, 2),
+	FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll", 1, 4),
+	FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll", 1, 8),
+	FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5),
+	FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2", "univpll_d5", 1, 2),
+	FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4", "univpll_d5", 1, 4),
+	FACTOR(CLK_TOP_UNIVPLL3_D8, "univpll3_d8", "univpll_d5", 1, 8),
+	FACTOR(CLK_TOP_ULPOSC_CK_ORG, "ulposc_ck_org", "ulposc", 1, 1),
+	FACTOR(CLK_TOP_ULPOSC_CK, "ulposc_ck", "ulposc_ck_org", 1, 3),
+	FACTOR(CLK_TOP_ULPOSC_D2, "ulposc_d2", "ulposc_ck", 1, 2),
+	FACTOR(CLK_TOP_ULPOSC_D3, "ulposc_d3", "ulposc_ck", 1, 4),
+	FACTOR(CLK_TOP_ULPOSC_D4, "ulposc_d4", "ulposc_ck", 1, 8),
+	FACTOR(CLK_TOP_ULPOSC_D8, "ulposc_d8", "ulposc_ck", 1, 10),
+	FACTOR(CLK_TOP_ULPOSC_D10, "ulposc_d10", "ulposc_ck_org", 1, 1),
+	FACTOR(CLK_TOP_APLL1_CK, "apll1_ck", "apll1", 1, 1),
+	FACTOR(CLK_TOP_APLL2_CK, "apll2_ck", "apll2", 1, 1),
+	FACTOR(CLK_TOP_MFGPLL_CK, "mfgpll_ck", "mfgpll", 1, 1),
+	FACTOR(CLK_TOP_MFGPLL_D2, "mfgpll_d2", "mfgpll_ck", 1, 2),
+	FACTOR(CLK_TOP_IMGPLL_CK, "imgpll_ck", "imgpll", 1, 1),
+	FACTOR(CLK_TOP_IMGPLL_D2, "imgpll_d2", "imgpll_ck", 1, 2),
+	FACTOR(CLK_TOP_IMGPLL_D4, "imgpll_d4", "imgpll_ck", 1, 4),
+	FACTOR(CLK_TOP_CODECPLL_CK, "codecpll_ck", "codecpll", 1, 1),
+	FACTOR(CLK_TOP_CODECPLL_D2, "codecpll_d2", "codecpll_ck", 1, 2),
+	FACTOR(CLK_TOP_VDECPLL_CK, "vdecpll_ck", "vdecpll", 1, 1),
+	FACTOR(CLK_TOP_TVDPLL_CK, "tvdpll_ck", "tvdpll", 1, 1),
+	FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll_ck", 1, 2),
+	FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll_ck", 1, 4),
+	FACTOR(CLK_TOP_TVDPLL_D8, "tvdpll_d8", "tvdpll_ck", 1, 8),
+	FACTOR(CLK_TOP_TVDPLL_D16, "tvdpll_d16", "tvdpll_ck", 1, 16),
+	FACTOR(CLK_TOP_MSDCPLL_CK, "msdcpll_ck", "msdcpll", 1, 1),
+	FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll_ck", 1, 2),
+	FACTOR(CLK_TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll_ck", 1, 4),
+	FACTOR(CLK_TOP_MSDCPLL_D8, "msdcpll_d8", "msdcpll_ck", 1, 8),
+};
+
+static const char * const axi_parents[] = {
+	"clk26m",
+	"syspll_d7",
+	"ulposc_axi_ck_mux",
+};
+
+static const char * const ulposc_axi_ck_mux_parents[] = {
+	"syspll1_d4",
+	"ulposc_axi_ck_mux_pre",
+};
+
+static const char * const ulposc_axi_ck_mux_pre_parents[] = {
+	"ulposc_d2",
+	"ulposc_d3",
+};
+
+static const char * const ddrphycfg_parents[] = {
+	"clk26m",
+	"syspll3_d2",
+	"syspll2_d4",
+	"syspll1_d8",
+};
+
+static const char * const mm_parents[] = {
+	"clk26m",
+	"imgpll_ck",
+	"univpll1_d2",
+	"syspll1_d2",
+};
+
+static const char * const pwm_parents[] = {
+	"clk26m",
+	"univpll2_d4",
+	"ulposc_d2",
+	"ulposc_d3",
+	"ulposc_d8",
+	"ulposc_d10",
+	"ulposc_d4",
+};
+
+static const char * const vdec_parents[] = {
+	"clk26m",
+	"vdecpll_ck",
+	"imgpll_ck",
+	"syspll_d3",
+	"univpll_d5",
+	"clk26m",
+	"clk26m",
+};
+
+static const char * const venc_parents[] = {
+	"clk26m",
+	"codecpll_ck",
+	"syspll_d3",
+};
+
+static const char * const mfg_parents[] = {
+	"clk26m",
+	"mfgpll_ck",
+	"syspll_d3",
+	"univpll_d3",
+};
+
+static const char * const camtg[] = {
+	"clk26m",
+	"univpll_d26",
+	"univpll2_d2",
+};
+
+static const char * const uart_parents[] = {
+	"clk26m",
+	"univpll2_d8",
+};
+
+static const char * const spi_parents[] = {
+	"clk26m",
+	"syspll3_d2",
+	"syspll2_d4",
+	"ulposc_spi_ck_mux",
+};
+
+static const char * const ulposc_spi_ck_mux_parents[] = {
+	"ulposc_d2",
+	"ulposc_d3",
+};
+
+static const char * const usb20_parents[] = {
+	"clk26m",
+	"univpll1_d8",
+	"syspll4_d2",
+};
+
+static const char * const msdc50_0_hclk_parents[] = {
+	"clk26m",
+	"syspll1_d2",
+	"syspll2_d2",
+	"syspll4_d2",
+};
+
+static const char * const msdc50_0_parents[] = {
+	"clk26m",
+	"msdcpll",
+	"syspll_d3",
+	"univpll1_d4",
+	"syspll2_d2",
+	"syspll_d7",
+	"msdcpll_d2",
+	"univpll1_d2",
+	"univpll_d3",
+};
+
+static const char * const msdc30_1_parents[] = {
+	"clk26m",
+	"univpll2_d2",
+	"msdcpll_d2",
+	"univpll1_d4",
+	"syspll2_d2",
+	"syspll_d7",
+	"univpll_d7",
+};
+
+static const char * const msdc30_2_parents[] = {
+	"clk26m",
+	"univpll2_d8",
+	"syspll2_d8",
+	"syspll1_d8",
+	"msdcpll_d8",
+	"syspll3_d4",
+	"univpll_d26",
+};
+
+static const char * const audio_parents[] = {
+	"clk26m",
+	"syspll3_d4",
+	"syspll4_d4",
+	"syspll1_d16",
+};
+
+static const char * const aud_intbus_parents[] = {
+	"clk26m",
+	"syspll1_d4",
+	"syspll4_d2",
+};
+
+static const char * const pmicspi_parents[] = {
+	"clk26m",
+	"univpll_d26",
+	"syspll3_d4",
+	"syspll1_d8",
+	"ulposc_d4",
+	"ulposc_d8",
+	"syspll2_d8",
+};
+
+static const char * const scp_parents[] = {
+	"clk26m",
+	"syspll_d3",
+	"ulposc_ck",
+	"univpll_d5",
+};
+
+static const char * const atb_parents[] = {
+	"clk26m",
+	"syspll1_d2",
+	"syspll_d5",
+};
+
+static const char * const mjc_parents[] = {
+	"clk26m",
+	"imgpll_ck",
+	"univpll_d5",
+	"syspll1_d2",
+};
+
+static const char * const dpi0_parents[] = {
+	"clk26m",
+	"tvdpll_d2",
+	"tvdpll_d4",
+	"tvdpll_d8",
+	"tvdpll_d16",
+	"clk26m",
+	"clk26m",
+};
+
+static const char * const aud_1_parents[] = {
+	"clk26m",
+	"apll1_ck",
+};
+
+static const char * const aud_2_parents[] = {
+	"clk26m",
+	"apll2_ck",
+};
+
+static const char * const ssusb_top_sys_parents[] = {
+	"clk26m",
+	"univpll3_d2",
+};
+
+static const char * const spm_parents[] = {
+	"clk26m",
+	"syspll1_d8",
+};
+
+static const char * const bsi_spi_parents[] = {
+	"clk26m",
+	"syspll_d3_d3",
+	"syspll1_d4",
+	"syspll_d7",
+};
+
+static const char * const audio_h_parents[] = {
+	"clk26m",
+	"apll2_ck",
+	"apll1_ck",
+	"univpll_d7",
+};
+
+static const char * const mfg_52m_parents[] = {
+	"clk26m",
+	"univpll2_d8",
+	"univpll2_d4",
+	"univpll2_d4",
+};
+
+static const char * const anc_md32_parents[] = {
+	"clk26m",
+	"syspll1_d2",
+	"univpll_d5",
+};
+
+static const struct mtk_composite top_muxes[] = {
+	MUX(CLK_TOP_MUX_ULPOSC_AXI_CK_MUX_PRE, "ulposc_axi_ck_mux_pre",
+	    ulposc_axi_ck_mux_pre_parents, 0x0040, 3, 1),
+	MUX(CLK_TOP_MUX_ULPOSC_AXI_CK_MUX, "ulposc_axi_ck_mux",
+	    ulposc_axi_ck_mux_parents, 0x0040, 2, 1),
+	MUX(CLK_TOP_MUX_AXI, "axi_sel", axi_parents,
+	    0x0040, 0, 2),
+	MUX(CLK_TOP_MUX_DDRPHYCFG, "ddrphycfg_sel", ddrphycfg_parents,
+	    0x0040, 16, 2),
+	MUX(CLK_TOP_MUX_MM, "mm_sel", mm_parents,
+	    0x0040, 24, 2),
+	MUX_GATE(CLK_TOP_MUX_PWM, "pwm_sel", pwm_parents, 0x0050, 0, 3, 7),
+	MUX_GATE(CLK_TOP_MUX_VDEC, "vdec_sel", vdec_parents, 0x0050, 8, 3, 15),
+	MUX_GATE(CLK_TOP_MUX_VENC, "venc_sel", venc_parents, 0x0050, 16, 2, 23),
+	MUX_GATE(CLK_TOP_MUX_MFG, "mfg_sel", mfg_parents, 0x0050, 24, 2, 31),
+	MUX_GATE(CLK_TOP_MUX_CAMTG, "camtg_sel", camtg, 0x0060, 0, 2, 7),
+	MUX_GATE(CLK_TOP_MUX_UART, "uart_sel", uart_parents, 0x0060, 8, 1, 15),
+	MUX_GATE(CLK_TOP_MUX_SPI, "spi_sel", spi_parents, 0x0060, 16, 2, 23),
+	MUX(CLK_TOP_MUX_ULPOSC_SPI_CK_MUX, "ulposc_spi_ck_mux",
+	    ulposc_spi_ck_mux_parents, 0x0060, 18, 1),
+	MUX_GATE(CLK_TOP_MUX_USB20, "usb20_sel", usb20_parents,
+		 0x0060, 24, 2, 31),
+	MUX(CLK_TOP_MUX_MSDC50_0_HCLK, "msdc50_0_hclk_sel",
+	    msdc50_0_hclk_parents, 0x0070, 8, 2),
+	MUX_GATE(CLK_TOP_MUX_MSDC50_0, "msdc50_0_sel", msdc50_0_parents,
+		 0x0070, 16, 4, 23),
+	MUX_GATE(CLK_TOP_MUX_MSDC30_1, "msdc30_1_sel", msdc30_1_parents,
+		 0x0070, 24, 3, 31),
+	MUX_GATE(CLK_TOP_MUX_MSDC30_2, "msdc30_2_sel", msdc30_2_parents,
+		 0x0080, 0, 3, 7),
+	MUX_GATE(CLK_TOP_MUX_AUDIO, "audio_sel", audio_parents,
+		 0x0080, 16, 2, 23),
+	MUX(CLK_TOP_MUX_AUD_INTBUS, "aud_intbus_sel", aud_intbus_parents,
+	    0x0080, 24, 2),
+	MUX(CLK_TOP_MUX_PMICSPI, "pmicspi_sel", pmicspi_parents,
+	    0x0090, 0, 3),
+	MUX(CLK_TOP_MUX_SCP, "scp_sel", scp_parents,
+	    0x0090, 8, 2),
+	MUX(CLK_TOP_MUX_ATB, "atb_sel", atb_parents,
+	    0x0090, 16, 2),
+	MUX_GATE(CLK_TOP_MUX_MJC, "mjc_sel", mjc_parents, 0x0090, 24, 2, 31),
+	MUX_GATE(CLK_TOP_MUX_DPI0, "dpi0_sel", dpi0_parents, 0x00A0, 0, 3, 7),
+	MUX_GATE(CLK_TOP_MUX_AUD_1, "aud_1_sel", aud_1_parents,
+		 0x00A0, 16, 1, 23),
+	MUX_GATE(CLK_TOP_MUX_AUD_2, "aud_2_sel", aud_2_parents,
+		 0x00A0, 24, 1, 31),
+	MUX(CLK_TOP_MUX_SSUSB_TOP_SYS, "ssusb_top_sys_sel",
+	    ssusb_top_sys_parents, 0x00B0, 8, 1),
+	MUX(CLK_TOP_MUX_SPM, "spm_sel", spm_parents,
+	    0x00C0, 0, 1),
+	MUX(CLK_TOP_MUX_BSI_SPI, "bsi_spi_sel", bsi_spi_parents,
+	    0x00C0, 8, 2),
+	MUX_GATE(CLK_TOP_MUX_AUDIO_H, "audio_h_sel", audio_h_parents,
+		 0x00C0, 16, 2, 23),
+	MUX_GATE(CLK_TOP_MUX_ANC_MD32, "anc_md32_sel", anc_md32_parents,
+		 0x00C0, 24, 2, 31),
+	MUX(CLK_TOP_MUX_MFG_52M, "mfg_52m_sel", mfg_52m_parents,
+	    0x0104, 1, 2),
+};
+
+static int mtk_topckgen_init(struct platform_device *pdev)
+{
+	struct clk_onecell_data *clk_data;
+	void __iomem *base;
+	struct device_node *node = pdev->dev.of_node;
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	clk_data = mtk_alloc_clk_data(CLK_TOP_NR);
+
+	mtk_clk_register_factors(top_fixed_divs, ARRAY_SIZE(top_fixed_divs),
+				 clk_data);
+
+	mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
+				    &mt6797_clk_lock, clk_data);
+
+	return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+static const struct mtk_gate_regs infra0_cg_regs = {
+	.set_ofs = 0x0080,
+	.clr_ofs = 0x0084,
+	.sta_ofs = 0x0090,
+};
+
+static const struct mtk_gate_regs infra1_cg_regs = {
+	.set_ofs = 0x0088,
+	.clr_ofs = 0x008c,
+	.sta_ofs = 0x0094,
+};
+
+static const struct mtk_gate_regs infra2_cg_regs = {
+	.set_ofs = 0x00a8,
+	.clr_ofs = 0x00ac,
+	.sta_ofs = 0x00b0,
+};
+
+#define GATE_ICG0(_id, _name, _parent, _shift) {	\
+	.id = _id,					\
+	.name = _name,					\
+	.parent_name = _parent,				\
+	.regs = &infra0_cg_regs,			\
+	.shift = _shift,				\
+	.ops = &mtk_clk_gate_ops_setclr,		\
+}
+
+#define GATE_ICG1(_id, _name, _parent, _shift) {	\
+	.id = _id,					\
+	.name = _name,					\
+	.parent_name = _parent,				\
+	.regs = &infra1_cg_regs,			\
+	.shift = _shift,				\
+	.ops = &mtk_clk_gate_ops_setclr,		\
+}
+
+#define GATE_ICG2(_id, _name, _parent, _shift) {	\
+	.id = _id,					\
+	.name = _name,					\
+	.parent_name = _parent,				\
+	.regs = &infra2_cg_regs,			\
+	.shift = _shift,				\
+	.ops = &mtk_clk_gate_ops_setclr,		\
+}
+
+static const struct mtk_gate infra_clks[] = {
+	GATE_ICG0(CLK_INFRA_PMIC_TMR, "infra_pmic_tmr", "ulposc", 0),
+	GATE_ICG0(CLK_INFRA_PMIC_AP, "infra_pmic_ap", "pmicspi_sel", 1),
+	GATE_ICG0(CLK_INFRA_PMIC_MD, "infra_pmic_md", "pmicspi_sel", 2),
+	GATE_ICG0(CLK_INFRA_PMIC_CONN, "infra_pmic_conn", "pmicspi_sel", 3),
+	GATE_ICG0(CLK_INFRA_SCP, "infra_scp", "scp_sel", 4),
+	GATE_ICG0(CLK_INFRA_SEJ, "infra_sej", "axi_sel", 5),
+	GATE_ICG0(CLK_INFRA_APXGPT, "infra_apxgpt", "axi_sel", 6),
+	GATE_ICG0(CLK_INFRA_SEJ_13M, "infra_sej_13m", "clk26m", 7),
+	GATE_ICG0(CLK_INFRA_ICUSB, "infra_icusb", "usb20_sel", 8),
+	GATE_ICG0(CLK_INFRA_GCE, "infra_gce", "axi_sel", 9),
+	GATE_ICG0(CLK_INFRA_THERM, "infra_therm", "axi_sel", 10),
+	GATE_ICG0(CLK_INFRA_I2C0, "infra_i2c0", "axi_sel", 11),
+	GATE_ICG0(CLK_INFRA_I2C1, "infra_i2c1", "axi_sel", 12),
+	GATE_ICG0(CLK_INFRA_I2C2, "infra_i2c2", "axi_sel", 13),
+	GATE_ICG0(CLK_INFRA_I2C3, "infra_i2c3", "axi_sel", 14),
+	GATE_ICG0(CLK_INFRA_PWM_HCLK, "infra_pwm_hclk", "axi_sel", 15),
+	GATE_ICG0(CLK_INFRA_PWM1, "infra_pwm1", "axi_sel", 16),
+	GATE_ICG0(CLK_INFRA_PWM2, "infra_pwm2", "axi_sel", 17),
+	GATE_ICG0(CLK_INFRA_PWM3, "infra_pwm3", "axi_sel", 18),
+	GATE_ICG0(CLK_INFRA_PWM4, "infra_pwm4", "axi_sel", 19),
+	GATE_ICG0(CLK_INFRA_PWM, "infra_pwm", "axi_sel", 21),
+	GATE_ICG0(CLK_INFRA_UART0, "infra_uart0", "uart_sel", 22),
+	GATE_ICG0(CLK_INFRA_UART1, "infra_uart1", "uart_sel", 23),
+	GATE_ICG0(CLK_INFRA_UART2, "infra_uart2", "uart_sel", 24),
+	GATE_ICG0(CLK_INFRA_UART3, "infra_uart3", "uart_sel", 25),
+	GATE_ICG0(CLK_INFRA_MD2MD_CCIF_0, "infra_md2md_ccif_0", "axi_sel", 27),
+	GATE_ICG0(CLK_INFRA_MD2MD_CCIF_1, "infra_md2md_ccif_1", "axi_sel", 28),
+	GATE_ICG0(CLK_INFRA_MD2MD_CCIF_2, "infra_md2md_ccif_2", "axi_sel", 29),
+	GATE_ICG0(CLK_INFRA_FHCTL, "infra_fhctl", "clk26m", 30),
+	GATE_ICG0(CLK_INFRA_BTIF, "infra_btif", "axi_sel", 31),
+	GATE_ICG1(CLK_INFRA_MD2MD_CCIF_3, "infra_md2md_ccif_3", "axi_sel", 0),
+	GATE_ICG1(CLK_INFRA_SPI, "infra_spi", "spi_sel", 1),
+	GATE_ICG1(CLK_INFRA_MSDC0, "infra_msdc0", "msdc50_0_sel", 2),
+	GATE_ICG1(CLK_INFRA_MD2MD_CCIF_4, "infra_md2md_ccif_4", "axi_sel", 3),
+	GATE_ICG1(CLK_INFRA_MSDC1, "infra_msdc1", "msdc30_1_sel", 4),
+	GATE_ICG1(CLK_INFRA_MSDC2, "infra_msdc2", "msdc30_2_sel", 5),
+	GATE_ICG1(CLK_INFRA_MD2MD_CCIF_5, "infra_md2md_ccif_5", "axi_sel", 7),
+	GATE_ICG1(CLK_INFRA_GCPU, "infra_gcpu", "axi_sel", 8),
+	GATE_ICG1(CLK_INFRA_TRNG, "infra_trng", "axi_sel", 9),
+	GATE_ICG1(CLK_INFRA_AUXADC, "infra_auxadc", "clk26m", 10),
+	GATE_ICG1(CLK_INFRA_CPUM, "infra_cpum", "axi_sel", 11),
+	GATE_ICG1(CLK_INFRA_AP_C2K_CCIF_0, "infra_ap_c2k_ccif_0",
+		  "axi_sel", 12),
+	GATE_ICG1(CLK_INFRA_AP_C2K_CCIF_1, "infra_ap_c2k_ccif_1",
+		  "axi_sel", 13),
+	GATE_ICG1(CLK_INFRA_CLDMA, "infra_cldma", "axi_sel", 16),
+	GATE_ICG1(CLK_INFRA_DISP_PWM, "infra_disp_pwm", "pwm_sel", 17),
+	GATE_ICG1(CLK_INFRA_AP_DMA, "infra_ap_dma", "axi_sel", 18),
+	GATE_ICG1(CLK_INFRA_DEVICE_APC, "infra_device_apc", "axi_sel", 20),
+	GATE_ICG1(CLK_INFRA_L2C_SRAM, "infra_l2c_sram", "mm_sel", 22),
+	GATE_ICG1(CLK_INFRA_CCIF_AP, "infra_ccif_ap", "axi_sel", 23),
+	GATE_ICG1(CLK_INFRA_AUDIO, "infra_audio", "axi_sel", 25),
+	GATE_ICG1(CLK_INFRA_CCIF_MD, "infra_ccif_md", "axi_sel", 26),
+	GATE_ICG1(CLK_INFRA_DRAMC_F26M, "infra_dramc_f26m", "clk26m", 31),
+	GATE_ICG2(CLK_INFRA_I2C4, "infra_i2c4", "axi_sel", 0),
+	GATE_ICG2(CLK_INFRA_I2C_APPM, "infra_i2c_appm", "axi_sel", 1),
+	GATE_ICG2(CLK_INFRA_I2C_GPUPM, "infra_i2c_gpupm", "axi_sel", 2),
+	GATE_ICG2(CLK_INFRA_I2C2_IMM, "infra_i2c2_imm", "axi_sel", 3),
+	GATE_ICG2(CLK_INFRA_I2C2_ARB, "infra_i2c2_arb", "axi_sel", 4),
+	GATE_ICG2(CLK_INFRA_I2C3_IMM, "infra_i2c3_imm", "axi_sel", 5),
+	GATE_ICG2(CLK_INFRA_I2C3_ARB, "infra_i2c3_arb", "axi_sel", 6),
+	GATE_ICG2(CLK_INFRA_I2C5, "infra_i2c5", "axi_sel", 7),
+	GATE_ICG2(CLK_INFRA_SYS_CIRQ, "infra_sys_cirq", "axi_sel", 8),
+	GATE_ICG2(CLK_INFRA_SPI1, "infra_spi1", "spi_sel", 10),
+	GATE_ICG2(CLK_INFRA_DRAMC_B_F26M, "infra_dramc_b_f26m", "clk26m", 11),
+	GATE_ICG2(CLK_INFRA_ANC_MD32, "infra_anc_md32", "anc_md32_sel", 12),
+	GATE_ICG2(CLK_INFRA_ANC_MD32_32K, "infra_anc_md32_32k", "clk26m", 13),
+	GATE_ICG2(CLK_INFRA_DVFS_SPM1, "infra_dvfs_spm1", "axi_sel", 15),
+	GATE_ICG2(CLK_INFRA_AES_TOP0, "infra_aes_top0", "axi_sel", 16),
+	GATE_ICG2(CLK_INFRA_AES_TOP1, "infra_aes_top1", "axi_sel", 17),
+	GATE_ICG2(CLK_INFRA_SSUSB_BUS, "infra_ssusb_bus", "axi_sel", 18),
+	GATE_ICG2(CLK_INFRA_SPI2, "infra_spi2", "spi_sel", 19),
+	GATE_ICG2(CLK_INFRA_SPI3, "infra_spi3", "spi_sel", 20),
+	GATE_ICG2(CLK_INFRA_SPI4, "infra_spi4", "spi_sel", 21),
+	GATE_ICG2(CLK_INFRA_SPI5, "infra_spi5", "spi_sel", 22),
+	GATE_ICG2(CLK_INFRA_IRTX, "infra_irtx", "spi_sel", 23),
+	GATE_ICG2(CLK_INFRA_SSUSB_SYS, "infra_ssusb_sys",
+		  "ssusb_top_sys_sel", 24),
+	GATE_ICG2(CLK_INFRA_SSUSB_REF, "infra_ssusb_ref", "clk26m", 9),
+	GATE_ICG2(CLK_INFRA_AUDIO_26M, "infra_audio_26m", "clk26m", 26),
+	GATE_ICG2(CLK_INFRA_AUDIO_26M_PAD_TOP, "infra_audio_26m_pad_top",
+		  "clk26m", 27),
+	GATE_ICG2(CLK_INFRA_MODEM_TEMP_SHARE, "infra_modem_temp_share",
+		  "axi_sel", 28),
+	GATE_ICG2(CLK_INFRA_VAD_WRAP_SOC, "infra_vad_wrap_soc", "axi_sel", 29),
+	GATE_ICG2(CLK_INFRA_DRAMC_CONF, "infra_dramc_conf", "axi_sel", 30),
+	GATE_ICG2(CLK_INFRA_DRAMC_B_CONF, "infra_dramc_b_conf", "axi_sel", 31),
+	GATE_ICG1(CLK_INFRA_MFG_VCG, "infra_mfg_vcg", "mfg_52m_sel", 14),
+};
+
+static const struct mtk_fixed_factor infra_fixed_divs[] = {
+	FACTOR(CLK_INFRA_13M, "clk13m", "clk26m", 1, 2),
+};
+
+static struct clk_onecell_data *infra_clk_data;
+
+static void mtk_infrasys_init_early(struct device_node *node)
+{
+	int r, i;
+
+	if (!infra_clk_data) {
+		infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR);
+
+		for (i = 0; i < CLK_INFRA_NR; i++)
+			infra_clk_data->clks[i] = ERR_PTR(-EPROBE_DEFER);
+	}
+
+	mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
+				 infra_clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, infra_clk_data);
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+		       __func__, r);
+}
+
+CLK_OF_DECLARE_DRIVER(mtk_infra, "mediatek,mt6797-infracfg",
+		      mtk_infrasys_init_early);
+
+static int mtk_infrasys_init(struct platform_device *pdev)
+{
+	int r, i;
+	struct device_node *node = pdev->dev.of_node;
+
+	if (!infra_clk_data) {
+		infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR);
+	} else {
+		for (i = 0; i < CLK_INFRA_NR; i++) {
+			if (infra_clk_data->clks[i] == ERR_PTR(-EPROBE_DEFER))
+				infra_clk_data->clks[i] = ERR_PTR(-ENOENT);
+		}
+	}
+
+	mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
+			       infra_clk_data);
+	mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
+				 infra_clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, infra_clk_data);
+	if (r)
+		return r;
+
+	return 0;
+}
+
+#define MT6797_PLL_FMAX		(3000UL * MHZ)
+
+#define CON0_MT6797_RST_BAR	BIT(24)
+
+#define PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,	\
+			_pd_reg, _pd_shift, _tuner_reg, _pcw_reg,	\
+			_pcw_shift, _div_table) {			\
+	.id = _id,						\
+	.name = _name,						\
+	.reg = _reg,						\
+	.pwr_reg = _pwr_reg,					\
+	.en_mask = _en_mask,					\
+	.flags = _flags,					\
+	.rst_bar_mask = CON0_MT6797_RST_BAR,			\
+	.fmax = MT6797_PLL_FMAX,				\
+	.pcwbits = _pcwbits,					\
+	.pd_reg = _pd_reg,					\
+	.pd_shift = _pd_shift,					\
+	.tuner_reg = _tuner_reg,				\
+	.pcw_reg = _pcw_reg,					\
+	.pcw_shift = _pcw_shift,				\
+	.div_table = _div_table,				\
+}
+
+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,	\
+			_pd_reg, _pd_shift, _tuner_reg, _pcw_reg,	\
+			_pcw_shift)					\
+		PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \
+			_pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift, \
+			NULL)
+
+static const struct mtk_pll_data plls[] = {
+	PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x0220, 0x022C, 0xF0000101, PLL_AO,
+	    21, 0x220, 4, 0x0, 0x224, 0),
+	PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x0230, 0x023C, 0xFE000011, 0, 7,
+	    0x230, 4, 0x0, 0x234, 14),
+	PLL(CLK_APMIXED_MFGPLL, "mfgpll", 0x0240, 0x024C, 0x00000101, 0, 21,
+	    0x244, 24, 0x0, 0x244, 0),
+	PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x0250, 0x025C, 0x00000121, 0, 21,
+	    0x250, 4, 0x0, 0x254, 0),
+	PLL(CLK_APMIXED_IMGPLL, "imgpll", 0x0260, 0x026C, 0x00000121, 0, 21,
+	    0x260, 4, 0x0, 0x264, 0),
+	PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x0270, 0x027C, 0xC0000121, 0, 21,
+	    0x270, 4, 0x0, 0x274, 0),
+	PLL(CLK_APMIXED_CODECPLL, "codecpll", 0x0290, 0x029C, 0x00000121, 0, 21,
+	    0x290, 4, 0x0, 0x294, 0),
+	PLL(CLK_APMIXED_VDECPLL, "vdecpll", 0x02E4, 0x02F0, 0x00000121, 0, 21,
+	    0x2E4, 4, 0x0, 0x2E8, 0),
+	PLL(CLK_APMIXED_APLL1, "apll1", 0x02A0, 0x02B0, 0x00000131, 0, 31,
+	    0x2A0, 4, 0x2A8, 0x2A4, 0),
+	PLL(CLK_APMIXED_APLL2, "apll2", 0x02B4, 0x02C4, 0x00000131, 0, 31,
+	    0x2B4, 4, 0x2BC, 0x2B8, 0),
+};
+
+static int mtk_apmixedsys_init(struct platform_device *pdev)
+{
+	struct clk_onecell_data *clk_data;
+	struct device_node *node = pdev->dev.of_node;
+
+	clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR);
+	if (!clk_data)
+		return -ENOMEM;
+
+	mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
+
+	return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+static const struct of_device_id of_match_clk_mt6797[] = {
+	{
+		.compatible = "mediatek,mt6797-topckgen",
+		.data = mtk_topckgen_init,
+	}, {
+		.compatible = "mediatek,mt6797-infracfg",
+		.data = mtk_infrasys_init,
+	}, {
+		.compatible = "mediatek,mt6797-apmixedsys",
+		.data = mtk_apmixedsys_init,
+	}, {
+		/* sentinel */
+	}
+};
+
+static int clk_mt6797_probe(struct platform_device *pdev)
+{
+	int (*clk_init)(struct platform_device *);
+	int r;
+
+	clk_init = of_device_get_match_data(&pdev->dev);
+	if (!clk_init)
+		return -EINVAL;
+
+	r = clk_init(pdev);
+	if (r)
+		dev_err(&pdev->dev,
+			"could not register clock provider: %s: %d\n",
+			pdev->name, r);
+
+	return r;
+}
+
+static struct platform_driver clk_mt6797_drv = {
+	.probe = clk_mt6797_probe,
+	.driver = {
+		.name = "clk-mt6797",
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_clk_mt6797,
+	},
+};
+
+static int __init clk_mt6797_init(void)
+{
+	return platform_driver_register(&clk_mt6797_drv);
+}
+
+arch_initcall(clk_mt6797_init);
diff --git a/include/dt-bindings/clock/mt6797-clk.h b/include/dt-bindings/clock/mt6797-clk.h
new file mode 100644
index 0000000..e48aa47
--- /dev/null
+++ b/include/dt-bindings/clock/mt6797-clk.h
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Kevin Chen <kevin-cw.chen@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_MT6797_H
+#define _DT_BINDINGS_CLK_MT6797_H
+
+/* TOPCKGEN */
+#define	CLK_TOP_MUX_ULPOSC_AXI_CK_MUX_PRE	1
+#define	CLK_TOP_MUX_ULPOSC_AXI_CK_MUX		2
+#define	CLK_TOP_MUX_AXI				3
+#define	CLK_TOP_MUX_MEM				4
+#define	CLK_TOP_MUX_DDRPHYCFG			5
+#define	CLK_TOP_MUX_MM				6
+#define	CLK_TOP_MUX_PWM				7
+#define	CLK_TOP_MUX_VDEC			8
+#define	CLK_TOP_MUX_VENC			9
+#define	CLK_TOP_MUX_MFG				10
+#define	CLK_TOP_MUX_CAMTG			11
+#define	CLK_TOP_MUX_UART			12
+#define	CLK_TOP_MUX_SPI				13
+#define	CLK_TOP_MUX_ULPOSC_SPI_CK_MUX		14
+#define	CLK_TOP_MUX_USB20			15
+#define	CLK_TOP_MUX_MSDC50_0_HCLK		16
+#define	CLK_TOP_MUX_MSDC50_0			17
+#define	CLK_TOP_MUX_MSDC30_1			18
+#define	CLK_TOP_MUX_MSDC30_2			19
+#define	CLK_TOP_MUX_AUDIO			20
+#define	CLK_TOP_MUX_AUD_INTBUS			21
+#define	CLK_TOP_MUX_PMICSPI			22
+#define	CLK_TOP_MUX_SCP				23
+#define	CLK_TOP_MUX_ATB				24
+#define	CLK_TOP_MUX_MJC				25
+#define	CLK_TOP_MUX_DPI0			26
+#define	CLK_TOP_MUX_AUD_1			27
+#define	CLK_TOP_MUX_AUD_2			28
+#define	CLK_TOP_MUX_SSUSB_TOP_SYS		29
+#define	CLK_TOP_MUX_SPM				30
+#define	CLK_TOP_MUX_BSI_SPI			31
+#define	CLK_TOP_MUX_AUDIO_H			32
+#define	CLK_TOP_MUX_ANC_MD32			33
+#define	CLK_TOP_MUX_MFG_52M			34
+#define	CLK_TOP_SYSPLL_CK			35
+#define	CLK_TOP_SYSPLL_D2			36
+#define	CLK_TOP_SYSPLL1_D2			37
+#define	CLK_TOP_SYSPLL1_D4			38
+#define	CLK_TOP_SYSPLL1_D8			39
+#define	CLK_TOP_SYSPLL1_D16			40
+#define	CLK_TOP_SYSPLL_D3			41
+#define	CLK_TOP_SYSPLL_D3_D3			42
+#define	CLK_TOP_SYSPLL2_D2			43
+#define	CLK_TOP_SYSPLL2_D4			44
+#define	CLK_TOP_SYSPLL2_D8			45
+#define	CLK_TOP_SYSPLL_D5			46
+#define	CLK_TOP_SYSPLL3_D2			47
+#define	CLK_TOP_SYSPLL3_D4			48
+#define	CLK_TOP_SYSPLL_D7			49
+#define	CLK_TOP_SYSPLL4_D2			50
+#define	CLK_TOP_SYSPLL4_D4			51
+#define	CLK_TOP_UNIVPLL_CK			52
+#define	CLK_TOP_UNIVPLL_D7			53
+#define	CLK_TOP_UNIVPLL_D26			54
+#define	CLK_TOP_SSUSB_PHY_48M_CK		55
+#define	CLK_TOP_USB_PHY48M_CK			56
+#define	CLK_TOP_UNIVPLL_D2			57
+#define	CLK_TOP_UNIVPLL1_D2			58
+#define	CLK_TOP_UNIVPLL1_D4			59
+#define	CLK_TOP_UNIVPLL1_D8			60
+#define	CLK_TOP_UNIVPLL_D3			61
+#define	CLK_TOP_UNIVPLL2_D2			62
+#define	CLK_TOP_UNIVPLL2_D4			63
+#define	CLK_TOP_UNIVPLL2_D8			64
+#define	CLK_TOP_UNIVPLL_D5			65
+#define	CLK_TOP_UNIVPLL3_D2			66
+#define	CLK_TOP_UNIVPLL3_D4			67
+#define	CLK_TOP_UNIVPLL3_D8			68
+#define	CLK_TOP_ULPOSC_CK_ORG			69
+#define	CLK_TOP_ULPOSC_CK			70
+#define	CLK_TOP_ULPOSC_D2			71
+#define	CLK_TOP_ULPOSC_D3			72
+#define	CLK_TOP_ULPOSC_D4			73
+#define	CLK_TOP_ULPOSC_D8			74
+#define	CLK_TOP_ULPOSC_D10			75
+#define	CLK_TOP_APLL1_CK			76
+#define	CLK_TOP_APLL2_CK			77
+#define	CLK_TOP_MFGPLL_CK			78
+#define	CLK_TOP_MFGPLL_D2			79
+#define	CLK_TOP_IMGPLL_CK			80
+#define	CLK_TOP_IMGPLL_D2			81
+#define	CLK_TOP_IMGPLL_D4			82
+#define	CLK_TOP_CODECPLL_CK			83
+#define	CLK_TOP_CODECPLL_D2			84
+#define	CLK_TOP_VDECPLL_CK			85
+#define	CLK_TOP_TVDPLL_CK			86
+#define	CLK_TOP_TVDPLL_D2			87
+#define	CLK_TOP_TVDPLL_D4			88
+#define	CLK_TOP_TVDPLL_D8			89
+#define	CLK_TOP_TVDPLL_D16			90
+#define	CLK_TOP_MSDCPLL_CK			91
+#define	CLK_TOP_MSDCPLL_D2			92
+#define	CLK_TOP_MSDCPLL_D4			93
+#define	CLK_TOP_MSDCPLL_D8			94
+#define CLK_TOP_NR				95
+
+/* APMIXED_SYS */
+#define CLK_APMIXED_MAINPLL			1
+#define CLK_APMIXED_UNIVPLL			2
+#define CLK_APMIXED_MFGPLL			3
+#define CLK_APMIXED_MSDCPLL			4
+#define CLK_APMIXED_IMGPLL			5
+#define CLK_APMIXED_TVDPLL			6
+#define CLK_APMIXED_CODECPLL			7
+#define CLK_APMIXED_VDECPLL			8
+#define CLK_APMIXED_APLL1			9
+#define CLK_APMIXED_APLL2			10
+#define CLK_APMIXED_NR				11
+
+/* INFRA_SYS */
+#define	CLK_INFRA_PMIC_TMR			1
+#define	CLK_INFRA_PMIC_AP			2
+#define	CLK_INFRA_PMIC_MD			3
+#define	CLK_INFRA_PMIC_CONN			4
+#define	CLK_INFRA_SCP				5
+#define	CLK_INFRA_SEJ				6
+#define	CLK_INFRA_APXGPT			7
+#define	CLK_INFRA_SEJ_13M			8
+#define	CLK_INFRA_ICUSB				9
+#define	CLK_INFRA_GCE				10
+#define	CLK_INFRA_THERM				11
+#define	CLK_INFRA_I2C0				12
+#define	CLK_INFRA_I2C1				13
+#define	CLK_INFRA_I2C2				14
+#define	CLK_INFRA_I2C3				15
+#define	CLK_INFRA_PWM_HCLK			16
+#define	CLK_INFRA_PWM1				17
+#define	CLK_INFRA_PWM2				18
+#define	CLK_INFRA_PWM3				19
+#define	CLK_INFRA_PWM4				20
+#define	CLK_INFRA_PWM				21
+#define	CLK_INFRA_UART0				22
+#define	CLK_INFRA_UART1				23
+#define	CLK_INFRA_UART2				24
+#define	CLK_INFRA_UART3				25
+#define	CLK_INFRA_MD2MD_CCIF_0			26
+#define	CLK_INFRA_MD2MD_CCIF_1			27
+#define	CLK_INFRA_MD2MD_CCIF_2			28
+#define	CLK_INFRA_FHCTL				29
+#define	CLK_INFRA_BTIF				30
+#define	CLK_INFRA_MD2MD_CCIF_3			31
+#define	CLK_INFRA_SPI				32
+#define	CLK_INFRA_MSDC0				33
+#define	CLK_INFRA_MD2MD_CCIF_4			34
+#define	CLK_INFRA_MSDC1				35
+#define	CLK_INFRA_MSDC2				36
+#define	CLK_INFRA_MD2MD_CCIF_5			37
+#define	CLK_INFRA_GCPU				38
+#define	CLK_INFRA_TRNG				39
+#define	CLK_INFRA_AUXADC			40
+#define	CLK_INFRA_CPUM				41
+#define	CLK_INFRA_AP_C2K_CCIF_0			42
+#define	CLK_INFRA_AP_C2K_CCIF_1			43
+#define	CLK_INFRA_CLDMA				44
+#define	CLK_INFRA_DISP_PWM			45
+#define	CLK_INFRA_AP_DMA			46
+#define	CLK_INFRA_DEVICE_APC			47
+#define	CLK_INFRA_L2C_SRAM			48
+#define	CLK_INFRA_CCIF_AP			49
+#define	CLK_INFRA_AUDIO				50
+#define	CLK_INFRA_CCIF_MD			51
+#define	CLK_INFRA_DRAMC_F26M			52
+#define	CLK_INFRA_I2C4				53
+#define	CLK_INFRA_I2C_APPM			54
+#define	CLK_INFRA_I2C_GPUPM			55
+#define	CLK_INFRA_I2C2_IMM			56
+#define	CLK_INFRA_I2C2_ARB			57
+#define	CLK_INFRA_I2C3_IMM			58
+#define	CLK_INFRA_I2C3_ARB			59
+#define	CLK_INFRA_I2C5				60
+#define	CLK_INFRA_SYS_CIRQ			61
+#define	CLK_INFRA_SPI1				62
+#define	CLK_INFRA_DRAMC_B_F26M			63
+#define	CLK_INFRA_ANC_MD32			64
+#define	CLK_INFRA_ANC_MD32_32K			65
+#define	CLK_INFRA_DVFS_SPM1			66
+#define	CLK_INFRA_AES_TOP0			67
+#define	CLK_INFRA_AES_TOP1			68
+#define	CLK_INFRA_SSUSB_BUS			69
+#define	CLK_INFRA_SPI2				70
+#define	CLK_INFRA_SPI3				71
+#define	CLK_INFRA_SPI4				72
+#define	CLK_INFRA_SPI5				73
+#define	CLK_INFRA_IRTX				74
+#define	CLK_INFRA_SSUSB_SYS			75
+#define	CLK_INFRA_SSUSB_REF			76
+#define	CLK_INFRA_AUDIO_26M			77
+#define	CLK_INFRA_AUDIO_26M_PAD_TOP		78
+#define	CLK_INFRA_MODEM_TEMP_SHARE		79
+#define	CLK_INFRA_VAD_WRAP_SOC			80
+#define	CLK_INFRA_DRAMC_CONF			81
+#define	CLK_INFRA_DRAMC_B_CONF			82
+#define CLK_INFRA_MFG_VCG			83
+#define CLK_INFRA_13M				84
+#define CLK_INFRA_NR				85
+
+/* IMG_SYS */
+#define	CLK_IMG_FDVT				1
+#define	CLK_IMG_DPE				2
+#define	CLK_IMG_DIP				3
+#define	CLK_IMG_LARB6				4
+#define CLK_IMG_NR				5
+
+/* MM_SYS */
+#define	CLK_MM_SMI_COMMON			1
+#define	CLK_MM_SMI_LARB0			2
+#define	CLK_MM_SMI_LARB5			3
+#define	CLK_MM_CAM_MDP				4
+#define	CLK_MM_MDP_RDMA0			5
+#define	CLK_MM_MDP_RDMA1			6
+#define	CLK_MM_MDP_RSZ0				7
+#define	CLK_MM_MDP_RSZ1				8
+#define	CLK_MM_MDP_RSZ2				9
+#define	CLK_MM_MDP_TDSHP			10
+#define	CLK_MM_MDP_COLOR			11
+#define	CLK_MM_MDP_WDMA				12
+#define	CLK_MM_MDP_WROT0			13
+#define	CLK_MM_MDP_WROT1			14
+#define	CLK_MM_FAKE_ENG				15
+#define	CLK_MM_DISP_OVL0			16
+#define	CLK_MM_DISP_OVL1			17
+#define	CLK_MM_DISP_OVL0_2L			18
+#define	CLK_MM_DISP_OVL1_2L			19
+#define	CLK_MM_DISP_RDMA0			20
+#define	CLK_MM_DISP_RDMA1			21
+#define	CLK_MM_DISP_WDMA0			22
+#define	CLK_MM_DISP_WDMA1			23
+#define	CLK_MM_DISP_COLOR			24
+#define	CLK_MM_DISP_CCORR			25
+#define	CLK_MM_DISP_AAL				26
+#define	CLK_MM_DISP_GAMMA			27
+#define	CLK_MM_DISP_OD				28
+#define	CLK_MM_DISP_DITHER			29
+#define	CLK_MM_DISP_UFOE			30
+#define	CLK_MM_DISP_DSC				31
+#define	CLK_MM_DISP_SPLIT			32
+#define	CLK_MM_DSI0_MM_CLOCK			33
+#define	CLK_MM_DSI1_MM_CLOCK			34
+#define	CLK_MM_DPI_MM_CLOCK			35
+#define	CLK_MM_DPI_INTERFACE_CLOCK		36
+#define	CLK_MM_LARB4_AXI_ASIF_MM_CLOCK		37
+#define	CLK_MM_LARB4_AXI_ASIF_MJC_CLOCK		38
+#define	CLK_MM_DISP_OVL0_MOUT_CLOCK		39
+#define	CLK_MM_FAKE_ENG2			40
+#define	CLK_MM_DSI0_INTERFACE_CLOCK		41
+#define	CLK_MM_DSI1_INTERFACE_CLOCK		42
+#define CLK_MM_NR				43
+
+/* VDEC_SYS */
+#define	CLK_VDEC_CKEN_ENG			1
+#define	CLK_VDEC_ACTIVE				2
+#define	CLK_VDEC_CKEN				3
+#define	CLK_VDEC_LARB1_CKEN			4
+#define CLK_VDEC_NR				5
+
+/* VENC_SYS */
+#define	CLK_VENC_0				1
+#define	CLK_VENC_1				2
+#define	CLK_VENC_2				3
+#define	CLK_VENC_3				4
+#define CLK_VENC_NR				5
+
+#endif /* _DT_BINDINGS_CLK_MT6797_H */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 06/10] clk: mediatek: add clk support for MT6797
@ 2017-02-06 12:15   ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-06 12:15 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: CC Hwang, Loda Chou, Miles Chen, Jades Shih, Yingjoe Chen,
	My Chuang, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, Marc Zyngier, Thomas Gleixner, Will Deacon,
	Stephen Boyd, linux-clk, Chieh-Jay Liu, Kevin-CW Chen,
	Mars Cheng

From: Kevin-CW Chen <kevin-cw.chen@mediatek.com>

Add MT6797 clock support, include topckgen, apmixedsys, infracfg
and subsystem clocks

Signed-off-by: Kevin-CW Chen <kevin-cw.chen@mediatek.com>
Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
---
 drivers/clk/mediatek/Kconfig           |   33 ++
 drivers/clk/mediatek/Makefile          |    5 +
 drivers/clk/mediatek/clk-mt6797-img.c  |   76 ++++
 drivers/clk/mediatek/clk-mt6797-mm.c   |  136 ++++++
 drivers/clk/mediatek/clk-mt6797-vdec.c |   93 +++++
 drivers/clk/mediatek/clk-mt6797-venc.c |   78 ++++
 drivers/clk/mediatek/clk-mt6797.c      |  716 ++++++++++++++++++++++++++++++++
 include/dt-bindings/clock/mt6797-clk.h |  281 +++++++++++++
 8 files changed, 1418 insertions(+)
 create mode 100644 drivers/clk/mediatek/clk-mt6797-img.c
 create mode 100644 drivers/clk/mediatek/clk-mt6797-mm.c
 create mode 100644 drivers/clk/mediatek/clk-mt6797-vdec.c
 create mode 100644 drivers/clk/mediatek/clk-mt6797-venc.c
 create mode 100644 drivers/clk/mediatek/clk-mt6797.c
 create mode 100644 include/dt-bindings/clock/mt6797-clk.h

diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
index 0bd631a..4b91eed 100644
--- a/drivers/clk/mediatek/Kconfig
+++ b/drivers/clk/mediatek/Kconfig
@@ -49,6 +49,39 @@ config COMMON_CLK_MT2701_BDPSYS
 	---help---
 	  This driver supports Mediatek MT2701 bdpsys clocks.

+config COMMON_CLK_MT6797
+       bool "Clock driver for Mediatek MT6797"
+       depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
+       select COMMON_CLK_MEDIATEK
+       default ARCH_MEDIATEK && ARM64
+       ---help---
+         This driver supports Mediatek MT6797 basic clocks.
+
+config COMMON_CLK_MT6797_MMSYS
+       bool "Clock driver for Mediatek MT6797 mmsys"
+       depends on COMMON_CLK_MT6797
+       ---help---
+         This driver supports Mediatek MT6797 mmsys clocks.
+
+config COMMON_CLK_MT6797_IMGSYS
+       bool "Clock driver for Mediatek MT6797 imgsys"
+       depends on COMMON_CLK_MT6797
+       ---help---
+         This driver supports Mediatek MT6797 imgsys clocks.
+
+config COMMON_CLK_MT6797_VDECSYS
+       bool "Clock driver for Mediatek MT6797 vdecsys"
+       depends on COMMON_CLK_MT6797
+       ---help---
+         This driver supports Mediatek MT6797 vdecsys clocks.
+
+config COMMON_CLK_MT6797_VENCSYS
+       bool "Clock driver for Mediatek MT6797 vencsys"
+       depends on COMMON_CLK_MT6797
+       ---help---
+         This driver supports Mediatek MT6797 vencsys clocks.
+
+
 config COMMON_CLK_MT8135
 	bool "Clock driver for Mediatek MT8135"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 19ae7ef..5c3afb8 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -1,5 +1,10 @@
 obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o
 obj-$(CONFIG_RESET_CONTROLLER) += reset.o
+obj-$(CONFIG_COMMON_CLK_MT6797) += clk-mt6797.o
+obj-$(CONFIG_COMMON_CLK_MT6797_IMGSYS) += clk-mt6797-img.o
+obj-$(CONFIG_COMMON_CLK_MT6797_MMSYS) += clk-mt6797-mm.o
+obj-$(CONFIG_COMMON_CLK_MT6797_VDECSYS) += clk-mt6797-vdec.o
+obj-$(CONFIG_COMMON_CLK_MT6797_VENCSYS) += clk-mt6797-venc.o
 obj-$(CONFIG_COMMON_CLK_MT2701) += clk-mt2701.o
 obj-$(CONFIG_COMMON_CLK_MT2701_BDPSYS) += clk-mt2701-bdp.o
 obj-$(CONFIG_COMMON_CLK_MT2701_ETHSYS) += clk-mt2701-eth.o
diff --git a/drivers/clk/mediatek/clk-mt6797-img.c b/drivers/clk/mediatek/clk-mt6797-img.c
new file mode 100644
index 0000000..94cc480
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt6797-img.c
@@ -0,0 +1,76 @@
+/* Copyright (c) 2017 MediaTek Inc.
+ * Author: Kevin Chen <kevin-cw.chen@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/clk-provider.h>
+#include <linux/platform_device.h>
+#include <dt-bindings/clock/mt6797-clk.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+static const struct mtk_gate_regs img_cg_regs = {
+	.set_ofs = 0x0004,
+	.clr_ofs = 0x0008,
+	.sta_ofs = 0x0000,
+};
+
+#define GATE_IMG(_id, _name, _parent, _shift) {		\
+		.id = _id,				\
+		.name = _name,				\
+		.parent_name = _parent,			\
+		.regs = &img_cg_regs,			\
+		.shift = _shift,			\
+		.ops = &mtk_clk_gate_ops_setclr,	\
+	}
+
+static const struct mtk_gate img_clks[] = {
+	GATE_IMG(CLK_IMG_FDVT, "img_fdvt", "mm_sel", 11),
+	GATE_IMG(CLK_IMG_DPE, "img_dpe", "mm_sel", 10),
+	GATE_IMG(CLK_IMG_DIP, "img_dip", "mm_sel", 6),
+	GATE_IMG(CLK_IMG_LARB6, "img_larb6", "mm_sel", 0),
+};
+
+static const struct of_device_id of_match_clk_mt6797_img[] = {
+	{ .compatible = "mediatek,mt6797-imgsys", },
+	{}
+};
+
+static int clk_mt6797_img_probe(struct platform_device *pdev)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+	struct device_node *node = pdev->dev.of_node;
+
+	clk_data = mtk_alloc_clk_data(CLK_IMG_NR);
+
+	mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks),
+			       clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		dev_err(&pdev->dev,
+			"could not register clock provider: %s: %d\n",
+			pdev->name, r);
+
+	return r;
+}
+
+static struct platform_driver clk_mt6797_img_drv = {
+	.probe = clk_mt6797_img_probe,
+	.driver = {
+		.name = "clk-mt6797-img",
+		.of_match_table = of_match_clk_mt6797_img,
+	},
+};
+
+builtin_platform_driver(clk_mt6797_img_drv);
diff --git a/drivers/clk/mediatek/clk-mt6797-mm.c b/drivers/clk/mediatek/clk-mt6797-mm.c
new file mode 100644
index 0000000..c57d3ee
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt6797-mm.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Kevin Chen <kevin-cw.chen@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/clk-provider.h>
+#include <linux/platform_device.h>
+#include <dt-bindings/clock/mt6797-clk.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+static const struct mtk_gate_regs mm0_cg_regs = {
+	.set_ofs = 0x0104,
+	.clr_ofs = 0x0108,
+	.sta_ofs = 0x0100,
+};
+
+static const struct mtk_gate_regs mm1_cg_regs = {
+	.set_ofs = 0x0114,
+	.clr_ofs = 0x0118,
+	.sta_ofs = 0x0110,
+};
+
+#define GATE_MM0(_id, _name, _parent, _shift) {			\
+	.id = _id,					\
+	.name = _name,					\
+	.parent_name = _parent,				\
+	.regs = &mm0_cg_regs,				\
+	.shift = _shift,				\
+	.ops = &mtk_clk_gate_ops_setclr,		\
+}
+
+#define GATE_MM1(_id, _name, _parent, _shift) {			\
+	.id = _id,					\
+	.name = _name,					\
+	.parent_name = _parent,				\
+	.regs = &mm1_cg_regs,				\
+	.shift = _shift,				\
+	.ops = &mtk_clk_gate_ops_setclr,		\
+}
+
+static const struct mtk_gate mm_clks[] = {
+	GATE_MM0(CLK_MM_SMI_COMMON, "mm_smi_common", "mm_sel", 0),
+	GATE_MM0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1),
+	GATE_MM0(CLK_MM_SMI_LARB5, "mm_smi_larb5", "mm_sel", 2),
+	GATE_MM0(CLK_MM_CAM_MDP, "mm_cam_mdp", "mm_sel", 3),
+	GATE_MM0(CLK_MM_MDP_RDMA0, "mm_mdp_rdma0", "mm_sel", 4),
+	GATE_MM0(CLK_MM_MDP_RDMA1, "mm_mdp_rdma1", "mm_sel", 5),
+	GATE_MM0(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "mm_sel", 6),
+	GATE_MM0(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "mm_sel", 7),
+	GATE_MM0(CLK_MM_MDP_RSZ2, "mm_mdp_rsz2", "mm_sel", 8),
+	GATE_MM0(CLK_MM_MDP_TDSHP, "mm_mdp_tdshp", "mm_sel", 9),
+	GATE_MM0(CLK_MM_MDP_COLOR, "mm_mdp_color", "mm_sel", 10),
+	GATE_MM0(CLK_MM_MDP_WDMA, "mm_mdp_wdma", "mm_sel", 11),
+	GATE_MM0(CLK_MM_MDP_WROT0, "mm_mdp_wrot0", "mm_sel", 12),
+	GATE_MM0(CLK_MM_MDP_WROT1, "mm_mdp_wrot1", "mm_sel", 13),
+	GATE_MM0(CLK_MM_FAKE_ENG, "mm_fake_eng", "mm_sel", 14),
+	GATE_MM0(CLK_MM_DISP_OVL0, "mm_disp_ovl0", "mm_sel", 15),
+	GATE_MM0(CLK_MM_DISP_OVL1, "mm_disp_ovl1", "mm_sel", 16),
+	GATE_MM0(CLK_MM_DISP_OVL0_2L, "mm_disp_ovl0_2l", "mm_sel", 17),
+	GATE_MM0(CLK_MM_DISP_OVL1_2L, "mm_disp_ovl1_2l", "mm_sel", 18),
+	GATE_MM0(CLK_MM_DISP_RDMA0, "mm_disp_rdma0", "mm_sel", 19),
+	GATE_MM0(CLK_MM_DISP_RDMA1, "mm_disp_rdma1", "mm_sel", 20),
+	GATE_MM0(CLK_MM_DISP_WDMA0, "mm_disp_wdma0", "mm_sel", 21),
+	GATE_MM0(CLK_MM_DISP_WDMA1, "mm_disp_wdma1", "mm_sel", 22),
+	GATE_MM0(CLK_MM_DISP_COLOR, "mm_disp_color", "mm_sel", 23),
+	GATE_MM0(CLK_MM_DISP_CCORR, "mm_disp_ccorr", "mm_sel", 24),
+	GATE_MM0(CLK_MM_DISP_AAL, "mm_disp_aal", "mm_sel", 25),
+	GATE_MM0(CLK_MM_DISP_GAMMA, "mm_disp_gamma", "mm_sel", 26),
+	GATE_MM0(CLK_MM_DISP_OD, "mm_disp_od", "mm_sel", 27),
+	GATE_MM0(CLK_MM_DISP_DITHER, "mm_disp_dither", "mm_sel", 28),
+	GATE_MM0(CLK_MM_DISP_UFOE, "mm_disp_ufoe", "mm_sel", 29),
+	GATE_MM0(CLK_MM_DISP_DSC, "mm_disp_dsc", "mm_sel", 30),
+	GATE_MM0(CLK_MM_DISP_SPLIT, "mm_disp_split", "mm_sel", 31),
+	GATE_MM1(CLK_MM_DSI0_MM_CLOCK, "mm_dsi0_mm_clock", "mm_sel", 0),
+	GATE_MM1(CLK_MM_DSI1_MM_CLOCK, "mm_dsi1_mm_clock", "mm_sel", 2),
+	GATE_MM1(CLK_MM_DPI_MM_CLOCK, "mm_dpi_mm_clock", "mm_sel", 4),
+	GATE_MM1(CLK_MM_DPI_INTERFACE_CLOCK, "mm_dpi_interface_clock",
+		 "dpi0_sel", 5),
+	GATE_MM1(CLK_MM_LARB4_AXI_ASIF_MM_CLOCK, "mm_larb4_axi_asif_mm_clock",
+		 "mm_sel", 6),
+	GATE_MM1(CLK_MM_LARB4_AXI_ASIF_MJC_CLOCK, "mm_larb4_axi_asif_mjc_clock",
+		 "mjc_sel", 7),
+	GATE_MM1(CLK_MM_DISP_OVL0_MOUT_CLOCK, "mm_disp_ovl0_mout_clock",
+		 "mm_sel", 8),
+	GATE_MM1(CLK_MM_FAKE_ENG2, "mm_fake_eng2", "mm_sel", 9),
+	GATE_MM1(CLK_MM_DSI0_INTERFACE_CLOCK, "mm_dsi0_interface_clock",
+		 "clk26m", 1),
+	GATE_MM1(CLK_MM_DSI1_INTERFACE_CLOCK, "mm_dsi1_interface_clock",
+		 "clk26m", 3),
+};
+
+static const struct of_device_id of_match_clk_mt6797_mm[] = {
+	{ .compatible = "mediatek,mt6797-mmsys", },
+	{}
+};
+
+static int clk_mt6797_mm_probe(struct platform_device *pdev)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+	struct device_node *node = pdev->dev.of_node;
+
+	clk_data = mtk_alloc_clk_data(CLK_MM_NR);
+
+	mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks),
+			       clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		dev_err(&pdev->dev,
+			"could not register clock provider: %s: %d\n",
+			pdev->name, r);
+
+	return r;
+}
+
+static struct platform_driver clk_mt6797_mm_drv = {
+	.probe = clk_mt6797_mm_probe,
+	.driver = {
+		.name = "clk-mt6797-mm",
+		.of_match_table = of_match_clk_mt6797_mm,
+	},
+};
+
+builtin_platform_driver(clk_mt6797_mm_drv);
diff --git a/drivers/clk/mediatek/clk-mt6797-vdec.c b/drivers/clk/mediatek/clk-mt6797-vdec.c
new file mode 100644
index 0000000..7c402ca
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt6797-vdec.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Kevin-CW Chen <kevin-cw.chen@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/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt6797-clk.h>
+
+static const struct mtk_gate_regs vdec0_cg_regs = {
+	.set_ofs = 0x0000,
+	.clr_ofs = 0x0004,
+	.sta_ofs = 0x0000,
+};
+
+static const struct mtk_gate_regs vdec1_cg_regs = {
+	.set_ofs = 0x0008,
+	.clr_ofs = 0x000c,
+	.sta_ofs = 0x0008,
+};
+
+#define GATE_VDEC0(_id, _name, _parent, _shift) {		\
+	.id = _id,					\
+	.name = _name,					\
+	.parent_name = _parent,				\
+	.regs = &vdec0_cg_regs,				\
+	.shift = _shift,				\
+	.ops = &mtk_clk_gate_ops_setclr_inv,		\
+}
+
+#define GATE_VDEC1(_id, _name, _parent, _shift) {		\
+	.id = _id,					\
+	.name = _name,					\
+	.parent_name = _parent,				\
+	.regs = &vdec1_cg_regs,				\
+	.shift = _shift,				\
+	.ops = &mtk_clk_gate_ops_setclr_inv,		\
+}
+
+static const struct mtk_gate vdec_clks[] = {
+	GATE_VDEC0(CLK_VDEC_CKEN_ENG, "vdec_cken_eng", "vdec_sel", 8),
+	GATE_VDEC0(CLK_VDEC_ACTIVE, "vdec_active", "vdec_sel", 4),
+	GATE_VDEC0(CLK_VDEC_CKEN, "vdec_cken", "vdec_sel", 0),
+	GATE_VDEC1(CLK_VDEC_LARB1_CKEN, "vdec_larb1_cken", "mm_sel", 0),
+};
+
+static const struct of_device_id of_match_clk_mt6797_vdec[] = {
+	{ .compatible = "mediatek,mt6797-vdecsys", },
+	{}
+};
+
+static int clk_mt6797_vdec_probe(struct platform_device *pdev)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+	struct device_node *node = pdev->dev.of_node;
+
+	clk_data = mtk_alloc_clk_data(CLK_VDEC_NR);
+
+	mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks),
+			       clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		dev_err(&pdev->dev,
+			"could not register clock provider: %s: %d\n",
+			pdev->name, r);
+
+	return r;
+}
+
+static struct platform_driver clk_mt6797_vdec_drv = {
+	.probe = clk_mt6797_vdec_probe,
+	.driver = {
+		.name = "clk-mt6797-vdec",
+		.of_match_table = of_match_clk_mt6797_vdec,
+	},
+};
+
+builtin_platform_driver(clk_mt6797_vdec_drv);
diff --git a/drivers/clk/mediatek/clk-mt6797-venc.c b/drivers/clk/mediatek/clk-mt6797-venc.c
new file mode 100644
index 0000000..e73d517
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt6797-venc.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Kevin Chen <kevin-cw.chen@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/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt6797-clk.h>
+
+static const struct mtk_gate_regs venc_cg_regs = {
+	.set_ofs = 0x0004,
+	.clr_ofs = 0x0008,
+	.sta_ofs = 0x0000,
+};
+
+#define GATE_VENC(_id, _name, _parent, _shift) {	\
+		.id = _id,				\
+		.name = _name,				\
+		.parent_name = _parent,			\
+		.regs = &venc_cg_regs,			\
+		.shift = _shift,			\
+		.ops = &mtk_clk_gate_ops_setclr_inv,	\
+	}
+
+static const struct mtk_gate venc_clks[] = {
+	GATE_VENC(CLK_VENC_0, "venc_0", "mm_sel", 0),
+	GATE_VENC(CLK_VENC_1, "venc_1", "venc_sel", 4),
+	GATE_VENC(CLK_VENC_2, "venc_2", "venc_sel", 8),
+	GATE_VENC(CLK_VENC_3, "venc_3", "venc_sel", 12),
+};
+
+static const struct of_device_id of_match_clk_mt6797_venc[] = {
+	{ .compatible = "mediatek,mt6797-vencsys", },
+	{}
+};
+
+static int clk_mt6797_venc_probe(struct platform_device *pdev)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+	struct device_node *node = pdev->dev.of_node;
+
+	clk_data = mtk_alloc_clk_data(CLK_VENC_NR);
+
+	mtk_clk_register_gates(node, venc_clks, ARRAY_SIZE(venc_clks),
+			       clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		dev_err(&pdev->dev,
+			"could not register clock provider: %s: %d\n",
+			pdev->name, r);
+
+	return r;
+}
+
+static struct platform_driver clk_mt6797_venc_drv = {
+	.probe = clk_mt6797_venc_probe,
+	.driver = {
+		.name = "clk-mt6797-venc",
+		.of_match_table = of_match_clk_mt6797_venc,
+	},
+};
+
+builtin_platform_driver(clk_mt6797_venc_drv);
diff --git a/drivers/clk/mediatek/clk-mt6797.c b/drivers/clk/mediatek/clk-mt6797.c
new file mode 100644
index 0000000..7ebb7f1
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt6797.c
@@ -0,0 +1,716 @@
+/*
+ * Copyright (c) 2016 MediaTek Inc.
+ * Author: Kevin Chen <kevin-cw.chen@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/clk.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt6797-clk.h>
+
+/*
+ * For some clocks, we don't care what their actual rates are. And these
+ * clocks may change their rate on different products or different scenarios.
+ * So we model these clocks' rate as 0, to denote it's not an actual rate.
+ */
+
+static DEFINE_SPINLOCK(mt6797_clk_lock);
+
+static const struct mtk_fixed_factor top_fixed_divs[] = {
+	FACTOR(CLK_TOP_SYSPLL_CK, "syspll_ck", "mainpll", 1, 1),
+	FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "mainpll", 1, 2),
+	FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "syspll_d2", 1, 2),
+	FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "syspll_d2", 1, 4),
+	FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "syspll_d2", 1, 8),
+	FACTOR(CLK_TOP_SYSPLL1_D16, "syspll1_d16", "syspll_d2", 1, 16),
+	FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "mainpll", 1, 3),
+	FACTOR(CLK_TOP_SYSPLL_D3_D3, "syspll_d3_d3", "syspll_d3", 1, 3),
+	FACTOR(CLK_TOP_SYSPLL2_D2, "syspll2_d2", "syspll_d3", 1, 2),
+	FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "syspll_d3", 1, 4),
+	FACTOR(CLK_TOP_SYSPLL2_D8, "syspll2_d8", "syspll_d3", 1, 8),
+	FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll", 1, 5),
+	FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "syspll_d5", 1, 2),
+	FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "syspll_d5", 1, 4),
+	FACTOR(CLK_TOP_SYSPLL_D7, "syspll_d7", "mainpll", 1, 7),
+	FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "syspll_d7", 1, 2),
+	FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "syspll_d7", 1, 4),
+	FACTOR(CLK_TOP_UNIVPLL_CK, "univpll_ck", "univpll", 1, 1),
+	FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll", 1, 7),
+	FACTOR(CLK_TOP_UNIVPLL_D26, "univpll_d26", "univpll", 1, 26),
+	FACTOR(CLK_TOP_SSUSB_PHY_48M_CK, "ssusb_phy_48m_ck", "univpll", 1, 1),
+	FACTOR(CLK_TOP_USB_PHY48M_CK, "usb_phy48m_ck", "univpll", 1, 1),
+	FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll", 1, 2),
+	FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_d2", 1, 2),
+	FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_d2", 1, 4),
+	FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_d2", 1, 8),
+	FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll", 1, 3),
+	FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll", 1, 2),
+	FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll", 1, 4),
+	FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll", 1, 8),
+	FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5),
+	FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2", "univpll_d5", 1, 2),
+	FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4", "univpll_d5", 1, 4),
+	FACTOR(CLK_TOP_UNIVPLL3_D8, "univpll3_d8", "univpll_d5", 1, 8),
+	FACTOR(CLK_TOP_ULPOSC_CK_ORG, "ulposc_ck_org", "ulposc", 1, 1),
+	FACTOR(CLK_TOP_ULPOSC_CK, "ulposc_ck", "ulposc_ck_org", 1, 3),
+	FACTOR(CLK_TOP_ULPOSC_D2, "ulposc_d2", "ulposc_ck", 1, 2),
+	FACTOR(CLK_TOP_ULPOSC_D3, "ulposc_d3", "ulposc_ck", 1, 4),
+	FACTOR(CLK_TOP_ULPOSC_D4, "ulposc_d4", "ulposc_ck", 1, 8),
+	FACTOR(CLK_TOP_ULPOSC_D8, "ulposc_d8", "ulposc_ck", 1, 10),
+	FACTOR(CLK_TOP_ULPOSC_D10, "ulposc_d10", "ulposc_ck_org", 1, 1),
+	FACTOR(CLK_TOP_APLL1_CK, "apll1_ck", "apll1", 1, 1),
+	FACTOR(CLK_TOP_APLL2_CK, "apll2_ck", "apll2", 1, 1),
+	FACTOR(CLK_TOP_MFGPLL_CK, "mfgpll_ck", "mfgpll", 1, 1),
+	FACTOR(CLK_TOP_MFGPLL_D2, "mfgpll_d2", "mfgpll_ck", 1, 2),
+	FACTOR(CLK_TOP_IMGPLL_CK, "imgpll_ck", "imgpll", 1, 1),
+	FACTOR(CLK_TOP_IMGPLL_D2, "imgpll_d2", "imgpll_ck", 1, 2),
+	FACTOR(CLK_TOP_IMGPLL_D4, "imgpll_d4", "imgpll_ck", 1, 4),
+	FACTOR(CLK_TOP_CODECPLL_CK, "codecpll_ck", "codecpll", 1, 1),
+	FACTOR(CLK_TOP_CODECPLL_D2, "codecpll_d2", "codecpll_ck", 1, 2),
+	FACTOR(CLK_TOP_VDECPLL_CK, "vdecpll_ck", "vdecpll", 1, 1),
+	FACTOR(CLK_TOP_TVDPLL_CK, "tvdpll_ck", "tvdpll", 1, 1),
+	FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll_ck", 1, 2),
+	FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll_ck", 1, 4),
+	FACTOR(CLK_TOP_TVDPLL_D8, "tvdpll_d8", "tvdpll_ck", 1, 8),
+	FACTOR(CLK_TOP_TVDPLL_D16, "tvdpll_d16", "tvdpll_ck", 1, 16),
+	FACTOR(CLK_TOP_MSDCPLL_CK, "msdcpll_ck", "msdcpll", 1, 1),
+	FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll_ck", 1, 2),
+	FACTOR(CLK_TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll_ck", 1, 4),
+	FACTOR(CLK_TOP_MSDCPLL_D8, "msdcpll_d8", "msdcpll_ck", 1, 8),
+};
+
+static const char * const axi_parents[] = {
+	"clk26m",
+	"syspll_d7",
+	"ulposc_axi_ck_mux",
+};
+
+static const char * const ulposc_axi_ck_mux_parents[] = {
+	"syspll1_d4",
+	"ulposc_axi_ck_mux_pre",
+};
+
+static const char * const ulposc_axi_ck_mux_pre_parents[] = {
+	"ulposc_d2",
+	"ulposc_d3",
+};
+
+static const char * const ddrphycfg_parents[] = {
+	"clk26m",
+	"syspll3_d2",
+	"syspll2_d4",
+	"syspll1_d8",
+};
+
+static const char * const mm_parents[] = {
+	"clk26m",
+	"imgpll_ck",
+	"univpll1_d2",
+	"syspll1_d2",
+};
+
+static const char * const pwm_parents[] = {
+	"clk26m",
+	"univpll2_d4",
+	"ulposc_d2",
+	"ulposc_d3",
+	"ulposc_d8",
+	"ulposc_d10",
+	"ulposc_d4",
+};
+
+static const char * const vdec_parents[] = {
+	"clk26m",
+	"vdecpll_ck",
+	"imgpll_ck",
+	"syspll_d3",
+	"univpll_d5",
+	"clk26m",
+	"clk26m",
+};
+
+static const char * const venc_parents[] = {
+	"clk26m",
+	"codecpll_ck",
+	"syspll_d3",
+};
+
+static const char * const mfg_parents[] = {
+	"clk26m",
+	"mfgpll_ck",
+	"syspll_d3",
+	"univpll_d3",
+};
+
+static const char * const camtg[] = {
+	"clk26m",
+	"univpll_d26",
+	"univpll2_d2",
+};
+
+static const char * const uart_parents[] = {
+	"clk26m",
+	"univpll2_d8",
+};
+
+static const char * const spi_parents[] = {
+	"clk26m",
+	"syspll3_d2",
+	"syspll2_d4",
+	"ulposc_spi_ck_mux",
+};
+
+static const char * const ulposc_spi_ck_mux_parents[] = {
+	"ulposc_d2",
+	"ulposc_d3",
+};
+
+static const char * const usb20_parents[] = {
+	"clk26m",
+	"univpll1_d8",
+	"syspll4_d2",
+};
+
+static const char * const msdc50_0_hclk_parents[] = {
+	"clk26m",
+	"syspll1_d2",
+	"syspll2_d2",
+	"syspll4_d2",
+};
+
+static const char * const msdc50_0_parents[] = {
+	"clk26m",
+	"msdcpll",
+	"syspll_d3",
+	"univpll1_d4",
+	"syspll2_d2",
+	"syspll_d7",
+	"msdcpll_d2",
+	"univpll1_d2",
+	"univpll_d3",
+};
+
+static const char * const msdc30_1_parents[] = {
+	"clk26m",
+	"univpll2_d2",
+	"msdcpll_d2",
+	"univpll1_d4",
+	"syspll2_d2",
+	"syspll_d7",
+	"univpll_d7",
+};
+
+static const char * const msdc30_2_parents[] = {
+	"clk26m",
+	"univpll2_d8",
+	"syspll2_d8",
+	"syspll1_d8",
+	"msdcpll_d8",
+	"syspll3_d4",
+	"univpll_d26",
+};
+
+static const char * const audio_parents[] = {
+	"clk26m",
+	"syspll3_d4",
+	"syspll4_d4",
+	"syspll1_d16",
+};
+
+static const char * const aud_intbus_parents[] = {
+	"clk26m",
+	"syspll1_d4",
+	"syspll4_d2",
+};
+
+static const char * const pmicspi_parents[] = {
+	"clk26m",
+	"univpll_d26",
+	"syspll3_d4",
+	"syspll1_d8",
+	"ulposc_d4",
+	"ulposc_d8",
+	"syspll2_d8",
+};
+
+static const char * const scp_parents[] = {
+	"clk26m",
+	"syspll_d3",
+	"ulposc_ck",
+	"univpll_d5",
+};
+
+static const char * const atb_parents[] = {
+	"clk26m",
+	"syspll1_d2",
+	"syspll_d5",
+};
+
+static const char * const mjc_parents[] = {
+	"clk26m",
+	"imgpll_ck",
+	"univpll_d5",
+	"syspll1_d2",
+};
+
+static const char * const dpi0_parents[] = {
+	"clk26m",
+	"tvdpll_d2",
+	"tvdpll_d4",
+	"tvdpll_d8",
+	"tvdpll_d16",
+	"clk26m",
+	"clk26m",
+};
+
+static const char * const aud_1_parents[] = {
+	"clk26m",
+	"apll1_ck",
+};
+
+static const char * const aud_2_parents[] = {
+	"clk26m",
+	"apll2_ck",
+};
+
+static const char * const ssusb_top_sys_parents[] = {
+	"clk26m",
+	"univpll3_d2",
+};
+
+static const char * const spm_parents[] = {
+	"clk26m",
+	"syspll1_d8",
+};
+
+static const char * const bsi_spi_parents[] = {
+	"clk26m",
+	"syspll_d3_d3",
+	"syspll1_d4",
+	"syspll_d7",
+};
+
+static const char * const audio_h_parents[] = {
+	"clk26m",
+	"apll2_ck",
+	"apll1_ck",
+	"univpll_d7",
+};
+
+static const char * const mfg_52m_parents[] = {
+	"clk26m",
+	"univpll2_d8",
+	"univpll2_d4",
+	"univpll2_d4",
+};
+
+static const char * const anc_md32_parents[] = {
+	"clk26m",
+	"syspll1_d2",
+	"univpll_d5",
+};
+
+static const struct mtk_composite top_muxes[] = {
+	MUX(CLK_TOP_MUX_ULPOSC_AXI_CK_MUX_PRE, "ulposc_axi_ck_mux_pre",
+	    ulposc_axi_ck_mux_pre_parents, 0x0040, 3, 1),
+	MUX(CLK_TOP_MUX_ULPOSC_AXI_CK_MUX, "ulposc_axi_ck_mux",
+	    ulposc_axi_ck_mux_parents, 0x0040, 2, 1),
+	MUX(CLK_TOP_MUX_AXI, "axi_sel", axi_parents,
+	    0x0040, 0, 2),
+	MUX(CLK_TOP_MUX_DDRPHYCFG, "ddrphycfg_sel", ddrphycfg_parents,
+	    0x0040, 16, 2),
+	MUX(CLK_TOP_MUX_MM, "mm_sel", mm_parents,
+	    0x0040, 24, 2),
+	MUX_GATE(CLK_TOP_MUX_PWM, "pwm_sel", pwm_parents, 0x0050, 0, 3, 7),
+	MUX_GATE(CLK_TOP_MUX_VDEC, "vdec_sel", vdec_parents, 0x0050, 8, 3, 15),
+	MUX_GATE(CLK_TOP_MUX_VENC, "venc_sel", venc_parents, 0x0050, 16, 2, 23),
+	MUX_GATE(CLK_TOP_MUX_MFG, "mfg_sel", mfg_parents, 0x0050, 24, 2, 31),
+	MUX_GATE(CLK_TOP_MUX_CAMTG, "camtg_sel", camtg, 0x0060, 0, 2, 7),
+	MUX_GATE(CLK_TOP_MUX_UART, "uart_sel", uart_parents, 0x0060, 8, 1, 15),
+	MUX_GATE(CLK_TOP_MUX_SPI, "spi_sel", spi_parents, 0x0060, 16, 2, 23),
+	MUX(CLK_TOP_MUX_ULPOSC_SPI_CK_MUX, "ulposc_spi_ck_mux",
+	    ulposc_spi_ck_mux_parents, 0x0060, 18, 1),
+	MUX_GATE(CLK_TOP_MUX_USB20, "usb20_sel", usb20_parents,
+		 0x0060, 24, 2, 31),
+	MUX(CLK_TOP_MUX_MSDC50_0_HCLK, "msdc50_0_hclk_sel",
+	    msdc50_0_hclk_parents, 0x0070, 8, 2),
+	MUX_GATE(CLK_TOP_MUX_MSDC50_0, "msdc50_0_sel", msdc50_0_parents,
+		 0x0070, 16, 4, 23),
+	MUX_GATE(CLK_TOP_MUX_MSDC30_1, "msdc30_1_sel", msdc30_1_parents,
+		 0x0070, 24, 3, 31),
+	MUX_GATE(CLK_TOP_MUX_MSDC30_2, "msdc30_2_sel", msdc30_2_parents,
+		 0x0080, 0, 3, 7),
+	MUX_GATE(CLK_TOP_MUX_AUDIO, "audio_sel", audio_parents,
+		 0x0080, 16, 2, 23),
+	MUX(CLK_TOP_MUX_AUD_INTBUS, "aud_intbus_sel", aud_intbus_parents,
+	    0x0080, 24, 2),
+	MUX(CLK_TOP_MUX_PMICSPI, "pmicspi_sel", pmicspi_parents,
+	    0x0090, 0, 3),
+	MUX(CLK_TOP_MUX_SCP, "scp_sel", scp_parents,
+	    0x0090, 8, 2),
+	MUX(CLK_TOP_MUX_ATB, "atb_sel", atb_parents,
+	    0x0090, 16, 2),
+	MUX_GATE(CLK_TOP_MUX_MJC, "mjc_sel", mjc_parents, 0x0090, 24, 2, 31),
+	MUX_GATE(CLK_TOP_MUX_DPI0, "dpi0_sel", dpi0_parents, 0x00A0, 0, 3, 7),
+	MUX_GATE(CLK_TOP_MUX_AUD_1, "aud_1_sel", aud_1_parents,
+		 0x00A0, 16, 1, 23),
+	MUX_GATE(CLK_TOP_MUX_AUD_2, "aud_2_sel", aud_2_parents,
+		 0x00A0, 24, 1, 31),
+	MUX(CLK_TOP_MUX_SSUSB_TOP_SYS, "ssusb_top_sys_sel",
+	    ssusb_top_sys_parents, 0x00B0, 8, 1),
+	MUX(CLK_TOP_MUX_SPM, "spm_sel", spm_parents,
+	    0x00C0, 0, 1),
+	MUX(CLK_TOP_MUX_BSI_SPI, "bsi_spi_sel", bsi_spi_parents,
+	    0x00C0, 8, 2),
+	MUX_GATE(CLK_TOP_MUX_AUDIO_H, "audio_h_sel", audio_h_parents,
+		 0x00C0, 16, 2, 23),
+	MUX_GATE(CLK_TOP_MUX_ANC_MD32, "anc_md32_sel", anc_md32_parents,
+		 0x00C0, 24, 2, 31),
+	MUX(CLK_TOP_MUX_MFG_52M, "mfg_52m_sel", mfg_52m_parents,
+	    0x0104, 1, 2),
+};
+
+static int mtk_topckgen_init(struct platform_device *pdev)
+{
+	struct clk_onecell_data *clk_data;
+	void __iomem *base;
+	struct device_node *node = pdev->dev.of_node;
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	clk_data = mtk_alloc_clk_data(CLK_TOP_NR);
+
+	mtk_clk_register_factors(top_fixed_divs, ARRAY_SIZE(top_fixed_divs),
+				 clk_data);
+
+	mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
+				    &mt6797_clk_lock, clk_data);
+
+	return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+static const struct mtk_gate_regs infra0_cg_regs = {
+	.set_ofs = 0x0080,
+	.clr_ofs = 0x0084,
+	.sta_ofs = 0x0090,
+};
+
+static const struct mtk_gate_regs infra1_cg_regs = {
+	.set_ofs = 0x0088,
+	.clr_ofs = 0x008c,
+	.sta_ofs = 0x0094,
+};
+
+static const struct mtk_gate_regs infra2_cg_regs = {
+	.set_ofs = 0x00a8,
+	.clr_ofs = 0x00ac,
+	.sta_ofs = 0x00b0,
+};
+
+#define GATE_ICG0(_id, _name, _parent, _shift) {	\
+	.id = _id,					\
+	.name = _name,					\
+	.parent_name = _parent,				\
+	.regs = &infra0_cg_regs,			\
+	.shift = _shift,				\
+	.ops = &mtk_clk_gate_ops_setclr,		\
+}
+
+#define GATE_ICG1(_id, _name, _parent, _shift) {	\
+	.id = _id,					\
+	.name = _name,					\
+	.parent_name = _parent,				\
+	.regs = &infra1_cg_regs,			\
+	.shift = _shift,				\
+	.ops = &mtk_clk_gate_ops_setclr,		\
+}
+
+#define GATE_ICG2(_id, _name, _parent, _shift) {	\
+	.id = _id,					\
+	.name = _name,					\
+	.parent_name = _parent,				\
+	.regs = &infra2_cg_regs,			\
+	.shift = _shift,				\
+	.ops = &mtk_clk_gate_ops_setclr,		\
+}
+
+static const struct mtk_gate infra_clks[] = {
+	GATE_ICG0(CLK_INFRA_PMIC_TMR, "infra_pmic_tmr", "ulposc", 0),
+	GATE_ICG0(CLK_INFRA_PMIC_AP, "infra_pmic_ap", "pmicspi_sel", 1),
+	GATE_ICG0(CLK_INFRA_PMIC_MD, "infra_pmic_md", "pmicspi_sel", 2),
+	GATE_ICG0(CLK_INFRA_PMIC_CONN, "infra_pmic_conn", "pmicspi_sel", 3),
+	GATE_ICG0(CLK_INFRA_SCP, "infra_scp", "scp_sel", 4),
+	GATE_ICG0(CLK_INFRA_SEJ, "infra_sej", "axi_sel", 5),
+	GATE_ICG0(CLK_INFRA_APXGPT, "infra_apxgpt", "axi_sel", 6),
+	GATE_ICG0(CLK_INFRA_SEJ_13M, "infra_sej_13m", "clk26m", 7),
+	GATE_ICG0(CLK_INFRA_ICUSB, "infra_icusb", "usb20_sel", 8),
+	GATE_ICG0(CLK_INFRA_GCE, "infra_gce", "axi_sel", 9),
+	GATE_ICG0(CLK_INFRA_THERM, "infra_therm", "axi_sel", 10),
+	GATE_ICG0(CLK_INFRA_I2C0, "infra_i2c0", "axi_sel", 11),
+	GATE_ICG0(CLK_INFRA_I2C1, "infra_i2c1", "axi_sel", 12),
+	GATE_ICG0(CLK_INFRA_I2C2, "infra_i2c2", "axi_sel", 13),
+	GATE_ICG0(CLK_INFRA_I2C3, "infra_i2c3", "axi_sel", 14),
+	GATE_ICG0(CLK_INFRA_PWM_HCLK, "infra_pwm_hclk", "axi_sel", 15),
+	GATE_ICG0(CLK_INFRA_PWM1, "infra_pwm1", "axi_sel", 16),
+	GATE_ICG0(CLK_INFRA_PWM2, "infra_pwm2", "axi_sel", 17),
+	GATE_ICG0(CLK_INFRA_PWM3, "infra_pwm3", "axi_sel", 18),
+	GATE_ICG0(CLK_INFRA_PWM4, "infra_pwm4", "axi_sel", 19),
+	GATE_ICG0(CLK_INFRA_PWM, "infra_pwm", "axi_sel", 21),
+	GATE_ICG0(CLK_INFRA_UART0, "infra_uart0", "uart_sel", 22),
+	GATE_ICG0(CLK_INFRA_UART1, "infra_uart1", "uart_sel", 23),
+	GATE_ICG0(CLK_INFRA_UART2, "infra_uart2", "uart_sel", 24),
+	GATE_ICG0(CLK_INFRA_UART3, "infra_uart3", "uart_sel", 25),
+	GATE_ICG0(CLK_INFRA_MD2MD_CCIF_0, "infra_md2md_ccif_0", "axi_sel", 27),
+	GATE_ICG0(CLK_INFRA_MD2MD_CCIF_1, "infra_md2md_ccif_1", "axi_sel", 28),
+	GATE_ICG0(CLK_INFRA_MD2MD_CCIF_2, "infra_md2md_ccif_2", "axi_sel", 29),
+	GATE_ICG0(CLK_INFRA_FHCTL, "infra_fhctl", "clk26m", 30),
+	GATE_ICG0(CLK_INFRA_BTIF, "infra_btif", "axi_sel", 31),
+	GATE_ICG1(CLK_INFRA_MD2MD_CCIF_3, "infra_md2md_ccif_3", "axi_sel", 0),
+	GATE_ICG1(CLK_INFRA_SPI, "infra_spi", "spi_sel", 1),
+	GATE_ICG1(CLK_INFRA_MSDC0, "infra_msdc0", "msdc50_0_sel", 2),
+	GATE_ICG1(CLK_INFRA_MD2MD_CCIF_4, "infra_md2md_ccif_4", "axi_sel", 3),
+	GATE_ICG1(CLK_INFRA_MSDC1, "infra_msdc1", "msdc30_1_sel", 4),
+	GATE_ICG1(CLK_INFRA_MSDC2, "infra_msdc2", "msdc30_2_sel", 5),
+	GATE_ICG1(CLK_INFRA_MD2MD_CCIF_5, "infra_md2md_ccif_5", "axi_sel", 7),
+	GATE_ICG1(CLK_INFRA_GCPU, "infra_gcpu", "axi_sel", 8),
+	GATE_ICG1(CLK_INFRA_TRNG, "infra_trng", "axi_sel", 9),
+	GATE_ICG1(CLK_INFRA_AUXADC, "infra_auxadc", "clk26m", 10),
+	GATE_ICG1(CLK_INFRA_CPUM, "infra_cpum", "axi_sel", 11),
+	GATE_ICG1(CLK_INFRA_AP_C2K_CCIF_0, "infra_ap_c2k_ccif_0",
+		  "axi_sel", 12),
+	GATE_ICG1(CLK_INFRA_AP_C2K_CCIF_1, "infra_ap_c2k_ccif_1",
+		  "axi_sel", 13),
+	GATE_ICG1(CLK_INFRA_CLDMA, "infra_cldma", "axi_sel", 16),
+	GATE_ICG1(CLK_INFRA_DISP_PWM, "infra_disp_pwm", "pwm_sel", 17),
+	GATE_ICG1(CLK_INFRA_AP_DMA, "infra_ap_dma", "axi_sel", 18),
+	GATE_ICG1(CLK_INFRA_DEVICE_APC, "infra_device_apc", "axi_sel", 20),
+	GATE_ICG1(CLK_INFRA_L2C_SRAM, "infra_l2c_sram", "mm_sel", 22),
+	GATE_ICG1(CLK_INFRA_CCIF_AP, "infra_ccif_ap", "axi_sel", 23),
+	GATE_ICG1(CLK_INFRA_AUDIO, "infra_audio", "axi_sel", 25),
+	GATE_ICG1(CLK_INFRA_CCIF_MD, "infra_ccif_md", "axi_sel", 26),
+	GATE_ICG1(CLK_INFRA_DRAMC_F26M, "infra_dramc_f26m", "clk26m", 31),
+	GATE_ICG2(CLK_INFRA_I2C4, "infra_i2c4", "axi_sel", 0),
+	GATE_ICG2(CLK_INFRA_I2C_APPM, "infra_i2c_appm", "axi_sel", 1),
+	GATE_ICG2(CLK_INFRA_I2C_GPUPM, "infra_i2c_gpupm", "axi_sel", 2),
+	GATE_ICG2(CLK_INFRA_I2C2_IMM, "infra_i2c2_imm", "axi_sel", 3),
+	GATE_ICG2(CLK_INFRA_I2C2_ARB, "infra_i2c2_arb", "axi_sel", 4),
+	GATE_ICG2(CLK_INFRA_I2C3_IMM, "infra_i2c3_imm", "axi_sel", 5),
+	GATE_ICG2(CLK_INFRA_I2C3_ARB, "infra_i2c3_arb", "axi_sel", 6),
+	GATE_ICG2(CLK_INFRA_I2C5, "infra_i2c5", "axi_sel", 7),
+	GATE_ICG2(CLK_INFRA_SYS_CIRQ, "infra_sys_cirq", "axi_sel", 8),
+	GATE_ICG2(CLK_INFRA_SPI1, "infra_spi1", "spi_sel", 10),
+	GATE_ICG2(CLK_INFRA_DRAMC_B_F26M, "infra_dramc_b_f26m", "clk26m", 11),
+	GATE_ICG2(CLK_INFRA_ANC_MD32, "infra_anc_md32", "anc_md32_sel", 12),
+	GATE_ICG2(CLK_INFRA_ANC_MD32_32K, "infra_anc_md32_32k", "clk26m", 13),
+	GATE_ICG2(CLK_INFRA_DVFS_SPM1, "infra_dvfs_spm1", "axi_sel", 15),
+	GATE_ICG2(CLK_INFRA_AES_TOP0, "infra_aes_top0", "axi_sel", 16),
+	GATE_ICG2(CLK_INFRA_AES_TOP1, "infra_aes_top1", "axi_sel", 17),
+	GATE_ICG2(CLK_INFRA_SSUSB_BUS, "infra_ssusb_bus", "axi_sel", 18),
+	GATE_ICG2(CLK_INFRA_SPI2, "infra_spi2", "spi_sel", 19),
+	GATE_ICG2(CLK_INFRA_SPI3, "infra_spi3", "spi_sel", 20),
+	GATE_ICG2(CLK_INFRA_SPI4, "infra_spi4", "spi_sel", 21),
+	GATE_ICG2(CLK_INFRA_SPI5, "infra_spi5", "spi_sel", 22),
+	GATE_ICG2(CLK_INFRA_IRTX, "infra_irtx", "spi_sel", 23),
+	GATE_ICG2(CLK_INFRA_SSUSB_SYS, "infra_ssusb_sys",
+		  "ssusb_top_sys_sel", 24),
+	GATE_ICG2(CLK_INFRA_SSUSB_REF, "infra_ssusb_ref", "clk26m", 9),
+	GATE_ICG2(CLK_INFRA_AUDIO_26M, "infra_audio_26m", "clk26m", 26),
+	GATE_ICG2(CLK_INFRA_AUDIO_26M_PAD_TOP, "infra_audio_26m_pad_top",
+		  "clk26m", 27),
+	GATE_ICG2(CLK_INFRA_MODEM_TEMP_SHARE, "infra_modem_temp_share",
+		  "axi_sel", 28),
+	GATE_ICG2(CLK_INFRA_VAD_WRAP_SOC, "infra_vad_wrap_soc", "axi_sel", 29),
+	GATE_ICG2(CLK_INFRA_DRAMC_CONF, "infra_dramc_conf", "axi_sel", 30),
+	GATE_ICG2(CLK_INFRA_DRAMC_B_CONF, "infra_dramc_b_conf", "axi_sel", 31),
+	GATE_ICG1(CLK_INFRA_MFG_VCG, "infra_mfg_vcg", "mfg_52m_sel", 14),
+};
+
+static const struct mtk_fixed_factor infra_fixed_divs[] = {
+	FACTOR(CLK_INFRA_13M, "clk13m", "clk26m", 1, 2),
+};
+
+static struct clk_onecell_data *infra_clk_data;
+
+static void mtk_infrasys_init_early(struct device_node *node)
+{
+	int r, i;
+
+	if (!infra_clk_data) {
+		infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR);
+
+		for (i = 0; i < CLK_INFRA_NR; i++)
+			infra_clk_data->clks[i] = ERR_PTR(-EPROBE_DEFER);
+	}
+
+	mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
+				 infra_clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, infra_clk_data);
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+		       __func__, r);
+}
+
+CLK_OF_DECLARE_DRIVER(mtk_infra, "mediatek,mt6797-infracfg",
+		      mtk_infrasys_init_early);
+
+static int mtk_infrasys_init(struct platform_device *pdev)
+{
+	int r, i;
+	struct device_node *node = pdev->dev.of_node;
+
+	if (!infra_clk_data) {
+		infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR);
+	} else {
+		for (i = 0; i < CLK_INFRA_NR; i++) {
+			if (infra_clk_data->clks[i] == ERR_PTR(-EPROBE_DEFER))
+				infra_clk_data->clks[i] = ERR_PTR(-ENOENT);
+		}
+	}
+
+	mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
+			       infra_clk_data);
+	mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
+				 infra_clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, infra_clk_data);
+	if (r)
+		return r;
+
+	return 0;
+}
+
+#define MT6797_PLL_FMAX		(3000UL * MHZ)
+
+#define CON0_MT6797_RST_BAR	BIT(24)
+
+#define PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,	\
+			_pd_reg, _pd_shift, _tuner_reg, _pcw_reg,	\
+			_pcw_shift, _div_table) {			\
+	.id = _id,						\
+	.name = _name,						\
+	.reg = _reg,						\
+	.pwr_reg = _pwr_reg,					\
+	.en_mask = _en_mask,					\
+	.flags = _flags,					\
+	.rst_bar_mask = CON0_MT6797_RST_BAR,			\
+	.fmax = MT6797_PLL_FMAX,				\
+	.pcwbits = _pcwbits,					\
+	.pd_reg = _pd_reg,					\
+	.pd_shift = _pd_shift,					\
+	.tuner_reg = _tuner_reg,				\
+	.pcw_reg = _pcw_reg,					\
+	.pcw_shift = _pcw_shift,				\
+	.div_table = _div_table,				\
+}
+
+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,	\
+			_pd_reg, _pd_shift, _tuner_reg, _pcw_reg,	\
+			_pcw_shift)					\
+		PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \
+			_pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift, \
+			NULL)
+
+static const struct mtk_pll_data plls[] = {
+	PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x0220, 0x022C, 0xF0000101, PLL_AO,
+	    21, 0x220, 4, 0x0, 0x224, 0),
+	PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x0230, 0x023C, 0xFE000011, 0, 7,
+	    0x230, 4, 0x0, 0x234, 14),
+	PLL(CLK_APMIXED_MFGPLL, "mfgpll", 0x0240, 0x024C, 0x00000101, 0, 21,
+	    0x244, 24, 0x0, 0x244, 0),
+	PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x0250, 0x025C, 0x00000121, 0, 21,
+	    0x250, 4, 0x0, 0x254, 0),
+	PLL(CLK_APMIXED_IMGPLL, "imgpll", 0x0260, 0x026C, 0x00000121, 0, 21,
+	    0x260, 4, 0x0, 0x264, 0),
+	PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x0270, 0x027C, 0xC0000121, 0, 21,
+	    0x270, 4, 0x0, 0x274, 0),
+	PLL(CLK_APMIXED_CODECPLL, "codecpll", 0x0290, 0x029C, 0x00000121, 0, 21,
+	    0x290, 4, 0x0, 0x294, 0),
+	PLL(CLK_APMIXED_VDECPLL, "vdecpll", 0x02E4, 0x02F0, 0x00000121, 0, 21,
+	    0x2E4, 4, 0x0, 0x2E8, 0),
+	PLL(CLK_APMIXED_APLL1, "apll1", 0x02A0, 0x02B0, 0x00000131, 0, 31,
+	    0x2A0, 4, 0x2A8, 0x2A4, 0),
+	PLL(CLK_APMIXED_APLL2, "apll2", 0x02B4, 0x02C4, 0x00000131, 0, 31,
+	    0x2B4, 4, 0x2BC, 0x2B8, 0),
+};
+
+static int mtk_apmixedsys_init(struct platform_device *pdev)
+{
+	struct clk_onecell_data *clk_data;
+	struct device_node *node = pdev->dev.of_node;
+
+	clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR);
+	if (!clk_data)
+		return -ENOMEM;
+
+	mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
+
+	return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+static const struct of_device_id of_match_clk_mt6797[] = {
+	{
+		.compatible = "mediatek,mt6797-topckgen",
+		.data = mtk_topckgen_init,
+	}, {
+		.compatible = "mediatek,mt6797-infracfg",
+		.data = mtk_infrasys_init,
+	}, {
+		.compatible = "mediatek,mt6797-apmixedsys",
+		.data = mtk_apmixedsys_init,
+	}, {
+		/* sentinel */
+	}
+};
+
+static int clk_mt6797_probe(struct platform_device *pdev)
+{
+	int (*clk_init)(struct platform_device *);
+	int r;
+
+	clk_init = of_device_get_match_data(&pdev->dev);
+	if (!clk_init)
+		return -EINVAL;
+
+	r = clk_init(pdev);
+	if (r)
+		dev_err(&pdev->dev,
+			"could not register clock provider: %s: %d\n",
+			pdev->name, r);
+
+	return r;
+}
+
+static struct platform_driver clk_mt6797_drv = {
+	.probe = clk_mt6797_probe,
+	.driver = {
+		.name = "clk-mt6797",
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_clk_mt6797,
+	},
+};
+
+static int __init clk_mt6797_init(void)
+{
+	return platform_driver_register(&clk_mt6797_drv);
+}
+
+arch_initcall(clk_mt6797_init);
diff --git a/include/dt-bindings/clock/mt6797-clk.h b/include/dt-bindings/clock/mt6797-clk.h
new file mode 100644
index 0000000..e48aa47
--- /dev/null
+++ b/include/dt-bindings/clock/mt6797-clk.h
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Kevin Chen <kevin-cw.chen@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_MT6797_H
+#define _DT_BINDINGS_CLK_MT6797_H
+
+/* TOPCKGEN */
+#define	CLK_TOP_MUX_ULPOSC_AXI_CK_MUX_PRE	1
+#define	CLK_TOP_MUX_ULPOSC_AXI_CK_MUX		2
+#define	CLK_TOP_MUX_AXI				3
+#define	CLK_TOP_MUX_MEM				4
+#define	CLK_TOP_MUX_DDRPHYCFG			5
+#define	CLK_TOP_MUX_MM				6
+#define	CLK_TOP_MUX_PWM				7
+#define	CLK_TOP_MUX_VDEC			8
+#define	CLK_TOP_MUX_VENC			9
+#define	CLK_TOP_MUX_MFG				10
+#define	CLK_TOP_MUX_CAMTG			11
+#define	CLK_TOP_MUX_UART			12
+#define	CLK_TOP_MUX_SPI				13
+#define	CLK_TOP_MUX_ULPOSC_SPI_CK_MUX		14
+#define	CLK_TOP_MUX_USB20			15
+#define	CLK_TOP_MUX_MSDC50_0_HCLK		16
+#define	CLK_TOP_MUX_MSDC50_0			17
+#define	CLK_TOP_MUX_MSDC30_1			18
+#define	CLK_TOP_MUX_MSDC30_2			19
+#define	CLK_TOP_MUX_AUDIO			20
+#define	CLK_TOP_MUX_AUD_INTBUS			21
+#define	CLK_TOP_MUX_PMICSPI			22
+#define	CLK_TOP_MUX_SCP				23
+#define	CLK_TOP_MUX_ATB				24
+#define	CLK_TOP_MUX_MJC				25
+#define	CLK_TOP_MUX_DPI0			26
+#define	CLK_TOP_MUX_AUD_1			27
+#define	CLK_TOP_MUX_AUD_2			28
+#define	CLK_TOP_MUX_SSUSB_TOP_SYS		29
+#define	CLK_TOP_MUX_SPM				30
+#define	CLK_TOP_MUX_BSI_SPI			31
+#define	CLK_TOP_MUX_AUDIO_H			32
+#define	CLK_TOP_MUX_ANC_MD32			33
+#define	CLK_TOP_MUX_MFG_52M			34
+#define	CLK_TOP_SYSPLL_CK			35
+#define	CLK_TOP_SYSPLL_D2			36
+#define	CLK_TOP_SYSPLL1_D2			37
+#define	CLK_TOP_SYSPLL1_D4			38
+#define	CLK_TOP_SYSPLL1_D8			39
+#define	CLK_TOP_SYSPLL1_D16			40
+#define	CLK_TOP_SYSPLL_D3			41
+#define	CLK_TOP_SYSPLL_D3_D3			42
+#define	CLK_TOP_SYSPLL2_D2			43
+#define	CLK_TOP_SYSPLL2_D4			44
+#define	CLK_TOP_SYSPLL2_D8			45
+#define	CLK_TOP_SYSPLL_D5			46
+#define	CLK_TOP_SYSPLL3_D2			47
+#define	CLK_TOP_SYSPLL3_D4			48
+#define	CLK_TOP_SYSPLL_D7			49
+#define	CLK_TOP_SYSPLL4_D2			50
+#define	CLK_TOP_SYSPLL4_D4			51
+#define	CLK_TOP_UNIVPLL_CK			52
+#define	CLK_TOP_UNIVPLL_D7			53
+#define	CLK_TOP_UNIVPLL_D26			54
+#define	CLK_TOP_SSUSB_PHY_48M_CK		55
+#define	CLK_TOP_USB_PHY48M_CK			56
+#define	CLK_TOP_UNIVPLL_D2			57
+#define	CLK_TOP_UNIVPLL1_D2			58
+#define	CLK_TOP_UNIVPLL1_D4			59
+#define	CLK_TOP_UNIVPLL1_D8			60
+#define	CLK_TOP_UNIVPLL_D3			61
+#define	CLK_TOP_UNIVPLL2_D2			62
+#define	CLK_TOP_UNIVPLL2_D4			63
+#define	CLK_TOP_UNIVPLL2_D8			64
+#define	CLK_TOP_UNIVPLL_D5			65
+#define	CLK_TOP_UNIVPLL3_D2			66
+#define	CLK_TOP_UNIVPLL3_D4			67
+#define	CLK_TOP_UNIVPLL3_D8			68
+#define	CLK_TOP_ULPOSC_CK_ORG			69
+#define	CLK_TOP_ULPOSC_CK			70
+#define	CLK_TOP_ULPOSC_D2			71
+#define	CLK_TOP_ULPOSC_D3			72
+#define	CLK_TOP_ULPOSC_D4			73
+#define	CLK_TOP_ULPOSC_D8			74
+#define	CLK_TOP_ULPOSC_D10			75
+#define	CLK_TOP_APLL1_CK			76
+#define	CLK_TOP_APLL2_CK			77
+#define	CLK_TOP_MFGPLL_CK			78
+#define	CLK_TOP_MFGPLL_D2			79
+#define	CLK_TOP_IMGPLL_CK			80
+#define	CLK_TOP_IMGPLL_D2			81
+#define	CLK_TOP_IMGPLL_D4			82
+#define	CLK_TOP_CODECPLL_CK			83
+#define	CLK_TOP_CODECPLL_D2			84
+#define	CLK_TOP_VDECPLL_CK			85
+#define	CLK_TOP_TVDPLL_CK			86
+#define	CLK_TOP_TVDPLL_D2			87
+#define	CLK_TOP_TVDPLL_D4			88
+#define	CLK_TOP_TVDPLL_D8			89
+#define	CLK_TOP_TVDPLL_D16			90
+#define	CLK_TOP_MSDCPLL_CK			91
+#define	CLK_TOP_MSDCPLL_D2			92
+#define	CLK_TOP_MSDCPLL_D4			93
+#define	CLK_TOP_MSDCPLL_D8			94
+#define CLK_TOP_NR				95
+
+/* APMIXED_SYS */
+#define CLK_APMIXED_MAINPLL			1
+#define CLK_APMIXED_UNIVPLL			2
+#define CLK_APMIXED_MFGPLL			3
+#define CLK_APMIXED_MSDCPLL			4
+#define CLK_APMIXED_IMGPLL			5
+#define CLK_APMIXED_TVDPLL			6
+#define CLK_APMIXED_CODECPLL			7
+#define CLK_APMIXED_VDECPLL			8
+#define CLK_APMIXED_APLL1			9
+#define CLK_APMIXED_APLL2			10
+#define CLK_APMIXED_NR				11
+
+/* INFRA_SYS */
+#define	CLK_INFRA_PMIC_TMR			1
+#define	CLK_INFRA_PMIC_AP			2
+#define	CLK_INFRA_PMIC_MD			3
+#define	CLK_INFRA_PMIC_CONN			4
+#define	CLK_INFRA_SCP				5
+#define	CLK_INFRA_SEJ				6
+#define	CLK_INFRA_APXGPT			7
+#define	CLK_INFRA_SEJ_13M			8
+#define	CLK_INFRA_ICUSB				9
+#define	CLK_INFRA_GCE				10
+#define	CLK_INFRA_THERM				11
+#define	CLK_INFRA_I2C0				12
+#define	CLK_INFRA_I2C1				13
+#define	CLK_INFRA_I2C2				14
+#define	CLK_INFRA_I2C3				15
+#define	CLK_INFRA_PWM_HCLK			16
+#define	CLK_INFRA_PWM1				17
+#define	CLK_INFRA_PWM2				18
+#define	CLK_INFRA_PWM3				19
+#define	CLK_INFRA_PWM4				20
+#define	CLK_INFRA_PWM				21
+#define	CLK_INFRA_UART0				22
+#define	CLK_INFRA_UART1				23
+#define	CLK_INFRA_UART2				24
+#define	CLK_INFRA_UART3				25
+#define	CLK_INFRA_MD2MD_CCIF_0			26
+#define	CLK_INFRA_MD2MD_CCIF_1			27
+#define	CLK_INFRA_MD2MD_CCIF_2			28
+#define	CLK_INFRA_FHCTL				29
+#define	CLK_INFRA_BTIF				30
+#define	CLK_INFRA_MD2MD_CCIF_3			31
+#define	CLK_INFRA_SPI				32
+#define	CLK_INFRA_MSDC0				33
+#define	CLK_INFRA_MD2MD_CCIF_4			34
+#define	CLK_INFRA_MSDC1				35
+#define	CLK_INFRA_MSDC2				36
+#define	CLK_INFRA_MD2MD_CCIF_5			37
+#define	CLK_INFRA_GCPU				38
+#define	CLK_INFRA_TRNG				39
+#define	CLK_INFRA_AUXADC			40
+#define	CLK_INFRA_CPUM				41
+#define	CLK_INFRA_AP_C2K_CCIF_0			42
+#define	CLK_INFRA_AP_C2K_CCIF_1			43
+#define	CLK_INFRA_CLDMA				44
+#define	CLK_INFRA_DISP_PWM			45
+#define	CLK_INFRA_AP_DMA			46
+#define	CLK_INFRA_DEVICE_APC			47
+#define	CLK_INFRA_L2C_SRAM			48
+#define	CLK_INFRA_CCIF_AP			49
+#define	CLK_INFRA_AUDIO				50
+#define	CLK_INFRA_CCIF_MD			51
+#define	CLK_INFRA_DRAMC_F26M			52
+#define	CLK_INFRA_I2C4				53
+#define	CLK_INFRA_I2C_APPM			54
+#define	CLK_INFRA_I2C_GPUPM			55
+#define	CLK_INFRA_I2C2_IMM			56
+#define	CLK_INFRA_I2C2_ARB			57
+#define	CLK_INFRA_I2C3_IMM			58
+#define	CLK_INFRA_I2C3_ARB			59
+#define	CLK_INFRA_I2C5				60
+#define	CLK_INFRA_SYS_CIRQ			61
+#define	CLK_INFRA_SPI1				62
+#define	CLK_INFRA_DRAMC_B_F26M			63
+#define	CLK_INFRA_ANC_MD32			64
+#define	CLK_INFRA_ANC_MD32_32K			65
+#define	CLK_INFRA_DVFS_SPM1			66
+#define	CLK_INFRA_AES_TOP0			67
+#define	CLK_INFRA_AES_TOP1			68
+#define	CLK_INFRA_SSUSB_BUS			69
+#define	CLK_INFRA_SPI2				70
+#define	CLK_INFRA_SPI3				71
+#define	CLK_INFRA_SPI4				72
+#define	CLK_INFRA_SPI5				73
+#define	CLK_INFRA_IRTX				74
+#define	CLK_INFRA_SSUSB_SYS			75
+#define	CLK_INFRA_SSUSB_REF			76
+#define	CLK_INFRA_AUDIO_26M			77
+#define	CLK_INFRA_AUDIO_26M_PAD_TOP		78
+#define	CLK_INFRA_MODEM_TEMP_SHARE		79
+#define	CLK_INFRA_VAD_WRAP_SOC			80
+#define	CLK_INFRA_DRAMC_CONF			81
+#define	CLK_INFRA_DRAMC_B_CONF			82
+#define CLK_INFRA_MFG_VCG			83
+#define CLK_INFRA_13M				84
+#define CLK_INFRA_NR				85
+
+/* IMG_SYS */
+#define	CLK_IMG_FDVT				1
+#define	CLK_IMG_DPE				2
+#define	CLK_IMG_DIP				3
+#define	CLK_IMG_LARB6				4
+#define CLK_IMG_NR				5
+
+/* MM_SYS */
+#define	CLK_MM_SMI_COMMON			1
+#define	CLK_MM_SMI_LARB0			2
+#define	CLK_MM_SMI_LARB5			3
+#define	CLK_MM_CAM_MDP				4
+#define	CLK_MM_MDP_RDMA0			5
+#define	CLK_MM_MDP_RDMA1			6
+#define	CLK_MM_MDP_RSZ0				7
+#define	CLK_MM_MDP_RSZ1				8
+#define	CLK_MM_MDP_RSZ2				9
+#define	CLK_MM_MDP_TDSHP			10
+#define	CLK_MM_MDP_COLOR			11
+#define	CLK_MM_MDP_WDMA				12
+#define	CLK_MM_MDP_WROT0			13
+#define	CLK_MM_MDP_WROT1			14
+#define	CLK_MM_FAKE_ENG				15
+#define	CLK_MM_DISP_OVL0			16
+#define	CLK_MM_DISP_OVL1			17
+#define	CLK_MM_DISP_OVL0_2L			18
+#define	CLK_MM_DISP_OVL1_2L			19
+#define	CLK_MM_DISP_RDMA0			20
+#define	CLK_MM_DISP_RDMA1			21
+#define	CLK_MM_DISP_WDMA0			22
+#define	CLK_MM_DISP_WDMA1			23
+#define	CLK_MM_DISP_COLOR			24
+#define	CLK_MM_DISP_CCORR			25
+#define	CLK_MM_DISP_AAL				26
+#define	CLK_MM_DISP_GAMMA			27
+#define	CLK_MM_DISP_OD				28
+#define	CLK_MM_DISP_DITHER			29
+#define	CLK_MM_DISP_UFOE			30
+#define	CLK_MM_DISP_DSC				31
+#define	CLK_MM_DISP_SPLIT			32
+#define	CLK_MM_DSI0_MM_CLOCK			33
+#define	CLK_MM_DSI1_MM_CLOCK			34
+#define	CLK_MM_DPI_MM_CLOCK			35
+#define	CLK_MM_DPI_INTERFACE_CLOCK		36
+#define	CLK_MM_LARB4_AXI_ASIF_MM_CLOCK		37
+#define	CLK_MM_LARB4_AXI_ASIF_MJC_CLOCK		38
+#define	CLK_MM_DISP_OVL0_MOUT_CLOCK		39
+#define	CLK_MM_FAKE_ENG2			40
+#define	CLK_MM_DSI0_INTERFACE_CLOCK		41
+#define	CLK_MM_DSI1_INTERFACE_CLOCK		42
+#define CLK_MM_NR				43
+
+/* VDEC_SYS */
+#define	CLK_VDEC_CKEN_ENG			1
+#define	CLK_VDEC_ACTIVE				2
+#define	CLK_VDEC_CKEN				3
+#define	CLK_VDEC_LARB1_CKEN			4
+#define CLK_VDEC_NR				5
+
+/* VENC_SYS */
+#define	CLK_VENC_0				1
+#define	CLK_VENC_1				2
+#define	CLK_VENC_2				3
+#define	CLK_VENC_3				4
+#define CLK_VENC_NR				5
+
+#endif /* _DT_BINDINGS_CLK_MT6797_H */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 07/10] soc: mediatek: refine scysys for mediatek platforms
@ 2017-02-06 12:15   ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-06 12:15 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: CC Hwang, Loda Chou, Miles Chen, Jades Shih, Yingjoe Chen,
	My Chuang, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, Marc Zyngier, Thomas Gleixner, Will Deacon,
	Stephen Boyd, linux-clk, Chieh-Jay Liu, Mars Cheng,
	Kevin-CW Chen

This adds 2 refinements: avoid fixed spm power statue and add vdec item

Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
Signed-off-by: Kevin-CW Chen <kevin-cw.chen@mediatek.com>
---
 drivers/soc/mediatek/mtk-scpsys.c |   35 +++++++++++++++++++++++++++++------
 1 file changed, 29 insertions(+), 6 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
index beb7916..a8ba800 100644
--- a/drivers/soc/mediatek/mtk-scpsys.c
+++ b/drivers/soc/mediatek/mtk-scpsys.c
@@ -71,6 +71,7 @@ enum clk_id {
 	CLK_VENC,
 	CLK_VENC_LT,
 	CLK_ETHIF,
+	CLK_VDEC,
 	CLK_MAX,
 };
 
@@ -81,6 +82,7 @@ enum clk_id {
 	"venc",
 	"venc_lt",
 	"ethif",
+	"vdec",
 	NULL,
 };
 
@@ -107,21 +109,28 @@ struct scp_domain {
 	struct regulator *supply;
 };
 
+struct scp_ctrl_reg {
+	int pwr_sta_offs;
+	int pwr_sta2nd_offs;
+};
+
 struct scp {
 	struct scp_domain *domains;
 	struct genpd_onecell_data pd_data;
 	struct device *dev;
 	void __iomem *base;
 	struct regmap *infracfg;
+	struct scp_ctrl_reg ctrl_reg;
 };
 
 static int scpsys_domain_is_on(struct scp_domain *scpd)
 {
 	struct scp *scp = scpd->scp;
 
-	u32 status = readl(scp->base + SPM_PWR_STATUS) & scpd->data->sta_mask;
-	u32 status2 = readl(scp->base + SPM_PWR_STATUS_2ND) &
-				scpd->data->sta_mask;
+	u32 status = readl(scp->base + scp->ctrl_reg.pwr_sta_offs) &
+						scpd->data->sta_mask;
+	u32 status2 = readl(scp->base + scp->ctrl_reg.pwr_sta2nd_offs) &
+						scpd->data->sta_mask;
 
 	/*
 	 * A domain is on when both status bits are set. If only one is set
@@ -346,7 +355,8 @@ static void init_clks(struct platform_device *pdev, struct clk **clk)
 }
 
 static struct scp *init_scp(struct platform_device *pdev,
-			const struct scp_domain_data *scp_domain_data, int num)
+			const struct scp_domain_data *scp_domain_data, int num,
+			struct scp_ctrl_reg *scp_ctrl_reg)
 {
 	struct genpd_onecell_data *pd_data;
 	struct resource *res;
@@ -358,6 +368,9 @@ static struct scp *init_scp(struct platform_device *pdev,
 	if (!scp)
 		return ERR_PTR(-ENOMEM);
 
+	scp->ctrl_reg.pwr_sta_offs = scp_ctrl_reg->pwr_sta_offs;
+	scp->ctrl_reg.pwr_sta2nd_offs = scp_ctrl_reg->pwr_sta2nd_offs;
+
 	scp->dev = &pdev->dev;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -556,8 +569,13 @@ static void mtk_register_power_domains(struct platform_device *pdev,
 static int __init scpsys_probe_mt2701(struct platform_device *pdev)
 {
 	struct scp *scp;
+	struct scp_ctrl_reg scp_reg;
 
-	scp = init_scp(pdev, scp_domain_data_mt2701, NUM_DOMAINS_MT2701);
+	scp_reg.pwr_sta_offs = SPM_PWR_STATUS;
+	scp_reg.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND;
+
+	scp = init_scp(pdev, scp_domain_data_mt2701, NUM_DOMAINS_MT2701,
+		       &scp_reg);
 	if (IS_ERR(scp))
 		return PTR_ERR(scp);
 
@@ -667,8 +685,13 @@ static int __init scpsys_probe_mt8173(struct platform_device *pdev)
 	struct scp *scp;
 	struct genpd_onecell_data *pd_data;
 	int ret;
+	struct scp_ctrl_reg scp_reg;
+
+	scp_reg.pwr_sta_offs = SPM_PWR_STATUS;
+	scp_reg.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND;
 
-	scp = init_scp(pdev, scp_domain_data_mt8173, NUM_DOMAINS_MT8173);
+	scp = init_scp(pdev, scp_domain_data_mt8173, NUM_DOMAINS_MT8173,
+		       &scp_reg);
 	if (IS_ERR(scp))
 		return PTR_ERR(scp);
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 07/10] soc: mediatek: refine scysys for mediatek platforms
@ 2017-02-06 12:15   ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-06 12:15 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, CC Hwang,
	wsd_upstream-NuS5LvNUpcJWk0Htik3J/w, Marc Zyngier, Will Deacon,
	Mars Cheng, Loda Chou, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	Jades Shih, linux-clk-u79uwXL29TY76Z2rM5mHXA, Miles Chen,
	Kevin-CW Chen, linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	My Chuang, Yingjoe Chen, Thomas Gleixner, Stephen Boyd,
	Chieh-Jay Liu

This adds 2 refinements: avoid fixed spm power statue and add vdec item

Signed-off-by: Mars Cheng <mars.cheng-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
Signed-off-by: Kevin-CW Chen <kevin-cw.chen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
---
 drivers/soc/mediatek/mtk-scpsys.c |   35 +++++++++++++++++++++++++++++------
 1 file changed, 29 insertions(+), 6 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
index beb7916..a8ba800 100644
--- a/drivers/soc/mediatek/mtk-scpsys.c
+++ b/drivers/soc/mediatek/mtk-scpsys.c
@@ -71,6 +71,7 @@ enum clk_id {
 	CLK_VENC,
 	CLK_VENC_LT,
 	CLK_ETHIF,
+	CLK_VDEC,
 	CLK_MAX,
 };
 
@@ -81,6 +82,7 @@ enum clk_id {
 	"venc",
 	"venc_lt",
 	"ethif",
+	"vdec",
 	NULL,
 };
 
@@ -107,21 +109,28 @@ struct scp_domain {
 	struct regulator *supply;
 };
 
+struct scp_ctrl_reg {
+	int pwr_sta_offs;
+	int pwr_sta2nd_offs;
+};
+
 struct scp {
 	struct scp_domain *domains;
 	struct genpd_onecell_data pd_data;
 	struct device *dev;
 	void __iomem *base;
 	struct regmap *infracfg;
+	struct scp_ctrl_reg ctrl_reg;
 };
 
 static int scpsys_domain_is_on(struct scp_domain *scpd)
 {
 	struct scp *scp = scpd->scp;
 
-	u32 status = readl(scp->base + SPM_PWR_STATUS) & scpd->data->sta_mask;
-	u32 status2 = readl(scp->base + SPM_PWR_STATUS_2ND) &
-				scpd->data->sta_mask;
+	u32 status = readl(scp->base + scp->ctrl_reg.pwr_sta_offs) &
+						scpd->data->sta_mask;
+	u32 status2 = readl(scp->base + scp->ctrl_reg.pwr_sta2nd_offs) &
+						scpd->data->sta_mask;
 
 	/*
 	 * A domain is on when both status bits are set. If only one is set
@@ -346,7 +355,8 @@ static void init_clks(struct platform_device *pdev, struct clk **clk)
 }
 
 static struct scp *init_scp(struct platform_device *pdev,
-			const struct scp_domain_data *scp_domain_data, int num)
+			const struct scp_domain_data *scp_domain_data, int num,
+			struct scp_ctrl_reg *scp_ctrl_reg)
 {
 	struct genpd_onecell_data *pd_data;
 	struct resource *res;
@@ -358,6 +368,9 @@ static struct scp *init_scp(struct platform_device *pdev,
 	if (!scp)
 		return ERR_PTR(-ENOMEM);
 
+	scp->ctrl_reg.pwr_sta_offs = scp_ctrl_reg->pwr_sta_offs;
+	scp->ctrl_reg.pwr_sta2nd_offs = scp_ctrl_reg->pwr_sta2nd_offs;
+
 	scp->dev = &pdev->dev;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -556,8 +569,13 @@ static void mtk_register_power_domains(struct platform_device *pdev,
 static int __init scpsys_probe_mt2701(struct platform_device *pdev)
 {
 	struct scp *scp;
+	struct scp_ctrl_reg scp_reg;
 
-	scp = init_scp(pdev, scp_domain_data_mt2701, NUM_DOMAINS_MT2701);
+	scp_reg.pwr_sta_offs = SPM_PWR_STATUS;
+	scp_reg.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND;
+
+	scp = init_scp(pdev, scp_domain_data_mt2701, NUM_DOMAINS_MT2701,
+		       &scp_reg);
 	if (IS_ERR(scp))
 		return PTR_ERR(scp);
 
@@ -667,8 +685,13 @@ static int __init scpsys_probe_mt8173(struct platform_device *pdev)
 	struct scp *scp;
 	struct genpd_onecell_data *pd_data;
 	int ret;
+	struct scp_ctrl_reg scp_reg;
+
+	scp_reg.pwr_sta_offs = SPM_PWR_STATUS;
+	scp_reg.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND;
 
-	scp = init_scp(pdev, scp_domain_data_mt8173, NUM_DOMAINS_MT8173);
+	scp = init_scp(pdev, scp_domain_data_mt8173, NUM_DOMAINS_MT8173,
+		       &scp_reg);
 	if (IS_ERR(scp))
 		return PTR_ERR(scp);
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 08/10] soc: mediatek: add MT6797 power dt-bindings
  2017-02-06 12:15 ` Mars Cheng
@ 2017-02-06 12:15   ` Mars Cheng
  -1 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-06 12:15 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: CC Hwang, Loda Chou, Miles Chen, Jades Shih, Yingjoe Chen,
	My Chuang, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, Marc Zyngier, Thomas Gleixner, Will Deacon,
	Stephen Boyd, linux-clk, Chieh-Jay Liu, Mars Cheng,
	Kevin-CW Chen

This adds power dt-bindings for MT6797

Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
Signed-off-by: Kevin-CW Chen <kevin-cw.chen@mediatek.com>
---
 .../devicetree/bindings/soc/mediatek/scpsys.txt    |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
index 16fe94d..b1d165b 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
+++ b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
@@ -9,11 +9,14 @@ domain control.
 
 The driver implements the Generic PM domain bindings described in
 power/power_domain.txt. It provides the power domains defined in
-include/dt-bindings/power/mt8173-power.h and mt2701-power.h.
+- include/dt-bindings/power/mt8173-power.h
+- include/dt-bindings/power/mt6797-power.h
+- include/dt-bindings/power/mt2701-power.h
 
 Required properties:
 - compatible: Should be one of:
 	- "mediatek,mt2701-scpsys"
+	- "mediatek,mt6797-scpsys"
 	- "mediatek,mt8173-scpsys"
 - #power-domain-cells: Must be 1
 - reg: Address range of the SCPSYS unit
@@ -22,6 +25,7 @@ Required properties:
                       These are clocks which hardware needs to be
                       enabled before enabling certain power domains.
 	Required clocks for MT2701: "mm", "mfg", "ethif"
+	Required clocks for MT6797: "mm", "mfg", "vdec"
 	Required clocks for MT8173: "mm", "mfg", "venc", "venc_lt"
 
 Optional properties:
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 08/10] soc: mediatek: add MT6797 power dt-bindings
@ 2017-02-06 12:15   ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-06 12:15 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: CC Hwang, Loda Chou, Miles Chen, Jades Shih, Yingjoe Chen,
	My Chuang, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, Marc Zyngier, Thomas Gleixner, Will Deacon,
	Stephen Boyd, linux-clk, Chieh-Jay Liu, Mars Cheng,
	Kevin-CW Chen

This adds power dt-bindings for MT6797

Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
Signed-off-by: Kevin-CW Chen <kevin-cw.chen@mediatek.com>
---
 .../devicetree/bindings/soc/mediatek/scpsys.txt    |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
index 16fe94d..b1d165b 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
+++ b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
@@ -9,11 +9,14 @@ domain control.
 
 The driver implements the Generic PM domain bindings described in
 power/power_domain.txt. It provides the power domains defined in
-include/dt-bindings/power/mt8173-power.h and mt2701-power.h.
+- include/dt-bindings/power/mt8173-power.h
+- include/dt-bindings/power/mt6797-power.h
+- include/dt-bindings/power/mt2701-power.h
 
 Required properties:
 - compatible: Should be one of:
 	- "mediatek,mt2701-scpsys"
+	- "mediatek,mt6797-scpsys"
 	- "mediatek,mt8173-scpsys"
 - #power-domain-cells: Must be 1
 - reg: Address range of the SCPSYS unit
@@ -22,6 +25,7 @@ Required properties:
                       These are clocks which hardware needs to be
                       enabled before enabling certain power domains.
 	Required clocks for MT2701: "mm", "mfg", "ethif"
+	Required clocks for MT6797: "mm", "mfg", "vdec"
 	Required clocks for MT8173: "mm", "mfg", "venc", "venc_lt"
 
 Optional properties:
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 09/10] soc: mediatek: add MT6797 scysys support
  2017-02-06 12:15 ` Mars Cheng
@ 2017-02-06 12:15   ` Mars Cheng
  -1 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-06 12:15 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: CC Hwang, Loda Chou, Miles Chen, Jades Shih, Yingjoe Chen,
	My Chuang, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, Marc Zyngier, Thomas Gleixner, Will Deacon,
	Stephen Boyd, linux-clk, Chieh-Jay Liu, Mars Cheng,
	Kevin-CW Chen

This adds scysys support for MT6797

Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
Signed-off-by: Kevin-CW Chen <kevin-cw.chen@mediatek.com>
---
 drivers/soc/mediatek/mtk-scpsys.c        |  114 ++++++++++++++++++++++++++++++
 include/dt-bindings/power/mt6797-power.h |   30 ++++++++
 2 files changed, 144 insertions(+)
 create mode 100644 include/dt-bindings/power/mt6797-power.h

diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
index a8ba800..fc7bf95 100644
--- a/drivers/soc/mediatek/mtk-scpsys.c
+++ b/drivers/soc/mediatek/mtk-scpsys.c
@@ -21,6 +21,7 @@
 #include <linux/soc/mediatek/infracfg.h>
 
 #include <dt-bindings/power/mt2701-power.h>
+#include <dt-bindings/power/mt6797-power.h>
 #include <dt-bindings/power/mt8173-power.h>
 
 #define SPM_VDE_PWR_CON			0x0210
@@ -585,6 +586,116 @@ static int __init scpsys_probe_mt2701(struct platform_device *pdev)
 }
 
 /*
+ * MT6797 power domain support
+ */
+
+static const struct scp_domain_data scp_domain_data_mt6797[] = {
+	[MT6797_POWER_DOMAIN_VDEC] = {
+		.name = "vdec",
+		.sta_mask = BIT(7),
+		.ctl_offs = 0x300,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.clk_id = {CLK_VDEC},
+	},
+	[MT6797_POWER_DOMAIN_VENC] = {
+		.name = "venc",
+		.sta_mask = BIT(21),
+		.ctl_offs = 0x304,
+		.sram_pdn_bits = GENMASK(11, 8),
+		.sram_pdn_ack_bits = GENMASK(15, 12),
+		.clk_id = {CLK_NONE},
+	},
+	[MT6797_POWER_DOMAIN_ISP] = {
+		.name = "isp",
+		.sta_mask = BIT(5),
+		.ctl_offs = 0x308,
+		.sram_pdn_bits = GENMASK(9, 8),
+		.sram_pdn_ack_bits = GENMASK(13, 12),
+		.clk_id = {CLK_NONE},
+	},
+	[MT6797_POWER_DOMAIN_MM] = {
+		.name = "mm",
+		.sta_mask = BIT(3),
+		.ctl_offs = 0x30C,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.clk_id = {CLK_MM},
+		.bus_prot_mask = (BIT(1) | BIT(2)),
+	},
+	[MT6797_POWER_DOMAIN_AUDIO] = {
+		.name = "audio",
+		.sta_mask = BIT(24),
+		.ctl_offs = 0x314,
+		.sram_pdn_bits = GENMASK(11, 8),
+		.sram_pdn_ack_bits = GENMASK(15, 12),
+		.clk_id = {CLK_NONE},
+	},
+	[MT6797_POWER_DOMAIN_MFG_ASYNC] = {
+		.name = "mfg_async",
+		.sta_mask = BIT(13),
+		.ctl_offs = 0x334,
+		.sram_pdn_bits = 0,
+		.sram_pdn_ack_bits = 0,
+		.clk_id = {CLK_MFG},
+	},
+	[MT6797_POWER_DOMAIN_MJC] = {
+		.name = "mjc",
+		.sta_mask = BIT(20),
+		.ctl_offs = 0x310,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.clk_id = {CLK_NONE},
+	},
+};
+
+#define NUM_DOMAINS_MT6797	ARRAY_SIZE(scp_domain_data_mt6797)
+#define SPM_PWR_STATUS_MT6797		0x0180
+#define SPM_PWR_STATUS_2ND_MT6797	0x0184
+
+static int __init scpsys_probe_mt6797(struct platform_device *pdev)
+{
+	struct scp *scp;
+	struct genpd_onecell_data *pd_data;
+	int ret;
+	struct scp_ctrl_reg scp_reg;
+
+	scp_reg.pwr_sta_offs = SPM_PWR_STATUS_MT6797;
+	scp_reg.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797;
+
+	scp = init_scp(pdev, scp_domain_data_mt6797, NUM_DOMAINS_MT6797,
+		       &scp_reg);
+	if (IS_ERR(scp))
+		return PTR_ERR(scp);
+
+	mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT6797);
+
+	pd_data = &scp->pd_data;
+
+	ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM],
+				pd_data->domains[MT6797_POWER_DOMAIN_VDEC]);
+	if (ret && IS_ENABLED(CONFIG_PM))
+		dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
+
+	ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM],
+				pd_data->domains[MT6797_POWER_DOMAIN_ISP]);
+	if (ret && IS_ENABLED(CONFIG_PM))
+		dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
+
+	ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM],
+				pd_data->domains[MT6797_POWER_DOMAIN_VENC]);
+	if (ret && IS_ENABLED(CONFIG_PM))
+		dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
+
+	ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM],
+		pd_data->domains[MT6797_POWER_DOMAIN_MJC]);
+	if (ret && IS_ENABLED(CONFIG_PM))
+		dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
+
+	return 0;
+}
+
+/*
  * MT8173 power domain support
  */
 
@@ -721,6 +832,9 @@ static int __init scpsys_probe_mt8173(struct platform_device *pdev)
 		.compatible = "mediatek,mt2701-scpsys",
 		.data = scpsys_probe_mt2701,
 	}, {
+		.compatible = "mediatek,mt6797-scpsys",
+		.data = scpsys_probe_mt6797,
+	}, {
 		.compatible = "mediatek,mt8173-scpsys",
 		.data = scpsys_probe_mt8173,
 	}, {
diff --git a/include/dt-bindings/power/mt6797-power.h b/include/dt-bindings/power/mt6797-power.h
new file mode 100644
index 0000000..d54b377
--- /dev/null
+++ b/include/dt-bindings/power/mt6797-power.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Mars.C <mars.cheng@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,
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _DT_BINDINGS_POWER_MT6797_POWER_H
+#define _DT_BINDINGS_POWER_MT6797_POWER_H
+
+#define MT6797_POWER_DOMAIN_VDEC		0
+#define MT6797_POWER_DOMAIN_VENC		1
+#define MT6797_POWER_DOMAIN_ISP		2
+#define MT6797_POWER_DOMAIN_MM			3
+#define MT6797_POWER_DOMAIN_AUDIO		4
+#define MT6797_POWER_DOMAIN_MFG_ASYNC		5
+#define MT6797_POWER_DOMAIN_MFG		6
+#define MT6797_POWER_DOMAIN_MFG_CORE0		7
+#define MT6797_POWER_DOMAIN_MFG_CORE1		8
+#define MT6797_POWER_DOMAIN_MFG_CORE2		9
+#define MT6797_POWER_DOMAIN_MFG_CORE3		10
+#define MT6797_POWER_DOMAIN_MJC		11
+
+#endif /* _DT_BINDINGS_POWER_MT6797_POWER_H */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 09/10] soc: mediatek: add MT6797 scysys support
@ 2017-02-06 12:15   ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-06 12:15 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: CC Hwang, Loda Chou, Miles Chen, Jades Shih, Yingjoe Chen,
	My Chuang, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, Marc Zyngier, Thomas Gleixner, Will Deacon,
	Stephen Boyd, linux-clk, Chieh-Jay Liu, Mars Cheng,
	Kevin-CW Chen

This adds scysys support for MT6797

Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
Signed-off-by: Kevin-CW Chen <kevin-cw.chen@mediatek.com>
---
 drivers/soc/mediatek/mtk-scpsys.c        |  114 ++++++++++++++++++++++++++++++
 include/dt-bindings/power/mt6797-power.h |   30 ++++++++
 2 files changed, 144 insertions(+)
 create mode 100644 include/dt-bindings/power/mt6797-power.h

diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
index a8ba800..fc7bf95 100644
--- a/drivers/soc/mediatek/mtk-scpsys.c
+++ b/drivers/soc/mediatek/mtk-scpsys.c
@@ -21,6 +21,7 @@
 #include <linux/soc/mediatek/infracfg.h>
 
 #include <dt-bindings/power/mt2701-power.h>
+#include <dt-bindings/power/mt6797-power.h>
 #include <dt-bindings/power/mt8173-power.h>
 
 #define SPM_VDE_PWR_CON			0x0210
@@ -585,6 +586,116 @@ static int __init scpsys_probe_mt2701(struct platform_device *pdev)
 }
 
 /*
+ * MT6797 power domain support
+ */
+
+static const struct scp_domain_data scp_domain_data_mt6797[] = {
+	[MT6797_POWER_DOMAIN_VDEC] = {
+		.name = "vdec",
+		.sta_mask = BIT(7),
+		.ctl_offs = 0x300,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.clk_id = {CLK_VDEC},
+	},
+	[MT6797_POWER_DOMAIN_VENC] = {
+		.name = "venc",
+		.sta_mask = BIT(21),
+		.ctl_offs = 0x304,
+		.sram_pdn_bits = GENMASK(11, 8),
+		.sram_pdn_ack_bits = GENMASK(15, 12),
+		.clk_id = {CLK_NONE},
+	},
+	[MT6797_POWER_DOMAIN_ISP] = {
+		.name = "isp",
+		.sta_mask = BIT(5),
+		.ctl_offs = 0x308,
+		.sram_pdn_bits = GENMASK(9, 8),
+		.sram_pdn_ack_bits = GENMASK(13, 12),
+		.clk_id = {CLK_NONE},
+	},
+	[MT6797_POWER_DOMAIN_MM] = {
+		.name = "mm",
+		.sta_mask = BIT(3),
+		.ctl_offs = 0x30C,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.clk_id = {CLK_MM},
+		.bus_prot_mask = (BIT(1) | BIT(2)),
+	},
+	[MT6797_POWER_DOMAIN_AUDIO] = {
+		.name = "audio",
+		.sta_mask = BIT(24),
+		.ctl_offs = 0x314,
+		.sram_pdn_bits = GENMASK(11, 8),
+		.sram_pdn_ack_bits = GENMASK(15, 12),
+		.clk_id = {CLK_NONE},
+	},
+	[MT6797_POWER_DOMAIN_MFG_ASYNC] = {
+		.name = "mfg_async",
+		.sta_mask = BIT(13),
+		.ctl_offs = 0x334,
+		.sram_pdn_bits = 0,
+		.sram_pdn_ack_bits = 0,
+		.clk_id = {CLK_MFG},
+	},
+	[MT6797_POWER_DOMAIN_MJC] = {
+		.name = "mjc",
+		.sta_mask = BIT(20),
+		.ctl_offs = 0x310,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.clk_id = {CLK_NONE},
+	},
+};
+
+#define NUM_DOMAINS_MT6797	ARRAY_SIZE(scp_domain_data_mt6797)
+#define SPM_PWR_STATUS_MT6797		0x0180
+#define SPM_PWR_STATUS_2ND_MT6797	0x0184
+
+static int __init scpsys_probe_mt6797(struct platform_device *pdev)
+{
+	struct scp *scp;
+	struct genpd_onecell_data *pd_data;
+	int ret;
+	struct scp_ctrl_reg scp_reg;
+
+	scp_reg.pwr_sta_offs = SPM_PWR_STATUS_MT6797;
+	scp_reg.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797;
+
+	scp = init_scp(pdev, scp_domain_data_mt6797, NUM_DOMAINS_MT6797,
+		       &scp_reg);
+	if (IS_ERR(scp))
+		return PTR_ERR(scp);
+
+	mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT6797);
+
+	pd_data = &scp->pd_data;
+
+	ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM],
+				pd_data->domains[MT6797_POWER_DOMAIN_VDEC]);
+	if (ret && IS_ENABLED(CONFIG_PM))
+		dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
+
+	ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM],
+				pd_data->domains[MT6797_POWER_DOMAIN_ISP]);
+	if (ret && IS_ENABLED(CONFIG_PM))
+		dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
+
+	ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM],
+				pd_data->domains[MT6797_POWER_DOMAIN_VENC]);
+	if (ret && IS_ENABLED(CONFIG_PM))
+		dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
+
+	ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM],
+		pd_data->domains[MT6797_POWER_DOMAIN_MJC]);
+	if (ret && IS_ENABLED(CONFIG_PM))
+		dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
+
+	return 0;
+}
+
+/*
  * MT8173 power domain support
  */
 
@@ -721,6 +832,9 @@ static int __init scpsys_probe_mt8173(struct platform_device *pdev)
 		.compatible = "mediatek,mt2701-scpsys",
 		.data = scpsys_probe_mt2701,
 	}, {
+		.compatible = "mediatek,mt6797-scpsys",
+		.data = scpsys_probe_mt6797,
+	}, {
 		.compatible = "mediatek,mt8173-scpsys",
 		.data = scpsys_probe_mt8173,
 	}, {
diff --git a/include/dt-bindings/power/mt6797-power.h b/include/dt-bindings/power/mt6797-power.h
new file mode 100644
index 0000000..d54b377
--- /dev/null
+++ b/include/dt-bindings/power/mt6797-power.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Mars.C <mars.cheng@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,
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _DT_BINDINGS_POWER_MT6797_POWER_H
+#define _DT_BINDINGS_POWER_MT6797_POWER_H
+
+#define MT6797_POWER_DOMAIN_VDEC		0
+#define MT6797_POWER_DOMAIN_VENC		1
+#define MT6797_POWER_DOMAIN_ISP		2
+#define MT6797_POWER_DOMAIN_MM			3
+#define MT6797_POWER_DOMAIN_AUDIO		4
+#define MT6797_POWER_DOMAIN_MFG_ASYNC		5
+#define MT6797_POWER_DOMAIN_MFG		6
+#define MT6797_POWER_DOMAIN_MFG_CORE0		7
+#define MT6797_POWER_DOMAIN_MFG_CORE1		8
+#define MT6797_POWER_DOMAIN_MFG_CORE2		9
+#define MT6797_POWER_DOMAIN_MFG_CORE3		10
+#define MT6797_POWER_DOMAIN_MJC		11
+
+#endif /* _DT_BINDINGS_POWER_MT6797_POWER_H */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 10/10] arm64: dts: mediatek: add clk nodes for MT6797
@ 2017-02-06 12:15   ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-06 12:15 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: CC Hwang, Loda Chou, Miles Chen, Jades Shih, Yingjoe Chen,
	My Chuang, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, Marc Zyngier, Thomas Gleixner, Will Deacon,
	Stephen Boyd, linux-clk, Chieh-Jay Liu, Mars Cheng,
	Kevin-CW Chen

This adds clk nodes for MT6797

Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
Signed-off-by: Kevin-CW Chen <kevin-cw.chen@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt6797.dtsi |   71 ++++++++++++++++++++++++++++--
 1 file changed, 67 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt6797.dtsi b/arch/arm64/boot/dts/mediatek/mt6797.dtsi
index da3a6ff..eca2376 100644
--- a/arch/arm64/boot/dts/mediatek/mt6797.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt6797.dtsi
@@ -11,6 +11,8 @@
  * GNU General Public License for more details.
  */
 
+#include <dt-bindings/clock/mt6797-clk.h>
+#include <dt-bindings/power/mt6797-power.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 
@@ -127,6 +129,35 @@
 			     (GIC_CPU_MASK_SIMPLE(10) | IRQ_TYPE_LEVEL_LOW)>;
 	};
 
+	topckgen: topckgen@10000000 {
+		compatible = "mediatek,mt6797-topckgen";
+		reg = <0 0x10000000 0 0x1000>;
+		#clock-cells = <1>;
+	};
+
+	infrasys: infracfg_ao@10001000 {
+		compatible = "mediatek,mt6797-infracfg", "syscon";
+		reg = <0 0x10001000 0 0x1000>;
+		#clock-cells = <1>;
+	};
+
+	scpsys: scpsys@10006000 {
+		compatible = "mediatek,mt6797-scpsys";
+		#power-domain-cells = <1>;
+		reg = <0 0x10006000 0 0x1000>;
+		clocks = <&topckgen CLK_TOP_MUX_MFG>,
+			 <&topckgen CLK_TOP_MUX_MM>,
+			 <&topckgen CLK_TOP_MUX_VDEC>;
+		clock-names = "mfg", "mm", "vdec";
+		infracfg = <&infrasys>;
+	};
+
+	apmixedsys: apmixed@1000c000 {
+		compatible = "mediatek,mt6797-apmixedsys";
+		reg = <0 0x1000c000 0 0x1000>;
+		#clock-cells = <1>;
+	};
+
 	sysirq: intpol-controller@10200620 {
 		compatible = "mediatek,mt6797-sysirq",
 			     "mediatek,mt6577-sysirq";
@@ -143,7 +174,9 @@
 			     "mediatek,mt6577-uart";
 		reg = <0 0x11002000 0 0x400>;
 		interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>;
-		clocks = <&clk26m>;
+		clocks = <&infrasys CLK_INFRA_UART0>,
+			 <&infrasys CLK_INFRA_AP_DMA>;
+		clock-names = "baud", "bus";
 		status = "disabled";
 	};
 
@@ -152,7 +185,9 @@
 			     "mediatek,mt6577-uart";
 		reg = <0 0x11003000 0 0x400>;
 		interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_LOW>;
-		clocks = <&clk26m>;
+		clocks = <&infrasys CLK_INFRA_UART1>,
+			 <&infrasys CLK_INFRA_AP_DMA>;
+		clock-names = "baud", "bus";
 		status = "disabled";
 	};
 
@@ -161,7 +196,9 @@
 			     "mediatek,mt6577-uart";
 		reg = <0 0x11004000 0 0x400>;
 		interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_LOW>;
-		clocks = <&clk26m>;
+		clocks = <&infrasys CLK_INFRA_UART2>,
+			 <&infrasys CLK_INFRA_AP_DMA>;
+		clock-names = "baud", "bus";
 		status = "disabled";
 	};
 
@@ -170,10 +207,36 @@
 			     "mediatek,mt6577-uart";
 		reg = <0 0x11005000 0 0x400>;
 		interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_LOW>;
-		clocks = <&clk26m>;
+		clocks = <&infrasys CLK_INFRA_UART3>,
+			 <&infrasys CLK_INFRA_AP_DMA>;
+		clock-names = "baud", "bus";
 		status = "disabled";
 	};
 
+	mmsys: mmsys_config@14000000 {
+		compatible = "mediatek,mt6797-mmsys", "syscon";
+		reg = <0 0x14000000 0 0x1000>;
+		#clock-cells = <1>;
+	};
+
+	imgsys: imgsys_config@15000000  {
+		compatible = "mediatek,mt6797-imgsys", "syscon";
+		reg = <0 0x15000000 0 0x1000>;
+		#clock-cells = <1>;
+	};
+
+	vdecsys: vdec_gcon@16000000 {
+		compatible = "mediatek,mt6797-vdecsys", "syscon";
+		reg = <0 0x16000000 0 0x10000>;
+		#clock-cells = <1>;
+	};
+
+	vencsys: venc_gcon@17000000 {
+		compatible = "mediatek,mt6797-vencsys", "syscon";
+		reg = <0 0x17000000 0 0x1000>;
+		#clock-cells = <1>;
+	};
+
 	gic: interrupt-controller@19000000 {
 		compatible = "arm,gic-v3";
 		#interrupt-cells = <3>;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 10/10] arm64: dts: mediatek: add clk nodes for MT6797
@ 2017-02-06 12:15   ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-06 12:15 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, CC Hwang,
	wsd_upstream-NuS5LvNUpcJWk0Htik3J/w, Marc Zyngier, Will Deacon,
	Mars Cheng, Loda Chou, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	Jades Shih, linux-clk-u79uwXL29TY76Z2rM5mHXA, Miles Chen,
	Kevin-CW Chen, linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	My Chuang, Yingjoe Chen, Thomas Gleixner, Stephen Boyd,
	Chieh-Jay Liu

This adds clk nodes for MT6797

Signed-off-by: Mars Cheng <mars.cheng-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
Signed-off-by: Kevin-CW Chen <kevin-cw.chen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
---
 arch/arm64/boot/dts/mediatek/mt6797.dtsi |   71 ++++++++++++++++++++++++++++--
 1 file changed, 67 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt6797.dtsi b/arch/arm64/boot/dts/mediatek/mt6797.dtsi
index da3a6ff..eca2376 100644
--- a/arch/arm64/boot/dts/mediatek/mt6797.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt6797.dtsi
@@ -11,6 +11,8 @@
  * GNU General Public License for more details.
  */
 
+#include <dt-bindings/clock/mt6797-clk.h>
+#include <dt-bindings/power/mt6797-power.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 
@@ -127,6 +129,35 @@
 			     (GIC_CPU_MASK_SIMPLE(10) | IRQ_TYPE_LEVEL_LOW)>;
 	};
 
+	topckgen: topckgen@10000000 {
+		compatible = "mediatek,mt6797-topckgen";
+		reg = <0 0x10000000 0 0x1000>;
+		#clock-cells = <1>;
+	};
+
+	infrasys: infracfg_ao@10001000 {
+		compatible = "mediatek,mt6797-infracfg", "syscon";
+		reg = <0 0x10001000 0 0x1000>;
+		#clock-cells = <1>;
+	};
+
+	scpsys: scpsys@10006000 {
+		compatible = "mediatek,mt6797-scpsys";
+		#power-domain-cells = <1>;
+		reg = <0 0x10006000 0 0x1000>;
+		clocks = <&topckgen CLK_TOP_MUX_MFG>,
+			 <&topckgen CLK_TOP_MUX_MM>,
+			 <&topckgen CLK_TOP_MUX_VDEC>;
+		clock-names = "mfg", "mm", "vdec";
+		infracfg = <&infrasys>;
+	};
+
+	apmixedsys: apmixed@1000c000 {
+		compatible = "mediatek,mt6797-apmixedsys";
+		reg = <0 0x1000c000 0 0x1000>;
+		#clock-cells = <1>;
+	};
+
 	sysirq: intpol-controller@10200620 {
 		compatible = "mediatek,mt6797-sysirq",
 			     "mediatek,mt6577-sysirq";
@@ -143,7 +174,9 @@
 			     "mediatek,mt6577-uart";
 		reg = <0 0x11002000 0 0x400>;
 		interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>;
-		clocks = <&clk26m>;
+		clocks = <&infrasys CLK_INFRA_UART0>,
+			 <&infrasys CLK_INFRA_AP_DMA>;
+		clock-names = "baud", "bus";
 		status = "disabled";
 	};
 
@@ -152,7 +185,9 @@
 			     "mediatek,mt6577-uart";
 		reg = <0 0x11003000 0 0x400>;
 		interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_LOW>;
-		clocks = <&clk26m>;
+		clocks = <&infrasys CLK_INFRA_UART1>,
+			 <&infrasys CLK_INFRA_AP_DMA>;
+		clock-names = "baud", "bus";
 		status = "disabled";
 	};
 
@@ -161,7 +196,9 @@
 			     "mediatek,mt6577-uart";
 		reg = <0 0x11004000 0 0x400>;
 		interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_LOW>;
-		clocks = <&clk26m>;
+		clocks = <&infrasys CLK_INFRA_UART2>,
+			 <&infrasys CLK_INFRA_AP_DMA>;
+		clock-names = "baud", "bus";
 		status = "disabled";
 	};
 
@@ -170,10 +207,36 @@
 			     "mediatek,mt6577-uart";
 		reg = <0 0x11005000 0 0x400>;
 		interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_LOW>;
-		clocks = <&clk26m>;
+		clocks = <&infrasys CLK_INFRA_UART3>,
+			 <&infrasys CLK_INFRA_AP_DMA>;
+		clock-names = "baud", "bus";
 		status = "disabled";
 	};
 
+	mmsys: mmsys_config@14000000 {
+		compatible = "mediatek,mt6797-mmsys", "syscon";
+		reg = <0 0x14000000 0 0x1000>;
+		#clock-cells = <1>;
+	};
+
+	imgsys: imgsys_config@15000000  {
+		compatible = "mediatek,mt6797-imgsys", "syscon";
+		reg = <0 0x15000000 0 0x1000>;
+		#clock-cells = <1>;
+	};
+
+	vdecsys: vdec_gcon@16000000 {
+		compatible = "mediatek,mt6797-vdecsys", "syscon";
+		reg = <0 0x16000000 0 0x10000>;
+		#clock-cells = <1>;
+	};
+
+	vencsys: venc_gcon@17000000 {
+		compatible = "mediatek,mt6797-vencsys", "syscon";
+		reg = <0 0x17000000 0 0x1000>;
+		#clock-cells = <1>;
+	};
+
 	gic: interrupt-controller@19000000 {
 		compatible = "arm,gic-v3";
 		#interrupt-cells = <3>;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 04/10] arm64: dts: mediatek: add mt6797 support
  2017-02-06 12:15   ` Mars Cheng
  (?)
@ 2017-02-06 12:28   ` Marc Zyngier
  2017-02-06 12:37       ` Mars Cheng
  -1 siblings, 1 reply; 44+ messages in thread
From: Marc Zyngier @ 2017-02-06 12:28 UTC (permalink / raw)
  To: Mars Cheng, Matthias Brugger
  Cc: CC Hwang, Loda Chou, Miles Chen, Jades Shih, Yingjoe Chen,
	My Chuang, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, Thomas Gleixner, Will Deacon, Stephen Boyd,
	linux-clk, Chieh-Jay Liu

On 06/02/17 12:15, Mars Cheng wrote:
> This adds basic chip support for MT6797 SoC.
> 
> Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
> ---
>  arch/arm64/boot/dts/mediatek/Makefile       |    1 +
>  arch/arm64/boot/dts/mediatek/mt6797-evb.dts |   36 ++++++
>  arch/arm64/boot/dts/mediatek/mt6797.dtsi    |  187 +++++++++++++++++++++++++++
>  3 files changed, 224 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/mediatek/mt6797-evb.dts
>  create mode 100644 arch/arm64/boot/dts/mediatek/mt6797.dtsi
> 
> diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
> index 9fbfd32..015eb07 100644
> --- a/arch/arm64/boot/dts/mediatek/Makefile
> +++ b/arch/arm64/boot/dts/mediatek/Makefile
> @@ -1,5 +1,6 @@
>  dtb-$(CONFIG_ARCH_MEDIATEK) += mt6755-evb.dtb
>  dtb-$(CONFIG_ARCH_MEDIATEK) += mt6795-evb.dtb
> +dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-evb.dtb
>  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-evb.dtb
>  
>  always		:= $(dtb-y)
> diff --git a/arch/arm64/boot/dts/mediatek/mt6797-evb.dts b/arch/arm64/boot/dts/mediatek/mt6797-evb.dts
> new file mode 100644
> index 0000000..c79109c
> --- /dev/null
> +++ b/arch/arm64/boot/dts/mediatek/mt6797-evb.dts

[...]

> +	timer {
> +		compatible = "arm,armv8-timer";
> +		interrupt-parent = <&gic>;
> +		interrupts = <GIC_PPI 13
> +			     (GIC_CPU_MASK_SIMPLE(10) | IRQ_TYPE_LEVEL_LOW)>,

That's exactly why I positively hate these GIC_CPU_MASK_SIMPLE() and co.
They just hide all kind of sins:
- With GICv1/v2, this field can only be 8bit wide. Good luck shoving 10
CPUs there.
- GICv3 *doesn't* have any affinity bitmap in the binding (it can be
expressed in a very different way).

So please get rid of this GIC_CPU_MASK_SIMPLE, it is just wrong.

> +			     <GIC_PPI 14
> +			     (GIC_CPU_MASK_SIMPLE(10) | IRQ_TYPE_LEVEL_LOW)>,
> +			     <GIC_PPI 11
> +			     (GIC_CPU_MASK_SIMPLE(10) | IRQ_TYPE_LEVEL_LOW)>,
> +			     <GIC_PPI 10
> +			     (GIC_CPU_MASK_SIMPLE(10) | IRQ_TYPE_LEVEL_LOW)>;
> +	};
> +
> +	sysirq: intpol-controller@10200620 {
> +		compatible = "mediatek,mt6797-sysirq",
> +			     "mediatek,mt6577-sysirq";
> +		interrupt-controller;
> +		#interrupt-cells = <3>;
> +		#intpol-bases = <2>;
> +		interrupt-parent = <&gic>;
> +		reg = <0 0x10220620 0 0x20>,
> +		      <0 0x10220690 0 0x10>;
> +	};
> +
> +	uart0: serial@11002000 {
> +		compatible = "mediatek,mt6797-uart",
> +			     "mediatek,mt6577-uart";
> +		reg = <0 0x11002000 0 0x400>;
> +		interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>;
> +		clocks = <&clk26m>;
> +		status = "disabled";
> +	};
> +
> +	uart1: serial@11003000 {
> +		compatible = "mediatek,mt6797-uart",
> +			     "mediatek,mt6577-uart";
> +		reg = <0 0x11003000 0 0x400>;
> +		interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_LOW>;
> +		clocks = <&clk26m>;
> +		status = "disabled";
> +	};
> +
> +	uart2: serial@11004000 {
> +		compatible = "mediatek,mt6797-uart",
> +			     "mediatek,mt6577-uart";
> +		reg = <0 0x11004000 0 0x400>;
> +		interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_LOW>;
> +		clocks = <&clk26m>;
> +		status = "disabled";
> +	};
> +
> +	uart3: serial@11005000 {
> +		compatible = "mediatek,mt6797-uart",
> +			     "mediatek,mt6577-uart";
> +		reg = <0 0x11005000 0 0x400>;
> +		interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_LOW>;
> +		clocks = <&clk26m>;
> +		status = "disabled";
> +	};
> +
> +	gic: interrupt-controller@19000000 {
> +		compatible = "arm,gic-v3";
> +		#interrupt-cells = <3>;
> +		interrupt-parent = <&gic>;
> +		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
> +		interrupt-controller;
> +		reg = <0 0x19000000 0 0x10000>,    /* GICD */
> +		      <0 0x19200000 0 0x200000>,   /* GICR */
> +		      <0 0x10240000 0 0x2000>;     /* GICC */

No GICH, no GICV, no ITS?

> +	};
> +};
> 

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 04/10] arm64: dts: mediatek: add mt6797 support
  2017-02-06 12:28   ` Marc Zyngier
@ 2017-02-06 12:37       ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-06 12:37 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Matthias Brugger, CC Hwang, Loda Chou, Miles Chen, Jades Shih,
	Yingjoe Chen, My Chuang, linux-kernel, linux-mediatek,
	devicetree, wsd_upstream, Thomas Gleixner, Will Deacon,
	Stephen Boyd, linux-clk, Chieh-Jay Liu

On Mon, 2017-02-06 at 12:28 +0000, Marc Zyngier wrote:
> On 06/02/17 12:15, Mars Cheng wrote:
> > This adds basic chip support for MT6797 SoC.
> > 
> > Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
> > ---
> >  arch/arm64/boot/dts/mediatek/Makefile       |    1 +
> >  arch/arm64/boot/dts/mediatek/mt6797-evb.dts |   36 ++++++
> >  arch/arm64/boot/dts/mediatek/mt6797.dtsi    |  187 +++++++++++++++++++++++++++
> >  3 files changed, 224 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/mediatek/mt6797-evb.dts
> >  create mode 100644 arch/arm64/boot/dts/mediatek/mt6797.dtsi
> > 
> > diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
> > index 9fbfd32..015eb07 100644
> > --- a/arch/arm64/boot/dts/mediatek/Makefile
> > +++ b/arch/arm64/boot/dts/mediatek/Makefile
> > @@ -1,5 +1,6 @@
> >  dtb-$(CONFIG_ARCH_MEDIATEK) += mt6755-evb.dtb
> >  dtb-$(CONFIG_ARCH_MEDIATEK) += mt6795-evb.dtb
> > +dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-evb.dtb
> >  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-evb.dtb
> >  
> >  always		:= $(dtb-y)
> > diff --git a/arch/arm64/boot/dts/mediatek/mt6797-evb.dts b/arch/arm64/boot/dts/mediatek/mt6797-evb.dts
> > new file mode 100644
> > index 0000000..c79109c
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/mediatek/mt6797-evb.dts
> 
> [...]
> 
> > +	timer {
> > +		compatible = "arm,armv8-timer";
> > +		interrupt-parent = <&gic>;
> > +		interrupts = <GIC_PPI 13
> > +			     (GIC_CPU_MASK_SIMPLE(10) | IRQ_TYPE_LEVEL_LOW)>,
> 
> That's exactly why I positively hate these GIC_CPU_MASK_SIMPLE() and co.
> They just hide all kind of sins:
> - With GICv1/v2, this field can only be 8bit wide. Good luck shoving 10
> CPUs there.
> - GICv3 *doesn't* have any affinity bitmap in the binding (it can be
> expressed in a very different way).

> So please get rid of this GIC_CPU_MASK_SIMPLE, it is just wrong.
> 

Got it. Will remove these.

> > +			     <GIC_PPI 14
> > +			     (GIC_CPU_MASK_SIMPLE(10) | IRQ_TYPE_LEVEL_LOW)>,
> > +			     <GIC_PPI 11
> > +			     (GIC_CPU_MASK_SIMPLE(10) | IRQ_TYPE_LEVEL_LOW)>,
> > +			     <GIC_PPI 10
> > +			     (GIC_CPU_MASK_SIMPLE(10) | IRQ_TYPE_LEVEL_LOW)>;
> > +	};
> > +
> > +	sysirq: intpol-controller@10200620 {
> > +		compatible = "mediatek,mt6797-sysirq",
> > +			     "mediatek,mt6577-sysirq";
> > +		interrupt-controller;
> > +		#interrupt-cells = <3>;
> > +		#intpol-bases = <2>;
> > +		interrupt-parent = <&gic>;
> > +		reg = <0 0x10220620 0 0x20>,
> > +		      <0 0x10220690 0 0x10>;
> > +	};
> > +
> > +	uart0: serial@11002000 {
> > +		compatible = "mediatek,mt6797-uart",
> > +			     "mediatek,mt6577-uart";
> > +		reg = <0 0x11002000 0 0x400>;
> > +		interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>;
> > +		clocks = <&clk26m>;
> > +		status = "disabled";
> > +	};
> > +
> > +	uart1: serial@11003000 {
> > +		compatible = "mediatek,mt6797-uart",
> > +			     "mediatek,mt6577-uart";
> > +		reg = <0 0x11003000 0 0x400>;
> > +		interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_LOW>;
> > +		clocks = <&clk26m>;
> > +		status = "disabled";
> > +	};
> > +
> > +	uart2: serial@11004000 {
> > +		compatible = "mediatek,mt6797-uart",
> > +			     "mediatek,mt6577-uart";
> > +		reg = <0 0x11004000 0 0x400>;
> > +		interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_LOW>;
> > +		clocks = <&clk26m>;
> > +		status = "disabled";
> > +	};
> > +
> > +	uart3: serial@11005000 {
> > +		compatible = "mediatek,mt6797-uart",
> > +			     "mediatek,mt6577-uart";
> > +		reg = <0 0x11005000 0 0x400>;
> > +		interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_LOW>;
> > +		clocks = <&clk26m>;
> > +		status = "disabled";
> > +	};
> > +
> > +	gic: interrupt-controller@19000000 {
> > +		compatible = "arm,gic-v3";
> > +		#interrupt-cells = <3>;
> > +		interrupt-parent = <&gic>;
> > +		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
> > +		interrupt-controller;
> > +		reg = <0 0x19000000 0 0x10000>,    /* GICD */
> > +		      <0 0x19200000 0 0x200000>,   /* GICR */
> > +		      <0 0x10240000 0 0x2000>;     /* GICC */
> 
> No GICH, no GICV, no ITS?

Have confirmed with our HW guys, no GICH, GICV, ITS. :-)

> 
> > +	};
> > +};
> > 
> 
> Thanks,
> 
> 	M.

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 04/10] arm64: dts: mediatek: add mt6797 support
@ 2017-02-06 12:37       ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-06 12:37 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Matthias Brugger, CC Hwang, Loda Chou, Miles Chen, Jades Shih,
	Yingjoe Chen, My Chuang, linux-kernel, linux-mediatek,
	devicetree, wsd_upstream, Thomas Gleixner, Will Deacon,
	Stephen Boyd, linux-clk, Chieh-Jay Liu

On Mon, 2017-02-06 at 12:28 +0000, Marc Zyngier wrote:
> On 06/02/17 12:15, Mars Cheng wrote:
> > This adds basic chip support for MT6797 SoC.
> > 
> > Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
> > ---
> >  arch/arm64/boot/dts/mediatek/Makefile       |    1 +
> >  arch/arm64/boot/dts/mediatek/mt6797-evb.dts |   36 ++++++
> >  arch/arm64/boot/dts/mediatek/mt6797.dtsi    |  187 +++++++++++++++++++++++++++
> >  3 files changed, 224 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/mediatek/mt6797-evb.dts
> >  create mode 100644 arch/arm64/boot/dts/mediatek/mt6797.dtsi
> > 
> > diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
> > index 9fbfd32..015eb07 100644
> > --- a/arch/arm64/boot/dts/mediatek/Makefile
> > +++ b/arch/arm64/boot/dts/mediatek/Makefile
> > @@ -1,5 +1,6 @@
> >  dtb-$(CONFIG_ARCH_MEDIATEK) += mt6755-evb.dtb
> >  dtb-$(CONFIG_ARCH_MEDIATEK) += mt6795-evb.dtb
> > +dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-evb.dtb
> >  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-evb.dtb
> >  
> >  always		:= $(dtb-y)
> > diff --git a/arch/arm64/boot/dts/mediatek/mt6797-evb.dts b/arch/arm64/boot/dts/mediatek/mt6797-evb.dts
> > new file mode 100644
> > index 0000000..c79109c
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/mediatek/mt6797-evb.dts
> 
> [...]
> 
> > +	timer {
> > +		compatible = "arm,armv8-timer";
> > +		interrupt-parent = <&gic>;
> > +		interrupts = <GIC_PPI 13
> > +			     (GIC_CPU_MASK_SIMPLE(10) | IRQ_TYPE_LEVEL_LOW)>,
> 
> That's exactly why I positively hate these GIC_CPU_MASK_SIMPLE() and co.
> They just hide all kind of sins:
> - With GICv1/v2, this field can only be 8bit wide. Good luck shoving 10
> CPUs there.
> - GICv3 *doesn't* have any affinity bitmap in the binding (it can be
> expressed in a very different way).

> So please get rid of this GIC_CPU_MASK_SIMPLE, it is just wrong.
> 

Got it. Will remove these.

> > +			     <GIC_PPI 14
> > +			     (GIC_CPU_MASK_SIMPLE(10) | IRQ_TYPE_LEVEL_LOW)>,
> > +			     <GIC_PPI 11
> > +			     (GIC_CPU_MASK_SIMPLE(10) | IRQ_TYPE_LEVEL_LOW)>,
> > +			     <GIC_PPI 10
> > +			     (GIC_CPU_MASK_SIMPLE(10) | IRQ_TYPE_LEVEL_LOW)>;
> > +	};
> > +
> > +	sysirq: intpol-controller@10200620 {
> > +		compatible = "mediatek,mt6797-sysirq",
> > +			     "mediatek,mt6577-sysirq";
> > +		interrupt-controller;
> > +		#interrupt-cells = <3>;
> > +		#intpol-bases = <2>;
> > +		interrupt-parent = <&gic>;
> > +		reg = <0 0x10220620 0 0x20>,
> > +		      <0 0x10220690 0 0x10>;
> > +	};
> > +
> > +	uart0: serial@11002000 {
> > +		compatible = "mediatek,mt6797-uart",
> > +			     "mediatek,mt6577-uart";
> > +		reg = <0 0x11002000 0 0x400>;
> > +		interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>;
> > +		clocks = <&clk26m>;
> > +		status = "disabled";
> > +	};
> > +
> > +	uart1: serial@11003000 {
> > +		compatible = "mediatek,mt6797-uart",
> > +			     "mediatek,mt6577-uart";
> > +		reg = <0 0x11003000 0 0x400>;
> > +		interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_LOW>;
> > +		clocks = <&clk26m>;
> > +		status = "disabled";
> > +	};
> > +
> > +	uart2: serial@11004000 {
> > +		compatible = "mediatek,mt6797-uart",
> > +			     "mediatek,mt6577-uart";
> > +		reg = <0 0x11004000 0 0x400>;
> > +		interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_LOW>;
> > +		clocks = <&clk26m>;
> > +		status = "disabled";
> > +	};
> > +
> > +	uart3: serial@11005000 {
> > +		compatible = "mediatek,mt6797-uart",
> > +			     "mediatek,mt6577-uart";
> > +		reg = <0 0x11005000 0 0x400>;
> > +		interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_LOW>;
> > +		clocks = <&clk26m>;
> > +		status = "disabled";
> > +	};
> > +
> > +	gic: interrupt-controller@19000000 {
> > +		compatible = "arm,gic-v3";
> > +		#interrupt-cells = <3>;
> > +		interrupt-parent = <&gic>;
> > +		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
> > +		interrupt-controller;
> > +		reg = <0 0x19000000 0 0x10000>,    /* GICD */
> > +		      <0 0x19200000 0 0x200000>,   /* GICR */
> > +		      <0 0x10240000 0 0x2000>;     /* GICC */
> 
> No GICH, no GICV, no ITS?

Have confirmed with our HW guys, no GICH, GICV, ITS. :-)

> 
> > +	};
> > +};
> > 
> 
> Thanks,
> 
> 	M.



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 01/10] Document: DT: mediatek: multiple base address support for sysirq
  2017-02-06 12:15   ` Mars Cheng
  (?)
@ 2017-02-08 23:20   ` Rob Herring
  2017-02-09  1:47       ` Mars Cheng
  -1 siblings, 1 reply; 44+ messages in thread
From: Rob Herring @ 2017-02-08 23:20 UTC (permalink / raw)
  To: Mars Cheng
  Cc: Matthias Brugger, CC Hwang, Loda Chou, Miles Chen, Jades Shih,
	Yingjoe Chen, My Chuang, linux-kernel, linux-mediatek,
	devicetree, wsd_upstream, Marc Zyngier, Thomas Gleixner,
	Will Deacon, Stephen Boyd, linux-clk, Chieh-Jay Liu

On Mon, Feb 06, 2017 at 08:15:27PM +0800, Mars Cheng wrote:
> This describes how to specify multiple base addresses for sysirq
> in mediatek platforms.
> 
> Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
> ---
>  .../interrupt-controller/mediatek,sysirq.txt       |   13 +++++++++----
>  1 file changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt b/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt
> index 9d1d72c..1718454 100644
> --- a/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt
> +++ b/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt
> @@ -18,16 +18,21 @@ Required properties:
>  	"mediatek,mt2701-sysirq"
>  - interrupt-controller : Identifies the node as an interrupt controller
>  - #interrupt-cells : Use the same format as specified by GIC in arm,gic.txt.
> +- #intpol-bases: Indicate how many base addresses to be used, default is 1.

There is no point in this. It can either be implied by the compatible 
string or you just try to get the resource for the 2nd region. (Or in DT 
terms, get the size of reg.)

>  - interrupt-parent: phandle of irq parent for sysirq. The parent must
>    use the same interrupt-cells format as GIC.
>  - reg: Physical base address of the intpol registers and length of memory
> -  mapped region.
> +  mapped region. Could be multiple bases here. Ex: mt6797 needs 2 reg, others
> +  need 1. If not set, the default is 1.
>  
>  Example:
> -	sysirq: interrupt-controller@10200100 {
> -		compatible = "mediatek,mt6589-sysirq", "mediatek,mt6577-sysirq";
> +	sysirq: intpol-controller@10200620 {
> +		compatible = "mediatek,mt6797-sysirq",
> +			     "mediatek,mt6577-sysirq";
>  		interrupt-controller;
>  		#interrupt-cells = <3>;
> +		#intpol-bases = <2>;
>  		interrupt-parent = <&gic>;
> -		reg = <0 0x10200100 0 0x1c>;
> +		reg = <0 0x10220620 0 0x20>,
> +		      <0 0x10220690 0 0x10>;
>  	};
> -- 
> 1.7.9.5
> 
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 03/10] Document: DT: Add bindings for mediatek MT6797 SoC Platform
  2017-02-06 12:15   ` Mars Cheng
  (?)
@ 2017-02-09  0:34   ` Rob Herring
  -1 siblings, 0 replies; 44+ messages in thread
From: Rob Herring @ 2017-02-09  0:34 UTC (permalink / raw)
  To: Mars Cheng
  Cc: Matthias Brugger, CC Hwang, Loda Chou, Miles Chen, Jades Shih,
	Yingjoe Chen, My Chuang, linux-kernel, linux-mediatek,
	devicetree, wsd_upstream, Marc Zyngier, Thomas Gleixner,
	Will Deacon, Stephen Boyd, linux-clk, Chieh-Jay Liu

On Mon, Feb 06, 2017 at 08:15:29PM +0800, Mars Cheng wrote:
> This adds dt-binding documentation for Mediatek MT6797. Only
> include very basic items, gic, uart timer and cpu.

For the subject: 

"dt-bindings: arm: Add Mediatek MT6797 SoC Platform"

Otherwise,

Acked-by: Rob Herring <robh@kernel.org>

> 
> Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
> ---
>  Documentation/devicetree/bindings/arm/mediatek.txt |    4 ++++
>  .../interrupt-controller/mediatek,sysirq.txt       |    1 +
>  .../devicetree/bindings/serial/mtk-uart.txt        |    1 +
>  3 files changed, 6 insertions(+)

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 05/10] dt-bindings: arm: mediatek: document clk bindings for MT6797
@ 2017-02-09  0:35     ` Rob Herring
  0 siblings, 0 replies; 44+ messages in thread
From: Rob Herring @ 2017-02-09  0:35 UTC (permalink / raw)
  To: Mars Cheng
  Cc: Matthias Brugger, CC Hwang, Loda Chou, Miles Chen, Jades Shih,
	Yingjoe Chen, My Chuang, linux-kernel, linux-mediatek,
	devicetree, wsd_upstream, Marc Zyngier, Thomas Gleixner,
	Will Deacon, Stephen Boyd, linux-clk, Chieh-Jay Liu,
	Kevin-CW Chen

On Mon, Feb 06, 2017 at 08:15:31PM +0800, Mars Cheng wrote:
> From: Kevin-CW Chen <kevin-cw.chen@mediatek.com>
> 
> This patch adds the binding documentation for apmixedsys, imgsys,
> infracfg, mmsys, topckgen, vdecsys and vencsys for MT6797.
> 
> Signed-off-by: Kevin-CW Chen <kevin-cw.chen@mediatek.com>
> Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
> ---
>  .../bindings/arm/mediatek/mediatek,apmixedsys.txt  |    1 +
>  .../bindings/arm/mediatek/mediatek,imgsys.txt      |    1 +
>  .../bindings/arm/mediatek/mediatek,infracfg.txt    |    1 +
>  .../bindings/arm/mediatek/mediatek,mmsys.txt       |    1 +
>  .../bindings/arm/mediatek/mediatek,topckgen.txt    |    1 +
>  .../bindings/arm/mediatek/mediatek,vdecsys.txt     |    1 +
>  .../bindings/arm/mediatek/mediatek,vencsys.txt     |    3 ++-
>  7 files changed, 8 insertions(+), 1 deletion(-)

Acked-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 05/10] dt-bindings: arm: mediatek: document clk bindings for MT6797
@ 2017-02-09  0:35     ` Rob Herring
  0 siblings, 0 replies; 44+ messages in thread
From: Rob Herring @ 2017-02-09  0:35 UTC (permalink / raw)
  To: Mars Cheng
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, CC Hwang,
	wsd_upstream-NuS5LvNUpcJWk0Htik3J/w, Marc Zyngier, Will Deacon,
	Loda Chou, linux-kernel-u79uwXL29TY76Z2rM5mHXA, Jades Shih,
	linux-clk-u79uwXL29TY76Z2rM5mHXA, Miles Chen, Kevin-CW Chen,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, My Chuang,
	Matthias Brugger, Yingjoe Chen, Thomas Gleixner, Stephen Boyd,
	Chieh-Jay Liu

On Mon, Feb 06, 2017 at 08:15:31PM +0800, Mars Cheng wrote:
> From: Kevin-CW Chen <kevin-cw.chen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> 
> This patch adds the binding documentation for apmixedsys, imgsys,
> infracfg, mmsys, topckgen, vdecsys and vencsys for MT6797.
> 
> Signed-off-by: Kevin-CW Chen <kevin-cw.chen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> Signed-off-by: Mars Cheng <mars.cheng-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> ---
>  .../bindings/arm/mediatek/mediatek,apmixedsys.txt  |    1 +
>  .../bindings/arm/mediatek/mediatek,imgsys.txt      |    1 +
>  .../bindings/arm/mediatek/mediatek,infracfg.txt    |    1 +
>  .../bindings/arm/mediatek/mediatek,mmsys.txt       |    1 +
>  .../bindings/arm/mediatek/mediatek,topckgen.txt    |    1 +
>  .../bindings/arm/mediatek/mediatek,vdecsys.txt     |    1 +
>  .../bindings/arm/mediatek/mediatek,vencsys.txt     |    3 ++-
>  7 files changed, 8 insertions(+), 1 deletion(-)

Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 08/10] soc: mediatek: add MT6797 power dt-bindings
  2017-02-06 12:15   ` Mars Cheng
  (?)
@ 2017-02-09  0:37   ` Rob Herring
  2017-02-09  1:32       ` Mars Cheng
  -1 siblings, 1 reply; 44+ messages in thread
From: Rob Herring @ 2017-02-09  0:37 UTC (permalink / raw)
  To: Mars Cheng
  Cc: Matthias Brugger, CC Hwang, Loda Chou, Miles Chen, Jades Shih,
	Yingjoe Chen, My Chuang, linux-kernel, linux-mediatek,
	devicetree, wsd_upstream, Marc Zyngier, Thomas Gleixner,
	Will Deacon, Stephen Boyd, linux-clk, Chieh-Jay Liu,
	Kevin-CW Chen

On Mon, Feb 06, 2017 at 08:15:34PM +0800, Mars Cheng wrote:
> This adds power dt-bindings for MT6797

Some consistency in the subject for bindings please.

> 
> Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
> Signed-off-by: Kevin-CW Chen <kevin-cw.chen@mediatek.com>
> ---
>  .../devicetree/bindings/soc/mediatek/scpsys.txt    |    6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
> index 16fe94d..b1d165b 100644
> --- a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
> +++ b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
> @@ -9,11 +9,14 @@ domain control.
>  
>  The driver implements the Generic PM domain bindings described in
>  power/power_domain.txt. It provides the power domains defined in
> -include/dt-bindings/power/mt8173-power.h and mt2701-power.h.
> +- include/dt-bindings/power/mt8173-power.h
> +- include/dt-bindings/power/mt6797-power.h
> +- include/dt-bindings/power/mt2701-power.h
>  
>  Required properties:
>  - compatible: Should be one of:
>  	- "mediatek,mt2701-scpsys"
> +	- "mediatek,mt6797-scpsys"
>  	- "mediatek,mt8173-scpsys"
>  - #power-domain-cells: Must be 1
>  - reg: Address range of the SCPSYS unit
> @@ -22,6 +25,7 @@ Required properties:
>                        These are clocks which hardware needs to be
>                        enabled before enabling certain power domains.
>  	Required clocks for MT2701: "mm", "mfg", "ethif"
> +	Required clocks for MT6797: "mm", "mfg", "vdec"
>  	Required clocks for MT8173: "mm", "mfg", "venc", "venc_lt"
>  
>  Optional properties:
> -- 
> 1.7.9.5
> 
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 08/10] soc: mediatek: add MT6797 power dt-bindings
  2017-02-09  0:37   ` Rob Herring
@ 2017-02-09  1:32       ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-09  1:32 UTC (permalink / raw)
  To: Rob Herring
  Cc: Matthias Brugger, CC Hwang, Loda Chou, Miles Chen, Jades Shih,
	Yingjoe Chen, My Chuang, linux-kernel, linux-mediatek,
	devicetree, wsd_upstream, Marc Zyngier, Thomas Gleixner,
	Will Deacon, Stephen Boyd, linux-clk, Chieh-Jay Liu,
	Kevin-CW Chen

On Wed, 2017-02-08 at 18:37 -0600, Rob Herring wrote:
> On Mon, Feb 06, 2017 at 08:15:34PM +0800, Mars Cheng wrote:
> > This adds power dt-bindings for MT6797
> 
> Some consistency in the subject for bindings please.

Got it, will use the format like "dt-bindings: xxx: xxx" to send patch
set v3

Thanks.

> 
> > 
> > Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
> > Signed-off-by: Kevin-CW Chen <kevin-cw.chen@mediatek.com>
> > ---
> >  .../devicetree/bindings/soc/mediatek/scpsys.txt    |    6 +++++-
> >  1 file changed, 5 insertions(+), 1 deletion(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
> > index 16fe94d..b1d165b 100644
> > --- a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
> > +++ b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
> > @@ -9,11 +9,14 @@ domain control.
> >  
> >  The driver implements the Generic PM domain bindings described in
> >  power/power_domain.txt. It provides the power domains defined in
> > -include/dt-bindings/power/mt8173-power.h and mt2701-power.h.
> > +- include/dt-bindings/power/mt8173-power.h
> > +- include/dt-bindings/power/mt6797-power.h
> > +- include/dt-bindings/power/mt2701-power.h
> >  
> >  Required properties:
> >  - compatible: Should be one of:
> >  	- "mediatek,mt2701-scpsys"
> > +	- "mediatek,mt6797-scpsys"
> >  	- "mediatek,mt8173-scpsys"
> >  - #power-domain-cells: Must be 1
> >  - reg: Address range of the SCPSYS unit
> > @@ -22,6 +25,7 @@ Required properties:
> >                        These are clocks which hardware needs to be
> >                        enabled before enabling certain power domains.
> >  	Required clocks for MT2701: "mm", "mfg", "ethif"
> > +	Required clocks for MT6797: "mm", "mfg", "vdec"
> >  	Required clocks for MT8173: "mm", "mfg", "venc", "venc_lt"
> >  
> >  Optional properties:
> > -- 
> > 1.7.9.5
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe devicetree" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 08/10] soc: mediatek: add MT6797 power dt-bindings
@ 2017-02-09  1:32       ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-09  1:32 UTC (permalink / raw)
  To: Rob Herring
  Cc: Matthias Brugger, CC Hwang, Loda Chou, Miles Chen, Jades Shih,
	Yingjoe Chen, My Chuang, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	wsd_upstream-NuS5LvNUpcJWk0Htik3J/w, Marc Zyngier,
	Thomas Gleixner, Will Deacon, Stephen Boyd,
	linux-clk-u79uwXL29TY76Z2rM5mHXA, Chieh-Jay Liu, Kevin-CW Chen

On Wed, 2017-02-08 at 18:37 -0600, Rob Herring wrote:
> On Mon, Feb 06, 2017 at 08:15:34PM +0800, Mars Cheng wrote:
> > This adds power dt-bindings for MT6797
> 
> Some consistency in the subject for bindings please.

Got it, will use the format like "dt-bindings: xxx: xxx" to send patch
set v3

Thanks.

> 
> > 
> > Signed-off-by: Mars Cheng <mars.cheng-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> > Signed-off-by: Kevin-CW Chen <kevin-cw.chen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> > ---
> >  .../devicetree/bindings/soc/mediatek/scpsys.txt    |    6 +++++-
> >  1 file changed, 5 insertions(+), 1 deletion(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
> > index 16fe94d..b1d165b 100644
> > --- a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
> > +++ b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
> > @@ -9,11 +9,14 @@ domain control.
> >  
> >  The driver implements the Generic PM domain bindings described in
> >  power/power_domain.txt. It provides the power domains defined in
> > -include/dt-bindings/power/mt8173-power.h and mt2701-power.h.
> > +- include/dt-bindings/power/mt8173-power.h
> > +- include/dt-bindings/power/mt6797-power.h
> > +- include/dt-bindings/power/mt2701-power.h
> >  
> >  Required properties:
> >  - compatible: Should be one of:
> >  	- "mediatek,mt2701-scpsys"
> > +	- "mediatek,mt6797-scpsys"
> >  	- "mediatek,mt8173-scpsys"
> >  - #power-domain-cells: Must be 1
> >  - reg: Address range of the SCPSYS unit
> > @@ -22,6 +25,7 @@ Required properties:
> >                        These are clocks which hardware needs to be
> >                        enabled before enabling certain power domains.
> >  	Required clocks for MT2701: "mm", "mfg", "ethif"
> > +	Required clocks for MT6797: "mm", "mfg", "vdec"
> >  	Required clocks for MT8173: "mm", "mfg", "venc", "venc_lt"
> >  
> >  Optional properties:
> > -- 
> > 1.7.9.5
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe devicetree" in
> > the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html


--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 01/10] Document: DT: mediatek: multiple base address support for sysirq
  2017-02-08 23:20   ` Rob Herring
@ 2017-02-09  1:47       ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-09  1:47 UTC (permalink / raw)
  To: Rob Herring
  Cc: Matthias Brugger, CC Hwang, Loda Chou, Miles Chen, Jades Shih,
	Yingjoe Chen, My Chuang, linux-kernel, linux-mediatek,
	devicetree, wsd_upstream, Marc Zyngier, Thomas Gleixner,
	Will Deacon, Stephen Boyd, linux-clk, Chieh-Jay Liu

Hi Rob,

On Wed, 2017-02-08 at 17:20 -0600, Rob Herring wrote:
> On Mon, Feb 06, 2017 at 08:15:27PM +0800, Mars Cheng wrote:
> > This describes how to specify multiple base addresses for sysirq
> > in mediatek platforms.
> > 
> > Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
> > ---
> >  .../interrupt-controller/mediatek,sysirq.txt       |   13 +++++++++----
> >  1 file changed, 9 insertions(+), 4 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt b/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt
> > index 9d1d72c..1718454 100644
> > --- a/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt
> > +++ b/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt
> > @@ -18,16 +18,21 @@ Required properties:
> >  	"mediatek,mt2701-sysirq"
> >  - interrupt-controller : Identifies the node as an interrupt controller
> >  - #interrupt-cells : Use the same format as specified by GIC in arm,gic.txt.
> > +- #intpol-bases: Indicate how many base addresses to be used, default is 1.
> 
> There is no point in this. It can either be implied by the compatible 
> string or you just try to get the resource for the 2nd region. (Or in DT 
> terms, get the size of reg.)
> 

Originally I try to mimic #redistributor-regions in
Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt.

But I think you are right since irq-gic-v3 has several kinds of bases in
reg so that they need an indicator to decode. For irq-mtk-sysirq, we can
just try 2nd region and increment a counter to get the number of bases.

Will fix this in v3.

Thanks.

> >  - interrupt-parent: phandle of irq parent for sysirq. The parent must
> >    use the same interrupt-cells format as GIC.
> >  - reg: Physical base address of the intpol registers and length of memory
> > -  mapped region.
> > +  mapped region. Could be multiple bases here. Ex: mt6797 needs 2 reg, others
> > +  need 1. If not set, the default is 1.
> >  
> >  Example:
> > -	sysirq: interrupt-controller@10200100 {
> > -		compatible = "mediatek,mt6589-sysirq", "mediatek,mt6577-sysirq";
> > +	sysirq: intpol-controller@10200620 {
> > +		compatible = "mediatek,mt6797-sysirq",
> > +			     "mediatek,mt6577-sysirq";
> >  		interrupt-controller;
> >  		#interrupt-cells = <3>;
> > +		#intpol-bases = <2>;
> >  		interrupt-parent = <&gic>;
> > -		reg = <0 0x10200100 0 0x1c>;
> > +		reg = <0 0x10220620 0 0x20>,
> > +		      <0 0x10220690 0 0x10>;
> >  	};
> > -- 
> > 1.7.9.5
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe devicetree" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 01/10] Document: DT: mediatek: multiple base address support for sysirq
@ 2017-02-09  1:47       ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-09  1:47 UTC (permalink / raw)
  To: Rob Herring
  Cc: Matthias Brugger, CC Hwang, Loda Chou, Miles Chen, Jades Shih,
	Yingjoe Chen, My Chuang, linux-kernel, linux-mediatek,
	devicetree, wsd_upstream, Marc Zyngier, Thomas Gleixner,
	Will Deacon, Stephen Boyd, linux-clk, Chieh-Jay Liu

Hi Rob,

On Wed, 2017-02-08 at 17:20 -0600, Rob Herring wrote:
> On Mon, Feb 06, 2017 at 08:15:27PM +0800, Mars Cheng wrote:
> > This describes how to specify multiple base addresses for sysirq
> > in mediatek platforms.
> > 
> > Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
> > ---
> >  .../interrupt-controller/mediatek,sysirq.txt       |   13 +++++++++----
> >  1 file changed, 9 insertions(+), 4 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt b/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt
> > index 9d1d72c..1718454 100644
> > --- a/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt
> > +++ b/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt
> > @@ -18,16 +18,21 @@ Required properties:
> >  	"mediatek,mt2701-sysirq"
> >  - interrupt-controller : Identifies the node as an interrupt controller
> >  - #interrupt-cells : Use the same format as specified by GIC in arm,gic.txt.
> > +- #intpol-bases: Indicate how many base addresses to be used, default is 1.
> 
> There is no point in this. It can either be implied by the compatible 
> string or you just try to get the resource for the 2nd region. (Or in DT 
> terms, get the size of reg.)
> 

Originally I try to mimic #redistributor-regions in
Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt.

But I think you are right since irq-gic-v3 has several kinds of bases in
reg so that they need an indicator to decode. For irq-mtk-sysirq, we can
just try 2nd region and increment a counter to get the number of bases.

Will fix this in v3.

Thanks.

> >  - interrupt-parent: phandle of irq parent for sysirq. The parent must
> >    use the same interrupt-cells format as GIC.
> >  - reg: Physical base address of the intpol registers and length of memory
> > -  mapped region.
> > +  mapped region. Could be multiple bases here. Ex: mt6797 needs 2 reg, others
> > +  need 1. If not set, the default is 1.
> >  
> >  Example:
> > -	sysirq: interrupt-controller@10200100 {
> > -		compatible = "mediatek,mt6589-sysirq", "mediatek,mt6577-sysirq";
> > +	sysirq: intpol-controller@10200620 {
> > +		compatible = "mediatek,mt6797-sysirq",
> > +			     "mediatek,mt6577-sysirq";
> >  		interrupt-controller;
> >  		#interrupt-cells = <3>;
> > +		#intpol-bases = <2>;
> >  		interrupt-parent = <&gic>;
> > -		reg = <0 0x10200100 0 0x1c>;
> > +		reg = <0 0x10220620 0 0x20>,
> > +		      <0 0x10220690 0 0x10>;
> >  	};
> > -- 
> > 1.7.9.5
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe devicetree" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 02/10] irqchip: mtk-sysirq: extend intpol base to arbitrary number
@ 2017-02-09  9:03     ` Marc Zyngier
  0 siblings, 0 replies; 44+ messages in thread
From: Marc Zyngier @ 2017-02-09  9:03 UTC (permalink / raw)
  To: Mars Cheng, Matthias Brugger
  Cc: CC Hwang, Loda Chou, Miles Chen, Jades Shih, Yingjoe Chen,
	My Chuang, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, Thomas Gleixner, Will Deacon, Stephen Boyd,
	linux-clk, Chieh-Jay Liu

On 06/02/17 12:15, Mars Cheng wrote:
> Originally driver only supports one base. However, MT6797 has
> more than one bases to configure interrupt polarity. To support
> possible design change, here comes a solution to use arbitrary
> number of bases.
> 
> Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
> ---
>  drivers/irqchip/irq-mtk-sysirq.c |   71 +++++++++++++++++++++++++++-----------
>  1 file changed, 50 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c
> index 63ac73b..2645706 100644
> --- a/drivers/irqchip/irq-mtk-sysirq.c
> +++ b/drivers/irqchip/irq-mtk-sysirq.c
> @@ -24,7 +24,9 @@
>  
>  struct mtk_sysirq_chip_data {
>  	spinlock_t lock;
> -	void __iomem *intpol_base;
> +	u32 nr_intpol_bases;
> +	void __iomem **intpol_bases;
> +	u32 *intpol_words;
>  };
>  
>  static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
> @@ -33,13 +35,15 @@ static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
>  	struct mtk_sysirq_chip_data *chip_data = data->chip_data;
>  	u32 offset, reg_index, value;
>  	unsigned long flags;
> -	int ret;
> +	int ret, i;
>  
>  	offset = hwirq & 0x1f;
>  	reg_index = hwirq >> 5;
> +	for (i = 0; reg_index >= chip_data->intpol_words[i]; i++)
> +		reg_index -= chip_data->intpol_words[i];

Two questions:
- What guarantees that two successive regions deal with consecutive
interrupts? For example, if I have region A that deals with interrupts
0-31, what guarantees that region B covers 32-63?
- Given that there is a static relation between a region and a hwirq,
can't you compute this relation at init time, and let set_type be a fast
path?

>  
>  	spin_lock_irqsave(&chip_data->lock, flags);
> -	value = readl_relaxed(chip_data->intpol_base + reg_index * 4);
> +	value = readl_relaxed(chip_data->intpol_bases[i] + reg_index * 4);
>  	if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_EDGE_FALLING) {
>  		if (type == IRQ_TYPE_LEVEL_LOW)
>  			type = IRQ_TYPE_LEVEL_HIGH;
> @@ -49,7 +53,8 @@ static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
>  	} else {
>  		value &= ~(1 << offset);
>  	}
> -	writel(value, chip_data->intpol_base + reg_index * 4);
> +
> +	writel(value, chip_data->intpol_bases[i] + reg_index * 4);

Why do you have a writel here, while you're using relaxed accessors
otherwise? Is there anything else that needs to be made visible to the
irqchip?

>  
>  	data = data->parent_data;
>  	ret = data->chip->irq_set_type(data, type);
> @@ -124,8 +129,7 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
>  {
>  	struct irq_domain *domain, *domain_parent;
>  	struct mtk_sysirq_chip_data *chip_data;
> -	int ret, size, intpol_num;
> -	struct resource res;
> +	int ret, size, intpol_num = 0, nr_intpol_bases, i;
>  
>  	domain_parent = irq_find_host(parent);
>  	if (!domain_parent) {
> @@ -133,36 +137,61 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
>  		return -EINVAL;
>  	}
>  
> -	ret = of_address_to_resource(node, 0, &res);
> -	if (ret)
> -		return ret;
> -
>  	chip_data = kzalloc(sizeof(*chip_data), GFP_KERNEL);
>  	if (!chip_data)
>  		return -ENOMEM;
>  
> -	size = resource_size(&res);
> -	intpol_num = size * 8;
> -	chip_data->intpol_base = ioremap(res.start, size);
> -	if (!chip_data->intpol_base) {
> -		pr_err("mtk_sysirq: unable to map sysirq register\n");
> -		ret = -ENXIO;
> -		goto out_free;
> +	if (of_property_read_u32(node, "#intpol-bases", &nr_intpol_bases))
> +		nr_intpol_bases = 1;
> +
> +	chip_data->intpol_words =
> +		kcalloc(nr_intpol_bases, sizeof(u32), GFP_KERNEL);

Please keep the assignment on a single line.

> +	if (!chip_data->intpol_words) {
> +		ret = -ENOMEM;
> +		goto out_free_chip;
> +	}
> +
> +	chip_data->intpol_bases =
> +		kcalloc(nr_intpol_bases, sizeof(void __iomem *), GFP_KERNEL);

Same here.

> +	if (!chip_data->intpol_bases) {
> +		ret = -ENOMEM;
> +		goto out_free_intpol_words;
> +	}
> +
> +	for (i = 0; i < nr_intpol_bases; i++) {
> +		struct resource res;
> +
> +		ret = of_address_to_resource(node, i, &res);
> +		size = resource_size(&res);
> +		intpol_num += size * 8;
> +		chip_data->intpol_words[i] = size / 4;
> +		chip_data->intpol_bases[i] = of_iomap(node, i);
> +		if (ret || !chip_data->intpol_bases[i]) {
> +			pr_err("%s: couldn't map region %d\n",
> +			       node->full_name, i);
> +			ret = -ENODEV;
> +			goto out_free_intpol;
> +		}
>  	}
>  
>  	domain = irq_domain_add_hierarchy(domain_parent, 0, intpol_num, node,
>  					  &sysirq_domain_ops, chip_data);
>  	if (!domain) {
>  		ret = -ENOMEM;
> -		goto out_unmap;
> +		goto out_free_intpol;
>  	}
>  	spin_lock_init(&chip_data->lock);
>  
>  	return 0;
>  
> -out_unmap:
> -	iounmap(chip_data->intpol_base);
> -out_free:
> +out_free_intpol:
> +	for (i = 0; i < nr_intpol_bases; i++)
> +		if (chip_data->intpol_bases[i])
> +			iounmap(chip_data->intpol_bases[i]);
> +	kfree(chip_data->intpol_bases);
> +out_free_intpol_words:
> +	kfree(chip_data->intpol_words);
> +out_free_chip:
>  	kfree(chip_data);
>  	return ret;
>  }
> 

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 02/10] irqchip: mtk-sysirq: extend intpol base to arbitrary number
@ 2017-02-09  9:03     ` Marc Zyngier
  0 siblings, 0 replies; 44+ messages in thread
From: Marc Zyngier @ 2017-02-09  9:03 UTC (permalink / raw)
  To: Mars Cheng, Matthias Brugger
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, CC Hwang,
	wsd_upstream-NuS5LvNUpcJWk0Htik3J/w, Will Deacon, Loda Chou,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Jades Shih,
	linux-clk-u79uwXL29TY76Z2rM5mHXA, Miles Chen,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, My Chuang,
	Yingjoe Chen, Thomas Gleixner, Stephen Boyd, Chieh-Jay Liu

On 06/02/17 12:15, Mars Cheng wrote:
> Originally driver only supports one base. However, MT6797 has
> more than one bases to configure interrupt polarity. To support
> possible design change, here comes a solution to use arbitrary
> number of bases.
> 
> Signed-off-by: Mars Cheng <mars.cheng-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> ---
>  drivers/irqchip/irq-mtk-sysirq.c |   71 +++++++++++++++++++++++++++-----------
>  1 file changed, 50 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c
> index 63ac73b..2645706 100644
> --- a/drivers/irqchip/irq-mtk-sysirq.c
> +++ b/drivers/irqchip/irq-mtk-sysirq.c
> @@ -24,7 +24,9 @@
>  
>  struct mtk_sysirq_chip_data {
>  	spinlock_t lock;
> -	void __iomem *intpol_base;
> +	u32 nr_intpol_bases;
> +	void __iomem **intpol_bases;
> +	u32 *intpol_words;
>  };
>  
>  static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
> @@ -33,13 +35,15 @@ static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
>  	struct mtk_sysirq_chip_data *chip_data = data->chip_data;
>  	u32 offset, reg_index, value;
>  	unsigned long flags;
> -	int ret;
> +	int ret, i;
>  
>  	offset = hwirq & 0x1f;
>  	reg_index = hwirq >> 5;
> +	for (i = 0; reg_index >= chip_data->intpol_words[i]; i++)
> +		reg_index -= chip_data->intpol_words[i];

Two questions:
- What guarantees that two successive regions deal with consecutive
interrupts? For example, if I have region A that deals with interrupts
0-31, what guarantees that region B covers 32-63?
- Given that there is a static relation between a region and a hwirq,
can't you compute this relation at init time, and let set_type be a fast
path?

>  
>  	spin_lock_irqsave(&chip_data->lock, flags);
> -	value = readl_relaxed(chip_data->intpol_base + reg_index * 4);
> +	value = readl_relaxed(chip_data->intpol_bases[i] + reg_index * 4);
>  	if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_EDGE_FALLING) {
>  		if (type == IRQ_TYPE_LEVEL_LOW)
>  			type = IRQ_TYPE_LEVEL_HIGH;
> @@ -49,7 +53,8 @@ static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
>  	} else {
>  		value &= ~(1 << offset);
>  	}
> -	writel(value, chip_data->intpol_base + reg_index * 4);
> +
> +	writel(value, chip_data->intpol_bases[i] + reg_index * 4);

Why do you have a writel here, while you're using relaxed accessors
otherwise? Is there anything else that needs to be made visible to the
irqchip?

>  
>  	data = data->parent_data;
>  	ret = data->chip->irq_set_type(data, type);
> @@ -124,8 +129,7 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
>  {
>  	struct irq_domain *domain, *domain_parent;
>  	struct mtk_sysirq_chip_data *chip_data;
> -	int ret, size, intpol_num;
> -	struct resource res;
> +	int ret, size, intpol_num = 0, nr_intpol_bases, i;
>  
>  	domain_parent = irq_find_host(parent);
>  	if (!domain_parent) {
> @@ -133,36 +137,61 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
>  		return -EINVAL;
>  	}
>  
> -	ret = of_address_to_resource(node, 0, &res);
> -	if (ret)
> -		return ret;
> -
>  	chip_data = kzalloc(sizeof(*chip_data), GFP_KERNEL);
>  	if (!chip_data)
>  		return -ENOMEM;
>  
> -	size = resource_size(&res);
> -	intpol_num = size * 8;
> -	chip_data->intpol_base = ioremap(res.start, size);
> -	if (!chip_data->intpol_base) {
> -		pr_err("mtk_sysirq: unable to map sysirq register\n");
> -		ret = -ENXIO;
> -		goto out_free;
> +	if (of_property_read_u32(node, "#intpol-bases", &nr_intpol_bases))
> +		nr_intpol_bases = 1;
> +
> +	chip_data->intpol_words =
> +		kcalloc(nr_intpol_bases, sizeof(u32), GFP_KERNEL);

Please keep the assignment on a single line.

> +	if (!chip_data->intpol_words) {
> +		ret = -ENOMEM;
> +		goto out_free_chip;
> +	}
> +
> +	chip_data->intpol_bases =
> +		kcalloc(nr_intpol_bases, sizeof(void __iomem *), GFP_KERNEL);

Same here.

> +	if (!chip_data->intpol_bases) {
> +		ret = -ENOMEM;
> +		goto out_free_intpol_words;
> +	}
> +
> +	for (i = 0; i < nr_intpol_bases; i++) {
> +		struct resource res;
> +
> +		ret = of_address_to_resource(node, i, &res);
> +		size = resource_size(&res);
> +		intpol_num += size * 8;
> +		chip_data->intpol_words[i] = size / 4;
> +		chip_data->intpol_bases[i] = of_iomap(node, i);
> +		if (ret || !chip_data->intpol_bases[i]) {
> +			pr_err("%s: couldn't map region %d\n",
> +			       node->full_name, i);
> +			ret = -ENODEV;
> +			goto out_free_intpol;
> +		}
>  	}
>  
>  	domain = irq_domain_add_hierarchy(domain_parent, 0, intpol_num, node,
>  					  &sysirq_domain_ops, chip_data);
>  	if (!domain) {
>  		ret = -ENOMEM;
> -		goto out_unmap;
> +		goto out_free_intpol;
>  	}
>  	spin_lock_init(&chip_data->lock);
>  
>  	return 0;
>  
> -out_unmap:
> -	iounmap(chip_data->intpol_base);
> -out_free:
> +out_free_intpol:
> +	for (i = 0; i < nr_intpol_bases; i++)
> +		if (chip_data->intpol_bases[i])
> +			iounmap(chip_data->intpol_bases[i]);
> +	kfree(chip_data->intpol_bases);
> +out_free_intpol_words:
> +	kfree(chip_data->intpol_words);
> +out_free_chip:
>  	kfree(chip_data);
>  	return ret;
>  }
> 

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 02/10] irqchip: mtk-sysirq: extend intpol base to arbitrary number
@ 2017-02-09  9:31       ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-09  9:31 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Matthias Brugger, CC Hwang, Loda Chou, Miles Chen, Jades Shih,
	Yingjoe Chen, My Chuang, linux-kernel, linux-mediatek,
	devicetree, wsd_upstream, Thomas Gleixner, Will Deacon,
	Stephen Boyd, linux-clk, Chieh-Jay Liu

On Thu, 2017-02-09 at 09:03 +0000, Marc Zyngier wrote:
> On 06/02/17 12:15, Mars Cheng wrote:
> > Originally driver only supports one base. However, MT6797 has
> > more than one bases to configure interrupt polarity. To support
> > possible design change, here comes a solution to use arbitrary
> > number of bases.
> > 
> > Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
> > ---
> >  drivers/irqchip/irq-mtk-sysirq.c |   71 +++++++++++++++++++++++++++-----------
> >  1 file changed, 50 insertions(+), 21 deletions(-)
> > 
> > diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c
> > index 63ac73b..2645706 100644
> > --- a/drivers/irqchip/irq-mtk-sysirq.c
> > +++ b/drivers/irqchip/irq-mtk-sysirq.c
> > @@ -24,7 +24,9 @@
> >  
> >  struct mtk_sysirq_chip_data {
> >  	spinlock_t lock;
> > -	void __iomem *intpol_base;
> > +	u32 nr_intpol_bases;
> > +	void __iomem **intpol_bases;
> > +	u32 *intpol_words;
> >  };
> >  
> >  static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
> > @@ -33,13 +35,15 @@ static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
> >  	struct mtk_sysirq_chip_data *chip_data = data->chip_data;
> >  	u32 offset, reg_index, value;
> >  	unsigned long flags;
> > -	int ret;
> > +	int ret, i;
> >  
> >  	offset = hwirq & 0x1f;
> >  	reg_index = hwirq >> 5;
> > +	for (i = 0; reg_index >= chip_data->intpol_words[i]; i++)
> > +		reg_index -= chip_data->intpol_words[i];
> 
> Two questions:
> - What guarantees that two successive regions deal with consecutive
> interrupts? For example, if I have region A that deals with interrupts
> 0-31, what guarantees that region B covers 32-63?

It is guaranteed by mediatek's chip design team. For those chips with
multiple bases, they all have the consecutive interrupts in the next
region.

> - Given that there is a static relation between a region and a hwirq,
> can't you compute this relation at init time, and let set_type be a fast
> path?
> 

sure, I can do this to optimize set_type. will do it in v3

> >  
> >  	spin_lock_irqsave(&chip_data->lock, flags);
> > -	value = readl_relaxed(chip_data->intpol_base + reg_index * 4);
> > +	value = readl_relaxed(chip_data->intpol_bases[i] + reg_index * 4);
> >  	if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_EDGE_FALLING) {
> >  		if (type == IRQ_TYPE_LEVEL_LOW)
> >  			type = IRQ_TYPE_LEVEL_HIGH;
> > @@ -49,7 +53,8 @@ static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
> >  	} else {
> >  		value &= ~(1 << offset);
> >  	}
> > -	writel(value, chip_data->intpol_base + reg_index * 4);
> > +
> > +	writel(value, chip_data->intpol_bases[i] + reg_index * 4);
> 
> Why do you have a writel here, while you're using relaxed accessors
> otherwise? Is there anything else that needs to be made visible to the
> irqchip?
> 

before we call spin_unlock_irqrestore() in the end of set_type, polarity
should take effect so we use writel() here. This patch did not change
the usage.

> >  
> >  	data = data->parent_data;
> >  	ret = data->chip->irq_set_type(data, type);
> > @@ -124,8 +129,7 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
> >  {
> >  	struct irq_domain *domain, *domain_parent;
> >  	struct mtk_sysirq_chip_data *chip_data;
> > -	int ret, size, intpol_num;
> > -	struct resource res;
> > +	int ret, size, intpol_num = 0, nr_intpol_bases, i;
> >  
> >  	domain_parent = irq_find_host(parent);
> >  	if (!domain_parent) {
> > @@ -133,36 +137,61 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
> >  		return -EINVAL;
> >  	}
> >  
> > -	ret = of_address_to_resource(node, 0, &res);
> > -	if (ret)
> > -		return ret;
> > -
> >  	chip_data = kzalloc(sizeof(*chip_data), GFP_KERNEL);
> >  	if (!chip_data)
> >  		return -ENOMEM;
> >  
> > -	size = resource_size(&res);
> > -	intpol_num = size * 8;
> > -	chip_data->intpol_base = ioremap(res.start, size);
> > -	if (!chip_data->intpol_base) {
> > -		pr_err("mtk_sysirq: unable to map sysirq register\n");
> > -		ret = -ENXIO;
> > -		goto out_free;
> > +	if (of_property_read_u32(node, "#intpol-bases", &nr_intpol_bases))
> > +		nr_intpol_bases = 1;
> > +
> > +	chip_data->intpol_words =
> > +		kcalloc(nr_intpol_bases, sizeof(u32), GFP_KERNEL);
> 
> Please keep the assignment on a single line.
> 

Got it, but another warning (prefer 75 char in single line) would pop
up. Would you still like me to keep it on a single line?

> > +	if (!chip_data->intpol_words) {
> > +		ret = -ENOMEM;
> > +		goto out_free_chip;
> > +	}
> > +
> > +	chip_data->intpol_bases =
> > +		kcalloc(nr_intpol_bases, sizeof(void __iomem *), GFP_KERNEL);
> 
> Same here.
> 
> > +	if (!chip_data->intpol_bases) {
> > +		ret = -ENOMEM;
> > +		goto out_free_intpol_words;
> > +	}
> > +
> > +	for (i = 0; i < nr_intpol_bases; i++) {
> > +		struct resource res;
> > +
> > +		ret = of_address_to_resource(node, i, &res);
> > +		size = resource_size(&res);
> > +		intpol_num += size * 8;
> > +		chip_data->intpol_words[i] = size / 4;
> > +		chip_data->intpol_bases[i] = of_iomap(node, i);
> > +		if (ret || !chip_data->intpol_bases[i]) {
> > +			pr_err("%s: couldn't map region %d\n",
> > +			       node->full_name, i);
> > +			ret = -ENODEV;
> > +			goto out_free_intpol;
> > +		}
> >  	}
> >  
> >  	domain = irq_domain_add_hierarchy(domain_parent, 0, intpol_num, node,
> >  					  &sysirq_domain_ops, chip_data);
> >  	if (!domain) {
> >  		ret = -ENOMEM;
> > -		goto out_unmap;
> > +		goto out_free_intpol;
> >  	}
> >  	spin_lock_init(&chip_data->lock);
> >  
> >  	return 0;
> >  
> > -out_unmap:
> > -	iounmap(chip_data->intpol_base);
> > -out_free:
> > +out_free_intpol:
> > +	for (i = 0; i < nr_intpol_bases; i++)
> > +		if (chip_data->intpol_bases[i])
> > +			iounmap(chip_data->intpol_bases[i]);
> > +	kfree(chip_data->intpol_bases);
> > +out_free_intpol_words:
> > +	kfree(chip_data->intpol_words);
> > +out_free_chip:
> >  	kfree(chip_data);
> >  	return ret;
> >  }
> > 
> 
> Thanks,
> 
> 	M.

Thanks,

          Mars Cheng

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 02/10] irqchip: mtk-sysirq: extend intpol base to arbitrary number
@ 2017-02-09  9:31       ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-09  9:31 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, CC Hwang,
	wsd_upstream-NuS5LvNUpcJWk0Htik3J/w, Will Deacon, Loda Chou,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Jades Shih,
	linux-clk-u79uwXL29TY76Z2rM5mHXA, Miles Chen,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, My Chuang,
	Matthias Brugger, Yingjoe Chen, Thomas Gleixner, Stephen Boyd,
	Chieh-Jay Liu

On Thu, 2017-02-09 at 09:03 +0000, Marc Zyngier wrote:
> On 06/02/17 12:15, Mars Cheng wrote:
> > Originally driver only supports one base. However, MT6797 has
> > more than one bases to configure interrupt polarity. To support
> > possible design change, here comes a solution to use arbitrary
> > number of bases.
> > 
> > Signed-off-by: Mars Cheng <mars.cheng-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> > ---
> >  drivers/irqchip/irq-mtk-sysirq.c |   71 +++++++++++++++++++++++++++-----------
> >  1 file changed, 50 insertions(+), 21 deletions(-)
> > 
> > diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c
> > index 63ac73b..2645706 100644
> > --- a/drivers/irqchip/irq-mtk-sysirq.c
> > +++ b/drivers/irqchip/irq-mtk-sysirq.c
> > @@ -24,7 +24,9 @@
> >  
> >  struct mtk_sysirq_chip_data {
> >  	spinlock_t lock;
> > -	void __iomem *intpol_base;
> > +	u32 nr_intpol_bases;
> > +	void __iomem **intpol_bases;
> > +	u32 *intpol_words;
> >  };
> >  
> >  static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
> > @@ -33,13 +35,15 @@ static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
> >  	struct mtk_sysirq_chip_data *chip_data = data->chip_data;
> >  	u32 offset, reg_index, value;
> >  	unsigned long flags;
> > -	int ret;
> > +	int ret, i;
> >  
> >  	offset = hwirq & 0x1f;
> >  	reg_index = hwirq >> 5;
> > +	for (i = 0; reg_index >= chip_data->intpol_words[i]; i++)
> > +		reg_index -= chip_data->intpol_words[i];
> 
> Two questions:
> - What guarantees that two successive regions deal with consecutive
> interrupts? For example, if I have region A that deals with interrupts
> 0-31, what guarantees that region B covers 32-63?

It is guaranteed by mediatek's chip design team. For those chips with
multiple bases, they all have the consecutive interrupts in the next
region.

> - Given that there is a static relation between a region and a hwirq,
> can't you compute this relation at init time, and let set_type be a fast
> path?
> 

sure, I can do this to optimize set_type. will do it in v3

> >  
> >  	spin_lock_irqsave(&chip_data->lock, flags);
> > -	value = readl_relaxed(chip_data->intpol_base + reg_index * 4);
> > +	value = readl_relaxed(chip_data->intpol_bases[i] + reg_index * 4);
> >  	if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_EDGE_FALLING) {
> >  		if (type == IRQ_TYPE_LEVEL_LOW)
> >  			type = IRQ_TYPE_LEVEL_HIGH;
> > @@ -49,7 +53,8 @@ static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
> >  	} else {
> >  		value &= ~(1 << offset);
> >  	}
> > -	writel(value, chip_data->intpol_base + reg_index * 4);
> > +
> > +	writel(value, chip_data->intpol_bases[i] + reg_index * 4);
> 
> Why do you have a writel here, while you're using relaxed accessors
> otherwise? Is there anything else that needs to be made visible to the
> irqchip?
> 

before we call spin_unlock_irqrestore() in the end of set_type, polarity
should take effect so we use writel() here. This patch did not change
the usage.

> >  
> >  	data = data->parent_data;
> >  	ret = data->chip->irq_set_type(data, type);
> > @@ -124,8 +129,7 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
> >  {
> >  	struct irq_domain *domain, *domain_parent;
> >  	struct mtk_sysirq_chip_data *chip_data;
> > -	int ret, size, intpol_num;
> > -	struct resource res;
> > +	int ret, size, intpol_num = 0, nr_intpol_bases, i;
> >  
> >  	domain_parent = irq_find_host(parent);
> >  	if (!domain_parent) {
> > @@ -133,36 +137,61 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
> >  		return -EINVAL;
> >  	}
> >  
> > -	ret = of_address_to_resource(node, 0, &res);
> > -	if (ret)
> > -		return ret;
> > -
> >  	chip_data = kzalloc(sizeof(*chip_data), GFP_KERNEL);
> >  	if (!chip_data)
> >  		return -ENOMEM;
> >  
> > -	size = resource_size(&res);
> > -	intpol_num = size * 8;
> > -	chip_data->intpol_base = ioremap(res.start, size);
> > -	if (!chip_data->intpol_base) {
> > -		pr_err("mtk_sysirq: unable to map sysirq register\n");
> > -		ret = -ENXIO;
> > -		goto out_free;
> > +	if (of_property_read_u32(node, "#intpol-bases", &nr_intpol_bases))
> > +		nr_intpol_bases = 1;
> > +
> > +	chip_data->intpol_words =
> > +		kcalloc(nr_intpol_bases, sizeof(u32), GFP_KERNEL);
> 
> Please keep the assignment on a single line.
> 

Got it, but another warning (prefer 75 char in single line) would pop
up. Would you still like me to keep it on a single line?

> > +	if (!chip_data->intpol_words) {
> > +		ret = -ENOMEM;
> > +		goto out_free_chip;
> > +	}
> > +
> > +	chip_data->intpol_bases =
> > +		kcalloc(nr_intpol_bases, sizeof(void __iomem *), GFP_KERNEL);
> 
> Same here.
> 
> > +	if (!chip_data->intpol_bases) {
> > +		ret = -ENOMEM;
> > +		goto out_free_intpol_words;
> > +	}
> > +
> > +	for (i = 0; i < nr_intpol_bases; i++) {
> > +		struct resource res;
> > +
> > +		ret = of_address_to_resource(node, i, &res);
> > +		size = resource_size(&res);
> > +		intpol_num += size * 8;
> > +		chip_data->intpol_words[i] = size / 4;
> > +		chip_data->intpol_bases[i] = of_iomap(node, i);
> > +		if (ret || !chip_data->intpol_bases[i]) {
> > +			pr_err("%s: couldn't map region %d\n",
> > +			       node->full_name, i);
> > +			ret = -ENODEV;
> > +			goto out_free_intpol;
> > +		}
> >  	}
> >  
> >  	domain = irq_domain_add_hierarchy(domain_parent, 0, intpol_num, node,
> >  					  &sysirq_domain_ops, chip_data);
> >  	if (!domain) {
> >  		ret = -ENOMEM;
> > -		goto out_unmap;
> > +		goto out_free_intpol;
> >  	}
> >  	spin_lock_init(&chip_data->lock);
> >  
> >  	return 0;
> >  
> > -out_unmap:
> > -	iounmap(chip_data->intpol_base);
> > -out_free:
> > +out_free_intpol:
> > +	for (i = 0; i < nr_intpol_bases; i++)
> > +		if (chip_data->intpol_bases[i])
> > +			iounmap(chip_data->intpol_bases[i]);
> > +	kfree(chip_data->intpol_bases);
> > +out_free_intpol_words:
> > +	kfree(chip_data->intpol_words);
> > +out_free_chip:
> >  	kfree(chip_data);
> >  	return ret;
> >  }
> > 
> 
> Thanks,
> 
> 	M.

Thanks,

          Mars Cheng

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 02/10] irqchip: mtk-sysirq: extend intpol base to arbitrary number
  2017-02-09  9:31       ` Mars Cheng
@ 2017-02-09  9:43         ` Marc Zyngier
  -1 siblings, 0 replies; 44+ messages in thread
From: Marc Zyngier @ 2017-02-09  9:43 UTC (permalink / raw)
  To: Mars Cheng
  Cc: Matthias Brugger, CC Hwang, Loda Chou, Miles Chen, Jades Shih,
	Yingjoe Chen, My Chuang, linux-kernel, linux-mediatek,
	devicetree, wsd_upstream, Thomas Gleixner, Will Deacon,
	Stephen Boyd, linux-clk, Chieh-Jay Liu

On 09/02/17 09:31, Mars Cheng wrote:
> On Thu, 2017-02-09 at 09:03 +0000, Marc Zyngier wrote:
>> On 06/02/17 12:15, Mars Cheng wrote:
>>> Originally driver only supports one base. However, MT6797 has
>>> more than one bases to configure interrupt polarity. To support
>>> possible design change, here comes a solution to use arbitrary
>>> number of bases.
>>>
>>> Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
>>> ---
>>>  drivers/irqchip/irq-mtk-sysirq.c |   71 +++++++++++++++++++++++++++-----------
>>>  1 file changed, 50 insertions(+), 21 deletions(-)
>>>
>>> diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c
>>> index 63ac73b..2645706 100644
>>> --- a/drivers/irqchip/irq-mtk-sysirq.c
>>> +++ b/drivers/irqchip/irq-mtk-sysirq.c
>>> @@ -24,7 +24,9 @@
>>>  
>>>  struct mtk_sysirq_chip_data {
>>>  	spinlock_t lock;
>>> -	void __iomem *intpol_base;
>>> +	u32 nr_intpol_bases;
>>> +	void __iomem **intpol_bases;
>>> +	u32 *intpol_words;
>>>  };
>>>  
>>>  static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
>>> @@ -33,13 +35,15 @@ static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
>>>  	struct mtk_sysirq_chip_data *chip_data = data->chip_data;
>>>  	u32 offset, reg_index, value;
>>>  	unsigned long flags;
>>> -	int ret;
>>> +	int ret, i;
>>>  
>>>  	offset = hwirq & 0x1f;
>>>  	reg_index = hwirq >> 5;
>>> +	for (i = 0; reg_index >= chip_data->intpol_words[i]; i++)
>>> +		reg_index -= chip_data->intpol_words[i];
>>
>> Two questions:
>> - What guarantees that two successive regions deal with consecutive
>> interrupts? For example, if I have region A that deals with interrupts
>> 0-31, what guarantees that region B covers 32-63?
> 
> It is guaranteed by mediatek's chip design team. For those chips with
> multiple bases, they all have the consecutive interrupts in the next
> region.

Hum. OK. We'll see how long this holds true, I suppose.

> 
>> - Given that there is a static relation between a region and a hwirq,
>> can't you compute this relation at init time, and let set_type be a fast
>> path?
>>
> 
> sure, I can do this to optimize set_type. will do it in v3
> 
>>>  
>>>  	spin_lock_irqsave(&chip_data->lock, flags);
>>> -	value = readl_relaxed(chip_data->intpol_base + reg_index * 4);
>>> +	value = readl_relaxed(chip_data->intpol_bases[i] + reg_index * 4);
>>>  	if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_EDGE_FALLING) {
>>>  		if (type == IRQ_TYPE_LEVEL_LOW)
>>>  			type = IRQ_TYPE_LEVEL_HIGH;
>>> @@ -49,7 +53,8 @@ static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
>>>  	} else {
>>>  		value &= ~(1 << offset);
>>>  	}
>>> -	writel(value, chip_data->intpol_base + reg_index * 4);
>>> +
>>> +	writel(value, chip_data->intpol_bases[i] + reg_index * 4);
>>
>> Why do you have a writel here, while you're using relaxed accessors
>> otherwise? Is there anything else that needs to be made visible to the
>> irqchip?
>>
> 
> before we call spin_unlock_irqrestore() in the end of set_type, polarity
> should take effect so we use writel() here. This patch did not change
> the usage.

That's not what I mean. writel has a DSB *before* performing the write
to the device. Do you have any write (to memory) that needs to be made
visible to the irqchip before the write to the register occurs?

Looking at the code, I'd say no. This is a standard device
read-modify-write sequence, no in-memory data that needs to make it
before the write occurs.

So please turn this into a writel_relaxed.

> 
>>>  
>>>  	data = data->parent_data;
>>>  	ret = data->chip->irq_set_type(data, type);
>>> @@ -124,8 +129,7 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
>>>  {
>>>  	struct irq_domain *domain, *domain_parent;
>>>  	struct mtk_sysirq_chip_data *chip_data;
>>> -	int ret, size, intpol_num;
>>> -	struct resource res;
>>> +	int ret, size, intpol_num = 0, nr_intpol_bases, i;
>>>  
>>>  	domain_parent = irq_find_host(parent);
>>>  	if (!domain_parent) {
>>> @@ -133,36 +137,61 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
>>>  		return -EINVAL;
>>>  	}
>>>  
>>> -	ret = of_address_to_resource(node, 0, &res);
>>> -	if (ret)
>>> -		return ret;
>>> -
>>>  	chip_data = kzalloc(sizeof(*chip_data), GFP_KERNEL);
>>>  	if (!chip_data)
>>>  		return -ENOMEM;
>>>  
>>> -	size = resource_size(&res);
>>> -	intpol_num = size * 8;
>>> -	chip_data->intpol_base = ioremap(res.start, size);
>>> -	if (!chip_data->intpol_base) {
>>> -		pr_err("mtk_sysirq: unable to map sysirq register\n");
>>> -		ret = -ENXIO;
>>> -		goto out_free;
>>> +	if (of_property_read_u32(node, "#intpol-bases", &nr_intpol_bases))
>>> +		nr_intpol_bases = 1;
>>> +
>>> +	chip_data->intpol_words =
>>> +		kcalloc(nr_intpol_bases, sizeof(u32), GFP_KERNEL);
>>
>> Please keep the assignment on a single line.
>>
> 
> Got it, but another warning (prefer 75 char in single line) would pop
> up. Would you still like me to keep it on a single line?

rm scripts/checkpatch.pl

Look, no warning! More seriously, if you're really worried about this,
you can reformat it:

	chip_data->intpol_words = kcalloc(nr_intpol_bases,
					  sizeof(u32), GFP_KERNEL);

like this.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 02/10] irqchip: mtk-sysirq: extend intpol base to arbitrary number
@ 2017-02-09  9:43         ` Marc Zyngier
  0 siblings, 0 replies; 44+ messages in thread
From: Marc Zyngier @ 2017-02-09  9:43 UTC (permalink / raw)
  To: Mars Cheng
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, CC Hwang,
	wsd_upstream-NuS5LvNUpcJWk0Htik3J/w, Will Deacon, Loda Chou,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Jades Shih,
	linux-clk-u79uwXL29TY76Z2rM5mHXA, Miles Chen,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, My Chuang,
	Matthias Brugger, Yingjoe Chen, Thomas Gleixner, Stephen Boyd,
	Chieh-Jay Liu

On 09/02/17 09:31, Mars Cheng wrote:
> On Thu, 2017-02-09 at 09:03 +0000, Marc Zyngier wrote:
>> On 06/02/17 12:15, Mars Cheng wrote:
>>> Originally driver only supports one base. However, MT6797 has
>>> more than one bases to configure interrupt polarity. To support
>>> possible design change, here comes a solution to use arbitrary
>>> number of bases.
>>>
>>> Signed-off-by: Mars Cheng <mars.cheng-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
>>> ---
>>>  drivers/irqchip/irq-mtk-sysirq.c |   71 +++++++++++++++++++++++++++-----------
>>>  1 file changed, 50 insertions(+), 21 deletions(-)
>>>
>>> diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c
>>> index 63ac73b..2645706 100644
>>> --- a/drivers/irqchip/irq-mtk-sysirq.c
>>> +++ b/drivers/irqchip/irq-mtk-sysirq.c
>>> @@ -24,7 +24,9 @@
>>>  
>>>  struct mtk_sysirq_chip_data {
>>>  	spinlock_t lock;
>>> -	void __iomem *intpol_base;
>>> +	u32 nr_intpol_bases;
>>> +	void __iomem **intpol_bases;
>>> +	u32 *intpol_words;
>>>  };
>>>  
>>>  static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
>>> @@ -33,13 +35,15 @@ static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
>>>  	struct mtk_sysirq_chip_data *chip_data = data->chip_data;
>>>  	u32 offset, reg_index, value;
>>>  	unsigned long flags;
>>> -	int ret;
>>> +	int ret, i;
>>>  
>>>  	offset = hwirq & 0x1f;
>>>  	reg_index = hwirq >> 5;
>>> +	for (i = 0; reg_index >= chip_data->intpol_words[i]; i++)
>>> +		reg_index -= chip_data->intpol_words[i];
>>
>> Two questions:
>> - What guarantees that two successive regions deal with consecutive
>> interrupts? For example, if I have region A that deals with interrupts
>> 0-31, what guarantees that region B covers 32-63?
> 
> It is guaranteed by mediatek's chip design team. For those chips with
> multiple bases, they all have the consecutive interrupts in the next
> region.

Hum. OK. We'll see how long this holds true, I suppose.

> 
>> - Given that there is a static relation between a region and a hwirq,
>> can't you compute this relation at init time, and let set_type be a fast
>> path?
>>
> 
> sure, I can do this to optimize set_type. will do it in v3
> 
>>>  
>>>  	spin_lock_irqsave(&chip_data->lock, flags);
>>> -	value = readl_relaxed(chip_data->intpol_base + reg_index * 4);
>>> +	value = readl_relaxed(chip_data->intpol_bases[i] + reg_index * 4);
>>>  	if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_EDGE_FALLING) {
>>>  		if (type == IRQ_TYPE_LEVEL_LOW)
>>>  			type = IRQ_TYPE_LEVEL_HIGH;
>>> @@ -49,7 +53,8 @@ static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
>>>  	} else {
>>>  		value &= ~(1 << offset);
>>>  	}
>>> -	writel(value, chip_data->intpol_base + reg_index * 4);
>>> +
>>> +	writel(value, chip_data->intpol_bases[i] + reg_index * 4);
>>
>> Why do you have a writel here, while you're using relaxed accessors
>> otherwise? Is there anything else that needs to be made visible to the
>> irqchip?
>>
> 
> before we call spin_unlock_irqrestore() in the end of set_type, polarity
> should take effect so we use writel() here. This patch did not change
> the usage.

That's not what I mean. writel has a DSB *before* performing the write
to the device. Do you have any write (to memory) that needs to be made
visible to the irqchip before the write to the register occurs?

Looking at the code, I'd say no. This is a standard device
read-modify-write sequence, no in-memory data that needs to make it
before the write occurs.

So please turn this into a writel_relaxed.

> 
>>>  
>>>  	data = data->parent_data;
>>>  	ret = data->chip->irq_set_type(data, type);
>>> @@ -124,8 +129,7 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
>>>  {
>>>  	struct irq_domain *domain, *domain_parent;
>>>  	struct mtk_sysirq_chip_data *chip_data;
>>> -	int ret, size, intpol_num;
>>> -	struct resource res;
>>> +	int ret, size, intpol_num = 0, nr_intpol_bases, i;
>>>  
>>>  	domain_parent = irq_find_host(parent);
>>>  	if (!domain_parent) {
>>> @@ -133,36 +137,61 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
>>>  		return -EINVAL;
>>>  	}
>>>  
>>> -	ret = of_address_to_resource(node, 0, &res);
>>> -	if (ret)
>>> -		return ret;
>>> -
>>>  	chip_data = kzalloc(sizeof(*chip_data), GFP_KERNEL);
>>>  	if (!chip_data)
>>>  		return -ENOMEM;
>>>  
>>> -	size = resource_size(&res);
>>> -	intpol_num = size * 8;
>>> -	chip_data->intpol_base = ioremap(res.start, size);
>>> -	if (!chip_data->intpol_base) {
>>> -		pr_err("mtk_sysirq: unable to map sysirq register\n");
>>> -		ret = -ENXIO;
>>> -		goto out_free;
>>> +	if (of_property_read_u32(node, "#intpol-bases", &nr_intpol_bases))
>>> +		nr_intpol_bases = 1;
>>> +
>>> +	chip_data->intpol_words =
>>> +		kcalloc(nr_intpol_bases, sizeof(u32), GFP_KERNEL);
>>
>> Please keep the assignment on a single line.
>>
> 
> Got it, but another warning (prefer 75 char in single line) would pop
> up. Would you still like me to keep it on a single line?

rm scripts/checkpatch.pl

Look, no warning! More seriously, if you're really worried about this,
you can reformat it:

	chip_data->intpol_words = kcalloc(nr_intpol_bases,
					  sizeof(u32), GFP_KERNEL);

like this.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 02/10] irqchip: mtk-sysirq: extend intpol base to arbitrary number
@ 2017-02-09  9:49           ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-09  9:49 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Matthias Brugger, CC Hwang, Loda Chou, Miles Chen, Jades Shih,
	Yingjoe Chen, My Chuang, linux-kernel, linux-mediatek,
	devicetree, wsd_upstream, Thomas Gleixner, Will Deacon,
	Stephen Boyd, linux-clk, Chieh-Jay Liu

On Thu, 2017-02-09 at 09:43 +0000, Marc Zyngier wrote:
> On 09/02/17 09:31, Mars Cheng wrote:
> > On Thu, 2017-02-09 at 09:03 +0000, Marc Zyngier wrote:
> >> On 06/02/17 12:15, Mars Cheng wrote:
> >>> Originally driver only supports one base. However, MT6797 has
> >>> more than one bases to configure interrupt polarity. To support
> >>> possible design change, here comes a solution to use arbitrary
> >>> number of bases.
> >>>
> >>> Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
> >>> ---
> >>>  drivers/irqchip/irq-mtk-sysirq.c |   71 +++++++++++++++++++++++++++-----------
> >>>  1 file changed, 50 insertions(+), 21 deletions(-)
> >>>
> >>> diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c
> >>> index 63ac73b..2645706 100644
> >>> --- a/drivers/irqchip/irq-mtk-sysirq.c
> >>> +++ b/drivers/irqchip/irq-mtk-sysirq.c
> >>> @@ -24,7 +24,9 @@
> >>>  
> >>>  struct mtk_sysirq_chip_data {
> >>>  	spinlock_t lock;
> >>> -	void __iomem *intpol_base;
> >>> +	u32 nr_intpol_bases;
> >>> +	void __iomem **intpol_bases;
> >>> +	u32 *intpol_words;
> >>>  };
> >>>  
> >>>  static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
> >>> @@ -33,13 +35,15 @@ static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
> >>>  	struct mtk_sysirq_chip_data *chip_data = data->chip_data;
> >>>  	u32 offset, reg_index, value;
> >>>  	unsigned long flags;
> >>> -	int ret;
> >>> +	int ret, i;
> >>>  
> >>>  	offset = hwirq & 0x1f;
> >>>  	reg_index = hwirq >> 5;
> >>> +	for (i = 0; reg_index >= chip_data->intpol_words[i]; i++)
> >>> +		reg_index -= chip_data->intpol_words[i];
> >>
> >> Two questions:
> >> - What guarantees that two successive regions deal with consecutive
> >> interrupts? For example, if I have region A that deals with interrupts
> >> 0-31, what guarantees that region B covers 32-63?
> > 
> > It is guaranteed by mediatek's chip design team. For those chips with
> > multiple bases, they all have the consecutive interrupts in the next
> > region.
> 
> Hum. OK. We'll see how long this holds true, I suppose.
> 
> > 
> >> - Given that there is a static relation between a region and a hwirq,
> >> can't you compute this relation at init time, and let set_type be a fast
> >> path?
> >>
> > 
> > sure, I can do this to optimize set_type. will do it in v3
> > 
> >>>  
> >>>  	spin_lock_irqsave(&chip_data->lock, flags);
> >>> -	value = readl_relaxed(chip_data->intpol_base + reg_index * 4);
> >>> +	value = readl_relaxed(chip_data->intpol_bases[i] + reg_index * 4);
> >>>  	if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_EDGE_FALLING) {
> >>>  		if (type == IRQ_TYPE_LEVEL_LOW)
> >>>  			type = IRQ_TYPE_LEVEL_HIGH;
> >>> @@ -49,7 +53,8 @@ static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
> >>>  	} else {
> >>>  		value &= ~(1 << offset);
> >>>  	}
> >>> -	writel(value, chip_data->intpol_base + reg_index * 4);
> >>> +
> >>> +	writel(value, chip_data->intpol_bases[i] + reg_index * 4);
> >>
> >> Why do you have a writel here, while you're using relaxed accessors
> >> otherwise? Is there anything else that needs to be made visible to the
> >> irqchip?
> >>
> > 
> > before we call spin_unlock_irqrestore() in the end of set_type, polarity
> > should take effect so we use writel() here. This patch did not change
> > the usage.
> 
> That's not what I mean. writel has a DSB *before* performing the write
> to the device. Do you have any write (to memory) that needs to be made
> visible to the irqchip before the write to the register occurs?
> 
> Looking at the code, I'd say no. This is a standard device
> read-modify-write sequence, no in-memory data that needs to make it
> before the write occurs.
> 
> So please turn this into a writel_relaxed.

Got it, you are right. will fix this in v3.

> 
> > 
> >>>  
> >>>  	data = data->parent_data;
> >>>  	ret = data->chip->irq_set_type(data, type);
> >>> @@ -124,8 +129,7 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
> >>>  {
> >>>  	struct irq_domain *domain, *domain_parent;
> >>>  	struct mtk_sysirq_chip_data *chip_data;
> >>> -	int ret, size, intpol_num;
> >>> -	struct resource res;
> >>> +	int ret, size, intpol_num = 0, nr_intpol_bases, i;
> >>>  
> >>>  	domain_parent = irq_find_host(parent);
> >>>  	if (!domain_parent) {
> >>> @@ -133,36 +137,61 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
> >>>  		return -EINVAL;
> >>>  	}
> >>>  
> >>> -	ret = of_address_to_resource(node, 0, &res);
> >>> -	if (ret)
> >>> -		return ret;
> >>> -
> >>>  	chip_data = kzalloc(sizeof(*chip_data), GFP_KERNEL);
> >>>  	if (!chip_data)
> >>>  		return -ENOMEM;
> >>>  
> >>> -	size = resource_size(&res);
> >>> -	intpol_num = size * 8;
> >>> -	chip_data->intpol_base = ioremap(res.start, size);
> >>> -	if (!chip_data->intpol_base) {
> >>> -		pr_err("mtk_sysirq: unable to map sysirq register\n");
> >>> -		ret = -ENXIO;
> >>> -		goto out_free;
> >>> +	if (of_property_read_u32(node, "#intpol-bases", &nr_intpol_bases))
> >>> +		nr_intpol_bases = 1;
> >>> +
> >>> +	chip_data->intpol_words =
> >>> +		kcalloc(nr_intpol_bases, sizeof(u32), GFP_KERNEL);
> >>
> >> Please keep the assignment on a single line.
> >>
> > 
> > Got it, but another warning (prefer 75 char in single line) would pop
> > up. Would you still like me to keep it on a single line?
> 
> rm scripts/checkpatch.pl
> 
> Look, no warning! More seriously, if you're really worried about this,
> you can reformat it:
> 
> 	chip_data->intpol_words = kcalloc(nr_intpol_bases,
> 					  sizeof(u32), GFP_KERNEL);
> 
> like this.
> 

Got it, will fix it in v3. Thanks. :-)

> Thanks,
> 
> 	M.

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 02/10] irqchip: mtk-sysirq: extend intpol base to arbitrary number
@ 2017-02-09  9:49           ` Mars Cheng
  0 siblings, 0 replies; 44+ messages in thread
From: Mars Cheng @ 2017-02-09  9:49 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, CC Hwang,
	wsd_upstream-NuS5LvNUpcJWk0Htik3J/w, Will Deacon, Loda Chou,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Jades Shih,
	linux-clk-u79uwXL29TY76Z2rM5mHXA, Miles Chen,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, My Chuang,
	Matthias Brugger, Yingjoe Chen, Thomas Gleixner, Stephen Boyd,
	Chieh-Jay Liu

On Thu, 2017-02-09 at 09:43 +0000, Marc Zyngier wrote:
> On 09/02/17 09:31, Mars Cheng wrote:
> > On Thu, 2017-02-09 at 09:03 +0000, Marc Zyngier wrote:
> >> On 06/02/17 12:15, Mars Cheng wrote:
> >>> Originally driver only supports one base. However, MT6797 has
> >>> more than one bases to configure interrupt polarity. To support
> >>> possible design change, here comes a solution to use arbitrary
> >>> number of bases.
> >>>
> >>> Signed-off-by: Mars Cheng <mars.cheng-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> >>> ---
> >>>  drivers/irqchip/irq-mtk-sysirq.c |   71 +++++++++++++++++++++++++++-----------
> >>>  1 file changed, 50 insertions(+), 21 deletions(-)
> >>>
> >>> diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c
> >>> index 63ac73b..2645706 100644
> >>> --- a/drivers/irqchip/irq-mtk-sysirq.c
> >>> +++ b/drivers/irqchip/irq-mtk-sysirq.c
> >>> @@ -24,7 +24,9 @@
> >>>  
> >>>  struct mtk_sysirq_chip_data {
> >>>  	spinlock_t lock;
> >>> -	void __iomem *intpol_base;
> >>> +	u32 nr_intpol_bases;
> >>> +	void __iomem **intpol_bases;
> >>> +	u32 *intpol_words;
> >>>  };
> >>>  
> >>>  static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
> >>> @@ -33,13 +35,15 @@ static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
> >>>  	struct mtk_sysirq_chip_data *chip_data = data->chip_data;
> >>>  	u32 offset, reg_index, value;
> >>>  	unsigned long flags;
> >>> -	int ret;
> >>> +	int ret, i;
> >>>  
> >>>  	offset = hwirq & 0x1f;
> >>>  	reg_index = hwirq >> 5;
> >>> +	for (i = 0; reg_index >= chip_data->intpol_words[i]; i++)
> >>> +		reg_index -= chip_data->intpol_words[i];
> >>
> >> Two questions:
> >> - What guarantees that two successive regions deal with consecutive
> >> interrupts? For example, if I have region A that deals with interrupts
> >> 0-31, what guarantees that region B covers 32-63?
> > 
> > It is guaranteed by mediatek's chip design team. For those chips with
> > multiple bases, they all have the consecutive interrupts in the next
> > region.
> 
> Hum. OK. We'll see how long this holds true, I suppose.
> 
> > 
> >> - Given that there is a static relation between a region and a hwirq,
> >> can't you compute this relation at init time, and let set_type be a fast
> >> path?
> >>
> > 
> > sure, I can do this to optimize set_type. will do it in v3
> > 
> >>>  
> >>>  	spin_lock_irqsave(&chip_data->lock, flags);
> >>> -	value = readl_relaxed(chip_data->intpol_base + reg_index * 4);
> >>> +	value = readl_relaxed(chip_data->intpol_bases[i] + reg_index * 4);
> >>>  	if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_EDGE_FALLING) {
> >>>  		if (type == IRQ_TYPE_LEVEL_LOW)
> >>>  			type = IRQ_TYPE_LEVEL_HIGH;
> >>> @@ -49,7 +53,8 @@ static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
> >>>  	} else {
> >>>  		value &= ~(1 << offset);
> >>>  	}
> >>> -	writel(value, chip_data->intpol_base + reg_index * 4);
> >>> +
> >>> +	writel(value, chip_data->intpol_bases[i] + reg_index * 4);
> >>
> >> Why do you have a writel here, while you're using relaxed accessors
> >> otherwise? Is there anything else that needs to be made visible to the
> >> irqchip?
> >>
> > 
> > before we call spin_unlock_irqrestore() in the end of set_type, polarity
> > should take effect so we use writel() here. This patch did not change
> > the usage.
> 
> That's not what I mean. writel has a DSB *before* performing the write
> to the device. Do you have any write (to memory) that needs to be made
> visible to the irqchip before the write to the register occurs?
> 
> Looking at the code, I'd say no. This is a standard device
> read-modify-write sequence, no in-memory data that needs to make it
> before the write occurs.
> 
> So please turn this into a writel_relaxed.

Got it, you are right. will fix this in v3.

> 
> > 
> >>>  
> >>>  	data = data->parent_data;
> >>>  	ret = data->chip->irq_set_type(data, type);
> >>> @@ -124,8 +129,7 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
> >>>  {
> >>>  	struct irq_domain *domain, *domain_parent;
> >>>  	struct mtk_sysirq_chip_data *chip_data;
> >>> -	int ret, size, intpol_num;
> >>> -	struct resource res;
> >>> +	int ret, size, intpol_num = 0, nr_intpol_bases, i;
> >>>  
> >>>  	domain_parent = irq_find_host(parent);
> >>>  	if (!domain_parent) {
> >>> @@ -133,36 +137,61 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
> >>>  		return -EINVAL;
> >>>  	}
> >>>  
> >>> -	ret = of_address_to_resource(node, 0, &res);
> >>> -	if (ret)
> >>> -		return ret;
> >>> -
> >>>  	chip_data = kzalloc(sizeof(*chip_data), GFP_KERNEL);
> >>>  	if (!chip_data)
> >>>  		return -ENOMEM;
> >>>  
> >>> -	size = resource_size(&res);
> >>> -	intpol_num = size * 8;
> >>> -	chip_data->intpol_base = ioremap(res.start, size);
> >>> -	if (!chip_data->intpol_base) {
> >>> -		pr_err("mtk_sysirq: unable to map sysirq register\n");
> >>> -		ret = -ENXIO;
> >>> -		goto out_free;
> >>> +	if (of_property_read_u32(node, "#intpol-bases", &nr_intpol_bases))
> >>> +		nr_intpol_bases = 1;
> >>> +
> >>> +	chip_data->intpol_words =
> >>> +		kcalloc(nr_intpol_bases, sizeof(u32), GFP_KERNEL);
> >>
> >> Please keep the assignment on a single line.
> >>
> > 
> > Got it, but another warning (prefer 75 char in single line) would pop
> > up. Would you still like me to keep it on a single line?
> 
> rm scripts/checkpatch.pl
> 
> Look, no warning! More seriously, if you're really worried about this,
> you can reformat it:
> 
> 	chip_data->intpol_words = kcalloc(nr_intpol_bases,
> 					  sizeof(u32), GFP_KERNEL);
> 
> like this.
> 

Got it, will fix it in v3. Thanks. :-)

> Thanks,
> 
> 	M.

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 07/10] soc: mediatek: refine scysys for mediatek platforms
  2017-02-06 12:15   ` Mars Cheng
  (?)
@ 2017-02-11 23:15   ` Matthias Brugger
  -1 siblings, 0 replies; 44+ messages in thread
From: Matthias Brugger @ 2017-02-11 23:15 UTC (permalink / raw)
  To: Mars Cheng
  Cc: CC Hwang, Loda Chou, Miles Chen, Jades Shih, Yingjoe Chen,
	My Chuang, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, Marc Zyngier, Thomas Gleixner, Will Deacon,
	Stephen Boyd, linux-clk, Chieh-Jay Liu, Kevin-CW Chen



On 02/06/2017 01:15 PM, Mars Cheng wrote:
> This adds 2 refinements: avoid fixed spm power statue and add vdec item
>

Please be more explicit in the commit message.

> Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
> Signed-off-by: Kevin-CW Chen <kevin-cw.chen@mediatek.com>
> ---
>  drivers/soc/mediatek/mtk-scpsys.c |   35 +++++++++++++++++++++++++++++------
>  1 file changed, 29 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
> index beb7916..a8ba800 100644
> --- a/drivers/soc/mediatek/mtk-scpsys.c
> +++ b/drivers/soc/mediatek/mtk-scpsys.c
> @@ -71,6 +71,7 @@ enum clk_id {
>  	CLK_VENC,
>  	CLK_VENC_LT,
>  	CLK_ETHIF,
> +	CLK_VDEC,
>  	CLK_MAX,
>  };
>
> @@ -81,6 +82,7 @@ enum clk_id {
>  	"venc",
>  	"venc_lt",
>  	"ethif",
> +	"vdec",
>  	NULL,
>  };

Put CLK_VDEC addition in the patch where you add support for mt6797.

Thanks,
Matthias

>
> @@ -107,21 +109,28 @@ struct scp_domain {
>  	struct regulator *supply;
>  };
>
> +struct scp_ctrl_reg {
> +	int pwr_sta_offs;
> +	int pwr_sta2nd_offs;
> +};
> +
>  struct scp {
>  	struct scp_domain *domains;
>  	struct genpd_onecell_data pd_data;
>  	struct device *dev;
>  	void __iomem *base;
>  	struct regmap *infracfg;
> +	struct scp_ctrl_reg ctrl_reg;
>  };
>
>  static int scpsys_domain_is_on(struct scp_domain *scpd)
>  {
>  	struct scp *scp = scpd->scp;
>
> -	u32 status = readl(scp->base + SPM_PWR_STATUS) & scpd->data->sta_mask;
> -	u32 status2 = readl(scp->base + SPM_PWR_STATUS_2ND) &
> -				scpd->data->sta_mask;
> +	u32 status = readl(scp->base + scp->ctrl_reg.pwr_sta_offs) &
> +						scpd->data->sta_mask;
> +	u32 status2 = readl(scp->base + scp->ctrl_reg.pwr_sta2nd_offs) &
> +						scpd->data->sta_mask;
>
>  	/*
>  	 * A domain is on when both status bits are set. If only one is set
> @@ -346,7 +355,8 @@ static void init_clks(struct platform_device *pdev, struct clk **clk)
>  }
>
>  static struct scp *init_scp(struct platform_device *pdev,
> -			const struct scp_domain_data *scp_domain_data, int num)
> +			const struct scp_domain_data *scp_domain_data, int num,
> +			struct scp_ctrl_reg *scp_ctrl_reg)
>  {
>  	struct genpd_onecell_data *pd_data;
>  	struct resource *res;
> @@ -358,6 +368,9 @@ static struct scp *init_scp(struct platform_device *pdev,
>  	if (!scp)
>  		return ERR_PTR(-ENOMEM);
>
> +	scp->ctrl_reg.pwr_sta_offs = scp_ctrl_reg->pwr_sta_offs;
> +	scp->ctrl_reg.pwr_sta2nd_offs = scp_ctrl_reg->pwr_sta2nd_offs;
> +
>  	scp->dev = &pdev->dev;
>
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> @@ -556,8 +569,13 @@ static void mtk_register_power_domains(struct platform_device *pdev,
>  static int __init scpsys_probe_mt2701(struct platform_device *pdev)
>  {
>  	struct scp *scp;
> +	struct scp_ctrl_reg scp_reg;
>
> -	scp = init_scp(pdev, scp_domain_data_mt2701, NUM_DOMAINS_MT2701);
> +	scp_reg.pwr_sta_offs = SPM_PWR_STATUS;
> +	scp_reg.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND;
> +
> +	scp = init_scp(pdev, scp_domain_data_mt2701, NUM_DOMAINS_MT2701,
> +		       &scp_reg);
>  	if (IS_ERR(scp))
>  		return PTR_ERR(scp);
>
> @@ -667,8 +685,13 @@ static int __init scpsys_probe_mt8173(struct platform_device *pdev)
>  	struct scp *scp;
>  	struct genpd_onecell_data *pd_data;
>  	int ret;
> +	struct scp_ctrl_reg scp_reg;
> +
> +	scp_reg.pwr_sta_offs = SPM_PWR_STATUS;
> +	scp_reg.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND;
>
> -	scp = init_scp(pdev, scp_domain_data_mt8173, NUM_DOMAINS_MT8173);
> +	scp = init_scp(pdev, scp_domain_data_mt8173, NUM_DOMAINS_MT8173,
> +		       &scp_reg);
>  	if (IS_ERR(scp))
>  		return PTR_ERR(scp);
>
>

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 06/10] clk: mediatek: add clk support for MT6797
  2017-02-06 12:15   ` Mars Cheng
  (?)
@ 2017-02-11 23:31   ` Matthias Brugger
  -1 siblings, 0 replies; 44+ messages in thread
From: Matthias Brugger @ 2017-02-11 23:31 UTC (permalink / raw)
  To: Mars Cheng
  Cc: CC Hwang, Loda Chou, Miles Chen, Jades Shih, Yingjoe Chen,
	My Chuang, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, Marc Zyngier, Thomas Gleixner, Will Deacon,
	Stephen Boyd, linux-clk, Chieh-Jay Liu, Kevin-CW Chen



On 02/06/2017 01:15 PM, Mars Cheng wrote:
> From: Kevin-CW Chen <kevin-cw.chen@mediatek.com>
>
> Add MT6797 clock support, include topckgen, apmixedsys, infracfg
> and subsystem clocks
>
> Signed-off-by: Kevin-CW Chen <kevin-cw.chen@mediatek.com>
> Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
> ---

Tested-by: Matthias Brugger <matthias.bgg@gmail.com>

>  drivers/clk/mediatek/Kconfig           |   33 ++
>  drivers/clk/mediatek/Makefile          |    5 +
>  drivers/clk/mediatek/clk-mt6797-img.c  |   76 ++++
>  drivers/clk/mediatek/clk-mt6797-mm.c   |  136 ++++++
>  drivers/clk/mediatek/clk-mt6797-vdec.c |   93 +++++
>  drivers/clk/mediatek/clk-mt6797-venc.c |   78 ++++
>  drivers/clk/mediatek/clk-mt6797.c      |  716 ++++++++++++++++++++++++++++++++
>  include/dt-bindings/clock/mt6797-clk.h |  281 +++++++++++++
>  8 files changed, 1418 insertions(+)
>  create mode 100644 drivers/clk/mediatek/clk-mt6797-img.c
>  create mode 100644 drivers/clk/mediatek/clk-mt6797-mm.c
>  create mode 100644 drivers/clk/mediatek/clk-mt6797-vdec.c
>  create mode 100644 drivers/clk/mediatek/clk-mt6797-venc.c
>  create mode 100644 drivers/clk/mediatek/clk-mt6797.c
>  create mode 100644 include/dt-bindings/clock/mt6797-clk.h
>
> diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
> index 0bd631a..4b91eed 100644
> --- a/drivers/clk/mediatek/Kconfig
> +++ b/drivers/clk/mediatek/Kconfig
> @@ -49,6 +49,39 @@ config COMMON_CLK_MT2701_BDPSYS
>  	---help---
>  	  This driver supports Mediatek MT2701 bdpsys clocks.
>
> +config COMMON_CLK_MT6797
> +       bool "Clock driver for Mediatek MT6797"
> +       depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
> +       select COMMON_CLK_MEDIATEK
> +       default ARCH_MEDIATEK && ARM64
> +       ---help---
> +         This driver supports Mediatek MT6797 basic clocks.
> +
> +config COMMON_CLK_MT6797_MMSYS
> +       bool "Clock driver for Mediatek MT6797 mmsys"
> +       depends on COMMON_CLK_MT6797
> +       ---help---
> +         This driver supports Mediatek MT6797 mmsys clocks.
> +
> +config COMMON_CLK_MT6797_IMGSYS
> +       bool "Clock driver for Mediatek MT6797 imgsys"
> +       depends on COMMON_CLK_MT6797
> +       ---help---
> +         This driver supports Mediatek MT6797 imgsys clocks.
> +
> +config COMMON_CLK_MT6797_VDECSYS
> +       bool "Clock driver for Mediatek MT6797 vdecsys"
> +       depends on COMMON_CLK_MT6797
> +       ---help---
> +         This driver supports Mediatek MT6797 vdecsys clocks.
> +
> +config COMMON_CLK_MT6797_VENCSYS
> +       bool "Clock driver for Mediatek MT6797 vencsys"
> +       depends on COMMON_CLK_MT6797
> +       ---help---
> +         This driver supports Mediatek MT6797 vencsys clocks.
> +
> +
>  config COMMON_CLK_MT8135
>  	bool "Clock driver for Mediatek MT8135"
>  	depends on ARCH_MEDIATEK || COMPILE_TEST
> diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
> index 19ae7ef..5c3afb8 100644
> --- a/drivers/clk/mediatek/Makefile
> +++ b/drivers/clk/mediatek/Makefile
> @@ -1,5 +1,10 @@
>  obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o
>  obj-$(CONFIG_RESET_CONTROLLER) += reset.o
> +obj-$(CONFIG_COMMON_CLK_MT6797) += clk-mt6797.o
> +obj-$(CONFIG_COMMON_CLK_MT6797_IMGSYS) += clk-mt6797-img.o
> +obj-$(CONFIG_COMMON_CLK_MT6797_MMSYS) += clk-mt6797-mm.o
> +obj-$(CONFIG_COMMON_CLK_MT6797_VDECSYS) += clk-mt6797-vdec.o
> +obj-$(CONFIG_COMMON_CLK_MT6797_VENCSYS) += clk-mt6797-venc.o
>  obj-$(CONFIG_COMMON_CLK_MT2701) += clk-mt2701.o
>  obj-$(CONFIG_COMMON_CLK_MT2701_BDPSYS) += clk-mt2701-bdp.o
>  obj-$(CONFIG_COMMON_CLK_MT2701_ETHSYS) += clk-mt2701-eth.o
> diff --git a/drivers/clk/mediatek/clk-mt6797-img.c b/drivers/clk/mediatek/clk-mt6797-img.c
> new file mode 100644
> index 0000000..94cc480
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-mt6797-img.c
> @@ -0,0 +1,76 @@
> +/* Copyright (c) 2017 MediaTek Inc.
> + * Author: Kevin Chen <kevin-cw.chen@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/clk-provider.h>
> +#include <linux/platform_device.h>
> +#include <dt-bindings/clock/mt6797-clk.h>
> +
> +#include "clk-mtk.h"
> +#include "clk-gate.h"
> +
> +static const struct mtk_gate_regs img_cg_regs = {
> +	.set_ofs = 0x0004,
> +	.clr_ofs = 0x0008,
> +	.sta_ofs = 0x0000,
> +};
> +
> +#define GATE_IMG(_id, _name, _parent, _shift) {		\
> +		.id = _id,				\
> +		.name = _name,				\
> +		.parent_name = _parent,			\
> +		.regs = &img_cg_regs,			\
> +		.shift = _shift,			\
> +		.ops = &mtk_clk_gate_ops_setclr,	\
> +	}
> +
> +static const struct mtk_gate img_clks[] = {
> +	GATE_IMG(CLK_IMG_FDVT, "img_fdvt", "mm_sel", 11),
> +	GATE_IMG(CLK_IMG_DPE, "img_dpe", "mm_sel", 10),
> +	GATE_IMG(CLK_IMG_DIP, "img_dip", "mm_sel", 6),
> +	GATE_IMG(CLK_IMG_LARB6, "img_larb6", "mm_sel", 0),
> +};
> +
> +static const struct of_device_id of_match_clk_mt6797_img[] = {
> +	{ .compatible = "mediatek,mt6797-imgsys", },
> +	{}
> +};
> +
> +static int clk_mt6797_img_probe(struct platform_device *pdev)
> +{
> +	struct clk_onecell_data *clk_data;
> +	int r;
> +	struct device_node *node = pdev->dev.of_node;
> +
> +	clk_data = mtk_alloc_clk_data(CLK_IMG_NR);
> +
> +	mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks),
> +			       clk_data);
> +
> +	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> +	if (r)
> +		dev_err(&pdev->dev,
> +			"could not register clock provider: %s: %d\n",
> +			pdev->name, r);
> +
> +	return r;
> +}
> +
> +static struct platform_driver clk_mt6797_img_drv = {
> +	.probe = clk_mt6797_img_probe,
> +	.driver = {
> +		.name = "clk-mt6797-img",
> +		.of_match_table = of_match_clk_mt6797_img,
> +	},
> +};
> +
> +builtin_platform_driver(clk_mt6797_img_drv);
> diff --git a/drivers/clk/mediatek/clk-mt6797-mm.c b/drivers/clk/mediatek/clk-mt6797-mm.c
> new file mode 100644
> index 0000000..c57d3ee
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-mt6797-mm.c
> @@ -0,0 +1,136 @@
> +/*
> + * Copyright (c) 2017 MediaTek Inc.
> + * Author: Kevin Chen <kevin-cw.chen@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/clk-provider.h>
> +#include <linux/platform_device.h>
> +#include <dt-bindings/clock/mt6797-clk.h>
> +
> +#include "clk-mtk.h"
> +#include "clk-gate.h"
> +
> +static const struct mtk_gate_regs mm0_cg_regs = {
> +	.set_ofs = 0x0104,
> +	.clr_ofs = 0x0108,
> +	.sta_ofs = 0x0100,
> +};
> +
> +static const struct mtk_gate_regs mm1_cg_regs = {
> +	.set_ofs = 0x0114,
> +	.clr_ofs = 0x0118,
> +	.sta_ofs = 0x0110,
> +};
> +
> +#define GATE_MM0(_id, _name, _parent, _shift) {			\
> +	.id = _id,					\
> +	.name = _name,					\
> +	.parent_name = _parent,				\
> +	.regs = &mm0_cg_regs,				\
> +	.shift = _shift,				\
> +	.ops = &mtk_clk_gate_ops_setclr,		\
> +}
> +
> +#define GATE_MM1(_id, _name, _parent, _shift) {			\
> +	.id = _id,					\
> +	.name = _name,					\
> +	.parent_name = _parent,				\
> +	.regs = &mm1_cg_regs,				\
> +	.shift = _shift,				\
> +	.ops = &mtk_clk_gate_ops_setclr,		\
> +}
> +
> +static const struct mtk_gate mm_clks[] = {
> +	GATE_MM0(CLK_MM_SMI_COMMON, "mm_smi_common", "mm_sel", 0),
> +	GATE_MM0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1),
> +	GATE_MM0(CLK_MM_SMI_LARB5, "mm_smi_larb5", "mm_sel", 2),
> +	GATE_MM0(CLK_MM_CAM_MDP, "mm_cam_mdp", "mm_sel", 3),
> +	GATE_MM0(CLK_MM_MDP_RDMA0, "mm_mdp_rdma0", "mm_sel", 4),
> +	GATE_MM0(CLK_MM_MDP_RDMA1, "mm_mdp_rdma1", "mm_sel", 5),
> +	GATE_MM0(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "mm_sel", 6),
> +	GATE_MM0(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "mm_sel", 7),
> +	GATE_MM0(CLK_MM_MDP_RSZ2, "mm_mdp_rsz2", "mm_sel", 8),
> +	GATE_MM0(CLK_MM_MDP_TDSHP, "mm_mdp_tdshp", "mm_sel", 9),
> +	GATE_MM0(CLK_MM_MDP_COLOR, "mm_mdp_color", "mm_sel", 10),
> +	GATE_MM0(CLK_MM_MDP_WDMA, "mm_mdp_wdma", "mm_sel", 11),
> +	GATE_MM0(CLK_MM_MDP_WROT0, "mm_mdp_wrot0", "mm_sel", 12),
> +	GATE_MM0(CLK_MM_MDP_WROT1, "mm_mdp_wrot1", "mm_sel", 13),
> +	GATE_MM0(CLK_MM_FAKE_ENG, "mm_fake_eng", "mm_sel", 14),
> +	GATE_MM0(CLK_MM_DISP_OVL0, "mm_disp_ovl0", "mm_sel", 15),
> +	GATE_MM0(CLK_MM_DISP_OVL1, "mm_disp_ovl1", "mm_sel", 16),
> +	GATE_MM0(CLK_MM_DISP_OVL0_2L, "mm_disp_ovl0_2l", "mm_sel", 17),
> +	GATE_MM0(CLK_MM_DISP_OVL1_2L, "mm_disp_ovl1_2l", "mm_sel", 18),
> +	GATE_MM0(CLK_MM_DISP_RDMA0, "mm_disp_rdma0", "mm_sel", 19),
> +	GATE_MM0(CLK_MM_DISP_RDMA1, "mm_disp_rdma1", "mm_sel", 20),
> +	GATE_MM0(CLK_MM_DISP_WDMA0, "mm_disp_wdma0", "mm_sel", 21),
> +	GATE_MM0(CLK_MM_DISP_WDMA1, "mm_disp_wdma1", "mm_sel", 22),
> +	GATE_MM0(CLK_MM_DISP_COLOR, "mm_disp_color", "mm_sel", 23),
> +	GATE_MM0(CLK_MM_DISP_CCORR, "mm_disp_ccorr", "mm_sel", 24),
> +	GATE_MM0(CLK_MM_DISP_AAL, "mm_disp_aal", "mm_sel", 25),
> +	GATE_MM0(CLK_MM_DISP_GAMMA, "mm_disp_gamma", "mm_sel", 26),
> +	GATE_MM0(CLK_MM_DISP_OD, "mm_disp_od", "mm_sel", 27),
> +	GATE_MM0(CLK_MM_DISP_DITHER, "mm_disp_dither", "mm_sel", 28),
> +	GATE_MM0(CLK_MM_DISP_UFOE, "mm_disp_ufoe", "mm_sel", 29),
> +	GATE_MM0(CLK_MM_DISP_DSC, "mm_disp_dsc", "mm_sel", 30),
> +	GATE_MM0(CLK_MM_DISP_SPLIT, "mm_disp_split", "mm_sel", 31),
> +	GATE_MM1(CLK_MM_DSI0_MM_CLOCK, "mm_dsi0_mm_clock", "mm_sel", 0),
> +	GATE_MM1(CLK_MM_DSI1_MM_CLOCK, "mm_dsi1_mm_clock", "mm_sel", 2),
> +	GATE_MM1(CLK_MM_DPI_MM_CLOCK, "mm_dpi_mm_clock", "mm_sel", 4),
> +	GATE_MM1(CLK_MM_DPI_INTERFACE_CLOCK, "mm_dpi_interface_clock",
> +		 "dpi0_sel", 5),
> +	GATE_MM1(CLK_MM_LARB4_AXI_ASIF_MM_CLOCK, "mm_larb4_axi_asif_mm_clock",
> +		 "mm_sel", 6),
> +	GATE_MM1(CLK_MM_LARB4_AXI_ASIF_MJC_CLOCK, "mm_larb4_axi_asif_mjc_clock",
> +		 "mjc_sel", 7),
> +	GATE_MM1(CLK_MM_DISP_OVL0_MOUT_CLOCK, "mm_disp_ovl0_mout_clock",
> +		 "mm_sel", 8),
> +	GATE_MM1(CLK_MM_FAKE_ENG2, "mm_fake_eng2", "mm_sel", 9),
> +	GATE_MM1(CLK_MM_DSI0_INTERFACE_CLOCK, "mm_dsi0_interface_clock",
> +		 "clk26m", 1),
> +	GATE_MM1(CLK_MM_DSI1_INTERFACE_CLOCK, "mm_dsi1_interface_clock",
> +		 "clk26m", 3),
> +};
> +
> +static const struct of_device_id of_match_clk_mt6797_mm[] = {
> +	{ .compatible = "mediatek,mt6797-mmsys", },
> +	{}
> +};
> +
> +static int clk_mt6797_mm_probe(struct platform_device *pdev)
> +{
> +	struct clk_onecell_data *clk_data;
> +	int r;
> +	struct device_node *node = pdev->dev.of_node;
> +
> +	clk_data = mtk_alloc_clk_data(CLK_MM_NR);
> +
> +	mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks),
> +			       clk_data);
> +
> +	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> +	if (r)
> +		dev_err(&pdev->dev,
> +			"could not register clock provider: %s: %d\n",
> +			pdev->name, r);
> +
> +	return r;
> +}
> +
> +static struct platform_driver clk_mt6797_mm_drv = {
> +	.probe = clk_mt6797_mm_probe,
> +	.driver = {
> +		.name = "clk-mt6797-mm",
> +		.of_match_table = of_match_clk_mt6797_mm,
> +	},
> +};
> +
> +builtin_platform_driver(clk_mt6797_mm_drv);
> diff --git a/drivers/clk/mediatek/clk-mt6797-vdec.c b/drivers/clk/mediatek/clk-mt6797-vdec.c
> new file mode 100644
> index 0000000..7c402ca
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-mt6797-vdec.c
> @@ -0,0 +1,93 @@
> +/*
> + * Copyright (c) 2017 MediaTek Inc.
> + * Author: Kevin-CW Chen <kevin-cw.chen@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/clk-provider.h>
> +#include <linux/platform_device.h>
> +
> +#include "clk-mtk.h"
> +#include "clk-gate.h"
> +
> +#include <dt-bindings/clock/mt6797-clk.h>
> +
> +static const struct mtk_gate_regs vdec0_cg_regs = {
> +	.set_ofs = 0x0000,
> +	.clr_ofs = 0x0004,
> +	.sta_ofs = 0x0000,
> +};
> +
> +static const struct mtk_gate_regs vdec1_cg_regs = {
> +	.set_ofs = 0x0008,
> +	.clr_ofs = 0x000c,
> +	.sta_ofs = 0x0008,
> +};
> +
> +#define GATE_VDEC0(_id, _name, _parent, _shift) {		\
> +	.id = _id,					\
> +	.name = _name,					\
> +	.parent_name = _parent,				\
> +	.regs = &vdec0_cg_regs,				\
> +	.shift = _shift,				\
> +	.ops = &mtk_clk_gate_ops_setclr_inv,		\
> +}
> +
> +#define GATE_VDEC1(_id, _name, _parent, _shift) {		\
> +	.id = _id,					\
> +	.name = _name,					\
> +	.parent_name = _parent,				\
> +	.regs = &vdec1_cg_regs,				\
> +	.shift = _shift,				\
> +	.ops = &mtk_clk_gate_ops_setclr_inv,		\
> +}
> +
> +static const struct mtk_gate vdec_clks[] = {
> +	GATE_VDEC0(CLK_VDEC_CKEN_ENG, "vdec_cken_eng", "vdec_sel", 8),
> +	GATE_VDEC0(CLK_VDEC_ACTIVE, "vdec_active", "vdec_sel", 4),
> +	GATE_VDEC0(CLK_VDEC_CKEN, "vdec_cken", "vdec_sel", 0),
> +	GATE_VDEC1(CLK_VDEC_LARB1_CKEN, "vdec_larb1_cken", "mm_sel", 0),
> +};
> +
> +static const struct of_device_id of_match_clk_mt6797_vdec[] = {
> +	{ .compatible = "mediatek,mt6797-vdecsys", },
> +	{}
> +};
> +
> +static int clk_mt6797_vdec_probe(struct platform_device *pdev)
> +{
> +	struct clk_onecell_data *clk_data;
> +	int r;
> +	struct device_node *node = pdev->dev.of_node;
> +
> +	clk_data = mtk_alloc_clk_data(CLK_VDEC_NR);
> +
> +	mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks),
> +			       clk_data);
> +
> +	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> +	if (r)
> +		dev_err(&pdev->dev,
> +			"could not register clock provider: %s: %d\n",
> +			pdev->name, r);
> +
> +	return r;
> +}
> +
> +static struct platform_driver clk_mt6797_vdec_drv = {
> +	.probe = clk_mt6797_vdec_probe,
> +	.driver = {
> +		.name = "clk-mt6797-vdec",
> +		.of_match_table = of_match_clk_mt6797_vdec,
> +	},
> +};
> +
> +builtin_platform_driver(clk_mt6797_vdec_drv);
> diff --git a/drivers/clk/mediatek/clk-mt6797-venc.c b/drivers/clk/mediatek/clk-mt6797-venc.c
> new file mode 100644
> index 0000000..e73d517
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-mt6797-venc.c
> @@ -0,0 +1,78 @@
> +/*
> + * Copyright (c) 2017 MediaTek Inc.
> + * Author: Kevin Chen <kevin-cw.chen@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/clk-provider.h>
> +#include <linux/platform_device.h>
> +
> +#include "clk-mtk.h"
> +#include "clk-gate.h"
> +
> +#include <dt-bindings/clock/mt6797-clk.h>
> +
> +static const struct mtk_gate_regs venc_cg_regs = {
> +	.set_ofs = 0x0004,
> +	.clr_ofs = 0x0008,
> +	.sta_ofs = 0x0000,
> +};
> +
> +#define GATE_VENC(_id, _name, _parent, _shift) {	\
> +		.id = _id,				\
> +		.name = _name,				\
> +		.parent_name = _parent,			\
> +		.regs = &venc_cg_regs,			\
> +		.shift = _shift,			\
> +		.ops = &mtk_clk_gate_ops_setclr_inv,	\
> +	}
> +
> +static const struct mtk_gate venc_clks[] = {
> +	GATE_VENC(CLK_VENC_0, "venc_0", "mm_sel", 0),
> +	GATE_VENC(CLK_VENC_1, "venc_1", "venc_sel", 4),
> +	GATE_VENC(CLK_VENC_2, "venc_2", "venc_sel", 8),
> +	GATE_VENC(CLK_VENC_3, "venc_3", "venc_sel", 12),
> +};
> +
> +static const struct of_device_id of_match_clk_mt6797_venc[] = {
> +	{ .compatible = "mediatek,mt6797-vencsys", },
> +	{}
> +};
> +
> +static int clk_mt6797_venc_probe(struct platform_device *pdev)
> +{
> +	struct clk_onecell_data *clk_data;
> +	int r;
> +	struct device_node *node = pdev->dev.of_node;
> +
> +	clk_data = mtk_alloc_clk_data(CLK_VENC_NR);
> +
> +	mtk_clk_register_gates(node, venc_clks, ARRAY_SIZE(venc_clks),
> +			       clk_data);
> +
> +	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> +	if (r)
> +		dev_err(&pdev->dev,
> +			"could not register clock provider: %s: %d\n",
> +			pdev->name, r);
> +
> +	return r;
> +}
> +
> +static struct platform_driver clk_mt6797_venc_drv = {
> +	.probe = clk_mt6797_venc_probe,
> +	.driver = {
> +		.name = "clk-mt6797-venc",
> +		.of_match_table = of_match_clk_mt6797_venc,
> +	},
> +};
> +
> +builtin_platform_driver(clk_mt6797_venc_drv);
> diff --git a/drivers/clk/mediatek/clk-mt6797.c b/drivers/clk/mediatek/clk-mt6797.c
> new file mode 100644
> index 0000000..7ebb7f1
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-mt6797.c
> @@ -0,0 +1,716 @@
> +/*
> + * Copyright (c) 2016 MediaTek Inc.
> + * Author: Kevin Chen <kevin-cw.chen@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/clk.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +
> +#include "clk-mtk.h"
> +#include "clk-gate.h"
> +
> +#include <dt-bindings/clock/mt6797-clk.h>
> +
> +/*
> + * For some clocks, we don't care what their actual rates are. And these
> + * clocks may change their rate on different products or different scenarios.
> + * So we model these clocks' rate as 0, to denote it's not an actual rate.
> + */
> +
> +static DEFINE_SPINLOCK(mt6797_clk_lock);
> +
> +static const struct mtk_fixed_factor top_fixed_divs[] = {
> +	FACTOR(CLK_TOP_SYSPLL_CK, "syspll_ck", "mainpll", 1, 1),
> +	FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "mainpll", 1, 2),
> +	FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "syspll_d2", 1, 2),
> +	FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "syspll_d2", 1, 4),
> +	FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "syspll_d2", 1, 8),
> +	FACTOR(CLK_TOP_SYSPLL1_D16, "syspll1_d16", "syspll_d2", 1, 16),
> +	FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "mainpll", 1, 3),
> +	FACTOR(CLK_TOP_SYSPLL_D3_D3, "syspll_d3_d3", "syspll_d3", 1, 3),
> +	FACTOR(CLK_TOP_SYSPLL2_D2, "syspll2_d2", "syspll_d3", 1, 2),
> +	FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "syspll_d3", 1, 4),
> +	FACTOR(CLK_TOP_SYSPLL2_D8, "syspll2_d8", "syspll_d3", 1, 8),
> +	FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll", 1, 5),
> +	FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "syspll_d5", 1, 2),
> +	FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "syspll_d5", 1, 4),
> +	FACTOR(CLK_TOP_SYSPLL_D7, "syspll_d7", "mainpll", 1, 7),
> +	FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "syspll_d7", 1, 2),
> +	FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "syspll_d7", 1, 4),
> +	FACTOR(CLK_TOP_UNIVPLL_CK, "univpll_ck", "univpll", 1, 1),
> +	FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll", 1, 7),
> +	FACTOR(CLK_TOP_UNIVPLL_D26, "univpll_d26", "univpll", 1, 26),
> +	FACTOR(CLK_TOP_SSUSB_PHY_48M_CK, "ssusb_phy_48m_ck", "univpll", 1, 1),
> +	FACTOR(CLK_TOP_USB_PHY48M_CK, "usb_phy48m_ck", "univpll", 1, 1),
> +	FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll", 1, 2),
> +	FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_d2", 1, 2),
> +	FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_d2", 1, 4),
> +	FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_d2", 1, 8),
> +	FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll", 1, 3),
> +	FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll", 1, 2),
> +	FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll", 1, 4),
> +	FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll", 1, 8),
> +	FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5),
> +	FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2", "univpll_d5", 1, 2),
> +	FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4", "univpll_d5", 1, 4),
> +	FACTOR(CLK_TOP_UNIVPLL3_D8, "univpll3_d8", "univpll_d5", 1, 8),
> +	FACTOR(CLK_TOP_ULPOSC_CK_ORG, "ulposc_ck_org", "ulposc", 1, 1),
> +	FACTOR(CLK_TOP_ULPOSC_CK, "ulposc_ck", "ulposc_ck_org", 1, 3),
> +	FACTOR(CLK_TOP_ULPOSC_D2, "ulposc_d2", "ulposc_ck", 1, 2),
> +	FACTOR(CLK_TOP_ULPOSC_D3, "ulposc_d3", "ulposc_ck", 1, 4),
> +	FACTOR(CLK_TOP_ULPOSC_D4, "ulposc_d4", "ulposc_ck", 1, 8),
> +	FACTOR(CLK_TOP_ULPOSC_D8, "ulposc_d8", "ulposc_ck", 1, 10),
> +	FACTOR(CLK_TOP_ULPOSC_D10, "ulposc_d10", "ulposc_ck_org", 1, 1),
> +	FACTOR(CLK_TOP_APLL1_CK, "apll1_ck", "apll1", 1, 1),
> +	FACTOR(CLK_TOP_APLL2_CK, "apll2_ck", "apll2", 1, 1),
> +	FACTOR(CLK_TOP_MFGPLL_CK, "mfgpll_ck", "mfgpll", 1, 1),
> +	FACTOR(CLK_TOP_MFGPLL_D2, "mfgpll_d2", "mfgpll_ck", 1, 2),
> +	FACTOR(CLK_TOP_IMGPLL_CK, "imgpll_ck", "imgpll", 1, 1),
> +	FACTOR(CLK_TOP_IMGPLL_D2, "imgpll_d2", "imgpll_ck", 1, 2),
> +	FACTOR(CLK_TOP_IMGPLL_D4, "imgpll_d4", "imgpll_ck", 1, 4),
> +	FACTOR(CLK_TOP_CODECPLL_CK, "codecpll_ck", "codecpll", 1, 1),
> +	FACTOR(CLK_TOP_CODECPLL_D2, "codecpll_d2", "codecpll_ck", 1, 2),
> +	FACTOR(CLK_TOP_VDECPLL_CK, "vdecpll_ck", "vdecpll", 1, 1),
> +	FACTOR(CLK_TOP_TVDPLL_CK, "tvdpll_ck", "tvdpll", 1, 1),
> +	FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll_ck", 1, 2),
> +	FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll_ck", 1, 4),
> +	FACTOR(CLK_TOP_TVDPLL_D8, "tvdpll_d8", "tvdpll_ck", 1, 8),
> +	FACTOR(CLK_TOP_TVDPLL_D16, "tvdpll_d16", "tvdpll_ck", 1, 16),
> +	FACTOR(CLK_TOP_MSDCPLL_CK, "msdcpll_ck", "msdcpll", 1, 1),
> +	FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll_ck", 1, 2),
> +	FACTOR(CLK_TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll_ck", 1, 4),
> +	FACTOR(CLK_TOP_MSDCPLL_D8, "msdcpll_d8", "msdcpll_ck", 1, 8),
> +};
> +
> +static const char * const axi_parents[] = {
> +	"clk26m",
> +	"syspll_d7",
> +	"ulposc_axi_ck_mux",
> +};
> +
> +static const char * const ulposc_axi_ck_mux_parents[] = {
> +	"syspll1_d4",
> +	"ulposc_axi_ck_mux_pre",
> +};
> +
> +static const char * const ulposc_axi_ck_mux_pre_parents[] = {
> +	"ulposc_d2",
> +	"ulposc_d3",
> +};
> +
> +static const char * const ddrphycfg_parents[] = {
> +	"clk26m",
> +	"syspll3_d2",
> +	"syspll2_d4",
> +	"syspll1_d8",
> +};
> +
> +static const char * const mm_parents[] = {
> +	"clk26m",
> +	"imgpll_ck",
> +	"univpll1_d2",
> +	"syspll1_d2",
> +};
> +
> +static const char * const pwm_parents[] = {
> +	"clk26m",
> +	"univpll2_d4",
> +	"ulposc_d2",
> +	"ulposc_d3",
> +	"ulposc_d8",
> +	"ulposc_d10",
> +	"ulposc_d4",
> +};
> +
> +static const char * const vdec_parents[] = {
> +	"clk26m",
> +	"vdecpll_ck",
> +	"imgpll_ck",
> +	"syspll_d3",
> +	"univpll_d5",
> +	"clk26m",
> +	"clk26m",
> +};
> +
> +static const char * const venc_parents[] = {
> +	"clk26m",
> +	"codecpll_ck",
> +	"syspll_d3",
> +};
> +
> +static const char * const mfg_parents[] = {
> +	"clk26m",
> +	"mfgpll_ck",
> +	"syspll_d3",
> +	"univpll_d3",
> +};
> +
> +static const char * const camtg[] = {
> +	"clk26m",
> +	"univpll_d26",
> +	"univpll2_d2",
> +};
> +
> +static const char * const uart_parents[] = {
> +	"clk26m",
> +	"univpll2_d8",
> +};
> +
> +static const char * const spi_parents[] = {
> +	"clk26m",
> +	"syspll3_d2",
> +	"syspll2_d4",
> +	"ulposc_spi_ck_mux",
> +};
> +
> +static const char * const ulposc_spi_ck_mux_parents[] = {
> +	"ulposc_d2",
> +	"ulposc_d3",
> +};
> +
> +static const char * const usb20_parents[] = {
> +	"clk26m",
> +	"univpll1_d8",
> +	"syspll4_d2",
> +};
> +
> +static const char * const msdc50_0_hclk_parents[] = {
> +	"clk26m",
> +	"syspll1_d2",
> +	"syspll2_d2",
> +	"syspll4_d2",
> +};
> +
> +static const char * const msdc50_0_parents[] = {
> +	"clk26m",
> +	"msdcpll",
> +	"syspll_d3",
> +	"univpll1_d4",
> +	"syspll2_d2",
> +	"syspll_d7",
> +	"msdcpll_d2",
> +	"univpll1_d2",
> +	"univpll_d3",
> +};
> +
> +static const char * const msdc30_1_parents[] = {
> +	"clk26m",
> +	"univpll2_d2",
> +	"msdcpll_d2",
> +	"univpll1_d4",
> +	"syspll2_d2",
> +	"syspll_d7",
> +	"univpll_d7",
> +};
> +
> +static const char * const msdc30_2_parents[] = {
> +	"clk26m",
> +	"univpll2_d8",
> +	"syspll2_d8",
> +	"syspll1_d8",
> +	"msdcpll_d8",
> +	"syspll3_d4",
> +	"univpll_d26",
> +};
> +
> +static const char * const audio_parents[] = {
> +	"clk26m",
> +	"syspll3_d4",
> +	"syspll4_d4",
> +	"syspll1_d16",
> +};
> +
> +static const char * const aud_intbus_parents[] = {
> +	"clk26m",
> +	"syspll1_d4",
> +	"syspll4_d2",
> +};
> +
> +static const char * const pmicspi_parents[] = {
> +	"clk26m",
> +	"univpll_d26",
> +	"syspll3_d4",
> +	"syspll1_d8",
> +	"ulposc_d4",
> +	"ulposc_d8",
> +	"syspll2_d8",
> +};
> +
> +static const char * const scp_parents[] = {
> +	"clk26m",
> +	"syspll_d3",
> +	"ulposc_ck",
> +	"univpll_d5",
> +};
> +
> +static const char * const atb_parents[] = {
> +	"clk26m",
> +	"syspll1_d2",
> +	"syspll_d5",
> +};
> +
> +static const char * const mjc_parents[] = {
> +	"clk26m",
> +	"imgpll_ck",
> +	"univpll_d5",
> +	"syspll1_d2",
> +};
> +
> +static const char * const dpi0_parents[] = {
> +	"clk26m",
> +	"tvdpll_d2",
> +	"tvdpll_d4",
> +	"tvdpll_d8",
> +	"tvdpll_d16",
> +	"clk26m",
> +	"clk26m",
> +};
> +
> +static const char * const aud_1_parents[] = {
> +	"clk26m",
> +	"apll1_ck",
> +};
> +
> +static const char * const aud_2_parents[] = {
> +	"clk26m",
> +	"apll2_ck",
> +};
> +
> +static const char * const ssusb_top_sys_parents[] = {
> +	"clk26m",
> +	"univpll3_d2",
> +};
> +
> +static const char * const spm_parents[] = {
> +	"clk26m",
> +	"syspll1_d8",
> +};
> +
> +static const char * const bsi_spi_parents[] = {
> +	"clk26m",
> +	"syspll_d3_d3",
> +	"syspll1_d4",
> +	"syspll_d7",
> +};
> +
> +static const char * const audio_h_parents[] = {
> +	"clk26m",
> +	"apll2_ck",
> +	"apll1_ck",
> +	"univpll_d7",
> +};
> +
> +static const char * const mfg_52m_parents[] = {
> +	"clk26m",
> +	"univpll2_d8",
> +	"univpll2_d4",
> +	"univpll2_d4",
> +};
> +
> +static const char * const anc_md32_parents[] = {
> +	"clk26m",
> +	"syspll1_d2",
> +	"univpll_d5",
> +};
> +
> +static const struct mtk_composite top_muxes[] = {
> +	MUX(CLK_TOP_MUX_ULPOSC_AXI_CK_MUX_PRE, "ulposc_axi_ck_mux_pre",
> +	    ulposc_axi_ck_mux_pre_parents, 0x0040, 3, 1),
> +	MUX(CLK_TOP_MUX_ULPOSC_AXI_CK_MUX, "ulposc_axi_ck_mux",
> +	    ulposc_axi_ck_mux_parents, 0x0040, 2, 1),
> +	MUX(CLK_TOP_MUX_AXI, "axi_sel", axi_parents,
> +	    0x0040, 0, 2),
> +	MUX(CLK_TOP_MUX_DDRPHYCFG, "ddrphycfg_sel", ddrphycfg_parents,
> +	    0x0040, 16, 2),
> +	MUX(CLK_TOP_MUX_MM, "mm_sel", mm_parents,
> +	    0x0040, 24, 2),
> +	MUX_GATE(CLK_TOP_MUX_PWM, "pwm_sel", pwm_parents, 0x0050, 0, 3, 7),
> +	MUX_GATE(CLK_TOP_MUX_VDEC, "vdec_sel", vdec_parents, 0x0050, 8, 3, 15),
> +	MUX_GATE(CLK_TOP_MUX_VENC, "venc_sel", venc_parents, 0x0050, 16, 2, 23),
> +	MUX_GATE(CLK_TOP_MUX_MFG, "mfg_sel", mfg_parents, 0x0050, 24, 2, 31),
> +	MUX_GATE(CLK_TOP_MUX_CAMTG, "camtg_sel", camtg, 0x0060, 0, 2, 7),
> +	MUX_GATE(CLK_TOP_MUX_UART, "uart_sel", uart_parents, 0x0060, 8, 1, 15),
> +	MUX_GATE(CLK_TOP_MUX_SPI, "spi_sel", spi_parents, 0x0060, 16, 2, 23),
> +	MUX(CLK_TOP_MUX_ULPOSC_SPI_CK_MUX, "ulposc_spi_ck_mux",
> +	    ulposc_spi_ck_mux_parents, 0x0060, 18, 1),
> +	MUX_GATE(CLK_TOP_MUX_USB20, "usb20_sel", usb20_parents,
> +		 0x0060, 24, 2, 31),
> +	MUX(CLK_TOP_MUX_MSDC50_0_HCLK, "msdc50_0_hclk_sel",
> +	    msdc50_0_hclk_parents, 0x0070, 8, 2),
> +	MUX_GATE(CLK_TOP_MUX_MSDC50_0, "msdc50_0_sel", msdc50_0_parents,
> +		 0x0070, 16, 4, 23),
> +	MUX_GATE(CLK_TOP_MUX_MSDC30_1, "msdc30_1_sel", msdc30_1_parents,
> +		 0x0070, 24, 3, 31),
> +	MUX_GATE(CLK_TOP_MUX_MSDC30_2, "msdc30_2_sel", msdc30_2_parents,
> +		 0x0080, 0, 3, 7),
> +	MUX_GATE(CLK_TOP_MUX_AUDIO, "audio_sel", audio_parents,
> +		 0x0080, 16, 2, 23),
> +	MUX(CLK_TOP_MUX_AUD_INTBUS, "aud_intbus_sel", aud_intbus_parents,
> +	    0x0080, 24, 2),
> +	MUX(CLK_TOP_MUX_PMICSPI, "pmicspi_sel", pmicspi_parents,
> +	    0x0090, 0, 3),
> +	MUX(CLK_TOP_MUX_SCP, "scp_sel", scp_parents,
> +	    0x0090, 8, 2),
> +	MUX(CLK_TOP_MUX_ATB, "atb_sel", atb_parents,
> +	    0x0090, 16, 2),
> +	MUX_GATE(CLK_TOP_MUX_MJC, "mjc_sel", mjc_parents, 0x0090, 24, 2, 31),
> +	MUX_GATE(CLK_TOP_MUX_DPI0, "dpi0_sel", dpi0_parents, 0x00A0, 0, 3, 7),
> +	MUX_GATE(CLK_TOP_MUX_AUD_1, "aud_1_sel", aud_1_parents,
> +		 0x00A0, 16, 1, 23),
> +	MUX_GATE(CLK_TOP_MUX_AUD_2, "aud_2_sel", aud_2_parents,
> +		 0x00A0, 24, 1, 31),
> +	MUX(CLK_TOP_MUX_SSUSB_TOP_SYS, "ssusb_top_sys_sel",
> +	    ssusb_top_sys_parents, 0x00B0, 8, 1),
> +	MUX(CLK_TOP_MUX_SPM, "spm_sel", spm_parents,
> +	    0x00C0, 0, 1),
> +	MUX(CLK_TOP_MUX_BSI_SPI, "bsi_spi_sel", bsi_spi_parents,
> +	    0x00C0, 8, 2),
> +	MUX_GATE(CLK_TOP_MUX_AUDIO_H, "audio_h_sel", audio_h_parents,
> +		 0x00C0, 16, 2, 23),
> +	MUX_GATE(CLK_TOP_MUX_ANC_MD32, "anc_md32_sel", anc_md32_parents,
> +		 0x00C0, 24, 2, 31),
> +	MUX(CLK_TOP_MUX_MFG_52M, "mfg_52m_sel", mfg_52m_parents,
> +	    0x0104, 1, 2),
> +};
> +
> +static int mtk_topckgen_init(struct platform_device *pdev)
> +{
> +	struct clk_onecell_data *clk_data;
> +	void __iomem *base;
> +	struct device_node *node = pdev->dev.of_node;
> +	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +
> +	base = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(base))
> +		return PTR_ERR(base);
> +
> +	clk_data = mtk_alloc_clk_data(CLK_TOP_NR);
> +
> +	mtk_clk_register_factors(top_fixed_divs, ARRAY_SIZE(top_fixed_divs),
> +				 clk_data);
> +
> +	mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
> +				    &mt6797_clk_lock, clk_data);
> +
> +	return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> +}
> +
> +static const struct mtk_gate_regs infra0_cg_regs = {
> +	.set_ofs = 0x0080,
> +	.clr_ofs = 0x0084,
> +	.sta_ofs = 0x0090,
> +};
> +
> +static const struct mtk_gate_regs infra1_cg_regs = {
> +	.set_ofs = 0x0088,
> +	.clr_ofs = 0x008c,
> +	.sta_ofs = 0x0094,
> +};
> +
> +static const struct mtk_gate_regs infra2_cg_regs = {
> +	.set_ofs = 0x00a8,
> +	.clr_ofs = 0x00ac,
> +	.sta_ofs = 0x00b0,
> +};
> +
> +#define GATE_ICG0(_id, _name, _parent, _shift) {	\
> +	.id = _id,					\
> +	.name = _name,					\
> +	.parent_name = _parent,				\
> +	.regs = &infra0_cg_regs,			\
> +	.shift = _shift,				\
> +	.ops = &mtk_clk_gate_ops_setclr,		\
> +}
> +
> +#define GATE_ICG1(_id, _name, _parent, _shift) {	\
> +	.id = _id,					\
> +	.name = _name,					\
> +	.parent_name = _parent,				\
> +	.regs = &infra1_cg_regs,			\
> +	.shift = _shift,				\
> +	.ops = &mtk_clk_gate_ops_setclr,		\
> +}
> +
> +#define GATE_ICG2(_id, _name, _parent, _shift) {	\
> +	.id = _id,					\
> +	.name = _name,					\
> +	.parent_name = _parent,				\
> +	.regs = &infra2_cg_regs,			\
> +	.shift = _shift,				\
> +	.ops = &mtk_clk_gate_ops_setclr,		\
> +}
> +
> +static const struct mtk_gate infra_clks[] = {
> +	GATE_ICG0(CLK_INFRA_PMIC_TMR, "infra_pmic_tmr", "ulposc", 0),
> +	GATE_ICG0(CLK_INFRA_PMIC_AP, "infra_pmic_ap", "pmicspi_sel", 1),
> +	GATE_ICG0(CLK_INFRA_PMIC_MD, "infra_pmic_md", "pmicspi_sel", 2),
> +	GATE_ICG0(CLK_INFRA_PMIC_CONN, "infra_pmic_conn", "pmicspi_sel", 3),
> +	GATE_ICG0(CLK_INFRA_SCP, "infra_scp", "scp_sel", 4),
> +	GATE_ICG0(CLK_INFRA_SEJ, "infra_sej", "axi_sel", 5),
> +	GATE_ICG0(CLK_INFRA_APXGPT, "infra_apxgpt", "axi_sel", 6),
> +	GATE_ICG0(CLK_INFRA_SEJ_13M, "infra_sej_13m", "clk26m", 7),
> +	GATE_ICG0(CLK_INFRA_ICUSB, "infra_icusb", "usb20_sel", 8),
> +	GATE_ICG0(CLK_INFRA_GCE, "infra_gce", "axi_sel", 9),
> +	GATE_ICG0(CLK_INFRA_THERM, "infra_therm", "axi_sel", 10),
> +	GATE_ICG0(CLK_INFRA_I2C0, "infra_i2c0", "axi_sel", 11),
> +	GATE_ICG0(CLK_INFRA_I2C1, "infra_i2c1", "axi_sel", 12),
> +	GATE_ICG0(CLK_INFRA_I2C2, "infra_i2c2", "axi_sel", 13),
> +	GATE_ICG0(CLK_INFRA_I2C3, "infra_i2c3", "axi_sel", 14),
> +	GATE_ICG0(CLK_INFRA_PWM_HCLK, "infra_pwm_hclk", "axi_sel", 15),
> +	GATE_ICG0(CLK_INFRA_PWM1, "infra_pwm1", "axi_sel", 16),
> +	GATE_ICG0(CLK_INFRA_PWM2, "infra_pwm2", "axi_sel", 17),
> +	GATE_ICG0(CLK_INFRA_PWM3, "infra_pwm3", "axi_sel", 18),
> +	GATE_ICG0(CLK_INFRA_PWM4, "infra_pwm4", "axi_sel", 19),
> +	GATE_ICG0(CLK_INFRA_PWM, "infra_pwm", "axi_sel", 21),
> +	GATE_ICG0(CLK_INFRA_UART0, "infra_uart0", "uart_sel", 22),
> +	GATE_ICG0(CLK_INFRA_UART1, "infra_uart1", "uart_sel", 23),
> +	GATE_ICG0(CLK_INFRA_UART2, "infra_uart2", "uart_sel", 24),
> +	GATE_ICG0(CLK_INFRA_UART3, "infra_uart3", "uart_sel", 25),
> +	GATE_ICG0(CLK_INFRA_MD2MD_CCIF_0, "infra_md2md_ccif_0", "axi_sel", 27),
> +	GATE_ICG0(CLK_INFRA_MD2MD_CCIF_1, "infra_md2md_ccif_1", "axi_sel", 28),
> +	GATE_ICG0(CLK_INFRA_MD2MD_CCIF_2, "infra_md2md_ccif_2", "axi_sel", 29),
> +	GATE_ICG0(CLK_INFRA_FHCTL, "infra_fhctl", "clk26m", 30),
> +	GATE_ICG0(CLK_INFRA_BTIF, "infra_btif", "axi_sel", 31),
> +	GATE_ICG1(CLK_INFRA_MD2MD_CCIF_3, "infra_md2md_ccif_3", "axi_sel", 0),
> +	GATE_ICG1(CLK_INFRA_SPI, "infra_spi", "spi_sel", 1),
> +	GATE_ICG1(CLK_INFRA_MSDC0, "infra_msdc0", "msdc50_0_sel", 2),
> +	GATE_ICG1(CLK_INFRA_MD2MD_CCIF_4, "infra_md2md_ccif_4", "axi_sel", 3),
> +	GATE_ICG1(CLK_INFRA_MSDC1, "infra_msdc1", "msdc30_1_sel", 4),
> +	GATE_ICG1(CLK_INFRA_MSDC2, "infra_msdc2", "msdc30_2_sel", 5),
> +	GATE_ICG1(CLK_INFRA_MD2MD_CCIF_5, "infra_md2md_ccif_5", "axi_sel", 7),
> +	GATE_ICG1(CLK_INFRA_GCPU, "infra_gcpu", "axi_sel", 8),
> +	GATE_ICG1(CLK_INFRA_TRNG, "infra_trng", "axi_sel", 9),
> +	GATE_ICG1(CLK_INFRA_AUXADC, "infra_auxadc", "clk26m", 10),
> +	GATE_ICG1(CLK_INFRA_CPUM, "infra_cpum", "axi_sel", 11),
> +	GATE_ICG1(CLK_INFRA_AP_C2K_CCIF_0, "infra_ap_c2k_ccif_0",
> +		  "axi_sel", 12),
> +	GATE_ICG1(CLK_INFRA_AP_C2K_CCIF_1, "infra_ap_c2k_ccif_1",
> +		  "axi_sel", 13),
> +	GATE_ICG1(CLK_INFRA_CLDMA, "infra_cldma", "axi_sel", 16),
> +	GATE_ICG1(CLK_INFRA_DISP_PWM, "infra_disp_pwm", "pwm_sel", 17),
> +	GATE_ICG1(CLK_INFRA_AP_DMA, "infra_ap_dma", "axi_sel", 18),
> +	GATE_ICG1(CLK_INFRA_DEVICE_APC, "infra_device_apc", "axi_sel", 20),
> +	GATE_ICG1(CLK_INFRA_L2C_SRAM, "infra_l2c_sram", "mm_sel", 22),
> +	GATE_ICG1(CLK_INFRA_CCIF_AP, "infra_ccif_ap", "axi_sel", 23),
> +	GATE_ICG1(CLK_INFRA_AUDIO, "infra_audio", "axi_sel", 25),
> +	GATE_ICG1(CLK_INFRA_CCIF_MD, "infra_ccif_md", "axi_sel", 26),
> +	GATE_ICG1(CLK_INFRA_DRAMC_F26M, "infra_dramc_f26m", "clk26m", 31),
> +	GATE_ICG2(CLK_INFRA_I2C4, "infra_i2c4", "axi_sel", 0),
> +	GATE_ICG2(CLK_INFRA_I2C_APPM, "infra_i2c_appm", "axi_sel", 1),
> +	GATE_ICG2(CLK_INFRA_I2C_GPUPM, "infra_i2c_gpupm", "axi_sel", 2),
> +	GATE_ICG2(CLK_INFRA_I2C2_IMM, "infra_i2c2_imm", "axi_sel", 3),
> +	GATE_ICG2(CLK_INFRA_I2C2_ARB, "infra_i2c2_arb", "axi_sel", 4),
> +	GATE_ICG2(CLK_INFRA_I2C3_IMM, "infra_i2c3_imm", "axi_sel", 5),
> +	GATE_ICG2(CLK_INFRA_I2C3_ARB, "infra_i2c3_arb", "axi_sel", 6),
> +	GATE_ICG2(CLK_INFRA_I2C5, "infra_i2c5", "axi_sel", 7),
> +	GATE_ICG2(CLK_INFRA_SYS_CIRQ, "infra_sys_cirq", "axi_sel", 8),
> +	GATE_ICG2(CLK_INFRA_SPI1, "infra_spi1", "spi_sel", 10),
> +	GATE_ICG2(CLK_INFRA_DRAMC_B_F26M, "infra_dramc_b_f26m", "clk26m", 11),
> +	GATE_ICG2(CLK_INFRA_ANC_MD32, "infra_anc_md32", "anc_md32_sel", 12),
> +	GATE_ICG2(CLK_INFRA_ANC_MD32_32K, "infra_anc_md32_32k", "clk26m", 13),
> +	GATE_ICG2(CLK_INFRA_DVFS_SPM1, "infra_dvfs_spm1", "axi_sel", 15),
> +	GATE_ICG2(CLK_INFRA_AES_TOP0, "infra_aes_top0", "axi_sel", 16),
> +	GATE_ICG2(CLK_INFRA_AES_TOP1, "infra_aes_top1", "axi_sel", 17),
> +	GATE_ICG2(CLK_INFRA_SSUSB_BUS, "infra_ssusb_bus", "axi_sel", 18),
> +	GATE_ICG2(CLK_INFRA_SPI2, "infra_spi2", "spi_sel", 19),
> +	GATE_ICG2(CLK_INFRA_SPI3, "infra_spi3", "spi_sel", 20),
> +	GATE_ICG2(CLK_INFRA_SPI4, "infra_spi4", "spi_sel", 21),
> +	GATE_ICG2(CLK_INFRA_SPI5, "infra_spi5", "spi_sel", 22),
> +	GATE_ICG2(CLK_INFRA_IRTX, "infra_irtx", "spi_sel", 23),
> +	GATE_ICG2(CLK_INFRA_SSUSB_SYS, "infra_ssusb_sys",
> +		  "ssusb_top_sys_sel", 24),
> +	GATE_ICG2(CLK_INFRA_SSUSB_REF, "infra_ssusb_ref", "clk26m", 9),
> +	GATE_ICG2(CLK_INFRA_AUDIO_26M, "infra_audio_26m", "clk26m", 26),
> +	GATE_ICG2(CLK_INFRA_AUDIO_26M_PAD_TOP, "infra_audio_26m_pad_top",
> +		  "clk26m", 27),
> +	GATE_ICG2(CLK_INFRA_MODEM_TEMP_SHARE, "infra_modem_temp_share",
> +		  "axi_sel", 28),
> +	GATE_ICG2(CLK_INFRA_VAD_WRAP_SOC, "infra_vad_wrap_soc", "axi_sel", 29),
> +	GATE_ICG2(CLK_INFRA_DRAMC_CONF, "infra_dramc_conf", "axi_sel", 30),
> +	GATE_ICG2(CLK_INFRA_DRAMC_B_CONF, "infra_dramc_b_conf", "axi_sel", 31),
> +	GATE_ICG1(CLK_INFRA_MFG_VCG, "infra_mfg_vcg", "mfg_52m_sel", 14),
> +};
> +
> +static const struct mtk_fixed_factor infra_fixed_divs[] = {
> +	FACTOR(CLK_INFRA_13M, "clk13m", "clk26m", 1, 2),
> +};
> +
> +static struct clk_onecell_data *infra_clk_data;
> +
> +static void mtk_infrasys_init_early(struct device_node *node)
> +{
> +	int r, i;
> +
> +	if (!infra_clk_data) {
> +		infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR);
> +
> +		for (i = 0; i < CLK_INFRA_NR; i++)
> +			infra_clk_data->clks[i] = ERR_PTR(-EPROBE_DEFER);
> +	}
> +
> +	mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
> +				 infra_clk_data);
> +
> +	r = of_clk_add_provider(node, of_clk_src_onecell_get, infra_clk_data);
> +	if (r)
> +		pr_err("%s(): could not register clock provider: %d\n",
> +		       __func__, r);
> +}
> +
> +CLK_OF_DECLARE_DRIVER(mtk_infra, "mediatek,mt6797-infracfg",
> +		      mtk_infrasys_init_early);
> +
> +static int mtk_infrasys_init(struct platform_device *pdev)
> +{
> +	int r, i;
> +	struct device_node *node = pdev->dev.of_node;
> +
> +	if (!infra_clk_data) {
> +		infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR);
> +	} else {
> +		for (i = 0; i < CLK_INFRA_NR; i++) {
> +			if (infra_clk_data->clks[i] == ERR_PTR(-EPROBE_DEFER))
> +				infra_clk_data->clks[i] = ERR_PTR(-ENOENT);
> +		}
> +	}
> +
> +	mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
> +			       infra_clk_data);
> +	mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
> +				 infra_clk_data);
> +
> +	r = of_clk_add_provider(node, of_clk_src_onecell_get, infra_clk_data);
> +	if (r)
> +		return r;
> +
> +	return 0;
> +}
> +
> +#define MT6797_PLL_FMAX		(3000UL * MHZ)
> +
> +#define CON0_MT6797_RST_BAR	BIT(24)
> +
> +#define PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,	\
> +			_pd_reg, _pd_shift, _tuner_reg, _pcw_reg,	\
> +			_pcw_shift, _div_table) {			\
> +	.id = _id,						\
> +	.name = _name,						\
> +	.reg = _reg,						\
> +	.pwr_reg = _pwr_reg,					\
> +	.en_mask = _en_mask,					\
> +	.flags = _flags,					\
> +	.rst_bar_mask = CON0_MT6797_RST_BAR,			\
> +	.fmax = MT6797_PLL_FMAX,				\
> +	.pcwbits = _pcwbits,					\
> +	.pd_reg = _pd_reg,					\
> +	.pd_shift = _pd_shift,					\
> +	.tuner_reg = _tuner_reg,				\
> +	.pcw_reg = _pcw_reg,					\
> +	.pcw_shift = _pcw_shift,				\
> +	.div_table = _div_table,				\
> +}
> +
> +#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,	\
> +			_pd_reg, _pd_shift, _tuner_reg, _pcw_reg,	\
> +			_pcw_shift)					\
> +		PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \
> +			_pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift, \
> +			NULL)
> +
> +static const struct mtk_pll_data plls[] = {
> +	PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x0220, 0x022C, 0xF0000101, PLL_AO,
> +	    21, 0x220, 4, 0x0, 0x224, 0),
> +	PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x0230, 0x023C, 0xFE000011, 0, 7,
> +	    0x230, 4, 0x0, 0x234, 14),
> +	PLL(CLK_APMIXED_MFGPLL, "mfgpll", 0x0240, 0x024C, 0x00000101, 0, 21,
> +	    0x244, 24, 0x0, 0x244, 0),
> +	PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x0250, 0x025C, 0x00000121, 0, 21,
> +	    0x250, 4, 0x0, 0x254, 0),
> +	PLL(CLK_APMIXED_IMGPLL, "imgpll", 0x0260, 0x026C, 0x00000121, 0, 21,
> +	    0x260, 4, 0x0, 0x264, 0),
> +	PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x0270, 0x027C, 0xC0000121, 0, 21,
> +	    0x270, 4, 0x0, 0x274, 0),
> +	PLL(CLK_APMIXED_CODECPLL, "codecpll", 0x0290, 0x029C, 0x00000121, 0, 21,
> +	    0x290, 4, 0x0, 0x294, 0),
> +	PLL(CLK_APMIXED_VDECPLL, "vdecpll", 0x02E4, 0x02F0, 0x00000121, 0, 21,
> +	    0x2E4, 4, 0x0, 0x2E8, 0),
> +	PLL(CLK_APMIXED_APLL1, "apll1", 0x02A0, 0x02B0, 0x00000131, 0, 31,
> +	    0x2A0, 4, 0x2A8, 0x2A4, 0),
> +	PLL(CLK_APMIXED_APLL2, "apll2", 0x02B4, 0x02C4, 0x00000131, 0, 31,
> +	    0x2B4, 4, 0x2BC, 0x2B8, 0),
> +};
> +
> +static int mtk_apmixedsys_init(struct platform_device *pdev)
> +{
> +	struct clk_onecell_data *clk_data;
> +	struct device_node *node = pdev->dev.of_node;
> +
> +	clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR);
> +	if (!clk_data)
> +		return -ENOMEM;
> +
> +	mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
> +
> +	return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> +}
> +
> +static const struct of_device_id of_match_clk_mt6797[] = {
> +	{
> +		.compatible = "mediatek,mt6797-topckgen",
> +		.data = mtk_topckgen_init,
> +	}, {
> +		.compatible = "mediatek,mt6797-infracfg",
> +		.data = mtk_infrasys_init,
> +	}, {
> +		.compatible = "mediatek,mt6797-apmixedsys",
> +		.data = mtk_apmixedsys_init,
> +	}, {
> +		/* sentinel */
> +	}
> +};
> +
> +static int clk_mt6797_probe(struct platform_device *pdev)
> +{
> +	int (*clk_init)(struct platform_device *);
> +	int r;
> +
> +	clk_init = of_device_get_match_data(&pdev->dev);
> +	if (!clk_init)
> +		return -EINVAL;
> +
> +	r = clk_init(pdev);
> +	if (r)
> +		dev_err(&pdev->dev,
> +			"could not register clock provider: %s: %d\n",
> +			pdev->name, r);
> +
> +	return r;
> +}
> +
> +static struct platform_driver clk_mt6797_drv = {
> +	.probe = clk_mt6797_probe,
> +	.driver = {
> +		.name = "clk-mt6797",
> +		.owner = THIS_MODULE,
> +		.of_match_table = of_match_clk_mt6797,
> +	},
> +};
> +
> +static int __init clk_mt6797_init(void)
> +{
> +	return platform_driver_register(&clk_mt6797_drv);
> +}
> +
> +arch_initcall(clk_mt6797_init);
> diff --git a/include/dt-bindings/clock/mt6797-clk.h b/include/dt-bindings/clock/mt6797-clk.h
> new file mode 100644
> index 0000000..e48aa47
> --- /dev/null
> +++ b/include/dt-bindings/clock/mt6797-clk.h
> @@ -0,0 +1,281 @@
> +/*
> + * Copyright (c) 2017 MediaTek Inc.
> + * Author: Kevin Chen <kevin-cw.chen@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_MT6797_H
> +#define _DT_BINDINGS_CLK_MT6797_H
> +
> +/* TOPCKGEN */
> +#define	CLK_TOP_MUX_ULPOSC_AXI_CK_MUX_PRE	1
> +#define	CLK_TOP_MUX_ULPOSC_AXI_CK_MUX		2
> +#define	CLK_TOP_MUX_AXI				3
> +#define	CLK_TOP_MUX_MEM				4
> +#define	CLK_TOP_MUX_DDRPHYCFG			5
> +#define	CLK_TOP_MUX_MM				6
> +#define	CLK_TOP_MUX_PWM				7
> +#define	CLK_TOP_MUX_VDEC			8
> +#define	CLK_TOP_MUX_VENC			9
> +#define	CLK_TOP_MUX_MFG				10
> +#define	CLK_TOP_MUX_CAMTG			11
> +#define	CLK_TOP_MUX_UART			12
> +#define	CLK_TOP_MUX_SPI				13
> +#define	CLK_TOP_MUX_ULPOSC_SPI_CK_MUX		14
> +#define	CLK_TOP_MUX_USB20			15
> +#define	CLK_TOP_MUX_MSDC50_0_HCLK		16
> +#define	CLK_TOP_MUX_MSDC50_0			17
> +#define	CLK_TOP_MUX_MSDC30_1			18
> +#define	CLK_TOP_MUX_MSDC30_2			19
> +#define	CLK_TOP_MUX_AUDIO			20
> +#define	CLK_TOP_MUX_AUD_INTBUS			21
> +#define	CLK_TOP_MUX_PMICSPI			22
> +#define	CLK_TOP_MUX_SCP				23
> +#define	CLK_TOP_MUX_ATB				24
> +#define	CLK_TOP_MUX_MJC				25
> +#define	CLK_TOP_MUX_DPI0			26
> +#define	CLK_TOP_MUX_AUD_1			27
> +#define	CLK_TOP_MUX_AUD_2			28
> +#define	CLK_TOP_MUX_SSUSB_TOP_SYS		29
> +#define	CLK_TOP_MUX_SPM				30
> +#define	CLK_TOP_MUX_BSI_SPI			31
> +#define	CLK_TOP_MUX_AUDIO_H			32
> +#define	CLK_TOP_MUX_ANC_MD32			33
> +#define	CLK_TOP_MUX_MFG_52M			34
> +#define	CLK_TOP_SYSPLL_CK			35
> +#define	CLK_TOP_SYSPLL_D2			36
> +#define	CLK_TOP_SYSPLL1_D2			37
> +#define	CLK_TOP_SYSPLL1_D4			38
> +#define	CLK_TOP_SYSPLL1_D8			39
> +#define	CLK_TOP_SYSPLL1_D16			40
> +#define	CLK_TOP_SYSPLL_D3			41
> +#define	CLK_TOP_SYSPLL_D3_D3			42
> +#define	CLK_TOP_SYSPLL2_D2			43
> +#define	CLK_TOP_SYSPLL2_D4			44
> +#define	CLK_TOP_SYSPLL2_D8			45
> +#define	CLK_TOP_SYSPLL_D5			46
> +#define	CLK_TOP_SYSPLL3_D2			47
> +#define	CLK_TOP_SYSPLL3_D4			48
> +#define	CLK_TOP_SYSPLL_D7			49
> +#define	CLK_TOP_SYSPLL4_D2			50
> +#define	CLK_TOP_SYSPLL4_D4			51
> +#define	CLK_TOP_UNIVPLL_CK			52
> +#define	CLK_TOP_UNIVPLL_D7			53
> +#define	CLK_TOP_UNIVPLL_D26			54
> +#define	CLK_TOP_SSUSB_PHY_48M_CK		55
> +#define	CLK_TOP_USB_PHY48M_CK			56
> +#define	CLK_TOP_UNIVPLL_D2			57
> +#define	CLK_TOP_UNIVPLL1_D2			58
> +#define	CLK_TOP_UNIVPLL1_D4			59
> +#define	CLK_TOP_UNIVPLL1_D8			60
> +#define	CLK_TOP_UNIVPLL_D3			61
> +#define	CLK_TOP_UNIVPLL2_D2			62
> +#define	CLK_TOP_UNIVPLL2_D4			63
> +#define	CLK_TOP_UNIVPLL2_D8			64
> +#define	CLK_TOP_UNIVPLL_D5			65
> +#define	CLK_TOP_UNIVPLL3_D2			66
> +#define	CLK_TOP_UNIVPLL3_D4			67
> +#define	CLK_TOP_UNIVPLL3_D8			68
> +#define	CLK_TOP_ULPOSC_CK_ORG			69
> +#define	CLK_TOP_ULPOSC_CK			70
> +#define	CLK_TOP_ULPOSC_D2			71
> +#define	CLK_TOP_ULPOSC_D3			72
> +#define	CLK_TOP_ULPOSC_D4			73
> +#define	CLK_TOP_ULPOSC_D8			74
> +#define	CLK_TOP_ULPOSC_D10			75
> +#define	CLK_TOP_APLL1_CK			76
> +#define	CLK_TOP_APLL2_CK			77
> +#define	CLK_TOP_MFGPLL_CK			78
> +#define	CLK_TOP_MFGPLL_D2			79
> +#define	CLK_TOP_IMGPLL_CK			80
> +#define	CLK_TOP_IMGPLL_D2			81
> +#define	CLK_TOP_IMGPLL_D4			82
> +#define	CLK_TOP_CODECPLL_CK			83
> +#define	CLK_TOP_CODECPLL_D2			84
> +#define	CLK_TOP_VDECPLL_CK			85
> +#define	CLK_TOP_TVDPLL_CK			86
> +#define	CLK_TOP_TVDPLL_D2			87
> +#define	CLK_TOP_TVDPLL_D4			88
> +#define	CLK_TOP_TVDPLL_D8			89
> +#define	CLK_TOP_TVDPLL_D16			90
> +#define	CLK_TOP_MSDCPLL_CK			91
> +#define	CLK_TOP_MSDCPLL_D2			92
> +#define	CLK_TOP_MSDCPLL_D4			93
> +#define	CLK_TOP_MSDCPLL_D8			94
> +#define CLK_TOP_NR				95
> +
> +/* APMIXED_SYS */
> +#define CLK_APMIXED_MAINPLL			1
> +#define CLK_APMIXED_UNIVPLL			2
> +#define CLK_APMIXED_MFGPLL			3
> +#define CLK_APMIXED_MSDCPLL			4
> +#define CLK_APMIXED_IMGPLL			5
> +#define CLK_APMIXED_TVDPLL			6
> +#define CLK_APMIXED_CODECPLL			7
> +#define CLK_APMIXED_VDECPLL			8
> +#define CLK_APMIXED_APLL1			9
> +#define CLK_APMIXED_APLL2			10
> +#define CLK_APMIXED_NR				11
> +
> +/* INFRA_SYS */
> +#define	CLK_INFRA_PMIC_TMR			1
> +#define	CLK_INFRA_PMIC_AP			2
> +#define	CLK_INFRA_PMIC_MD			3
> +#define	CLK_INFRA_PMIC_CONN			4
> +#define	CLK_INFRA_SCP				5
> +#define	CLK_INFRA_SEJ				6
> +#define	CLK_INFRA_APXGPT			7
> +#define	CLK_INFRA_SEJ_13M			8
> +#define	CLK_INFRA_ICUSB				9
> +#define	CLK_INFRA_GCE				10
> +#define	CLK_INFRA_THERM				11
> +#define	CLK_INFRA_I2C0				12
> +#define	CLK_INFRA_I2C1				13
> +#define	CLK_INFRA_I2C2				14
> +#define	CLK_INFRA_I2C3				15
> +#define	CLK_INFRA_PWM_HCLK			16
> +#define	CLK_INFRA_PWM1				17
> +#define	CLK_INFRA_PWM2				18
> +#define	CLK_INFRA_PWM3				19
> +#define	CLK_INFRA_PWM4				20
> +#define	CLK_INFRA_PWM				21
> +#define	CLK_INFRA_UART0				22
> +#define	CLK_INFRA_UART1				23
> +#define	CLK_INFRA_UART2				24
> +#define	CLK_INFRA_UART3				25
> +#define	CLK_INFRA_MD2MD_CCIF_0			26
> +#define	CLK_INFRA_MD2MD_CCIF_1			27
> +#define	CLK_INFRA_MD2MD_CCIF_2			28
> +#define	CLK_INFRA_FHCTL				29
> +#define	CLK_INFRA_BTIF				30
> +#define	CLK_INFRA_MD2MD_CCIF_3			31
> +#define	CLK_INFRA_SPI				32
> +#define	CLK_INFRA_MSDC0				33
> +#define	CLK_INFRA_MD2MD_CCIF_4			34
> +#define	CLK_INFRA_MSDC1				35
> +#define	CLK_INFRA_MSDC2				36
> +#define	CLK_INFRA_MD2MD_CCIF_5			37
> +#define	CLK_INFRA_GCPU				38
> +#define	CLK_INFRA_TRNG				39
> +#define	CLK_INFRA_AUXADC			40
> +#define	CLK_INFRA_CPUM				41
> +#define	CLK_INFRA_AP_C2K_CCIF_0			42
> +#define	CLK_INFRA_AP_C2K_CCIF_1			43
> +#define	CLK_INFRA_CLDMA				44
> +#define	CLK_INFRA_DISP_PWM			45
> +#define	CLK_INFRA_AP_DMA			46
> +#define	CLK_INFRA_DEVICE_APC			47
> +#define	CLK_INFRA_L2C_SRAM			48
> +#define	CLK_INFRA_CCIF_AP			49
> +#define	CLK_INFRA_AUDIO				50
> +#define	CLK_INFRA_CCIF_MD			51
> +#define	CLK_INFRA_DRAMC_F26M			52
> +#define	CLK_INFRA_I2C4				53
> +#define	CLK_INFRA_I2C_APPM			54
> +#define	CLK_INFRA_I2C_GPUPM			55
> +#define	CLK_INFRA_I2C2_IMM			56
> +#define	CLK_INFRA_I2C2_ARB			57
> +#define	CLK_INFRA_I2C3_IMM			58
> +#define	CLK_INFRA_I2C3_ARB			59
> +#define	CLK_INFRA_I2C5				60
> +#define	CLK_INFRA_SYS_CIRQ			61
> +#define	CLK_INFRA_SPI1				62
> +#define	CLK_INFRA_DRAMC_B_F26M			63
> +#define	CLK_INFRA_ANC_MD32			64
> +#define	CLK_INFRA_ANC_MD32_32K			65
> +#define	CLK_INFRA_DVFS_SPM1			66
> +#define	CLK_INFRA_AES_TOP0			67
> +#define	CLK_INFRA_AES_TOP1			68
> +#define	CLK_INFRA_SSUSB_BUS			69
> +#define	CLK_INFRA_SPI2				70
> +#define	CLK_INFRA_SPI3				71
> +#define	CLK_INFRA_SPI4				72
> +#define	CLK_INFRA_SPI5				73
> +#define	CLK_INFRA_IRTX				74
> +#define	CLK_INFRA_SSUSB_SYS			75
> +#define	CLK_INFRA_SSUSB_REF			76
> +#define	CLK_INFRA_AUDIO_26M			77
> +#define	CLK_INFRA_AUDIO_26M_PAD_TOP		78
> +#define	CLK_INFRA_MODEM_TEMP_SHARE		79
> +#define	CLK_INFRA_VAD_WRAP_SOC			80
> +#define	CLK_INFRA_DRAMC_CONF			81
> +#define	CLK_INFRA_DRAMC_B_CONF			82
> +#define CLK_INFRA_MFG_VCG			83
> +#define CLK_INFRA_13M				84
> +#define CLK_INFRA_NR				85
> +
> +/* IMG_SYS */
> +#define	CLK_IMG_FDVT				1
> +#define	CLK_IMG_DPE				2
> +#define	CLK_IMG_DIP				3
> +#define	CLK_IMG_LARB6				4
> +#define CLK_IMG_NR				5
> +
> +/* MM_SYS */
> +#define	CLK_MM_SMI_COMMON			1
> +#define	CLK_MM_SMI_LARB0			2
> +#define	CLK_MM_SMI_LARB5			3
> +#define	CLK_MM_CAM_MDP				4
> +#define	CLK_MM_MDP_RDMA0			5
> +#define	CLK_MM_MDP_RDMA1			6
> +#define	CLK_MM_MDP_RSZ0				7
> +#define	CLK_MM_MDP_RSZ1				8
> +#define	CLK_MM_MDP_RSZ2				9
> +#define	CLK_MM_MDP_TDSHP			10
> +#define	CLK_MM_MDP_COLOR			11
> +#define	CLK_MM_MDP_WDMA				12
> +#define	CLK_MM_MDP_WROT0			13
> +#define	CLK_MM_MDP_WROT1			14
> +#define	CLK_MM_FAKE_ENG				15
> +#define	CLK_MM_DISP_OVL0			16
> +#define	CLK_MM_DISP_OVL1			17
> +#define	CLK_MM_DISP_OVL0_2L			18
> +#define	CLK_MM_DISP_OVL1_2L			19
> +#define	CLK_MM_DISP_RDMA0			20
> +#define	CLK_MM_DISP_RDMA1			21
> +#define	CLK_MM_DISP_WDMA0			22
> +#define	CLK_MM_DISP_WDMA1			23
> +#define	CLK_MM_DISP_COLOR			24
> +#define	CLK_MM_DISP_CCORR			25
> +#define	CLK_MM_DISP_AAL				26
> +#define	CLK_MM_DISP_GAMMA			27
> +#define	CLK_MM_DISP_OD				28
> +#define	CLK_MM_DISP_DITHER			29
> +#define	CLK_MM_DISP_UFOE			30
> +#define	CLK_MM_DISP_DSC				31
> +#define	CLK_MM_DISP_SPLIT			32
> +#define	CLK_MM_DSI0_MM_CLOCK			33
> +#define	CLK_MM_DSI1_MM_CLOCK			34
> +#define	CLK_MM_DPI_MM_CLOCK			35
> +#define	CLK_MM_DPI_INTERFACE_CLOCK		36
> +#define	CLK_MM_LARB4_AXI_ASIF_MM_CLOCK		37
> +#define	CLK_MM_LARB4_AXI_ASIF_MJC_CLOCK		38
> +#define	CLK_MM_DISP_OVL0_MOUT_CLOCK		39
> +#define	CLK_MM_FAKE_ENG2			40
> +#define	CLK_MM_DSI0_INTERFACE_CLOCK		41
> +#define	CLK_MM_DSI1_INTERFACE_CLOCK		42
> +#define CLK_MM_NR				43
> +
> +/* VDEC_SYS */
> +#define	CLK_VDEC_CKEN_ENG			1
> +#define	CLK_VDEC_ACTIVE				2
> +#define	CLK_VDEC_CKEN				3
> +#define	CLK_VDEC_LARB1_CKEN			4
> +#define CLK_VDEC_NR				5
> +
> +/* VENC_SYS */
> +#define	CLK_VENC_0				1
> +#define	CLK_VENC_1				2
> +#define	CLK_VENC_2				3
> +#define	CLK_VENC_3				4
> +#define CLK_VENC_NR				5
> +
> +#endif /* _DT_BINDINGS_CLK_MT6797_H */
>

^ permalink raw reply	[flat|nested] 44+ messages in thread

end of thread, other threads:[~2017-02-11 23:32 UTC | newest]

Thread overview: 44+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-06 12:15 [PATCH v2 00/10] Add Basic SoC support for MT6797 Mars Cheng
2017-02-06 12:15 ` Mars Cheng
2017-02-06 12:15 ` [PATCH v2 01/10] Document: DT: mediatek: multiple base address support for sysirq Mars Cheng
2017-02-06 12:15   ` Mars Cheng
2017-02-08 23:20   ` Rob Herring
2017-02-09  1:47     ` Mars Cheng
2017-02-09  1:47       ` Mars Cheng
2017-02-06 12:15 ` [PATCH v2 02/10] irqchip: mtk-sysirq: extend intpol base to arbitrary number Mars Cheng
2017-02-06 12:15   ` Mars Cheng
2017-02-09  9:03   ` Marc Zyngier
2017-02-09  9:03     ` Marc Zyngier
2017-02-09  9:31     ` Mars Cheng
2017-02-09  9:31       ` Mars Cheng
2017-02-09  9:43       ` Marc Zyngier
2017-02-09  9:43         ` Marc Zyngier
2017-02-09  9:49         ` Mars Cheng
2017-02-09  9:49           ` Mars Cheng
2017-02-06 12:15 ` [PATCH v2 03/10] Document: DT: Add bindings for mediatek MT6797 SoC Platform Mars Cheng
2017-02-06 12:15   ` Mars Cheng
2017-02-09  0:34   ` Rob Herring
2017-02-06 12:15 ` [PATCH v2 04/10] arm64: dts: mediatek: add mt6797 support Mars Cheng
2017-02-06 12:15   ` Mars Cheng
2017-02-06 12:28   ` Marc Zyngier
2017-02-06 12:37     ` Mars Cheng
2017-02-06 12:37       ` Mars Cheng
2017-02-06 12:15 ` [PATCH v2 05/10] dt-bindings: arm: mediatek: document clk bindings for MT6797 Mars Cheng
2017-02-06 12:15   ` Mars Cheng
2017-02-09  0:35   ` Rob Herring
2017-02-09  0:35     ` Rob Herring
2017-02-06 12:15 ` [PATCH v2 06/10] clk: mediatek: add clk support " Mars Cheng
2017-02-06 12:15   ` Mars Cheng
2017-02-11 23:31   ` Matthias Brugger
2017-02-06 12:15 ` [PATCH v2 07/10] soc: mediatek: refine scysys for mediatek platforms Mars Cheng
2017-02-06 12:15   ` Mars Cheng
2017-02-11 23:15   ` Matthias Brugger
2017-02-06 12:15 ` [PATCH v2 08/10] soc: mediatek: add MT6797 power dt-bindings Mars Cheng
2017-02-06 12:15   ` Mars Cheng
2017-02-09  0:37   ` Rob Herring
2017-02-09  1:32     ` Mars Cheng
2017-02-09  1:32       ` Mars Cheng
2017-02-06 12:15 ` [PATCH v2 09/10] soc: mediatek: add MT6797 scysys support Mars Cheng
2017-02-06 12:15   ` Mars Cheng
2017-02-06 12:15 ` [PATCH v2 10/10] arm64: dts: mediatek: add clk nodes for MT6797 Mars Cheng
2017-02-06 12:15   ` Mars Cheng

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.