linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 0/11] Add basic SoC support for mt6765
@ 2018-07-17  8:52 Mars Cheng
  2018-07-17  8:52 ` [PATCH v5 01/11] dt-bindings: clock: mediatek: document clk bindings for Mediatek MT6765 SoC Mars Cheng
                   ` (10 more replies)
  0 siblings, 11 replies; 32+ messages in thread
From: Mars Cheng @ 2018-07-17  8:52 UTC (permalink / raw)
  To: Matthias Brugger, Rob Herring, Marc Zyngier, Ryder Lee,
	Stephen Boyd, Sean Wang
  Cc: CC Hwang, Loda Chou, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, linux-serial, linux-arm-kernel, linux-clk

This patch adds basic SoC support for Mediatek's new 8-core SoC,
MT6765, which is mainly for smartphone application.

Changes in V5:
1. add clk support

Changes in V4:
1. add gic's settings in reg properties
2. remove some patches about dt-bindings since GKH already took them

Changes in V3:
1. split dt-binding document patchs
2. fix mt6765.dtsi warnings with W=12
3. remove uncessary PPI affinity for timer
4. add gicc base for gic dt node

Changes in V2:
1. fix clk properties in uart dts node
2. fix typo in submit title
3. add simple-bus in mt6765.dtsi
4. use correct SPDX license format

Mars Cheng (7):
  dt-bindings: clock: mediatek: document clk bindings for Mediatek
    MT6765 SoC
  dt-bindings: mediatek: Add smi dts binding for Mediatek MT6765 SoC
  dt-bindings: mediatek: add MT6765 power dt-bindings
  soc: mediatek: add MT6765 scpsys support
  clk: mediatek: add mt6765 clock IDs
  soc: mediatek: add MT6765 subdomain support
  arm64: dts: mediatek: add mt6765 support

Owen Chen (4):
  soc: mediatek: add new flow for mtcmos power.
  clk: mediatek: fix pll setting
  clk: mediatek: add new clkmux register API
  clk: mediatek: Add MT6765 clock support

 .../bindings/arm/mediatek/mediatek,apmixedsys.txt  |   1 +
 .../bindings/arm/mediatek/mediatek,audsys.txt      |   1 +
 .../bindings/arm/mediatek/mediatek,camsys.txt      |  27 +
 .../bindings/arm/mediatek/mediatek,imgsys.txt      |   1 +
 .../bindings/arm/mediatek/mediatek,infracfg.txt    |   1 +
 .../bindings/arm/mediatek/mediatek,mipi0a.txt      |  23 +
 .../bindings/arm/mediatek/mediatek,mmsys.txt       |   1 +
 .../bindings/arm/mediatek/mediatek,pericfg.txt     |   1 +
 .../bindings/arm/mediatek/mediatek,topckgen.txt    |   1 +
 .../bindings/arm/mediatek/mediatek,vcodecsys.txt   |  22 +
 .../memory-controllers/mediatek,smi-common.txt     |   1 +
 .../devicetree/bindings/soc/mediatek/scpsys.txt    |   6 +
 arch/arm64/boot/dts/mediatek/Makefile              |   1 +
 arch/arm64/boot/dts/mediatek/mt6765-evb.dts        |  33 +
 arch/arm64/boot/dts/mediatek/mt6765.dtsi           | 253 ++++++
 drivers/clk/mediatek/Kconfig                       |  87 ++
 drivers/clk/mediatek/Makefile                      |   9 +-
 drivers/clk/mediatek/clk-mt6765-audio.c            | 109 +++
 drivers/clk/mediatek/clk-mt6765-cam.c              |  83 ++
 drivers/clk/mediatek/clk-mt6765-img.c              |  79 ++
 drivers/clk/mediatek/clk-mt6765-mipi0a.c           |  77 ++
 drivers/clk/mediatek/clk-mt6765-mm.c               | 105 +++
drivers/clk/mediatek/clk-mt6765-vcodec.c           |  79 ++
 drivers/clk/mediatek/clk-mt6765.c                  | 963 +++++++++++++++++++++
 drivers/clk/mediatek/clk-mtk.c                     |  41 +
 drivers/clk/mediatek/clk-mtk.h                     |  87 +-
 drivers/clk/mediatek/clk-mux.c                     | 236 +++++
 drivers/clk/mediatek/clk-mux.h                     |  38 +
 drivers/clk/mediatek/clk-pll.c                     |  45 +-
 drivers/soc/mediatek/Makefile                      |   2 +-
 drivers/soc/mediatek/mtk-infracfg.c                | 178 +++-
 drivers/soc/mediatek/mtk-scpsys-ext.c              | 535 ++++++++++++
 drivers/soc/mediatek/mtk-scpsys.c                  | 235 ++++-
 include/dt-bindings/clock/mt6765-clk.h             | 313 +++++++
 include/dt-bindings/power/mt6765-power.h           |  14 +
 include/linux/soc/mediatek/infracfg.h              |   9 +-
 include/linux/soc/mediatek/scpsys-ext.h            |  66 ++
 37 files changed, 3681 insertions(+), 82 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,camsys.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mipi0a.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,vcodecsys.txt
 create mode 100644 arch/arm64/boot/dts/mediatek/mt6765-evb.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt6765.dtsi
 create mode 100644 drivers/clk/mediatek/clk-mt6765-audio.c
 create mode 100644 drivers/clk/mediatek/clk-mt6765-cam.c
 create mode 100644 drivers/clk/mediatek/clk-mt6765-img.c
 create mode 100644 drivers/clk/mediatek/clk-mt6765-mipi0a.c
 create mode 100644 drivers/clk/mediatek/clk-mt6765-mm.c
 create mode 100644 drivers/clk/mediatek/clk-mt6765-vcodec.c
 create mode 100644 drivers/clk/mediatek/clk-mt6765.c
 create mode 100644 drivers/clk/mediatek/clk-mux.c
 create mode 100644 drivers/clk/mediatek/clk-mux.h
 create mode 100644 drivers/soc/mediatek/mtk-scpsys-ext.c
 create mode 100644 include/dt-bindings/clock/mt6765-clk.h
 create mode 100644 include/dt-bindings/power/mt6765-power.h
 create mode 100644 include/linux/soc/mediatek/scpsys-ext.h


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

* [PATCH v5 01/11] dt-bindings: clock: mediatek: document clk bindings for Mediatek MT6765 SoC
  2018-07-17  8:52 [PATCH v5 0/11] Add basic SoC support for mt6765 Mars Cheng
@ 2018-07-17  8:52 ` Mars Cheng
  2018-07-20 17:43   ` Rob Herring
  2018-07-17  8:52 ` [PATCH v5 02/11] dt-bindings: mediatek: Add smi dts binding " Mars Cheng
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 32+ messages in thread
From: Mars Cheng @ 2018-07-17  8:52 UTC (permalink / raw)
  To: Matthias Brugger, Rob Herring, Marc Zyngier, Ryder Lee,
	Stephen Boyd, Sean Wang
  Cc: CC Hwang, Loda Chou, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, linux-serial, linux-arm-kernel, linux-clk,
	Mars Cheng, Owen Chen

This patch adds the binding documentation for apmixedsys, audsys, camsys,
imgsys, infracfg, mipi0a, topckgen, vcodecsys

Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
Signed-off-by: Owen Chen <owen.chen@mediatek.com>
---
 .../bindings/arm/mediatek/mediatek,apmixedsys.txt  |    1 +
 .../bindings/arm/mediatek/mediatek,audsys.txt      |    1 +
 .../bindings/arm/mediatek/mediatek,camsys.txt      |   27 ++++++++++++++++++++
 .../bindings/arm/mediatek/mediatek,imgsys.txt      |    1 +
 .../bindings/arm/mediatek/mediatek,infracfg.txt    |    1 +
 .../bindings/arm/mediatek/mediatek,mipi0a.txt      |   23 +++++++++++++++++
 .../bindings/arm/mediatek/mediatek,mmsys.txt       |    1 +
 .../bindings/arm/mediatek/mediatek,pericfg.txt     |    1 +
 .../bindings/arm/mediatek/mediatek,topckgen.txt    |    1 +
 .../bindings/arm/mediatek/mediatek,vcodecsys.txt   |   22 ++++++++++++++++
 10 files changed, 79 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,camsys.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mipi0a.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,vcodecsys.txt

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
index b404d59..44eaeac 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
@@ -8,6 +8,7 @@ Required Properties:
 - compatible: Should be one of:
 	- "mediatek,mt2701-apmixedsys"
 	- "mediatek,mt2712-apmixedsys", "syscon"
+	- "mediatek,mt6765-apmixedsys", "syscon"
 	- "mediatek,mt6797-apmixedsys"
 	- "mediatek,mt7622-apmixedsys"
 	- "mediatek,mt8135-apmixedsys"
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
index 34a69ba..9a8672a 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
@@ -7,6 +7,7 @@ Required Properties:
 
 - compatible: Should be one of:
 	- "mediatek,mt2701-audsys", "syscon"
+	- "mediatek,mt6765-audsys", "syscon"
 	- "mediatek,mt7622-audsys", "syscon"
 - #clock-cells: Must be 1
 
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,camsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,camsys.txt
new file mode 100644
index 0000000..dc75783
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,camsys.txt
@@ -0,0 +1,27 @@
+MediaTek CAMSYS controller
+============================
+
+The MediaTek CAMSYS controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be one of:
+	- "mediatek,mt6765-camsys", "syscon"
+- #clock-cells: Must be 1
+
+The AUDSYS controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Required sub-nodes:
+-------
+For common binding part and usage, refer to
+../sonud/mt2701-afe-pcm.txt.
+
+Example:
+
+camsys: camsys@1a000000  {
+	compatible = "mediatek,mt6765-camsys", "syscon";
+	reg = <0 0x1a000000  0 0x1000>;
+	#clock-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
index 868bd51..c7057d0 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
@@ -8,6 +8,7 @@ Required Properties:
 - compatible: Should be one of:
 	- "mediatek,mt2701-imgsys", "syscon"
 	- "mediatek,mt2712-imgsys", "syscon"
+	- "mediatek,mt6765-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 566f153..ac6aae5 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
@@ -9,6 +9,7 @@ Required Properties:
 - compatible: Should be one of:
 	- "mediatek,mt2701-infracfg", "syscon"
 	- "mediatek,mt2712-infracfg", "syscon"
+	- "mediatek,mt6765-infracfg", "syscon"
 	- "mediatek,mt6797-infracfg", "syscon"
 	- "mediatek,mt7622-infracfg", "syscon"
 	- "mediatek,mt8135-infracfg", "syscon"
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mipi0a.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mipi0a.txt
new file mode 100644
index 0000000..ba5ee7a
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mipi0a.txt
@@ -0,0 +1,23 @@
+Mediatek mipi_rx_ana_csi0a controller
+============================
+
+The Mediatek mipi_rx_ana_csi0a controller provides various clocks
+to the system.
+
+Required Properties:
+
+- compatible: Should be one of:
+	- "mediatek,mt6765-mipi_rx_ana_csi0a", "syscon"
+- #clock-cells: Must be 1
+
+The vencsys controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+mipi_rx_ana_csi0a: mipi_rx_ana_csi0a@11c10000 {
+	compatible = "mediatek,mt6765-mipi_rx_ana_csi0a", "syscon";
+	reg = <0 0x11c10000 0 0x1000>;
+	#clock-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
index 4eb8bbe..184f159 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
@@ -8,6 +8,7 @@ Required Properties:
 - compatible: Should be one of:
 	- "mediatek,mt2701-mmsys", "syscon"
 	- "mediatek,mt2712-mmsys", "syscon"
+	- "mediatek,mt6765-mmsys", "syscon"
 	- "mediatek,mt6797-mmsys", "syscon"
 	- "mediatek,mt8173-mmsys", "syscon"
 - #clock-cells: Must be 1
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
index fb58ca8..8eeb84b 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
@@ -9,6 +9,7 @@ Required Properties:
 - compatible: Should be one of:
 	- "mediatek,mt2701-pericfg", "syscon"
 	- "mediatek,mt2712-pericfg", "syscon"
+	- "mediatek,mt6765-pericfg", "syscon"
 	- "mediatek,mt7622-pericfg", "syscon"
 	- "mediatek,mt8135-pericfg", "syscon"
 	- "mediatek,mt8173-pericfg", "syscon"
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
index 24014a7..3a5cad6 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
@@ -8,6 +8,7 @@ Required Properties:
 - compatible: Should be one of:
 	- "mediatek,mt2701-topckgen"
 	- "mediatek,mt2712-topckgen", "syscon"
+	- "mediatek,mt6765-topckgen", "syscon"
 	- "mediatek,mt6797-topckgen"
 	- "mediatek,mt7622-topckgen"
 	- "mediatek,mt8135-topckgen"
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vcodecsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vcodecsys.txt
new file mode 100644
index 0000000..462889b
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vcodecsys.txt
@@ -0,0 +1,22 @@
+Mediatek vcodecsys controller
+============================
+
+The Mediatek vcodecsys controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be one of:
+	- "mediatek,mt6765-vcodecsys", "syscon"
+- #clock-cells: Must be 1
+
+The vencsys controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+venc_gcon: venc_gcon@17000000 {
+	compatible = "mediatek,mt6765-vcodecsys", "syscon";
+	reg = <0 0x17000000 0 0x10000>;
+	#clock-cells = <1>;
+};
-- 
1.7.9.5


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

* [PATCH v5 02/11] dt-bindings: mediatek: Add smi dts binding for Mediatek MT6765 SoC
  2018-07-17  8:52 [PATCH v5 0/11] Add basic SoC support for mt6765 Mars Cheng
  2018-07-17  8:52 ` [PATCH v5 01/11] dt-bindings: clock: mediatek: document clk bindings for Mediatek MT6765 SoC Mars Cheng
@ 2018-07-17  8:52 ` Mars Cheng
  2018-07-20 17:44   ` Rob Herring
  2018-07-17  8:52 ` [PATCH v5 03/11] dt-bindings: mediatek: add MT6765 power dt-bindings Mars Cheng
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 32+ messages in thread
From: Mars Cheng @ 2018-07-17  8:52 UTC (permalink / raw)
  To: Matthias Brugger, Rob Herring, Marc Zyngier, Ryder Lee,
	Stephen Boyd, Sean Wang
  Cc: CC Hwang, Loda Chou, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, linux-serial, linux-arm-kernel, linux-clk,
	Mars Cheng, Owen Chen

This patch adds MT6765 smi binding document

Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
Signed-off-by: Owen Chen <owen.chen@mediatek.com>
---
 .../memory-controllers/mediatek,smi-common.txt     |    1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt
index aa614b2..0bf64f5 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt
@@ -15,6 +15,7 @@ not needed for SMI generation 2.
 Required properties:
 - compatible : must be one of :
 	"mediatek,mt2701-smi-common"
+	"mediatek,mt6765-smi-common", "syscon"
 	"mediatek,mt8173-smi-common"
 - reg : the register and size of the SMI block.
 - power-domains : a phandle to the power domain of this local arbiter.
-- 
1.7.9.5


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

* [PATCH v5 03/11] dt-bindings: mediatek: add MT6765 power dt-bindings
  2018-07-17  8:52 [PATCH v5 0/11] Add basic SoC support for mt6765 Mars Cheng
  2018-07-17  8:52 ` [PATCH v5 01/11] dt-bindings: clock: mediatek: document clk bindings for Mediatek MT6765 SoC Mars Cheng
  2018-07-17  8:52 ` [PATCH v5 02/11] dt-bindings: mediatek: Add smi dts binding " Mars Cheng
@ 2018-07-17  8:52 ` Mars Cheng
  2018-07-20 17:45   ` Rob Herring
  2018-07-17  8:52 ` [PATCH v5 04/11] soc: mediatek: add MT6765 scpsys support Mars Cheng
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 32+ messages in thread
From: Mars Cheng @ 2018-07-17  8:52 UTC (permalink / raw)
  To: Matthias Brugger, Rob Herring, Marc Zyngier, Ryder Lee,
	Stephen Boyd, Sean Wang
  Cc: CC Hwang, Loda Chou, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, linux-serial, linux-arm-kernel, linux-clk,
	Mars Cheng, Owen Chen

This adds power dt-bindings for MT6765

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

diff --git a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
index d6fe16f..62a416a 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
+++ b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
@@ -11,6 +11,7 @@ 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
 - include/dt-bindings/power/mt6797-power.h
+- include/dt-bindings/power/mt6765-power.h
 - include/dt-bindings/power/mt2701-power.h
 - include/dt-bindings/power/mt2712-power.h
 - include/dt-bindings/power/mt7622-power.h
@@ -19,6 +20,7 @@ Required properties:
 - compatible: Should be one of:
 	- "mediatek,mt2701-scpsys"
 	- "mediatek,mt2712-scpsys"
+	- "mediatek,mt6765-scpsys"
 	- "mediatek,mt6797-scpsys"
 	- "mediatek,mt7622-scpsys"
 	- "mediatek,mt7623-scpsys", "mediatek,mt2701-scpsys": For MT7623 SoC
@@ -32,6 +34,10 @@ Required properties:
                       enabled before enabling certain power domains.
 	Required clocks for MT2701 or MT7623: "mm", "mfg", "ethif"
 	Required clocks for MT2712: "mm", "mfg", "venc", "jpgdec", "audio", "vdec"
+	Required clocks for MT6765: MUX: "mm", "mfg"
+				    CG: "mm-0", "mm-1", "mm-2", "mm-3", "isp-0",
+					"isp-1", "cam-0", "cam-1", "cam-2",
+					"cam-3","cam-4"
 	Required clocks for MT6797: "mm", "mfg", "vdec"
 	Required clocks for MT7622: "hif_sel"
 	Required clocks for MT7622A: "ethif"
-- 
1.7.9.5


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

* [PATCH v5 04/11] soc: mediatek: add MT6765 scpsys support
  2018-07-17  8:52 [PATCH v5 0/11] Add basic SoC support for mt6765 Mars Cheng
                   ` (2 preceding siblings ...)
  2018-07-17  8:52 ` [PATCH v5 03/11] dt-bindings: mediatek: add MT6765 power dt-bindings Mars Cheng
@ 2018-07-17  8:52 ` Mars Cheng
  2018-07-17 13:00   ` Sean Wang
  2018-07-20 17:46   ` Rob Herring
  2018-07-17  8:52 ` [PATCH v5 05/11] clk: mediatek: add mt6765 clock IDs Mars Cheng
                   ` (6 subsequent siblings)
  10 siblings, 2 replies; 32+ messages in thread
From: Mars Cheng @ 2018-07-17  8:52 UTC (permalink / raw)
  To: Matthias Brugger, Rob Herring, Marc Zyngier, Ryder Lee,
	Stephen Boyd, Sean Wang
  Cc: CC Hwang, Loda Chou, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, linux-serial, linux-arm-kernel, linux-clk,
	Mars Cheng, Owen Chen

This adds scpsys support for MT6765

Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
Signed-off-by: Owen Chen <owen.chen@mediatek.com>
---
 drivers/soc/mediatek/mtk-scpsys.c        |   88 ++++++++++++++++++++++++++++++
 include/dt-bindings/power/mt6765-power.h |   14 +++++
 2 files changed, 102 insertions(+)
 create mode 100644 include/dt-bindings/power/mt6765-power.h

diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
index 5b24bb4..4bb6c7a 100644
--- a/drivers/soc/mediatek/mtk-scpsys.c
+++ b/drivers/soc/mediatek/mtk-scpsys.c
@@ -23,6 +23,7 @@
 
 #include <dt-bindings/power/mt2701-power.h>
 #include <dt-bindings/power/mt2712-power.h>
+#include <dt-bindings/power/mt6765-power.h>
 #include <dt-bindings/power/mt6797-power.h>
 #include <dt-bindings/power/mt7622-power.h>
 #include <dt-bindings/power/mt7623a-power.h>
@@ -680,6 +681,79 @@ static void mtk_register_power_domains(struct platform_device *pdev,
 };
 
 /*
+ * MT6765 power domain support
+ */
+#define SPM_PWR_STATUS_MT6765			0x0180
+#define SPM_PWR_STATUS_2ND_MT6765		0x0184
+
+static const struct scp_domain_data scp_domain_data_mt6765[] = {
+	[MT6765_POWER_DOMAIN_VCODEC] = {
+		.name = "vcodec",
+		.sta_mask = BIT(26),
+		.ctl_offs = 0x300,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+	},
+	[MT6765_POWER_DOMAIN_ISP] = {
+		.name = "isp",
+		.sta_mask = BIT(5),
+		.ctl_offs = 0x308,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+	},
+	[MT6765_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),
+	},
+	[MT6765_POWER_DOMAIN_CONN] = {
+		.name = "conn",
+		.sta_mask = BIT(1),
+		.ctl_offs = 0x32C,
+		.sram_pdn_bits = 0,
+		.sram_pdn_ack_bits = 0,
+	},
+	[MT6765_POWER_DOMAIN_MFG_ASYNC] = {
+		.name = "mfg_async",
+		.sta_mask = BIT(23),
+		.ctl_offs = 0x334,
+		.sram_pdn_bits = 0,
+		.sram_pdn_ack_bits = 0,
+	},
+	[MT6765_POWER_DOMAIN_MFG] = {
+		.name = "mfg",
+		.sta_mask = BIT(4),
+		.ctl_offs = 0x338,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+	},
+	[MT6765_POWER_DOMAIN_CAM] = {
+		.name = "cam",
+		.sta_mask = BIT(25),
+		.ctl_offs = 0x344,
+		.sram_pdn_bits = GENMASK(8, 9),
+		.sram_pdn_ack_bits = GENMASK(12, 13),
+	},
+	[MT6765_POWER_DOMAIN_MFG_CORE0] = {
+		.name = "mfg_core0",
+		.sta_mask = BIT(7),
+		.ctl_offs = 0x34C,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+	},
+};
+
+static const struct scp_subdomain scp_subdomain_mt6765[] = {
+	{MT6765_POWER_DOMAIN_MM, MT6765_POWER_DOMAIN_CAM},
+	{MT6765_POWER_DOMAIN_MM, MT6765_POWER_DOMAIN_ISP},
+	{MT6765_POWER_DOMAIN_MM, MT6765_POWER_DOMAIN_VCODEC},
+	{MT6765_POWER_DOMAIN_MFG_ASYNC, MT6765_POWER_DOMAIN_MFG},
+	{MT6765_POWER_DOMAIN_MFG, MT6765_POWER_DOMAIN_MFG_CORE0},
+};
+
+/*
  * MT6797 power domain support
  */
 
@@ -962,6 +1036,17 @@ static void mtk_register_power_domains(struct platform_device *pdev,
 	.bus_prot_reg_update = false,
 };
 
+static const struct scp_soc_data mt6765_data = {
+	.domains = scp_domain_data_mt6765,
+	.num_domains = ARRAY_SIZE(scp_domain_data_mt6765),
+	.subdomains = scp_subdomain_mt6765,
+	.num_subdomains = ARRAY_SIZE(scp_subdomain_mt6765),
+	.regs = {
+		.pwr_sta_offs = SPM_PWR_STATUS_MT6765,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6765,
+	},
+};
+
 static const struct scp_soc_data mt6797_data = {
 	.domains = scp_domain_data_mt6797,
 	.num_domains = ARRAY_SIZE(scp_domain_data_mt6797),
@@ -1018,6 +1103,9 @@ static void mtk_register_power_domains(struct platform_device *pdev,
 		.compatible = "mediatek,mt2712-scpsys",
 		.data = &mt2712_data,
 	}, {
+		.compatible = "mediatek,mt6765-scpsys",
+		.data = &mt6765_data,
+	}, {
 		.compatible = "mediatek,mt6797-scpsys",
 		.data = &mt6797_data,
 	}, {
diff --git a/include/dt-bindings/power/mt6765-power.h b/include/dt-bindings/power/mt6765-power.h
new file mode 100644
index 0000000..d347b4e
--- /dev/null
+++ b/include/dt-bindings/power/mt6765-power.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _DT_BINDINGS_POWER_MT6765_POWER_H
+#define _DT_BINDINGS_POWER_MT6765_POWER_H
+
+#define MT6765_POWER_DOMAIN_CONN		0
+#define MT6765_POWER_DOMAIN_MM			1
+#define MT6765_POWER_DOMAIN_MFG_ASYNC		2
+#define MT6765_POWER_DOMAIN_ISP			3
+#define MT6765_POWER_DOMAIN_MFG			4
+#define MT6765_POWER_DOMAIN_MFG_CORE0		5
+#define MT6765_POWER_DOMAIN_CAM			6
+#define MT6765_POWER_DOMAIN_VCODEC		7
+
+#endif /* _DT_BINDINGS_POWER_MT6765_POWER_H */
-- 
1.7.9.5


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

* [PATCH v5 05/11] clk: mediatek: add mt6765 clock IDs
  2018-07-17  8:52 [PATCH v5 0/11] Add basic SoC support for mt6765 Mars Cheng
                   ` (3 preceding siblings ...)
  2018-07-17  8:52 ` [PATCH v5 04/11] soc: mediatek: add MT6765 scpsys support Mars Cheng
@ 2018-07-17  8:52 ` Mars Cheng
  2018-07-17 10:24   ` Matthias Brugger
  2018-07-17  8:52 ` [PATCH v5 06/11] soc: mediatek: add new flow for mtcmos power Mars Cheng
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 32+ messages in thread
From: Mars Cheng @ 2018-07-17  8:52 UTC (permalink / raw)
  To: Matthias Brugger, Rob Herring, Marc Zyngier, Ryder Lee,
	Stephen Boyd, Sean Wang
  Cc: CC Hwang, Loda Chou, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, linux-serial, linux-arm-kernel, linux-clk,
	Mars Cheng, Owen Chen

Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
Signed-off-by: Owen Chen <owen.chen@mediatek.com>
---
 include/dt-bindings/clock/mt6765-clk.h |  313 ++++++++++++++++++++++++++++++++
 1 file changed, 313 insertions(+)
 create mode 100644 include/dt-bindings/clock/mt6765-clk.h

diff --git a/include/dt-bindings/clock/mt6765-clk.h b/include/dt-bindings/clock/mt6765-clk.h
new file mode 100644
index 0000000..eb97e56
--- /dev/null
+++ b/include/dt-bindings/clock/mt6765-clk.h
@@ -0,0 +1,313 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _DT_BINDINGS_CLK_MT6765_H
+#define _DT_BINDINGS_CLK_MT6765_H
+
+/* FIX Clks */
+#define CLK_TOP_CLK26M			0
+
+/* APMIXEDSYS */
+#define CLK_APMIXED_ARMPLL_L		0
+#define CLK_APMIXED_ARMPLL		1
+#define CLK_APMIXED_CCIPLL		2
+#define CLK_APMIXED_MAINPLL		3
+#define CLK_APMIXED_MFGPLL		4
+#define CLK_APMIXED_MMPLL		5
+#define CLK_APMIXED_UNIV2PLL		6
+#define CLK_APMIXED_MSDCPLL		7
+#define CLK_APMIXED_APLL1		8
+#define CLK_APMIXED_MPLL		9
+#define CLK_APMIXED_ULPOSC1		10
+#define CLK_APMIXED_ULPOSC2		11
+#define CLK_APMIXED_SSUSB26M		12
+#define CLK_APMIXED_APPLL26M		13
+#define CLK_APMIXED_MIPIC0_26M		14
+#define CLK_APMIXED_MDPLLGP26M		15
+#define CLK_APMIXED_MMSYS_F26M		16
+#define CLK_APMIXED_UFS26M		17
+#define CLK_APMIXED_MIPIC1_26M		18
+#define CLK_APMIXED_MEMPLL26M		19
+#define CLK_APMIXED_CLKSQ_LVPLL_26M	20
+#define CLK_APMIXED_MIPID0_26M		21
+#define CLK_APMIXED_NR_CLK		22
+
+/* TOPCKGEN */
+#define CLK_TOP_SYSPLL			0
+#define CLK_TOP_SYSPLL_D2		1
+#define CLK_TOP_SYSPLL1_D2		2
+#define CLK_TOP_SYSPLL1_D4		3
+#define CLK_TOP_SYSPLL1_D8		4
+#define CLK_TOP_SYSPLL1_D16		5
+#define CLK_TOP_SYSPLL_D3		6
+#define CLK_TOP_SYSPLL2_D2		7
+#define CLK_TOP_SYSPLL2_D4		8
+#define CLK_TOP_SYSPLL2_D8		9
+#define CLK_TOP_SYSPLL_D5		10
+#define CLK_TOP_SYSPLL3_D2		11
+#define CLK_TOP_SYSPLL3_D4		12
+#define CLK_TOP_SYSPLL_D7		13
+#define CLK_TOP_SYSPLL4_D2		14
+#define CLK_TOP_SYSPLL4_D4		15
+#define CLK_TOP_USB20_192M		16
+#define CLK_TOP_USB20_192M_D4		17
+#define CLK_TOP_USB20_192M_D8		18
+#define CLK_TOP_USB20_192M_D16		19
+#define CLK_TOP_USB20_192M_D32		20
+#define CLK_TOP_UNIVPLL			21
+#define CLK_TOP_UNIVPLL_D2		22
+#define CLK_TOP_UNIVPLL1_D2		23
+#define CLK_TOP_UNIVPLL1_D4		24
+#define CLK_TOP_UNIVPLL_D3		25
+#define CLK_TOP_UNIVPLL2_D2		26
+#define CLK_TOP_UNIVPLL2_D4		27
+#define CLK_TOP_UNIVPLL2_D8		28
+#define CLK_TOP_UNIVPLL2_D32		29
+#define CLK_TOP_UNIVPLL_D5		30
+#define CLK_TOP_UNIVPLL3_D2		31
+#define CLK_TOP_UNIVPLL3_D4		32
+#define CLK_TOP_MMPLL			33
+#define CLK_TOP_MMPLL_D2		34
+#define CLK_TOP_MPLL			35
+#define CLK_TOP_DA_MPLL_104M_DIV	36
+#define CLK_TOP_DA_MPLL_52M_DIV		37
+#define CLK_TOP_MFGPLL			38
+#define CLK_TOP_MSDCPLL			39
+#define CLK_TOP_MSDCPLL_D2		40
+#define CLK_TOP_APLL1			41
+#define CLK_TOP_APLL1_D2		42
+#define CLK_TOP_APLL1_D4		43
+#define CLK_TOP_APLL1_D8		44
+#define CLK_TOP_ULPOSC1			45
+#define CLK_TOP_ULPOSC1_D2		46
+#define CLK_TOP_ULPOSC1_D4		47
+#define CLK_TOP_ULPOSC1_D8		48
+#define CLK_TOP_ULPOSC1_D16		49
+#define CLK_TOP_ULPOSC1_D32		50
+#define CLK_TOP_DMPLL			51
+#define CLK_TOP_F_FRTC			52
+#define CLK_TOP_F_F26M			53
+#define CLK_TOP_AXI			54
+#define CLK_TOP_MM			55
+#define CLK_TOP_SCP			56
+#define CLK_TOP_MFG			57
+#define CLK_TOP_F_FUART			58
+#define CLK_TOP_SPI			59
+#define CLK_TOP_MSDC50_0		60
+#define CLK_TOP_MSDC30_1		61
+#define CLK_TOP_AUDIO			62
+#define CLK_TOP_AUD_1			63
+#define CLK_TOP_AUD_ENGEN1		64
+#define CLK_TOP_F_FDISP_PWM		65
+#define CLK_TOP_SSPM			66
+#define CLK_TOP_DXCC			67
+#define CLK_TOP_I2C			68
+#define CLK_TOP_F_FPWM			69
+#define CLK_TOP_F_FSENINF		70
+#define CLK_TOP_AES_FDE			71
+#define CLK_TOP_F_BIST2FPC		72
+#define CLK_TOP_ARMPLL_DIVIDER_PLL0	73
+#define CLK_TOP_ARMPLL_DIVIDER_PLL1	74
+#define CLK_TOP_ARMPLL_DIVIDER_PLL2	75
+#define CLK_TOP_DA_USB20_48M_DIV	76
+#define CLK_TOP_DA_UNIV_48M_DIV		77
+#define CLK_TOP_APLL12_DIV0		78
+#define CLK_TOP_APLL12_DIV1		79
+#define CLK_TOP_APLL12_DIV2		80
+#define CLK_TOP_APLL12_DIV3		81
+#define CLK_TOP_ARMPLL_DIVIDER_PLL0_EN	82
+#define CLK_TOP_ARMPLL_DIVIDER_PLL1_EN	83
+#define CLK_TOP_ARMPLL_DIVIDER_PLL2_EN	84
+#define CLK_TOP_FMEM_OCC_DRC_EN		85
+#define CLK_TOP_USB20_48M_EN		86
+#define CLK_TOP_UNIVPLL_48M_EN		87
+#define CLK_TOP_MPLL_104M_EN		88
+#define CLK_TOP_MPLL_52M_EN		89
+#define CLK_TOP_F_UFS_MP_SAP_CFG_EN	90
+#define CLK_TOP_F_BIST2FPC_EN		91
+#define CLK_TOP_MD_32K			92
+#define CLK_TOP_MD_26M			93
+#define CLK_TOP_MD2_32K			94
+#define CLK_TOP_MD2_26M			95
+#define CLK_TOP_AXI_SEL			96
+#define CLK_TOP_MEM_SEL			97
+#define CLK_TOP_MM_SEL			98
+#define CLK_TOP_SCP_SEL			99
+#define CLK_TOP_MFG_SEL			100
+#define CLK_TOP_ATB_SEL			101
+#define CLK_TOP_CAMTG_SEL		102
+#define CLK_TOP_CAMTG1_SEL		103
+#define CLK_TOP_CAMTG2_SEL		104
+#define CLK_TOP_CAMTG3_SEL		105
+#define CLK_TOP_UART_SEL		106
+#define CLK_TOP_SPI_SEL			107
+#define CLK_TOP_MSDC50_0_HCLK_SEL	108
+#define CLK_TOP_MSDC50_0_SEL		109
+#define CLK_TOP_MSDC30_1_SEL		110
+#define CLK_TOP_AUDIO_SEL		111
+#define CLK_TOP_AUD_INTBUS_SEL		112
+#define CLK_TOP_AUD_1_SEL		113
+#define CLK_TOP_AUD_ENGEN1_SEL		114
+#define CLK_TOP_DISP_PWM_SEL		115
+#define CLK_TOP_SSPM_SEL		116
+#define CLK_TOP_DXCC_SEL		117
+#define CLK_TOP_USB_TOP_SEL		118
+#define CLK_TOP_SPM_SEL			119
+#define CLK_TOP_I2C_SEL			120
+#define CLK_TOP_PWM_SEL			121
+#define CLK_TOP_SENINF_SEL		122
+#define CLK_TOP_AES_FDE_SEL		123
+#define CLK_TOP_PWRAP_ULPOSC_SEL	124
+#define CLK_TOP_CAMTM_SEL		125
+#define CLK_TOP_NR_CLK			126
+
+/* INFRACFG */
+#define CLK_IFR_ICUSB			0
+#define CLK_IFR_GCE			1
+#define CLK_IFR_THERM			2
+#define CLK_IFR_I2C_AP			3
+#define CLK_IFR_I2C_CCU			4
+#define CLK_IFR_I2C_SSPM		5
+#define CLK_IFR_I2C_RSV			6
+#define CLK_IFR_PWM_HCLK		7
+#define CLK_IFR_PWM1			8
+#define CLK_IFR_PWM2			9
+#define CLK_IFR_PWM3			10
+#define CLK_IFR_PWM4			11
+#define CLK_IFR_PWM5			12
+#define CLK_IFR_PWM			13
+#define CLK_IFR_UART0			14
+#define CLK_IFR_UART1			15
+#define CLK_IFR_GCE_26M			16
+#define CLK_IFR_CQ_DMA_FPC		17
+#define CLK_IFR_BTIF			18
+#define CLK_IFR_SPI0			19
+#define CLK_IFR_MSDC0			20
+#define CLK_IFR_MSDC1			21
+#define CLK_IFR_TRNG			22
+#define CLK_IFR_AUXADC			23
+#define CLK_IFR_CCIF1_AP		24
+#define CLK_IFR_CCIF1_MD		25
+#define CLK_IFR_AUXADC_MD		26
+#define CLK_IFR_AP_DMA			27
+#define CLK_IFR_DEVICE_APC		28
+#define CLK_IFR_CCIF_AP			29
+#define CLK_IFR_AUDIO			30
+#define CLK_IFR_CCIF_MD			31
+#define CLK_IFR_RG_PWM_FBCLK6		32
+#define CLK_IFR_DISP_PWM		33
+#define CLK_IFR_CLDMA_BCLK		34
+#define CLK_IFR_AUDIO_26M_BCLK		35
+#define CLK_IFR_SPI1			36
+#define CLK_IFR_I2C4			37
+#define CLK_IFR_SPI2			38
+#define CLK_IFR_SPI3			39
+#define CLK_IFR_I2C5			40
+#define CLK_IFR_I2C5_ARBITER		41
+#define CLK_IFR_I2C5_IMM		42
+#define CLK_IFR_I2C1_ARBITER		43
+#define CLK_IFR_I2C1_IMM		44
+#define CLK_IFR_I2C2_ARBITER		45
+#define CLK_IFR_I2C2_IMM		46
+#define CLK_IFR_SPI4			47
+#define CLK_IFR_SPI5			48
+#define CLK_IFR_CQ_DMA			49
+#define CLK_IFR_FAES_FDE		50
+#define CLK_IFR_MSDC0_SELF		51
+#define CLK_IFR_MSDC1_SELF		52
+#define CLK_IFR_I2C6			53
+#define CLK_IFR_AP_MSDC0		54
+#define CLK_IFR_MD_MSDC0		55
+#define CLK_IFR_MSDC0_SRC		56
+#define CLK_IFR_MSDC1_SRC		57
+#define CLK_IFR_AES_TOP0_BCLK		58
+#define CLK_IFR_MCU_PM_BCLK		59
+#define CLK_IFR_CCIF2_AP		60
+#define CLK_IFR_CCIF2_MD		61
+#define CLK_IFR_CCIF3_AP		62
+#define CLK_IFR_CCIF3_MD		63
+#define CLK_IFR_NR_CLK			64
+
+/* AUDIO */
+#define CLK_AUDIO_AFE			0
+#define CLK_AUDIO_22M			1
+#define CLK_AUDIO_APLL_TUNER		2
+#define CLK_AUDIO_ADC			3
+#define CLK_AUDIO_DAC			4
+#define CLK_AUDIO_DAC_PREDIS		5
+#define CLK_AUDIO_TML			6
+#define CLK_AUDIO_I2S1_BCLK		7
+#define CLK_AUDIO_I2S2_BCLK		8
+#define CLK_AUDIO_I2S3_BCLK		9
+#define CLK_AUDIO_I2S4_BCLK		10
+#define CLK_AUDIO_NR_CLK		11
+
+/* MIPI_RX_ANA_CSI0A */
+
+#define CLK_MIPI0A_CSR_CSI_EN_0A	0
+#define CLK_MIPI0A_NR_CLK		1
+
+/* MMSYS_CONFIG */
+
+#define CLK_MM_MDP_RDMA0		0
+#define CLK_MM_MDP_CCORR0		1
+#define CLK_MM_MDP_RSZ0			2
+#define CLK_MM_MDP_RSZ1			3
+#define CLK_MM_MDP_TDSHP0		4
+#define CLK_MM_MDP_WROT0		5
+#define CLK_MM_MDP_WDMA0		6
+#define CLK_MM_DISP_OVL0		7
+#define CLK_MM_DISP_OVL0_2L		8
+#define CLK_MM_DISP_RSZ0		9
+#define CLK_MM_DISP_RDMA0		10
+#define CLK_MM_DISP_WDMA0		11
+#define CLK_MM_DISP_COLOR0		12
+#define CLK_MM_DISP_CCORR0		13
+#define CLK_MM_DISP_AAL0		14
+#define CLK_MM_DISP_GAMMA0		15
+#define CLK_MM_DISP_DITHER0		16
+#define CLK_MM_DSI0			17
+#define CLK_MM_FAKE_ENG			18
+#define CLK_MM_SMI_COMMON		19
+#define CLK_MM_SMI_LARB0		20
+#define CLK_MM_SMI_COMM0		21
+#define CLK_MM_SMI_COMM1		22
+#define CLK_MM_CAM_MDP			23
+#define CLK_MM_SMI_IMG			24
+#define CLK_MM_SMI_CAM			25
+#define CLK_MM_IMG_DL_RELAY		26
+#define CLK_MM_IMG_DL_ASYNC_TOP		27
+#define CLK_MM_DIG_DSI			28
+#define CLK_MM_F26M_HRTWT		29
+#define CLK_MM_NR_CLK			30
+
+/* IMGSYS */
+
+#define CLK_IMG_LARB2			0
+#define CLK_IMG_DIP			1
+#define CLK_IMG_FDVT			2
+#define CLK_IMG_DPE			3
+#define CLK_IMG_RSC			4
+#define CLK_IMG_NR_CLK			5
+
+/* VENCSYS */
+
+#define CLK_VENC_SET0_LARB		0
+#define CLK_VENC_SET1_VENC		1
+#define CLK_VENC_SET2_JPGENC		2
+#define CLK_VENC_SET3_VDEC		3
+#define CLK_VENC_NR_CLK			4
+
+/* CAMSYS */
+
+#define CLK_CAM_LARB3			0
+#define CLK_CAM_DFP_VAD			1
+#define CLK_CAM				2
+#define CLK_CAMTG			3
+#define CLK_CAM_SENINF			4
+#define CLK_CAMSV0			5
+#define CLK_CAMSV1			6
+#define CLK_CAMSV2			7
+#define CLK_CAM_CCU			8
+#define CLK_CAM_NR_CLK			9
+
+#endif /* _DT_BINDINGS_CLK_MT6765_H */
-- 
1.7.9.5


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

* [PATCH v5 06/11] soc: mediatek: add new flow for mtcmos power.
  2018-07-17  8:52 [PATCH v5 0/11] Add basic SoC support for mt6765 Mars Cheng
                   ` (4 preceding siblings ...)
  2018-07-17  8:52 ` [PATCH v5 05/11] clk: mediatek: add mt6765 clock IDs Mars Cheng
@ 2018-07-17  8:52 ` Mars Cheng
  2018-07-17 15:49   ` kbuild test robot
                     ` (4 more replies)
  2018-07-17  8:52 ` [PATCH v5 07/11] soc: mediatek: add MT6765 subdomain support Mars Cheng
                   ` (4 subsequent siblings)
  10 siblings, 5 replies; 32+ messages in thread
From: Mars Cheng @ 2018-07-17  8:52 UTC (permalink / raw)
  To: Matthias Brugger, Rob Herring, Marc Zyngier, Ryder Lee,
	Stephen Boyd, Sean Wang
  Cc: CC Hwang, Loda Chou, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, linux-serial, linux-arm-kernel, linux-clk,
	Owen Chen, Mars Cheng

From: Owen Chen <owen.chen@mediatek.com>

MT6765 need multiple register and actions to setup bus
protect.
1. turn on subsys CG before release bus protect to receive
   ack.
2. turn off subsys CG after set bus protect and receive
   ack.
3. bus protect need not only infracfg but other domain
   register to setup. Therefore we add a set/clr APIs
   with more customize arguments.

Signed-off-by: Owen Chen <owen.chen@mediatek.com>
Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
---
 drivers/soc/mediatek/Makefile           |    2 +-
 drivers/soc/mediatek/mtk-infracfg.c     |  178 +++++++++++---
 drivers/soc/mediatek/mtk-scpsys-ext.c   |  405 +++++++++++++++++++++++++++++++
 drivers/soc/mediatek/mtk-scpsys.c       |  147 +++++++++--
 include/linux/soc/mediatek/infracfg.h   |    9 +-
 include/linux/soc/mediatek/scpsys-ext.h |   66 +++++
 6 files changed, 745 insertions(+), 62 deletions(-)
 create mode 100644 drivers/soc/mediatek/mtk-scpsys-ext.c
 create mode 100644 include/linux/soc/mediatek/scpsys-ext.h

diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 12998b0..9dc6670 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,3 +1,3 @@
-obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
+obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o mtk-scpsys-ext.o
 obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
 obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-infracfg.c b/drivers/soc/mediatek/mtk-infracfg.c
index 958861c..11eadf8 100644
--- a/drivers/soc/mediatek/mtk-infracfg.c
+++ b/drivers/soc/mediatek/mtk-infracfg.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de>
  *
@@ -15,6 +16,7 @@
 #include <linux/jiffies.h>
 #include <linux/regmap.h>
 #include <linux/soc/mediatek/infracfg.h>
+#include <linux/soc/mediatek/scpsys-ext.h>
 #include <asm/processor.h>
 
 #define MTK_POLL_DELAY_US   10
@@ -26,62 +28,176 @@
 #define INFRA_TOPAXI_PROTECTEN_CLR	0x0264
 
 /**
- * mtk_infracfg_set_bus_protection - enable bus protection
- * @regmap: The infracfg regmap
- * @mask: The mask containing the protection bits to be enabled.
- * @reg_update: The boolean flag determines to set the protection bits
- *              by regmap_update_bits with enable register(PROTECTEN) or
- *              by regmap_write with set register(PROTECTEN_SET).
+ * mtk_generic_set_cmd - enable bus protection with set register
+ * @regmap: The bus protect regmap
+ * @set_ofs: The set register offset to set corresponding bit to 1.
+ * @sta_ofs: The status register offset to show bus protect enable/disable.
+ * @mask: The mask containing the protection bits to be disabled.
  *
  * This function enables the bus protection bits for disabled power
  * domains so that the system does not hang when some unit accesses the
  * bus while in power down.
  */
-int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask,
-		bool reg_update)
+int mtk_generic_set_cmd(struct regmap *regmap, u32 set_ofs,
+			u32 sta_ofs, u32 mask)
 {
 	u32 val;
 	int ret;
 
-	if (reg_update)
-		regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask,
-				mask);
-	else
-		regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_SET, mask);
+	regmap_write(regmap, set_ofs, mask);
 
-	ret = regmap_read_poll_timeout(infracfg, INFRA_TOPAXI_PROTECTSTA1,
-				       val, (val & mask) == mask,
-				       MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
+	ret = regmap_read_poll_timeout(regmap, sta_ofs, val,
+				       (val & mask) == mask,
+				       MTK_POLL_DELAY_US,
+				       MTK_POLL_TIMEOUT);
 
 	return ret;
 }
 
 /**
- * mtk_infracfg_clear_bus_protection - disable bus protection
- * @regmap: The infracfg regmap
+ * mtk_generic_clr_cmd - disable bus protection  with clr register
+ * @regmap: The bus protect regmap
+ * @clr_ofs: The clr register offset to clear corresponding bit to 0.
+ * @sta_ofs: The status register offset to show bus protect enable/disable.
  * @mask: The mask containing the protection bits to be disabled.
- * @reg_update: The boolean flag determines to clear the protection bits
- *              by regmap_update_bits with enable register(PROTECTEN) or
- *              by regmap_write with clear register(PROTECTEN_CLR).
  *
  * This function disables the bus protection bits previously enabled with
- * mtk_infracfg_set_bus_protection.
+ * mtk_set_bus_protection.
  */
 
-int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask,
-		bool reg_update)
+int mtk_generic_clr_cmd(struct regmap *regmap, u32 clr_ofs,
+			u32 sta_ofs, u32 mask)
 {
 	int ret;
 	u32 val;
 
-	if (reg_update)
-		regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, 0);
-	else
-		regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_CLR, mask);
+	regmap_write(regmap, clr_ofs, mask);
 
-	ret = regmap_read_poll_timeout(infracfg, INFRA_TOPAXI_PROTECTSTA1,
-				       val, !(val & mask),
-				       MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
+	ret = regmap_read_poll_timeout(regmap, sta_ofs, val,
+				       !(val & mask),
+				       MTK_POLL_DELAY_US,
+				       MTK_POLL_TIMEOUT);
+	return ret;
+}
+
+/**
+ * mtk_generic_enable_cmd - enable bus protection with upd register
+ * @regmap: The bus protect regmap
+ * @upd_ofs: The update register offset to directly rewrite value to
+ *              corresponding bit.
+ * @sta_ofs: The status register offset to show bus protect enable/disable.
+ * @mask: The mask containing the protection bits to be disabled.
+ *
+ * This function enables the bus protection bits for disabled power
+ * domains so that the system does not hang when some unit accesses the
+ * bus while in power down.
+ */
+int mtk_generic_enable_cmd(struct regmap *regmap, u32 upd_ofs,
+			   u32 sta_ofs, u32 mask)
+{
+	u32 val;
+	int ret;
+
+	regmap_update_bits(regmap, upd_ofs, mask, mask);
 
+	ret = regmap_read_poll_timeout(regmap, sta_ofs, val,
+				       (val & mask) == mask,
+				       MTK_POLL_DELAY_US,
+				       MTK_POLL_TIMEOUT);
 	return ret;
 }
+
+/**
+ * mtk_generic_disable_cmd - disable bus protection with updd register
+ * @regmap: The bus protect regmap
+ * @upd_ofs: The update register offset to directly rewrite value to
+ *              corresponding bit.
+ * @sta_ofs: The status register offset to show bus protect enable/disable.
+ * @mask: The mask containing the protection bits to be disabled.
+ *
+ * This function disables the bus protection bits previously enabled with
+ * mtk_set_bus_protection.
+ */
+
+int mtk_generic_disable_cmd(struct regmap *regmap, u32 upd_ofs,
+			    u32 sta_ofs, u32 mask)
+{
+	int ret;
+	u32 val;
+
+	regmap_update_bits(regmap, upd_ofs, mask, 0);
+
+	ret = regmap_read_poll_timeout(regmap, sta_ofs,
+				       val, !(val & mask),
+				       MTK_POLL_DELAY_US,
+				       MTK_POLL_TIMEOUT);
+	return ret;
+}
+
+/**
+ * mtk_set_bus_protection - enable bus protection
+ * @infracfg: The bus protect regmap, default use infracfg
+ * @mask: The mask containing the protection bits to be enabled.
+ *
+ * This function enables the bus protection bits for disabled power
+ * domains so that the system does not hang when some unit accesses the
+ * bus while in power down.
+ */
+int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask)
+{
+	return mtk_generic_set_cmd(infracfg,
+				   INFRA_TOPAXI_PROTECTEN_SET,
+				   INFRA_TOPAXI_PROTECTSTA1,
+				   mask);
+}
+
+/**
+ * mtk_clear_bus_protection - disable bus protection
+ * @infracfg: The bus protect regmap, default use infracfg
+ * @mask: The mask containing the protection bits to be disabled.
+ *
+ * This function disables the bus protection bits previously enabled with
+ * mtk_set_bus_protection.
+ */
+
+int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask)
+{
+	return mtk_generic_clr_cmd(infracfg,
+				   INFRA_TOPAXI_PROTECTEN_CLR,
+				   INFRA_TOPAXI_PROTECTSTA1,
+				   mask);
+}
+
+/**
+ * mtk_infracfg_enable_bus_protection - enable bus protection
+ * @infracfg: The bus protect regmap, default use infracfg
+ * @mask: The mask containing the protection bits to be disabled.
+ *
+ * This function enables the bus protection bits for disabled power
+ * domains so that the system does not hang when some unit accesses the
+ * bus while in power down.
+ */
+int mtk_infracfg_enable_bus_protection(struct regmap *infracfg, u32 mask)
+{
+	return mtk_generic_enable_cmd(infracfg,
+				      INFRA_TOPAXI_PROTECTEN,
+				      INFRA_TOPAXI_PROTECTSTA1,
+				      mask);
+}
+
+/**
+ * mtk_infracfg_disable_bus_protection - disable bus protection
+ * @infracfg: The bus protect regmap, default use infracfg
+ * @mask: The mask containing the protection bits to be disabled.
+ *
+ * This function disables the bus protection bits previously enabled with
+ * mtk_infracfg_set_bus_protection.
+ */
+
+int mtk_infracfg_disable_bus_protection(struct regmap *infracfg, u32 mask)
+{
+	return mtk_generic_disable_cmd(infracfg,
+				       INFRA_TOPAXI_PROTECTEN,
+				       INFRA_TOPAXI_PROTECTSTA1,
+				       mask);
+}
diff --git a/drivers/soc/mediatek/mtk-scpsys-ext.c b/drivers/soc/mediatek/mtk-scpsys-ext.c
new file mode 100644
index 0000000..965e64d
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-scpsys-ext.c
@@ -0,0 +1,405 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Owen Chen <owen.chen@mediatek.com>
+ */
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/slab.h>
+#include <linux/export.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/soc/mediatek/infracfg.h>
+#include <linux/soc/mediatek/scpsys-ext.h>
+
+
+#define MAX_CLKS		10
+#define INFRA			"infracfg"
+#define SMIC			"smi_comm"
+
+static LIST_HEAD(ext_clk_map_list);
+static LIST_HEAD(ext_attr_map_list);
+
+static struct regmap *infracfg;
+static struct regmap *smi_comm;
+
+enum regmap_type {
+	IFR_TYPE,
+	SMI_TYPE,
+	MAX_REGMAP_TYPE,
+};
+
+/**
+ * struct ext_reg_ctrl - set multiple register for bus protect
+ * @regmap: The bus protect regmap, 1: infracfg, 2: other master regmap
+ *                  such as SMI.
+ * @set_ofs: The set register offset to set corresponding bit to 1.
+ * @clr_ofs: The clr register offset to clear corresponding bit to 0.
+ * @sta_ofs: The status register offset to show bus protect enable/disable.
+ */
+struct ext_reg_ctrl {
+	enum regmap_type type;
+	u32 set_ofs;
+	u32 clr_ofs;
+	u32 sta_ofs;
+};
+
+/**
+ * struct ext_clk_ctrl - enable multiple clks for bus protect
+ * @clk: The clk need to enable before pwr on/bus protect.
+ * @scpd_n: The name present the scpsys domain where the clks belongs to.
+ * @clk_list: The list node linked to ext_clk_map_list.
+ */
+struct ext_clk_ctrl {
+	struct clk *clk;
+	const char *scpd_n;
+	struct list_head clk_list;
+};
+
+struct bus_mask_ops {
+	int	(*set)(struct regmap *regmap, u32 set_ofs,
+		       u32 sta_ofs, u32 mask);
+	int	(*release)(struct regmap *regmap, u32 clr_ofs,
+			   u32 sta_ofs, u32 mask);
+};
+
+static struct scpsys_ext_attr *__get_attr_parent(const char *parent_n)
+{
+	struct scpsys_ext_attr *attr;
+
+	if (!parent_n)
+		return ERR_PTR(-EINVAL);
+
+	list_for_each_entry(attr, &ext_attr_map_list, attr_list) {
+		if (attr->scpd_n && !strcmp(parent_n, attr->scpd_n))
+			return attr;
+	}
+
+	return ERR_PTR(-EINVAL);
+}
+
+int bus_ctrl_set_release(struct scpsys_ext_attr *attr, bool set)
+{
+	int i;
+	int ret = 0;
+
+	for (i = 0; i < MAX_STEP_NUM && attr->mask[i].mask; i++) {
+		struct ext_reg_ctrl *rc = attr->mask[i].regs;
+		struct regmap *regmap;
+
+		if (rc->type == IFR_TYPE)
+			regmap = infracfg;
+		else if (rc->type == SMI_TYPE)
+			regmap = smi_comm;
+		else
+			return -EINVAL;
+
+		if (set)
+			ret = attr->mask[i].ops->set(regmap,
+						rc->set_ofs,
+						rc->sta_ofs,
+						attr->mask[i].mask);
+		else
+			ret = attr->mask[i].ops->release(regmap,
+						rc->clr_ofs,
+						rc->sta_ofs,
+						attr->mask[i].mask);
+	}
+
+	return ret;
+}
+
+int bus_ctrl_set(struct scpsys_ext_attr *attr)
+{
+	return bus_ctrl_set_release(attr, CMD_ENABLE);
+}
+
+int bus_ctrl_release(struct scpsys_ext_attr *attr)
+{
+	return bus_ctrl_set_release(attr, CMD_DISABLE);
+}
+
+int bus_clk_enable_disable(struct scpsys_ext_attr *attr, bool enable)
+{
+	int i = 0;
+	int ret = 0;
+	struct ext_clk_ctrl *cc;
+	struct clk *clk[MAX_CLKS];
+
+	list_for_each_entry(cc, &ext_clk_map_list, clk_list) {
+		if (!strcmp(cc->scpd_n, attr->scpd_n)) {
+			if (enable)
+				ret = clk_prepare_enable(cc->clk);
+			else
+				clk_disable_unprepare(cc->clk);
+
+			if (ret) {
+				pr_err("Failed to  %s %s\n",
+				       enable ? "enable" : "disable",
+				       __clk_get_name(cc->clk));
+				goto err;
+			} else {
+				clk[i] = cc->clk;
+				i++;
+			}
+		}
+	}
+
+	return ret;
+
+err:
+	for (--i; i >= 0; i--)
+		if (enable)
+			clk_disable_unprepare(clk[i]);
+		else
+			clk_prepare_enable(clk[i]);
+	return ret;
+}
+
+int bus_clk_enable(struct scpsys_ext_attr *attr)
+{
+	struct scpsys_ext_attr *attr_p;
+	int ret = 0;
+
+	attr_p = __get_attr_parent(attr->parent_n);
+	if (!IS_ERR(attr_p)) {
+		ret = bus_clk_enable_disable(attr_p, CMD_ENABLE);
+		if (ret)
+			return ret;
+	}
+
+	return bus_clk_enable_disable(attr, CMD_ENABLE);
+}
+
+int bus_clk_disable(struct scpsys_ext_attr *attr)
+{
+	struct scpsys_ext_attr *attr_p;
+	int ret = 0;
+
+	ret = bus_clk_enable_disable(attr, CMD_DISABLE);
+	if (ret)
+		return ret;
+
+	attr_p = __get_attr_parent(attr->parent_n);
+	if (!IS_ERR(attr_p))
+		ret = bus_clk_enable_disable(attr_p, CMD_DISABLE);
+
+	return ret;
+}
+
+const struct bus_mask_ops bus_mask_set_clr_ctrl = {
+	.set = &mtk_generic_set_cmd,
+	.release = &mtk_generic_clr_cmd,
+};
+
+const struct bus_ext_ops ext_bus_ctrl = {
+	.enable = &bus_ctrl_set,
+	.disable = &bus_ctrl_release,
+};
+
+const struct bus_ext_ops ext_cg_ctrl = {
+	.enable = &bus_clk_enable,
+	.disable = &bus_clk_disable,
+};
+
+/*
+ * scpsys bus driver init
+ */
+struct regmap *syscon_regmap_lookup_by_phandle_idx(struct device_node *np,
+						   const char *property,
+						   int index)
+{
+	struct device_node *syscon_np;
+	struct regmap *regmap;
+
+	if (property)
+		syscon_np = of_parse_phandle(np, property, index);
+	else
+		syscon_np = np;
+
+	if (!syscon_np)
+		return ERR_PTR(-ENODEV);
+
+	regmap = syscon_node_to_regmap(syscon_np);
+	of_node_put(syscon_np);
+
+	return regmap;
+}
+
+int scpsys_ext_regmap_init(struct platform_device *pdev)
+{
+	infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
+						   INFRA);
+	if (IS_ERR(infracfg)) {
+		dev_err(&pdev->dev,
+			"Cannot find bus infracfg controller: %ld\n",
+			PTR_ERR(infracfg));
+		return PTR_ERR(infracfg);
+	}
+
+	smi_comm = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
+						   SMIC);
+	if (IS_ERR(smi_comm)) {
+		dev_err(&pdev->dev,
+			"Cannot find bus smi_comm controller: %ld\n",
+			PTR_ERR(smi_comm));
+		return PTR_ERR(smi_comm);
+	}
+
+	return 0;
+}
+
+static int add_clk_to_list(struct platform_device *pdev,
+			   const char *name,
+			   const char *scpd_n)
+{
+	struct clk *clk;
+	struct ext_clk_ctrl *cc;
+
+	clk = devm_clk_get(&pdev->dev, name);
+	if (IS_ERR(clk)) {
+		dev_err(&pdev->dev, "Failed add clk %ld\n", PTR_ERR(clk));
+		return PTR_ERR(clk);
+	}
+
+	cc = kzalloc(sizeof(*cc), GFP_KERNEL);
+	cc->clk = clk;
+	cc->scpd_n = kstrdup(scpd_n, GFP_KERNEL);
+
+	list_add(&cc->clk_list, &ext_clk_map_list);
+
+	return 0;
+}
+
+static int add_cg_to_list(struct platform_device *pdev)
+{
+	int i = 0;
+
+	struct device_node *node = pdev->dev.of_node;
+
+	if (!node) {
+		dev_err(&pdev->dev, "Cannot find topcksys node: %ld\n",
+			PTR_ERR(node));
+		return PTR_ERR(node);
+	}
+
+	do {
+		const char *ck_name;
+		char *temp_str;
+		char *tok[2] = {NULL};
+		int cg_idx = 0;
+		int idx = 0;
+		int ret = 0;
+
+		ret = of_property_read_string_index(node, "clock-names", i,
+						    &ck_name);
+		if (ret < 0)
+			break;
+
+		temp_str = kmalloc_array(strlen(ck_name), sizeof(char),
+					 GFP_KERNEL | __GFP_ZERO);
+		memcpy(temp_str, ck_name, strlen(ck_name));
+		temp_str[strlen(ck_name)] = '\0';
+		do {
+			tok[idx] = strsep(&temp_str, "-");
+			idx++;
+		} while (temp_str);
+
+		if (idx == 2) {
+			if (kstrtouint(tok[1], 10, &cg_idx))
+				return -EINVAL;
+
+			if (add_clk_to_list(pdev, ck_name, tok[0]))
+				return -EINVAL;
+		}
+		kfree(temp_str);
+		i++;
+	} while (1);
+
+	return 0;
+}
+
+int scpsys_ext_clk_init(struct platform_device *pdev)
+{
+	int ret = 0;
+
+	ret = add_cg_to_list(pdev);
+	if (ret)
+		goto err;
+
+err:
+	return ret;
+}
+
+int scpsys_ext_attr_init(const struct scpsys_ext_data *data)
+{
+	int i, count = 0;
+
+	for (i = 0; i < data->num_attr; i++) {
+		struct scpsys_ext_attr *node = data->attr + i;
+
+		if (!node)
+			continue;
+
+		list_add(&node->attr_list, &ext_attr_map_list);
+		count++;
+	}
+
+	if (!count)
+		return -EINVAL;
+
+	return 0;
+}
+
+static const struct of_device_id of_scpsys_ext_match_tbl[] = {
+	{
+		/* sentinel */
+	}
+};
+
+struct scpsys_ext_data *scpsys_ext_init(struct platform_device *pdev)
+{
+	const struct of_device_id *match;
+	struct scpsys_ext_data *data;
+	int ret;
+
+	match = of_match_device(of_scpsys_ext_match_tbl, &pdev->dev);
+
+	if (!match) {
+		dev_err(&pdev->dev, "no match\n");
+		return ERR_CAST(match);
+	}
+
+	data = (struct scpsys_ext_data *)match->data;
+	if (IS_ERR(data)) {
+		dev_err(&pdev->dev, "no match scpext data\n");
+		return ERR_CAST(data);
+	}
+
+	ret = scpsys_ext_attr_init(data);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"Failed to init bus attr: %d\n",
+			ret);
+		return ERR_PTR(ret);
+	}
+
+	ret = scpsys_ext_regmap_init(pdev);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"Failed to init bus register: %d\n",
+			ret);
+		return ERR_PTR(ret);
+	}
+
+	ret = scpsys_ext_clk_init(pdev);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to init bus clks: %d\n",
+			ret);
+		return ERR_PTR(ret);
+	}
+
+	return data;
+}
diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
index 4bb6c7a..03df2d6 100644
--- a/drivers/soc/mediatek/mtk-scpsys.c
+++ b/drivers/soc/mediatek/mtk-scpsys.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de>
  *
@@ -20,6 +21,7 @@
 #include <linux/pm_domain.h>
 #include <linux/regulator/consumer.h>
 #include <linux/soc/mediatek/infracfg.h>
+#include <linux/soc/mediatek/scpsys-ext.h>
 
 #include <dt-bindings/power/mt2701-power.h>
 #include <dt-bindings/power/mt2712-power.h>
@@ -117,6 +119,15 @@ enum clk_id {
 
 #define MAX_CLKS	3
 
+/**
+ * struct scp_domain_data - scp domain data for power on/off flow
+ * @name: The domain name.
+ * @sta_mask: The mask for power on/off status bit.
+ * @ctl_offs: The offset for main power control register.
+ * @sram_pdn_bits: The mask for sram power control bits.
+ * @sram_pdn_ack_bits The mask for sram power control acked bits.
+ * @caps: The flag for active wake-up action.
+ */
 struct scp_domain_data {
 	const char *name;
 	u32 sta_mask;
@@ -150,7 +161,7 @@ struct scp {
 	void __iomem *base;
 	struct regmap *infracfg;
 	struct scp_ctrl_reg ctrl_reg;
-	bool bus_prot_reg_update;
+	struct scpsys_ext_data *ext_data;
 };
 
 struct scp_subdomain {
@@ -164,7 +175,6 @@ struct scp_soc_data {
 	const struct scp_subdomain *subdomains;
 	int num_subdomains;
 	const struct scp_ctrl_reg regs;
-	bool bus_prot_reg_update;
 };
 
 static int scpsys_domain_is_on(struct scp_domain *scpd)
@@ -236,6 +246,31 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
 	val |= PWR_RST_B_BIT;
 	writel(val, ctl_addr);
 
+	if (!IS_ERR(scp->ext_data)) {
+		struct scpsys_ext_attr *attr;
+
+		attr = scp->ext_data->get_attr(scpd->data->name);
+		if (!IS_ERR(attr) && attr->cg_ops) {
+			ret = attr->cg_ops->enable(attr);
+			if (ret)
+				goto err_ext_clk;
+		}
+	}
+
+	val &= ~scpd->data->sram_pdn_bits;
+	writel(val, ctl_addr);
+
+	if (!IS_ERR(scp->ext_data)) {
+		struct scpsys_ext_attr *attr;
+
+		attr = scp->ext_data->get_attr(scpd->data->name);
+		if (!IS_ERR(attr) && attr->cg_ops) {
+			ret = attr->cg_ops->enable(attr);
+			if (ret)
+				goto err_ext_clk;
+		}
+	}
+
 	val &= ~scpd->data->sram_pdn_bits;
 	writel(val, ctl_addr);
 
@@ -247,25 +282,65 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
 		 * applied here.
 		 */
 		usleep_range(12000, 12100);
-
 	} else {
 		ret = readl_poll_timeout(ctl_addr, tmp, (tmp & pdn_ack) == 0,
 					 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
 		if (ret < 0)
-			goto err_pwr_ack;
+			goto err_sram;
 	}
 
 	if (scpd->data->bus_prot_mask) {
 		ret = mtk_infracfg_clear_bus_protection(scp->infracfg,
-				scpd->data->bus_prot_mask,
-				scp->bus_prot_reg_update);
+				scpd->data->bus_prot_mask);
 		if (ret)
-			goto err_pwr_ack;
+			goto err_sram;
+	}
+
+	if (!IS_ERR(scp->ext_data)) {
+		struct scpsys_ext_attr *attr;
+
+		attr = scp->ext_data->get_attr(scpd->data->name);
+		if (!IS_ERR(attr) && attr->bus_ops) {
+			ret = attr->bus_ops->disable(attr);
+			if (ret)
+				goto err_sram;
+		}
+	}
+
+	if (!IS_ERR(scp->ext_data)) {
+		struct scpsys_ext_attr *attr;
+
+		attr = scp->ext_data->get_attr(scpd->data->name);
+		if (!IS_ERR(attr) && attr->cg_ops) {
+			ret = attr->cg_ops->disable(attr);
+			if (ret)
+				goto err_sram;
+		}
 	}
 
 	return 0;
 
+err_sram:
+	val = readl(ctl_addr);
+	val |= scpd->data->sram_pdn_bits;
+	writel(val, ctl_addr);
+err_ext_clk:
+	val = readl(ctl_addr);
+	val |= PWR_ISO_BIT;
+	writel(val, ctl_addr);
+
+	val &= ~PWR_RST_B_BIT;
+	writel(val, ctl_addr);
+
+	val |= PWR_CLK_DIS_BIT;
+	writel(val, ctl_addr);
 err_pwr_ack:
+	val &= ~PWR_ON_BIT;
+	writel(val, ctl_addr);
+
+	val &= ~PWR_ON_2ND_BIT;
+	writel(val, ctl_addr);
+
 	for (i = MAX_CLKS - 1; i >= 0; i--) {
 		if (scpd->clk[i])
 			clk_disable_unprepare(scpd->clk[i]);
@@ -274,8 +349,6 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
 	if (scpd->supply)
 		regulator_disable(scpd->supply);
 
-	dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name);
-
 	return ret;
 }
 
@@ -289,14 +362,35 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
 	int ret, tmp;
 	int i;
 
+	if (!IS_ERR(scp->ext_data)) {
+		struct scpsys_ext_attr *attr;
+
+		attr = scp->ext_data->get_attr(scpd->data->name);
+		if (!IS_ERR(attr) && attr->cg_ops) {
+			ret = attr->cg_ops->enable(attr);
+			if (ret)
+				goto out;
+		}
+	}
+
 	if (scpd->data->bus_prot_mask) {
 		ret = mtk_infracfg_set_bus_protection(scp->infracfg,
-				scpd->data->bus_prot_mask,
-				scp->bus_prot_reg_update);
+				scpd->data->bus_prot_mask);
 		if (ret)
 			goto out;
 	}
 
+	if (!IS_ERR(scp->ext_data)) {
+		struct scpsys_ext_attr *attr;
+
+		attr = scp->ext_data->get_attr(scpd->data->name);
+		if (!IS_ERR(attr) && attr->bus_ops) {
+			ret = attr->bus_ops->enable(attr);
+			if (ret)
+				goto out;
+		}
+	}
+
 	val = readl(ctl_addr);
 	val |= scpd->data->sram_pdn_bits;
 	writel(val, ctl_addr);
@@ -307,6 +401,17 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
 	if (ret < 0)
 		goto out;
 
+	if (!IS_ERR(scp->ext_data)) {
+		struct scpsys_ext_attr *attr;
+
+		attr = scp->ext_data->get_attr(scpd->data->name);
+		if (!IS_ERR(attr) && attr->cg_ops) {
+			ret = attr->cg_ops->disable(attr);
+			if (ret)
+				goto out;
+		}
+	}
+
 	val |= PWR_ISO_BIT;
 	writel(val, ctl_addr);
 
@@ -337,8 +442,6 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
 	return 0;
 
 out:
-	dev_err(scp->dev, "Failed to power off domain %s\n", genpd->name);
-
 	return ret;
 }
 
@@ -352,8 +455,7 @@ 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_ctrl_reg *scp_ctrl_reg,
-			bool bus_prot_reg_update)
+			const struct scp_ctrl_reg *scp_ctrl_reg)
 {
 	struct genpd_onecell_data *pd_data;
 	struct resource *res;
@@ -367,11 +469,10 @@ static struct scp *init_scp(struct platform_device *pdev,
 
 	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->bus_prot_reg_update = bus_prot_reg_update;
-
 	scp->dev = &pdev->dev;
 
+	scp->ext_data = scpsys_ext_init(pdev);
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	scp->base = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(scp->base))
@@ -1021,7 +1122,6 @@ static void mtk_register_power_domains(struct platform_device *pdev,
 		.pwr_sta_offs = SPM_PWR_STATUS,
 		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
 	},
-	.bus_prot_reg_update = true,
 };
 
 static const struct scp_soc_data mt2712_data = {
@@ -1033,7 +1133,6 @@ static void mtk_register_power_domains(struct platform_device *pdev,
 		.pwr_sta_offs = SPM_PWR_STATUS,
 		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
 	},
-	.bus_prot_reg_update = false,
 };
 
 static const struct scp_soc_data mt6765_data = {
@@ -1056,7 +1155,6 @@ static void mtk_register_power_domains(struct platform_device *pdev,
 		.pwr_sta_offs = SPM_PWR_STATUS_MT6797,
 		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797
 	},
-	.bus_prot_reg_update = true,
 };
 
 static const struct scp_soc_data mt7622_data = {
@@ -1066,7 +1164,6 @@ static void mtk_register_power_domains(struct platform_device *pdev,
 		.pwr_sta_offs = SPM_PWR_STATUS,
 		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
 	},
-	.bus_prot_reg_update = true,
 };
 
 static const struct scp_soc_data mt7623a_data = {
@@ -1076,7 +1173,6 @@ static void mtk_register_power_domains(struct platform_device *pdev,
 		.pwr_sta_offs = SPM_PWR_STATUS,
 		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
 	},
-	.bus_prot_reg_update = true,
 };
 
 static const struct scp_soc_data mt8173_data = {
@@ -1088,7 +1184,6 @@ static void mtk_register_power_domains(struct platform_device *pdev,
 		.pwr_sta_offs = SPM_PWR_STATUS,
 		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
 	},
-	.bus_prot_reg_update = true,
 };
 
 /*
@@ -1132,8 +1227,8 @@ static int scpsys_probe(struct platform_device *pdev)
 
 	soc = of_device_get_match_data(&pdev->dev);
 
-	scp = init_scp(pdev, soc->domains, soc->num_domains, &soc->regs,
-			soc->bus_prot_reg_update);
+	scp = init_scp(pdev, soc->domains, soc->num_domains,
+		       &soc->regs);
 	if (IS_ERR(scp))
 		return PTR_ERR(scp);
 
diff --git a/include/linux/soc/mediatek/infracfg.h b/include/linux/soc/mediatek/infracfg.h
index fd25f01..bfad082 100644
--- a/include/linux/soc/mediatek/infracfg.h
+++ b/include/linux/soc/mediatek/infracfg.h
@@ -32,8 +32,9 @@
 #define MT7622_TOP_AXI_PROT_EN_WB		(BIT(2) | BIT(6) | \
 						 BIT(7) | BIT(8))
 
-int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask,
-		bool reg_update);
-int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask,
-		bool reg_update);
+int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask);
+int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask);
+int mtk_infracfg_enable_bus_protection(struct regmap *infracfg, u32 mask);
+int mtk_infracfg_disable_bus_protection(struct regmap *infracfg, u32 mask);
+
 #endif /* __SOC_MEDIATEK_INFRACFG_H */
diff --git a/include/linux/soc/mediatek/scpsys-ext.h b/include/linux/soc/mediatek/scpsys-ext.h
new file mode 100644
index 0000000..99b5ff1
--- /dev/null
+++ b/include/linux/soc/mediatek/scpsys-ext.h
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __SOC_MEDIATEK_SCPSYS_EXT_H
+#define __SOC_MEDIATEK_SCPSYS_EXT_H
+
+#include <linux/platform_device.h>
+
+#define CMD_ENABLE	1
+#define CMD_DISABLE	0
+
+#define MAX_STEP_NUM	4
+
+/**
+ * struct bus_mask - set mask and corresponding operation for bus protect
+ * @regs: The register set of bus register control, including set/clr/sta.
+ * @mask: The mask set for bus protect.
+ * @flag: The flag to idetify which operation we take for bus protect.
+ */
+struct bus_mask {
+	struct ext_reg_ctrl *regs;
+	u32 mask;
+	const struct bus_mask_ops *ops;
+};
+
+/**
+ * struct scpsys_ext_attr - extended attribute for bus protect and further
+ *                                           operand.
+ *
+ * @scpd_n: The name present the scpsys domain where the clks belongs to.
+ * @mask: The mask set for bus protect.
+ * @bus_ops: The operation we take for bus protect.
+ * @cg_ops: The operation we take for cg on/off.
+ * @attr_list: The list node linked to ext_attr_map_list.
+ */
+struct scpsys_ext_attr {
+	const char *scpd_n;
+	struct bus_mask mask[MAX_STEP_NUM];
+	const char *parent_n;
+	const struct bus_ext_ops *bus_ops;
+	const struct bus_ext_ops *cg_ops;
+
+	struct list_head attr_list;
+};
+
+struct scpsys_ext_data {
+	struct scpsys_ext_attr *attr;
+	u8 num_attr;
+	struct scpsys_ext_attr * (*get_attr)(const char *scpd_n);
+};
+
+struct bus_ext_ops {
+	int	(*enable)(struct scpsys_ext_attr *attr);
+	int	(*disable)(struct scpsys_ext_attr *attr);
+};
+
+int mtk_generic_set_cmd(struct regmap *regmap, u32 set_ofs,
+			u32 sta_ofs, u32 mask);
+int mtk_generic_clr_cmd(struct regmap *regmap, u32 clr_ofs,
+			u32 sta_ofs, u32 mask);
+int mtk_generic_enable_cmd(struct regmap *regmap, u32 upd_ofs,
+			   u32 sta_ofs, u32 mask);
+int mtk_generic_disable_cmd(struct regmap *regmap, u32 upd_ofs,
+			    u32 sta_ofs, u32 mask);
+
+struct scpsys_ext_data *scpsys_ext_init(struct platform_device *pdev);
+
+#endif /* __SOC_MEDIATEK_SCPSYS_EXT_H */
-- 
1.7.9.5


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

* [PATCH v5 07/11] soc: mediatek: add MT6765 subdomain support
  2018-07-17  8:52 [PATCH v5 0/11] Add basic SoC support for mt6765 Mars Cheng
                   ` (5 preceding siblings ...)
  2018-07-17  8:52 ` [PATCH v5 06/11] soc: mediatek: add new flow for mtcmos power Mars Cheng
@ 2018-07-17  8:52 ` Mars Cheng
  2018-07-17  8:52 ` [PATCH v5 08/11] clk: mediatek: fix pll setting Mars Cheng
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 32+ messages in thread
From: Mars Cheng @ 2018-07-17  8:52 UTC (permalink / raw)
  To: Matthias Brugger, Rob Herring, Marc Zyngier, Ryder Lee,
	Stephen Boyd, Sean Wang
  Cc: CC Hwang, Loda Chou, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, linux-serial, linux-arm-kernel, linux-clk,
	Mars Cheng, Owen Chen

add extend data, parent_n for domain-subdomain corresponse.

Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
Signed-off-by: Owen Chen <owen.chen@mediatek.com>
---
 drivers/soc/mediatek/mtk-scpsys-ext.c |  132 ++++++++++++++++++++++++++++++++-
 1 file changed, 131 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/mediatek/mtk-scpsys-ext.c b/drivers/soc/mediatek/mtk-scpsys-ext.c
index 965e64d..e649a06 100644
--- a/drivers/soc/mediatek/mtk-scpsys-ext.c
+++ b/drivers/soc/mediatek/mtk-scpsys-ext.c
@@ -13,7 +13,7 @@
 #include <linux/regmap.h>
 #include <linux/soc/mediatek/infracfg.h>
 #include <linux/soc/mediatek/scpsys-ext.h>
-
+#include <dt-bindings/power/mt6765-power.h>
 
 #define MAX_CLKS		10
 #define INFRA			"infracfg"
@@ -65,6 +65,21 @@ struct bus_mask_ops {
 			   u32 sta_ofs, u32 mask);
 };
 
+static struct scpsys_ext_attr *__get_attr_node(const char *scpd_n)
+{
+	struct scpsys_ext_attr *attr;
+
+	if (!scpd_n)
+		return ERR_PTR(-EINVAL);
+
+	list_for_each_entry(attr, &ext_attr_map_list, attr_list) {
+		if (attr->scpd_n && !strcmp(scpd_n, attr->scpd_n))
+			return attr;
+	}
+
+	return ERR_PTR(-EINVAL);
+}
+
 static struct scpsys_ext_attr *__get_attr_parent(const char *parent_n)
 {
 	struct scpsys_ext_attr *attr;
@@ -353,8 +368,123 @@ int scpsys_ext_attr_init(const struct scpsys_ext_data *data)
 	return 0;
 }
 
+/*
+ * MT6765 extend power domain support
+ */
+
+#define INFRA_TOPAXI_PROTECTEN_SET_MT6765	0x02A0
+#define INFRA_TOPAXI_PROTECTEN_STA1_MT6765	0x0228
+#define INFRA_TOPAXI_PROTECTEN_CLR_MT6765	0x02A4
+
+#define INFRA_TOPAXI_PROTECTEN_1_SET_MT6765	0x02A8
+#define INFRA_TOPAXI_PROTECTEN_STA1_1_MT6765	0x0258
+#define INFRA_TOPAXI_PROTECTEN_1_CLR_MT6765	0x02AC
+
+#define SMI_COMMON_SMI_CLAMP_MT6765		0x03C0
+#define SMI_COMMON_SMI_CLAMP_SET_MT6765	0x03C4
+#define SMI_COMMON_SMI_CLAMP_CLR_MT6765	0x03C8
+
+static struct ext_reg_ctrl infra_bus_regs_0_mt6765 = {
+	.type = IFR_TYPE,
+	.set_ofs = INFRA_TOPAXI_PROTECTEN_SET_MT6765,
+	.clr_ofs = INFRA_TOPAXI_PROTECTEN_CLR_MT6765,
+	.sta_ofs = INFRA_TOPAXI_PROTECTEN_STA1_MT6765,
+};
+
+#define BUS_IFR0_MT6765(_mask) {				\
+		.regs = &infra_bus_regs_0_mt6765,		\
+		.mask = _mask,				\
+		.ops = &bus_mask_set_clr_ctrl,		\
+	}
+
+static struct ext_reg_ctrl infra_bus_regs_1_mt6765 = {
+	.type = IFR_TYPE,
+	.set_ofs = INFRA_TOPAXI_PROTECTEN_1_SET_MT6765,
+	.clr_ofs = INFRA_TOPAXI_PROTECTEN_1_CLR_MT6765,
+	.sta_ofs = INFRA_TOPAXI_PROTECTEN_STA1_1_MT6765,
+};
+
+#define BUS_IFR1_MT6765(_mask) {				\
+		.regs = &infra_bus_regs_1_mt6765,		\
+		.mask = _mask,				\
+		.ops = &bus_mask_set_clr_ctrl,		\
+	}
+
+static struct ext_reg_ctrl smi_bus_regs_0_mt6765 = {
+	.type = SMI_TYPE,
+	.set_ofs = SMI_COMMON_SMI_CLAMP_SET_MT6765,
+	.clr_ofs = SMI_COMMON_SMI_CLAMP_CLR_MT6765,
+	.sta_ofs = SMI_COMMON_SMI_CLAMP_MT6765,
+};
+
+#define BUS_SMI0_MT6765(_mask) {				\
+		.regs = &smi_bus_regs_0_mt6765,		\
+		.mask = _mask,				\
+		.ops = &bus_mask_set_clr_ctrl,		\
+	}
+
+static struct scpsys_ext_attr scp_ext_attr_mt6765[] = {
+	[MT6765_POWER_DOMAIN_ISP] = {
+		.scpd_n = "isp",
+		.mask =  {
+			BUS_IFR1_MT6765(BIT(20)),
+			BUS_SMI0_MT6765(BIT(2)),
+		},
+		.parent_n = "mm",
+		.bus_ops = &ext_bus_ctrl,
+		.cg_ops = &ext_cg_ctrl,
+	},
+	[MT6765_POWER_DOMAIN_MM] = {
+		.scpd_n = "mm",
+		.mask = {
+			BUS_IFR1_MT6765(BIT(16) | BIT(17)),
+			BUS_IFR0_MT6765(BIT(10) | BIT(11)),
+			BUS_IFR0_MT6765(BIT(1) | BIT(2)),
+		},
+		.bus_ops = &ext_bus_ctrl,
+		.cg_ops = &ext_cg_ctrl,
+	},
+	[MT6765_POWER_DOMAIN_CONN] = {
+		.scpd_n = "conn",
+		.mask = {
+			BUS_IFR0_MT6765(BIT(13)),
+			BUS_IFR1_MT6765(BIT(18)),
+			BUS_IFR0_MT6765(BIT(14) | BIT(16)),
+		},
+		.bus_ops = &ext_bus_ctrl,
+	},
+	[MT6765_POWER_DOMAIN_MFG] = {
+		.scpd_n = "mfg",
+		.mask = {
+			BUS_IFR0_MT6765(BIT(25)),
+			BUS_IFR0_MT6765(BIT(21) | BIT(22)),
+		},
+		.bus_ops = &ext_bus_ctrl,
+	},
+	[MT6765_POWER_DOMAIN_CAM] = {
+		.scpd_n = "cam",
+		.mask = {
+			BUS_IFR1_MT6765(BIT(19) | BIT(21)),
+			BUS_IFR0_MT6765(BIT(20)),
+			BUS_SMI0_MT6765(BIT(3)),
+		},
+		.parent_n = "mm",
+		.bus_ops = &ext_bus_ctrl,
+		.cg_ops = &ext_cg_ctrl,
+	},
+};
+
+static const struct scpsys_ext_data scp_ext_data_mt6765 = {
+	.attr = scp_ext_attr_mt6765,
+	.num_attr = ARRAY_SIZE(scp_ext_attr_mt6765),
+	.get_attr = __get_attr_node,
+};
+
 static const struct of_device_id of_scpsys_ext_match_tbl[] = {
 	{
+		.compatible = "mediatek,mt6765-scpsys",
+		.data = &scp_ext_data_mt6765,
+	}, {
 		/* sentinel */
 	}
 };
-- 
1.7.9.5


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

* [PATCH v5 08/11] clk: mediatek: fix pll setting
  2018-07-17  8:52 [PATCH v5 0/11] Add basic SoC support for mt6765 Mars Cheng
                   ` (6 preceding siblings ...)
  2018-07-17  8:52 ` [PATCH v5 07/11] soc: mediatek: add MT6765 subdomain support Mars Cheng
@ 2018-07-17  8:52 ` Mars Cheng
  2018-07-17  8:52 ` [PATCH v5 09/11] clk: mediatek: add new clkmux register API Mars Cheng
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 32+ messages in thread
From: Mars Cheng @ 2018-07-17  8:52 UTC (permalink / raw)
  To: Matthias Brugger, Rob Herring, Marc Zyngier, Ryder Lee,
	Stephen Boyd, Sean Wang
  Cc: CC Hwang, Loda Chou, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, linux-serial, linux-arm-kernel, linux-clk,
	Owen Chen

From: Owen Chen <owen.chen@mediatek.com>

1. pcwibits: The integer bits of pcw for plls is extend to 8 bits,
   add a variable to indicate this change and
   backward-compatible.
2. fmin: The pll freqency lower-bound is vary from 1GMhz to
   1.5Ghz, add a variable to indicate platform-dependent.

Signed-off-by: Owen Chen <owen.chen@mediatek.com>
---
 drivers/clk/mediatek/clk-mtk.h |    2 ++
 drivers/clk/mediatek/clk-pll.c |   45 ++++++++++++++++++++++++++++++++++------
 2 files changed, 41 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index f83c2bb..1882221 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -215,7 +215,9 @@ struct mtk_pll_data {
 	const struct clk_ops *ops;
 	u32 rst_bar_mask;
 	unsigned long fmax;
+	unsigned long fmin;
 	int pcwbits;
+	int pcwibits;
 	uint32_t pcw_reg;
 	int pcw_shift;
 	const struct mtk_pll_div_table *div_table;
diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
index f54e401..df571e5 100644
--- a/drivers/clk/mediatek/clk-pll.c
+++ b/drivers/clk/mediatek/clk-pll.c
@@ -27,7 +27,7 @@
 #define CON0_BASE_EN		BIT(0)
 #define CON0_PWR_ON		BIT(0)
 #define CON0_ISO_EN		BIT(1)
-#define CON0_PCW_CHG		BIT(31)
+#define CON1_PCW_CHG		BIT(31)
 
 #define AUDPLL_TUNER_EN		BIT(31)
 
@@ -69,11 +69,13 @@ static unsigned long __mtk_pll_recalc_rate(struct mtk_clk_pll *pll, u32 fin,
 {
 	int pcwbits = pll->data->pcwbits;
 	int pcwfbits;
+	int ibits;
 	u64 vco;
 	u8 c = 0;
 
 	/* The fractional part of the PLL divider. */
-	pcwfbits = pcwbits > INTEGER_BITS ? pcwbits - INTEGER_BITS : 0;
+	ibits = pll->data->pcwibits ? pll->data->pcwibits : INTEGER_BITS;
+	pcwfbits = pcwbits > ibits ? pcwbits - ibits : 0;
 
 	vco = (u64)fin * pcw;
 
@@ -93,9 +95,31 @@ static void mtk_pll_set_rate_regs(struct mtk_clk_pll *pll, u32 pcw,
 {
 	u32 con1, val;
 	int pll_en;
+	u32 tuner_en = 0;
+	u32 tuner_en_mask;
+	void __iomem *tuner_en_addr = NULL;
 
 	pll_en = readl(pll->base_addr + REG_CON0) & CON0_BASE_EN;
 
+	/* disable tuner */
+	if (pll->tuner_en_addr) {
+		tuner_en_addr = pll->tuner_en_addr;
+		tuner_en_mask = BIT(pll->data->tuner_en_bit);
+	} else if (pll->tuner_addr) {
+		tuner_en_addr = pll->tuner_addr;
+		tuner_en_mask = AUDPLL_TUNER_EN;
+	}
+
+	if (tuner_en_addr) {
+		val = readl(tuner_en_addr);
+		tuner_en = val & tuner_en_mask;
+
+		if (tuner_en) {
+			val &= ~tuner_en_mask;
+			writel(val, tuner_en_addr);
+		}
+	}
+
 	/* set postdiv */
 	val = readl(pll->pd_addr);
 	val &= ~(POSTDIV_MASK << pll->data->pd_shift);
@@ -116,12 +140,20 @@ static void mtk_pll_set_rate_regs(struct mtk_clk_pll *pll, u32 pcw,
 	con1 = readl(pll->base_addr + REG_CON1);
 
 	if (pll_en)
-		con1 |= CON0_PCW_CHG;
+		con1 |= CON1_PCW_CHG;
 
 	writel(con1, pll->base_addr + REG_CON1);
+
 	if (pll->tuner_addr)
 		writel(con1 + 1, pll->tuner_addr);
 
+	/* restore tuner_en */
+	if (tuner_en_addr && tuner_en) {
+		val = readl(tuner_en_addr);
+		val |= tuner_en_mask;
+		writel(val, tuner_en_addr);
+	}
+
 	if (pll_en)
 		udelay(20);
 }
@@ -138,9 +170,10 @@ static void mtk_pll_set_rate_regs(struct mtk_clk_pll *pll, u32 pcw,
 static void mtk_pll_calc_values(struct mtk_clk_pll *pll, u32 *pcw, u32 *postdiv,
 		u32 freq, u32 fin)
 {
-	unsigned long fmin = 1000 * MHZ;
+	unsigned long fmin = pll->data->fmin ? pll->data->fmin : 1000 * MHZ;
 	const struct mtk_pll_div_table *div_table = pll->data->div_table;
 	u64 _pcw;
+	int ibits;
 	u32 val;
 
 	if (freq > pll->data->fmax)
@@ -164,7 +197,8 @@ static void mtk_pll_calc_values(struct mtk_clk_pll *pll, u32 *pcw, u32 *postdiv,
 	}
 
 	/* _pcw = freq * postdiv / fin * 2^pcwfbits */
-	_pcw = ((u64)freq << val) << (pll->data->pcwbits - INTEGER_BITS);
+	ibits = pll->data->pcwibits ? pll->data->pcwibits : INTEGER_BITS;
+	_pcw = ((u64)freq << val) << (pll->data->pcwbits - ibits);
 	do_div(_pcw, fin);
 
 	*pcw = (u32)_pcw;
@@ -192,7 +226,6 @@ static unsigned long mtk_pll_recalc_rate(struct clk_hw *hw,
 
 	postdiv = (readl(pll->pd_addr) >> pll->data->pd_shift) & POSTDIV_MASK;
 	postdiv = 1 << postdiv;
-
 	pcw = readl(pll->pcw_addr) >> pll->data->pcw_shift;
 	pcw &= GENMASK(pll->data->pcwbits - 1, 0);
 
-- 
1.7.9.5


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

* [PATCH v5 09/11] clk: mediatek: add new clkmux register API
  2018-07-17  8:52 [PATCH v5 0/11] Add basic SoC support for mt6765 Mars Cheng
                   ` (7 preceding siblings ...)
  2018-07-17  8:52 ` [PATCH v5 08/11] clk: mediatek: fix pll setting Mars Cheng
@ 2018-07-17  8:52 ` Mars Cheng
  2018-07-19  6:57   ` Sean Wang
  2018-07-17  8:52 ` [PATCH v5 10/11] clk: mediatek: Add MT6765 clock support Mars Cheng
  2018-07-17  8:52 ` [PATCH v5 11/11] arm64: dts: mediatek: add mt6765 support Mars Cheng
  10 siblings, 1 reply; 32+ messages in thread
From: Mars Cheng @ 2018-07-17  8:52 UTC (permalink / raw)
  To: Matthias Brugger, Rob Herring, Marc Zyngier, Ryder Lee,
	Stephen Boyd, Sean Wang
  Cc: CC Hwang, Loda Chou, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, linux-serial, linux-arm-kernel, linux-clk,
	Owen Chen

From: Owen Chen <owen.chen@mediatek.com>

MT6765 add "set/clr" register for each clkmux setting, and
one update register to trigger value change. It is designed
to prevent read-modify-write racing issue. The sw design
need to add a new API to handle this hw change with a new
mtk_clk_mux/mtk_clk_upd struct in new file "clk-mux"and
clk-upd".

Signed-off-by: Owen Chen <owen.chen@mediatek.com>
---
 drivers/clk/mediatek/Makefile  |    2 +-
 drivers/clk/mediatek/clk-mtk.c |   41 +++++++
 drivers/clk/mediatek/clk-mtk.h |   85 ++++++++++++---
 drivers/clk/mediatek/clk-mux.c |  236 ++++++++++++++++++++++++++++++++++++++++
 drivers/clk/mediatek/clk-mux.h |   38 +++++++
 5 files changed, 388 insertions(+), 14 deletions(-)
 create mode 100644 drivers/clk/mediatek/clk-mux.c
 create mode 100644 drivers/clk/mediatek/clk-mux.h

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 844b55d..b97980d 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o clk-cpumux.o reset.o
+obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o clk-cpumux.o reset.o clk-mux.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
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 9c0ae42..50becd0 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -22,6 +22,7 @@
 #include <linux/mfd/syscon.h>
 
 #include "clk-mtk.h"
+#include "clk-mux.h"
 #include "clk-gate.h"
 
 struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num)
@@ -144,6 +145,46 @@ int mtk_clk_register_gates(struct device_node *node,
 	return 0;
 }
 
+int mtk_clk_register_muxes(const struct mtk_mux *muxes,
+			   int num, struct device_node *node,
+			   spinlock_t *lock,
+			   struct clk_onecell_data *clk_data)
+{
+	struct regmap *regmap;
+	struct clk *clk;
+	int i;
+
+	if (!clk_data)
+		return -ENOMEM;
+
+	regmap = syscon_node_to_regmap(node);
+	if (IS_ERR(regmap)) {
+		pr_err("Cannot find regmap for %pOF: %ld\n", node,
+		       PTR_ERR(regmap));
+		return PTR_ERR(regmap);
+	}
+
+	for (i = 0; i < num; i++) {
+		const struct mtk_mux *mux = &muxes[i];
+
+		if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[mux->id]))
+			continue;
+
+		clk = mtk_clk_register_mux(mux, regmap, lock);
+
+		if (IS_ERR(clk)) {
+			pr_err("Failed to register clk %s: %ld\n",
+			       mux->name, PTR_ERR(clk));
+			continue;
+		}
+
+		if (clk_data)
+			clk_data->clks[mux->id] = clk;
+	}
+
+	return 0;
+}
+
 struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
 		void __iomem *base, spinlock_t *lock)
 {
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index 1882221..61693f6 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -24,7 +24,9 @@
 
 #define MAX_MUX_GATE_BIT	31
 #define INVALID_MUX_GATE_BIT	(MAX_MUX_GATE_BIT + 1)
-
+#define INVALID_OFS		-1
+#define INVALID_SHFT		-1
+#define INVALID_WIDTH		-1
 #define MHZ (1000 * 1000)
 
 struct mtk_fixed_clk {
@@ -84,10 +86,72 @@ struct mtk_composite {
 	signed char num_parents;
 };
 
+struct mtk_mux {
+	int id;
+	const char *name;
+	const char * const *parent_names;
+	unsigned int flags;
+
+	u32 mux_ofs;
+	u32 set_ofs;
+	u32 clr_ofs;
+	u32 upd_ofs;
+
+	signed char mux_shift;
+	signed char mux_width;
+	signed char gate_shift;
+	signed char upd_shift;
+
+	const struct clk_ops *ops;
+
+	signed char num_parents;
+};
+
 /*
  * In case the rate change propagation to parent clocks is undesirable,
  * this macro allows to specify the clock flags manually.
  */
+#define CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, _mux_set_ofs,\
+			_mux_clr_ofs, _shift, _width, _gate,		\
+			_upd_ofs, _upd, _flags, _ops) {			\
+		.id = _id,						\
+		.name = _name,						\
+		.mux_ofs = _mux_ofs,					\
+		.set_ofs = _mux_set_ofs,				\
+		.clr_ofs = _mux_clr_ofs,				\
+		.upd_ofs = _upd_ofs,					\
+		.mux_shift = _shift,					\
+		.mux_width = _width,					\
+		.gate_shift = _gate,					\
+		.upd_shift = _upd,					\
+		.parent_names = _parents,				\
+		.num_parents = ARRAY_SIZE(_parents),			\
+		.flags = _flags,					\
+		.ops = &_ops,						\
+	}
+
+#define MUX_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, _mux_set_ofs,\
+			_mux_clr_ofs, _shift, _width, _gate,		\
+			_upd_ofs, _upd, _flags)			\
+		CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs,	\
+			_mux_set_ofs, _mux_clr_ofs, _shift, _width,	\
+			_gate, _upd_ofs, _upd, _flags,			\
+			mtk_mux_clr_set_upd_ops)
+
+#define MUX_CLR_SET_UPD(_id, _name, _parents, _mux_ofs, _mux_set_ofs,	\
+			_mux_clr_ofs, _shift, _width, _gate,		\
+			_upd_ofs, _upd)				\
+		MUX_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs,	\
+			_mux_set_ofs, _mux_clr_ofs, _shift, _width,	\
+			_gate, _upd_ofs, _upd, CLK_SET_RATE_PARENT)
+
+#define MUX_UPD(_id, _name, _parents, _mux_ofs, _shift, _width, _gate,	\
+			_upd_ofs, _upd)				\
+		CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs,	\
+			INVALID_OFS, INVALID_OFS, _shift, _width,	\
+			_gate, _upd_ofs, _upd, CLK_SET_RATE_PARENT,	\
+			mtk_mux_upd_ops)
+
 #define MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width,	\
 			_gate, _flags) {				\
 		.id = _id,						\
@@ -111,18 +175,8 @@ struct mtk_composite {
 	MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width,	\
 		_gate, CLK_SET_RATE_PARENT)
 
-#define MUX(_id, _name, _parents, _reg, _shift, _width) {		\
-		.id = _id,						\
-		.name = _name,						\
-		.mux_reg = _reg,					\
-		.mux_shift = _shift,					\
-		.mux_width = _width,					\
-		.gate_shift = -1,					\
-		.divider_shift = -1,					\
-		.parent_names = _parents,				\
-		.num_parents = ARRAY_SIZE(_parents),			\
-		.flags = CLK_SET_RATE_PARENT,				\
-	}
+#define MUX(_id, _name, _parents, _reg, _shift, _width)		\
+	MUX_GATE(_id, _name, _parents, _reg, _shift, _width, INVALID_SHFT)
 
 #define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg,	\
 					_div_width, _div_shift) {	\
@@ -138,6 +192,11 @@ struct mtk_composite {
 		.flags = 0,						\
 	}
 
+int mtk_clk_register_muxes(const struct mtk_mux *muxes,
+			   int num, struct device_node *node,
+			   spinlock_t *lock,
+			   struct clk_onecell_data *clk_data);
+
 struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
 		void __iomem *base, spinlock_t *lock);
 
diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c
new file mode 100644
index 0000000..219181b
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mux.c
@@ -0,0 +1,236 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Owen Chen <owen.chen@mediatek.com>
+ */
+
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+
+#include "clk-mtk.h"
+#include "clk-mux.h"
+
+static inline struct mtk_clk_mux
+	*to_mtk_clk_mux(struct clk_hw *hw)
+{
+	return container_of(hw, struct mtk_clk_mux, hw);
+}
+
+static int mtk_mux_enable(struct clk_hw *hw)
+{
+	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
+	u32 mask = BIT(mux->gate_shift);
+	unsigned long flags = 0;
+
+	if (mux->lock)
+		spin_lock_irqsave(mux->lock, flags);
+
+	regmap_update_bits(mux->regmap, mux->mux_ofs, mask, 0);
+
+	if (mux->lock)
+		spin_unlock_irqrestore(mux->lock, flags);
+	return 0;
+}
+
+static void mtk_mux_disable(struct clk_hw *hw)
+{
+	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
+	u32 mask = BIT(mux->gate_shift);
+	unsigned long flags = 0;
+
+	if (mux->lock)
+		spin_lock_irqsave(mux->lock, flags);
+
+	regmap_update_bits(mux->regmap, mux->mux_ofs, mask, mask);
+
+	if (mux->lock)
+		spin_unlock_irqrestore(mux->lock, flags);
+}
+
+static int mtk_mux_enable_setclr(struct clk_hw *hw)
+{
+	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
+	u32 val;
+	unsigned long flags = 0;
+
+	if (mux->lock)
+		spin_lock_irqsave(mux->lock, flags);
+
+	val = BIT(mux->gate_shift);
+	regmap_write(mux->regmap, mux->mux_clr_ofs, val);
+
+	if (mux->lock)
+		spin_unlock_irqrestore(mux->lock, flags);
+	return 0;
+}
+
+static void mtk_mux_disable_setclr(struct clk_hw *hw)
+{
+	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
+	u32 val;
+	unsigned long flags = 0;
+
+	if (mux->lock)
+		spin_lock_irqsave(mux->lock, flags);
+
+	val = BIT(mux->gate_shift);
+	regmap_write(mux->regmap, mux->mux_set_ofs, val);
+
+	if (mux->lock)
+		spin_unlock_irqrestore(mux->lock, flags);
+}
+
+static int mtk_mux_is_enabled(struct clk_hw *hw)
+{
+	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
+	u32 val = 0;
+
+	if (mux->gate_shift < 0)
+		return true;
+
+	regmap_read(mux->regmap, mux->mux_ofs, &val);
+
+	return (val & BIT(mux->gate_shift)) == 0;
+}
+
+static u8 mtk_mux_get_parent(struct clk_hw *hw)
+{
+	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
+	int num_parents = clk_hw_get_num_parents(hw);
+	u32 mask = GENMASK(mux->mux_width - 1, 0);
+	u32 val;
+
+	regmap_read(mux->regmap, mux->mux_ofs, &val);
+	val = (val >> mux->mux_shift) & mask;
+
+	if (val >= num_parents)
+		return -EINVAL;
+
+	return val;
+}
+
+static int mtk_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
+	u32 mask = GENMASK(mux->mux_width - 1, 0);
+	u32 val, orig;
+	unsigned long flags = 0;
+
+	if (mux->lock)
+		spin_lock_irqsave(mux->lock, flags);
+
+	regmap_read(mux->regmap, mux->mux_ofs, &val);
+	orig = val;
+	val &= ~(mask << mux->mux_shift);
+	val |= index << mux->mux_shift;
+
+	if (val != orig) {
+		regmap_write(mux->regmap, mux->mux_ofs, val);
+
+		if (mux->upd_shift >= 0)
+			regmap_write(mux->regmap, mux->upd_ofs,
+				     BIT(mux->upd_shift));
+	}
+
+	if (mux->lock)
+		spin_unlock_irqrestore(mux->lock, flags);
+
+	return 0;
+}
+
+static int mtk_mux_set_parent_setclr(struct clk_hw *hw, u8 index)
+{
+	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
+	u32 mask = GENMASK(mux->mux_width - 1, 0);
+	u32 val, orig;
+	unsigned long flags = 0;
+
+	if (mux->lock)
+		spin_lock_irqsave(mux->lock, flags);
+
+	regmap_read(mux->regmap, mux->mux_ofs, &val);
+	orig = val;
+	val &= ~(mask << mux->mux_shift);
+	val |= index << mux->mux_shift;
+
+	if (val != orig) {
+		val = (mask << mux->mux_shift);
+		regmap_write(mux->regmap, mux->mux_clr_ofs, val);
+		val = (index << mux->mux_shift);
+		regmap_write(mux->regmap, mux->mux_set_ofs, val);
+
+		if (mux->upd_shift >= 0)
+			regmap_write(mux->regmap, mux->upd_ofs,
+				     BIT(mux->upd_shift));
+	}
+
+	if (mux->lock)
+		spin_unlock_irqrestore(mux->lock, flags);
+
+	return 0;
+}
+
+const struct clk_ops mtk_mux_upd_ops = {
+	.enable = mtk_mux_enable,
+	.disable = mtk_mux_disable,
+	.is_enabled = mtk_mux_is_enabled,
+	.get_parent = mtk_mux_get_parent,
+	.set_parent = mtk_mux_set_parent,
+	.determine_rate = NULL,
+};
+
+const struct clk_ops mtk_mux_clr_set_upd_ops = {
+	.enable = mtk_mux_enable_setclr,
+	.disable = mtk_mux_disable_setclr,
+	.is_enabled = mtk_mux_is_enabled,
+	.get_parent = mtk_mux_get_parent,
+	.set_parent = mtk_mux_set_parent_setclr,
+	.determine_rate = NULL,
+};
+
+struct clk *mtk_clk_register_mux(const struct mtk_mux *mux,
+				 struct regmap *regmap,
+				 spinlock_t *lock)
+{
+	struct clk *clk;
+	struct clk_init_data init;
+	struct mtk_clk_mux *mtk_mux = NULL;
+	int ret;
+
+	mtk_mux = kzalloc(sizeof(*mtk_mux), GFP_KERNEL);
+	if (!mtk_mux)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = mux->name;
+	init.flags = (mux->flags) | CLK_SET_RATE_PARENT;
+	init.parent_names = mux->parent_names;
+	init.num_parents = mux->num_parents;
+	init.ops = mux->ops;
+
+	mtk_mux->regmap = regmap;
+	mtk_mux->name = mux->name;
+	mtk_mux->mux_ofs = mux->mux_ofs;
+	mtk_mux->mux_set_ofs = mux->set_ofs;
+	mtk_mux->mux_clr_ofs = mux->clr_ofs;
+	mtk_mux->upd_ofs = mux->upd_ofs;
+	mtk_mux->mux_shift = mux->mux_shift;
+	mtk_mux->mux_width = mux->mux_width;
+	mtk_mux->gate_shift = mux->gate_shift;
+	mtk_mux->upd_shift = mux->upd_shift;
+
+	mtk_mux->lock = lock;
+	mtk_mux->hw.init = &init;
+
+	clk = clk_register(NULL, &mtk_mux->hw);
+	if (IS_ERR(clk)) {
+		ret = PTR_ERR(clk);
+		goto err_out;
+	}
+
+	return clk;
+err_out:
+	kfree(mtk_mux);
+
+	return ERR_PTR(ret);
+}
diff --git a/drivers/clk/mediatek/clk-mux.h b/drivers/clk/mediatek/clk-mux.h
new file mode 100644
index 0000000..64f8e7c
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mux.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Owen Chen <owen.chen@mediatek.com>
+ */
+
+#ifndef __DRV_CLK_MUX_H
+#define __DRV_CLK_MUX_H
+
+#include <linux/clk-provider.h>
+
+struct mtk_clk_mux {
+	struct clk_hw hw;
+	struct regmap *regmap;
+
+	const char *name;
+
+	int mux_set_ofs;
+	int mux_clr_ofs;
+	int mux_ofs;
+	int upd_ofs;
+
+	s8 mux_shift;
+	s8 mux_width;
+	s8 gate_shift;
+	s8 upd_shift;
+
+	spinlock_t *lock;
+};
+
+extern const struct clk_ops mtk_mux_upd_ops;
+extern const struct clk_ops mtk_mux_clr_set_upd_ops;
+
+struct clk *mtk_clk_register_mux(const struct mtk_mux *mux,
+				 struct regmap *regmap,
+				 spinlock_t *lock);
+
+#endif /* __DRV_CLK_MUX_H */
-- 
1.7.9.5


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

* [PATCH v5 10/11] clk: mediatek: Add MT6765 clock support
  2018-07-17  8:52 [PATCH v5 0/11] Add basic SoC support for mt6765 Mars Cheng
                   ` (8 preceding siblings ...)
  2018-07-17  8:52 ` [PATCH v5 09/11] clk: mediatek: add new clkmux register API Mars Cheng
@ 2018-07-17  8:52 ` Mars Cheng
  2018-07-17 16:09   ` kbuild test robot
                     ` (2 more replies)
  2018-07-17  8:52 ` [PATCH v5 11/11] arm64: dts: mediatek: add mt6765 support Mars Cheng
  10 siblings, 3 replies; 32+ messages in thread
From: Mars Cheng @ 2018-07-17  8:52 UTC (permalink / raw)
  To: Matthias Brugger, Rob Herring, Marc Zyngier, Ryder Lee,
	Stephen Boyd, Sean Wang
  Cc: CC Hwang, Loda Chou, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, linux-serial, linux-arm-kernel, linux-clk,
	Owen Chen, Mars Cheng

From: Owen Chen <owen.chen@mediatek.com>

Add MT6765 clock support, include topckgen, apmixedsys,
infracfg, and subsystem clocks.

Signed-off-by: Owen Chen <owen.chen@mediatek.com>
Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
---
 drivers/clk/mediatek/Kconfig             |   87 +++
 drivers/clk/mediatek/Makefile            |    7 +
 drivers/clk/mediatek/clk-mt6765-audio.c  |  109 ++++
 drivers/clk/mediatek/clk-mt6765-cam.c    |   83 +++
 drivers/clk/mediatek/clk-mt6765-img.c    |   79 +++
 drivers/clk/mediatek/clk-mt6765-mipi0a.c |   77 +++
 drivers/clk/mediatek/clk-mt6765-mm.c     |  105 ++++
 drivers/clk/mediatek/clk-mt6765-vcodec.c |   79 +++
 drivers/clk/mediatek/clk-mt6765.c        |  963 ++++++++++++++++++++++++++++++
 9 files changed, 1589 insertions(+)
 create mode 100644 drivers/clk/mediatek/clk-mt6765-audio.c
 create mode 100644 drivers/clk/mediatek/clk-mt6765-cam.c
 create mode 100644 drivers/clk/mediatek/clk-mt6765-img.c
 create mode 100644 drivers/clk/mediatek/clk-mt6765-mipi0a.c
 create mode 100644 drivers/clk/mediatek/clk-mt6765-mm.c
 create mode 100644 drivers/clk/mediatek/clk-mt6765-vcodec.c
 create mode 100644 drivers/clk/mediatek/clk-mt6765.c

diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
index 3dd1dab..95e5e52 100644
--- a/drivers/clk/mediatek/Kconfig
+++ b/drivers/clk/mediatek/Kconfig
@@ -193,4 +193,91 @@ config COMMON_CLK_MT8173
 	default ARCH_MEDIATEK
 	---help---
 	  This driver supports MediaTek MT8173 clocks.
+
+config COMMON_CLK_MT6765
+       bool "Clock driver for MediaTek MT6765"
+       depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
+       select COMMON_CLK_MEDIATEK
+       default ARCH_MEDIATEK && ARM64
+       help
+         This driver supports MediaTek MT6765 basic clocks.
+
+config COMMON_CLK_MT6765_AUDIOSYS
+       bool "Clock driver for MediaTek MT6765 audiosys"
+       depends on COMMON_CLK_MT6765
+       help
+         This driver supports MediaTek MT6765 audiosys clocks.
+
+config COMMON_CLK_MT6765_CAMSYS
+       bool "Clock driver for MediaTek MT6765 camsys"
+       depends on COMMON_CLK_MT6765
+       help
+         This driver supports MediaTek MT6765 camsys clocks.
+
+config COMMON_CLK_MT6765_GCESYS
+       bool "Clock driver for MediaTek MT6765 gcesys"
+       depends on COMMON_CLK_MT6765
+       help
+         This driver supports MediaTek MT6765 gcesys clocks.
+
+config COMMON_CLK_MT6765_MMSYS
+       bool "Clock driver for MediaTek MT6765 mmsys"
+       depends on COMMON_CLK_MT6765
+       help
+         This driver supports MediaTek MT6765 mmsys clocks.
+
+config COMMON_CLK_MT6765_IMGSYS
+       bool "Clock driver for MediaTek MT6765 imgsys"
+       depends on COMMON_CLK_MT6765
+       help
+         This driver supports MediaTek MT6765 imgsys clocks.
+
+config COMMON_CLK_MT6765_VCODECSYS
+       bool "Clock driver for MediaTek MT6765 vcodecsys"
+       depends on COMMON_CLK_MT6765
+       help
+         This driver supports MediaTek MT6765 vcodecsys clocks.
+
+config COMMON_CLK_MT6765_MFGSYS
+       bool "Clock driver for MediaTek MT6765 mfgsys"
+       depends on COMMON_CLK_MT6765
+       help
+         This driver supports MediaTek MT6765 mfgsys clocks.
+
+config COMMON_CLK_MT6765_MIPI0ASYS
+       bool "Clock driver for MediaTek MT6765 mipi0asys"
+       depends on COMMON_CLK_MT6765
+       help
+         This driver supports MediaTek MT6765 mipi0asys clocks.
+
+config COMMON_CLK_MT6765_MIPI0BSYS
+       bool "Clock driver for MediaTek MT6765 mipi0bsys"
+       depends on COMMON_CLK_MT6765
+       help
+         This driver supports MediaTek MT6765 mipi0bsys clocks.
+
+config COMMON_CLK_MT6765_MIPI1ASYS
+       bool "Clock driver for MediaTek MT6765 mipi1asys"
+       depends on COMMON_CLK_MT6765
+       help
+         This driver supports MediaTek MT6765 mipi1asys clocks.
+
+config COMMON_CLK_MT6765_MIPI1BSYS
+       bool "Clock driver for MediaTek MT6765 mipi1bsys"
+       depends on COMMON_CLK_MT6765
+       help
+         This driver supports MediaTek MT6765 mipi1bsys clocks.
+
+config COMMON_CLK_MT6765_MIPI2ASYS
+       bool "Clock driver for MediaTek MT6765 mipi2asys"
+       depends on COMMON_CLK_MT6765
+      help
+         This driver supports MediaTek MT6765 mipi2asys clocks.
+
+config COMMON_CLK_MT6765_MIPI2BSYS
+       bool "Clock driver for MediaTek MT6765 mipi2bsys"
+       depends on COMMON_CLK_MT6765
+       help
+         This driver supports MediaTek MT6765 mipi2bsys clocks.
+
 endmenu
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index b97980d..b455a8e 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -1,5 +1,12 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o clk-cpumux.o reset.o clk-mux.o
+obj-$(CONFIG_COMMON_CLK_MT6765) += clk-mt6765.o
+obj-$(CONFIG_COMMON_CLK_MT6765_AUDIOSYS) += clk-mt6765-audio.o
+obj-$(CONFIG_COMMON_CLK_MT6765_CAMSYS) += clk-mt6765-cam.o
+obj-$(CONFIG_COMMON_CLK_MT6765_IMGSYS) += clk-mt6765-img.o
+obj-$(CONFIG_COMMON_CLK_MT6765_MIPI0ASYS) += clk-mt6765-mipi0a.o
+obj-$(CONFIG_COMMON_CLK_MT6765_MMSYS) += clk-mt6765-mm.o
+obj-$(CONFIG_COMMON_CLK_MT6765_VCODECSYS) += clk-mt6765-vcodec.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
diff --git a/drivers/clk/mediatek/clk-mt6765-audio.c b/drivers/clk/mediatek/clk-mt6765-audio.c
new file mode 100644
index 0000000..0515e2b
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt6765-audio.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Owen Chen <owen.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/mt6765-clk.h>
+
+static const struct mtk_gate_regs audio0_cg_regs = {
+	.set_ofs = 0x0,
+	.clr_ofs = 0x0,
+	.sta_ofs = 0x0,
+};
+
+static const struct mtk_gate_regs audio1_cg_regs = {
+	.set_ofs = 0x4,
+	.clr_ofs = 0x4,
+	.sta_ofs = 0x4,
+};
+
+#define GATE_AUDIO0(_id, _name, _parent, _shift) {	\
+		.id = _id,				\
+		.name = _name,				\
+		.parent_name = _parent,			\
+		.regs = &audio0_cg_regs,		\
+		.shift = _shift,			\
+		.ops = &mtk_clk_gate_ops_no_setclr,	\
+	}
+
+#define GATE_AUDIO1(_id, _name, _parent, _shift) {	\
+		.id = _id,				\
+		.name = _name,				\
+		.parent_name = _parent,			\
+		.regs = &audio1_cg_regs,		\
+		.shift = _shift,			\
+		.ops = &mtk_clk_gate_ops_no_setclr,	\
+	}
+
+static const struct mtk_gate audio_clks[] __initconst = {
+	/* AUDIO0 */
+	GATE_AUDIO0(CLK_AUDIO_AFE, "aud_afe", "audio_ck", 2),
+	GATE_AUDIO0(CLK_AUDIO_22M, "aud_22m", "aud_engen1_ck", 8),
+	GATE_AUDIO0(CLK_AUDIO_APLL_TUNER, "aud_apll_tuner",
+		    "aud_engen1_ck", 19),
+	GATE_AUDIO0(CLK_AUDIO_ADC, "aud_adc", "audio_ck", 24),
+	GATE_AUDIO0(CLK_AUDIO_DAC, "aud_dac", "audio_ck", 25),
+	GATE_AUDIO0(CLK_AUDIO_DAC_PREDIS, "aud_dac_predis",
+		    "audio_ck", 26),
+	GATE_AUDIO0(CLK_AUDIO_TML, "aud_tml", "audio_ck", 27),
+	/* AUDIO1 */
+	GATE_AUDIO1(CLK_AUDIO_I2S1_BCLK, "aud_i2s1_bclk",
+		    "audio_ck", 4),
+	GATE_AUDIO1(CLK_AUDIO_I2S2_BCLK, "aud_i2s2_bclk",
+		    "audio_ck", 5),
+	GATE_AUDIO1(CLK_AUDIO_I2S3_BCLK, "aud_i2s3_bclk",
+		    "audio_ck", 6),
+	GATE_AUDIO1(CLK_AUDIO_I2S4_BCLK, "aud_i2s4_bclk",
+		    "audio_ck", 7),
+};
+
+static int clk_mt6765_audio_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_AUDIO_NR_CLK);
+
+	mtk_clk_register_gates(node, audio_clks,
+			       ARRAY_SIZE(audio_clks), clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+		       __func__, r);
+
+	return r;
+}
+
+static const struct of_device_id of_match_clk_mt6765_audio[] = {
+	{ .compatible = "mediatek,mt6765-audsys", },
+	{}
+};
+
+static struct platform_driver clk_mt6765_audio_drv = {
+	.probe = clk_mt6765_audio_probe,
+	.driver = {
+		.name = "clk-mt6765-audio",
+		.of_match_table = of_match_clk_mt6765_audio,
+	},
+};
+
+builtin_platform_driver(clk_mt6765_audio_drv);
diff --git a/drivers/clk/mediatek/clk-mt6765-cam.c b/drivers/clk/mediatek/clk-mt6765-cam.c
new file mode 100644
index 0000000..e36721b
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt6765-cam.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Owen Chen <owen.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/mt6765-clk.h>
+
+static const struct mtk_gate_regs cam_cg_regs = {
+	.set_ofs = 0x4,
+	.clr_ofs = 0x8,
+	.sta_ofs = 0x0,
+};
+
+#define GATE_CAM(_id, _name, _parent, _shift) {		\
+		.id = _id,				\
+		.name = _name,				\
+		.parent_name = _parent,			\
+		.regs = &cam_cg_regs,			\
+		.shift = _shift,			\
+		.ops = &mtk_clk_gate_ops_setclr,	\
+	}
+
+static const struct mtk_gate cam_clks[] __initconst = {
+	GATE_CAM(CLK_CAM_LARB3, "cam_larb3", "mm_ck", 0),
+	GATE_CAM(CLK_CAM_DFP_VAD, "cam_dfp_vad", "mm_ck", 1),
+	GATE_CAM(CLK_CAM, "cam", "mm_ck", 6),
+	GATE_CAM(CLK_CAMTG, "camtg", "mm_ck", 7),
+	GATE_CAM(CLK_CAM_SENINF, "cam_seninf", "mm_ck", 8),
+	GATE_CAM(CLK_CAMSV0, "camsv0", "mm_ck", 9),
+	GATE_CAM(CLK_CAMSV1, "camsv1", "mm_ck", 10),
+	GATE_CAM(CLK_CAMSV2, "camsv2", "mm_ck", 11),
+	GATE_CAM(CLK_CAM_CCU, "cam_ccu", "mm_ck", 12),
+};
+
+static int clk_mt6765_cam_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_CAM_NR_CLK);
+
+	mtk_clk_register_gates(node, cam_clks, ARRAY_SIZE(cam_clks), clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+		       __func__, r);
+
+	return r;
+}
+
+static const struct of_device_id of_match_clk_mt6765_cam[] = {
+	{ .compatible = "mediatek,mt6765-camsys", },
+	{}
+};
+
+static struct platform_driver clk_mt6765_cam_drv = {
+	.probe = clk_mt6765_cam_probe,
+	.driver = {
+		.name = "clk-mt6765-cam",
+		.of_match_table = of_match_clk_mt6765_cam,
+	},
+};
+
+builtin_platform_driver(clk_mt6765_cam_drv);
diff --git a/drivers/clk/mediatek/clk-mt6765-img.c b/drivers/clk/mediatek/clk-mt6765-img.c
new file mode 100644
index 0000000..a0c35ce
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt6765-img.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Owen Chen <owen.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/mt6765-clk.h>
+
+static const struct mtk_gate_regs img_cg_regs = {
+	.set_ofs = 0x4,
+	.clr_ofs = 0x8,
+	.sta_ofs = 0x0,
+};
+
+#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[] __initconst = {
+	GATE_IMG(CLK_IMG_LARB2, "img_larb2", "mm_ck", 0),
+	GATE_IMG(CLK_IMG_DIP, "img_dip", "mm_ck", 2),
+	GATE_IMG(CLK_IMG_FDVT, "img_fdvt", "mm_ck", 3),
+	GATE_IMG(CLK_IMG_DPE, "img_dpe", "mm_ck", 4),
+	GATE_IMG(CLK_IMG_RSC, "img_rsc", "mm_ck", 5),
+};
+
+static int clk_mt6765_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_CLK);
+
+	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)
+		pr_err("%s(): could not register clock provider: %d\n",
+		       __func__, r);
+
+	return r;
+}
+
+static const struct of_device_id of_match_clk_mt6765_img[] = {
+	{ .compatible = "mediatek,mt6765-imgsys", },
+	{}
+};
+
+static struct platform_driver clk_mt6765_img_drv = {
+	.probe = clk_mt6765_img_probe,
+	.driver = {
+		.name = "clk-mt6765-img",
+		.of_match_table = of_match_clk_mt6765_img,
+	},
+};
+
+builtin_platform_driver(clk_mt6765_img_drv);
diff --git a/drivers/clk/mediatek/clk-mt6765-mipi0a.c b/drivers/clk/mediatek/clk-mt6765-mipi0a.c
new file mode 100644
index 0000000..7366be6
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt6765-mipi0a.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Owen Chen <owen.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/mt6765-clk.h>
+
+static const struct mtk_gate_regs mipi0a_cg_regs = {
+	.set_ofs = 0x80,
+	.clr_ofs = 0x80,
+	.sta_ofs = 0x80,
+};
+
+#define GATE_MIPI0A(_id, _name, _parent, _shift) {	\
+		.id = _id,				\
+		.name = _name,				\
+		.parent_name = _parent,			\
+		.regs = &mipi0a_cg_regs,			\
+		.shift = _shift,			\
+		.ops = &mtk_clk_gate_ops_no_setclr_inv,	\
+	}
+
+static const struct mtk_gate mipi0a_clks[] __initconst = {
+	GATE_MIPI0A(CLK_MIPI0A_CSR_CSI_EN_0A,
+		    "mipi0a_csr_0a", "f_fseninf_ck", 1),
+};
+
+static int clk_mt6765_mipi0a_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_MIPI0A_NR_CLK);
+
+	mtk_clk_register_gates(node, mipi0a_clks,
+			       ARRAY_SIZE(mipi0a_clks), clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+		       __func__, r);
+
+	return r;
+}
+
+static const struct of_device_id of_match_clk_mt6765_mipi0a[] = {
+	{ .compatible = "mediatek,mt6765-mipi_rx_ana_csi0a", },
+	{}
+};
+
+static struct platform_driver clk_mt6765_mipi0a_drv = {
+	.probe = clk_mt6765_mipi0a_probe,
+	.driver = {
+		.name = "clk-mt6765-mipi0a",
+		.of_match_table = of_match_clk_mt6765_mipi0a,
+	},
+};
+
+builtin_platform_driver(clk_mt6765_mipi0a_drv);
diff --git a/drivers/clk/mediatek/clk-mt6765-mm.c b/drivers/clk/mediatek/clk-mt6765-mm.c
new file mode 100644
index 0000000..5ad1e0d
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt6765-mm.c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Owen Chen <owen.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/mt6765-clk.h>
+
+static const struct mtk_gate_regs mm_cg_regs = {
+	.set_ofs = 0x104,
+	.clr_ofs = 0x108,
+	.sta_ofs = 0x100,
+};
+
+#define GATE_MM(_id, _name, _parent, _shift) {		\
+		.id = _id,				\
+		.name = _name,				\
+		.parent_name = _parent,			\
+		.regs = &mm_cg_regs,			\
+		.shift = _shift,			\
+		.ops = &mtk_clk_gate_ops_setclr,	\
+	}
+
+static const struct mtk_gate mm_clks[] __initconst = {
+	/* MM */
+	GATE_MM(CLK_MM_MDP_RDMA0, "mm_mdp_rdma0", "mm_ck", 0),
+	GATE_MM(CLK_MM_MDP_CCORR0, "mm_mdp_ccorr0", "mm_ck", 1),
+	GATE_MM(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "mm_ck", 2),
+	GATE_MM(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "mm_ck", 3),
+	GATE_MM(CLK_MM_MDP_TDSHP0, "mm_mdp_tdshp0", "mm_ck", 4),
+	GATE_MM(CLK_MM_MDP_WROT0, "mm_mdp_wrot0", "mm_ck", 5),
+	GATE_MM(CLK_MM_MDP_WDMA0, "mm_mdp_wdma0", "mm_ck", 6),
+	GATE_MM(CLK_MM_DISP_OVL0, "mm_disp_ovl0", "mm_ck", 7),
+	GATE_MM(CLK_MM_DISP_OVL0_2L, "mm_disp_ovl0_2l", "mm_ck", 8),
+	GATE_MM(CLK_MM_DISP_RSZ0, "mm_disp_rsz0", "mm_ck", 9),
+	GATE_MM(CLK_MM_DISP_RDMA0, "mm_disp_rdma0", "mm_ck", 10),
+	GATE_MM(CLK_MM_DISP_WDMA0, "mm_disp_wdma0", "mm_ck", 11),
+	GATE_MM(CLK_MM_DISP_COLOR0, "mm_disp_color0", "mm_ck", 12),
+	GATE_MM(CLK_MM_DISP_CCORR0, "mm_disp_ccorr0", "mm_ck", 13),
+	GATE_MM(CLK_MM_DISP_AAL0, "mm_disp_aal0", "mm_ck", 14),
+	GATE_MM(CLK_MM_DISP_GAMMA0, "mm_disp_gamma0", "mm_ck", 15),
+	GATE_MM(CLK_MM_DISP_DITHER0, "mm_disp_dither0", "mm_ck", 16),
+	GATE_MM(CLK_MM_DSI0, "mm_dsi0", "mm_ck", 17),
+	GATE_MM(CLK_MM_FAKE_ENG, "mm_fake_eng", "mm_ck", 18),
+	GATE_MM(CLK_MM_SMI_COMMON, "mm_smi_common", "mm_ck", 19),
+	GATE_MM(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_ck", 20),
+	GATE_MM(CLK_MM_SMI_COMM0, "mm_smi_comm0", "mm_ck", 21),
+	GATE_MM(CLK_MM_SMI_COMM1, "mm_smi_comm1", "mm_ck", 22),
+	GATE_MM(CLK_MM_CAM_MDP, "mm_cam_mdp_ck", "mm_ck", 23),
+	GATE_MM(CLK_MM_SMI_IMG, "mm_smi_img_ck", "mm_ck", 24),
+	GATE_MM(CLK_MM_SMI_CAM, "mm_smi_cam_ck", "mm_ck", 25),
+	GATE_MM(CLK_MM_IMG_DL_RELAY, "mm_img_dl_relay", "mm_ck", 26),
+	GATE_MM(CLK_MM_IMG_DL_ASYNC_TOP, "mm_imgdl_async", "mm_ck", 27),
+	GATE_MM(CLK_MM_DIG_DSI, "mm_dig_dsi_ck", "mm_ck", 28),
+	GATE_MM(CLK_MM_F26M_HRTWT, "mm_hrtwt", "f_f26m_ck", 29),
+};
+
+static int clk_mt6765_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_CLK);
+
+	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)
+		pr_err("%s(): could not register clock provider: %d\n",
+		       __func__, r);
+
+	return r;
+}
+
+static const struct of_device_id of_match_clk_mt6765_mm[] = {
+	{ .compatible = "mediatek,mt6765-mmsys", },
+	{}
+};
+
+static struct platform_driver clk_mt6765_mm_drv = {
+	.probe = clk_mt6765_mm_probe,
+	.driver = {
+		.name = "clk-mt6765-mm",
+		.of_match_table = of_match_clk_mt6765_mm,
+	},
+};
+
+builtin_platform_driver(clk_mt6765_mm_drv);
diff --git a/drivers/clk/mediatek/clk-mt6765-vcodec.c b/drivers/clk/mediatek/clk-mt6765-vcodec.c
new file mode 100644
index 0000000..fb690c2
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt6765-vcodec.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Owen Chen <owen.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/mt6765-clk.h>
+
+static const struct mtk_gate_regs venc_cg_regs = {
+	.set_ofs = 0x4,
+	.clr_ofs = 0x8,
+	.sta_ofs = 0x0,
+};
+
+#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[] __initconst = {
+	GATE_VENC(CLK_VENC_SET0_LARB, "venc_set0_larb", "mm_ck", 0),
+	GATE_VENC(CLK_VENC_SET1_VENC, "venc_set1_venc", "mm_ck", 4),
+	GATE_VENC(CLK_VENC_SET2_JPGENC, "jpgenc", "mm_ck", 8),
+	GATE_VENC(CLK_VENC_SET3_VDEC, "venc_set3_vdec", "mm_ck", 12),
+};
+
+static int clk_mt6765_vcodec_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_CLK);
+
+	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)
+		pr_err("%s(): could not register clock provider: %d\n",
+		       __func__, r);
+
+	return r;
+}
+
+static const struct of_device_id of_match_clk_mt6765_venc[] = {
+	{ .compatible = "mediatek,mt6765-vcodecsys", },
+	{}
+};
+
+static struct platform_driver clk_mt6765_vcodec_drv = {
+	.probe = clk_mt6765_vcodec_probe,
+	.driver = {
+		.name = "clk-mt6765-vcodec",
+		.of_match_table = of_match_clk_mt6765_vcodec,
+	},
+};
+
+builtin_platform_driver(clk_mt6765_vcodec_drv);
diff --git a/drivers/clk/mediatek/clk-mt6765.c b/drivers/clk/mediatek/clk-mt6765.c
new file mode 100644
index 0000000..7b360b9
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt6765.c
@@ -0,0 +1,963 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Owen Chen <owen.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/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+#include "clk-mux.h"
+
+#include <dt-bindings/clock/mt6765-clk.h>
+
+/*fmeter div select 4*/
+#define _DIV4_ 1
+
+static DEFINE_SPINLOCK(mt6765_clk_lock);
+
+/* Total 12 subsys */
+void __iomem *cksys_base;
+void __iomem *apmixed_base;
+
+/* CKSYS */
+#define CLK_SCP_CFG_0		(cksys_base + 0x200)
+#define CLK_SCP_CFG_1		(cksys_base + 0x204)
+
+/* CG */
+#define AP_PLL_CON3		(apmixed_base + 0x0C)
+#define PLLON_CON0		(apmixed_base + 0x44)
+#define PLLON_CON1		(apmixed_base + 0x48)
+
+/* clk cfg update */
+#define CLK_CFG_0		0x40
+#define CLK_CFG_0_SET		0x44
+#define CLK_CFG_0_CLR		0x48
+#define CLK_CFG_1		0x50
+#define CLK_CFG_1_SET		0x54
+#define CLK_CFG_1_CLR		0x58
+#define CLK_CFG_2		0x60
+#define CLK_CFG_2_SET		0x64
+#define CLK_CFG_2_CLR		0x68
+#define CLK_CFG_3		0x70
+#define CLK_CFG_3_SET		0x74
+#define CLK_CFG_3_CLR		0x78
+#define CLK_CFG_4		0x80
+#define CLK_CFG_4_SET		0x84
+#define CLK_CFG_4_CLR		0x88
+#define CLK_CFG_5		0x90
+#define CLK_CFG_5_SET		0x94
+#define CLK_CFG_5_CLR		0x98
+#define CLK_CFG_6		0xa0
+#define CLK_CFG_6_SET		0xa4
+#define CLK_CFG_6_CLR		0xa8
+#define CLK_CFG_7		0xb0
+#define CLK_CFG_7_SET		0xb4
+#define CLK_CFG_7_CLR		0xb8
+#define CLK_CFG_8		0xc0
+#define CLK_CFG_8_SET		0xc4
+#define CLK_CFG_8_CLR		0xc8
+#define CLK_CFG_9		0xd0
+#define CLK_CFG_9_SET		0xd4
+#define CLK_CFG_9_CLR		0xd8
+#define CLK_CFG_10		0xe0
+#define CLK_CFG_10_SET		0xe4
+#define CLK_CFG_10_CLR		0xe8
+#define CLK_CFG_UPDATE		0x004
+
+static const struct mtk_fixed_clk fixed_clks[] __initconst = {
+	FIXED_CLK(CLK_TOP_F_FRTC, "f_frtc_ck", "clk32k", 32768),
+	FIXED_CLK(CLK_TOP_CLK26M, "clk_26m_ck", "clk26m", 26000000),
+	FIXED_CLK(CLK_TOP_DMPLL, "dmpll_ck", NULL, 466000000),
+};
+
+static const struct mtk_fixed_factor top_divs[] __initconst = {
+	FACTOR(CLK_TOP_SYSPLL, "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_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, "univpll", "univ2pll", 1, 2),
+	FACTOR(CLK_TOP_USB20_192M, "usb20_192m_ck", "univpll", 2, 13),
+	FACTOR(CLK_TOP_USB20_192M_D4, "usb20_192m_d4", "usb20_192m_ck", 1, 4),
+	FACTOR(CLK_TOP_USB20_192M_D8, "usb20_192m_d8", "usb20_192m_ck", 1, 8),
+	FACTOR(CLK_TOP_USB20_192M_D16,
+	       "usb20_192m_d16", "usb20_192m_ck", 1, 16),
+	FACTOR(CLK_TOP_USB20_192M_D32,
+	       "usb20_192m_d32", "usb20_192m_ck", 1, 32),
+	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_UNIVPLL_D3, "univpll_d3", "univpll", 1, 3),
+	FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll_d3", 1, 2),
+	FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll_d3", 1, 4),
+	FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll_d3", 1, 8),
+	FACTOR(CLK_TOP_UNIVPLL2_D32, "univpll2_d32", "univpll_d3", 1, 32),
+	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_MMPLL, "mmpll_ck", "mmpll", 1, 1),
+	FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll_ck", 1, 2),
+	FACTOR(CLK_TOP_MPLL, "mpll_ck", "mpll", 1, 1),
+	FACTOR(CLK_TOP_DA_MPLL_104M_DIV, "mpll_104m_div", "mpll_ck", 1, 2),
+	FACTOR(CLK_TOP_DA_MPLL_52M_DIV, "mpll_52m_div", "mpll_ck", 1, 4),
+	FACTOR(CLK_TOP_MFGPLL, "mfgpll_ck", "mfgpll", 1, 1),
+	FACTOR(CLK_TOP_MSDCPLL, "msdcpll_ck", "msdcpll", 1, 1),
+	FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll_ck", 1, 2),
+	FACTOR(CLK_TOP_APLL1, "apll1_ck", "apll1", 1, 1),
+	FACTOR(CLK_TOP_APLL1_D2, "apll1_d2", "apll1_ck", 1, 2),
+	FACTOR(CLK_TOP_APLL1_D4, "apll1_d4", "apll1_ck", 1, 4),
+	FACTOR(CLK_TOP_APLL1_D8, "apll1_d8", "apll1_ck", 1, 8),
+	FACTOR(CLK_TOP_ULPOSC1, "ulposc1_ck", "ulposc1", 1, 1),
+	FACTOR(CLK_TOP_ULPOSC1_D2, "ulposc1_d2", "ulposc1_ck", 1, 2),
+	FACTOR(CLK_TOP_ULPOSC1_D4, "ulposc1_d4", "ulposc1_ck", 1, 4),
+	FACTOR(CLK_TOP_ULPOSC1_D8, "ulposc1_d8", "ulposc1_ck", 1, 8),
+	FACTOR(CLK_TOP_ULPOSC1_D16, "ulposc1_d16", "ulposc1_ck", 1, 16),
+	FACTOR(CLK_TOP_ULPOSC1_D32, "ulposc1_d32", "ulposc1_ck", 1, 32),
+	FACTOR(CLK_TOP_F_F26M, "f_f26m_ck", "clk_26m_ck", 1, 1),
+	FACTOR(CLK_TOP_AXI, "axi_ck", "axi_sel", 1, 1),
+	FACTOR(CLK_TOP_MM, "mm_ck", "mm_sel", 1, 1),
+	FACTOR(CLK_TOP_SCP, "scp_ck", "scp_sel", 1, 1),
+	FACTOR(CLK_TOP_MFG, "mfg_ck", "mfg_sel", 1, 1),
+	FACTOR(CLK_TOP_F_FUART, "f_fuart_ck", "uart_sel", 1, 1),
+	FACTOR(CLK_TOP_SPI, "spi_ck", "spi_sel", 1, 1),
+	FACTOR(CLK_TOP_MSDC50_0, "msdc50_0_ck", "msdc50_0_sel", 1, 1),
+	FACTOR(CLK_TOP_MSDC30_1, "msdc30_1_ck", "msdc30_1_sel", 1, 1),
+	FACTOR(CLK_TOP_AUDIO, "audio_ck", "audio_sel", 1, 1),
+	FACTOR(CLK_TOP_AUD_1, "aud_1_ck", "aud_1_sel", 1, 1),
+	FACTOR(CLK_TOP_AUD_ENGEN1, "aud_engen1_ck", "aud_engen1_sel", 1, 1),
+	FACTOR(CLK_TOP_F_FDISP_PWM, "f_fdisp_pwm_ck", "disp_pwm_sel", 1, 1),
+	FACTOR(CLK_TOP_SSPM, "sspm_ck", "sspm_sel", 1, 1),
+	FACTOR(CLK_TOP_DXCC, "dxcc_ck", "dxcc_sel", 1, 1),
+	FACTOR(CLK_TOP_I2C, "i2c_ck", "i2c_sel", 1, 1),
+	FACTOR(CLK_TOP_F_FPWM, "f_fpwm_ck", "pwm_sel", 1, 1),
+	FACTOR(CLK_TOP_F_FSENINF, "f_fseninf_ck", "seninf_sel", 1, 1),
+	FACTOR(CLK_TOP_AES_FDE, "aes_fde_ck", "aes_fde_sel", 1, 1),
+	FACTOR(CLK_TOP_F_BIST2FPC, "f_bist2fpc_ck", "univpll2_d2", 1, 1),
+	FACTOR(CLK_TOP_ARMPLL_DIVIDER_PLL0, "arm_div_pll0", "syspll_d2", 1, 1),
+	FACTOR(CLK_TOP_ARMPLL_DIVIDER_PLL1, "arm_div_pll1", "syspll_ck", 1, 1),
+	FACTOR(CLK_TOP_ARMPLL_DIVIDER_PLL2, "arm_div_pll2", "univpll_d2", 1, 1),
+	FACTOR(CLK_TOP_DA_USB20_48M_DIV,
+	       "usb20_48m_div", "usb20_192m_d4", 1, 1),
+	FACTOR(CLK_TOP_DA_UNIV_48M_DIV, "univ_48m_div", "usb20_192m_d4", 1, 1),
+};
+
+static const char * const axi_parents[] __initconst = {
+	"clk26m",
+	"syspll_d7",
+	"syspll1_d4",
+	"syspll3_d2"
+};
+
+static const char * const mem_parents[] __initconst = {
+	"clk26m",
+	"dmpll_ck",
+	"apll1_ck"
+};
+
+static const char * const mm_parents[] __initconst = {
+	"clk26m",
+	"mmpll_ck",
+	"syspll1_d2",
+	"syspll_d5",
+	"syspll1_d4",
+	"univpll_d5",
+	"univpll1_d2",
+	"mmpll_d2"
+};
+
+static const char * const scp_parents[] __initconst = {
+	"clk26m",
+	"syspll4_d2",
+	"univpll2_d2",
+	"syspll1_d2",
+	"univpll1_d2",
+	"syspll_d3",
+	"univpll_d3"
+};
+
+static const char * const mfg_parents[] __initconst = {
+	"clk26m",
+	"mfgpll_ck",
+	"syspll_d3",
+	"univpll_d3"
+};
+
+static const char * const atb_parents[] __initconst = {
+	"clk26m",
+	"syspll1_d4",
+	"syspll1_d2"
+};
+
+static const char * const camtg_parents[] __initconst = {
+	"clk26m",
+	"usb20_192m_d8",
+	"univpll2_d8",
+	"usb20_192m_d4",
+	"univpll2_d32",
+	"usb20_192m_d16",
+	"usb20_192m_d32"
+};
+
+static const char * const uart_parents[] __initconst = {
+	"clk26m",
+	"univpll2_d8"
+};
+
+static const char * const spi_parents[] __initconst = {
+	"clk26m",
+	"syspll3_d2",
+	"syspll4_d2",
+	"syspll2_d4"
+};
+
+static const char * const msdc5hclk_parents[] __initconst = {
+	"clk26m",
+	"syspll1_d2",
+	"univpll1_d4",
+	"syspll2_d2"
+};
+
+static const char * const msdc50_0_parents[] __initconst = {
+	"clk26m",
+	"msdcpll_ck",
+	"syspll2_d2",
+	"syspll4_d2",
+	"univpll1_d2",
+	"syspll1_d2",
+	"univpll_d5",
+	"univpll1_d4"
+};
+
+static const char * const msdc30_1_parents[] __initconst = {
+	"clk26m",
+	"msdcpll_d2",
+	"univpll2_d2",
+	"syspll2_d2",
+	"syspll1_d4",
+	"univpll1_d4",
+	"usb20_192m_d4",
+	"syspll2_d4"
+};
+
+static const char * const audio_parents[] __initconst = {
+	"clk26m",
+	"syspll3_d4",
+	"syspll4_d4",
+	"syspll1_d16"
+};
+
+static const char * const aud_intbus_parents[] __initconst = {
+	"clk26m",
+	"syspll1_d4",
+	"syspll4_d2"
+};
+
+static const char * const aud_1_parents[] __initconst = {
+	"clk26m",
+	"apll1_ck"
+};
+
+static const char * const aud_engen1_parents[] __initconst = {
+	"clk26m",
+	"apll1_d2",
+	"apll1_d4",
+	"apll1_d8"
+};
+
+static const char * const disp_pwm_parents[] __initconst = {
+	"clk26m",
+	"univpll2_d4",
+	"ulposc1_d2",
+	"ulposc1_d8"
+};
+
+static const char * const sspm_parents[] __initconst = {
+	"clk26m",
+	"syspll1_d2",
+	"syspll_d3"
+};
+
+static const char * const dxcc_parents[] __initconst = {
+	"clk26m",
+	"syspll1_d2",
+	"syspll1_d4",
+	"syspll1_d8"
+};
+
+static const char * const usb_top_parents[] __initconst = {
+	"clk26m",
+	"univpll3_d4"
+};
+
+static const char * const spm_parents[] __initconst = {
+	"clk26m",
+	"syspll1_d8"
+};
+
+static const char * const i2c_parents[] __initconst = {
+	"clk26m",
+	"univpll3_d4",
+	"univpll3_d2",
+	"syspll1_d8",
+	"syspll2_d8"
+};
+
+static const char * const pwm_parents[] __initconst = {
+	"clk26m",
+	"univpll3_d4",
+	"syspll1_d8"
+};
+
+static const char * const seninf_parents[] __initconst = {
+	"clk26m",
+	"univpll1_d4",
+	"univpll1_d2",
+	"univpll2_d2"
+};
+
+static const char * const aes_fde_parents[] __initconst = {
+	"clk26m",
+	"msdcpll_ck",
+	"univpll_d3",
+	"univpll2_d2",
+	"univpll1_d2",
+	"syspll1_d2"
+};
+
+static const char * const ulposc_parents[] __initconst = {
+	"clk26m",
+	"ulposc1_d4",
+	"ulposc1_d8",
+	"ulposc1_d16",
+	"ulposc1_d32"
+};
+
+static const char * const camtm_parents[] __initconst = {
+	"clk26m",
+	"univpll1_d4",
+	"univpll1_d2",
+	"univpll2_d2"
+};
+
+#define INVALID_UPDATE_REG 0xFFFFFFFF
+#define INVALID_UPDATE_SHIFT -1
+#define INVALID_MUX_GATE -1
+
+static const struct mtk_mux top_muxes[] __initconst = {
+	/* CLK_CFG_0 */
+	MUX_CLR_SET_UPD_FLAGS(CLK_TOP_AXI_SEL, "axi_sel", axi_parents,
+			      CLK_CFG_0, CLK_CFG_0_SET, CLK_CFG_0_CLR,
+			      0, 2, 7, CLK_CFG_UPDATE, 0, CLK_IS_CRITICAL),
+	MUX_CLR_SET_UPD_FLAGS(CLK_TOP_MEM_SEL, "mem_sel", mem_parents,
+			      CLK_CFG_0, CLK_CFG_0_SET, CLK_CFG_0_CLR,
+			      8, 2, 15, CLK_CFG_UPDATE, 1, CLK_IS_CRITICAL),
+	MUX_CLR_SET_UPD(CLK_TOP_MM_SEL, "mm_sel", mm_parents, CLK_CFG_0,
+			CLK_CFG_0_SET, CLK_CFG_0_CLR, 16, 3, 23,
+			CLK_CFG_UPDATE, 2),
+	MUX_CLR_SET_UPD(CLK_TOP_SCP_SEL, "scp_sel", scp_parents, CLK_CFG_0,
+			CLK_CFG_0_SET, CLK_CFG_0_CLR, 24, 3, 31,
+			CLK_CFG_UPDATE, 3),
+	/* CLK_CFG_1 */
+	MUX_CLR_SET_UPD(CLK_TOP_MFG_SEL, "mfg_sel", mfg_parents, CLK_CFG_1,
+			CLK_CFG_1_SET, CLK_CFG_1_CLR, 0, 2, 7,
+			CLK_CFG_UPDATE, 4),
+	MUX_CLR_SET_UPD(CLK_TOP_ATB_SEL, "atb_sel", atb_parents, CLK_CFG_1,
+			CLK_CFG_1_SET, CLK_CFG_1_CLR, 8, 2, 15,
+			CLK_CFG_UPDATE, 5),
+	MUX_CLR_SET_UPD(CLK_TOP_CAMTG_SEL, "camtg_sel",
+			camtg_parents, CLK_CFG_1, CLK_CFG_1_SET,
+			CLK_CFG_1_CLR, 16, 3, 23, CLK_CFG_UPDATE, 6),
+	MUX_CLR_SET_UPD(CLK_TOP_CAMTG1_SEL, "camtg1_sel", camtg_parents,
+			CLK_CFG_1, CLK_CFG_1_SET, CLK_CFG_1_CLR,
+			24, 3, 31, CLK_CFG_UPDATE, 7),
+	/* CLK_CFG_2 */
+	MUX_CLR_SET_UPD(CLK_TOP_CAMTG2_SEL, "camtg2_sel",
+			camtg_parents, CLK_CFG_2, CLK_CFG_2_SET,
+			CLK_CFG_2_CLR, 0, 3, 7, CLK_CFG_UPDATE, 8),
+	MUX_CLR_SET_UPD(CLK_TOP_CAMTG3_SEL, "camtg3_sel", camtg_parents,
+			CLK_CFG_2, CLK_CFG_2_SET, CLK_CFG_2_CLR,
+			8, 3, 15, CLK_CFG_UPDATE, 9),
+	MUX_CLR_SET_UPD(CLK_TOP_UART_SEL, "uart_sel", uart_parents,
+			CLK_CFG_2, CLK_CFG_2_SET, CLK_CFG_2_CLR, 16, 1, 23,
+			CLK_CFG_UPDATE, 10),
+	MUX_CLR_SET_UPD(CLK_TOP_SPI_SEL, "spi_sel", spi_parents, CLK_CFG_2,
+			CLK_CFG_2_SET, CLK_CFG_2_CLR, 24, 2, 31,
+			CLK_CFG_UPDATE, 11),
+	/* CLK_CFG_3 */
+	MUX_CLR_SET_UPD(CLK_TOP_MSDC50_0_HCLK_SEL, "msdc5hclk",
+			msdc5hclk_parents, CLK_CFG_3, CLK_CFG_3_SET,
+			CLK_CFG_3_CLR, 0, 2, 7, CLK_CFG_UPDATE, 12),
+	MUX_CLR_SET_UPD(CLK_TOP_MSDC50_0_SEL, "msdc50_0_sel",
+			msdc50_0_parents, CLK_CFG_3, CLK_CFG_3_SET,
+			CLK_CFG_3_CLR, 8, 3, 15, CLK_CFG_UPDATE, 13),
+	MUX_CLR_SET_UPD(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel",
+			msdc30_1_parents, CLK_CFG_3, CLK_CFG_3_SET,
+			CLK_CFG_3_CLR, 16, 3, 23, CLK_CFG_UPDATE, 14),
+	MUX_CLR_SET_UPD(CLK_TOP_AUDIO_SEL, "audio_sel", audio_parents,
+			CLK_CFG_3, CLK_CFG_3_SET, CLK_CFG_3_CLR,
+			24, 2, 31, CLK_CFG_UPDATE, 15),
+	/* CLK_CFG_4 */
+	MUX_CLR_SET_UPD(CLK_TOP_AUD_INTBUS_SEL, "aud_intbus_sel",
+			aud_intbus_parents, CLK_CFG_4, CLK_CFG_4_SET,
+			CLK_CFG_4_CLR, 0, 2, 7, CLK_CFG_UPDATE, 16),
+	MUX_CLR_SET_UPD(CLK_TOP_AUD_1_SEL, "aud_1_sel", aud_1_parents,
+			CLK_CFG_4, CLK_CFG_4_SET, CLK_CFG_4_CLR,
+			8, 1, 15, CLK_CFG_UPDATE, 17),
+	MUX_CLR_SET_UPD(CLK_TOP_AUD_ENGEN1_SEL, "aud_engen1_sel",
+			aud_engen1_parents, CLK_CFG_4, CLK_CFG_4_SET,
+			CLK_CFG_4_CLR, 16, 2, 23, CLK_CFG_UPDATE, 18),
+	MUX_CLR_SET_UPD(CLK_TOP_DISP_PWM_SEL, "disp_pwm_sel",
+			disp_pwm_parents, CLK_CFG_4, CLK_CFG_4_SET,
+			CLK_CFG_4_CLR, 24, 2, 31, CLK_CFG_UPDATE, 19),
+	/* CLK_CFG_5 */
+	MUX_CLR_SET_UPD(CLK_TOP_SSPM_SEL, "sspm_sel", sspm_parents,
+			CLK_CFG_5, CLK_CFG_5_SET, CLK_CFG_5_CLR, 0, 2, 7,
+			CLK_CFG_UPDATE, 20),
+	MUX_CLR_SET_UPD(CLK_TOP_DXCC_SEL, "dxcc_sel", dxcc_parents,
+			CLK_CFG_5, CLK_CFG_5_SET, CLK_CFG_5_CLR, 8, 2, 15,
+			CLK_CFG_UPDATE, 21),
+	MUX_CLR_SET_UPD(CLK_TOP_USB_TOP_SEL, "usb_top_sel", usb_top_parents,
+			CLK_CFG_5, CLK_CFG_5_SET, CLK_CFG_5_CLR, 16, 1, 23,
+			CLK_CFG_UPDATE, 22),
+	MUX_CLR_SET_UPD(CLK_TOP_SPM_SEL, "spm_sel", spm_parents, CLK_CFG_5,
+			CLK_CFG_5_SET, CLK_CFG_5_CLR, 24, 1, 31,
+			CLK_CFG_UPDATE, 23),
+	/* CLK_CFG_6 */
+	MUX_CLR_SET_UPD(CLK_TOP_I2C_SEL, "i2c_sel", i2c_parents, CLK_CFG_6,
+			CLK_CFG_6_SET, CLK_CFG_6_CLR, 0, 3, 7, CLK_CFG_UPDATE,
+			24),
+	MUX_CLR_SET_UPD(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents, CLK_CFG_6,
+			CLK_CFG_6_SET, CLK_CFG_6_CLR, 8, 2, 15, CLK_CFG_UPDATE,
+			25),
+	MUX_CLR_SET_UPD(CLK_TOP_SENINF_SEL, "seninf_sel", seninf_parents,
+			CLK_CFG_6, CLK_CFG_6_SET, CLK_CFG_6_CLR, 16, 2, 23,
+			CLK_CFG_UPDATE, 26),
+	MUX_CLR_SET_UPD(CLK_TOP_AES_FDE_SEL, "aes_fde_sel", aes_fde_parents,
+			CLK_CFG_6, CLK_CFG_6_SET, CLK_CFG_6_CLR, 24, 3, 31,
+			CLK_CFG_UPDATE, 27),
+	/* CLK_CFG_7 */
+	MUX_CLR_SET_UPD_FLAGS(CLK_TOP_PWRAP_ULPOSC_SEL, "ulposc_sel",
+			      ulposc_parents, CLK_CFG_7, CLK_CFG_7_SET,
+			      CLK_CFG_7_CLR, 0, 3, 7, CLK_CFG_UPDATE, 28,
+			      CLK_IS_CRITICAL),
+	MUX_CLR_SET_UPD(CLK_TOP_CAMTM_SEL, "camtm_sel", camtm_parents,
+			CLK_CFG_7, CLK_CFG_7_SET, CLK_CFG_7_CLR, 8, 2, 15,
+			CLK_CFG_UPDATE, 29),
+};
+
+static const struct mtk_gate_regs top0_cg_regs = {
+	.set_ofs = 0x0,
+	.clr_ofs = 0x0,
+	.sta_ofs = 0x0,
+};
+
+static const struct mtk_gate_regs top1_cg_regs = {
+	.set_ofs = 0x104,
+	.clr_ofs = 0x104,
+	.sta_ofs = 0x104,
+};
+
+static const struct mtk_gate_regs top2_cg_regs = {
+	.set_ofs = 0x320,
+	.clr_ofs = 0x320,
+	.sta_ofs = 0x320,
+};
+
+#define GATE_TOP0(_id, _name, _parent, _shift) {	\
+		.id = _id,				\
+		.name = _name,				\
+		.parent_name = _parent,			\
+		.regs = &top0_cg_regs,			\
+		.shift = _shift,			\
+		.ops = &mtk_clk_gate_ops_no_setclr,	\
+	}
+
+#define GATE_TOP1(_id, _name, _parent, _shift) {	\
+		.id = _id,				\
+		.name = _name,				\
+		.parent_name = _parent,			\
+		.regs = &top1_cg_regs,			\
+		.shift = _shift,			\
+		.ops = &mtk_clk_gate_ops_no_setclr_inv,	\
+	}
+
+#define GATE_TOP2(_id, _name, _parent, _shift) {	\
+		.id = _id,				\
+		.name = _name,				\
+		.parent_name = _parent,			\
+		.regs = &top2_cg_regs,			\
+		.shift = _shift,			\
+		.ops = &mtk_clk_gate_ops_no_setclr,	\
+	}
+
+static const struct mtk_gate top_clks[] __initconst = {
+	/* TOP0 */
+	GATE_TOP0(CLK_TOP_MD_32K, "md_32k", "f_frtc_ck", 8),
+	GATE_TOP0(CLK_TOP_MD_26M, "md_26m", "f_f26m_ck", 9),
+	GATE_TOP0(CLK_TOP_MD2_32K, "md2_32k", "f_frtc_ck", 10),
+	GATE_TOP0(CLK_TOP_MD2_26M, "md2_26m", "f_f26m_ck", 11),
+	/* TOP1 */
+	GATE_TOP1(CLK_TOP_ARMPLL_DIVIDER_PLL0_EN,
+		  "arm_div_pll0_en", "arm_div_pll0", 3),
+	GATE_TOP1(CLK_TOP_ARMPLL_DIVIDER_PLL1_EN,
+		  "arm_div_pll1_en", "arm_div_pll1", 4),
+	GATE_TOP1(CLK_TOP_ARMPLL_DIVIDER_PLL2_EN,
+		  "arm_div_pll2_en", "arm_div_pll2", 5),
+	GATE_TOP1(CLK_TOP_FMEM_OCC_DRC_EN, "drc_en", "univpll2_d2", 6),
+	GATE_TOP1(CLK_TOP_USB20_48M_EN, "usb20_48m_en", "usb20_48m_div", 8),
+	GATE_TOP1(CLK_TOP_UNIVPLL_48M_EN, "univpll_48m_en", "univ_48m_div", 9),
+	GATE_TOP1(CLK_TOP_F_UFS_MP_SAP_CFG_EN, "ufs_sap", "f_f26m_ck", 12),
+	GATE_TOP1(CLK_TOP_F_BIST2FPC_EN, "bist2fpc", "f_bist2fpc_ck", 16),
+	/* TOP2 */
+	GATE_TOP2(CLK_TOP_APLL12_DIV0, "apll12_div0", "aud_1_ck", 2),
+	GATE_TOP2(CLK_TOP_APLL12_DIV1, "apll12_div1", "aud_1_ck", 3),
+	GATE_TOP2(CLK_TOP_APLL12_DIV2, "apll12_div2", "aud_1_ck", 4),
+	GATE_TOP2(CLK_TOP_APLL12_DIV3, "apll12_div3", "aud_1_ck", 5),
+};
+
+static const struct mtk_gate_regs ifr0_cg_regs = {
+	.set_ofs = 0x200,
+	.clr_ofs = 0x200,
+	.sta_ofs = 0x200,
+};
+
+static const struct mtk_gate_regs ifr1_cg_regs = {
+	.set_ofs = 0x74,
+	.clr_ofs = 0x74,
+	.sta_ofs = 0x74,
+};
+
+static const struct mtk_gate_regs ifr2_cg_regs = {
+	.set_ofs = 0x80,
+	.clr_ofs = 0x84,
+	.sta_ofs = 0x90,
+};
+
+static const struct mtk_gate_regs ifr3_cg_regs = {
+	.set_ofs = 0x88,
+	.clr_ofs = 0x8c,
+	.sta_ofs = 0x94,
+};
+
+static const struct mtk_gate_regs ifr4_cg_regs = {
+	.set_ofs = 0xa4,
+	.clr_ofs = 0xa8,
+	.sta_ofs = 0xac,
+};
+
+static const struct mtk_gate_regs ifr5_cg_regs = {
+	.set_ofs = 0xc0,
+	.clr_ofs = 0xc4,
+	.sta_ofs = 0xc8,
+};
+
+#define GATE_IFR0(_id, _name, _parent, _shift) {	\
+		.id = _id,				\
+		.name = _name,				\
+		.parent_name = _parent,			\
+		.regs = &ifr0_cg_regs,			\
+		.shift = _shift,			\
+		.ops = &mtk_clk_gate_ops_no_setclr_inv,	\
+	}
+
+#define GATE_IFR1(_id, _name, _parent, _shift) {	\
+		.id = _id,				\
+		.name = _name,				\
+		.parent_name = _parent,			\
+		.regs = &ifr1_cg_regs,			\
+		.shift = _shift,			\
+		.ops = &mtk_clk_gate_ops_no_setclr,	\
+	}
+
+#define GATE_IFR2(_id, _name, _parent, _shift) {	\
+		.id = _id,				\
+		.name = _name,				\
+		.parent_name = _parent,			\
+		.regs = &ifr2_cg_regs,			\
+		.shift = _shift,			\
+		.ops = &mtk_clk_gate_ops_setclr,	\
+	}
+
+#define GATE_IFR3(_id, _name, _parent, _shift) {	\
+		.id = _id,				\
+		.name = _name,				\
+		.parent_name = _parent,			\
+		.regs = &ifr3_cg_regs,			\
+		.shift = _shift,			\
+		.ops = &mtk_clk_gate_ops_setclr,	\
+	}
+
+#define GATE_IFR4(_id, _name, _parent, _shift) {	\
+		.id = _id,				\
+		.name = _name,				\
+		.parent_name = _parent,			\
+		.regs = &ifr4_cg_regs,			\
+		.shift = _shift,			\
+		.ops = &mtk_clk_gate_ops_setclr,	\
+	}
+
+#define GATE_IFR5(_id, _name, _parent, _shift) {	\
+		.id = _id,				\
+		.name = _name,				\
+		.parent_name = _parent,			\
+		.regs = &ifr5_cg_regs,			\
+		.shift = _shift,			\
+		.ops = &mtk_clk_gate_ops_setclr,	\
+	}
+
+static const struct mtk_gate ifr_clks[] __initconst = {
+	/* INFRA_TOPAXI */
+	/* INFRA PERI */
+	/* INFRA mode 0 */
+	GATE_IFR2(CLK_IFR_ICUSB, "ifr_icusb", "axi_ck", 8),
+	GATE_IFR2(CLK_IFR_GCE, "ifr_gce", "axi_ck", 9),
+	GATE_IFR2(CLK_IFR_THERM, "ifr_therm", "axi_ck", 10),
+	GATE_IFR2(CLK_IFR_I2C_AP, "ifr_i2c_ap", "i2c_ck", 11),
+	GATE_IFR2(CLK_IFR_I2C_CCU, "ifr_i2c_ccu", "i2c_ck", 12),
+	GATE_IFR2(CLK_IFR_I2C_SSPM, "ifr_i2c_sspm", "i2c_ck", 13),
+	GATE_IFR2(CLK_IFR_I2C_RSV, "ifr_i2c_rsv", "i2c_ck", 14),
+	GATE_IFR2(CLK_IFR_PWM_HCLK, "ifr_pwm_hclk", "axi_ck", 15),
+	GATE_IFR2(CLK_IFR_PWM1, "ifr_pwm1", "f_fpwm_ck", 16),
+	GATE_IFR2(CLK_IFR_PWM2, "ifr_pwm2", "f_fpwm_ck", 17),
+	GATE_IFR2(CLK_IFR_PWM3, "ifr_pwm3", "f_fpwm_ck", 18),
+	GATE_IFR2(CLK_IFR_PWM4, "ifr_pwm4", "f_fpwm_ck", 19),
+	GATE_IFR2(CLK_IFR_PWM5, "ifr_pwm5", "f_fpwm_ck", 20),
+	GATE_IFR2(CLK_IFR_PWM, "ifr_pwm", "f_fpwm_ck", 21),
+	GATE_IFR2(CLK_IFR_UART0, "ifr_uart0", "f_fuart_ck", 22),
+	GATE_IFR2(CLK_IFR_UART1, "ifr_uart1", "f_fuart_ck", 23),
+	GATE_IFR2(CLK_IFR_GCE_26M, "ifr_gce_26m", "f_f26m_ck", 27),
+	GATE_IFR2(CLK_IFR_CQ_DMA_FPC, "ifr_dma", "axi_ck", 28),
+	GATE_IFR2(CLK_IFR_BTIF, "ifr_btif", "axi_ck", 31),
+	/* INFRA mode 1 */
+	GATE_IFR3(CLK_IFR_SPI0, "ifr_spi0", "spi_ck", 1),
+	GATE_IFR3(CLK_IFR_MSDC0, "ifr_msdc0", "msdc5hclk", 2),
+	GATE_IFR3(CLK_IFR_MSDC1, "ifr_msdc1", "axi_ck", 4),
+	GATE_IFR3(CLK_IFR_TRNG, "ifr_trng", "axi_ck", 9),
+	GATE_IFR3(CLK_IFR_AUXADC, "ifr_auxadc", "f_f26m_ck", 10),
+	GATE_IFR3(CLK_IFR_CCIF1_AP, "ifr_ccif1_ap", "axi_ck", 12),
+	GATE_IFR3(CLK_IFR_CCIF1_MD, "ifr_ccif1_md", "axi_ck", 13),
+	GATE_IFR3(CLK_IFR_AUXADC_MD, "ifr_auxadc_md", "f_f26m_ck", 14),
+	GATE_IFR3(CLK_IFR_AP_DMA, "ifr_ap_dma", "axi_ck", 18),
+	GATE_IFR3(CLK_IFR_DEVICE_APC, "ifr_dapc", "axi_ck", 20),
+	GATE_IFR3(CLK_IFR_CCIF_AP, "ifr_ccif_ap", "axi_ck", 23),
+	GATE_IFR3(CLK_IFR_AUDIO, "ifr_audio", "axi_ck", 25),
+	GATE_IFR3(CLK_IFR_CCIF_MD, "ifr_ccif_md", "axi_ck", 26),
+	/* INFRA mode 2 */
+	GATE_IFR4(CLK_IFR_RG_PWM_FBCLK6, "ifr_pwmfb", "f_f26m_ck", 0),
+	GATE_IFR4(CLK_IFR_DISP_PWM, "ifr_disp_pwm", "f_fdisp_pwm_ck", 2),
+	GATE_IFR4(CLK_IFR_CLDMA_BCLK, "ifr_cldmabclk", "axi_ck", 3),
+	GATE_IFR4(CLK_IFR_AUDIO_26M_BCLK, "ifr_audio26m", "f_f26m_ck", 4),
+	GATE_IFR4(CLK_IFR_SPI1, "ifr_spi1", "spi_ck", 6),
+	GATE_IFR4(CLK_IFR_I2C4, "ifr_i2c4", "i2c_ck", 7),
+	GATE_IFR4(CLK_IFR_SPI2, "ifr_spi2", "spi_ck", 9),
+	GATE_IFR4(CLK_IFR_SPI3, "ifr_spi3", "spi_ck", 10),
+	GATE_IFR4(CLK_IFR_I2C5, "ifr_i2c5", "i2c_ck", 18),
+	GATE_IFR4(CLK_IFR_I2C5_ARBITER, "ifr_i2c5a", "i2c_ck", 19),
+	GATE_IFR4(CLK_IFR_I2C5_IMM, "ifr_i2c5_imm", "i2c_ck", 20),
+	GATE_IFR4(CLK_IFR_I2C1_ARBITER, "ifr_i2c1a", "i2c_ck", 21),
+	GATE_IFR4(CLK_IFR_I2C1_IMM, "ifr_i2c1_imm", "i2c_ck", 22),
+	GATE_IFR4(CLK_IFR_I2C2_ARBITER, "ifr_i2c2a", "i2c_ck", 23),
+	GATE_IFR4(CLK_IFR_I2C2_IMM, "ifr_i2c2_imm", "i2c_ck", 24),
+	GATE_IFR4(CLK_IFR_SPI4, "ifr_spi4", "spi_ck", 25),
+	GATE_IFR4(CLK_IFR_SPI5, "ifr_spi5", "spi_ck", 26),
+	GATE_IFR4(CLK_IFR_CQ_DMA, "ifr_cq_dma", "axi_ck", 27),
+	GATE_IFR4(CLK_IFR_FAES_FDE, "ifr_faes_fde_ck", "aes_fde_ck", 29),
+	/* INFRA mode 3 */
+	GATE_IFR5(CLK_IFR_MSDC0_SELF, "ifr_msdc0sf", "msdc50_0_ck", 0),
+	GATE_IFR5(CLK_IFR_MSDC1_SELF, "ifr_msdc1sf", "msdc50_0_ck", 1),
+	GATE_IFR5(CLK_IFR_I2C6, "ifr_i2c6", "i2c_ck", 6),
+	GATE_IFR5(CLK_IFR_AP_MSDC0, "ifr_ap_msdc0", "msdc50_0_ck", 7),
+	GATE_IFR5(CLK_IFR_MD_MSDC0, "ifr_md_msdc0", "msdc50_0_ck", 8),
+	GATE_IFR5(CLK_IFR_MSDC0_SRC, "ifr_msdc0_clk", "msdc50_0_ck", 9),
+	GATE_IFR5(CLK_IFR_MSDC1_SRC, "ifr_msdc1_clk", "msdc30_1_ck", 10),
+	GATE_IFR5(CLK_IFR_MCU_PM_BCLK, "ifr_mcu_pm_bclk", "axi_ck", 17),
+	GATE_IFR5(CLK_IFR_CCIF2_AP, "ifr_ccif2_ap", "axi_ck", 18),
+	GATE_IFR5(CLK_IFR_CCIF2_MD, "ifr_ccif2_md", "axi_ck", 19),
+	GATE_IFR5(CLK_IFR_CCIF3_AP, "ifr_ccif3_ap", "axi_ck", 20),
+	GATE_IFR5(CLK_IFR_CCIF3_MD, "ifr_ccif3_md", "axi_ck", 21),
+};
+
+/* additional CCF control for mipi26M race condition(disp/camera) */
+static const struct mtk_gate_regs apmixed_cg_regs = {
+	.set_ofs = 0x14,
+	.clr_ofs = 0x14,
+	.sta_ofs = 0x14,
+};
+
+#define GATE_APMIXED(_id, _name, _parent, _shift) {	\
+		.id = _id,				\
+		.name = _name,				\
+		.parent_name = _parent,			\
+		.regs = &apmixed_cg_regs,		\
+		.shift = _shift,			\
+		.ops = &mtk_clk_gate_ops_no_setclr_inv,		\
+	}
+
+static const struct mtk_gate apmixed_clks[] __initconst = {
+	/* AUDIO0 */
+	GATE_APMIXED(CLK_APMIXED_SSUSB26M, "apmixed_ssusb26m", "f_f26m_ck",
+		     4),
+	GATE_APMIXED(CLK_APMIXED_APPLL26M, "apmixed_appll26m", "f_f26m_ck",
+		     5),
+	GATE_APMIXED(CLK_APMIXED_MIPIC0_26M, "apmixed_mipic026m", "f_f26m_ck",
+		     6),
+	GATE_APMIXED(CLK_APMIXED_MDPLLGP26M, "apmixed_mdpll26m", "f_f26m_ck",
+		     7),
+	GATE_APMIXED(CLK_APMIXED_MMSYS_F26M, "apmixed_mmsys26m", "f_f26m_ck",
+		     8),
+	GATE_APMIXED(CLK_APMIXED_UFS26M, "apmixed_ufs26m", "f_f26m_ck",
+		     9),
+	GATE_APMIXED(CLK_APMIXED_MIPIC1_26M, "apmixed_mipic126m", "f_f26m_ck",
+		     11),
+	GATE_APMIXED(CLK_APMIXED_MEMPLL26M, "apmixed_mempll26m", "f_f26m_ck",
+		     13),
+	GATE_APMIXED(CLK_APMIXED_CLKSQ_LVPLL_26M, "apmixed_lvpll26m",
+		     "f_f26m_ck", 14),
+	GATE_APMIXED(CLK_APMIXED_MIPID0_26M, "apmixed_mipid026m", "f_f26m_ck",
+		     16),
+};
+
+#define MT6765_PLL_FMAX		(3800UL * MHZ)
+#define MT6765_PLL_FMIN		(1500UL * MHZ)
+
+#define CON0_MT6765_RST_BAR	BIT(23)
+
+#define PLL_INFO_NULL		(0xFF)
+
+#define PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,	\
+		_pcwibits, _pd_reg, _pd_shift, _tuner_reg, _tuner_en_reg,\
+		_tuner_en_bit, _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_MT6765_RST_BAR,			\
+		.fmax = MT6765_PLL_FMAX,				\
+		.fmin = MT6765_PLL_FMIN,				\
+		.pcwbits = _pcwbits,					\
+		.pcwibits = _pcwibits,					\
+		.pd_reg = _pd_reg,					\
+		.pd_shift = _pd_shift,					\
+		.tuner_reg = _tuner_reg,				\
+		.tuner_en_reg = _tuner_en_reg,				\
+		.tuner_en_bit = _tuner_en_bit,				\
+		.pcw_reg = _pcw_reg,					\
+		.pcw_shift = _pcw_shift,				\
+		.div_table = _div_table,				\
+	}
+
+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,	\
+			_pcwibits, _pd_reg, _pd_shift, _tuner_reg,	\
+			_tuner_en_reg, _tuner_en_bit, _pcw_reg,	\
+			_pcw_shift)	\
+		PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags,	\
+			_pcwbits, _pcwibits, _pd_reg, _pd_shift,	\
+			_tuner_reg, _tuner_en_reg, _tuner_en_bit,	\
+			_pcw_reg, _pcw_shift, NULL)	\
+
+static const struct mtk_pll_data plls[] = {
+	PLL(CLK_APMIXED_ARMPLL_L, "armpll_l", 0x021C, 0x0228, BIT(0),
+	    PLL_AO, 22, 8, 0x0220, 24, 0, 0, 0, 0x0220, 0),
+	PLL(CLK_APMIXED_ARMPLL, "armpll", 0x020C, 0x0218, BIT(0),
+	    PLL_AO, 22, 8, 0x0210, 24, 0, 0, 0, 0x0210, 0),
+	PLL(CLK_APMIXED_CCIPLL, "ccipll", 0x022C, 0x0238, BIT(0),
+	    PLL_AO, 22, 8, 0x0230, 24, 0, 0, 0, 0x0230, 0),
+	PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x023C, 0x0248, BIT(0),
+	    (HAVE_RST_BAR | PLL_AO), 22, 8, 0x0240, 24, 0, 0, 0, 0x0240,
+	    0),
+	PLL(CLK_APMIXED_MFGPLL, "mfgpll", 0x024C, 0x0258, BIT(0),
+	    0, 22, 8, 0x0250, 24, 0, 0, 0, 0x0250, 0),
+	PLL(CLK_APMIXED_MMPLL, "mmpll", 0x025C, 0x0268, BIT(0),
+	    0, 22, 8, 0x0260, 24, 0, 0, 0, 0x0260, 0),
+	PLL(CLK_APMIXED_UNIV2PLL, "univ2pll", 0x026C, 0x0278, BIT(0),
+	    HAVE_RST_BAR, 22, 8, 0x0270, 24, 0, 0, 0, 0x0270, 0),
+	PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x027C, 0x0288, BIT(0),
+	    0, 22, 8, 0x0280, 24, 0, 0, 0, 0x0280, 0),
+	PLL(CLK_APMIXED_APLL1, "apll1", 0x028C, 0x029C, BIT(0),
+	    0, 32, 8, 0x0290, 24, 0x0040, 0x000C, 0, 0x0294, 0),
+	PLL(CLK_APMIXED_MPLL, "mpll", 0x02A0, 0x02AC, BIT(0),
+	    PLL_AO, 22, 8, 0x02A4, 24, 0, 0, 0, 0x02A4, 0),
+};
+
+static int clk_mt6765_apmixed_probe(struct platform_device *pdev)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+	struct device_node *node = pdev->dev.of_node;
+	void __iomem *base;
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base)) {
+		pr_err("%s(): ioremap failed\n", __func__);
+		return PTR_ERR(base);
+	}
+
+	clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
+
+	mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
+
+	mtk_clk_register_gates(node, apmixed_clks,
+			       ARRAY_SIZE(apmixed_clks), clk_data);
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+		       __func__, r);
+
+	apmixed_base = base;
+	/* MPLL, CCIPLL, MAINPLL set HW mode, TDCLKSQ, CLKSQ1 */
+	clk_writel(clk_readl(AP_PLL_CON3) & 0xFFFFFFE1, AP_PLL_CON3);
+	clk_writel(clk_readl(PLLON_CON0) & 0x01041041, PLLON_CON0);
+	clk_writel(clk_readl(PLLON_CON1) & 0x01041041, PLLON_CON1);
+
+	return r;
+}
+
+static struct clk_onecell_data *mt6765_top_clk_data;
+
+static int clk_mt6765_top_probe(struct platform_device *pdev)
+{
+	int r;
+	struct device_node *node = pdev->dev.of_node;
+	void __iomem *base;
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base)) {
+		pr_err("%s(): ioremap failed\n", __func__);
+		return PTR_ERR(base);
+	}
+
+	mt6765_top_clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
+
+	mtk_clk_register_fixed_clks(fixed_clks, ARRAY_SIZE(fixed_clks),
+				    mt6765_top_clk_data);
+	mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs),
+				 mt6765_top_clk_data);
+	mtk_clk_register_muxes(top_muxes, ARRAY_SIZE(top_muxes), node,
+			       &mt6765_clk_lock, mt6765_top_clk_data);
+	mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
+			       mt6765_top_clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get,
+				mt6765_top_clk_data);
+
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+		       __func__, r);
+
+	cksys_base = base;
+	/* [4]:no need */
+	clk_writel(clk_readl(CLK_SCP_CFG_0) | 0x3EF, CLK_SCP_CFG_0);
+	/*[1,2,3,8]: no need*/
+	clk_writel(clk_readl(CLK_SCP_CFG_1) | 0x1, CLK_SCP_CFG_1);
+
+	return r;
+}
+
+static int clk_mt6765_ifr_probe(struct platform_device *pdev)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+	struct device_node *node = pdev->dev.of_node;
+	void __iomem *base;
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base)) {
+		pr_err("%s(): ioremap failed\n", __func__);
+		return PTR_ERR(base);
+	}
+
+	clk_data = mtk_alloc_clk_data(CLK_IFR_NR_CLK);
+
+	mtk_clk_register_gates(node, ifr_clks, ARRAY_SIZE(ifr_clks),
+			       clk_data);
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+		       __func__, r);
+
+	return r;
+}
+
+static const struct of_device_id of_match_clk_mt6765[] = {
+	{
+		.compatible = "mediatek,mt6765-apmixedsys",
+		.data = clk_mt6765_apmixed_probe,
+	}, {
+		.compatible = "mediatek,mt6765-topckgen",
+		.data = clk_mt6765_top_probe,
+	}, {
+		.compatible = "mediatek,mt6765-infracfg",
+		.data = clk_mt6765_ifr_probe,
+	}, {
+		/* sentinel */
+	}
+};
+
+static int clk_mt6765_probe(struct platform_device *pdev)
+{
+	int (*clk_probe)(struct platform_device *d);
+	int r;
+
+	clk_probe = of_device_get_match_data(&pdev->dev);
+	if (!clk_probe)
+		return -EINVAL;
+
+	r = clk_probe(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_mt6765_drv = {
+	.probe = clk_mt6765_probe,
+	.driver = {
+		.name = "clk-mt6765",
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_clk_mt6765,
+	},
+};
+
+static int __init clk_mt6765_init(void)
+{
+	return platform_driver_register(&clk_mt6765_drv);
+}
+
+arch_initcall(clk_mt6765_init);
-- 
1.7.9.5


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

* [PATCH v5 11/11] arm64: dts: mediatek: add mt6765 support
  2018-07-17  8:52 [PATCH v5 0/11] Add basic SoC support for mt6765 Mars Cheng
                   ` (9 preceding siblings ...)
  2018-07-17  8:52 ` [PATCH v5 10/11] clk: mediatek: Add MT6765 clock support Mars Cheng
@ 2018-07-17  8:52 ` Mars Cheng
  10 siblings, 0 replies; 32+ messages in thread
From: Mars Cheng @ 2018-07-17  8:52 UTC (permalink / raw)
  To: Matthias Brugger, Rob Herring, Marc Zyngier, Ryder Lee,
	Stephen Boyd, Sean Wang
  Cc: CC Hwang, Loda Chou, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, linux-serial, linux-arm-kernel, linux-clk,
	Mars Cheng, Owen Chen

This adds basic chip support for MT6765 SoC.

Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
Signed-off-by: Owen Chen <owen.chen@mediatek.com>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/boot/dts/mediatek/Makefile       |    1 +
 arch/arm64/boot/dts/mediatek/mt6765-evb.dts |   33 ++++
 arch/arm64/boot/dts/mediatek/mt6765.dtsi    |  253 +++++++++++++++++++++++++++
 3 files changed, 287 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt6765-evb.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt6765.dtsi

diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index ac17f60..7506b0d 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt2712-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt6755-evb.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt6765-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt6795-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb1.dtb
diff --git a/arch/arm64/boot/dts/mediatek/mt6765-evb.dts b/arch/arm64/boot/dts/mediatek/mt6765-evb.dts
new file mode 100644
index 0000000..36dddff2
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt6765-evb.dts
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * dts file for Mediatek MT6765
+ *
+ * (C) Copyright 2018. Mediatek, Inc.
+ *
+ * Mars Cheng <mars.cheng@mediatek.com>
+ */
+
+/dts-v1/;
+#include "mt6765.dtsi"
+
+/ {
+	model = "MediaTek MT6765 EVB";
+	compatible = "mediatek,mt6765-evb", "mediatek,mt6765";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	memory@40000000 {
+		device_type = "memory";
+		reg = <0 0x40000000 0 0x1e800000>;
+	};
+
+	chosen {
+		stdout-path = "serial0:921600n8";
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt6765.dtsi b/arch/arm64/boot/dts/mediatek/mt6765.dtsi
new file mode 100644
index 0000000..37f9f3a
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt6765.dtsi
@@ -0,0 +1,253 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * dts file for Mediatek MT6765
+ *
+ * (C) Copyright 2018. Mediatek, Inc.
+ *
+ * Mars Cheng <mars.cheng@mediatek.com>
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/mt6765-clk.h>
+
+/ {
+	compatible = "mediatek,mt6765";
+	interrupt-parent = <&sysirq>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	psci {
+		compatible = "arm,psci-0.2";
+		method = "smc";
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x000>;
+		};
+
+		cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x001>;
+		};
+
+		cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x002>;
+		};
+
+		cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x003>;
+		};
+
+		cpu@100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x100>;
+		};
+
+		cpu@101 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x101>;
+		};
+
+		cpu@102 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x102>;
+		};
+
+		cpu@103 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x103>;
+		};
+	};
+
+	clocks {
+		clk26m: clk26m {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <26000000>;
+		};
+
+		clk32k: clk32k {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <32000>;
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+	};
+
+	soc {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		compatible = "simple-bus";
+		ranges;
+
+		gic: interrupt-controller@c000000 {
+			compatible = "arm,gic-v3";
+			#interrupt-cells = <3>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			interrupt-parent = <&gic>;
+			interrupt-controller;
+			reg = <0 0x0c000000 0 0x40000>,  /* GICD */
+			      <0 0x0c100000 0 0x200000>, /* GICR */
+			      <0 0x0c400000 0 0x2000>,   /* GICC */
+			      <0 0x0c410000 0 0x2000>,   /* GICH */
+			      <0 0x0c420000 0 0x20000>;  /* GICV */
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		topckgen: topckgen@10000000 {
+			compatible = "mediatek,mt6765-topckgen", "syscon";
+			reg = <0 0x10000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		infracfg: infracfg@10001000 {
+			compatible = "mediatek,mt6765-infracfg", "syscon";
+			reg = <0 0x10001000 0 0x1000>;
+			interrupts = <GIC_SPI 147 IRQ_TYPE_EDGE_RISING>;
+			#clock-cells = <1>;
+		};
+
+		pericfg: pericfg@10003000 {
+			compatible = "mediatek,mt6765-pericfg", "syscon";
+			reg = <0 0x10003000 0 0x1000>;
+		};
+
+		scpsys: scpsys@10006000 {
+			compatible = "mediatek,mt6765-scpsys";
+			reg =	<0 0x10006000 0 0x1000>; /* spm */
+			#power-domain-cells = <1>;
+			clocks = <&topckgen CLK_TOP_MFG_SEL>,
+				 <&topckgen CLK_TOP_MM_SEL>,
+				 <&mmsys_config CLK_MM_SMI_COMMON>,
+				 <&mmsys_config CLK_MM_SMI_COMM0>,
+				 <&mmsys_config CLK_MM_SMI_COMM1>,
+				 <&mmsys_config CLK_MM_SMI_LARB0>,
+				 <&imgsys CLK_IMG_LARB2>,
+				 <&mmsys_config CLK_MM_SMI_IMG>,
+				 <&camsys CLK_CAM_LARB3>,
+				 <&camsys CLK_CAM_DFP_VAD>,
+				 <&camsys CLK_CAM>,
+				 <&camsys CLK_CAM_CCU>,
+				 <&mmsys_config CLK_MM_SMI_CAM>;
+			clock-names = "mfg", "mm",
+				      "mm-0", "mm-1", "mm-2", "mm-3",
+				      "isp-0", "isp-1", "cam-0", "cam-1",
+				      "cam-2", "cam-3", "cam-4";
+			infracfg = <&infracfg>;
+			smi_comm = <&smi_common>;
+		};
+
+		apmixed: apmixed@1000c000 {
+			compatible = "mediatek,mt6765-apmixedsys", "syscon";
+			reg = <0 0x1000c000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		sysirq: interrupt-controller@10200a80 {
+			compatible = "mediatek,mt6765-sysirq",
+				     "mediatek,mt6577-sysirq";
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			interrupt-parent = <&gic>;
+			reg = <0 0x10200a80 0 0x50>;
+		};
+
+		uart0: serial@11002000 {
+			compatible = "mediatek,mt6765-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11002000 0 0x400>;
+			interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>;
+			clocks = <&infracfg CLK_IFR_UART0>,
+				 <&infracfg CLK_IFR_AP_DMA>;
+			clock-names = "baud", "bus";
+			status = "disabled";
+		};
+
+		uart1: serial@11003000 {
+			compatible = "mediatek,mt6765-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11003000 0 0x400>;
+			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_LOW>;
+			clocks = <&infracfg CLK_IFR_UART1>,
+				 <&infracfg CLK_IFR_AP_DMA>;
+			clock-names = "baud", "bus";
+			status = "disabled";
+		};
+
+		audio: audio@11220000 {
+			compatible = "mediatek,mt6765-audsys", "syscon";
+			reg = <0 0x11220000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		mipi_rx_ana_csi0a: mipi_rx_ana_csi0a@11c10000 {
+			compatible = "mediatek,mt6765-mipi_rx_ana_csi0a",
+				     "syscon";
+			reg = <0 0x11c10000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		mmsys_config: mmsys_config@14000000 {
+			compatible = "mediatek,mt6765-mmsys", "syscon";
+			reg = <0 0x14000000 0 0x1000>;
+			interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_LOW>;
+			#clock-cells = <1>;
+		};
+
+		smi_common: smi_common@14002000 {
+			compatible = "mediatek,mt6765-smi-common", "syscon";
+			reg = <0 0x14002000 0 0x1000>;
+		};
+
+		imgsys: imgsys@15020000 {
+			compatible = "mediatek,mt6765-imgsys", "syscon";
+			reg = <0 0x15020000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		venc_gcon: venc_gcon@17000000 {
+			compatible = "mediatek,mt6765-vcodecsys", "syscon";
+			reg = <0 0x17000000 0 0x10000>;
+			#clock-cells = <1>;
+		};
+
+		camsys: camsys@1a000000  {
+			compatible = "mediatek,mt6765-camsys", "syscon";
+			reg = <0 0x1a000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+	}; /* end of soc */
+};
-- 
1.7.9.5


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

* Re: [PATCH v5 05/11] clk: mediatek: add mt6765 clock IDs
  2018-07-17  8:52 ` [PATCH v5 05/11] clk: mediatek: add mt6765 clock IDs Mars Cheng
@ 2018-07-17 10:24   ` Matthias Brugger
  2018-07-18  4:23     ` Mars Cheng
  0 siblings, 1 reply; 32+ messages in thread
From: Matthias Brugger @ 2018-07-17 10:24 UTC (permalink / raw)
  To: Mars Cheng, Rob Herring, Marc Zyngier, Ryder Lee, Stephen Boyd,
	Sean Wang
  Cc: CC Hwang, Loda Chou, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, linux-serial, linux-arm-kernel, linux-clk,
	Owen Chen



On 17/07/18 10:52, Mars Cheng wrote:
> Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
> Signed-off-by: Owen Chen <owen.chen@mediatek.com>

Please provide a commit message.

Thanks,
Matthias

> ---
>  include/dt-bindings/clock/mt6765-clk.h |  313 ++++++++++++++++++++++++++++++++
>  1 file changed, 313 insertions(+)
>  create mode 100644 include/dt-bindings/clock/mt6765-clk.h
> 
> diff --git a/include/dt-bindings/clock/mt6765-clk.h b/include/dt-bindings/clock/mt6765-clk.h
> new file mode 100644
> index 0000000..eb97e56
> --- /dev/null
> +++ b/include/dt-bindings/clock/mt6765-clk.h
> @@ -0,0 +1,313 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +#ifndef _DT_BINDINGS_CLK_MT6765_H
> +#define _DT_BINDINGS_CLK_MT6765_H
> +
> +/* FIX Clks */
> +#define CLK_TOP_CLK26M			0
> +
> +/* APMIXEDSYS */
> +#define CLK_APMIXED_ARMPLL_L		0
> +#define CLK_APMIXED_ARMPLL		1
> +#define CLK_APMIXED_CCIPLL		2
> +#define CLK_APMIXED_MAINPLL		3
> +#define CLK_APMIXED_MFGPLL		4
> +#define CLK_APMIXED_MMPLL		5
> +#define CLK_APMIXED_UNIV2PLL		6
> +#define CLK_APMIXED_MSDCPLL		7
> +#define CLK_APMIXED_APLL1		8
> +#define CLK_APMIXED_MPLL		9
> +#define CLK_APMIXED_ULPOSC1		10
> +#define CLK_APMIXED_ULPOSC2		11
> +#define CLK_APMIXED_SSUSB26M		12
> +#define CLK_APMIXED_APPLL26M		13
> +#define CLK_APMIXED_MIPIC0_26M		14
> +#define CLK_APMIXED_MDPLLGP26M		15
> +#define CLK_APMIXED_MMSYS_F26M		16
> +#define CLK_APMIXED_UFS26M		17
> +#define CLK_APMIXED_MIPIC1_26M		18
> +#define CLK_APMIXED_MEMPLL26M		19
> +#define CLK_APMIXED_CLKSQ_LVPLL_26M	20
> +#define CLK_APMIXED_MIPID0_26M		21
> +#define CLK_APMIXED_NR_CLK		22
> +
> +/* TOPCKGEN */
> +#define CLK_TOP_SYSPLL			0
> +#define CLK_TOP_SYSPLL_D2		1
> +#define CLK_TOP_SYSPLL1_D2		2
> +#define CLK_TOP_SYSPLL1_D4		3
> +#define CLK_TOP_SYSPLL1_D8		4
> +#define CLK_TOP_SYSPLL1_D16		5
> +#define CLK_TOP_SYSPLL_D3		6
> +#define CLK_TOP_SYSPLL2_D2		7
> +#define CLK_TOP_SYSPLL2_D4		8
> +#define CLK_TOP_SYSPLL2_D8		9
> +#define CLK_TOP_SYSPLL_D5		10
> +#define CLK_TOP_SYSPLL3_D2		11
> +#define CLK_TOP_SYSPLL3_D4		12
> +#define CLK_TOP_SYSPLL_D7		13
> +#define CLK_TOP_SYSPLL4_D2		14
> +#define CLK_TOP_SYSPLL4_D4		15
> +#define CLK_TOP_USB20_192M		16
> +#define CLK_TOP_USB20_192M_D4		17
> +#define CLK_TOP_USB20_192M_D8		18
> +#define CLK_TOP_USB20_192M_D16		19
> +#define CLK_TOP_USB20_192M_D32		20
> +#define CLK_TOP_UNIVPLL			21
> +#define CLK_TOP_UNIVPLL_D2		22
> +#define CLK_TOP_UNIVPLL1_D2		23
> +#define CLK_TOP_UNIVPLL1_D4		24
> +#define CLK_TOP_UNIVPLL_D3		25
> +#define CLK_TOP_UNIVPLL2_D2		26
> +#define CLK_TOP_UNIVPLL2_D4		27
> +#define CLK_TOP_UNIVPLL2_D8		28
> +#define CLK_TOP_UNIVPLL2_D32		29
> +#define CLK_TOP_UNIVPLL_D5		30
> +#define CLK_TOP_UNIVPLL3_D2		31
> +#define CLK_TOP_UNIVPLL3_D4		32
> +#define CLK_TOP_MMPLL			33
> +#define CLK_TOP_MMPLL_D2		34
> +#define CLK_TOP_MPLL			35
> +#define CLK_TOP_DA_MPLL_104M_DIV	36
> +#define CLK_TOP_DA_MPLL_52M_DIV		37
> +#define CLK_TOP_MFGPLL			38
> +#define CLK_TOP_MSDCPLL			39
> +#define CLK_TOP_MSDCPLL_D2		40
> +#define CLK_TOP_APLL1			41
> +#define CLK_TOP_APLL1_D2		42
> +#define CLK_TOP_APLL1_D4		43
> +#define CLK_TOP_APLL1_D8		44
> +#define CLK_TOP_ULPOSC1			45
> +#define CLK_TOP_ULPOSC1_D2		46
> +#define CLK_TOP_ULPOSC1_D4		47
> +#define CLK_TOP_ULPOSC1_D8		48
> +#define CLK_TOP_ULPOSC1_D16		49
> +#define CLK_TOP_ULPOSC1_D32		50
> +#define CLK_TOP_DMPLL			51
> +#define CLK_TOP_F_FRTC			52
> +#define CLK_TOP_F_F26M			53
> +#define CLK_TOP_AXI			54
> +#define CLK_TOP_MM			55
> +#define CLK_TOP_SCP			56
> +#define CLK_TOP_MFG			57
> +#define CLK_TOP_F_FUART			58
> +#define CLK_TOP_SPI			59
> +#define CLK_TOP_MSDC50_0		60
> +#define CLK_TOP_MSDC30_1		61
> +#define CLK_TOP_AUDIO			62
> +#define CLK_TOP_AUD_1			63
> +#define CLK_TOP_AUD_ENGEN1		64
> +#define CLK_TOP_F_FDISP_PWM		65
> +#define CLK_TOP_SSPM			66
> +#define CLK_TOP_DXCC			67
> +#define CLK_TOP_I2C			68
> +#define CLK_TOP_F_FPWM			69
> +#define CLK_TOP_F_FSENINF		70
> +#define CLK_TOP_AES_FDE			71
> +#define CLK_TOP_F_BIST2FPC		72
> +#define CLK_TOP_ARMPLL_DIVIDER_PLL0	73
> +#define CLK_TOP_ARMPLL_DIVIDER_PLL1	74
> +#define CLK_TOP_ARMPLL_DIVIDER_PLL2	75
> +#define CLK_TOP_DA_USB20_48M_DIV	76
> +#define CLK_TOP_DA_UNIV_48M_DIV		77
> +#define CLK_TOP_APLL12_DIV0		78
> +#define CLK_TOP_APLL12_DIV1		79
> +#define CLK_TOP_APLL12_DIV2		80
> +#define CLK_TOP_APLL12_DIV3		81
> +#define CLK_TOP_ARMPLL_DIVIDER_PLL0_EN	82
> +#define CLK_TOP_ARMPLL_DIVIDER_PLL1_EN	83
> +#define CLK_TOP_ARMPLL_DIVIDER_PLL2_EN	84
> +#define CLK_TOP_FMEM_OCC_DRC_EN		85
> +#define CLK_TOP_USB20_48M_EN		86
> +#define CLK_TOP_UNIVPLL_48M_EN		87
> +#define CLK_TOP_MPLL_104M_EN		88
> +#define CLK_TOP_MPLL_52M_EN		89
> +#define CLK_TOP_F_UFS_MP_SAP_CFG_EN	90
> +#define CLK_TOP_F_BIST2FPC_EN		91
> +#define CLK_TOP_MD_32K			92
> +#define CLK_TOP_MD_26M			93
> +#define CLK_TOP_MD2_32K			94
> +#define CLK_TOP_MD2_26M			95
> +#define CLK_TOP_AXI_SEL			96
> +#define CLK_TOP_MEM_SEL			97
> +#define CLK_TOP_MM_SEL			98
> +#define CLK_TOP_SCP_SEL			99
> +#define CLK_TOP_MFG_SEL			100
> +#define CLK_TOP_ATB_SEL			101
> +#define CLK_TOP_CAMTG_SEL		102
> +#define CLK_TOP_CAMTG1_SEL		103
> +#define CLK_TOP_CAMTG2_SEL		104
> +#define CLK_TOP_CAMTG3_SEL		105
> +#define CLK_TOP_UART_SEL		106
> +#define CLK_TOP_SPI_SEL			107
> +#define CLK_TOP_MSDC50_0_HCLK_SEL	108
> +#define CLK_TOP_MSDC50_0_SEL		109
> +#define CLK_TOP_MSDC30_1_SEL		110
> +#define CLK_TOP_AUDIO_SEL		111
> +#define CLK_TOP_AUD_INTBUS_SEL		112
> +#define CLK_TOP_AUD_1_SEL		113
> +#define CLK_TOP_AUD_ENGEN1_SEL		114
> +#define CLK_TOP_DISP_PWM_SEL		115
> +#define CLK_TOP_SSPM_SEL		116
> +#define CLK_TOP_DXCC_SEL		117
> +#define CLK_TOP_USB_TOP_SEL		118
> +#define CLK_TOP_SPM_SEL			119
> +#define CLK_TOP_I2C_SEL			120
> +#define CLK_TOP_PWM_SEL			121
> +#define CLK_TOP_SENINF_SEL		122
> +#define CLK_TOP_AES_FDE_SEL		123
> +#define CLK_TOP_PWRAP_ULPOSC_SEL	124
> +#define CLK_TOP_CAMTM_SEL		125
> +#define CLK_TOP_NR_CLK			126
> +
> +/* INFRACFG */
> +#define CLK_IFR_ICUSB			0
> +#define CLK_IFR_GCE			1
> +#define CLK_IFR_THERM			2
> +#define CLK_IFR_I2C_AP			3
> +#define CLK_IFR_I2C_CCU			4
> +#define CLK_IFR_I2C_SSPM		5
> +#define CLK_IFR_I2C_RSV			6
> +#define CLK_IFR_PWM_HCLK		7
> +#define CLK_IFR_PWM1			8
> +#define CLK_IFR_PWM2			9
> +#define CLK_IFR_PWM3			10
> +#define CLK_IFR_PWM4			11
> +#define CLK_IFR_PWM5			12
> +#define CLK_IFR_PWM			13
> +#define CLK_IFR_UART0			14
> +#define CLK_IFR_UART1			15
> +#define CLK_IFR_GCE_26M			16
> +#define CLK_IFR_CQ_DMA_FPC		17
> +#define CLK_IFR_BTIF			18
> +#define CLK_IFR_SPI0			19
> +#define CLK_IFR_MSDC0			20
> +#define CLK_IFR_MSDC1			21
> +#define CLK_IFR_TRNG			22
> +#define CLK_IFR_AUXADC			23
> +#define CLK_IFR_CCIF1_AP		24
> +#define CLK_IFR_CCIF1_MD		25
> +#define CLK_IFR_AUXADC_MD		26
> +#define CLK_IFR_AP_DMA			27
> +#define CLK_IFR_DEVICE_APC		28
> +#define CLK_IFR_CCIF_AP			29
> +#define CLK_IFR_AUDIO			30
> +#define CLK_IFR_CCIF_MD			31
> +#define CLK_IFR_RG_PWM_FBCLK6		32
> +#define CLK_IFR_DISP_PWM		33
> +#define CLK_IFR_CLDMA_BCLK		34
> +#define CLK_IFR_AUDIO_26M_BCLK		35
> +#define CLK_IFR_SPI1			36
> +#define CLK_IFR_I2C4			37
> +#define CLK_IFR_SPI2			38
> +#define CLK_IFR_SPI3			39
> +#define CLK_IFR_I2C5			40
> +#define CLK_IFR_I2C5_ARBITER		41
> +#define CLK_IFR_I2C5_IMM		42
> +#define CLK_IFR_I2C1_ARBITER		43
> +#define CLK_IFR_I2C1_IMM		44
> +#define CLK_IFR_I2C2_ARBITER		45
> +#define CLK_IFR_I2C2_IMM		46
> +#define CLK_IFR_SPI4			47
> +#define CLK_IFR_SPI5			48
> +#define CLK_IFR_CQ_DMA			49
> +#define CLK_IFR_FAES_FDE		50
> +#define CLK_IFR_MSDC0_SELF		51
> +#define CLK_IFR_MSDC1_SELF		52
> +#define CLK_IFR_I2C6			53
> +#define CLK_IFR_AP_MSDC0		54
> +#define CLK_IFR_MD_MSDC0		55
> +#define CLK_IFR_MSDC0_SRC		56
> +#define CLK_IFR_MSDC1_SRC		57
> +#define CLK_IFR_AES_TOP0_BCLK		58
> +#define CLK_IFR_MCU_PM_BCLK		59
> +#define CLK_IFR_CCIF2_AP		60
> +#define CLK_IFR_CCIF2_MD		61
> +#define CLK_IFR_CCIF3_AP		62
> +#define CLK_IFR_CCIF3_MD		63
> +#define CLK_IFR_NR_CLK			64
> +
> +/* AUDIO */
> +#define CLK_AUDIO_AFE			0
> +#define CLK_AUDIO_22M			1
> +#define CLK_AUDIO_APLL_TUNER		2
> +#define CLK_AUDIO_ADC			3
> +#define CLK_AUDIO_DAC			4
> +#define CLK_AUDIO_DAC_PREDIS		5
> +#define CLK_AUDIO_TML			6
> +#define CLK_AUDIO_I2S1_BCLK		7
> +#define CLK_AUDIO_I2S2_BCLK		8
> +#define CLK_AUDIO_I2S3_BCLK		9
> +#define CLK_AUDIO_I2S4_BCLK		10
> +#define CLK_AUDIO_NR_CLK		11
> +
> +/* MIPI_RX_ANA_CSI0A */
> +
> +#define CLK_MIPI0A_CSR_CSI_EN_0A	0
> +#define CLK_MIPI0A_NR_CLK		1
> +
> +/* MMSYS_CONFIG */
> +
> +#define CLK_MM_MDP_RDMA0		0
> +#define CLK_MM_MDP_CCORR0		1
> +#define CLK_MM_MDP_RSZ0			2
> +#define CLK_MM_MDP_RSZ1			3
> +#define CLK_MM_MDP_TDSHP0		4
> +#define CLK_MM_MDP_WROT0		5
> +#define CLK_MM_MDP_WDMA0		6
> +#define CLK_MM_DISP_OVL0		7
> +#define CLK_MM_DISP_OVL0_2L		8
> +#define CLK_MM_DISP_RSZ0		9
> +#define CLK_MM_DISP_RDMA0		10
> +#define CLK_MM_DISP_WDMA0		11
> +#define CLK_MM_DISP_COLOR0		12
> +#define CLK_MM_DISP_CCORR0		13
> +#define CLK_MM_DISP_AAL0		14
> +#define CLK_MM_DISP_GAMMA0		15
> +#define CLK_MM_DISP_DITHER0		16
> +#define CLK_MM_DSI0			17
> +#define CLK_MM_FAKE_ENG			18
> +#define CLK_MM_SMI_COMMON		19
> +#define CLK_MM_SMI_LARB0		20
> +#define CLK_MM_SMI_COMM0		21
> +#define CLK_MM_SMI_COMM1		22
> +#define CLK_MM_CAM_MDP			23
> +#define CLK_MM_SMI_IMG			24
> +#define CLK_MM_SMI_CAM			25
> +#define CLK_MM_IMG_DL_RELAY		26
> +#define CLK_MM_IMG_DL_ASYNC_TOP		27
> +#define CLK_MM_DIG_DSI			28
> +#define CLK_MM_F26M_HRTWT		29
> +#define CLK_MM_NR_CLK			30
> +
> +/* IMGSYS */
> +
> +#define CLK_IMG_LARB2			0
> +#define CLK_IMG_DIP			1
> +#define CLK_IMG_FDVT			2
> +#define CLK_IMG_DPE			3
> +#define CLK_IMG_RSC			4
> +#define CLK_IMG_NR_CLK			5
> +
> +/* VENCSYS */
> +
> +#define CLK_VENC_SET0_LARB		0
> +#define CLK_VENC_SET1_VENC		1
> +#define CLK_VENC_SET2_JPGENC		2
> +#define CLK_VENC_SET3_VDEC		3
> +#define CLK_VENC_NR_CLK			4
> +
> +/* CAMSYS */
> +
> +#define CLK_CAM_LARB3			0
> +#define CLK_CAM_DFP_VAD			1
> +#define CLK_CAM				2
> +#define CLK_CAMTG			3
> +#define CLK_CAM_SENINF			4
> +#define CLK_CAMSV0			5
> +#define CLK_CAMSV1			6
> +#define CLK_CAMSV2			7
> +#define CLK_CAM_CCU			8
> +#define CLK_CAM_NR_CLK			9
> +
> +#endif /* _DT_BINDINGS_CLK_MT6765_H */
> 

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

* Re: [PATCH v5 04/11] soc: mediatek: add MT6765 scpsys support
  2018-07-17  8:52 ` [PATCH v5 04/11] soc: mediatek: add MT6765 scpsys support Mars Cheng
@ 2018-07-17 13:00   ` Sean Wang
  2018-07-18  8:54     ` Mars Cheng
  2018-07-20 17:46   ` Rob Herring
  1 sibling, 1 reply; 32+ messages in thread
From: Sean Wang @ 2018-07-17 13:00 UTC (permalink / raw)
  To: Mars Cheng
  Cc: Matthias Brugger, Rob Herring, Marc Zyngier, Ryder Lee,
	Stephen Boyd, CC Hwang, Loda Chou, linux-kernel, linux-mediatek,
	devicetree, wsd_upstream, linux-serial, linux-arm-kernel,
	linux-clk, Owen Chen

On Tue, 2018-07-17 at 16:52 +0800, Mars Cheng wrote:
> This adds scpsys support for MT6765
> 

it looks like 4/11 have to depend on 6/11 and 7/11 to get a full function on scpsys for MT6765.

you should keep dependency in order to submit these patches

> Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
> Signed-off-by: Owen Chen <owen.chen@mediatek.com>
> ---
>  drivers/soc/mediatek/mtk-scpsys.c        |   88 ++++++++++++++++++++++++++++++
>  include/dt-bindings/power/mt6765-power.h |   14 +++++
>  2 files changed, 102 insertions(+)
>  create mode 100644 include/dt-bindings/power/mt6765-power.h
> 
> diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
> index 5b24bb4..4bb6c7a 100644
> --- a/drivers/soc/mediatek/mtk-scpsys.c
> +++ b/drivers/soc/mediatek/mtk-scpsys.c
> @@ -23,6 +23,7 @@
>  
>  #include <dt-bindings/power/mt2701-power.h>
>  #include <dt-bindings/power/mt2712-power.h>
> +#include <dt-bindings/power/mt6765-power.h>
>  #include <dt-bindings/power/mt6797-power.h>
>  #include <dt-bindings/power/mt7622-power.h>
>  #include <dt-bindings/power/mt7623a-power.h>
> @@ -680,6 +681,79 @@ static void mtk_register_power_domains(struct platform_device *pdev,
>  };
>  
>  /*
> + * MT6765 power domain support
> + */
> +#define SPM_PWR_STATUS_MT6765			0x0180
> +#define SPM_PWR_STATUS_2ND_MT6765		0x0184
> +
> +static const struct scp_domain_data scp_domain_data_mt6765[] = {
> +	[MT6765_POWER_DOMAIN_VCODEC] = {
> +		.name = "vcodec",
> +		.sta_mask = BIT(26),
> +		.ctl_offs = 0x300,
> +		.sram_pdn_bits = GENMASK(8, 8),
> +		.sram_pdn_ack_bits = GENMASK(12, 12),
> +	},
> +	[MT6765_POWER_DOMAIN_ISP] = {
> +		.name = "isp",
> +		.sta_mask = BIT(5),
> +		.ctl_offs = 0x308,
> +		.sram_pdn_bits = GENMASK(8, 8),
> +		.sram_pdn_ack_bits = GENMASK(12, 12),
> +	},
> +	[MT6765_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),
> +	},
> +	[MT6765_POWER_DOMAIN_CONN] = {
> +		.name = "conn",
> +		.sta_mask = BIT(1),
> +		.ctl_offs = 0x32C,
> +		.sram_pdn_bits = 0,
> +		.sram_pdn_ack_bits = 0,
> +	},
> +	[MT6765_POWER_DOMAIN_MFG_ASYNC] = {
> +		.name = "mfg_async",
> +		.sta_mask = BIT(23),
> +		.ctl_offs = 0x334,
> +		.sram_pdn_bits = 0,
> +		.sram_pdn_ack_bits = 0,
> +	},
> +	[MT6765_POWER_DOMAIN_MFG] = {
> +		.name = "mfg",
> +		.sta_mask = BIT(4),
> +		.ctl_offs = 0x338,
> +		.sram_pdn_bits = GENMASK(8, 8),
> +		.sram_pdn_ack_bits = GENMASK(12, 12),
> +	},
> +	[MT6765_POWER_DOMAIN_CAM] = {
> +		.name = "cam",
> +		.sta_mask = BIT(25),
> +		.ctl_offs = 0x344,
> +		.sram_pdn_bits = GENMASK(8, 9),
> +		.sram_pdn_ack_bits = GENMASK(12, 13),
> +	},
> +	[MT6765_POWER_DOMAIN_MFG_CORE0] = {
> +		.name = "mfg_core0",
> +		.sta_mask = BIT(7),
> +		.ctl_offs = 0x34C,
> +		.sram_pdn_bits = GENMASK(8, 8),
> +		.sram_pdn_ack_bits = GENMASK(12, 12),
> +	},

Above power domains really don't require any clock controlled with
clk_id before any access on them?

> +};
> +
> +static const struct scp_subdomain scp_subdomain_mt6765[] = {
> +	{MT6765_POWER_DOMAIN_MM, MT6765_POWER_DOMAIN_CAM},
> +	{MT6765_POWER_DOMAIN_MM, MT6765_POWER_DOMAIN_ISP},
> +	{MT6765_POWER_DOMAIN_MM, MT6765_POWER_DOMAIN_VCODEC},
> +	{MT6765_POWER_DOMAIN_MFG_ASYNC, MT6765_POWER_DOMAIN_MFG},
> +	{MT6765_POWER_DOMAIN_MFG, MT6765_POWER_DOMAIN_MFG_CORE0},
> +};
> +
> +/*
>   * MT6797 power domain support
>   */
>  
> @@ -962,6 +1036,17 @@ static void mtk_register_power_domains(struct platform_device *pdev,
>  	.bus_prot_reg_update = false,
>  };
>  
> +static const struct scp_soc_data mt6765_data = {
> +	.domains = scp_domain_data_mt6765,
> +	.num_domains = ARRAY_SIZE(scp_domain_data_mt6765),
> +	.subdomains = scp_subdomain_mt6765,
> +	.num_subdomains = ARRAY_SIZE(scp_subdomain_mt6765),
> +	.regs = {
> +		.pwr_sta_offs = SPM_PWR_STATUS_MT6765,
> +		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6765,
> +	},
> +};
> +
>  static const struct scp_soc_data mt6797_data = {
>  	.domains = scp_domain_data_mt6797,
>  	.num_domains = ARRAY_SIZE(scp_domain_data_mt6797),
> @@ -1018,6 +1103,9 @@ static void mtk_register_power_domains(struct platform_device *pdev,
>  		.compatible = "mediatek,mt2712-scpsys",
>  		.data = &mt2712_data,
>  	}, {
> +		.compatible = "mediatek,mt6765-scpsys",
> +		.data = &mt6765_data,
> +	}, {
>  		.compatible = "mediatek,mt6797-scpsys",
>  		.data = &mt6797_data,
>  	}, {
> diff --git a/include/dt-bindings/power/mt6765-power.h b/include/dt-bindings/power/mt6765-power.h
> new file mode 100644
> index 0000000..d347b4e
> --- /dev/null
> +++ b/include/dt-bindings/power/mt6765-power.h
> @@ -0,0 +1,14 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _DT_BINDINGS_POWER_MT6765_POWER_H
> +#define _DT_BINDINGS_POWER_MT6765_POWER_H
> +
> +#define MT6765_POWER_DOMAIN_CONN		0
> +#define MT6765_POWER_DOMAIN_MM			1
> +#define MT6765_POWER_DOMAIN_MFG_ASYNC		2
> +#define MT6765_POWER_DOMAIN_ISP			3
> +#define MT6765_POWER_DOMAIN_MFG			4
> +#define MT6765_POWER_DOMAIN_MFG_CORE0		5
> +#define MT6765_POWER_DOMAIN_CAM			6
> +#define MT6765_POWER_DOMAIN_VCODEC		7
> +
> +#endif /* _DT_BINDINGS_POWER_MT6765_POWER_H */



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

* Re: [PATCH v5 06/11] soc: mediatek: add new flow for mtcmos power.
  2018-07-17  8:52 ` [PATCH v5 06/11] soc: mediatek: add new flow for mtcmos power Mars Cheng
@ 2018-07-17 15:49   ` kbuild test robot
  2018-07-17 18:19   ` [RFC PATCH] soc: mediatek: bus_ctrl_set_release() can be static kbuild test robot
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 32+ messages in thread
From: kbuild test robot @ 2018-07-17 15:49 UTC (permalink / raw)
  To: Mars Cheng
  Cc: kbuild-all, Matthias Brugger, Rob Herring, Marc Zyngier,
	Ryder Lee, Stephen Boyd, Sean Wang, CC Hwang, Loda Chou,
	linux-kernel, linux-mediatek, devicetree, wsd_upstream,
	linux-serial, linux-arm-kernel, linux-clk, Owen Chen, Mars Cheng

[-- Attachment #1: Type: text/plain, Size: 9119 bytes --]

Hi Owen,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on robh/for-next]
[also build test ERROR on v4.18-rc5 next-20180717]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Mars-Cheng/Add-basic-SoC-support-for-mt6765/20180717-205540
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: powerpc-allyesconfig (attached as .config)
compiler: powerpc64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=7.2.0 make.cross ARCH=powerpc 

All error/warnings (new ones prefixed by >>):

   In file included from include/linux/kernel.h:14:0,
                    from include/linux/clk.h:16,
                    from drivers/soc/mediatek/mtk-scpsys-ext.c:6:
   drivers/soc/mediatek/mtk-scpsys-ext.c: In function 'bus_clk_enable_disable':
>> drivers/soc/mediatek/mtk-scpsys-ext.c:141:12: error: implicit declaration of function '__clk_get_name'; did you mean 'clk_get_rate'? [-Werror=implicit-function-declaration]
               __clk_get_name(cc->clk));
               ^
   include/linux/printk.h:304:33: note: in definition of macro 'pr_err'
     printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
                                    ^~~~~~~~~~~
   In file included from include/linux/printk.h:7:0,
                    from include/linux/kernel.h:14,
                    from include/linux/clk.h:16,
                    from drivers/soc/mediatek/mtk-scpsys-ext.c:6:
>> include/linux/kern_levels.h:5:18: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'int' [-Wformat=]
    #define KERN_SOH "\001"  /* ASCII Start Of Header */
                     ^
   include/linux/kern_levels.h:11:18: note: in expansion of macro 'KERN_SOH'
    #define KERN_ERR KERN_SOH "3" /* error conditions */
                     ^~~~~~~~
   include/linux/printk.h:304:9: note: in expansion of macro 'KERN_ERR'
     printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
            ^~~~~~~~
>> drivers/soc/mediatek/mtk-scpsys-ext.c:139:5: note: in expansion of macro 'pr_err'
        pr_err("Failed to  %s %s\n",
        ^~~~~~
   drivers/soc/mediatek/mtk-scpsys-ext.c:139:28: note: format string is defined here
        pr_err("Failed to  %s %s\n",
                              ~^
                              %d
   cc1: some warnings being treated as errors
--
   In file included from include/linux/kernel.h:14:0,
                    from include/linux/clk.h:16,
                    from drivers/soc//mediatek/mtk-scpsys-ext.c:6:
   drivers/soc//mediatek/mtk-scpsys-ext.c: In function 'bus_clk_enable_disable':
   drivers/soc//mediatek/mtk-scpsys-ext.c:141:12: error: implicit declaration of function '__clk_get_name'; did you mean 'clk_get_rate'? [-Werror=implicit-function-declaration]
               __clk_get_name(cc->clk));
               ^
   include/linux/printk.h:304:33: note: in definition of macro 'pr_err'
     printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
                                    ^~~~~~~~~~~
   In file included from include/linux/printk.h:7:0,
                    from include/linux/kernel.h:14,
                    from include/linux/clk.h:16,
                    from drivers/soc//mediatek/mtk-scpsys-ext.c:6:
>> include/linux/kern_levels.h:5:18: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'int' [-Wformat=]
    #define KERN_SOH "\001"  /* ASCII Start Of Header */
                     ^
   include/linux/kern_levels.h:11:18: note: in expansion of macro 'KERN_SOH'
    #define KERN_ERR KERN_SOH "3" /* error conditions */
                     ^~~~~~~~
   include/linux/printk.h:304:9: note: in expansion of macro 'KERN_ERR'
     printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
            ^~~~~~~~
   drivers/soc//mediatek/mtk-scpsys-ext.c:139:5: note: in expansion of macro 'pr_err'
        pr_err("Failed to  %s %s\n",
        ^~~~~~
   drivers/soc//mediatek/mtk-scpsys-ext.c:139:28: note: format string is defined here
        pr_err("Failed to  %s %s\n",
                              ~^
                              %d
   cc1: some warnings being treated as errors

vim +141 drivers/soc/mediatek/mtk-scpsys-ext.c

   > 6	#include <linux/clk.h>
     7	#include <linux/clk-provider.h>
     8	#include <linux/slab.h>
     9	#include <linux/export.h>
    10	#include <linux/mfd/syscon.h>
    11	#include <linux/of_device.h>
    12	#include <linux/platform_device.h>
    13	#include <linux/regmap.h>
    14	#include <linux/soc/mediatek/infracfg.h>
    15	#include <linux/soc/mediatek/scpsys-ext.h>
    16	
    17	
    18	#define MAX_CLKS		10
    19	#define INFRA			"infracfg"
    20	#define SMIC			"smi_comm"
    21	
    22	static LIST_HEAD(ext_clk_map_list);
    23	static LIST_HEAD(ext_attr_map_list);
    24	
    25	static struct regmap *infracfg;
    26	static struct regmap *smi_comm;
    27	
    28	enum regmap_type {
    29		IFR_TYPE,
    30		SMI_TYPE,
    31		MAX_REGMAP_TYPE,
    32	};
    33	
    34	/**
    35	 * struct ext_reg_ctrl - set multiple register for bus protect
    36	 * @regmap: The bus protect regmap, 1: infracfg, 2: other master regmap
    37	 *                  such as SMI.
    38	 * @set_ofs: The set register offset to set corresponding bit to 1.
    39	 * @clr_ofs: The clr register offset to clear corresponding bit to 0.
    40	 * @sta_ofs: The status register offset to show bus protect enable/disable.
    41	 */
    42	struct ext_reg_ctrl {
    43		enum regmap_type type;
    44		u32 set_ofs;
    45		u32 clr_ofs;
    46		u32 sta_ofs;
    47	};
    48	
    49	/**
    50	 * struct ext_clk_ctrl - enable multiple clks for bus protect
    51	 * @clk: The clk need to enable before pwr on/bus protect.
    52	 * @scpd_n: The name present the scpsys domain where the clks belongs to.
    53	 * @clk_list: The list node linked to ext_clk_map_list.
    54	 */
    55	struct ext_clk_ctrl {
    56		struct clk *clk;
    57		const char *scpd_n;
    58		struct list_head clk_list;
    59	};
    60	
    61	struct bus_mask_ops {
    62		int	(*set)(struct regmap *regmap, u32 set_ofs,
    63			       u32 sta_ofs, u32 mask);
    64		int	(*release)(struct regmap *regmap, u32 clr_ofs,
    65				   u32 sta_ofs, u32 mask);
    66	};
    67	
    68	static struct scpsys_ext_attr *__get_attr_parent(const char *parent_n)
    69	{
    70		struct scpsys_ext_attr *attr;
    71	
    72		if (!parent_n)
    73			return ERR_PTR(-EINVAL);
    74	
    75		list_for_each_entry(attr, &ext_attr_map_list, attr_list) {
    76			if (attr->scpd_n && !strcmp(parent_n, attr->scpd_n))
    77				return attr;
    78		}
    79	
    80		return ERR_PTR(-EINVAL);
    81	}
    82	
    83	int bus_ctrl_set_release(struct scpsys_ext_attr *attr, bool set)
    84	{
    85		int i;
    86		int ret = 0;
    87	
    88		for (i = 0; i < MAX_STEP_NUM && attr->mask[i].mask; i++) {
    89			struct ext_reg_ctrl *rc = attr->mask[i].regs;
    90			struct regmap *regmap;
    91	
    92			if (rc->type == IFR_TYPE)
    93				regmap = infracfg;
    94			else if (rc->type == SMI_TYPE)
    95				regmap = smi_comm;
    96			else
    97				return -EINVAL;
    98	
    99			if (set)
   100				ret = attr->mask[i].ops->set(regmap,
   101							rc->set_ofs,
   102							rc->sta_ofs,
   103							attr->mask[i].mask);
   104			else
   105				ret = attr->mask[i].ops->release(regmap,
   106							rc->clr_ofs,
   107							rc->sta_ofs,
   108							attr->mask[i].mask);
   109		}
   110	
   111		return ret;
   112	}
   113	
   114	int bus_ctrl_set(struct scpsys_ext_attr *attr)
   115	{
   116		return bus_ctrl_set_release(attr, CMD_ENABLE);
   117	}
   118	
   119	int bus_ctrl_release(struct scpsys_ext_attr *attr)
   120	{
   121		return bus_ctrl_set_release(attr, CMD_DISABLE);
   122	}
   123	
   124	int bus_clk_enable_disable(struct scpsys_ext_attr *attr, bool enable)
   125	{
   126		int i = 0;
   127		int ret = 0;
   128		struct ext_clk_ctrl *cc;
   129		struct clk *clk[MAX_CLKS];
   130	
   131		list_for_each_entry(cc, &ext_clk_map_list, clk_list) {
   132			if (!strcmp(cc->scpd_n, attr->scpd_n)) {
   133				if (enable)
   134					ret = clk_prepare_enable(cc->clk);
   135				else
   136					clk_disable_unprepare(cc->clk);
   137	
   138				if (ret) {
 > 139					pr_err("Failed to  %s %s\n",
   140					       enable ? "enable" : "disable",
 > 141					       __clk_get_name(cc->clk));
   142					goto err;
   143				} else {
   144					clk[i] = cc->clk;
   145					i++;
   146				}
   147			}
   148		}
   149	
   150		return ret;
   151	
   152	err:
   153		for (--i; i >= 0; i--)
   154			if (enable)
   155				clk_disable_unprepare(clk[i]);
   156			else
   157				clk_prepare_enable(clk[i]);
   158		return ret;
   159	}
   160	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 57726 bytes --]

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

* Re: [PATCH v5 10/11] clk: mediatek: Add MT6765 clock support
  2018-07-17  8:52 ` [PATCH v5 10/11] clk: mediatek: Add MT6765 clock support Mars Cheng
@ 2018-07-17 16:09   ` kbuild test robot
  2018-07-17 18:52   ` kbuild test robot
  2018-07-17 18:52   ` [RFC PATCH] clk: mediatek: cksys_base can be static kbuild test robot
  2 siblings, 0 replies; 32+ messages in thread
From: kbuild test robot @ 2018-07-17 16:09 UTC (permalink / raw)
  To: Mars Cheng
  Cc: kbuild-all, Matthias Brugger, Rob Herring, Marc Zyngier,
	Ryder Lee, Stephen Boyd, Sean Wang, CC Hwang, Loda Chou,
	linux-kernel, linux-mediatek, devicetree, wsd_upstream,
	linux-serial, linux-arm-kernel, linux-clk, Owen Chen, Mars Cheng

[-- Attachment #1: Type: text/plain, Size: 1446 bytes --]

Hi Owen,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on robh/for-next]
[also build test ERROR on v4.18-rc5 next-20180717]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Mars-Cheng/Add-basic-SoC-support-for-mt6765/20180717-205540
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: i386-allmodconfig (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

>> drivers/clk/mediatek/clk-mt6765-vcodec.c:75:21: error: 'of_match_clk_mt6765_vcodec' undeclared here (not in a function); did you mean 'of_match_clk_mt6765_venc'?
      .of_match_table = of_match_clk_mt6765_vcodec,
                        ^~~~~~~~~~~~~~~~~~~~~~~~~~
                        of_match_clk_mt6765_venc

vim +75 drivers/clk/mediatek/clk-mt6765-vcodec.c

    70	
    71	static struct platform_driver clk_mt6765_vcodec_drv = {
    72		.probe = clk_mt6765_vcodec_probe,
    73		.driver = {
    74			.name = "clk-mt6765-vcodec",
  > 75			.of_match_table = of_match_clk_mt6765_vcodec,
    76		},
    77	};
    78	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 64183 bytes --]

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

* Re: [PATCH v5 06/11] soc: mediatek: add new flow for mtcmos power.
  2018-07-17  8:52 ` [PATCH v5 06/11] soc: mediatek: add new flow for mtcmos power Mars Cheng
  2018-07-17 15:49   ` kbuild test robot
  2018-07-17 18:19   ` [RFC PATCH] soc: mediatek: bus_ctrl_set_release() can be static kbuild test robot
@ 2018-07-17 18:19   ` kbuild test robot
  2018-07-17 20:36   ` kbuild test robot
  2018-07-18 14:50   ` Matthias Brugger
  4 siblings, 0 replies; 32+ messages in thread
From: kbuild test robot @ 2018-07-17 18:19 UTC (permalink / raw)
  To: Mars Cheng
  Cc: kbuild-all, Matthias Brugger, Rob Herring, Marc Zyngier,
	Ryder Lee, Stephen Boyd, Sean Wang, CC Hwang, Loda Chou,
	linux-kernel, linux-mediatek, devicetree, wsd_upstream,
	linux-serial, linux-arm-kernel, linux-clk, Owen Chen, Mars Cheng

Hi Owen,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on robh/for-next]
[also build test WARNING on v4.18-rc5 next-20180717]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Mars-Cheng/Add-basic-SoC-support-for-mt6765/20180717-205540
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
reproduce:
        # apt-get install sparse
        make ARCH=x86_64 allmodconfig
        make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

>> drivers/soc/mediatek/mtk-scpsys-ext.c:83:5: sparse: symbol 'bus_ctrl_set_release' was not declared. Should it be static?
>> drivers/soc/mediatek/mtk-scpsys-ext.c:114:5: sparse: symbol 'bus_ctrl_set' was not declared. Should it be static?
>> drivers/soc/mediatek/mtk-scpsys-ext.c:119:5: sparse: symbol 'bus_ctrl_release' was not declared. Should it be static?
>> drivers/soc/mediatek/mtk-scpsys-ext.c:124:5: sparse: symbol 'bus_clk_enable_disable' was not declared. Should it be static?
>> drivers/soc/mediatek/mtk-scpsys-ext.c:161:5: sparse: symbol 'bus_clk_enable' was not declared. Should it be static?
>> drivers/soc/mediatek/mtk-scpsys-ext.c:192:27: sparse: symbol 'bus_mask_set_clr_ctrl' was not declared. Should it be static?
>> drivers/soc/mediatek/mtk-scpsys-ext.c:197:26: sparse: symbol 'ext_bus_ctrl' was not declared. Should it be static?
>> drivers/soc/mediatek/mtk-scpsys-ext.c:202:26: sparse: symbol 'ext_cg_ctrl' was not declared. Should it be static?
>> drivers/soc/mediatek/mtk-scpsys-ext.c:210:15: sparse: symbol 'syscon_regmap_lookup_by_phandle_idx' was not declared. Should it be static?
>> drivers/soc/mediatek/mtk-scpsys-ext.c:231:5: sparse: symbol 'scpsys_ext_regmap_init' was not declared. Should it be static?
   include/linux/slab.h:631:13: sparse: undefined identifier '__builtin_mul_overflow'
>> drivers/soc/mediatek/mtk-scpsys-ext.c:324:5: sparse: symbol 'scpsys_ext_clk_init' was not declared. Should it be static?
>> drivers/soc/mediatek/mtk-scpsys-ext.c:336:5: sparse: symbol 'scpsys_ext_attr_init' was not declared. Should it be static?
   include/linux/slab.h:631:13: sparse: call with no type!

Please review and possibly fold the followup patch.

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

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

* [RFC PATCH] soc: mediatek: bus_ctrl_set_release() can be static
  2018-07-17  8:52 ` [PATCH v5 06/11] soc: mediatek: add new flow for mtcmos power Mars Cheng
  2018-07-17 15:49   ` kbuild test robot
@ 2018-07-17 18:19   ` kbuild test robot
  2018-07-17 18:19   ` [PATCH v5 06/11] soc: mediatek: add new flow for mtcmos power kbuild test robot
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 32+ messages in thread
From: kbuild test robot @ 2018-07-17 18:19 UTC (permalink / raw)
  To: Mars Cheng
  Cc: kbuild-all, Matthias Brugger, Rob Herring, Marc Zyngier,
	Ryder Lee, Stephen Boyd, Sean Wang, CC Hwang, Loda Chou,
	linux-kernel, linux-mediatek, devicetree, wsd_upstream,
	linux-serial, linux-arm-kernel, linux-clk, Owen Chen, Mars Cheng


Fixes: 4666e05d0237 ("soc: mediatek: add new flow for mtcmos power.")
Signed-off-by: kbuild test robot <fengguang.wu@intel.com>
---
 mtk-scpsys-ext.c |   28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-scpsys-ext.c b/drivers/soc/mediatek/mtk-scpsys-ext.c
index 965e64d..e4ceb38 100644
--- a/drivers/soc/mediatek/mtk-scpsys-ext.c
+++ b/drivers/soc/mediatek/mtk-scpsys-ext.c
@@ -80,7 +80,7 @@ static struct scpsys_ext_attr *__get_attr_parent(const char *parent_n)
 	return ERR_PTR(-EINVAL);
 }
 
-int bus_ctrl_set_release(struct scpsys_ext_attr *attr, bool set)
+static int bus_ctrl_set_release(struct scpsys_ext_attr *attr, bool set)
 {
 	int i;
 	int ret = 0;
@@ -111,17 +111,17 @@ int bus_ctrl_set_release(struct scpsys_ext_attr *attr, bool set)
 	return ret;
 }
 
-int bus_ctrl_set(struct scpsys_ext_attr *attr)
+static int bus_ctrl_set(struct scpsys_ext_attr *attr)
 {
 	return bus_ctrl_set_release(attr, CMD_ENABLE);
 }
 
-int bus_ctrl_release(struct scpsys_ext_attr *attr)
+static int bus_ctrl_release(struct scpsys_ext_attr *attr)
 {
 	return bus_ctrl_set_release(attr, CMD_DISABLE);
 }
 
-int bus_clk_enable_disable(struct scpsys_ext_attr *attr, bool enable)
+static int bus_clk_enable_disable(struct scpsys_ext_attr *attr, bool enable)
 {
 	int i = 0;
 	int ret = 0;
@@ -158,7 +158,7 @@ int bus_clk_enable_disable(struct scpsys_ext_attr *attr, bool enable)
 	return ret;
 }
 
-int bus_clk_enable(struct scpsys_ext_attr *attr)
+static int bus_clk_enable(struct scpsys_ext_attr *attr)
 {
 	struct scpsys_ext_attr *attr_p;
 	int ret = 0;
@@ -189,17 +189,17 @@ int bus_clk_disable(struct scpsys_ext_attr *attr)
 	return ret;
 }
 
-const struct bus_mask_ops bus_mask_set_clr_ctrl = {
+static const struct bus_mask_ops bus_mask_set_clr_ctrl = {
 	.set = &mtk_generic_set_cmd,
 	.release = &mtk_generic_clr_cmd,
 };
 
-const struct bus_ext_ops ext_bus_ctrl = {
+static const struct bus_ext_ops ext_bus_ctrl = {
 	.enable = &bus_ctrl_set,
 	.disable = &bus_ctrl_release,
 };
 
-const struct bus_ext_ops ext_cg_ctrl = {
+static const struct bus_ext_ops ext_cg_ctrl = {
 	.enable = &bus_clk_enable,
 	.disable = &bus_clk_disable,
 };
@@ -207,9 +207,9 @@ const struct bus_ext_ops ext_cg_ctrl = {
 /*
  * scpsys bus driver init
  */
-struct regmap *syscon_regmap_lookup_by_phandle_idx(struct device_node *np,
-						   const char *property,
-						   int index)
+static struct regmap *syscon_regmap_lookup_by_phandle_idx(struct device_node *np,
+							  const char *property,
+							  int index)
 {
 	struct device_node *syscon_np;
 	struct regmap *regmap;
@@ -228,7 +228,7 @@ struct regmap *syscon_regmap_lookup_by_phandle_idx(struct device_node *np,
 	return regmap;
 }
 
-int scpsys_ext_regmap_init(struct platform_device *pdev)
+static int scpsys_ext_regmap_init(struct platform_device *pdev)
 {
 	infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
 						   INFRA);
@@ -321,7 +321,7 @@ static int add_cg_to_list(struct platform_device *pdev)
 	return 0;
 }
 
-int scpsys_ext_clk_init(struct platform_device *pdev)
+static int scpsys_ext_clk_init(struct platform_device *pdev)
 {
 	int ret = 0;
 
@@ -333,7 +333,7 @@ int scpsys_ext_clk_init(struct platform_device *pdev)
 	return ret;
 }
 
-int scpsys_ext_attr_init(const struct scpsys_ext_data *data)
+static int scpsys_ext_attr_init(const struct scpsys_ext_data *data)
 {
 	int i, count = 0;
 

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

* Re: [PATCH v5 10/11] clk: mediatek: Add MT6765 clock support
  2018-07-17  8:52 ` [PATCH v5 10/11] clk: mediatek: Add MT6765 clock support Mars Cheng
  2018-07-17 16:09   ` kbuild test robot
@ 2018-07-17 18:52   ` kbuild test robot
  2018-07-17 18:52   ` [RFC PATCH] clk: mediatek: cksys_base can be static kbuild test robot
  2 siblings, 0 replies; 32+ messages in thread
From: kbuild test robot @ 2018-07-17 18:52 UTC (permalink / raw)
  To: Mars Cheng
  Cc: kbuild-all, Matthias Brugger, Rob Herring, Marc Zyngier,
	Ryder Lee, Stephen Boyd, Sean Wang, CC Hwang, Loda Chou,
	linux-kernel, linux-mediatek, devicetree, wsd_upstream,
	linux-serial, linux-arm-kernel, linux-clk, Owen Chen, Mars Cheng

Hi Owen,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on robh/for-next]
[also build test WARNING on v4.18-rc5 next-20180717]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Mars-Cheng/Add-basic-SoC-support-for-mt6765/20180717-205540
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
reproduce:
        # apt-get install sparse
        make ARCH=x86_64 allmodconfig
        make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

>> drivers/clk/mediatek/clk-mt6765.c:36:14: sparse: symbol 'cksys_base' was not declared. Should it be static?
>> drivers/clk/mediatek/clk-mt6765.c:37:14: sparse: symbol 'apmixed_base' was not declared. Should it be static?

Please review and possibly fold the followup patch.

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

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

* [RFC PATCH] clk: mediatek: cksys_base can be static
  2018-07-17  8:52 ` [PATCH v5 10/11] clk: mediatek: Add MT6765 clock support Mars Cheng
  2018-07-17 16:09   ` kbuild test robot
  2018-07-17 18:52   ` kbuild test robot
@ 2018-07-17 18:52   ` kbuild test robot
  2 siblings, 0 replies; 32+ messages in thread
From: kbuild test robot @ 2018-07-17 18:52 UTC (permalink / raw)
  To: Mars Cheng
  Cc: kbuild-all, Matthias Brugger, Rob Herring, Marc Zyngier,
	Ryder Lee, Stephen Boyd, Sean Wang, CC Hwang, Loda Chou,
	linux-kernel, linux-mediatek, devicetree, wsd_upstream,
	linux-serial, linux-arm-kernel, linux-clk, Owen Chen, Mars Cheng


Fixes: 3cff52bad99d ("clk: mediatek: Add MT6765 clock support")
Signed-off-by: kbuild test robot <fengguang.wu@intel.com>
---
 clk-mt6765.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mt6765.c b/drivers/clk/mediatek/clk-mt6765.c
index 7b360b9..2f90511 100644
--- a/drivers/clk/mediatek/clk-mt6765.c
+++ b/drivers/clk/mediatek/clk-mt6765.c
@@ -33,8 +33,8 @@
 static DEFINE_SPINLOCK(mt6765_clk_lock);
 
 /* Total 12 subsys */
-void __iomem *cksys_base;
-void __iomem *apmixed_base;
+static void __iomem *cksys_base;
+static void __iomem *apmixed_base;
 
 /* CKSYS */
 #define CLK_SCP_CFG_0		(cksys_base + 0x200)

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

* Re: [PATCH v5 06/11] soc: mediatek: add new flow for mtcmos power.
  2018-07-17  8:52 ` [PATCH v5 06/11] soc: mediatek: add new flow for mtcmos power Mars Cheng
                     ` (2 preceding siblings ...)
  2018-07-17 18:19   ` [PATCH v5 06/11] soc: mediatek: add new flow for mtcmos power kbuild test robot
@ 2018-07-17 20:36   ` kbuild test robot
  2018-07-18 14:50   ` Matthias Brugger
  4 siblings, 0 replies; 32+ messages in thread
From: kbuild test robot @ 2018-07-17 20:36 UTC (permalink / raw)
  To: Mars Cheng
  Cc: kbuild-all, Matthias Brugger, Rob Herring, Marc Zyngier,
	Ryder Lee, Stephen Boyd, Sean Wang, CC Hwang, Loda Chou,
	linux-kernel, linux-mediatek, devicetree, wsd_upstream,
	linux-serial, linux-arm-kernel, linux-clk, Owen Chen, Mars Cheng

[-- Attachment #1: Type: text/plain, Size: 7124 bytes --]

Hi Owen,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on robh/for-next]
[also build test ERROR on v4.18-rc5 next-20180717]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Mars-Cheng/Add-basic-SoC-support-for-mt6765/20180717-205540
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: openrisc-allyesconfig (attached as .config)
compiler: or1k-linux-gcc (GCC) 6.0.0 20160327 (experimental)
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=openrisc 

All errors (new ones prefixed by >>):

   In file included from include/linux/kernel.h:14:0,
                    from include/linux/clk.h:16,
                    from drivers/soc/mediatek/mtk-scpsys-ext.c:6:
   drivers/soc/mediatek/mtk-scpsys-ext.c: In function 'bus_clk_enable_disable':
>> drivers/soc/mediatek/mtk-scpsys-ext.c:141:12: error: implicit declaration of function '__clk_get_name' [-Werror=implicit-function-declaration]
               __clk_get_name(cc->clk));
               ^
   include/linux/printk.h:304:33: note: in definition of macro 'pr_err'
     printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
                                    ^~~~~~~~~~~
   In file included from include/linux/printk.h:7:0,
                    from include/linux/kernel.h:14,
                    from include/linux/clk.h:16,
                    from drivers/soc/mediatek/mtk-scpsys-ext.c:6:
   include/linux/kern_levels.h:5:18: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'int' [-Wformat=]
    #define KERN_SOH "\001"  /* ASCII Start Of Header */
                     ^
   include/linux/kern_levels.h:11:18: note: in expansion of macro 'KERN_SOH'
    #define KERN_ERR KERN_SOH "3" /* error conditions */
                     ^~~~~~~~
   include/linux/printk.h:304:9: note: in expansion of macro 'KERN_ERR'
     printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
            ^~~~~~~~
   drivers/soc/mediatek/mtk-scpsys-ext.c:139:5: note: in expansion of macro 'pr_err'
        pr_err("Failed to  %s %s\n",
        ^~~~~~
   cc1: some warnings being treated as errors

vim +/__clk_get_name +141 drivers/soc/mediatek/mtk-scpsys-ext.c

   > 6	#include <linux/clk.h>
     7	#include <linux/clk-provider.h>
     8	#include <linux/slab.h>
     9	#include <linux/export.h>
    10	#include <linux/mfd/syscon.h>
    11	#include <linux/of_device.h>
    12	#include <linux/platform_device.h>
    13	#include <linux/regmap.h>
    14	#include <linux/soc/mediatek/infracfg.h>
    15	#include <linux/soc/mediatek/scpsys-ext.h>
    16	
    17	
    18	#define MAX_CLKS		10
    19	#define INFRA			"infracfg"
    20	#define SMIC			"smi_comm"
    21	
    22	static LIST_HEAD(ext_clk_map_list);
    23	static LIST_HEAD(ext_attr_map_list);
    24	
    25	static struct regmap *infracfg;
    26	static struct regmap *smi_comm;
    27	
    28	enum regmap_type {
    29		IFR_TYPE,
    30		SMI_TYPE,
    31		MAX_REGMAP_TYPE,
    32	};
    33	
    34	/**
    35	 * struct ext_reg_ctrl - set multiple register for bus protect
    36	 * @regmap: The bus protect regmap, 1: infracfg, 2: other master regmap
    37	 *                  such as SMI.
    38	 * @set_ofs: The set register offset to set corresponding bit to 1.
    39	 * @clr_ofs: The clr register offset to clear corresponding bit to 0.
    40	 * @sta_ofs: The status register offset to show bus protect enable/disable.
    41	 */
    42	struct ext_reg_ctrl {
    43		enum regmap_type type;
    44		u32 set_ofs;
    45		u32 clr_ofs;
    46		u32 sta_ofs;
    47	};
    48	
    49	/**
    50	 * struct ext_clk_ctrl - enable multiple clks for bus protect
    51	 * @clk: The clk need to enable before pwr on/bus protect.
    52	 * @scpd_n: The name present the scpsys domain where the clks belongs to.
    53	 * @clk_list: The list node linked to ext_clk_map_list.
    54	 */
    55	struct ext_clk_ctrl {
    56		struct clk *clk;
    57		const char *scpd_n;
    58		struct list_head clk_list;
    59	};
    60	
    61	struct bus_mask_ops {
    62		int	(*set)(struct regmap *regmap, u32 set_ofs,
    63			       u32 sta_ofs, u32 mask);
    64		int	(*release)(struct regmap *regmap, u32 clr_ofs,
    65				   u32 sta_ofs, u32 mask);
    66	};
    67	
    68	static struct scpsys_ext_attr *__get_attr_parent(const char *parent_n)
    69	{
    70		struct scpsys_ext_attr *attr;
    71	
    72		if (!parent_n)
    73			return ERR_PTR(-EINVAL);
    74	
    75		list_for_each_entry(attr, &ext_attr_map_list, attr_list) {
    76			if (attr->scpd_n && !strcmp(parent_n, attr->scpd_n))
    77				return attr;
    78		}
    79	
    80		return ERR_PTR(-EINVAL);
    81	}
    82	
    83	int bus_ctrl_set_release(struct scpsys_ext_attr *attr, bool set)
    84	{
    85		int i;
    86		int ret = 0;
    87	
    88		for (i = 0; i < MAX_STEP_NUM && attr->mask[i].mask; i++) {
    89			struct ext_reg_ctrl *rc = attr->mask[i].regs;
    90			struct regmap *regmap;
    91	
    92			if (rc->type == IFR_TYPE)
    93				regmap = infracfg;
    94			else if (rc->type == SMI_TYPE)
    95				regmap = smi_comm;
    96			else
    97				return -EINVAL;
    98	
    99			if (set)
   100				ret = attr->mask[i].ops->set(regmap,
   101							rc->set_ofs,
   102							rc->sta_ofs,
   103							attr->mask[i].mask);
   104			else
   105				ret = attr->mask[i].ops->release(regmap,
   106							rc->clr_ofs,
   107							rc->sta_ofs,
   108							attr->mask[i].mask);
   109		}
   110	
   111		return ret;
   112	}
   113	
   114	int bus_ctrl_set(struct scpsys_ext_attr *attr)
   115	{
   116		return bus_ctrl_set_release(attr, CMD_ENABLE);
   117	}
   118	
   119	int bus_ctrl_release(struct scpsys_ext_attr *attr)
   120	{
   121		return bus_ctrl_set_release(attr, CMD_DISABLE);
   122	}
   123	
   124	int bus_clk_enable_disable(struct scpsys_ext_attr *attr, bool enable)
   125	{
   126		int i = 0;
   127		int ret = 0;
   128		struct ext_clk_ctrl *cc;
   129		struct clk *clk[MAX_CLKS];
   130	
   131		list_for_each_entry(cc, &ext_clk_map_list, clk_list) {
   132			if (!strcmp(cc->scpd_n, attr->scpd_n)) {
   133				if (enable)
   134					ret = clk_prepare_enable(cc->clk);
   135				else
   136					clk_disable_unprepare(cc->clk);
   137	
   138				if (ret) {
   139					pr_err("Failed to  %s %s\n",
   140					       enable ? "enable" : "disable",
 > 141					       __clk_get_name(cc->clk));
   142					goto err;
   143				} else {
   144					clk[i] = cc->clk;
   145					i++;
   146				}
   147			}
   148		}
   149	
   150		return ret;
   151	
   152	err:
   153		for (--i; i >= 0; i--)
   154			if (enable)
   155				clk_disable_unprepare(clk[i]);
   156			else
   157				clk_prepare_enable(clk[i]);
   158		return ret;
   159	}
   160	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 45626 bytes --]

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

* Re: [PATCH v5 05/11] clk: mediatek: add mt6765 clock IDs
  2018-07-17 10:24   ` Matthias Brugger
@ 2018-07-18  4:23     ` Mars Cheng
  0 siblings, 0 replies; 32+ messages in thread
From: Mars Cheng @ 2018-07-18  4:23 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: Rob Herring, Marc Zyngier, Ryder Lee, Stephen Boyd, Sean Wang,
	CC Hwang, Loda Chou, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, linux-serial, linux-arm-kernel, linux-clk,
	Owen Chen

Hi Matthias

On Tue, 2018-07-17 at 12:24 +0200, Matthias Brugger wrote:
> 
> On 17/07/18 10:52, Mars Cheng wrote:
> > Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
> > Signed-off-by: Owen Chen <owen.chen@mediatek.com>
> 
> Please provide a commit message.
> 
> Thanks,
> Matthias

Got it, it is my bad, will add it.

Thanks.
> 
> > ---
> >  include/dt-bindings/clock/mt6765-clk.h |  313 ++++++++++++++++++++++++++++++++
> >  1 file changed, 313 insertions(+)
> >  create mode 100644 include/dt-bindings/clock/mt6765-clk.h
> > 
> > diff --git a/include/dt-bindings/clock/mt6765-clk.h b/include/dt-bindings/clock/mt6765-clk.h
> > new file mode 100644
> > index 0000000..eb97e56
> > --- /dev/null
> > +++ b/include/dt-bindings/clock/mt6765-clk.h
> > @@ -0,0 +1,313 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +
> > +#ifndef _DT_BINDINGS_CLK_MT6765_H
> > +#define _DT_BINDINGS_CLK_MT6765_H
> > +
> > +/* FIX Clks */
> > +#define CLK_TOP_CLK26M			0
> > +
> > +/* APMIXEDSYS */
> > +#define CLK_APMIXED_ARMPLL_L		0
> > +#define CLK_APMIXED_ARMPLL		1
> > +#define CLK_APMIXED_CCIPLL		2
> > +#define CLK_APMIXED_MAINPLL		3
> > +#define CLK_APMIXED_MFGPLL		4
> > +#define CLK_APMIXED_MMPLL		5
> > +#define CLK_APMIXED_UNIV2PLL		6
> > +#define CLK_APMIXED_MSDCPLL		7
> > +#define CLK_APMIXED_APLL1		8
> > +#define CLK_APMIXED_MPLL		9
> > +#define CLK_APMIXED_ULPOSC1		10
> > +#define CLK_APMIXED_ULPOSC2		11
> > +#define CLK_APMIXED_SSUSB26M		12
> > +#define CLK_APMIXED_APPLL26M		13
> > +#define CLK_APMIXED_MIPIC0_26M		14
> > +#define CLK_APMIXED_MDPLLGP26M		15
> > +#define CLK_APMIXED_MMSYS_F26M		16
> > +#define CLK_APMIXED_UFS26M		17
> > +#define CLK_APMIXED_MIPIC1_26M		18
> > +#define CLK_APMIXED_MEMPLL26M		19
> > +#define CLK_APMIXED_CLKSQ_LVPLL_26M	20
> > +#define CLK_APMIXED_MIPID0_26M		21
> > +#define CLK_APMIXED_NR_CLK		22
> > +
> > +/* TOPCKGEN */
> > +#define CLK_TOP_SYSPLL			0
> > +#define CLK_TOP_SYSPLL_D2		1
> > +#define CLK_TOP_SYSPLL1_D2		2
> > +#define CLK_TOP_SYSPLL1_D4		3
> > +#define CLK_TOP_SYSPLL1_D8		4
> > +#define CLK_TOP_SYSPLL1_D16		5
> > +#define CLK_TOP_SYSPLL_D3		6
> > +#define CLK_TOP_SYSPLL2_D2		7
> > +#define CLK_TOP_SYSPLL2_D4		8
> > +#define CLK_TOP_SYSPLL2_D8		9
> > +#define CLK_TOP_SYSPLL_D5		10
> > +#define CLK_TOP_SYSPLL3_D2		11
> > +#define CLK_TOP_SYSPLL3_D4		12
> > +#define CLK_TOP_SYSPLL_D7		13
> > +#define CLK_TOP_SYSPLL4_D2		14
> > +#define CLK_TOP_SYSPLL4_D4		15
> > +#define CLK_TOP_USB20_192M		16
> > +#define CLK_TOP_USB20_192M_D4		17
> > +#define CLK_TOP_USB20_192M_D8		18
> > +#define CLK_TOP_USB20_192M_D16		19
> > +#define CLK_TOP_USB20_192M_D32		20
> > +#define CLK_TOP_UNIVPLL			21
> > +#define CLK_TOP_UNIVPLL_D2		22
> > +#define CLK_TOP_UNIVPLL1_D2		23
> > +#define CLK_TOP_UNIVPLL1_D4		24
> > +#define CLK_TOP_UNIVPLL_D3		25
> > +#define CLK_TOP_UNIVPLL2_D2		26
> > +#define CLK_TOP_UNIVPLL2_D4		27
> > +#define CLK_TOP_UNIVPLL2_D8		28
> > +#define CLK_TOP_UNIVPLL2_D32		29
> > +#define CLK_TOP_UNIVPLL_D5		30
> > +#define CLK_TOP_UNIVPLL3_D2		31
> > +#define CLK_TOP_UNIVPLL3_D4		32
> > +#define CLK_TOP_MMPLL			33
> > +#define CLK_TOP_MMPLL_D2		34
> > +#define CLK_TOP_MPLL			35
> > +#define CLK_TOP_DA_MPLL_104M_DIV	36
> > +#define CLK_TOP_DA_MPLL_52M_DIV		37
> > +#define CLK_TOP_MFGPLL			38
> > +#define CLK_TOP_MSDCPLL			39
> > +#define CLK_TOP_MSDCPLL_D2		40
> > +#define CLK_TOP_APLL1			41
> > +#define CLK_TOP_APLL1_D2		42
> > +#define CLK_TOP_APLL1_D4		43
> > +#define CLK_TOP_APLL1_D8		44
> > +#define CLK_TOP_ULPOSC1			45
> > +#define CLK_TOP_ULPOSC1_D2		46
> > +#define CLK_TOP_ULPOSC1_D4		47
> > +#define CLK_TOP_ULPOSC1_D8		48
> > +#define CLK_TOP_ULPOSC1_D16		49
> > +#define CLK_TOP_ULPOSC1_D32		50
> > +#define CLK_TOP_DMPLL			51
> > +#define CLK_TOP_F_FRTC			52
> > +#define CLK_TOP_F_F26M			53
> > +#define CLK_TOP_AXI			54
> > +#define CLK_TOP_MM			55
> > +#define CLK_TOP_SCP			56
> > +#define CLK_TOP_MFG			57
> > +#define CLK_TOP_F_FUART			58
> > +#define CLK_TOP_SPI			59
> > +#define CLK_TOP_MSDC50_0		60
> > +#define CLK_TOP_MSDC30_1		61
> > +#define CLK_TOP_AUDIO			62
> > +#define CLK_TOP_AUD_1			63
> > +#define CLK_TOP_AUD_ENGEN1		64
> > +#define CLK_TOP_F_FDISP_PWM		65
> > +#define CLK_TOP_SSPM			66
> > +#define CLK_TOP_DXCC			67
> > +#define CLK_TOP_I2C			68
> > +#define CLK_TOP_F_FPWM			69
> > +#define CLK_TOP_F_FSENINF		70
> > +#define CLK_TOP_AES_FDE			71
> > +#define CLK_TOP_F_BIST2FPC		72
> > +#define CLK_TOP_ARMPLL_DIVIDER_PLL0	73
> > +#define CLK_TOP_ARMPLL_DIVIDER_PLL1	74
> > +#define CLK_TOP_ARMPLL_DIVIDER_PLL2	75
> > +#define CLK_TOP_DA_USB20_48M_DIV	76
> > +#define CLK_TOP_DA_UNIV_48M_DIV		77
> > +#define CLK_TOP_APLL12_DIV0		78
> > +#define CLK_TOP_APLL12_DIV1		79
> > +#define CLK_TOP_APLL12_DIV2		80
> > +#define CLK_TOP_APLL12_DIV3		81
> > +#define CLK_TOP_ARMPLL_DIVIDER_PLL0_EN	82
> > +#define CLK_TOP_ARMPLL_DIVIDER_PLL1_EN	83
> > +#define CLK_TOP_ARMPLL_DIVIDER_PLL2_EN	84
> > +#define CLK_TOP_FMEM_OCC_DRC_EN		85
> > +#define CLK_TOP_USB20_48M_EN		86
> > +#define CLK_TOP_UNIVPLL_48M_EN		87
> > +#define CLK_TOP_MPLL_104M_EN		88
> > +#define CLK_TOP_MPLL_52M_EN		89
> > +#define CLK_TOP_F_UFS_MP_SAP_CFG_EN	90
> > +#define CLK_TOP_F_BIST2FPC_EN		91
> > +#define CLK_TOP_MD_32K			92
> > +#define CLK_TOP_MD_26M			93
> > +#define CLK_TOP_MD2_32K			94
> > +#define CLK_TOP_MD2_26M			95
> > +#define CLK_TOP_AXI_SEL			96
> > +#define CLK_TOP_MEM_SEL			97
> > +#define CLK_TOP_MM_SEL			98
> > +#define CLK_TOP_SCP_SEL			99
> > +#define CLK_TOP_MFG_SEL			100
> > +#define CLK_TOP_ATB_SEL			101
> > +#define CLK_TOP_CAMTG_SEL		102
> > +#define CLK_TOP_CAMTG1_SEL		103
> > +#define CLK_TOP_CAMTG2_SEL		104
> > +#define CLK_TOP_CAMTG3_SEL		105
> > +#define CLK_TOP_UART_SEL		106
> > +#define CLK_TOP_SPI_SEL			107
> > +#define CLK_TOP_MSDC50_0_HCLK_SEL	108
> > +#define CLK_TOP_MSDC50_0_SEL		109
> > +#define CLK_TOP_MSDC30_1_SEL		110
> > +#define CLK_TOP_AUDIO_SEL		111
> > +#define CLK_TOP_AUD_INTBUS_SEL		112
> > +#define CLK_TOP_AUD_1_SEL		113
> > +#define CLK_TOP_AUD_ENGEN1_SEL		114
> > +#define CLK_TOP_DISP_PWM_SEL		115
> > +#define CLK_TOP_SSPM_SEL		116
> > +#define CLK_TOP_DXCC_SEL		117
> > +#define CLK_TOP_USB_TOP_SEL		118
> > +#define CLK_TOP_SPM_SEL			119
> > +#define CLK_TOP_I2C_SEL			120
> > +#define CLK_TOP_PWM_SEL			121
> > +#define CLK_TOP_SENINF_SEL		122
> > +#define CLK_TOP_AES_FDE_SEL		123
> > +#define CLK_TOP_PWRAP_ULPOSC_SEL	124
> > +#define CLK_TOP_CAMTM_SEL		125
> > +#define CLK_TOP_NR_CLK			126
> > +
> > +/* INFRACFG */
> > +#define CLK_IFR_ICUSB			0
> > +#define CLK_IFR_GCE			1
> > +#define CLK_IFR_THERM			2
> > +#define CLK_IFR_I2C_AP			3
> > +#define CLK_IFR_I2C_CCU			4
> > +#define CLK_IFR_I2C_SSPM		5
> > +#define CLK_IFR_I2C_RSV			6
> > +#define CLK_IFR_PWM_HCLK		7
> > +#define CLK_IFR_PWM1			8
> > +#define CLK_IFR_PWM2			9
> > +#define CLK_IFR_PWM3			10
> > +#define CLK_IFR_PWM4			11
> > +#define CLK_IFR_PWM5			12
> > +#define CLK_IFR_PWM			13
> > +#define CLK_IFR_UART0			14
> > +#define CLK_IFR_UART1			15
> > +#define CLK_IFR_GCE_26M			16
> > +#define CLK_IFR_CQ_DMA_FPC		17
> > +#define CLK_IFR_BTIF			18
> > +#define CLK_IFR_SPI0			19
> > +#define CLK_IFR_MSDC0			20
> > +#define CLK_IFR_MSDC1			21
> > +#define CLK_IFR_TRNG			22
> > +#define CLK_IFR_AUXADC			23
> > +#define CLK_IFR_CCIF1_AP		24
> > +#define CLK_IFR_CCIF1_MD		25
> > +#define CLK_IFR_AUXADC_MD		26
> > +#define CLK_IFR_AP_DMA			27
> > +#define CLK_IFR_DEVICE_APC		28
> > +#define CLK_IFR_CCIF_AP			29
> > +#define CLK_IFR_AUDIO			30
> > +#define CLK_IFR_CCIF_MD			31
> > +#define CLK_IFR_RG_PWM_FBCLK6		32
> > +#define CLK_IFR_DISP_PWM		33
> > +#define CLK_IFR_CLDMA_BCLK		34
> > +#define CLK_IFR_AUDIO_26M_BCLK		35
> > +#define CLK_IFR_SPI1			36
> > +#define CLK_IFR_I2C4			37
> > +#define CLK_IFR_SPI2			38
> > +#define CLK_IFR_SPI3			39
> > +#define CLK_IFR_I2C5			40
> > +#define CLK_IFR_I2C5_ARBITER		41
> > +#define CLK_IFR_I2C5_IMM		42
> > +#define CLK_IFR_I2C1_ARBITER		43
> > +#define CLK_IFR_I2C1_IMM		44
> > +#define CLK_IFR_I2C2_ARBITER		45
> > +#define CLK_IFR_I2C2_IMM		46
> > +#define CLK_IFR_SPI4			47
> > +#define CLK_IFR_SPI5			48
> > +#define CLK_IFR_CQ_DMA			49
> > +#define CLK_IFR_FAES_FDE		50
> > +#define CLK_IFR_MSDC0_SELF		51
> > +#define CLK_IFR_MSDC1_SELF		52
> > +#define CLK_IFR_I2C6			53
> > +#define CLK_IFR_AP_MSDC0		54
> > +#define CLK_IFR_MD_MSDC0		55
> > +#define CLK_IFR_MSDC0_SRC		56
> > +#define CLK_IFR_MSDC1_SRC		57
> > +#define CLK_IFR_AES_TOP0_BCLK		58
> > +#define CLK_IFR_MCU_PM_BCLK		59
> > +#define CLK_IFR_CCIF2_AP		60
> > +#define CLK_IFR_CCIF2_MD		61
> > +#define CLK_IFR_CCIF3_AP		62
> > +#define CLK_IFR_CCIF3_MD		63
> > +#define CLK_IFR_NR_CLK			64
> > +
> > +/* AUDIO */
> > +#define CLK_AUDIO_AFE			0
> > +#define CLK_AUDIO_22M			1
> > +#define CLK_AUDIO_APLL_TUNER		2
> > +#define CLK_AUDIO_ADC			3
> > +#define CLK_AUDIO_DAC			4
> > +#define CLK_AUDIO_DAC_PREDIS		5
> > +#define CLK_AUDIO_TML			6
> > +#define CLK_AUDIO_I2S1_BCLK		7
> > +#define CLK_AUDIO_I2S2_BCLK		8
> > +#define CLK_AUDIO_I2S3_BCLK		9
> > +#define CLK_AUDIO_I2S4_BCLK		10
> > +#define CLK_AUDIO_NR_CLK		11
> > +
> > +/* MIPI_RX_ANA_CSI0A */
> > +
> > +#define CLK_MIPI0A_CSR_CSI_EN_0A	0
> > +#define CLK_MIPI0A_NR_CLK		1
> > +
> > +/* MMSYS_CONFIG */
> > +
> > +#define CLK_MM_MDP_RDMA0		0
> > +#define CLK_MM_MDP_CCORR0		1
> > +#define CLK_MM_MDP_RSZ0			2
> > +#define CLK_MM_MDP_RSZ1			3
> > +#define CLK_MM_MDP_TDSHP0		4
> > +#define CLK_MM_MDP_WROT0		5
> > +#define CLK_MM_MDP_WDMA0		6
> > +#define CLK_MM_DISP_OVL0		7
> > +#define CLK_MM_DISP_OVL0_2L		8
> > +#define CLK_MM_DISP_RSZ0		9
> > +#define CLK_MM_DISP_RDMA0		10
> > +#define CLK_MM_DISP_WDMA0		11
> > +#define CLK_MM_DISP_COLOR0		12
> > +#define CLK_MM_DISP_CCORR0		13
> > +#define CLK_MM_DISP_AAL0		14
> > +#define CLK_MM_DISP_GAMMA0		15
> > +#define CLK_MM_DISP_DITHER0		16
> > +#define CLK_MM_DSI0			17
> > +#define CLK_MM_FAKE_ENG			18
> > +#define CLK_MM_SMI_COMMON		19
> > +#define CLK_MM_SMI_LARB0		20
> > +#define CLK_MM_SMI_COMM0		21
> > +#define CLK_MM_SMI_COMM1		22
> > +#define CLK_MM_CAM_MDP			23
> > +#define CLK_MM_SMI_IMG			24
> > +#define CLK_MM_SMI_CAM			25
> > +#define CLK_MM_IMG_DL_RELAY		26
> > +#define CLK_MM_IMG_DL_ASYNC_TOP		27
> > +#define CLK_MM_DIG_DSI			28
> > +#define CLK_MM_F26M_HRTWT		29
> > +#define CLK_MM_NR_CLK			30
> > +
> > +/* IMGSYS */
> > +
> > +#define CLK_IMG_LARB2			0
> > +#define CLK_IMG_DIP			1
> > +#define CLK_IMG_FDVT			2
> > +#define CLK_IMG_DPE			3
> > +#define CLK_IMG_RSC			4
> > +#define CLK_IMG_NR_CLK			5
> > +
> > +/* VENCSYS */
> > +
> > +#define CLK_VENC_SET0_LARB		0
> > +#define CLK_VENC_SET1_VENC		1
> > +#define CLK_VENC_SET2_JPGENC		2
> > +#define CLK_VENC_SET3_VDEC		3
> > +#define CLK_VENC_NR_CLK			4
> > +
> > +/* CAMSYS */
> > +
> > +#define CLK_CAM_LARB3			0
> > +#define CLK_CAM_DFP_VAD			1
> > +#define CLK_CAM				2
> > +#define CLK_CAMTG			3
> > +#define CLK_CAM_SENINF			4
> > +#define CLK_CAMSV0			5
> > +#define CLK_CAMSV1			6
> > +#define CLK_CAMSV2			7
> > +#define CLK_CAM_CCU			8
> > +#define CLK_CAM_NR_CLK			9
> > +
> > +#endif /* _DT_BINDINGS_CLK_MT6765_H */
> > 



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

* Re: [PATCH v5 04/11] soc: mediatek: add MT6765 scpsys support
  2018-07-17 13:00   ` Sean Wang
@ 2018-07-18  8:54     ` Mars Cheng
  0 siblings, 0 replies; 32+ messages in thread
From: Mars Cheng @ 2018-07-18  8:54 UTC (permalink / raw)
  To: Sean Wang
  Cc: Matthias Brugger, Rob Herring, Marc Zyngier, Ryder Lee,
	Stephen Boyd, CC Hwang, Loda Chou, linux-kernel, linux-mediatek,
	devicetree, wsd_upstream, linux-serial, linux-arm-kernel,
	linux-clk, Owen Chen

Hi Sean

On Tue, 2018-07-17 at 21:00 +0800, Sean Wang wrote:
> On Tue, 2018-07-17 at 16:52 +0800, Mars Cheng wrote:
> > This adds scpsys support for MT6765
> > 
> 
> it looks like 4/11 have to depend on 6/11 and 7/11 to get a full function on scpsys for MT6765.
> 
> you should keep dependency in order to submit these patches
> 

Got it, will reorder the sequence.

> > Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
> > Signed-off-by: Owen Chen <owen.chen@mediatek.com>
> > ---
> >  drivers/soc/mediatek/mtk-scpsys.c        |   88 ++++++++++++++++++++++++++++++
> >  include/dt-bindings/power/mt6765-power.h |   14 +++++
> >  2 files changed, 102 insertions(+)
> >  create mode 100644 include/dt-bindings/power/mt6765-power.h
> > 
> > diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
> > index 5b24bb4..4bb6c7a 100644
> > --- a/drivers/soc/mediatek/mtk-scpsys.c
> > +++ b/drivers/soc/mediatek/mtk-scpsys.c
> > @@ -23,6 +23,7 @@
> >  
> >  #include <dt-bindings/power/mt2701-power.h>
> >  #include <dt-bindings/power/mt2712-power.h>
> > +#include <dt-bindings/power/mt6765-power.h>
> >  #include <dt-bindings/power/mt6797-power.h>
> >  #include <dt-bindings/power/mt7622-power.h>
> >  #include <dt-bindings/power/mt7623a-power.h>
> > @@ -680,6 +681,79 @@ static void mtk_register_power_domains(struct platform_device *pdev,
> >  };
> >  
> >  /*
> > + * MT6765 power domain support
> > + */
> > +#define SPM_PWR_STATUS_MT6765			0x0180
> > +#define SPM_PWR_STATUS_2ND_MT6765		0x0184
> > +
> > +static const struct scp_domain_data scp_domain_data_mt6765[] = {
> > +	[MT6765_POWER_DOMAIN_VCODEC] = {
> > +		.name = "vcodec",
> > +		.sta_mask = BIT(26),
> > +		.ctl_offs = 0x300,
> > +		.sram_pdn_bits = GENMASK(8, 8),
> > +		.sram_pdn_ack_bits = GENMASK(12, 12),
> > +	},
> > +	[MT6765_POWER_DOMAIN_ISP] = {
> > +		.name = "isp",
> > +		.sta_mask = BIT(5),
> > +		.ctl_offs = 0x308,
> > +		.sram_pdn_bits = GENMASK(8, 8),
> > +		.sram_pdn_ack_bits = GENMASK(12, 12),
> > +	},
> > +	[MT6765_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),
> > +	},
> > +	[MT6765_POWER_DOMAIN_CONN] = {
> > +		.name = "conn",
> > +		.sta_mask = BIT(1),
> > +		.ctl_offs = 0x32C,
> > +		.sram_pdn_bits = 0,
> > +		.sram_pdn_ack_bits = 0,
> > +	},
> > +	[MT6765_POWER_DOMAIN_MFG_ASYNC] = {
> > +		.name = "mfg_async",
> > +		.sta_mask = BIT(23),
> > +		.ctl_offs = 0x334,
> > +		.sram_pdn_bits = 0,
> > +		.sram_pdn_ack_bits = 0,
> > +	},
> > +	[MT6765_POWER_DOMAIN_MFG] = {
> > +		.name = "mfg",
> > +		.sta_mask = BIT(4),
> > +		.ctl_offs = 0x338,
> > +		.sram_pdn_bits = GENMASK(8, 8),
> > +		.sram_pdn_ack_bits = GENMASK(12, 12),
> > +	},
> > +	[MT6765_POWER_DOMAIN_CAM] = {
> > +		.name = "cam",
> > +		.sta_mask = BIT(25),
> > +		.ctl_offs = 0x344,
> > +		.sram_pdn_bits = GENMASK(8, 9),
> > +		.sram_pdn_ack_bits = GENMASK(12, 13),
> > +	},
> > +	[MT6765_POWER_DOMAIN_MFG_CORE0] = {
> > +		.name = "mfg_core0",
> > +		.sta_mask = BIT(7),
> > +		.ctl_offs = 0x34C,
> > +		.sram_pdn_bits = GENMASK(8, 8),
> > +		.sram_pdn_ack_bits = GENMASK(12, 12),
> > +	},
> 
> Above power domains really don't require any clock controlled with
> clk_id before any access on them?
> 

Yes, already sync with Owen, they are lost. will add them.

Thanks.
> > +};
> > +
> > +static const struct scp_subdomain scp_subdomain_mt6765[] = {
> > +	{MT6765_POWER_DOMAIN_MM, MT6765_POWER_DOMAIN_CAM},
> > +	{MT6765_POWER_DOMAIN_MM, MT6765_POWER_DOMAIN_ISP},
> > +	{MT6765_POWER_DOMAIN_MM, MT6765_POWER_DOMAIN_VCODEC},
> > +	{MT6765_POWER_DOMAIN_MFG_ASYNC, MT6765_POWER_DOMAIN_MFG},
> > +	{MT6765_POWER_DOMAIN_MFG, MT6765_POWER_DOMAIN_MFG_CORE0},
> > +};
> > +
> > +/*
> >   * MT6797 power domain support
> >   */
> >  
> > @@ -962,6 +1036,17 @@ static void mtk_register_power_domains(struct platform_device *pdev,
> >  	.bus_prot_reg_update = false,
> >  };
> >  
> > +static const struct scp_soc_data mt6765_data = {
> > +	.domains = scp_domain_data_mt6765,
> > +	.num_domains = ARRAY_SIZE(scp_domain_data_mt6765),
> > +	.subdomains = scp_subdomain_mt6765,
> > +	.num_subdomains = ARRAY_SIZE(scp_subdomain_mt6765),
> > +	.regs = {
> > +		.pwr_sta_offs = SPM_PWR_STATUS_MT6765,
> > +		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6765,
> > +	},
> > +};
> > +
> >  static const struct scp_soc_data mt6797_data = {
> >  	.domains = scp_domain_data_mt6797,
> >  	.num_domains = ARRAY_SIZE(scp_domain_data_mt6797),
> > @@ -1018,6 +1103,9 @@ static void mtk_register_power_domains(struct platform_device *pdev,
> >  		.compatible = "mediatek,mt2712-scpsys",
> >  		.data = &mt2712_data,
> >  	}, {
> > +		.compatible = "mediatek,mt6765-scpsys",
> > +		.data = &mt6765_data,
> > +	}, {
> >  		.compatible = "mediatek,mt6797-scpsys",
> >  		.data = &mt6797_data,
> >  	}, {
> > diff --git a/include/dt-bindings/power/mt6765-power.h b/include/dt-bindings/power/mt6765-power.h
> > new file mode 100644
> > index 0000000..d347b4e
> > --- /dev/null
> > +++ b/include/dt-bindings/power/mt6765-power.h
> > @@ -0,0 +1,14 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#ifndef _DT_BINDINGS_POWER_MT6765_POWER_H
> > +#define _DT_BINDINGS_POWER_MT6765_POWER_H
> > +
> > +#define MT6765_POWER_DOMAIN_CONN		0
> > +#define MT6765_POWER_DOMAIN_MM			1
> > +#define MT6765_POWER_DOMAIN_MFG_ASYNC		2
> > +#define MT6765_POWER_DOMAIN_ISP			3
> > +#define MT6765_POWER_DOMAIN_MFG			4
> > +#define MT6765_POWER_DOMAIN_MFG_CORE0		5
> > +#define MT6765_POWER_DOMAIN_CAM			6
> > +#define MT6765_POWER_DOMAIN_VCODEC		7
> > +
> > +#endif /* _DT_BINDINGS_POWER_MT6765_POWER_H */
> 
> 



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

* Re: [PATCH v5 06/11] soc: mediatek: add new flow for mtcmos power.
  2018-07-17  8:52 ` [PATCH v5 06/11] soc: mediatek: add new flow for mtcmos power Mars Cheng
                     ` (3 preceding siblings ...)
  2018-07-17 20:36   ` kbuild test robot
@ 2018-07-18 14:50   ` Matthias Brugger
  2018-07-25  9:42     ` Owen Chen
  4 siblings, 1 reply; 32+ messages in thread
From: Matthias Brugger @ 2018-07-18 14:50 UTC (permalink / raw)
  To: Mars Cheng, Rob Herring, Marc Zyngier, Ryder Lee, Stephen Boyd,
	Sean Wang
  Cc: CC Hwang, Loda Chou, linux-kernel, linux-mediatek, devicetree,
	wsd_upstream, linux-serial, linux-arm-kernel, linux-clk,
	Owen Chen



On 17/07/18 10:52, Mars Cheng wrote:
> From: Owen Chen <owen.chen@mediatek.com>
> 
> MT6765 need multiple register and actions to setup bus
> protect.
> 1. turn on subsys CG before release bus protect to receive
>    ack.
> 2. turn off subsys CG after set bus protect and receive
>    ack.
> 3. bus protect need not only infracfg but other domain
>    register to setup. Therefore we add a set/clr APIs
>    with more customize arguments.
> 
> Signed-off-by: Owen Chen <owen.chen@mediatek.com>
> Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
> ---
>  drivers/soc/mediatek/Makefile           |    2 +-
>  drivers/soc/mediatek/mtk-infracfg.c     |  178 +++++++++++---
>  drivers/soc/mediatek/mtk-scpsys-ext.c   |  405 +++++++++++++++++++++++++++++++
>  drivers/soc/mediatek/mtk-scpsys.c       |  147 +++++++++--
>  include/linux/soc/mediatek/infracfg.h   |    9 +-
>  include/linux/soc/mediatek/scpsys-ext.h |   66 +++++
>  6 files changed, 745 insertions(+), 62 deletions(-)
>  create mode 100644 drivers/soc/mediatek/mtk-scpsys-ext.c
>  create mode 100644 include/linux/soc/mediatek/scpsys-ext.h
> 
> diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> index 12998b0..9dc6670 100644
> --- a/drivers/soc/mediatek/Makefile
> +++ b/drivers/soc/mediatek/Makefile
> @@ -1,3 +1,3 @@
> -obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
> +obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o mtk-scpsys-ext.o
>  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
>  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> diff --git a/drivers/soc/mediatek/mtk-infracfg.c b/drivers/soc/mediatek/mtk-infracfg.c
> index 958861c..11eadf8 100644
> --- a/drivers/soc/mediatek/mtk-infracfg.c
> +++ b/drivers/soc/mediatek/mtk-infracfg.c
> @@ -1,3 +1,4 @@
> +// SPDX-License-Identifier: GPL-2.0
>  /*
>   * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de>
>   *
> @@ -15,6 +16,7 @@
>  #include <linux/jiffies.h>
>  #include <linux/regmap.h>
>  #include <linux/soc/mediatek/infracfg.h>
> +#include <linux/soc/mediatek/scpsys-ext.h>
>  #include <asm/processor.h>
>  
>  #define MTK_POLL_DELAY_US   10
> @@ -26,62 +28,176 @@
>  #define INFRA_TOPAXI_PROTECTEN_CLR	0x0264
>  
>  /**
> - * mtk_infracfg_set_bus_protection - enable bus protection
> - * @regmap: The infracfg regmap
> - * @mask: The mask containing the protection bits to be enabled.
> - * @reg_update: The boolean flag determines to set the protection bits
> - *              by regmap_update_bits with enable register(PROTECTEN) or
> - *              by regmap_write with set register(PROTECTEN_SET).
> + * mtk_generic_set_cmd - enable bus protection with set register
> + * @regmap: The bus protect regmap
> + * @set_ofs: The set register offset to set corresponding bit to 1.
> + * @sta_ofs: The status register offset to show bus protect enable/disable.
> + * @mask: The mask containing the protection bits to be disabled.
>   *
>   * This function enables the bus protection bits for disabled power
>   * domains so that the system does not hang when some unit accesses the
>   * bus while in power down.
>   */
> -int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask,
> -		bool reg_update)
> +int mtk_generic_set_cmd(struct regmap *regmap, u32 set_ofs,
> +			u32 sta_ofs, u32 mask)
>  {
>  	u32 val;
>  	int ret;
>  
> -	if (reg_update)
> -		regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask,
> -				mask);
> -	else
> -		regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_SET, mask);
> +	regmap_write(regmap, set_ofs, mask);
>  
> -	ret = regmap_read_poll_timeout(infracfg, INFRA_TOPAXI_PROTECTSTA1,
> -				       val, (val & mask) == mask,
> -				       MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
> +	ret = regmap_read_poll_timeout(regmap, sta_ofs, val,
> +				       (val & mask) == mask,
> +				       MTK_POLL_DELAY_US,
> +				       MTK_POLL_TIMEOUT);
>  
>  	return ret;
>  }
>  
>  /**
> - * mtk_infracfg_clear_bus_protection - disable bus protection
> - * @regmap: The infracfg regmap
> + * mtk_generic_clr_cmd - disable bus protection  with clr register
> + * @regmap: The bus protect regmap
> + * @clr_ofs: The clr register offset to clear corresponding bit to 0.
> + * @sta_ofs: The status register offset to show bus protect enable/disable.
>   * @mask: The mask containing the protection bits to be disabled.
> - * @reg_update: The boolean flag determines to clear the protection bits
> - *              by regmap_update_bits with enable register(PROTECTEN) or
> - *              by regmap_write with clear register(PROTECTEN_CLR).
>   *
>   * This function disables the bus protection bits previously enabled with
> - * mtk_infracfg_set_bus_protection.
> + * mtk_set_bus_protection.
>   */
>  
> -int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask,
> -		bool reg_update)
> +int mtk_generic_clr_cmd(struct regmap *regmap, u32 clr_ofs,
> +			u32 sta_ofs, u32 mask)
>  {
>  	int ret;
>  	u32 val;
>  
> -	if (reg_update)
> -		regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, 0);
> -	else
> -		regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_CLR, mask);
> +	regmap_write(regmap, clr_ofs, mask);
>  
> -	ret = regmap_read_poll_timeout(infracfg, INFRA_TOPAXI_PROTECTSTA1,
> -				       val, !(val & mask),
> -				       MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
> +	ret = regmap_read_poll_timeout(regmap, sta_ofs, val,
> +				       !(val & mask),
> +				       MTK_POLL_DELAY_US,
> +				       MTK_POLL_TIMEOUT);
> +	return ret;
> +}
> +
> +/**
> + * mtk_generic_enable_cmd - enable bus protection with upd register
> + * @regmap: The bus protect regmap
> + * @upd_ofs: The update register offset to directly rewrite value to
> + *              corresponding bit.
> + * @sta_ofs: The status register offset to show bus protect enable/disable.
> + * @mask: The mask containing the protection bits to be disabled.
> + *
> + * This function enables the bus protection bits for disabled power
> + * domains so that the system does not hang when some unit accesses the
> + * bus while in power down.
> + */
> +int mtk_generic_enable_cmd(struct regmap *regmap, u32 upd_ofs,
> +			   u32 sta_ofs, u32 mask)
> +{
> +	u32 val;
> +	int ret;
> +
> +	regmap_update_bits(regmap, upd_ofs, mask, mask);
>  
> +	ret = regmap_read_poll_timeout(regmap, sta_ofs, val,
> +				       (val & mask) == mask,
> +				       MTK_POLL_DELAY_US,
> +				       MTK_POLL_TIMEOUT);
>  	return ret;
>  }
> +
> +/**
> + * mtk_generic_disable_cmd - disable bus protection with updd register
> + * @regmap: The bus protect regmap
> + * @upd_ofs: The update register offset to directly rewrite value to
> + *              corresponding bit.
> + * @sta_ofs: The status register offset to show bus protect enable/disable.
> + * @mask: The mask containing the protection bits to be disabled.
> + *
> + * This function disables the bus protection bits previously enabled with
> + * mtk_set_bus_protection.
> + */
> +
> +int mtk_generic_disable_cmd(struct regmap *regmap, u32 upd_ofs,
> +			    u32 sta_ofs, u32 mask)
> +{
> +	int ret;
> +	u32 val;
> +
> +	regmap_update_bits(regmap, upd_ofs, mask, 0);
> +
> +	ret = regmap_read_poll_timeout(regmap, sta_ofs,
> +				       val, !(val & mask),
> +				       MTK_POLL_DELAY_US,
> +				       MTK_POLL_TIMEOUT);
> +	return ret;
> +}
> +
> +/**
> + * mtk_set_bus_protection - enable bus protection
> + * @infracfg: The bus protect regmap, default use infracfg
> + * @mask: The mask containing the protection bits to be enabled.
> + *
> + * This function enables the bus protection bits for disabled power
> + * domains so that the system does not hang when some unit accesses the
> + * bus while in power down.
> + */
> +int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask)
> +{
> +	return mtk_generic_set_cmd(infracfg,
> +				   INFRA_TOPAXI_PROTECTEN_SET,
> +				   INFRA_TOPAXI_PROTECTSTA1,
> +				   mask);
> +}
> +
> +/**
> + * mtk_clear_bus_protection - disable bus protection
> + * @infracfg: The bus protect regmap, default use infracfg
> + * @mask: The mask containing the protection bits to be disabled.
> + *
> + * This function disables the bus protection bits previously enabled with
> + * mtk_set_bus_protection.
> + */
> +
> +int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask)
> +{
> +	return mtk_generic_clr_cmd(infracfg,
> +				   INFRA_TOPAXI_PROTECTEN_CLR,
> +				   INFRA_TOPAXI_PROTECTSTA1,
> +				   mask);
> +}
> +
> +/**
> + * mtk_infracfg_enable_bus_protection - enable bus protection
> + * @infracfg: The bus protect regmap, default use infracfg
> + * @mask: The mask containing the protection bits to be disabled.
> + *
> + * This function enables the bus protection bits for disabled power
> + * domains so that the system does not hang when some unit accesses the
> + * bus while in power down.
> + */
> +int mtk_infracfg_enable_bus_protection(struct regmap *infracfg, u32 mask)
> +{
> +	return mtk_generic_enable_cmd(infracfg,
> +				      INFRA_TOPAXI_PROTECTEN,
> +				      INFRA_TOPAXI_PROTECTSTA1,
> +				      mask);
> +}
> +
> +/**
> + * mtk_infracfg_disable_bus_protection - disable bus protection
> + * @infracfg: The bus protect regmap, default use infracfg
> + * @mask: The mask containing the protection bits to be disabled.
> + *
> + * This function disables the bus protection bits previously enabled with
> + * mtk_infracfg_set_bus_protection.
> + */
> +
> +int mtk_infracfg_disable_bus_protection(struct regmap *infracfg, u32 mask)
> +{
> +	return mtk_generic_disable_cmd(infracfg,
> +				       INFRA_TOPAXI_PROTECTEN,
> +				       INFRA_TOPAXI_PROTECTSTA1,
> +				       mask);
> +}
> diff --git a/drivers/soc/mediatek/mtk-scpsys-ext.c b/drivers/soc/mediatek/mtk-scpsys-ext.c
> new file mode 100644
> index 0000000..965e64d
> --- /dev/null
> +++ b/drivers/soc/mediatek/mtk-scpsys-ext.c
> @@ -0,0 +1,405 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2018 MediaTek Inc.
> + * Author: Owen Chen <owen.chen@mediatek.com>
> + */
> +#include <linux/clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/slab.h>
> +#include <linux/export.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/soc/mediatek/infracfg.h>
> +#include <linux/soc/mediatek/scpsys-ext.h>
> +
> +
> +#define MAX_CLKS		10
> +#define INFRA			"infracfg"
> +#define SMIC			"smi_comm"

Don't use defines for this. While at it I suppose it should be "smi_common"

> +
> +static LIST_HEAD(ext_clk_map_list);
> +static LIST_HEAD(ext_attr_map_list);
> +
> +static struct regmap *infracfg;
> +static struct regmap *smi_comm;
> +
> +enum regmap_type {
> +	IFR_TYPE,
> +	SMI_TYPE,
> +	MAX_REGMAP_TYPE,
> +};
> +
> +/**
> + * struct ext_reg_ctrl - set multiple register for bus protect
> + * @regmap: The bus protect regmap, 1: infracfg, 2: other master regmap
> + *                  such as SMI.
> + * @set_ofs: The set register offset to set corresponding bit to 1.
> + * @clr_ofs: The clr register offset to clear corresponding bit to 0.
> + * @sta_ofs: The status register offset to show bus protect enable/disable.
> + */
> +struct ext_reg_ctrl {
> +	enum regmap_type type;
> +	u32 set_ofs;
> +	u32 clr_ofs;
> +	u32 sta_ofs;
> +};
> +
> +/**
> + * struct ext_clk_ctrl - enable multiple clks for bus protect
> + * @clk: The clk need to enable before pwr on/bus protect.
> + * @scpd_n: The name present the scpsys domain where the clks belongs to.
> + * @clk_list: The list node linked to ext_clk_map_list.
> + */
> +struct ext_clk_ctrl {
> +	struct clk *clk;
> +	const char *scpd_n;
> +	struct list_head clk_list;
> +};
> +
> +struct bus_mask_ops {
> +	int	(*set)(struct regmap *regmap, u32 set_ofs,
> +		       u32 sta_ofs, u32 mask);
> +	int	(*release)(struct regmap *regmap, u32 clr_ofs,
> +			   u32 sta_ofs, u32 mask);
> +};
> +
> +static struct scpsys_ext_attr *__get_attr_parent(const char *parent_n)
> +{
> +	struct scpsys_ext_attr *attr;
> +
> +	if (!parent_n)
> +		return ERR_PTR(-EINVAL);
> +
> +	list_for_each_entry(attr, &ext_attr_map_list, attr_list) {
> +		if (attr->scpd_n && !strcmp(parent_n, attr->scpd_n))
> +			return attr;
> +	}
> +
> +	return ERR_PTR(-EINVAL);
> +}
> +
> +int bus_ctrl_set_release(struct scpsys_ext_attr *attr, bool set)
> +{
> +	int i;
> +	int ret = 0;
> +
> +	for (i = 0; i < MAX_STEP_NUM && attr->mask[i].mask; i++) {
> +		struct ext_reg_ctrl *rc = attr->mask[i].regs;
> +		struct regmap *regmap;
> +
> +		if (rc->type == IFR_TYPE)
> +			regmap = infracfg;
> +		else if (rc->type == SMI_TYPE)
> +			regmap = smi_comm;
> +		else
> +			return -EINVAL;
> +
> +		if (set)
> +			ret = attr->mask[i].ops->set(regmap,
> +						rc->set_ofs,
> +						rc->sta_ofs,
> +						attr->mask[i].mask);
> +		else
> +			ret = attr->mask[i].ops->release(regmap,
> +						rc->clr_ofs,
> +						rc->sta_ofs,
> +						attr->mask[i].mask);
> +	}
> +
> +	return ret;
> +}
> +
> +int bus_ctrl_set(struct scpsys_ext_attr *attr)
> +{
> +	return bus_ctrl_set_release(attr, CMD_ENABLE);
> +}
> +
> +int bus_ctrl_release(struct scpsys_ext_attr *attr)
> +{
> +	return bus_ctrl_set_release(attr, CMD_DISABLE);
> +}
> +
> +int bus_clk_enable_disable(struct scpsys_ext_attr *attr, bool enable)
> +{
> +	int i = 0;
> +	int ret = 0;
> +	struct ext_clk_ctrl *cc;
> +	struct clk *clk[MAX_CLKS];
> +
> +	list_for_each_entry(cc, &ext_clk_map_list, clk_list) {

Why can't we handle this in the same way as we do in mtk-scpsys.c ?

> +		if (!strcmp(cc->scpd_n, attr->scpd_n)) {
> +			if (enable)
> +				ret = clk_prepare_enable(cc->clk);
> +			else
> +				clk_disable_unprepare(cc->clk);
> +
> +			if (ret) {
> +				pr_err("Failed to  %s %s\n",
> +				       enable ? "enable" : "disable",
> +				       __clk_get_name(cc->clk));
> +				goto err;
> +			} else {
> +				clk[i] = cc->clk;
> +				i++;
> +			}
> +		}
> +	}
> +
> +	return ret;
> +
> +err:
> +	for (--i; i >= 0; i--)
> +		if (enable)
> +			clk_disable_unprepare(clk[i]);
> +		else
> +			clk_prepare_enable(clk[i]);
> +	return ret;
> +}
> +
> +int bus_clk_enable(struct scpsys_ext_attr *attr)
> +{
> +	struct scpsys_ext_attr *attr_p;
> +	int ret = 0;
> +
> +	attr_p = __get_attr_parent(attr->parent_n);

Why can't we implement this using the pg_genpd_add_subdomain approach?

> +	if (!IS_ERR(attr_p)) {
> +		ret = bus_clk_enable_disable(attr_p, CMD_ENABLE);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return bus_clk_enable_disable(attr, CMD_ENABLE);
> +}
> +
> +int bus_clk_disable(struct scpsys_ext_attr *attr)
> +{
> +	struct scpsys_ext_attr *attr_p;
> +	int ret = 0;
> +
> +	ret = bus_clk_enable_disable(attr, CMD_DISABLE);
> +	if (ret)
> +		return ret;
> +
> +	attr_p = __get_attr_parent(attr->parent_n);
> +	if (!IS_ERR(attr_p))
> +		ret = bus_clk_enable_disable(attr_p, CMD_DISABLE);

Same here.

> +
> +	return ret;
> +}
> +
> +const struct bus_mask_ops bus_mask_set_clr_ctrl = {
> +	.set = &mtk_generic_set_cmd,
> +	.release = &mtk_generic_clr_cmd,
> +};
> +
> +const struct bus_ext_ops ext_bus_ctrl = {
> +	.enable = &bus_ctrl_set,
> +	.disable = &bus_ctrl_release,
> +};
> +
> +const struct bus_ext_ops ext_cg_ctrl = {
> +	.enable = &bus_clk_enable,
> +	.disable = &bus_clk_disable,
> +};
> +
> +/*
> + * scpsys bus driver init
> + */
> +struct regmap *syscon_regmap_lookup_by_phandle_idx(struct device_node *np,
> +						   const char *property,
> +						   int index)
> +{
> +	struct device_node *syscon_np;
> +	struct regmap *regmap;
> +
> +	if (property)
> +		syscon_np = of_parse_phandle(np, property, index);
> +	else
> +		syscon_np = np;
> +
> +	if (!syscon_np)
> +		return ERR_PTR(-ENODEV);
> +
> +	regmap = syscon_node_to_regmap(syscon_np);
> +	of_node_put(syscon_np);
> +
> +	return regmap;
> +}

Why do we need this? It is never called...

> +
> +int scpsys_ext_regmap_init(struct platform_device *pdev)
> +{
> +	infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
> +						   INFRA);
> +	if (IS_ERR(infracfg)) {
> +		dev_err(&pdev->dev,
> +			"Cannot find bus infracfg controller: %ld\n",
> +			PTR_ERR(infracfg));
> +		return PTR_ERR(infracfg);
> +	}
> +
> +	smi_comm = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
> +						   SMIC);
> +	if (IS_ERR(smi_comm)) {
> +		dev_err(&pdev->dev,
> +			"Cannot find bus smi_comm controller: %ld\n",
> +			PTR_ERR(smi_comm));
> +		return PTR_ERR(smi_comm);
> +	}
> +
> +	return 0;
> +}
> +
> +static int add_clk_to_list(struct platform_device *pdev,
> +			   const char *name,
> +			   const char *scpd_n)
> +{
> +	struct clk *clk;
> +	struct ext_clk_ctrl *cc;
> +
> +	clk = devm_clk_get(&pdev->dev, name);
> +	if (IS_ERR(clk)) {
> +		dev_err(&pdev->dev, "Failed add clk %ld\n", PTR_ERR(clk));
> +		return PTR_ERR(clk);
> +	}
> +
> +	cc = kzalloc(sizeof(*cc), GFP_KERNEL);
> +	cc->clk = clk;
> +	cc->scpd_n = kstrdup(scpd_n, GFP_KERNEL);
> +
> +	list_add(&cc->clk_list, &ext_clk_map_list);
> +
> +	return 0;
> +}
> +
> +static int add_cg_to_list(struct platform_device *pdev)
> +{
> +	int i = 0;
> +
> +	struct device_node *node = pdev->dev.of_node;
> +
> +	if (!node) {
> +		dev_err(&pdev->dev, "Cannot find topcksys node: %ld\n",

Why topcksys? Shouldn't that be the node of scpsys?

> +			PTR_ERR(node));
> +		return PTR_ERR(node);
> +	}
> +
> +	do {
> +		const char *ck_name;
> +		char *temp_str;
> +		char *tok[2] = {NULL};
> +		int cg_idx = 0;
> +		int idx = 0;
> +		int ret = 0;
> +
> +		ret = of_property_read_string_index(node, "clock-names", i,
> +						    &ck_name);
> +		if (ret < 0)
> +			break;
> +
> +		temp_str = kmalloc_array(strlen(ck_name), sizeof(char),
> +					 GFP_KERNEL | __GFP_ZERO);
> +		memcpy(temp_str, ck_name, strlen(ck_name));
> +		temp_str[strlen(ck_name)] = '\0';

why don't you use kstrdup or similar?

> +		do {
> +			tok[idx] = strsep(&temp_str, "-");
> +			idx++;
> +		} while (temp_str);

You want to split the clock name like "mm-2" in
char **tok = {"mm", "2"};
correct? That can be done easier AFAIK:
tok[0] = strsep(&temp_str, "-");
tok[1] = &temp_str;

> +
> +		if (idx == 2) {

You don't add clocks like "mfg" and "mm". Why?

> +			if (kstrtouint(tok[1], 10, &cg_idx))

And then? You don't do anything with cg_idx...

> +				return -EINVAL;
> +
> +			if (add_clk_to_list(pdev, ck_name, tok[0]))

add_clk_to_list third parameter is the name of the scp domain, but you pass the
clock name here. I'm puzzled.

> +				return -EINVAL;
> +		}
> +		kfree(temp_str);
> +		i++;
> +	} while (1);
> +
> +	return 0;
> +}
> +
> +int scpsys_ext_clk_init(struct platform_device *pdev)
> +{
> +	int ret = 0;
> +
> +	ret = add_cg_to_list(pdev);
> +	if (ret)
> +		goto err;
> +
> +err:
> +	return ret;
> +}

Why do we need add_cg_to_list, it can be implemented directly here. Why is here
a goto to a return statement that will be executed anyway? Please go through the
code and check that it is clean before submitting.

> +
> +int scpsys_ext_attr_init(const struct scpsys_ext_data *data)
> +{
> +	int i, count = 0;
> +
> +	for (i = 0; i < data->num_attr; i++) {
> +		struct scpsys_ext_attr *node = data->attr + i;
> +
> +		if (!node)
> +			continue;
> +
> +		list_add(&node->attr_list, &ext_attr_map_list);
> +		count++;
> +	}
> +
> +	if (!count)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id of_scpsys_ext_match_tbl[] = {
> +	{
> +		/* sentinel */
> +	}
> +};
> +
> +struct scpsys_ext_data *scpsys_ext_init(struct platform_device *pdev)
> +{
> +	const struct of_device_id *match;
> +	struct scpsys_ext_data *data;
> +	int ret;
> +
> +	match = of_match_device(of_scpsys_ext_match_tbl, &pdev->dev);
> +
> +	if (!match) {
> +		dev_err(&pdev->dev, "no match\n");
> +		return ERR_CAST(match);
> +	}
> +
> +	data = (struct scpsys_ext_data *)match->data;
> +	if (IS_ERR(data)) {
> +		dev_err(&pdev->dev, "no match scpext data\n");
> +		return ERR_CAST(data);
> +	}
> +
> +	ret = scpsys_ext_attr_init(data);
> +	if (ret) {
> +		dev_err(&pdev->dev,
> +			"Failed to init bus attr: %d\n",
> +			ret);
> +		return ERR_PTR(ret);
> +	}
> +
> +	ret = scpsys_ext_regmap_init(pdev);
> +	if (ret) {
> +		dev_err(&pdev->dev,
> +			"Failed to init bus register: %d\n",
> +			ret);
> +		return ERR_PTR(ret);
> +	}
> +
> +	ret = scpsys_ext_clk_init(pdev);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Failed to init bus clks: %d\n",
> +			ret);
> +		return ERR_PTR(ret);
> +	}
> +
> +	return data;
> +}
> diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
> index 4bb6c7a..03df2d6 100644
> --- a/drivers/soc/mediatek/mtk-scpsys.c
> +++ b/drivers/soc/mediatek/mtk-scpsys.c
> @@ -1,3 +1,4 @@
> +// SPDX-License-Identifier: GPL-2.0
>  /*
>   * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de>
>   *
> @@ -20,6 +21,7 @@
>  #include <linux/pm_domain.h>
>  #include <linux/regulator/consumer.h>
>  #include <linux/soc/mediatek/infracfg.h>
> +#include <linux/soc/mediatek/scpsys-ext.h>
>  
>  #include <dt-bindings/power/mt2701-power.h>
>  #include <dt-bindings/power/mt2712-power.h>
> @@ -117,6 +119,15 @@ enum clk_id {
>  
>  #define MAX_CLKS	3
>  
> +/**
> + * struct scp_domain_data - scp domain data for power on/off flow
> + * @name: The domain name.
> + * @sta_mask: The mask for power on/off status bit.
> + * @ctl_offs: The offset for main power control register.
> + * @sram_pdn_bits: The mask for sram power control bits.
> + * @sram_pdn_ack_bits The mask for sram power control acked bits.
> + * @caps: The flag for active wake-up action.
> + */
>  struct scp_domain_data {
>  	const char *name;
>  	u32 sta_mask;
> @@ -150,7 +161,7 @@ struct scp {
>  	void __iomem *base;
>  	struct regmap *infracfg;
>  	struct scp_ctrl_reg ctrl_reg;
> -	bool bus_prot_reg_update;
> +	struct scpsys_ext_data *ext_data;
>  };
>  
>  struct scp_subdomain {
> @@ -164,7 +175,6 @@ struct scp_soc_data {
>  	const struct scp_subdomain *subdomains;
>  	int num_subdomains;
>  	const struct scp_ctrl_reg regs;
> -	bool bus_prot_reg_update;
>  };
>  
>  static int scpsys_domain_is_on(struct scp_domain *scpd)
> @@ -236,6 +246,31 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
>  	val |= PWR_RST_B_BIT;
>  	writel(val, ctl_addr);
>  
> +	if (!IS_ERR(scp->ext_data)) {
> +		struct scpsys_ext_attr *attr;
> +
> +		attr = scp->ext_data->get_attr(scpd->data->name);
> +		if (!IS_ERR(attr) && attr->cg_ops) {
> +			ret = attr->cg_ops->enable(attr);
> +			if (ret)
> +				goto err_ext_clk;
> +		}
> +	}
> +
> +	val &= ~scpd->data->sram_pdn_bits;
> +	writel(val, ctl_addr);
> +
> +	if (!IS_ERR(scp->ext_data)) {
> +		struct scpsys_ext_attr *attr;
> +
> +		attr = scp->ext_data->get_attr(scpd->data->name);
> +		if (!IS_ERR(attr) && attr->cg_ops) {
> +			ret = attr->cg_ops->enable(attr);
> +			if (ret)
> +				goto err_ext_clk;
> +		}
> +	}
> +
>  	val &= ~scpd->data->sram_pdn_bits;
>  	writel(val, ctl_addr);
>  
> @@ -247,25 +282,65 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
>  		 * applied here.
>  		 */
>  		usleep_range(12000, 12100);
> -
>  	} else {
>  		ret = readl_poll_timeout(ctl_addr, tmp, (tmp & pdn_ack) == 0,
>  					 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
>  		if (ret < 0)
> -			goto err_pwr_ack;
> +			goto err_sram;
>  	}
>  
>  	if (scpd->data->bus_prot_mask) {
>  		ret = mtk_infracfg_clear_bus_protection(scp->infracfg,
> -				scpd->data->bus_prot_mask,
> -				scp->bus_prot_reg_update);
> +				scpd->data->bus_prot_mask);
>  		if (ret)
> -			goto err_pwr_ack;
> +			goto err_sram;
> +	}
> +
> +	if (!IS_ERR(scp->ext_data)) {
> +		struct scpsys_ext_attr *attr;
> +
> +		attr = scp->ext_data->get_attr(scpd->data->name);
> +		if (!IS_ERR(attr) && attr->bus_ops) {
> +			ret = attr->bus_ops->disable(attr);
> +			if (ret)
> +				goto err_sram;
> +		}
> +	}
> +
> +	if (!IS_ERR(scp->ext_data)) {
> +		struct scpsys_ext_attr *attr;
> +
> +		attr = scp->ext_data->get_attr(scpd->data->name);
> +		if (!IS_ERR(attr) && attr->cg_ops) {
> +			ret = attr->cg_ops->disable(attr);
> +			if (ret)
> +				goto err_sram;
> +		}
>  	}
>  
>  	return 0;
>  
> +err_sram:
> +	val = readl(ctl_addr);
> +	val |= scpd->data->sram_pdn_bits;
> +	writel(val, ctl_addr);
> +err_ext_clk:
> +	val = readl(ctl_addr);
> +	val |= PWR_ISO_BIT;
> +	writel(val, ctl_addr);
> +
> +	val &= ~PWR_RST_B_BIT;
> +	writel(val, ctl_addr);
> +
> +	val |= PWR_CLK_DIS_BIT;
> +	writel(val, ctl_addr);
>  err_pwr_ack:
> +	val &= ~PWR_ON_BIT;
> +	writel(val, ctl_addr);
> +
> +	val &= ~PWR_ON_2ND_BIT;
> +	writel(val, ctl_addr);
> +
>  	for (i = MAX_CLKS - 1; i >= 0; i--) {
>  		if (scpd->clk[i])
>  			clk_disable_unprepare(scpd->clk[i]);
> @@ -274,8 +349,6 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
>  	if (scpd->supply)
>  		regulator_disable(scpd->supply);
>  
> -	dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name);
> -
>  	return ret;
>  }
>  
> @@ -289,14 +362,35 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
>  	int ret, tmp;
>  	int i;
>  
> +	if (!IS_ERR(scp->ext_data)) {
> +		struct scpsys_ext_attr *attr;
> +
> +		attr = scp->ext_data->get_attr(scpd->data->name);
> +		if (!IS_ERR(attr) && attr->cg_ops) {
> +			ret = attr->cg_ops->enable(attr);
> +			if (ret)
> +				goto out;
> +		}
> +	}
> +
>  	if (scpd->data->bus_prot_mask) {
>  		ret = mtk_infracfg_set_bus_protection(scp->infracfg,
> -				scpd->data->bus_prot_mask,
> -				scp->bus_prot_reg_update);
> +				scpd->data->bus_prot_mask);
>  		if (ret)
>  			goto out;
>  	}
>  
> +	if (!IS_ERR(scp->ext_data)) {
> +		struct scpsys_ext_attr *attr;
> +
> +		attr = scp->ext_data->get_attr(scpd->data->name);
> +		if (!IS_ERR(attr) && attr->bus_ops) {
> +			ret = attr->bus_ops->enable(attr);
> +			if (ret)
> +				goto out;
> +		}
> +	}
> +
>  	val = readl(ctl_addr);
>  	val |= scpd->data->sram_pdn_bits;
>  	writel(val, ctl_addr);
> @@ -307,6 +401,17 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
>  	if (ret < 0)
>  		goto out;
>  
> +	if (!IS_ERR(scp->ext_data)) {
> +		struct scpsys_ext_attr *attr;
> +
> +		attr = scp->ext_data->get_attr(scpd->data->name);
> +		if (!IS_ERR(attr) && attr->cg_ops) {
> +			ret = attr->cg_ops->disable(attr);
> +			if (ret)
> +				goto out;
> +		}
> +	}
> +
>  	val |= PWR_ISO_BIT;
>  	writel(val, ctl_addr);
>  
> @@ -337,8 +442,6 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
>  	return 0;
>  
>  out:
> -	dev_err(scp->dev, "Failed to power off domain %s\n", genpd->name);
> -
>  	return ret;
>  }
>  
> @@ -352,8 +455,7 @@ 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_ctrl_reg *scp_ctrl_reg,
> -			bool bus_prot_reg_update)
> +			const struct scp_ctrl_reg *scp_ctrl_reg)
>  {
>  	struct genpd_onecell_data *pd_data;
>  	struct resource *res;
> @@ -367,11 +469,10 @@ static struct scp *init_scp(struct platform_device *pdev,
>  
>  	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->bus_prot_reg_update = bus_prot_reg_update;
> -
>  	scp->dev = &pdev->dev;
>  
> +	scp->ext_data = scpsys_ext_init(pdev);
> +
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  	scp->base = devm_ioremap_resource(&pdev->dev, res);
>  	if (IS_ERR(scp->base))
> @@ -1021,7 +1122,6 @@ static void mtk_register_power_domains(struct platform_device *pdev,
>  		.pwr_sta_offs = SPM_PWR_STATUS,
>  		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
>  	},
> -	.bus_prot_reg_update = true,
>  };
>  
>  static const struct scp_soc_data mt2712_data = {
> @@ -1033,7 +1133,6 @@ static void mtk_register_power_domains(struct platform_device *pdev,
>  		.pwr_sta_offs = SPM_PWR_STATUS,
>  		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
>  	},
> -	.bus_prot_reg_update = false,
>  };
>  
>  static const struct scp_soc_data mt6765_data = {
> @@ -1056,7 +1155,6 @@ static void mtk_register_power_domains(struct platform_device *pdev,
>  		.pwr_sta_offs = SPM_PWR_STATUS_MT6797,
>  		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797
>  	},
> -	.bus_prot_reg_update = true,

I don't understand why you can delete this flag if you don't change anything
else in the data structure. For me this looks like you will break other chips.
Please explain.

I have the gut feeling that this can be implemented in the existing mtk-scpsys
driver. Can you please explain what are the points that this is not possible.
I want to understand the design decisions you made here, because they seem
really odd to me.

Best regards,
Matthias

>  };
>  
>  static const struct scp_soc_data mt7622_data = {
> @@ -1066,7 +1164,6 @@ static void mtk_register_power_domains(struct platform_device *pdev,
>  		.pwr_sta_offs = SPM_PWR_STATUS,
>  		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
>  	},
> -	.bus_prot_reg_update = true,
>  };
>  
>  static const struct scp_soc_data mt7623a_data = {
> @@ -1076,7 +1173,6 @@ static void mtk_register_power_domains(struct platform_device *pdev,
>  		.pwr_sta_offs = SPM_PWR_STATUS,
>  		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
>  	},
> -	.bus_prot_reg_update = true,
>  };
>  
>  static const struct scp_soc_data mt8173_data = {
> @@ -1088,7 +1184,6 @@ static void mtk_register_power_domains(struct platform_device *pdev,
>  		.pwr_sta_offs = SPM_PWR_STATUS,
>  		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
>  	},
> -	.bus_prot_reg_update = true,
>  };
>  
>  /*
> @@ -1132,8 +1227,8 @@ static int scpsys_probe(struct platform_device *pdev)
>  
>  	soc = of_device_get_match_data(&pdev->dev);
>  
> -	scp = init_scp(pdev, soc->domains, soc->num_domains, &soc->regs,
> -			soc->bus_prot_reg_update);
> +	scp = init_scp(pdev, soc->domains, soc->num_domains,
> +		       &soc->regs);
>  	if (IS_ERR(scp))
>  		return PTR_ERR(scp);
>  
> diff --git a/include/linux/soc/mediatek/infracfg.h b/include/linux/soc/mediatek/infracfg.h
> index fd25f01..bfad082 100644
> --- a/include/linux/soc/mediatek/infracfg.h
> +++ b/include/linux/soc/mediatek/infracfg.h
> @@ -32,8 +32,9 @@
>  #define MT7622_TOP_AXI_PROT_EN_WB		(BIT(2) | BIT(6) | \
>  						 BIT(7) | BIT(8))
>  
> -int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask,
> -		bool reg_update);
> -int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask,
> -		bool reg_update);
> +int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask);
> +int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask);
> +int mtk_infracfg_enable_bus_protection(struct regmap *infracfg, u32 mask);
> +int mtk_infracfg_disable_bus_protection(struct regmap *infracfg, u32 mask);
> +
>  #endif /* __SOC_MEDIATEK_INFRACFG_H */
> diff --git a/include/linux/soc/mediatek/scpsys-ext.h b/include/linux/soc/mediatek/scpsys-ext.h
> new file mode 100644
> index 0000000..99b5ff1
> --- /dev/null
> +++ b/include/linux/soc/mediatek/scpsys-ext.h
> @@ -0,0 +1,66 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef __SOC_MEDIATEK_SCPSYS_EXT_H
> +#define __SOC_MEDIATEK_SCPSYS_EXT_H
> +
> +#include <linux/platform_device.h>
> +
> +#define CMD_ENABLE	1
> +#define CMD_DISABLE	0
> +
> +#define MAX_STEP_NUM	4
> +
> +/**
> + * struct bus_mask - set mask and corresponding operation for bus protect
> + * @regs: The register set of bus register control, including set/clr/sta.
> + * @mask: The mask set for bus protect.
> + * @flag: The flag to idetify which operation we take for bus protect.
> + */
> +struct bus_mask {
> +	struct ext_reg_ctrl *regs;
> +	u32 mask;
> +	const struct bus_mask_ops *ops;
> +};
> +
> +/**
> + * struct scpsys_ext_attr - extended attribute for bus protect and further
> + *                                           operand.
> + *
> + * @scpd_n: The name present the scpsys domain where the clks belongs to.
> + * @mask: The mask set for bus protect.
> + * @bus_ops: The operation we take for bus protect.
> + * @cg_ops: The operation we take for cg on/off.
> + * @attr_list: The list node linked to ext_attr_map_list.
> + */
> +struct scpsys_ext_attr {
> +	const char *scpd_n;
> +	struct bus_mask mask[MAX_STEP_NUM];
> +	const char *parent_n;
> +	const struct bus_ext_ops *bus_ops;
> +	const struct bus_ext_ops *cg_ops;
> +
> +	struct list_head attr_list;
> +};
> +
> +struct scpsys_ext_data {
> +	struct scpsys_ext_attr *attr;
> +	u8 num_attr;
> +	struct scpsys_ext_attr * (*get_attr)(const char *scpd_n);
> +};
> +
> +struct bus_ext_ops {
> +	int	(*enable)(struct scpsys_ext_attr *attr);
> +	int	(*disable)(struct scpsys_ext_attr *attr);
> +};
> +
> +int mtk_generic_set_cmd(struct regmap *regmap, u32 set_ofs,
> +			u32 sta_ofs, u32 mask);
> +int mtk_generic_clr_cmd(struct regmap *regmap, u32 clr_ofs,
> +			u32 sta_ofs, u32 mask);
> +int mtk_generic_enable_cmd(struct regmap *regmap, u32 upd_ofs,
> +			   u32 sta_ofs, u32 mask);
> +int mtk_generic_disable_cmd(struct regmap *regmap, u32 upd_ofs,
> +			    u32 sta_ofs, u32 mask);
> +
> +struct scpsys_ext_data *scpsys_ext_init(struct platform_device *pdev);
> +
> +#endif /* __SOC_MEDIATEK_SCPSYS_EXT_H */
> 

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

* Re: [PATCH v5 09/11] clk: mediatek: add new clkmux register API
  2018-07-17  8:52 ` [PATCH v5 09/11] clk: mediatek: add new clkmux register API Mars Cheng
@ 2018-07-19  6:57   ` Sean Wang
  2018-08-13  9:09     ` Owen Chen
  0 siblings, 1 reply; 32+ messages in thread
From: Sean Wang @ 2018-07-19  6:57 UTC (permalink / raw)
  To: Mars Cheng
  Cc: Matthias Brugger, Rob Herring, Marc Zyngier, Ryder Lee,
	Stephen Boyd, CC Hwang, Loda Chou, linux-kernel, linux-mediatek,
	devicetree, wsd_upstream, linux-serial, linux-arm-kernel,
	linux-clk, Owen Chen

On Tue, 2018-07-17 at 16:52 +0800, Mars Cheng wrote:
> From: Owen Chen <owen.chen@mediatek.com>
> 
> MT6765 add "set/clr" register for each clkmux setting, and
> one update register to trigger value change. It is designed
> to prevent read-modify-write racing issue. The sw design
> need to add a new API to handle this hw change with a new
> mtk_clk_mux/mtk_clk_upd struct in new file "clk-mux"and
> clk-upd".
> 

I don't see any word mtk_clk_upd or clk-upd in the patch

and the patch needs to be split into more patches

> Signed-off-by: Owen Chen <owen.chen@mediatek.com>
> ---
>  drivers/clk/mediatek/Makefile  |    2 +-
>  drivers/clk/mediatek/clk-mtk.c |   41 +++++++
>  drivers/clk/mediatek/clk-mtk.h |   85 ++++++++++++---
>  drivers/clk/mediatek/clk-mux.c |  236 ++++++++++++++++++++++++++++++++++++++++
>  drivers/clk/mediatek/clk-mux.h |   38 +++++++
>  5 files changed, 388 insertions(+), 14 deletions(-)
>  create mode 100644 drivers/clk/mediatek/clk-mux.c
>  create mode 100644 drivers/clk/mediatek/clk-mux.h
> 
> diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
> index 844b55d..b97980d 100644
> --- a/drivers/clk/mediatek/Makefile
> +++ b/drivers/clk/mediatek/Makefile
> @@ -1,5 +1,5 @@
>  # SPDX-License-Identifier: GPL-2.0
> -obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o clk-cpumux.o reset.o
> +obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o clk-cpumux.o reset.o clk-mux.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
> diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
> index 9c0ae42..50becd0 100644
> --- a/drivers/clk/mediatek/clk-mtk.c
> +++ b/drivers/clk/mediatek/clk-mtk.c
> @@ -22,6 +22,7 @@
>  #include <linux/mfd/syscon.h>
>  
>  #include "clk-mtk.h"
> +#include "clk-mux.h"
>  #include "clk-gate.h"
>  
>  struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num)
> @@ -144,6 +145,46 @@ int mtk_clk_register_gates(struct device_node *node,
>  	return 0;
>  }
>  
> +int mtk_clk_register_muxes(const struct mtk_mux *muxes,
> +			   int num, struct device_node *node,
> +			   spinlock_t *lock,
> +			   struct clk_onecell_data *clk_data)
> +{
> +	struct regmap *regmap;
> +	struct clk *clk;
> +	int i;
> +
> +	if (!clk_data)
> +		return -ENOMEM;
> +

general register function is able to handle that there is no clk_data.
It looks like a optional, not a mandatory

> +	regmap = syscon_node_to_regmap(node);
> +	if (IS_ERR(regmap)) {
> +		pr_err("Cannot find regmap for %pOF: %ld\n", node,
> +		       PTR_ERR(regmap));
> +		return PTR_ERR(regmap);
> +	}
> +
> +	for (i = 0; i < num; i++) {
> +		const struct mtk_mux *mux = &muxes[i];
> +
> +		if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[mux->id]))
> +			continue;
> +

it seems not necessary to check clk data every time

and always use positive check is good to read

> +		clk = mtk_clk_register_mux(mux, regmap, lock);
> +
> +		if (IS_ERR(clk)) {
> +			pr_err("Failed to register clk %s: %ld\n",
> +			       mux->name, PTR_ERR(clk));
> +			continue;
> +		}
> +
> +		if (clk_data)
> +			clk_data->clks[mux->id] = clk;

don't alter any data from input, that is a surprise for users

> +	}
> +
> +	return 0;
> +}
> +
>  struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
>  		void __iomem *base, spinlock_t *lock)
>  {
> diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
> index 1882221..61693f6 100644
> --- a/drivers/clk/mediatek/clk-mtk.h
> +++ b/drivers/clk/mediatek/clk-mtk.h
> @@ -24,7 +24,9 @@
>  
>  #define MAX_MUX_GATE_BIT	31
>  #define INVALID_MUX_GATE_BIT	(MAX_MUX_GATE_BIT + 1)
> -
> +#define INVALID_OFS		-1
> +#define INVALID_SHFT		-1
> +#define INVALID_WIDTH		-1
>  #define MHZ (1000 * 1000)
>  
>  struct mtk_fixed_clk {
> @@ -84,10 +86,72 @@ struct mtk_composite {
>  	signed char num_parents;
>  };
>  
> +struct mtk_mux {
> +	int id;
> +	const char *name;
> +	const char * const *parent_names;
> +	unsigned int flags;
> +
> +	u32 mux_ofs;
> +	u32 set_ofs;
> +	u32 clr_ofs;
> +	u32 upd_ofs;
> +
> +	signed char mux_shift;
> +	signed char mux_width;
> +	signed char gate_shift;
> +	signed char upd_shift;
> +
> +	const struct clk_ops *ops;
> +
> +	signed char num_parents;
> +};
> +

you have created a mtk-mux.h, why is you don't move the newly create
struct in?

>  /*
>   * In case the rate change propagation to parent clocks is undesirable,
>   * this macro allows to specify the clock flags manually.
>   */
> +#define CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, _mux_set_ofs,\
> +			_mux_clr_ofs, _shift, _width, _gate,		\
> +			_upd_ofs, _upd, _flags, _ops) {			\
> +		.id = _id,						\
> +		.name = _name,						\
> +		.mux_ofs = _mux_ofs,					\
> +		.set_ofs = _mux_set_ofs,				\
> +		.clr_ofs = _mux_clr_ofs,				\
> +		.upd_ofs = _upd_ofs,					\
> +		.mux_shift = _shift,					\
> +		.mux_width = _width,					\
> +		.gate_shift = _gate,					\
> +		.upd_shift = _upd,					\
> +		.parent_names = _parents,				\
> +		.num_parents = ARRAY_SIZE(_parents),			\
> +		.flags = _flags,					\
> +		.ops = &_ops,						\
> +	}
> +
> +#define MUX_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, _mux_set_ofs,\
> +			_mux_clr_ofs, _shift, _width, _gate,		\
> +			_upd_ofs, _upd, _flags)			\
> +		CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs,	\
> +			_mux_set_ofs, _mux_clr_ofs, _shift, _width,	\
> +			_gate, _upd_ofs, _upd, _flags,			\
> +			mtk_mux_clr_set_upd_ops)
> +
> +#define MUX_CLR_SET_UPD(_id, _name, _parents, _mux_ofs, _mux_set_ofs,	\
> +			_mux_clr_ofs, _shift, _width, _gate,		\
> +			_upd_ofs, _upd)				\
> +		MUX_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs,	\
> +			_mux_set_ofs, _mux_clr_ofs, _shift, _width,	\
> +			_gate, _upd_ofs, _upd, CLK_SET_RATE_PARENT)
> +
> +#define MUX_UPD(_id, _name, _parents, _mux_ofs, _shift, _width, _gate,	\
> +			_upd_ofs, _upd)				\
> +		CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs,	\
> +			INVALID_OFS, INVALID_OFS, _shift, _width,	\
> +			_gate, _upd_ofs, _upd, CLK_SET_RATE_PARENT,	\
> +			mtk_mux_upd_ops)
> +
>  #define MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width,	\
>  			_gate, _flags) {				\
>  		.id = _id,						\
> @@ -111,18 +175,8 @@ struct mtk_composite {
>  	MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width,	\
>  		_gate, CLK_SET_RATE_PARENT)
>  
> -#define MUX(_id, _name, _parents, _reg, _shift, _width) {		\
> -		.id = _id,						\
> -		.name = _name,						\
> -		.mux_reg = _reg,					\
> -		.mux_shift = _shift,					\
> -		.mux_width = _width,					\
> -		.gate_shift = -1,					\
> -		.divider_shift = -1,					\
> -		.parent_names = _parents,				\
> -		.num_parents = ARRAY_SIZE(_parents),			\
> -		.flags = CLK_SET_RATE_PARENT,				\
> -	}

As Matthias always said that, you alter the common thing that is already
used by a lot of SoC.

You should have a dedicate patch to state why you need it, provide the
way you propose. and use another patches for migrating old SoC, finally
then add the patch for your own SoC.

Don't mix everything in a single patch. The patch can't become reusable
hard to read it, even hard to backport to the other SoC picking up
patches they are really wanting.

> +#define MUX(_id, _name, _parents, _reg, _shift, _width)		\
> +	MUX_GATE(_id, _name, _parents, _reg, _shift, _width, INVALID_SHFT)
>  
>  #define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg,	\
>  					_div_width, _div_shift) {	\
> @@ -138,6 +192,11 @@ struct mtk_composite {
>  		.flags = 0,						\
>  	}
>  
> +int mtk_clk_register_muxes(const struct mtk_mux *muxes,
> +			   int num, struct device_node *node,
> +			   spinlock_t *lock,
> +			   struct clk_onecell_data *clk_data);
> +

move to mtk-mux.h

>  struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
>  		void __iomem *base, spinlock_t *lock);
>  
> diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c
> new file mode 100644
> index 0000000..219181b
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-mux.c
> @@ -0,0 +1,236 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2018 MediaTek Inc.
> + * Author: Owen Chen <owen.chen@mediatek.com>
> + */
> +
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/slab.h>
> +
> +#include "clk-mtk.h"
> +#include "clk-mux.h"
> +
> +static inline struct mtk_clk_mux
> +	*to_mtk_clk_mux(struct clk_hw *hw)
> +{
> +	return container_of(hw, struct mtk_clk_mux, hw);
> +}
> +
> +static int mtk_mux_enable(struct clk_hw *hw)
> +{
> +	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
> +	u32 mask = BIT(mux->gate_shift);
> +	unsigned long flags = 0;
> +
> +	if (mux->lock)
> +		spin_lock_irqsave(mux->lock, flags);
> +

we can see many functions in kernel, similar to your need, they always
be defined as two versions. for example.

mtk_mux_enable refer to lock version

mtk_mux_enable_nolock for lock-free version

that makes less condition, more readable, and users don't care much
about what stuff is put inside  

> +	regmap_update_bits(mux->regmap, mux->mux_ofs, mask, 0);
> +
> +	if (mux->lock)
> +		spin_unlock_irqrestore(mux->lock, flags);
> +	return 0;
> +}
> +
> +static void mtk_mux_disable(struct clk_hw *hw)
> +{
> +	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
> +	u32 mask = BIT(mux->gate_shift);
> +	unsigned long flags = 0;
> +
> +	if (mux->lock)
> +		spin_lock_irqsave(mux->lock, flags);
> +

ditto

> +	regmap_update_bits(mux->regmap, mux->mux_ofs, mask, mask);
> +
> +	if (mux->lock)
> +		spin_unlock_irqrestore(mux->lock, flags);
> +}
> +
> +static int mtk_mux_enable_setclr(struct clk_hw *hw)
> +{
> +	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
> +	u32 val;
> +	unsigned long flags = 0;
> +
> +	if (mux->lock)
> +		spin_lock_irqsave(mux->lock, flags);
> +

ditto

> +	val = BIT(mux->gate_shift);
> +	regmap_write(mux->regmap, mux->mux_clr_ofs, val);
> +
> +	if (mux->lock)
> +		spin_unlock_irqrestore(mux->lock, flags);
> +	return 0;
> +}
> +
> +static void mtk_mux_disable_setclr(struct clk_hw *hw)
> +{
> +	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
> +	u32 val;
> +	unsigned long flags = 0;
> +
> +	if (mux->lock)
> +		spin_lock_irqsave(mux->lock, flags);
> +

ditto

> +	val = BIT(mux->gate_shift);
> +	regmap_write(mux->regmap, mux->mux_set_ofs, val);
> +
> +	if (mux->lock)
> +		spin_unlock_irqrestore(mux->lock, flags);
> +}
> +
> +static int mtk_mux_is_enabled(struct clk_hw *hw)
> +{
> +	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
> +	u32 val = 0;
> +
> +	if (mux->gate_shift < 0)
> +		return true;
> +

return value should be bool

> +	regmap_read(mux->regmap, mux->mux_ofs, &val);
> +
> +	return (val & BIT(mux->gate_shift)) == 0;
> +}
> +
> +static u8 mtk_mux_get_parent(struct clk_hw *hw)
> +{


return value should be int
> +	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
> +	int num_parents = clk_hw_get_num_parents(hw);
> +	u32 mask = GENMASK(mux->mux_width - 1, 0);
> +	u32 val;
> +
> +	regmap_read(mux->regmap, mux->mux_ofs, &val);
> +	val = (val >> mux->mux_shift) & mask;
> +
> +	if (val >= num_parents)
> +		return -EINVAL;
> +
> +	return val;
> +}
> +
> +static int mtk_mux_set_parent(struct clk_hw *hw, u8 index)
> +{
> +	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
> +	u32 mask = GENMASK(mux->mux_width - 1, 0);
> +	u32 val, orig;
> +	unsigned long flags = 0;
> +
> +	if (mux->lock)
> +		spin_lock_irqsave(mux->lock, flags);
> +

use lock-free-or-not funciton

> +	regmap_read(mux->regmap, mux->mux_ofs, &val);
> +	orig = val;
> +	val &= ~(mask << mux->mux_shift);
> +	val |= index << mux->mux_shift;
> +
> +	if (val != orig) {
> +		regmap_write(mux->regmap, mux->mux_ofs, val);
> +
> +		if (mux->upd_shift >= 0)
> +			regmap_write(mux->regmap, mux->upd_ofs,
> +				     BIT(mux->upd_shift));


why not use regmap_update_bits like function ?

> +	}
> +
> +	if (mux->lock)
> +		spin_unlock_irqrestore(mux->lock, flags);
> +
> +	return 0;
> +}
> +
> +static int mtk_mux_set_parent_setclr(struct clk_hw *hw, u8 index)
> +{
> +	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
> +	u32 mask = GENMASK(mux->mux_width - 1, 0);
> +	u32 val, orig;
> +	unsigned long flags = 0;
> +
> +	if (mux->lock)
> +		spin_lock_irqsave(mux->lock, flags);
> +

use lock-free-or-not funciton

> +	regmap_read(mux->regmap, mux->mux_ofs, &val);
> +	orig = val;
> +	val &= ~(mask << mux->mux_shift);
> +	val |= index << mux->mux_shift;
> +
> +	if (val != orig) {
> +		val = (mask << mux->mux_shift);
> +		regmap_write(mux->regmap, mux->mux_clr_ofs, val);
> +		val = (index << mux->mux_shift);
> +		regmap_write(mux->regmap, mux->mux_set_ofs, val);
> +

why not use regmap_update_bits like function ?
> +		if (mux->upd_shift >= 0)
> +			regmap_write(mux->regmap, mux->upd_ofs,
> +				     BIT(mux->upd_shift));
> +	}
> +
> +	if (mux->lock)
> +		spin_unlock_irqrestore(mux->lock, flags);
> +
> +	return 0;
> +}
> +
> +const struct clk_ops mtk_mux_upd_ops = {
> +	.enable = mtk_mux_enable,
> +	.disable = mtk_mux_disable,
> +	.is_enabled = mtk_mux_is_enabled,
> +	.get_parent = mtk_mux_get_parent,
> +	.set_parent = mtk_mux_set_parent,
> +	.determine_rate = NULL,

explicitly set as NULL can be removed
> +};
> +
> +const struct clk_ops mtk_mux_clr_set_upd_ops = {
> +	.enable = mtk_mux_enable_setclr,
> +	.disable = mtk_mux_disable_setclr,
> +	.is_enabled = mtk_mux_is_enabled,
> +	.get_parent = mtk_mux_get_parent,
> +	.set_parent = mtk_mux_set_parent_setclr,
> +	.determine_rate = NULL,

explicitly set as NULL can be removed
> +};
> +
> +struct clk *mtk_clk_register_mux(const struct mtk_mux *mux,
> +				 struct regmap *regmap,
> +				 spinlock_t *lock)
> +{
> +	struct clk *clk;
> +	struct clk_init_data init;
> +	struct mtk_clk_mux *mtk_mux = NULL;
> +	int ret;
> +
make declaration as reverse xmas tree

> +	mtk_mux = kzalloc(sizeof(*mtk_mux), GFP_KERNEL);
> +	if (!mtk_mux)
> +		return ERR_PTR(-ENOMEM);
> +
> +	init.name = mux->name;
> +	init.flags = (mux->flags) | CLK_SET_RATE_PARENT;
> +	init.parent_names = mux->parent_names;
> +	init.num_parents = mux->num_parents;
> +	init.ops = mux->ops;
> +
> +	mtk_mux->regmap = regmap;
> +	mtk_mux->name = mux->name;
> +	mtk_mux->mux_ofs = mux->mux_ofs;
> +	mtk_mux->mux_set_ofs = mux->set_ofs;
> +	mtk_mux->mux_clr_ofs = mux->clr_ofs;
> +	mtk_mux->upd_ofs = mux->upd_ofs;
> +	mtk_mux->mux_shift = mux->mux_shift;
> +	mtk_mux->mux_width = mux->mux_width;
> +	mtk_mux->gate_shift = mux->gate_shift;
> +	mtk_mux->upd_shift = mux->upd_shift;
> +
> +	mtk_mux->lock = lock;
> +	mtk_mux->hw.init = &init;
> +
> +	clk = clk_register(NULL, &mtk_mux->hw);
> +	if (IS_ERR(clk)) {
> +		ret = PTR_ERR(clk);


ret is superfluous

> +		goto err_out;
> +	}
> +
> +	return clk;
> +err_out:
> +	kfree(mtk_mux);
> +

I felt err path can be optimized

> +	return ERR_PTR(ret);
> +}
> diff --git a/drivers/clk/mediatek/clk-mux.h b/drivers/clk/mediatek/clk-mux.h
> new file mode 100644
> index 0000000..64f8e7c
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-mux.h
> @@ -0,0 +1,38 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2018 MediaTek Inc.
> + * Author: Owen Chen <owen.chen@mediatek.com>
> + */
> +
> +#ifndef __DRV_CLK_MUX_H
> +#define __DRV_CLK_MUX_H
> +
> +#include <linux/clk-provider.h>
> +
> +struct mtk_clk_mux {
> +	struct clk_hw hw;
> +	struct regmap *regmap;
> +
> +	const char *name;
> +
> +	int mux_set_ofs;
> +	int mux_clr_ofs;
> +	int mux_ofs;
> +	int upd_ofs;
> +
> +	s8 mux_shift;
> +	s8 mux_width;
> +	s8 gate_shift;
> +	s8 upd_shift;
> +
> +	spinlock_t *lock;
> +};
> +
> +extern const struct clk_ops mtk_mux_upd_ops;
> +extern const struct clk_ops mtk_mux_clr_set_upd_ops;
> +


extern  is superfluous

> +struct clk *mtk_clk_register_mux(const struct mtk_mux *mux,
> +				 struct regmap *regmap,
> +				 spinlock_t *lock);
> +
> +#endif /* __DRV_CLK_MUX_H */



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

* Re: [PATCH v5 01/11] dt-bindings: clock: mediatek: document clk bindings for Mediatek MT6765 SoC
  2018-07-17  8:52 ` [PATCH v5 01/11] dt-bindings: clock: mediatek: document clk bindings for Mediatek MT6765 SoC Mars Cheng
@ 2018-07-20 17:43   ` Rob Herring
  2018-08-13  9:12     ` Owen Chen
  0 siblings, 1 reply; 32+ messages in thread
From: Rob Herring @ 2018-07-20 17:43 UTC (permalink / raw)
  To: Mars Cheng
  Cc: Matthias Brugger, Marc Zyngier, Ryder Lee, Stephen Boyd,
	Sean Wang, CC Hwang, Loda Chou, linux-kernel, linux-mediatek,
	devicetree, wsd_upstream, linux-serial, linux-arm-kernel,
	linux-clk, Owen Chen

On Tue, Jul 17, 2018 at 04:52:22PM +0800, Mars Cheng wrote:
> This patch adds the binding documentation for apmixedsys, audsys, camsys,
> imgsys, infracfg, mipi0a, topckgen, vcodecsys
> 
> Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
> Signed-off-by: Owen Chen <owen.chen@mediatek.com>
> ---
>  .../bindings/arm/mediatek/mediatek,apmixedsys.txt  |    1 +
>  .../bindings/arm/mediatek/mediatek,audsys.txt      |    1 +
>  .../bindings/arm/mediatek/mediatek,camsys.txt      |   27 ++++++++++++++++++++
>  .../bindings/arm/mediatek/mediatek,imgsys.txt      |    1 +
>  .../bindings/arm/mediatek/mediatek,infracfg.txt    |    1 +
>  .../bindings/arm/mediatek/mediatek,mipi0a.txt      |   23 +++++++++++++++++
>  .../bindings/arm/mediatek/mediatek,mmsys.txt       |    1 +
>  .../bindings/arm/mediatek/mediatek,pericfg.txt     |    1 +
>  .../bindings/arm/mediatek/mediatek,topckgen.txt    |    1 +
>  .../bindings/arm/mediatek/mediatek,vcodecsys.txt   |   22 ++++++++++++++++
>  10 files changed, 79 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,camsys.txt
>  create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mipi0a.txt
>  create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,vcodecsys.txt
> 
> diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
> index b404d59..44eaeac 100644
> --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
> +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
> @@ -8,6 +8,7 @@ Required Properties:
>  - compatible: Should be one of:
>  	- "mediatek,mt2701-apmixedsys"
>  	- "mediatek,mt2712-apmixedsys", "syscon"
> +	- "mediatek,mt6765-apmixedsys", "syscon"
>  	- "mediatek,mt6797-apmixedsys"
>  	- "mediatek,mt7622-apmixedsys"
>  	- "mediatek,mt8135-apmixedsys"
> diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
> index 34a69ba..9a8672a 100644
> --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
> +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
> @@ -7,6 +7,7 @@ Required Properties:
>  
>  - compatible: Should be one of:
>  	- "mediatek,mt2701-audsys", "syscon"
> +	- "mediatek,mt6765-audsys", "syscon"
>  	- "mediatek,mt7622-audsys", "syscon"
>  - #clock-cells: Must be 1
>  
> diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,camsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,camsys.txt
> new file mode 100644
> index 0000000..dc75783
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,camsys.txt
> @@ -0,0 +1,27 @@
> +MediaTek CAMSYS controller
> +============================
> +
> +The MediaTek CAMSYS controller provides various clocks to the system.

Only clocks? If so, then this should be moved to bindings/clocks/.

> +
> +Required Properties:
> +
> +- compatible: Should be one of:
> +	- "mediatek,mt6765-camsys", "syscon"
> +- #clock-cells: Must be 1
> +
> +The AUDSYS controller uses the common clk binding from
> +Documentation/devicetree/bindings/clock/clock-bindings.txt
> +The available clocks are defined in dt-bindings/clock/mt*-clk.h.
> +
> +Required sub-nodes:
> +-------
> +For common binding part and usage, refer to
> +../sonud/mt2701-afe-pcm.txt.
> +
> +Example:
> +
> +camsys: camsys@1a000000  {

clock-controller@...

if the above answer is yes.

Same comments on the other docs.

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

* Re: [PATCH v5 02/11] dt-bindings: mediatek: Add smi dts binding for Mediatek MT6765 SoC
  2018-07-17  8:52 ` [PATCH v5 02/11] dt-bindings: mediatek: Add smi dts binding " Mars Cheng
@ 2018-07-20 17:44   ` Rob Herring
  0 siblings, 0 replies; 32+ messages in thread
From: Rob Herring @ 2018-07-20 17:44 UTC (permalink / raw)
  To: Mars Cheng
  Cc: Matthias Brugger, Marc Zyngier, Ryder Lee, Stephen Boyd,
	Sean Wang, CC Hwang, Loda Chou, linux-kernel, linux-mediatek,
	devicetree, wsd_upstream, linux-serial, linux-arm-kernel,
	linux-clk, Owen Chen

On Tue, Jul 17, 2018 at 04:52:23PM +0800, Mars Cheng wrote:
> This patch adds MT6765 smi binding document
> 
> Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
> Signed-off-by: Owen Chen <owen.chen@mediatek.com>
> ---
>  .../memory-controllers/mediatek,smi-common.txt     |    1 +
>  1 file changed, 1 insertion(+)

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

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

* Re: [PATCH v5 03/11] dt-bindings: mediatek: add MT6765 power dt-bindings
  2018-07-17  8:52 ` [PATCH v5 03/11] dt-bindings: mediatek: add MT6765 power dt-bindings Mars Cheng
@ 2018-07-20 17:45   ` Rob Herring
  0 siblings, 0 replies; 32+ messages in thread
From: Rob Herring @ 2018-07-20 17:45 UTC (permalink / raw)
  To: Mars Cheng
  Cc: Matthias Brugger, Marc Zyngier, Ryder Lee, Stephen Boyd,
	Sean Wang, CC Hwang, Loda Chou, linux-kernel, linux-mediatek,
	devicetree, wsd_upstream, linux-serial, linux-arm-kernel,
	linux-clk, Owen Chen

On Tue, Jul 17, 2018 at 04:52:24PM +0800, Mars Cheng wrote:
> This adds power dt-bindings for MT6765
> 
> Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
> Signed-off-by: Owen Chen <owen.chen@mediatek.com>
> ---
>  .../devicetree/bindings/soc/mediatek/scpsys.txt    |    6 ++++++
>  1 file changed, 6 insertions(+)

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

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

* Re: [PATCH v5 04/11] soc: mediatek: add MT6765 scpsys support
  2018-07-17  8:52 ` [PATCH v5 04/11] soc: mediatek: add MT6765 scpsys support Mars Cheng
  2018-07-17 13:00   ` Sean Wang
@ 2018-07-20 17:46   ` Rob Herring
  1 sibling, 0 replies; 32+ messages in thread
From: Rob Herring @ 2018-07-20 17:46 UTC (permalink / raw)
  To: Mars Cheng
  Cc: Matthias Brugger, Marc Zyngier, Ryder Lee, Stephen Boyd,
	Sean Wang, CC Hwang, Loda Chou, linux-kernel, linux-mediatek,
	devicetree, wsd_upstream, linux-serial, linux-arm-kernel,
	linux-clk, Owen Chen

On Tue, Jul 17, 2018 at 04:52:25PM +0800, Mars Cheng wrote:
> This adds scpsys support for MT6765
> 
> Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
> Signed-off-by: Owen Chen <owen.chen@mediatek.com>
> ---
>  drivers/soc/mediatek/mtk-scpsys.c        |   88 ++++++++++++++++++++++++++++++
>  include/dt-bindings/power/mt6765-power.h |   14 +++++

This file goes in the binding patch.

>  2 files changed, 102 insertions(+)
>  create mode 100644 include/dt-bindings/power/mt6765-power.h

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

* Re: [PATCH v5 06/11] soc: mediatek: add new flow for mtcmos power.
  2018-07-18 14:50   ` Matthias Brugger
@ 2018-07-25  9:42     ` Owen Chen
  0 siblings, 0 replies; 32+ messages in thread
From: Owen Chen @ 2018-07-25  9:42 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: Mars Cheng, Rob Herring, Marc Zyngier, Ryder Lee, Stephen Boyd,
	Sean Wang, CC Hwang, Loda Chou, linux-kernel, linux-mediatek,
	devicetree, wsd_upstream, linux-serial, linux-arm-kernel,
	linux-clk

Hi Matthias

On Wed, 2018-07-18 at 16:50 +0200, Matthias Brugger wrote:
> 
> On 17/07/18 10:52, Mars Cheng wrote:
> > From: Owen Chen <owen.chen@mediatek.com>
> > 
> > MT6765 need multiple register and actions to setup bus
> > protect.
> > 1. turn on subsys CG before release bus protect to receive
> >    ack.
> > 2. turn off subsys CG after set bus protect and receive
> >    ack.
> > 3. bus protect need not only infracfg but other domain
> >    register to setup. Therefore we add a set/clr APIs
> >    with more customize arguments.
> > 
> > Signed-off-by: Owen Chen <owen.chen@mediatek.com>
> > Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
> > ---
> >  drivers/soc/mediatek/Makefile           |    2 +-
> >  drivers/soc/mediatek/mtk-infracfg.c     |  178 +++++++++++---
> >  drivers/soc/mediatek/mtk-scpsys-ext.c   |  405 +++++++++++++++++++++++++++++++
> >  drivers/soc/mediatek/mtk-scpsys.c       |  147 +++++++++--
> >  include/linux/soc/mediatek/infracfg.h   |    9 +-
> >  include/linux/soc/mediatek/scpsys-ext.h |   66 +++++
> >  6 files changed, 745 insertions(+), 62 deletions(-)
> >  create mode 100644 drivers/soc/mediatek/mtk-scpsys-ext.c
> >  create mode 100644 include/linux/soc/mediatek/scpsys-ext.h
> > 
> > diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> > index 12998b0..9dc6670 100644
> > --- a/drivers/soc/mediatek/Makefile
> > +++ b/drivers/soc/mediatek/Makefile
> > @@ -1,3 +1,3 @@
> > -obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
> > +obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o mtk-scpsys-ext.o
> >  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
> >  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> > diff --git a/drivers/soc/mediatek/mtk-infracfg.c b/drivers/soc/mediatek/mtk-infracfg.c
> > index 958861c..11eadf8 100644
> > --- a/drivers/soc/mediatek/mtk-infracfg.c
> > +++ b/drivers/soc/mediatek/mtk-infracfg.c
> > @@ -1,3 +1,4 @@
> > +// SPDX-License-Identifier: GPL-2.0
> >  /*
> >   * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de>
> >   *
> > @@ -15,6 +16,7 @@
> >  #include <linux/jiffies.h>
> >  #include <linux/regmap.h>
> >  #include <linux/soc/mediatek/infracfg.h>
> > +#include <linux/soc/mediatek/scpsys-ext.h>
> >  #include <asm/processor.h>
> >  
> >  #define MTK_POLL_DELAY_US   10
> > @@ -26,62 +28,176 @@
> >  #define INFRA_TOPAXI_PROTECTEN_CLR	0x0264
> >  
> >  /**
> > - * mtk_infracfg_set_bus_protection - enable bus protection
> > - * @regmap: The infracfg regmap
> > - * @mask: The mask containing the protection bits to be enabled.
> > - * @reg_update: The boolean flag determines to set the protection bits
> > - *              by regmap_update_bits with enable register(PROTECTEN) or
> > - *              by regmap_write with set register(PROTECTEN_SET).
> > + * mtk_generic_set_cmd - enable bus protection with set register
> > + * @regmap: The bus protect regmap
> > + * @set_ofs: The set register offset to set corresponding bit to 1.
> > + * @sta_ofs: The status register offset to show bus protect enable/disable.
> > + * @mask: The mask containing the protection bits to be disabled.
> >   *
> >   * This function enables the bus protection bits for disabled power
> >   * domains so that the system does not hang when some unit accesses the
> >   * bus while in power down.
> >   */
> > -int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask,
> > -		bool reg_update)
> > +int mtk_generic_set_cmd(struct regmap *regmap, u32 set_ofs,
> > +			u32 sta_ofs, u32 mask)
> >  {
> >  	u32 val;
> >  	int ret;
> >  
> > -	if (reg_update)
> > -		regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask,
> > -				mask);
> > -	else
> > -		regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_SET, mask);
> > +	regmap_write(regmap, set_ofs, mask);
> >  
> > -	ret = regmap_read_poll_timeout(infracfg, INFRA_TOPAXI_PROTECTSTA1,
> > -				       val, (val & mask) == mask,
> > -				       MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
> > +	ret = regmap_read_poll_timeout(regmap, sta_ofs, val,
> > +				       (val & mask) == mask,
> > +				       MTK_POLL_DELAY_US,
> > +				       MTK_POLL_TIMEOUT);
> >  
> >  	return ret;
> >  }
> >  
> >  /**
> > - * mtk_infracfg_clear_bus_protection - disable bus protection
> > - * @regmap: The infracfg regmap
> > + * mtk_generic_clr_cmd - disable bus protection  with clr register
> > + * @regmap: The bus protect regmap
> > + * @clr_ofs: The clr register offset to clear corresponding bit to 0.
> > + * @sta_ofs: The status register offset to show bus protect enable/disable.
> >   * @mask: The mask containing the protection bits to be disabled.
> > - * @reg_update: The boolean flag determines to clear the protection bits
> > - *              by regmap_update_bits with enable register(PROTECTEN) or
> > - *              by regmap_write with clear register(PROTECTEN_CLR).
> >   *
> >   * This function disables the bus protection bits previously enabled with
> > - * mtk_infracfg_set_bus_protection.
> > + * mtk_set_bus_protection.
> >   */
> >  
> > -int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask,
> > -		bool reg_update)
> > +int mtk_generic_clr_cmd(struct regmap *regmap, u32 clr_ofs,
> > +			u32 sta_ofs, u32 mask)
> >  {
> >  	int ret;
> >  	u32 val;
> >  
> > -	if (reg_update)
> > -		regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, 0);
> > -	else
> > -		regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_CLR, mask);
> > +	regmap_write(regmap, clr_ofs, mask);
> >  
> > -	ret = regmap_read_poll_timeout(infracfg, INFRA_TOPAXI_PROTECTSTA1,
> > -				       val, !(val & mask),
> > -				       MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
> > +	ret = regmap_read_poll_timeout(regmap, sta_ofs, val,
> > +				       !(val & mask),
> > +				       MTK_POLL_DELAY_US,
> > +				       MTK_POLL_TIMEOUT);
> > +	return ret;
> > +}
> > +
> > +/**
> > + * mtk_generic_enable_cmd - enable bus protection with upd register
> > + * @regmap: The bus protect regmap
> > + * @upd_ofs: The update register offset to directly rewrite value to
> > + *              corresponding bit.
> > + * @sta_ofs: The status register offset to show bus protect enable/disable.
> > + * @mask: The mask containing the protection bits to be disabled.
> > + *
> > + * This function enables the bus protection bits for disabled power
> > + * domains so that the system does not hang when some unit accesses the
> > + * bus while in power down.
> > + */
> > +int mtk_generic_enable_cmd(struct regmap *regmap, u32 upd_ofs,
> > +			   u32 sta_ofs, u32 mask)
> > +{
> > +	u32 val;
> > +	int ret;
> > +
> > +	regmap_update_bits(regmap, upd_ofs, mask, mask);
> >  
> > +	ret = regmap_read_poll_timeout(regmap, sta_ofs, val,
> > +				       (val & mask) == mask,
> > +				       MTK_POLL_DELAY_US,
> > +				       MTK_POLL_TIMEOUT);
> >  	return ret;
> >  }
> > +
> > +/**
> > + * mtk_generic_disable_cmd - disable bus protection with updd register
> > + * @regmap: The bus protect regmap
> > + * @upd_ofs: The update register offset to directly rewrite value to
> > + *              corresponding bit.
> > + * @sta_ofs: The status register offset to show bus protect enable/disable.
> > + * @mask: The mask containing the protection bits to be disabled.
> > + *
> > + * This function disables the bus protection bits previously enabled with
> > + * mtk_set_bus_protection.
> > + */
> > +
> > +int mtk_generic_disable_cmd(struct regmap *regmap, u32 upd_ofs,
> > +			    u32 sta_ofs, u32 mask)
> > +{
> > +	int ret;
> > +	u32 val;
> > +
> > +	regmap_update_bits(regmap, upd_ofs, mask, 0);
> > +
> > +	ret = regmap_read_poll_timeout(regmap, sta_ofs,
> > +				       val, !(val & mask),
> > +				       MTK_POLL_DELAY_US,
> > +				       MTK_POLL_TIMEOUT);
> > +	return ret;
> > +}
> > +
> > +/**
> > + * mtk_set_bus_protection - enable bus protection
> > + * @infracfg: The bus protect regmap, default use infracfg
> > + * @mask: The mask containing the protection bits to be enabled.
> > + *
> > + * This function enables the bus protection bits for disabled power
> > + * domains so that the system does not hang when some unit accesses the
> > + * bus while in power down.
> > + */
> > +int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask)
> > +{
> > +	return mtk_generic_set_cmd(infracfg,
> > +				   INFRA_TOPAXI_PROTECTEN_SET,
> > +				   INFRA_TOPAXI_PROTECTSTA1,
> > +				   mask);
> > +}
> > +
> > +/**
> > + * mtk_clear_bus_protection - disable bus protection
> > + * @infracfg: The bus protect regmap, default use infracfg
> > + * @mask: The mask containing the protection bits to be disabled.
> > + *
> > + * This function disables the bus protection bits previously enabled with
> > + * mtk_set_bus_protection.
> > + */
> > +
> > +int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask)
> > +{
> > +	return mtk_generic_clr_cmd(infracfg,
> > +				   INFRA_TOPAXI_PROTECTEN_CLR,
> > +				   INFRA_TOPAXI_PROTECTSTA1,
> > +				   mask);
> > +}
> > +
> > +/**
> > + * mtk_infracfg_enable_bus_protection - enable bus protection
> > + * @infracfg: The bus protect regmap, default use infracfg
> > + * @mask: The mask containing the protection bits to be disabled.
> > + *
> > + * This function enables the bus protection bits for disabled power
> > + * domains so that the system does not hang when some unit accesses the
> > + * bus while in power down.
> > + */
> > +int mtk_infracfg_enable_bus_protection(struct regmap *infracfg, u32 mask)
> > +{
> > +	return mtk_generic_enable_cmd(infracfg,
> > +				      INFRA_TOPAXI_PROTECTEN,
> > +				      INFRA_TOPAXI_PROTECTSTA1,
> > +				      mask);
> > +}
> > +
> > +/**
> > + * mtk_infracfg_disable_bus_protection - disable bus protection
> > + * @infracfg: The bus protect regmap, default use infracfg
> > + * @mask: The mask containing the protection bits to be disabled.
> > + *
> > + * This function disables the bus protection bits previously enabled with
> > + * mtk_infracfg_set_bus_protection.
> > + */
> > +
> > +int mtk_infracfg_disable_bus_protection(struct regmap *infracfg, u32 mask)
> > +{
> > +	return mtk_generic_disable_cmd(infracfg,
> > +				       INFRA_TOPAXI_PROTECTEN,
> > +				       INFRA_TOPAXI_PROTECTSTA1,
> > +				       mask);
> > +}
> > diff --git a/drivers/soc/mediatek/mtk-scpsys-ext.c b/drivers/soc/mediatek/mtk-scpsys-ext.c
> > new file mode 100644
> > index 0000000..965e64d
> > --- /dev/null
> > +++ b/drivers/soc/mediatek/mtk-scpsys-ext.c
> > @@ -0,0 +1,405 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2018 MediaTek Inc.
> > + * Author: Owen Chen <owen.chen@mediatek.com>
> > + */
> > +#include <linux/clk.h>
> > +#include <linux/clk-provider.h>
> > +#include <linux/slab.h>
> > +#include <linux/export.h>
> > +#include <linux/mfd/syscon.h>
> > +#include <linux/of_device.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/regmap.h>
> > +#include <linux/soc/mediatek/infracfg.h>
> > +#include <linux/soc/mediatek/scpsys-ext.h>
> > +
> > +
> > +#define MAX_CLKS		10
> > +#define INFRA			"infracfg"
> > +#define SMIC			"smi_comm"
> 
> Don't use defines for this. While at it I suppose it should be "smi_common"

OK. I will fix it.

> 
> > +
> > +static LIST_HEAD(ext_clk_map_list);
> > +static LIST_HEAD(ext_attr_map_list);
> > +
> > +static struct regmap *infracfg;
> > +static struct regmap *smi_comm;
> > +
> > +enum regmap_type {
> > +	IFR_TYPE,
> > +	SMI_TYPE,
> > +	MAX_REGMAP_TYPE,
> > +};
> > +
> > +/**
> > + * struct ext_reg_ctrl - set multiple register for bus protect
> > + * @regmap: The bus protect regmap, 1: infracfg, 2: other master regmap
> > + *                  such as SMI.
> > + * @set_ofs: The set register offset to set corresponding bit to 1.
> > + * @clr_ofs: The clr register offset to clear corresponding bit to 0.
> > + * @sta_ofs: The status register offset to show bus protect enable/disable.
> > + */
> > +struct ext_reg_ctrl {
> > +	enum regmap_type type;
> > +	u32 set_ofs;
> > +	u32 clr_ofs;
> > +	u32 sta_ofs;
> > +};
> > +
> > +/**
> > + * struct ext_clk_ctrl - enable multiple clks for bus protect
> > + * @clk: The clk need to enable before pwr on/bus protect.
> > + * @scpd_n: The name present the scpsys domain where the clks belongs to.
> > + * @clk_list: The list node linked to ext_clk_map_list.
> > + */
> > +struct ext_clk_ctrl {
> > +	struct clk *clk;
> > +	const char *scpd_n;
> > +	struct list_head clk_list;
> > +};
> > +
> > +struct bus_mask_ops {
> > +	int	(*set)(struct regmap *regmap, u32 set_ofs,
> > +		       u32 sta_ofs, u32 mask);
> > +	int	(*release)(struct regmap *regmap, u32 clr_ofs,
> > +			   u32 sta_ofs, u32 mask);
> > +};
> > +
> > +static struct scpsys_ext_attr *__get_attr_parent(const char *parent_n)
> > +{
> > +	struct scpsys_ext_attr *attr;
> > +
> > +	if (!parent_n)
> > +		return ERR_PTR(-EINVAL);
> > +
> > +	list_for_each_entry(attr, &ext_attr_map_list, attr_list) {
> > +		if (attr->scpd_n && !strcmp(parent_n, attr->scpd_n))
> > +			return attr;
> > +	}
> > +
> > +	return ERR_PTR(-EINVAL);
> > +}
> > +
> > +int bus_ctrl_set_release(struct scpsys_ext_attr *attr, bool set)
> > +{
> > +	int i;
> > +	int ret = 0;
> > +
> > +	for (i = 0; i < MAX_STEP_NUM && attr->mask[i].mask; i++) {
> > +		struct ext_reg_ctrl *rc = attr->mask[i].regs;
> > +		struct regmap *regmap;
> > +
> > +		if (rc->type == IFR_TYPE)
> > +			regmap = infracfg;
> > +		else if (rc->type == SMI_TYPE)
> > +			regmap = smi_comm;
> > +		else
> > +			return -EINVAL;
> > +
> > +		if (set)
> > +			ret = attr->mask[i].ops->set(regmap,
> > +						rc->set_ofs,
> > +						rc->sta_ofs,
> > +						attr->mask[i].mask);
> > +		else
> > +			ret = attr->mask[i].ops->release(regmap,
> > +						rc->clr_ofs,
> > +						rc->sta_ofs,
> > +						attr->mask[i].mask);
> > +	}
> > +
> > +	return ret;
> > +}
> > +
> > +int bus_ctrl_set(struct scpsys_ext_attr *attr)
> > +{
> > +	return bus_ctrl_set_release(attr, CMD_ENABLE);
> > +}
> > +
> > +int bus_ctrl_release(struct scpsys_ext_attr *attr)
> > +{
> > +	return bus_ctrl_set_release(attr, CMD_DISABLE);
> > +}
> > +
> > +int bus_clk_enable_disable(struct scpsys_ext_attr *attr, bool enable)
> > +{
> > +	int i = 0;
> > +	int ret = 0;
> > +	struct ext_clk_ctrl *cc;
> > +	struct clk *clk[MAX_CLKS];
> > +
> > +	list_for_each_entry(cc, &ext_clk_map_list, clk_list) {
> 
> Why can't we handle this in the same way as we do in mtk-scpsys.c ?


We originally thought it would be better to put all the additional flow
at new created file, but after consider the readability of code flow, we
would put this cg operation back to mtk_scpsys.c.

> 
> > +		if (!strcmp(cc->scpd_n, attr->scpd_n)) {
> > +			if (enable)
> > +				ret = clk_prepare_enable(cc->clk);
> > +			else
> > +				clk_disable_unprepare(cc->clk);
> > +
> > +			if (ret) {
> > +				pr_err("Failed to  %s %s\n",
> > +				       enable ? "enable" : "disable",
> > +				       __clk_get_name(cc->clk));
> > +				goto err;
> > +			} else {
> > +				clk[i] = cc->clk;
> > +				i++;
> > +			}
> > +		}
> > +	}
> > +
> > +	return ret;
> > +
> > +err:
> > +	for (--i; i >= 0; i--)
> > +		if (enable)
> > +			clk_disable_unprepare(clk[i]);
> > +		else
> > +			clk_prepare_enable(clk[i]);
> > +	return ret;
> > +}
> > +
> > +int bus_clk_enable(struct scpsys_ext_attr *attr)
> > +{
> > +	struct scpsys_ext_attr *attr_p;
> > +	int ret = 0;
> > +
> > +	attr_p = __get_attr_parent(attr->parent_n);
> 
> Why can't we implement this using the pg_genpd_add_subdomain approach?

OK, we will follow it.

> 
> > +	if (!IS_ERR(attr_p)) {
> > +		ret = bus_clk_enable_disable(attr_p, CMD_ENABLE);
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> > +	return bus_clk_enable_disable(attr, CMD_ENABLE);
> > +}
> > +
> > +int bus_clk_disable(struct scpsys_ext_attr *attr)
> > +{
> > +	struct scpsys_ext_attr *attr_p;
> > +	int ret = 0;
> > +
> > +	ret = bus_clk_enable_disable(attr, CMD_DISABLE);
> > +	if (ret)
> > +		return ret;
> > +
> > +	attr_p = __get_attr_parent(attr->parent_n);
> > +	if (!IS_ERR(attr_p))
> > +		ret = bus_clk_enable_disable(attr_p, CMD_DISABLE);
> 
> Same here.
> 
> > +
> > +	return ret;
> > +}
> > +
> > +const struct bus_mask_ops bus_mask_set_clr_ctrl = {
> > +	.set = &mtk_generic_set_cmd,
> > +	.release = &mtk_generic_clr_cmd,
> > +};
> > +
> > +const struct bus_ext_ops ext_bus_ctrl = {
> > +	.enable = &bus_ctrl_set,
> > +	.disable = &bus_ctrl_release,
> > +};
> > +
> > +const struct bus_ext_ops ext_cg_ctrl = {
> > +	.enable = &bus_clk_enable,
> > +	.disable = &bus_clk_disable,
> > +};
> > +
> > +/*
> > + * scpsys bus driver init
> > + */
> > +struct regmap *syscon_regmap_lookup_by_phandle_idx(struct device_node *np,
> > +						   const char *property,
> > +						   int index)
> > +{
> > +	struct device_node *syscon_np;
> > +	struct regmap *regmap;
> > +
> > +	if (property)
> > +		syscon_np = of_parse_phandle(np, property, index);
> > +	else
> > +		syscon_np = np;
> > +
> > +	if (!syscon_np)
> > +		return ERR_PTR(-ENODEV);
> > +
> > +	regmap = syscon_node_to_regmap(syscon_np);
> > +	of_node_put(syscon_np);
> > +
> > +	return regmap;
> > +}
> 
> Why do we need this? It is never called...

Sorry, Forgot to delete it.

> 
> > +
> > +int scpsys_ext_regmap_init(struct platform_device *pdev)
> > +{
> > +	infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
> > +						   INFRA);
> > +	if (IS_ERR(infracfg)) {
> > +		dev_err(&pdev->dev,
> > +			"Cannot find bus infracfg controller: %ld\n",
> > +			PTR_ERR(infracfg));
> > +		return PTR_ERR(infracfg);
> > +	}
> > +
> > +	smi_comm = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
> > +						   SMIC);
> > +	if (IS_ERR(smi_comm)) {
> > +		dev_err(&pdev->dev,
> > +			"Cannot find bus smi_comm controller: %ld\n",
> > +			PTR_ERR(smi_comm));
> > +		return PTR_ERR(smi_comm);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int add_clk_to_list(struct platform_device *pdev,
> > +			   const char *name,
> > +			   const char *scpd_n)
> > +{
> > +	struct clk *clk;
> > +	struct ext_clk_ctrl *cc;
> > +
> > +	clk = devm_clk_get(&pdev->dev, name);
> > +	if (IS_ERR(clk)) {
> > +		dev_err(&pdev->dev, "Failed add clk %ld\n", PTR_ERR(clk));
> > +		return PTR_ERR(clk);
> > +	}
> > +
> > +	cc = kzalloc(sizeof(*cc), GFP_KERNEL);
> > +	cc->clk = clk;
> > +	cc->scpd_n = kstrdup(scpd_n, GFP_KERNEL);
> > +
> > +	list_add(&cc->clk_list, &ext_clk_map_list);
> > +
> > +	return 0;
> > +}
> > +
> > +static int add_cg_to_list(struct platform_device *pdev)
> > +{
> > +	int i = 0;
> > +
> > +	struct device_node *node = pdev->dev.of_node;
> > +
> > +	if (!node) {
> > +		dev_err(&pdev->dev, "Cannot find topcksys node: %ld\n",
> 
> Why topcksys? Shouldn't that be the node of scpsys?


it's typo.we will fix it.

> 
> > +			PTR_ERR(node));
> > +		return PTR_ERR(node);
> > +	}
> > +
> > +	do {
> > +		const char *ck_name;
> > +		char *temp_str;
> > +		char *tok[2] = {NULL};
> > +		int cg_idx = 0;
> > +		int idx = 0;
> > +		int ret = 0;
> > +
> > +		ret = of_property_read_string_index(node, "clock-names", i,
> > +						    &ck_name);
> > +		if (ret < 0)
> > +			break;
> > +
> > +		temp_str = kmalloc_array(strlen(ck_name), sizeof(char),
> > +					 GFP_KERNEL | __GFP_ZERO);
> > +		memcpy(temp_str, ck_name, strlen(ck_name));
> > +		temp_str[strlen(ck_name)] = '\0';
> 
> why don't you use kstrdup or similar?


we will fix it.

> 
> > +		do {
> > +			tok[idx] = strsep(&temp_str, "-");
> > +			idx++;
> > +		} while (temp_str);
> 
> You want to split the clock name like "mm-2" in
> char **tok = {"mm", "2"};
> correct? That can be done easier AFAIK:
> tok[0] = strsep(&temp_str, "-");
> tok[1] = &temp_str;

we will fix it.

> 
> > +
> > +		if (idx == 2) {
> 
> You don't add clocks like "mfg" and "mm". Why?

it's not the same, "mm" and "mfg" belong to mux, not a cg.and mux is
handle by mtk_scpsys.c
 
> 
> > +			if (kstrtouint(tok[1], 10, &cg_idx))
> i
> And then? You don't do anything with cg_idx..t

yes, we will delete this check.

> 
> > +				return -EINVAL;
> > +
> > +			if (add_clk_to_list(pdev, ck_name, tok[0]))
> 
> add_clk_to_list third parameter is the name of the scp domain, but you pass the
> clock name here. I'm puzzled.

yes, our idea is to set the prefix same as scp domain name, so we can
find the correct cg clks which belong to relative scp domain.
ex: "mm-0""mm-1" need to enable for "mm" scp domain power control flow.

> 
> > +				return -EINVAL;
> > +		}
> > +		kfree(temp_str);
> > +		i++;
> > +	} while (1);
> > +
> > +	return 0;
> > +}
> > +
> > +int scpsys_ext_clk_init(struct platform_device *pdev)
> > +{
> > +	int ret = 0;
> > +
> > +	ret = add_cg_to_list(pdev);
> > +	if (ret)
> > +		goto err;
> > +
> > +err:
> > +	return ret;
> > +}
> 
> Why do we need add_cg_to_list, it can be implemented directly here. Why is here
> a goto to a return statement that will be executed anyway? Please go through the
> code and check that it is clean before submitting.

yes, we will fix it.

> 
> > +
> > +int scpsys_ext_attr_init(const struct scpsys_ext_data *data)
> > +{
> > +	int i, count = 0;
> > +
> > +	for (i = 0; i < data->num_attr; i++) {
> > +		struct scpsys_ext_attr *node = data->attr + i;
> > +
> > +		if (!node)
> > +			continue;
> > +
> > +		list_add(&node->attr_list, &ext_attr_map_list);
> > +		count++;
> > +	}
> > +
> > +	if (!count)
> > +		return -EINVAL;
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct of_device_id of_scpsys_ext_match_tbl[] = {
> > +	{
> > +		/* sentinel */
> > +	}
> > +};
> > +
> > +struct scpsys_ext_data *scpsys_ext_init(struct platform_device *pdev)
> > +{
> > +	const struct of_device_id *match;
> > +	struct scpsys_ext_data *data;
> > +	int ret;
> > +
> > +	match = of_match_device(of_scpsys_ext_match_tbl, &pdev->dev);
> > +
> > +	if (!match) {
> > +		dev_err(&pdev->dev, "no match\n");
> > +		return ERR_CAST(match);
> > +	}
> > +
> > +	data = (struct scpsys_ext_data *)match->data;
> > +	if (IS_ERR(data)) {
> > +		dev_err(&pdev->dev, "no match scpext data\n");
> > +		return ERR_CAST(data);
> > +	}
> > +
> > +	ret = scpsys_ext_attr_init(data);
> > +	if (ret) {
> > +		dev_err(&pdev->dev,
> > +			"Failed to init bus attr: %d\n",
> > +			ret);
> > +		return ERR_PTR(ret);
> > +	}
> > +
> > +	ret = scpsys_ext_regmap_init(pdev);
> > +	if (ret) {
> > +		dev_err(&pdev->dev,
> > +			"Failed to init bus register: %d\n",
> > +			ret);
> > +		return ERR_PTR(ret);
> > +	}
> > +
> > +	ret = scpsys_ext_clk_init(pdev);
> > +	if (ret) {
> > +		dev_err(&pdev->dev, "Failed to init bus clks: %d\n",
> > +			ret);
> > +		return ERR_PTR(ret);
> > +	}
> > +
> > +	return data;
> > +}
> > diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
> > index 4bb6c7a..03df2d6 100644
> > --- a/drivers/soc/mediatek/mtk-scpsys.c
> > +++ b/drivers/soc/mediatek/mtk-scpsys.c
> > @@ -1,3 +1,4 @@
> > +// SPDX-License-Identifier: GPL-2.0
> >  /*
> >   * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de>
> >   *
> > @@ -20,6 +21,7 @@
> >  #include <linux/pm_domain.h>
> >  #include <linux/regulator/consumer.h>
> >  #include <linux/soc/mediatek/infracfg.h>
> > +#include <linux/soc/mediatek/scpsys-ext.h>
> >  
> >  #include <dt-bindings/power/mt2701-power.h>
> >  #include <dt-bindings/power/mt2712-power.h>
> > @@ -117,6 +119,15 @@ enum clk_id {
> >  
> >  #define MAX_CLKS	3
> >  
> > +/**
> > + * struct scp_domain_data - scp domain data for power on/off flow
> > + * @name: The domain name.
> > + * @sta_mask: The mask for power on/off status bit.
> > + * @ctl_offs: The offset for main power control register.
> > + * @sram_pdn_bits: The mask for sram power control bits.
> > + * @sram_pdn_ack_bits The mask for sram power control acked bits.
> > + * @caps: The flag for active wake-up action.
> > + */
> >  struct scp_domain_data {
> >  	const char *name;
> >  	u32 sta_mask;
> > @@ -150,7 +161,7 @@ struct scp {
> >  	void __iomem *base;
> >  	struct regmap *infracfg;
> >  	struct scp_ctrl_reg ctrl_reg;
> > -	bool bus_prot_reg_update;
> > +	struct scpsys_ext_data *ext_data;
> >  };
> >  
> >  struct scp_subdomain {
> > @@ -164,7 +175,6 @@ struct scp_soc_data {
> >  	const struct scp_subdomain *subdomains;
> >  	int num_subdomains;
> >  	const struct scp_ctrl_reg regs;
> > -	bool bus_prot_reg_update;
> >  };
> >  
> >  static int scpsys_domain_is_on(struct scp_domain *scpd)
> > @@ -236,6 +246,31 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
> >  	val |= PWR_RST_B_BIT;
> >  	writel(val, ctl_addr);
> >  
> > +	if (!IS_ERR(scp->ext_data)) {
> > +		struct scpsys_ext_attr *attr;
> > +
> > +		attr = scp->ext_data->get_attr(scpd->data->name);
> > +		if (!IS_ERR(attr) && attr->cg_ops) {
> > +			ret = attr->cg_ops->enable(attr);
> > +			if (ret)
> > +				goto err_ext_clk;
> > +		}
> > +	}
> > +
> > +	val &= ~scpd->data->sram_pdn_bits;
> > +	writel(val, ctl_addr);
> > +
> > +	if (!IS_ERR(scp->ext_data)) {
> > +		struct scpsys_ext_attr *attr;
> > +
> > +		attr = scp->ext_data->get_attr(scpd->data->name);
> > +		if (!IS_ERR(attr) && attr->cg_ops) {
> > +			ret = attr->cg_ops->enable(attr);
> > +			if (ret)
> > +				goto err_ext_clk;
> > +		}
> > +	}
> > +
> >  	val &= ~scpd->data->sram_pdn_bits;
> >  	writel(val, ctl_addr);
> >  
> > @@ -247,25 +282,65 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
> >  		 * applied here.
> >  		 */
> >  		usleep_range(12000, 12100);
> > -
> >  	} else {
> >  		ret = readl_poll_timeout(ctl_addr, tmp, (tmp & pdn_ack) == 0,
> >  					 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
> >  		if (ret < 0)
> > -			goto err_pwr_ack;
> > +			goto err_sram;
> >  	}
> >  
> >  	if (scpd->data->bus_prot_mask) {
> >  		ret = mtk_infracfg_clear_bus_protection(scp->infracfg,
> > -				scpd->data->bus_prot_mask,
> > -				scp->bus_prot_reg_update);
> > +				scpd->data->bus_prot_mask);
> >  		if (ret)
> > -			goto err_pwr_ack;
> > +			goto err_sram;
> > +	}
> > +
> > +	if (!IS_ERR(scp->ext_data)) {
> > +		struct scpsys_ext_attr *attr;
> > +
> > +		attr = scp->ext_data->get_attr(scpd->data->name);
> > +		if (!IS_ERR(attr) && attr->bus_ops) {
> > +			ret = attr->bus_ops->disable(attr);
> > +			if (ret)
> > +				goto err_sram;
> > +		}
> > +	}
> > +
> > +	if (!IS_ERR(scp->ext_data)) {
> > +		struct scpsys_ext_attr *attr;
> > +
> > +		attr = scp->ext_data->get_attr(scpd->data->name);
> > +		if (!IS_ERR(attr) && attr->cg_ops) {
> > +			ret = attr->cg_ops->disable(attr);
> > +			if (ret)
> > +				goto err_sram;
> > +		}
> >  	}
> >  
> >  	return 0;
> >  
> > +err_sram:
> > +	val = readl(ctl_addr);
> > +	val |= scpd->data->sram_pdn_bits;
> > +	writel(val, ctl_addr);
> > +err_ext_clk:
> > +	val = readl(ctl_addr);
> > +	val |= PWR_ISO_BIT;
> > +	writel(val, ctl_addr);
> > +
> > +	val &= ~PWR_RST_B_BIT;
> > +	writel(val, ctl_addr);
> > +
> > +	val |= PWR_CLK_DIS_BIT;
> > +	writel(val, ctl_addr);
> >  err_pwr_ack:
> > +	val &= ~PWR_ON_BIT;
> > +	writel(val, ctl_addr);
> > +
> > +	val &= ~PWR_ON_2ND_BIT;
> > +	writel(val, ctl_addr);
> > +
> >  	for (i = MAX_CLKS - 1; i >= 0; i--) {
> >  		if (scpd->clk[i])
> >  			clk_disable_unprepare(scpd->clk[i]);
> > @@ -274,8 +349,6 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
> >  	if (scpd->supply)
> >  		regulator_disable(scpd->supply);
> >  
> > -	dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name);
> > -
> >  	return ret;
> >  }
> >  
> > @@ -289,14 +362,35 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
> >  	int ret, tmp;
> >  	int i;
> >  
> > +	if (!IS_ERR(scp->ext_data)) {
> > +		struct scpsys_ext_attr *attr;
> > +
> > +		attr = scp->ext_data->get_attr(scpd->data->name);
> > +		if (!IS_ERR(attr) && attr->cg_ops) {
> > +			ret = attr->cg_ops->enable(attr);
> > +			if (ret)
> > +				goto out;
> > +		}
> > +	}
> > +
> >  	if (scpd->data->bus_prot_mask) {
> >  		ret = mtk_infracfg_set_bus_protection(scp->infracfg,
> > -				scpd->data->bus_prot_mask,
> > -				scp->bus_prot_reg_update);
> > +				scpd->data->bus_prot_mask);
> >  		if (ret)
> >  			goto out;
> >  	}
> >  
> > +	if (!IS_ERR(scp->ext_data)) {
> > +		struct scpsys_ext_attr *attr;
> > +
> > +		attr = scp->ext_data->get_attr(scpd->data->name);
> > +		if (!IS_ERR(attr) && attr->bus_ops) {
> > +			ret = attr->bus_ops->enable(attr);
> > +			if (ret)
> > +				goto out;
> > +		}
> > +	}
> > +
> >  	val = readl(ctl_addr);
> >  	val |= scpd->data->sram_pdn_bits;
> >  	writel(val, ctl_addr);
> > @@ -307,6 +401,17 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
> >  	if (ret < 0)
> >  		goto out;
> >  
> > +	if (!IS_ERR(scp->ext_data)) {
> > +		struct scpsys_ext_attr *attr;
> > +
> > +		attr = scp->ext_data->get_attr(scpd->data->name);
> > +		if (!IS_ERR(attr) && attr->cg_ops) {
> > +			ret = attr->cg_ops->disable(attr);
> > +			if (ret)
> > +				goto out;
> > +		}
> > +	}
> > +
> >  	val |= PWR_ISO_BIT;
> >  	writel(val, ctl_addr);
> >  
> > @@ -337,8 +442,6 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
> >  	return 0;
> >  
> >  out:
> > -	dev_err(scp->dev, "Failed to power off domain %s\n", genpd->name);
> > -
> >  	return ret;
> >  }
> >  
> > @@ -352,8 +455,7 @@ 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_ctrl_reg *scp_ctrl_reg,
> > -			bool bus_prot_reg_update)
> > +			const struct scp_ctrl_reg *scp_ctrl_reg)
> >  {
> >  	struct genpd_onecell_data *pd_data;
> >  	struct resource *res;
> > @@ -367,11 +469,10 @@ static struct scp *init_scp(struct platform_device *pdev,
> >  
> >  	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->bus_prot_reg_update = bus_prot_reg_update;
> > -
> >  	scp->dev = &pdev->dev;
> >  
> > +	scp->ext_data = scpsys_ext_init(pdev);
> > +
> >  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >  	scp->base = devm_ioremap_resource(&pdev->dev, res);
> >  	if (IS_ERR(scp->base))
> > @@ -1021,7 +1122,6 @@ static void mtk_register_power_domains(struct platform_device *pdev,
> >  		.pwr_sta_offs = SPM_PWR_STATUS,
> >  		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
> >  	},
> > -	.bus_prot_reg_update = true,
> >  };
> >  
> >  static const struct scp_soc_data mt2712_data = {
> > @@ -1033,7 +1133,6 @@ static void mtk_register_power_domains(struct platform_device *pdev,
> >  		.pwr_sta_offs = SPM_PWR_STATUS,
> >  		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
> >  	},
> > -	.bus_prot_reg_update = false,
> >  };
> >  
> >  static const struct scp_soc_data mt6765_data = {
> > @@ -1056,7 +1155,6 @@ static void mtk_register_power_domains(struct platform_device *pdev,
> >  		.pwr_sta_offs = SPM_PWR_STATUS_MT6797,
> >  		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797
> >  	},
> > -	.bus_prot_reg_update = true,
> 
> I don't understand why you can delete this flag if you don't change anything
> else in the data structure. For me this looks like you will break other chips.
> Please explain.
> 
> I have the gut feeling that this can be implemented in the existing mtk-scpsys
> driver. Can you please explain what are the points that this is not possible.
> I want to understand the design decisions you made here, because they seem
> really odd to me.
> 
> Best regards,
> Matthias
> 

sorry, it should not be deleted. we will fix it.

> >  };
> >  
> >  static const struct scp_soc_data mt7622_data = {
> > @@ -1066,7 +1164,6 @@ static void mtk_register_power_domains(struct platform_device *pdev,
> >  		.pwr_sta_offs = SPM_PWR_STATUS,
> >  		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
> >  	},
> > -	.bus_prot_reg_update = true,
> >  };
> >  
> >  static const struct scp_soc_data mt7623a_data = {
> > @@ -1076,7 +1173,6 @@ static void mtk_register_power_domains(struct platform_device *pdev,
> >  		.pwr_sta_offs = SPM_PWR_STATUS,
> >  		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
> >  	},
> > -	.bus_prot_reg_update = true,
> >  };
> >  
> >  static const struct scp_soc_data mt8173_data = {
> > @@ -1088,7 +1184,6 @@ static void mtk_register_power_domains(struct platform_device *pdev,
> >  		.pwr_sta_offs = SPM_PWR_STATUS,
> >  		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
> >  	},
> > -	.bus_prot_reg_update = true,
> >  };
> >  
> >  /*
> > @@ -1132,8 +1227,8 @@ static int scpsys_probe(struct platform_device *pdev)
> >  
> >  	soc = of_device_get_match_data(&pdev->dev);
> >  
> > -	scp = init_scp(pdev, soc->domains, soc->num_domains, &soc->regs,
> > -			soc->bus_prot_reg_update);
> > +	scp = init_scp(pdev, soc->domains, soc->num_domains,
> > +		       &soc->regs);
> >  	if (IS_ERR(scp))
> >  		return PTR_ERR(scp);
> >  
> > diff --git a/include/linux/soc/mediatek/infracfg.h b/include/linux/soc/mediatek/infracfg.h
> > index fd25f01..bfad082 100644
> > --- a/include/linux/soc/mediatek/infracfg.h
> > +++ b/include/linux/soc/mediatek/infracfg.h
> > @@ -32,8 +32,9 @@
> >  #define MT7622_TOP_AXI_PROT_EN_WB		(BIT(2) | BIT(6) | \
> >  						 BIT(7) | BIT(8))
> >  
> > -int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask,
> > -		bool reg_update);
> > -int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask,
> > -		bool reg_update);
> > +int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask);
> > +int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask);
> > +int mtk_infracfg_enable_bus_protection(struct regmap *infracfg, u32 mask);
> > +int mtk_infracfg_disable_bus_protection(struct regmap *infracfg, u32 mask);
> > +
> >  #endif /* __SOC_MEDIATEK_INFRACFG_H */
> > diff --git a/include/linux/soc/mediatek/scpsys-ext.h b/include/linux/soc/mediatek/scpsys-ext.h
> > new file mode 100644
> > index 0000000..99b5ff1
> > --- /dev/null
> > +++ b/include/linux/soc/mediatek/scpsys-ext.h
> > @@ -0,0 +1,66 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#ifndef __SOC_MEDIATEK_SCPSYS_EXT_H
> > +#define __SOC_MEDIATEK_SCPSYS_EXT_H
> > +
> > +#include <linux/platform_device.h>
> > +
> > +#define CMD_ENABLE	1
> > +#define CMD_DISABLE	0
> > +
> > +#define MAX_STEP_NUM	4
> > +
> > +/**
> > + * struct bus_mask - set mask and corresponding operation for bus protect
> > + * @regs: The register set of bus register control, including set/clr/sta.
> > + * @mask: The mask set for bus protect.
> > + * @flag: The flag to idetify which operation we take for bus protect.
> > + */
> > +struct bus_mask {
> > +	struct ext_reg_ctrl *regs;
> > +	u32 mask;
> > +	const struct bus_mask_ops *ops;
> > +};
> > +
> > +/**
> > + * struct scpsys_ext_attr - extended attribute for bus protect and further
> > + *                                           operand.
> > + *
> > + * @scpd_n: The name present the scpsys domain where the clks belongs to.
> > + * @mask: The mask set for bus protect.
> > + * @bus_ops: The operation we take for bus protect.
> > + * @cg_ops: The operation we take for cg on/off.
> > + * @attr_list: The list node linked to ext_attr_map_list.
> > + */
> > +struct scpsys_ext_attr {
> > +	const char *scpd_n;
> > +	struct bus_mask mask[MAX_STEP_NUM];
> > +	const char *parent_n;
> > +	const struct bus_ext_ops *bus_ops;
> > +	const struct bus_ext_ops *cg_ops;
> > +
> > +	struct list_head attr_list;
> > +};
> > +
> > +struct scpsys_ext_data {
> > +	struct scpsys_ext_attr *attr;
> > +	u8 num_attr;
> > +	struct scpsys_ext_attr * (*get_attr)(const char *scpd_n);
> > +};
> > +
> > +struct bus_ext_ops {
> > +	int	(*enable)(struct scpsys_ext_attr *attr);
> > +	int	(*disable)(struct scpsys_ext_attr *attr);
> > +};
> > +
> > +int mtk_generic_set_cmd(struct regmap *regmap, u32 set_ofs,
> > +			u32 sta_ofs, u32 mask);
> > +int mtk_generic_clr_cmd(struct regmap *regmap, u32 clr_ofs,
> > +			u32 sta_ofs, u32 mask);
> > +int mtk_generic_enable_cmd(struct regmap *regmap, u32 upd_ofs,
> > +			   u32 sta_ofs, u32 mask);
> > +int mtk_generic_disable_cmd(struct regmap *regmap, u32 upd_ofs,
> > +			    u32 sta_ofs, u32 mask);
> > +
> > +struct scpsys_ext_data *scpsys_ext_init(struct platform_device *pdev);
> > +
> > +#endif /* __SOC_MEDIATEK_SCPSYS_EXT_H */
> > 



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

* Re: [PATCH v5 09/11] clk: mediatek: add new clkmux register API
  2018-07-19  6:57   ` Sean Wang
@ 2018-08-13  9:09     ` Owen Chen
  0 siblings, 0 replies; 32+ messages in thread
From: Owen Chen @ 2018-08-13  9:09 UTC (permalink / raw)
  To: Sean Wang
  Cc: Mars Cheng, Matthias Brugger, Rob Herring, Marc Zyngier,
	Ryder Lee, Stephen Boyd, CC Hwang, Loda Chou, linux-kernel,
	linux-mediatek, devicetree, wsd_upstream, linux-serial,
	linux-arm-kernel, linux-clk

On Thu, 2018-07-19 at 14:57 +0800, Sean Wang wrote:
> On Tue, 2018-07-17 at 16:52 +0800, Mars Cheng wrote:
> > From: Owen Chen <owen.chen@mediatek.com>
> > 
> > MT6765 add "set/clr" register for each clkmux setting, and
> > one update register to trigger value change. It is designed
> > to prevent read-modify-write racing issue. The sw design
> > need to add a new API to handle this hw change with a new
> > mtk_clk_mux/mtk_clk_upd struct in new file "clk-mux"and
> > clk-upd".
> > 
> 
> I don't see any word mtk_clk_upd or clk-upd in the patch
> 
> and the patch needs to be split into more patches
> 

clk-upd is old description, no more clk-upd for handling update bit.

I will remove it next version.

> > Signed-off-by: Owen Chen <owen.chen@mediatek.com>
> > ---
> >  drivers/clk/mediatek/Makefile  |    2 +-
> >  drivers/clk/mediatek/clk-mtk.c |   41 +++++++
> >  drivers/clk/mediatek/clk-mtk.h |   85 ++++++++++++---
> >  drivers/clk/mediatek/clk-mux.c |  236 ++++++++++++++++++++++++++++++++++++++++
> >  drivers/clk/mediatek/clk-mux.h |   38 +++++++
> >  5 files changed, 388 insertions(+), 14 deletions(-)
> >  create mode 100644 drivers/clk/mediatek/clk-mux.c
> >  create mode 100644 drivers/clk/mediatek/clk-mux.h
> > 
> > diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
> > index 844b55d..b97980d 100644
> > --- a/drivers/clk/mediatek/Makefile
> > +++ b/drivers/clk/mediatek/Makefile
> > @@ -1,5 +1,5 @@
> >  # SPDX-License-Identifier: GPL-2.0
> > -obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o clk-cpumux.o reset.o
> > +obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o clk-cpumux.o reset.o clk-mux.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
> > diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
> > index 9c0ae42..50becd0 100644
> > --- a/drivers/clk/mediatek/clk-mtk.c
> > +++ b/drivers/clk/mediatek/clk-mtk.c
> > @@ -22,6 +22,7 @@
> >  #include <linux/mfd/syscon.h>
> >  
> >  #include "clk-mtk.h"
> > +#include "clk-mux.h"
> >  #include "clk-gate.h"
> >  
> >  struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num)
> > @@ -144,6 +145,46 @@ int mtk_clk_register_gates(struct device_node *node,
> >  	return 0;
> >  }
> >  
> > +int mtk_clk_register_muxes(const struct mtk_mux *muxes,
> > +			   int num, struct device_node *node,
> > +			   spinlock_t *lock,
> > +			   struct clk_onecell_data *clk_data)
> > +{
> > +	struct regmap *regmap;
> > +	struct clk *clk;
> > +	int i;
> > +
> > +	if (!clk_data)
> > +		return -ENOMEM;
> > +
> 
> general register function is able to handle that there is no clk_data.
> It looks like a optional, not a mandatory
> 

clk_data is reused in topcksys clk registration, because of the
registration include muxes/gates/dividers/fixed_clks, so we need to make
sure clk_data is not NULL pointer so we can use to store the clk
structure we allocated.

> > +	regmap = syscon_node_to_regmap(node);
> > +	if (IS_ERR(regmap)) {
> > +		pr_err("Cannot find regmap for %pOF: %ld\n", node,
> > +		       PTR_ERR(regmap));
> > +		return PTR_ERR(regmap);
> > +	}
> > +
> > +	for (i = 0; i < num; i++) {
> > +		const struct mtk_mux *mux = &muxes[i];
> > +
> > +		if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[mux->id]))
> > +			continue;
> > +
> 
> it seems not necessary to check clk data every time
> 
> and always use positive check is good to read
> 

Yes, we will remove clk_data check at this point since not necessary.
the if condition check would alter next version.

> > +		clk = mtk_clk_register_mux(mux, regmap, lock);
> > +
> > +		if (IS_ERR(clk)) {
> > +			pr_err("Failed to register clk %s: %ld\n",
> > +			       mux->name, PTR_ERR(clk));
> > +			continue;
> > +		}
> > +
> > +		if (clk_data)
> > +			clk_data->clks[mux->id] = clk;
> 
> don't alter any data from input, that is a surprise for users
> 

As I mentioned on previous question, clk_data need to be alterd because
of after registration done, we need to offer clk_data as input of
of_clk_add_provider(...,clk_data)

> > +	}
> > +
> > +	return 0;
> > +}
> > +
> >  struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
> >  		void __iomem *base, spinlock_t *lock)
> >  {
> > diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
> > index 1882221..61693f6 100644
> > --- a/drivers/clk/mediatek/clk-mtk.h
> > +++ b/drivers/clk/mediatek/clk-mtk.h
> > @@ -24,7 +24,9 @@
> >  
> >  #define MAX_MUX_GATE_BIT	31
> >  #define INVALID_MUX_GATE_BIT	(MAX_MUX_GATE_BIT + 1)
> > -
> > +#define INVALID_OFS		-1
> > +#define INVALID_SHFT		-1
> > +#define INVALID_WIDTH		-1
> >  #define MHZ (1000 * 1000)
> >  
> >  struct mtk_fixed_clk {
> > @@ -84,10 +86,72 @@ struct mtk_composite {
> >  	signed char num_parents;
> >  };
> >  
> > +struct mtk_mux {
> > +	int id;
> > +	const char *name;
> > +	const char * const *parent_names;
> > +	unsigned int flags;
> > +
> > +	u32 mux_ofs;
> > +	u32 set_ofs;
> > +	u32 clr_ofs;
> > +	u32 upd_ofs;
> > +
> > +	signed char mux_shift;
> > +	signed char mux_width;
> > +	signed char gate_shift;
> > +	signed char upd_shift;
> > +
> > +	const struct clk_ops *ops;
> > +
> > +	signed char num_parents;
> > +};
> > +
> 
> you have created a mtk-mux.h, why is you don't move the newly create
> struct in?
> 

Okay, I would remove mtk_mux structure and only preserve mtk_clk_mux in
clk_mux.h.

> >  /*
> >   * In case the rate change propagation to parent clocks is undesirable,
> >   * this macro allows to specify the clock flags manually.
> >   */
> > +#define CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, _mux_set_ofs,\
> > +			_mux_clr_ofs, _shift, _width, _gate,		\
> > +			_upd_ofs, _upd, _flags, _ops) {			\
> > +		.id = _id,						\
> > +		.name = _name,						\
> > +		.mux_ofs = _mux_ofs,					\
> > +		.set_ofs = _mux_set_ofs,				\
> > +		.clr_ofs = _mux_clr_ofs,				\
> > +		.upd_ofs = _upd_ofs,					\
> > +		.mux_shift = _shift,					\
> > +		.mux_width = _width,					\
> > +		.gate_shift = _gate,					\
> > +		.upd_shift = _upd,					\
> > +		.parent_names = _parents,				\
> > +		.num_parents = ARRAY_SIZE(_parents),			\
> > +		.flags = _flags,					\
> > +		.ops = &_ops,						\
> > +	}
> > +
> > +#define MUX_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, _mux_set_ofs,\
> > +			_mux_clr_ofs, _shift, _width, _gate,		\
> > +			_upd_ofs, _upd, _flags)			\
> > +		CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs,	\
> > +			_mux_set_ofs, _mux_clr_ofs, _shift, _width,	\
> > +			_gate, _upd_ofs, _upd, _flags,			\
> > +			mtk_mux_clr_set_upd_ops)
> > +
> > +#define MUX_CLR_SET_UPD(_id, _name, _parents, _mux_ofs, _mux_set_ofs,	\
> > +			_mux_clr_ofs, _shift, _width, _gate,		\
> > +			_upd_ofs, _upd)				\
> > +		MUX_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs,	\
> > +			_mux_set_ofs, _mux_clr_ofs, _shift, _width,	\
> > +			_gate, _upd_ofs, _upd, CLK_SET_RATE_PARENT)
> > +
> > +#define MUX_UPD(_id, _name, _parents, _mux_ofs, _shift, _width, _gate,	\
> > +			_upd_ofs, _upd)				\
> > +		CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs,	\
> > +			INVALID_OFS, INVALID_OFS, _shift, _width,	\
> > +			_gate, _upd_ofs, _upd, CLK_SET_RATE_PARENT,	\
> > +			mtk_mux_upd_ops)
> > +
> >  #define MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width,	\
> >  			_gate, _flags) {				\
> >  		.id = _id,						\
> > @@ -111,18 +175,8 @@ struct mtk_composite {
> >  	MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width,	\
> >  		_gate, CLK_SET_RATE_PARENT)
> >  
> > -#define MUX(_id, _name, _parents, _reg, _shift, _width) {		\
> > -		.id = _id,						\
> > -		.name = _name,						\
> > -		.mux_reg = _reg,					\
> > -		.mux_shift = _shift,					\
> > -		.mux_width = _width,					\
> > -		.gate_shift = -1,					\
> > -		.divider_shift = -1,					\
> > -		.parent_names = _parents,				\
> > -		.num_parents = ARRAY_SIZE(_parents),			\
> > -		.flags = CLK_SET_RATE_PARENT,				\
> > -	}
> 
> As Matthias always said that, you alter the common thing that is already
> used by a lot of SoC.
> 
> You should have a dedicate patch to state why you need it, provide the
> way you propose. and use another patches for migrating old SoC, finally
> then add the patch for your own SoC.
> 
> Don't mix everything in a single patch. The patch can't become reusable
> hard to read it, even hard to backport to the other SoC picking up
> patches they are really wanting.
> 

Okay, I will restore it to original version.

> > +#define MUX(_id, _name, _parents, _reg, _shift, _width)		\
> > +	MUX_GATE(_id, _name, _parents, _reg, _shift, _width, INVALID_SHFT)
> >  
> >  #define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg,	\
> >  					_div_width, _div_shift) {	\
> > @@ -138,6 +192,11 @@ struct mtk_composite {
> >  		.flags = 0,						\
> >  	}
> >  
> > +int mtk_clk_register_muxes(const struct mtk_mux *muxes,
> > +			   int num, struct device_node *node,
> > +			   spinlock_t *lock,
> > +			   struct clk_onecell_data *clk_data);
> > +
> 
> move to mtk-mux.h
> 

Again, we can observe that other(gate/divider/fixed_clk) registration
functions all gather together in clk_mtk.h, if we want to move mtk_mux
to clk_mux.h, I think we may start a new patch to move all other three
registration functions and distribute it to their own driver code such
as clk_gate.h/clk_divider.h...etc.

> >  struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
> >  		void __iomem *base, spinlock_t *lock);
> >  
> > diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c
> > new file mode 100644
> > index 0000000..219181b
> > --- /dev/null
> > +++ b/drivers/clk/mediatek/clk-mux.c
> > @@ -0,0 +1,236 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2018 MediaTek Inc.
> > + * Author: Owen Chen <owen.chen@mediatek.com>
> > + */
> > +
> > +#include <linux/of.h>
> > +#include <linux/of_address.h>
> > +#include <linux/slab.h>
> > +
> > +#include "clk-mtk.h"
> > +#include "clk-mux.h"
> > +
> > +static inline struct mtk_clk_mux
> > +	*to_mtk_clk_mux(struct clk_hw *hw)
> > +{
> > +	return container_of(hw, struct mtk_clk_mux, hw);
> > +}
> > +
> > +static int mtk_mux_enable(struct clk_hw *hw)
> > +{
> > +	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
> > +	u32 mask = BIT(mux->gate_shift);
> > +	unsigned long flags = 0;
> > +
> > +	if (mux->lock)
> > +		spin_lock_irqsave(mux->lock, flags);
> > +
> 
> we can see many functions in kernel, similar to your need, they always
> be defined as two versions. for example.
> 
> mtk_mux_enable refer to lock version
> 
> mtk_mux_enable_nolock for lock-free version
> 
> that makes less condition, more readable, and users don't care much
> about what stuff is put inside  
> 

clk.c already provides spin_lock at entrance of clk_enable/clk_disalbe
API, so the lock version seems redundant here, I would remove the lock
version and keep this API lock-free as my next modification.

> > +	regmap_update_bits(mux->regmap, mux->mux_ofs, mask, 0);
> > +
> > +	if (mux->lock)
> > +		spin_unlock_irqrestore(mux->lock, flags);
> > +	return 0;
> > +}
> > +
> > +static void mtk_mux_disable(struct clk_hw *hw)
> > +{
> > +	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
> > +	u32 mask = BIT(mux->gate_shift);
> > +	unsigned long flags = 0;
> > +
> > +	if (mux->lock)
> > +		spin_lock_irqsave(mux->lock, flags);
> > +
> 
> ditto
> 

I would remove lock next modification.

> > +	regmap_update_bits(mux->regmap, mux->mux_ofs, mask, mask);
> > +
> > +	if (mux->lock)
> > +		spin_unlock_irqrestore(mux->lock, flags);
> > +}
> > +
> > +static int mtk_mux_enable_setclr(struct clk_hw *hw)
> > +{
> > +	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
> > +	u32 val;
> > +	unsigned long flags = 0;
> > +
> > +	if (mux->lock)
> > +		spin_lock_irqsave(mux->lock, flags);
> > +
> 
> ditto
> 

I would remove lock next modification.

> > +	val = BIT(mux->gate_shift);
> > +	regmap_write(mux->regmap, mux->mux_clr_ofs, val);
> > +
> > +	if (mux->lock)
> > +		spin_unlock_irqrestore(mux->lock, flags);
> > +	return 0;
> > +}
> > +
> > +static void mtk_mux_disable_setclr(struct clk_hw *hw)
> > +{
> > +	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
> > +	u32 val;
> > +	unsigned long flags = 0;
> > +
> > +	if (mux->lock)
> > +		spin_lock_irqsave(mux->lock, flags);
> > +
> 
> ditto
> 

I would remove lock next modification.

> > +	val = BIT(mux->gate_shift);
> > +	regmap_write(mux->regmap, mux->mux_set_ofs, val);
> > +
> > +	if (mux->lock)
> > +		spin_unlock_irqrestore(mux->lock, flags);
> > +}
> > +
> > +static int mtk_mux_is_enabled(struct clk_hw *hw)
> > +{
> > +	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
> > +	u32 val = 0;
> > +
> > +	if (mux->gate_shift < 0)
> > +		return true;
> > +
> 
> return value should be bool
> 

due to the proto type of is_enabled function is defined to return
integer. I will alter the return value to 1 or 0.

> > +	regmap_read(mux->regmap, mux->mux_ofs, &val);
> > +
> > +	return (val & BIT(mux->gate_shift)) == 0;
> > +}
> > +
> > +static u8 mtk_mux_get_parent(struct clk_hw *hw)
> > +{
> 
> 
> return value should be int

Okay, I would alter it next version.

> > +	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
> > +	int num_parents = clk_hw_get_num_parents(hw);
> > +	u32 mask = GENMASK(mux->mux_width - 1, 0);
> > +	u32 val;
> > +
> > +	regmap_read(mux->regmap, mux->mux_ofs, &val);
> > +	val = (val >> mux->mux_shift) & mask;
> > +
> > +	if (val >= num_parents)
> > +		return -EINVAL;
> > +
> > +	return val;
> > +}
> > +
> > +static int mtk_mux_set_parent(struct clk_hw *hw, u8 index)
> > +{
> > +	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
> > +	u32 mask = GENMASK(mux->mux_width - 1, 0);
> > +	u32 val, orig;
> > +	unsigned long flags = 0;
> > +
> > +	if (mux->lock)
> > +		spin_lock_irqsave(mux->lock, flags);
> > +
> 
> use lock-free-or-not funciton
> 

I would remove lock next modification.

> > +	regmap_read(mux->regmap, mux->mux_ofs, &val);
> > +	orig = val;
> > +	val &= ~(mask << mux->mux_shift);
> > +	val |= index << mux->mux_shift;
> > +
> > +	if (val != orig) {
> > +		regmap_write(mux->regmap, mux->mux_ofs, val);
> > +
> > +		if (mux->upd_shift >= 0)
> > +			regmap_write(mux->regmap, mux->upd_ofs,
> > +				     BIT(mux->upd_shift));
> 
> 
> why not use regmap_update_bits like function ?
> 

Okay, I would alter it next version..

> > +	}
> > +
> > +	if (mux->lock)
> > +		spin_unlock_irqrestore(mux->lock, flags);
> > +
> > +	return 0;
> > +}
> > +
> > +static int mtk_mux_set_parent_setclr(struct clk_hw *hw, u8 index)
> > +{
> > +	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
> > +	u32 mask = GENMASK(mux->mux_width - 1, 0);
> > +	u32 val, orig;
> > +	unsigned long flags = 0;
> > +
> > +	if (mux->lock)
> > +		spin_lock_irqsave(mux->lock, flags);
> > +
> 
> use lock-free-or-not funciton
> 

I would remove lock next modification.

> > +	regmap_read(mux->regmap, mux->mux_ofs, &val);
> > +	orig = val;
> > +	val &= ~(mask << mux->mux_shift);
> > +	val |= index << mux->mux_shift;
> > +
> > +	if (val != orig) {
> > +		val = (mask << mux->mux_shift);
> > +		regmap_write(mux->regmap, mux->mux_clr_ofs, val);
> > +		val = (index << mux->mux_shift);
> > +		regmap_write(mux->regmap, mux->mux_set_ofs, val);
> > +
> 
> why not use regmap_update_bits like function ?

This function specified that mux use set/clr register to update, so it
would be better to use regmap_write to write the whole register instead
of regmap_update_bit.

> > +		if (mux->upd_shift >= 0)
> > +			regmap_write(mux->regmap, mux->upd_ofs,
> > +				     BIT(mux->upd_shift));
> > +	}
> > +
> > +	if (mux->lock)
> > +		spin_unlock_irqrestore(mux->lock, flags);
> > +
> > +	return 0;
> > +}
> > +
> > +const struct clk_ops mtk_mux_upd_ops = {
> > +	.enable = mtk_mux_enable,
> > +	.disable = mtk_mux_disable,
> > +	.is_enabled = mtk_mux_is_enabled,
> > +	.get_parent = mtk_mux_get_parent,
> > +	.set_parent = mtk_mux_set_parent,
> > +	.determine_rate = NULL,
> 
> explicitly set as NULL can be removed

Okay, I would remove it next version.

> > +};
> > +
> > +const struct clk_ops mtk_mux_clr_set_upd_ops = {
> > +	.enable = mtk_mux_enable_setclr,
> > +	.disable = mtk_mux_disable_setclr,
> > +	.is_enabled = mtk_mux_is_enabled,
> > +	.get_parent = mtk_mux_get_parent,
> > +	.set_parent = mtk_mux_set_parent_setclr,
> > +	.determine_rate = NULL,
> 
> explicitly set as NULL can be removed

Okay, I would remove it next version.

> > +};
> > +
> > +struct clk *mtk_clk_register_mux(const struct mtk_mux *mux,
> > +				 struct regmap *regmap,
> > +				 spinlock_t *lock)
> > +{
> > +	struct clk *clk;
> > +	struct clk_init_data init;
> > +	struct mtk_clk_mux *mtk_mux = NULL;
> > +	int ret;
> > +
> make declaration as reverse xmas tree
> 

Okay, I would alter it next version.

> > +	mtk_mux = kzalloc(sizeof(*mtk_mux), GFP_KERNEL);
> > +	if (!mtk_mux)
> > +		return ERR_PTR(-ENOMEM);
> > +
> > +	init.name = mux->name;
> > +	init.flags = (mux->flags) | CLK_SET_RATE_PARENT;
> > +	init.parent_names = mux->parent_names;
> > +	init.num_parents = mux->num_parents;
> > +	init.ops = mux->ops;
> > +
> > +	mtk_mux->regmap = regmap;
> > +	mtk_mux->name = mux->name;
> > +	mtk_mux->mux_ofs = mux->mux_ofs;
> > +	mtk_mux->mux_set_ofs = mux->set_ofs;
> > +	mtk_mux->mux_clr_ofs = mux->clr_ofs;
> > +	mtk_mux->upd_ofs = mux->upd_ofs;
> > +	mtk_mux->mux_shift = mux->mux_shift;
> > +	mtk_mux->mux_width = mux->mux_width;
> > +	mtk_mux->gate_shift = mux->gate_shift;
> > +	mtk_mux->upd_shift = mux->upd_shift;
> > +
> > +	mtk_mux->lock = lock;
> > +	mtk_mux->hw.init = &init;
> > +
> > +	clk = clk_register(NULL, &mtk_mux->hw);
> > +	if (IS_ERR(clk)) {
> > +		ret = PTR_ERR(clk);
> 
> 
> ret is superfluous
> 

Okay, I would remove it next version.

> > +		goto err_out;
> > +	}
> > +
> > +	return clk;
> > +err_out:
> > +	kfree(mtk_mux);
> > +
> 
> I felt err path can be optimized
> 

Okay, I would remove it next version.

> > +	return ERR_PTR(ret);
> > +}
> > diff --git a/drivers/clk/mediatek/clk-mux.h b/drivers/clk/mediatek/clk-mux.h
> > new file mode 100644
> > index 0000000..64f8e7c
> > --- /dev/null
> > +++ b/drivers/clk/mediatek/clk-mux.h
> > @@ -0,0 +1,38 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright (c) 2018 MediaTek Inc.
> > + * Author: Owen Chen <owen.chen@mediatek.com>
> > + */
> > +
> > +#ifndef __DRV_CLK_MUX_H
> > +#define __DRV_CLK_MUX_H
> > +
> > +#include <linux/clk-provider.h>
> > +
> > +struct mtk_clk_mux {
> > +	struct clk_hw hw;
> > +	struct regmap *regmap;
> > +
> > +	const char *name;
> > +
> > +	int mux_set_ofs;
> > +	int mux_clr_ofs;
> > +	int mux_ofs;
> > +	int upd_ofs;
> > +
> > +	s8 mux_shift;
> > +	s8 mux_width;
> > +	s8 gate_shift;
> > +	s8 upd_shift;
> > +
> > +	spinlock_t *lock;
> > +};
> > +
> > +extern const struct clk_ops mtk_mux_upd_ops;
> > +extern const struct clk_ops mtk_mux_clr_set_upd_ops;
> > +
> 
> 
> extern  is superfluous
> 

Okay, I would remove it next version.

> > +struct clk *mtk_clk_register_mux(const struct mtk_mux *mux,
> > +				 struct regmap *regmap,
> > +				 spinlock_t *lock);
> > +
> > +#endif /* __DRV_CLK_MUX_H */
> 
> 



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

* Re: [PATCH v5 01/11] dt-bindings: clock: mediatek: document clk bindings for Mediatek MT6765 SoC
  2018-07-20 17:43   ` Rob Herring
@ 2018-08-13  9:12     ` Owen Chen
  0 siblings, 0 replies; 32+ messages in thread
From: Owen Chen @ 2018-08-13  9:12 UTC (permalink / raw)
  To: Rob Herring
  Cc: Mars Cheng, Matthias Brugger, Marc Zyngier, Ryder Lee,
	Stephen Boyd, Sean Wang, CC Hwang, Loda Chou, linux-kernel,
	linux-mediatek, devicetree, wsd_upstream, linux-serial,
	linux-arm-kernel, linux-clk

On Fri, 2018-07-20 at 11:43 -0600, Rob Herring wrote:
> On Tue, Jul 17, 2018 at 04:52:22PM +0800, Mars Cheng wrote:
> > This patch adds the binding documentation for apmixedsys, audsys, camsys,
> > imgsys, infracfg, mipi0a, topckgen, vcodecsys
> > 
> > Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
> > Signed-off-by: Owen Chen <owen.chen@mediatek.com>
> > ---
> >  .../bindings/arm/mediatek/mediatek,apmixedsys.txt  |    1 +
> >  .../bindings/arm/mediatek/mediatek,audsys.txt      |    1 +
> >  .../bindings/arm/mediatek/mediatek,camsys.txt      |   27 ++++++++++++++++++++
> >  .../bindings/arm/mediatek/mediatek,imgsys.txt      |    1 +
> >  .../bindings/arm/mediatek/mediatek,infracfg.txt    |    1 +
> >  .../bindings/arm/mediatek/mediatek,mipi0a.txt      |   23 +++++++++++++++++
> >  .../bindings/arm/mediatek/mediatek,mmsys.txt       |    1 +
> >  .../bindings/arm/mediatek/mediatek,pericfg.txt     |    1 +
> >  .../bindings/arm/mediatek/mediatek,topckgen.txt    |    1 +
> >  .../bindings/arm/mediatek/mediatek,vcodecsys.txt   |   22 ++++++++++++++++
> >  10 files changed, 79 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,camsys.txt
> >  create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mipi0a.txt
> >  create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,vcodecsys.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
> > index b404d59..44eaeac 100644
> > --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
> > +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
> > @@ -8,6 +8,7 @@ Required Properties:
> >  - compatible: Should be one of:
> >  	- "mediatek,mt2701-apmixedsys"
> >  	- "mediatek,mt2712-apmixedsys", "syscon"
> > +	- "mediatek,mt6765-apmixedsys", "syscon"
> >  	- "mediatek,mt6797-apmixedsys"
> >  	- "mediatek,mt7622-apmixedsys"
> >  	- "mediatek,mt8135-apmixedsys"
> > diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
> > index 34a69ba..9a8672a 100644
> > --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
> > +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
> > @@ -7,6 +7,7 @@ Required Properties:
> >  
> >  - compatible: Should be one of:
> >  	- "mediatek,mt2701-audsys", "syscon"
> > +	- "mediatek,mt6765-audsys", "syscon"
> >  	- "mediatek,mt7622-audsys", "syscon"
> >  - #clock-cells: Must be 1
> >  
> > diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,camsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,camsys.txt
> > new file mode 100644
> > index 0000000..dc75783
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,camsys.txt
> > @@ -0,0 +1,27 @@
> > +MediaTek CAMSYS controller
> > +============================
> > +
> > +The MediaTek CAMSYS controller provides various clocks to the system.
> 
> Only clocks? If so, then this should be moved to bindings/clocks/.
> 

camsys conclude not only clks but also mtcmos, so it's better to put
this node in this path.

> > +
> > +Required Properties:
> > +
> > +- compatible: Should be one of:
> > +	- "mediatek,mt6765-camsys", "syscon"
> > +- #clock-cells: Must be 1
> > +
> > +The AUDSYS controller uses the common clk binding from
> > +Documentation/devicetree/bindings/clock/clock-bindings.txt
> > +The available clocks are defined in dt-bindings/clock/mt*-clk.h.
> > +
> > +Required sub-nodes:
> > +-------
> > +For common binding part and usage, refer to
> > +../sonud/mt2701-afe-pcm.txt.
> > +
> > +Example:
> > +
> > +camsys: camsys@1a000000  {
> 
> clock-controller@...
> 
> if the above answer is yes.
> 
> Same comments on the other docs.



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

end of thread, other threads:[~2018-08-13  9:12 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-17  8:52 [PATCH v5 0/11] Add basic SoC support for mt6765 Mars Cheng
2018-07-17  8:52 ` [PATCH v5 01/11] dt-bindings: clock: mediatek: document clk bindings for Mediatek MT6765 SoC Mars Cheng
2018-07-20 17:43   ` Rob Herring
2018-08-13  9:12     ` Owen Chen
2018-07-17  8:52 ` [PATCH v5 02/11] dt-bindings: mediatek: Add smi dts binding " Mars Cheng
2018-07-20 17:44   ` Rob Herring
2018-07-17  8:52 ` [PATCH v5 03/11] dt-bindings: mediatek: add MT6765 power dt-bindings Mars Cheng
2018-07-20 17:45   ` Rob Herring
2018-07-17  8:52 ` [PATCH v5 04/11] soc: mediatek: add MT6765 scpsys support Mars Cheng
2018-07-17 13:00   ` Sean Wang
2018-07-18  8:54     ` Mars Cheng
2018-07-20 17:46   ` Rob Herring
2018-07-17  8:52 ` [PATCH v5 05/11] clk: mediatek: add mt6765 clock IDs Mars Cheng
2018-07-17 10:24   ` Matthias Brugger
2018-07-18  4:23     ` Mars Cheng
2018-07-17  8:52 ` [PATCH v5 06/11] soc: mediatek: add new flow for mtcmos power Mars Cheng
2018-07-17 15:49   ` kbuild test robot
2018-07-17 18:19   ` [RFC PATCH] soc: mediatek: bus_ctrl_set_release() can be static kbuild test robot
2018-07-17 18:19   ` [PATCH v5 06/11] soc: mediatek: add new flow for mtcmos power kbuild test robot
2018-07-17 20:36   ` kbuild test robot
2018-07-18 14:50   ` Matthias Brugger
2018-07-25  9:42     ` Owen Chen
2018-07-17  8:52 ` [PATCH v5 07/11] soc: mediatek: add MT6765 subdomain support Mars Cheng
2018-07-17  8:52 ` [PATCH v5 08/11] clk: mediatek: fix pll setting Mars Cheng
2018-07-17  8:52 ` [PATCH v5 09/11] clk: mediatek: add new clkmux register API Mars Cheng
2018-07-19  6:57   ` Sean Wang
2018-08-13  9:09     ` Owen Chen
2018-07-17  8:52 ` [PATCH v5 10/11] clk: mediatek: Add MT6765 clock support Mars Cheng
2018-07-17 16:09   ` kbuild test robot
2018-07-17 18:52   ` kbuild test robot
2018-07-17 18:52   ` [RFC PATCH] clk: mediatek: cksys_base can be static kbuild test robot
2018-07-17  8:52 ` [PATCH v5 11/11] arm64: dts: mediatek: add mt6765 support Mars Cheng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).