All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V4 00/13] Add driver for dvfsrc, support for active state of scpsys
@ 2020-03-13  9:34 ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Fan Chen, James Liao, Arvin Wang,
	Mike Turquette, devicetree, linux-arm-kernel, linux-mediatek,
	linux-kernel, linux-pm, srv_heupstream

The patchsets add support for MediaTek hardware module named DVFSRC
(dynamic voltage and frequency scaling resource collector). The DVFSRC is
a HW module which is used to collect all the requests from both software
and hardware and turn into the decision of minimum operating voltage and
minimum DRAM frequency to fulfill those requests.

So, This series is to implement the dvfsrc driver to collect all the
requests of operating voltage or DRAM bandwidth from other device drivers
likes GPU/Camera through 3 frameworks basically:

1. interconnect framework: to aggregate the bandwidth
   requirements from different clients

[1] https://patchwork.kernel.org/cover/10766329/

Below is the emi bandwidth map of mt8183. There has a hw module "DRAM scheduler"
which used to control the throughput. The DVFSRC will collect forecast data
of dram bandwidth from SW consumers(camera/gpu...), and according the forecast
to change the DRAM frequency

           ICC provider         ICC Nodes
                            ----          ----
           ---------       |CPU |   |--->|VPU |
  -----   |         |-----> ----    |     ----
 |DRAM |--|DRAM     |       ----    |     ----
 |     |--|scheduler|----->|GPU |   |--->|DISP|
 |     |--|(EMI)    |       ----    |     ----
 |     |--|         |       -----   |     ----
  -----   |         |----->|MMSYS|--|--->|VDEC|
           ---------        -----   |     ----
             /|\                    |     ----
              |change DRAM freq     |--->|VENC|
           ----------               |     ----
          |  DVFSR   |              |
          |          |              |     ----
           ----------               |--->|IMG |
                                    |     ----
                                    |     ----
                                    |--->|CAM |
                                          ----

2. Active state management of power domains[1]: to handle the operating
   voltage/dram opp requirement from different power domains

[2] https://lwn.net/Articles/744047/

3. Regualtor framework: to handle the operating voltage requirement from user or
   cosumer which not belong any power domain

Changes in V4:
* Add acked TAG on dt-bindings patches. (Rob)
* Declaration of emi_icc_aggregate since the prototype of aggregate function
has changed meanwhile. (Georgi)
* Used emi_icc_remove instead of icc_provider_del on probe. (Georgi)
* Add dvfsrc regulator driver into series.
* Bug fixed of mt8183_get_current_level.
* Add mutex protection for pstate operation on dvfsrc_set_performance.

Changes in V3:
* Remove RFC from the subject prefix of the series
* Combine dt-binding patch and move interconnect dt-binding document into
dvfsrc. (Rob)
* Remove unused header, add unit descirption to the bandwidth, rename compatible
name on interconnect driver. (Georgi)
* Fixed some coding style: check flow, naming, used readx_poll_timeout
on dvfsrc driver. (Ryan)
* Rename interconnect driver mt8183.c to mtk-emi.c
* Rename interconnect header mtk,mt8183.h to mtk,emi.h
* mtk-scpsys.c: Add opp table check first to avoid OF runtime parse failed

Changes in RFC V2:
* Remove the DT property dram_type. (Rob)
* Used generic dts property 'opp-level' to get the performace state. (Stephen)
* Remove unecessary dependency config on Kconfig. (Stephen)
* Remove unused header file, fixed some coding style issue, typo,
error handling on dvfsrc driver. (Nicolas/Stephen)
* Remove irq handler on dvfsrc driver. (Stephen)
* Remove init table on dvfsrc driver, combine hw init on trustzone.
* Add interconnect support of mt8183 to aggregate the emi bandwidth.
(Georgi)

V3: https://patchwork.kernel.org/cover/11118867/
RFC V2: https://lore.kernel.org/patchwork/patch/1068113/
RFC V1: https://lore.kernel.org/patchwork/cover/1028535/

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

* [PATCH V4 00/13] Add driver for dvfsrc, support for active state of scpsys
@ 2020-03-13  9:34 ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, Fan Chen, devicetree,
	linux-mediatek, Arvin Wang, linux-arm-kernel

The patchsets add support for MediaTek hardware module named DVFSRC
(dynamic voltage and frequency scaling resource collector). The DVFSRC is
a HW module which is used to collect all the requests from both software
and hardware and turn into the decision of minimum operating voltage and
minimum DRAM frequency to fulfill those requests.

So, This series is to implement the dvfsrc driver to collect all the
requests of operating voltage or DRAM bandwidth from other device drivers
likes GPU/Camera through 3 frameworks basically:

1. interconnect framework: to aggregate the bandwidth
   requirements from different clients

[1] https://patchwork.kernel.org/cover/10766329/

Below is the emi bandwidth map of mt8183. There has a hw module "DRAM scheduler"
which used to control the throughput. The DVFSRC will collect forecast data
of dram bandwidth from SW consumers(camera/gpu...), and according the forecast
to change the DRAM frequency

           ICC provider         ICC Nodes
                            ----          ----
           ---------       |CPU |   |--->|VPU |
  -----   |         |-----> ----    |     ----
 |DRAM |--|DRAM     |       ----    |     ----
 |     |--|scheduler|----->|GPU |   |--->|DISP|
 |     |--|(EMI)    |       ----    |     ----
 |     |--|         |       -----   |     ----
  -----   |         |----->|MMSYS|--|--->|VDEC|
           ---------        -----   |     ----
             /|\                    |     ----
              |change DRAM freq     |--->|VENC|
           ----------               |     ----
          |  DVFSR   |              |
          |          |              |     ----
           ----------               |--->|IMG |
                                    |     ----
                                    |     ----
                                    |--->|CAM |
                                          ----

2. Active state management of power domains[1]: to handle the operating
   voltage/dram opp requirement from different power domains

[2] https://lwn.net/Articles/744047/

3. Regualtor framework: to handle the operating voltage requirement from user or
   cosumer which not belong any power domain

Changes in V4:
* Add acked TAG on dt-bindings patches. (Rob)
* Declaration of emi_icc_aggregate since the prototype of aggregate function
has changed meanwhile. (Georgi)
* Used emi_icc_remove instead of icc_provider_del on probe. (Georgi)
* Add dvfsrc regulator driver into series.
* Bug fixed of mt8183_get_current_level.
* Add mutex protection for pstate operation on dvfsrc_set_performance.

Changes in V3:
* Remove RFC from the subject prefix of the series
* Combine dt-binding patch and move interconnect dt-binding document into
dvfsrc. (Rob)
* Remove unused header, add unit descirption to the bandwidth, rename compatible
name on interconnect driver. (Georgi)
* Fixed some coding style: check flow, naming, used readx_poll_timeout
on dvfsrc driver. (Ryan)
* Rename interconnect driver mt8183.c to mtk-emi.c
* Rename interconnect header mtk,mt8183.h to mtk,emi.h
* mtk-scpsys.c: Add opp table check first to avoid OF runtime parse failed

Changes in RFC V2:
* Remove the DT property dram_type. (Rob)
* Used generic dts property 'opp-level' to get the performace state. (Stephen)
* Remove unecessary dependency config on Kconfig. (Stephen)
* Remove unused header file, fixed some coding style issue, typo,
error handling on dvfsrc driver. (Nicolas/Stephen)
* Remove irq handler on dvfsrc driver. (Stephen)
* Remove init table on dvfsrc driver, combine hw init on trustzone.
* Add interconnect support of mt8183 to aggregate the emi bandwidth.
(Georgi)

V3: https://patchwork.kernel.org/cover/11118867/
RFC V2: https://lore.kernel.org/patchwork/patch/1068113/
RFC V1: https://lore.kernel.org/patchwork/cover/1028535/
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

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

* [PATCH V4 00/13] Add driver for dvfsrc, support for active state of scpsys
@ 2020-03-13  9:34 ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, Fan Chen, devicetree,
	linux-mediatek, Arvin Wang, linux-arm-kernel

The patchsets add support for MediaTek hardware module named DVFSRC
(dynamic voltage and frequency scaling resource collector). The DVFSRC is
a HW module which is used to collect all the requests from both software
and hardware and turn into the decision of minimum operating voltage and
minimum DRAM frequency to fulfill those requests.

So, This series is to implement the dvfsrc driver to collect all the
requests of operating voltage or DRAM bandwidth from other device drivers
likes GPU/Camera through 3 frameworks basically:

1. interconnect framework: to aggregate the bandwidth
   requirements from different clients

[1] https://patchwork.kernel.org/cover/10766329/

Below is the emi bandwidth map of mt8183. There has a hw module "DRAM scheduler"
which used to control the throughput. The DVFSRC will collect forecast data
of dram bandwidth from SW consumers(camera/gpu...), and according the forecast
to change the DRAM frequency

           ICC provider         ICC Nodes
                            ----          ----
           ---------       |CPU |   |--->|VPU |
  -----   |         |-----> ----    |     ----
 |DRAM |--|DRAM     |       ----    |     ----
 |     |--|scheduler|----->|GPU |   |--->|DISP|
 |     |--|(EMI)    |       ----    |     ----
 |     |--|         |       -----   |     ----
  -----   |         |----->|MMSYS|--|--->|VDEC|
           ---------        -----   |     ----
             /|\                    |     ----
              |change DRAM freq     |--->|VENC|
           ----------               |     ----
          |  DVFSR   |              |
          |          |              |     ----
           ----------               |--->|IMG |
                                    |     ----
                                    |     ----
                                    |--->|CAM |
                                          ----

2. Active state management of power domains[1]: to handle the operating
   voltage/dram opp requirement from different power domains

[2] https://lwn.net/Articles/744047/

3. Regualtor framework: to handle the operating voltage requirement from user or
   cosumer which not belong any power domain

Changes in V4:
* Add acked TAG on dt-bindings patches. (Rob)
* Declaration of emi_icc_aggregate since the prototype of aggregate function
has changed meanwhile. (Georgi)
* Used emi_icc_remove instead of icc_provider_del on probe. (Georgi)
* Add dvfsrc regulator driver into series.
* Bug fixed of mt8183_get_current_level.
* Add mutex protection for pstate operation on dvfsrc_set_performance.

Changes in V3:
* Remove RFC from the subject prefix of the series
* Combine dt-binding patch and move interconnect dt-binding document into
dvfsrc. (Rob)
* Remove unused header, add unit descirption to the bandwidth, rename compatible
name on interconnect driver. (Georgi)
* Fixed some coding style: check flow, naming, used readx_poll_timeout
on dvfsrc driver. (Ryan)
* Rename interconnect driver mt8183.c to mtk-emi.c
* Rename interconnect header mtk,mt8183.h to mtk,emi.h
* mtk-scpsys.c: Add opp table check first to avoid OF runtime parse failed

Changes in RFC V2:
* Remove the DT property dram_type. (Rob)
* Used generic dts property 'opp-level' to get the performace state. (Stephen)
* Remove unecessary dependency config on Kconfig. (Stephen)
* Remove unused header file, fixed some coding style issue, typo,
error handling on dvfsrc driver. (Nicolas/Stephen)
* Remove irq handler on dvfsrc driver. (Stephen)
* Remove init table on dvfsrc driver, combine hw init on trustzone.
* Add interconnect support of mt8183 to aggregate the emi bandwidth.
(Georgi)

V3: https://patchwork.kernel.org/cover/11118867/
RFC V2: https://lore.kernel.org/patchwork/patch/1068113/
RFC V1: https://lore.kernel.org/patchwork/cover/1028535/
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V4 01/13] dt-bindings: soc: Add dvfsrc driver bindings
  2020-03-13  9:34 ` Henry Chen
  (?)
@ 2020-03-13  9:34   ` Henry Chen
  -1 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Fan Chen, James Liao, Arvin Wang,
	Mike Turquette, devicetree, linux-arm-kernel, linux-mediatek,
	linux-kernel, linux-pm, srv_heupstream, Henry Chen

Document the binding for enabling dvfsrc on MediaTek SoC.

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 .../devicetree/bindings/soc/mediatek/dvfsrc.txt    | 23 ++++++++++++++++++++++
 include/dt-bindings/soc/mtk,dvfsrc.h               | 14 +++++++++++++
 2 files changed, 37 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
 create mode 100644 include/dt-bindings/soc/mtk,dvfsrc.h

diff --git a/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
new file mode 100644
index 0000000..7f43499
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
@@ -0,0 +1,23 @@
+MediaTek DVFSRC
+
+The Dynamic Voltage and Frequency Scaling Resource Collector (DVFSRC) is a
+HW module which is used to collect all the requests from both software and
+hardware and turn into the decision of minimum operating voltage and minimum
+DRAM frequency to fulfill those requests.
+
+Required Properties:
+- compatible: Should be one of the following
+	- "mediatek,mt8183-dvfsrc": For MT8183 SoC
+- reg: Address range of the DVFSRC unit
+- clock-names: Must include the following entries:
+	"dvfsrc": DVFSRC module clock
+- clocks: Must contain an entry for each entry in clock-names.
+
+Example:
+
+	dvfsrc@10012000 {
+		compatible = "mediatek,mt8183-dvfsrc";
+		reg = <0 0x10012000 0 0x1000>;
+		clocks = <&infracfg CLK_INFRA_DVFSRC>;
+		clock-names = "dvfsrc";
+	};
diff --git a/include/dt-bindings/soc/mtk,dvfsrc.h b/include/dt-bindings/soc/mtk,dvfsrc.h
new file mode 100644
index 0000000..a522488
--- /dev/null
+++ b/include/dt-bindings/soc/mtk,dvfsrc.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ */
+
+#ifndef _DT_BINDINGS_POWER_MTK_DVFSRC_H
+#define _DT_BINDINGS_POWER_MTK_DVFSRC_H
+
+#define MT8183_DVFSRC_LEVEL_1	1
+#define MT8183_DVFSRC_LEVEL_2	2
+#define MT8183_DVFSRC_LEVEL_3	3
+#define MT8183_DVFSRC_LEVEL_4	4
+
+#endif /* _DT_BINDINGS_POWER_MTK_DVFSRC_H */
-- 
1.9.1

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

* [PATCH V4 01/13] dt-bindings: soc: Add dvfsrc driver bindings
@ 2020-03-13  9:34   ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, Henry Chen, Fan Chen,
	devicetree, linux-mediatek, Arvin Wang, linux-arm-kernel

Document the binding for enabling dvfsrc on MediaTek SoC.

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 .../devicetree/bindings/soc/mediatek/dvfsrc.txt    | 23 ++++++++++++++++++++++
 include/dt-bindings/soc/mtk,dvfsrc.h               | 14 +++++++++++++
 2 files changed, 37 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
 create mode 100644 include/dt-bindings/soc/mtk,dvfsrc.h

diff --git a/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
new file mode 100644
index 0000000..7f43499
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
@@ -0,0 +1,23 @@
+MediaTek DVFSRC
+
+The Dynamic Voltage and Frequency Scaling Resource Collector (DVFSRC) is a
+HW module which is used to collect all the requests from both software and
+hardware and turn into the decision of minimum operating voltage and minimum
+DRAM frequency to fulfill those requests.
+
+Required Properties:
+- compatible: Should be one of the following
+	- "mediatek,mt8183-dvfsrc": For MT8183 SoC
+- reg: Address range of the DVFSRC unit
+- clock-names: Must include the following entries:
+	"dvfsrc": DVFSRC module clock
+- clocks: Must contain an entry for each entry in clock-names.
+
+Example:
+
+	dvfsrc@10012000 {
+		compatible = "mediatek,mt8183-dvfsrc";
+		reg = <0 0x10012000 0 0x1000>;
+		clocks = <&infracfg CLK_INFRA_DVFSRC>;
+		clock-names = "dvfsrc";
+	};
diff --git a/include/dt-bindings/soc/mtk,dvfsrc.h b/include/dt-bindings/soc/mtk,dvfsrc.h
new file mode 100644
index 0000000..a522488
--- /dev/null
+++ b/include/dt-bindings/soc/mtk,dvfsrc.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ */
+
+#ifndef _DT_BINDINGS_POWER_MTK_DVFSRC_H
+#define _DT_BINDINGS_POWER_MTK_DVFSRC_H
+
+#define MT8183_DVFSRC_LEVEL_1	1
+#define MT8183_DVFSRC_LEVEL_2	2
+#define MT8183_DVFSRC_LEVEL_3	3
+#define MT8183_DVFSRC_LEVEL_4	4
+
+#endif /* _DT_BINDINGS_POWER_MTK_DVFSRC_H */
-- 
1.9.1
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

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

* [PATCH V4 01/13] dt-bindings: soc: Add dvfsrc driver bindings
@ 2020-03-13  9:34   ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, Henry Chen, Fan Chen,
	devicetree, linux-mediatek, Arvin Wang, linux-arm-kernel

Document the binding for enabling dvfsrc on MediaTek SoC.

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 .../devicetree/bindings/soc/mediatek/dvfsrc.txt    | 23 ++++++++++++++++++++++
 include/dt-bindings/soc/mtk,dvfsrc.h               | 14 +++++++++++++
 2 files changed, 37 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
 create mode 100644 include/dt-bindings/soc/mtk,dvfsrc.h

diff --git a/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
new file mode 100644
index 0000000..7f43499
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
@@ -0,0 +1,23 @@
+MediaTek DVFSRC
+
+The Dynamic Voltage and Frequency Scaling Resource Collector (DVFSRC) is a
+HW module which is used to collect all the requests from both software and
+hardware and turn into the decision of minimum operating voltage and minimum
+DRAM frequency to fulfill those requests.
+
+Required Properties:
+- compatible: Should be one of the following
+	- "mediatek,mt8183-dvfsrc": For MT8183 SoC
+- reg: Address range of the DVFSRC unit
+- clock-names: Must include the following entries:
+	"dvfsrc": DVFSRC module clock
+- clocks: Must contain an entry for each entry in clock-names.
+
+Example:
+
+	dvfsrc@10012000 {
+		compatible = "mediatek,mt8183-dvfsrc";
+		reg = <0 0x10012000 0 0x1000>;
+		clocks = <&infracfg CLK_INFRA_DVFSRC>;
+		clock-names = "dvfsrc";
+	};
diff --git a/include/dt-bindings/soc/mtk,dvfsrc.h b/include/dt-bindings/soc/mtk,dvfsrc.h
new file mode 100644
index 0000000..a522488
--- /dev/null
+++ b/include/dt-bindings/soc/mtk,dvfsrc.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ */
+
+#ifndef _DT_BINDINGS_POWER_MTK_DVFSRC_H
+#define _DT_BINDINGS_POWER_MTK_DVFSRC_H
+
+#define MT8183_DVFSRC_LEVEL_1	1
+#define MT8183_DVFSRC_LEVEL_2	2
+#define MT8183_DVFSRC_LEVEL_3	3
+#define MT8183_DVFSRC_LEVEL_4	4
+
+#endif /* _DT_BINDINGS_POWER_MTK_DVFSRC_H */
-- 
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V4 02/13] dt-bindings: soc: Add opp table on scpsys bindings
  2020-03-13  9:34 ` Henry Chen
  (?)
@ 2020-03-13  9:34   ` Henry Chen
  -1 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Fan Chen, James Liao, Arvin Wang,
	Mike Turquette, devicetree, linux-arm-kernel, linux-mediatek,
	linux-kernel, linux-pm, srv_heupstream, Henry Chen

Add opp table on scpsys dt-bindings for Mediatek SoC.

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 .../devicetree/bindings/soc/mediatek/scpsys.txt    | 42 ++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
index 1baaa6f..d22f11d 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
+++ b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
@@ -70,6 +70,10 @@ Optional properties:
 - mfg_2d-supply: Power supply for the mfg_2d power domain
 - mfg-supply: Power supply for the mfg power domain
 
+- operating-points-v2: Phandle to the OPP table for the Power domain.
+	Refer to Documentation/devicetree/bindings/power/power_domain.txt
+	and Documentation/devicetree/bindings/opp/opp.txt for more details
+
 Example:
 
 	scpsys: scpsys@10006000 {
@@ -82,6 +86,27 @@ Example:
 			 <&topckgen CLK_TOP_VENC_SEL>,
 			 <&topckgen CLK_TOP_VENC_LT_SEL>;
 		clock-names = "mfg", "mm", "venc", "venc_lt";
+		operating-points-v2 = <&dvfsrc_opp_table>;
+
+		dvfsrc_opp_table: opp-table {
+			compatible = "operating-points-v2-level";
+
+			dvfsrc_vol_min: opp1 {
+				opp,level = <MT8183_DVFSRC_LEVEL_1>;
+			};
+
+			dvfsrc_freq_medium: opp2 {
+				opp,level = <MT8183_DVFSRC_LEVEL_2>;
+			};
+
+			dvfsrc_freq_max: opp3 {
+				opp,level = <MT8183_DVFSRC_LEVEL_3>;
+			};
+
+			dvfsrc_vol_max: opp4 {
+				opp,level = <MT8183_DVFSRC_LEVEL_4>;
+			};
+		};
 	};
 
 Example consumer:
@@ -89,4 +114,21 @@ Example consumer:
 	afe: mt8173-afe-pcm@11220000 {
 		compatible = "mediatek,mt8173-afe-pcm";
 		power-domains = <&scpsys MT8173_POWER_DOMAIN_AUDIO>;
+		operating-points-v2 = <&aud_opp_table>;
+	};
+
+	aud_opp_table: aud-opp-table {
+		compatible = "operating-points-v2";
+		opp1 {
+			opp-hz = /bits/ 64 <793000000>;
+			required-opps = <&dvfsrc_vol_min>;
+		};
+		opp2 {
+			opp-hz = /bits/ 64 <910000000>;
+			required-opps = <&dvfsrc_vol_max>;
+		};
+		opp3 {
+			opp-hz = /bits/ 64 <1014000000>;
+			required-opps = <&dvfsrc_vol_max>;
+		};
 	};
-- 
1.9.1

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

* [PATCH V4 02/13] dt-bindings: soc: Add opp table on scpsys bindings
@ 2020-03-13  9:34   ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, Henry Chen, Fan Chen,
	devicetree, linux-mediatek, Arvin Wang, linux-arm-kernel

Add opp table on scpsys dt-bindings for Mediatek SoC.

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 .../devicetree/bindings/soc/mediatek/scpsys.txt    | 42 ++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
index 1baaa6f..d22f11d 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
+++ b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
@@ -70,6 +70,10 @@ Optional properties:
 - mfg_2d-supply: Power supply for the mfg_2d power domain
 - mfg-supply: Power supply for the mfg power domain
 
+- operating-points-v2: Phandle to the OPP table for the Power domain.
+	Refer to Documentation/devicetree/bindings/power/power_domain.txt
+	and Documentation/devicetree/bindings/opp/opp.txt for more details
+
 Example:
 
 	scpsys: scpsys@10006000 {
@@ -82,6 +86,27 @@ Example:
 			 <&topckgen CLK_TOP_VENC_SEL>,
 			 <&topckgen CLK_TOP_VENC_LT_SEL>;
 		clock-names = "mfg", "mm", "venc", "venc_lt";
+		operating-points-v2 = <&dvfsrc_opp_table>;
+
+		dvfsrc_opp_table: opp-table {
+			compatible = "operating-points-v2-level";
+
+			dvfsrc_vol_min: opp1 {
+				opp,level = <MT8183_DVFSRC_LEVEL_1>;
+			};
+
+			dvfsrc_freq_medium: opp2 {
+				opp,level = <MT8183_DVFSRC_LEVEL_2>;
+			};
+
+			dvfsrc_freq_max: opp3 {
+				opp,level = <MT8183_DVFSRC_LEVEL_3>;
+			};
+
+			dvfsrc_vol_max: opp4 {
+				opp,level = <MT8183_DVFSRC_LEVEL_4>;
+			};
+		};
 	};
 
 Example consumer:
@@ -89,4 +114,21 @@ Example consumer:
 	afe: mt8173-afe-pcm@11220000 {
 		compatible = "mediatek,mt8173-afe-pcm";
 		power-domains = <&scpsys MT8173_POWER_DOMAIN_AUDIO>;
+		operating-points-v2 = <&aud_opp_table>;
+	};
+
+	aud_opp_table: aud-opp-table {
+		compatible = "operating-points-v2";
+		opp1 {
+			opp-hz = /bits/ 64 <793000000>;
+			required-opps = <&dvfsrc_vol_min>;
+		};
+		opp2 {
+			opp-hz = /bits/ 64 <910000000>;
+			required-opps = <&dvfsrc_vol_max>;
+		};
+		opp3 {
+			opp-hz = /bits/ 64 <1014000000>;
+			required-opps = <&dvfsrc_vol_max>;
+		};
 	};
-- 
1.9.1
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

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

* [PATCH V4 02/13] dt-bindings: soc: Add opp table on scpsys bindings
@ 2020-03-13  9:34   ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, Henry Chen, Fan Chen,
	devicetree, linux-mediatek, Arvin Wang, linux-arm-kernel

Add opp table on scpsys dt-bindings for Mediatek SoC.

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 .../devicetree/bindings/soc/mediatek/scpsys.txt    | 42 ++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
index 1baaa6f..d22f11d 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
+++ b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
@@ -70,6 +70,10 @@ Optional properties:
 - mfg_2d-supply: Power supply for the mfg_2d power domain
 - mfg-supply: Power supply for the mfg power domain
 
+- operating-points-v2: Phandle to the OPP table for the Power domain.
+	Refer to Documentation/devicetree/bindings/power/power_domain.txt
+	and Documentation/devicetree/bindings/opp/opp.txt for more details
+
 Example:
 
 	scpsys: scpsys@10006000 {
@@ -82,6 +86,27 @@ Example:
 			 <&topckgen CLK_TOP_VENC_SEL>,
 			 <&topckgen CLK_TOP_VENC_LT_SEL>;
 		clock-names = "mfg", "mm", "venc", "venc_lt";
+		operating-points-v2 = <&dvfsrc_opp_table>;
+
+		dvfsrc_opp_table: opp-table {
+			compatible = "operating-points-v2-level";
+
+			dvfsrc_vol_min: opp1 {
+				opp,level = <MT8183_DVFSRC_LEVEL_1>;
+			};
+
+			dvfsrc_freq_medium: opp2 {
+				opp,level = <MT8183_DVFSRC_LEVEL_2>;
+			};
+
+			dvfsrc_freq_max: opp3 {
+				opp,level = <MT8183_DVFSRC_LEVEL_3>;
+			};
+
+			dvfsrc_vol_max: opp4 {
+				opp,level = <MT8183_DVFSRC_LEVEL_4>;
+			};
+		};
 	};
 
 Example consumer:
@@ -89,4 +114,21 @@ Example consumer:
 	afe: mt8173-afe-pcm@11220000 {
 		compatible = "mediatek,mt8173-afe-pcm";
 		power-domains = <&scpsys MT8173_POWER_DOMAIN_AUDIO>;
+		operating-points-v2 = <&aud_opp_table>;
+	};
+
+	aud_opp_table: aud-opp-table {
+		compatible = "operating-points-v2";
+		opp1 {
+			opp-hz = /bits/ 64 <793000000>;
+			required-opps = <&dvfsrc_vol_min>;
+		};
+		opp2 {
+			opp-hz = /bits/ 64 <910000000>;
+			required-opps = <&dvfsrc_vol_max>;
+		};
+		opp3 {
+			opp-hz = /bits/ 64 <1014000000>;
+			required-opps = <&dvfsrc_vol_max>;
+		};
 	};
-- 
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V4 03/13] soc: mediatek: add support for the performance state
  2020-03-13  9:34 ` Henry Chen
  (?)
@ 2020-03-13  9:34   ` Henry Chen
  -1 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Fan Chen, James Liao, Arvin Wang,
	Mike Turquette, devicetree, linux-arm-kernel, linux-mediatek,
	linux-kernel, linux-pm, srv_heupstream, Henry Chen

Support power domain performance state, add header file for scp event.

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 drivers/soc/mediatek/mtk-scpsys.c | 58 +++++++++++++++++++++++++++++++++++++++
 drivers/soc/mediatek/mtk-scpsys.h | 22 +++++++++++++++
 2 files changed, 80 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-scpsys.h

diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
index 8538408..add75a5 100644
--- a/drivers/soc/mediatek/mtk-scpsys.c
+++ b/drivers/soc/mediatek/mtk-scpsys.c
@@ -10,8 +10,10 @@
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
+#include <linux/pm_opp.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 #include "scpsys.h"
 
 #include <dt-bindings/power/mt2701-power.h>
@@ -21,6 +23,7 @@
 #include <dt-bindings/power/mt7623a-power.h>
 #include <dt-bindings/power/mt8173-power.h>
 #include <dt-bindings/power/mt8183-power.h>
+#include "mtk-scpsys.h"
 
 #define MTK_POLL_DELAY_US   10
 #define MTK_POLL_TIMEOUT    USEC_PER_SEC
@@ -150,6 +153,18 @@ struct scp_soc_data {
 	const struct scp_ctrl_reg regs;
 };
 
+static BLOCKING_NOTIFIER_HEAD(scpsys_notifier_list);
+
+int register_scpsys_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_register(&scpsys_notifier_list, nb);
+}
+
+int unregister_scpsys_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_unregister(&scpsys_notifier_list, nb);
+}
+
 static int scpsys_domain_is_on(struct scp_domain *scpd)
 {
 	struct scp *scp = scpd->scp;
@@ -550,6 +565,41 @@ static int init_basic_clks(struct platform_device *pdev, struct clk **clk,
 	return 0;
 }
 
+static int mtk_pd_set_performance(struct generic_pm_domain *genpd,
+				  unsigned int state)
+{
+	int i;
+	struct scp_domain *scpd =
+		container_of(genpd, struct scp_domain, genpd);
+	struct scp_event_data scpe;
+	struct scp *scp = scpd->scp;
+	struct genpd_onecell_data *pd_data = &scp->pd_data;
+
+	for (i = 0; i < pd_data->num_domains; i++) {
+		if (genpd == pd_data->domains[i]) {
+			dev_dbg(scp->dev, "%d. %s = %d\n",
+				i, genpd->name, state);
+			break;
+		}
+	}
+
+	if (i == pd_data->num_domains)
+		return 0;
+
+	scpe.event_type = MTK_SCPSYS_PSTATE;
+	scpe.genpd = genpd;
+	scpe.domain_id = i;
+	blocking_notifier_call_chain(&scpsys_notifier_list, state, &scpe);
+
+	return 0;
+}
+
+static unsigned int mtk_pd_get_performance(struct generic_pm_domain *genpd,
+					   struct dev_pm_opp *opp)
+{
+	return dev_pm_opp_get_level(opp);
+}
+
 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)
@@ -650,6 +700,14 @@ static struct scp *init_scp(struct platform_device *pdev,
 		genpd->power_on = scpsys_power_on;
 		if (MTK_SCPD_CAPS(scpd, MTK_SCPD_ACTIVE_WAKEUP))
 			genpd->flags |= GENPD_FLAG_ACTIVE_WAKEUP;
+
+		/* Add opp table check first to avoid OF runtime parse failed */
+		if (of_count_phandle_with_args(pdev->dev.of_node,
+		    "operating-points-v2", NULL) > 0) {
+			genpd->set_performance_state = mtk_pd_set_performance;
+			genpd->opp_to_performance_state =
+				mtk_pd_get_performance;
+		}
 	}
 
 	return scp;
diff --git a/drivers/soc/mediatek/mtk-scpsys.h b/drivers/soc/mediatek/mtk-scpsys.h
new file mode 100644
index 0000000..c1e8325
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-scpsys.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ */
+
+#ifndef __MTK_SCPSYS_H__
+#define __MTK_SCPSYS_H__
+
+struct scp_event_data {
+	int event_type;
+	int domain_id;
+	struct generic_pm_domain *genpd;
+};
+
+enum scp_event_type {
+	MTK_SCPSYS_PSTATE,
+};
+
+int register_scpsys_notifier(struct notifier_block *nb);
+int unregister_scpsys_notifier(struct notifier_block *nb);
+
+#endif /* __MTK_SCPSYS_H__ */
-- 
1.9.1

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

* [PATCH V4 03/13] soc: mediatek: add support for the performance state
@ 2020-03-13  9:34   ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, Henry Chen, Fan Chen,
	devicetree, linux-mediatek, Arvin Wang, linux-arm-kernel

Support power domain performance state, add header file for scp event.

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 drivers/soc/mediatek/mtk-scpsys.c | 58 +++++++++++++++++++++++++++++++++++++++
 drivers/soc/mediatek/mtk-scpsys.h | 22 +++++++++++++++
 2 files changed, 80 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-scpsys.h

diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
index 8538408..add75a5 100644
--- a/drivers/soc/mediatek/mtk-scpsys.c
+++ b/drivers/soc/mediatek/mtk-scpsys.c
@@ -10,8 +10,10 @@
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
+#include <linux/pm_opp.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 #include "scpsys.h"
 
 #include <dt-bindings/power/mt2701-power.h>
@@ -21,6 +23,7 @@
 #include <dt-bindings/power/mt7623a-power.h>
 #include <dt-bindings/power/mt8173-power.h>
 #include <dt-bindings/power/mt8183-power.h>
+#include "mtk-scpsys.h"
 
 #define MTK_POLL_DELAY_US   10
 #define MTK_POLL_TIMEOUT    USEC_PER_SEC
@@ -150,6 +153,18 @@ struct scp_soc_data {
 	const struct scp_ctrl_reg regs;
 };
 
+static BLOCKING_NOTIFIER_HEAD(scpsys_notifier_list);
+
+int register_scpsys_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_register(&scpsys_notifier_list, nb);
+}
+
+int unregister_scpsys_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_unregister(&scpsys_notifier_list, nb);
+}
+
 static int scpsys_domain_is_on(struct scp_domain *scpd)
 {
 	struct scp *scp = scpd->scp;
@@ -550,6 +565,41 @@ static int init_basic_clks(struct platform_device *pdev, struct clk **clk,
 	return 0;
 }
 
+static int mtk_pd_set_performance(struct generic_pm_domain *genpd,
+				  unsigned int state)
+{
+	int i;
+	struct scp_domain *scpd =
+		container_of(genpd, struct scp_domain, genpd);
+	struct scp_event_data scpe;
+	struct scp *scp = scpd->scp;
+	struct genpd_onecell_data *pd_data = &scp->pd_data;
+
+	for (i = 0; i < pd_data->num_domains; i++) {
+		if (genpd == pd_data->domains[i]) {
+			dev_dbg(scp->dev, "%d. %s = %d\n",
+				i, genpd->name, state);
+			break;
+		}
+	}
+
+	if (i == pd_data->num_domains)
+		return 0;
+
+	scpe.event_type = MTK_SCPSYS_PSTATE;
+	scpe.genpd = genpd;
+	scpe.domain_id = i;
+	blocking_notifier_call_chain(&scpsys_notifier_list, state, &scpe);
+
+	return 0;
+}
+
+static unsigned int mtk_pd_get_performance(struct generic_pm_domain *genpd,
+					   struct dev_pm_opp *opp)
+{
+	return dev_pm_opp_get_level(opp);
+}
+
 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)
@@ -650,6 +700,14 @@ static struct scp *init_scp(struct platform_device *pdev,
 		genpd->power_on = scpsys_power_on;
 		if (MTK_SCPD_CAPS(scpd, MTK_SCPD_ACTIVE_WAKEUP))
 			genpd->flags |= GENPD_FLAG_ACTIVE_WAKEUP;
+
+		/* Add opp table check first to avoid OF runtime parse failed */
+		if (of_count_phandle_with_args(pdev->dev.of_node,
+		    "operating-points-v2", NULL) > 0) {
+			genpd->set_performance_state = mtk_pd_set_performance;
+			genpd->opp_to_performance_state =
+				mtk_pd_get_performance;
+		}
 	}
 
 	return scp;
diff --git a/drivers/soc/mediatek/mtk-scpsys.h b/drivers/soc/mediatek/mtk-scpsys.h
new file mode 100644
index 0000000..c1e8325
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-scpsys.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ */
+
+#ifndef __MTK_SCPSYS_H__
+#define __MTK_SCPSYS_H__
+
+struct scp_event_data {
+	int event_type;
+	int domain_id;
+	struct generic_pm_domain *genpd;
+};
+
+enum scp_event_type {
+	MTK_SCPSYS_PSTATE,
+};
+
+int register_scpsys_notifier(struct notifier_block *nb);
+int unregister_scpsys_notifier(struct notifier_block *nb);
+
+#endif /* __MTK_SCPSYS_H__ */
-- 
1.9.1
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

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

* [PATCH V4 03/13] soc: mediatek: add support for the performance state
@ 2020-03-13  9:34   ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, Henry Chen, Fan Chen,
	devicetree, linux-mediatek, Arvin Wang, linux-arm-kernel

Support power domain performance state, add header file for scp event.

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 drivers/soc/mediatek/mtk-scpsys.c | 58 +++++++++++++++++++++++++++++++++++++++
 drivers/soc/mediatek/mtk-scpsys.h | 22 +++++++++++++++
 2 files changed, 80 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-scpsys.h

diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
index 8538408..add75a5 100644
--- a/drivers/soc/mediatek/mtk-scpsys.c
+++ b/drivers/soc/mediatek/mtk-scpsys.c
@@ -10,8 +10,10 @@
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
+#include <linux/pm_opp.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 #include "scpsys.h"
 
 #include <dt-bindings/power/mt2701-power.h>
@@ -21,6 +23,7 @@
 #include <dt-bindings/power/mt7623a-power.h>
 #include <dt-bindings/power/mt8173-power.h>
 #include <dt-bindings/power/mt8183-power.h>
+#include "mtk-scpsys.h"
 
 #define MTK_POLL_DELAY_US   10
 #define MTK_POLL_TIMEOUT    USEC_PER_SEC
@@ -150,6 +153,18 @@ struct scp_soc_data {
 	const struct scp_ctrl_reg regs;
 };
 
+static BLOCKING_NOTIFIER_HEAD(scpsys_notifier_list);
+
+int register_scpsys_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_register(&scpsys_notifier_list, nb);
+}
+
+int unregister_scpsys_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_unregister(&scpsys_notifier_list, nb);
+}
+
 static int scpsys_domain_is_on(struct scp_domain *scpd)
 {
 	struct scp *scp = scpd->scp;
@@ -550,6 +565,41 @@ static int init_basic_clks(struct platform_device *pdev, struct clk **clk,
 	return 0;
 }
 
+static int mtk_pd_set_performance(struct generic_pm_domain *genpd,
+				  unsigned int state)
+{
+	int i;
+	struct scp_domain *scpd =
+		container_of(genpd, struct scp_domain, genpd);
+	struct scp_event_data scpe;
+	struct scp *scp = scpd->scp;
+	struct genpd_onecell_data *pd_data = &scp->pd_data;
+
+	for (i = 0; i < pd_data->num_domains; i++) {
+		if (genpd == pd_data->domains[i]) {
+			dev_dbg(scp->dev, "%d. %s = %d\n",
+				i, genpd->name, state);
+			break;
+		}
+	}
+
+	if (i == pd_data->num_domains)
+		return 0;
+
+	scpe.event_type = MTK_SCPSYS_PSTATE;
+	scpe.genpd = genpd;
+	scpe.domain_id = i;
+	blocking_notifier_call_chain(&scpsys_notifier_list, state, &scpe);
+
+	return 0;
+}
+
+static unsigned int mtk_pd_get_performance(struct generic_pm_domain *genpd,
+					   struct dev_pm_opp *opp)
+{
+	return dev_pm_opp_get_level(opp);
+}
+
 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)
@@ -650,6 +700,14 @@ static struct scp *init_scp(struct platform_device *pdev,
 		genpd->power_on = scpsys_power_on;
 		if (MTK_SCPD_CAPS(scpd, MTK_SCPD_ACTIVE_WAKEUP))
 			genpd->flags |= GENPD_FLAG_ACTIVE_WAKEUP;
+
+		/* Add opp table check first to avoid OF runtime parse failed */
+		if (of_count_phandle_with_args(pdev->dev.of_node,
+		    "operating-points-v2", NULL) > 0) {
+			genpd->set_performance_state = mtk_pd_set_performance;
+			genpd->opp_to_performance_state =
+				mtk_pd_get_performance;
+		}
 	}
 
 	return scp;
diff --git a/drivers/soc/mediatek/mtk-scpsys.h b/drivers/soc/mediatek/mtk-scpsys.h
new file mode 100644
index 0000000..c1e8325
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-scpsys.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ */
+
+#ifndef __MTK_SCPSYS_H__
+#define __MTK_SCPSYS_H__
+
+struct scp_event_data {
+	int event_type;
+	int domain_id;
+	struct generic_pm_domain *genpd;
+};
+
+enum scp_event_type {
+	MTK_SCPSYS_PSTATE,
+};
+
+int register_scpsys_notifier(struct notifier_block *nb);
+int unregister_scpsys_notifier(struct notifier_block *nb);
+
+#endif /* __MTK_SCPSYS_H__ */
-- 
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V4 04/13] arm64: dts: mt8183: add performance state support of scpsys
  2020-03-13  9:34 ` Henry Chen
  (?)
@ 2020-03-13  9:34   ` Henry Chen
  -1 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Fan Chen, James Liao, Arvin Wang,
	Mike Turquette, devicetree, linux-arm-kernel, linux-mediatek,
	linux-kernel, linux-pm, srv_heupstream, Henry Chen

Add support for performance state of scpsys on mt8183 platform

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8183.dtsi | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index 433c62e..7bf20ca 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -11,6 +11,7 @@
 #include <dt-bindings/power/mt8183-power.h>
 #include <dt-bindings/reset-controller/mt8183-resets.h>
 #include "mt8183-pinfunc.h"
+#include <dt-bindings/soc/mtk,dvfsrc.h>
 
 / {
 	compatible = "mediatek,mt8183";
@@ -310,6 +311,26 @@
 				      "vpu-3", "vpu-4", "vpu-5";
 			infracfg = <&infracfg>;
 			smi_comm = <&smi_common>;
+			operating-points-v2 = <&dvfsrc_opp_table>;
+			dvfsrc_opp_table: opp-table {
+				compatible = "operating-points-v2-level";
+
+				dvfsrc_vol_min: opp1 {
+					opp,level = <MT8183_DVFSRC_LEVEL_1>;
+				};
+
+				dvfsrc_freq_medium: opp2 {
+					opp,level = <MT8183_DVFSRC_LEVEL_2>;
+				};
+
+				dvfsrc_freq_max: opp3 {
+					opp,level = <MT8183_DVFSRC_LEVEL_3>;
+				};
+
+				dvfsrc_vol_max: opp4 {
+					opp,level = <MT8183_DVFSRC_LEVEL_4>;
+				};
+			};
 		};
 
 		apmixedsys: syscon@1000c000 {
-- 
1.9.1

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

* [PATCH V4 04/13] arm64: dts: mt8183: add performance state support of scpsys
@ 2020-03-13  9:34   ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, Henry Chen, Fan Chen,
	devicetree, linux-mediatek, Arvin Wang, linux-arm-kernel

Add support for performance state of scpsys on mt8183 platform

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8183.dtsi | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index 433c62e..7bf20ca 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -11,6 +11,7 @@
 #include <dt-bindings/power/mt8183-power.h>
 #include <dt-bindings/reset-controller/mt8183-resets.h>
 #include "mt8183-pinfunc.h"
+#include <dt-bindings/soc/mtk,dvfsrc.h>
 
 / {
 	compatible = "mediatek,mt8183";
@@ -310,6 +311,26 @@
 				      "vpu-3", "vpu-4", "vpu-5";
 			infracfg = <&infracfg>;
 			smi_comm = <&smi_common>;
+			operating-points-v2 = <&dvfsrc_opp_table>;
+			dvfsrc_opp_table: opp-table {
+				compatible = "operating-points-v2-level";
+
+				dvfsrc_vol_min: opp1 {
+					opp,level = <MT8183_DVFSRC_LEVEL_1>;
+				};
+
+				dvfsrc_freq_medium: opp2 {
+					opp,level = <MT8183_DVFSRC_LEVEL_2>;
+				};
+
+				dvfsrc_freq_max: opp3 {
+					opp,level = <MT8183_DVFSRC_LEVEL_3>;
+				};
+
+				dvfsrc_vol_max: opp4 {
+					opp,level = <MT8183_DVFSRC_LEVEL_4>;
+				};
+			};
 		};
 
 		apmixedsys: syscon@1000c000 {
-- 
1.9.1
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

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

* [PATCH V4 04/13] arm64: dts: mt8183: add performance state support of scpsys
@ 2020-03-13  9:34   ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, Henry Chen, Fan Chen,
	devicetree, linux-mediatek, Arvin Wang, linux-arm-kernel

Add support for performance state of scpsys on mt8183 platform

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8183.dtsi | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index 433c62e..7bf20ca 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -11,6 +11,7 @@
 #include <dt-bindings/power/mt8183-power.h>
 #include <dt-bindings/reset-controller/mt8183-resets.h>
 #include "mt8183-pinfunc.h"
+#include <dt-bindings/soc/mtk,dvfsrc.h>
 
 / {
 	compatible = "mediatek,mt8183";
@@ -310,6 +311,26 @@
 				      "vpu-3", "vpu-4", "vpu-5";
 			infracfg = <&infracfg>;
 			smi_comm = <&smi_common>;
+			operating-points-v2 = <&dvfsrc_opp_table>;
+			dvfsrc_opp_table: opp-table {
+				compatible = "operating-points-v2-level";
+
+				dvfsrc_vol_min: opp1 {
+					opp,level = <MT8183_DVFSRC_LEVEL_1>;
+				};
+
+				dvfsrc_freq_medium: opp2 {
+					opp,level = <MT8183_DVFSRC_LEVEL_2>;
+				};
+
+				dvfsrc_freq_max: opp3 {
+					opp,level = <MT8183_DVFSRC_LEVEL_3>;
+				};
+
+				dvfsrc_vol_max: opp4 {
+					opp,level = <MT8183_DVFSRC_LEVEL_4>;
+				};
+			};
 		};
 
 		apmixedsys: syscon@1000c000 {
-- 
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V4 05/13] soc: mediatek: add header for mediatek SIP interface
  2020-03-13  9:34 ` Henry Chen
  (?)
@ 2020-03-13  9:34   ` Henry Chen
  -1 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Fan Chen, James Liao, Arvin Wang,
	Mike Turquette, devicetree, linux-arm-kernel, linux-mediatek,
	linux-kernel, linux-pm, srv_heupstream, Henry Chen

Add a header to collect SIPs and add one SIP call to initialize power
management hardware for the SIP interface defined to access the SPM
handling vcore voltage and ddr rate changes on mt8183 (and most likely
later socs).

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 include/soc/mediatek/mtk_sip.h | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
 create mode 100644 include/soc/mediatek/mtk_sip.h

diff --git a/include/soc/mediatek/mtk_sip.h b/include/soc/mediatek/mtk_sip.h
new file mode 100644
index 0000000..945fc72
--- /dev/null
+++ b/include/soc/mediatek/mtk_sip.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ */
+#ifndef __SOC_MTK_SIP_H
+#define __SOC_MTK_SIP_H
+
+#ifdef CONFIG_ARM64
+#define MTK_SIP_SMC_AARCH_BIT		0x40000000
+#else
+#define MTK_SIP_SMC_AARCH_BIT		0x00000000
+#endif
+
+#define MTK_SIP_SPM			(0x82000506 | MTK_SIP_SMC_AARCH_BIT)
+#define MTK_SIP_SPM_DVFSRC_INIT		0x00
+
+#endif
-- 
1.9.1

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

* [PATCH V4 05/13] soc: mediatek: add header for mediatek SIP interface
@ 2020-03-13  9:34   ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, Henry Chen, Fan Chen,
	devicetree, linux-mediatek, Arvin Wang, linux-arm-kernel

Add a header to collect SIPs and add one SIP call to initialize power
management hardware for the SIP interface defined to access the SPM
handling vcore voltage and ddr rate changes on mt8183 (and most likely
later socs).

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 include/soc/mediatek/mtk_sip.h | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
 create mode 100644 include/soc/mediatek/mtk_sip.h

diff --git a/include/soc/mediatek/mtk_sip.h b/include/soc/mediatek/mtk_sip.h
new file mode 100644
index 0000000..945fc72
--- /dev/null
+++ b/include/soc/mediatek/mtk_sip.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ */
+#ifndef __SOC_MTK_SIP_H
+#define __SOC_MTK_SIP_H
+
+#ifdef CONFIG_ARM64
+#define MTK_SIP_SMC_AARCH_BIT		0x40000000
+#else
+#define MTK_SIP_SMC_AARCH_BIT		0x00000000
+#endif
+
+#define MTK_SIP_SPM			(0x82000506 | MTK_SIP_SMC_AARCH_BIT)
+#define MTK_SIP_SPM_DVFSRC_INIT		0x00
+
+#endif
-- 
1.9.1
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

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

* [PATCH V4 05/13] soc: mediatek: add header for mediatek SIP interface
@ 2020-03-13  9:34   ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, Henry Chen, Fan Chen,
	devicetree, linux-mediatek, Arvin Wang, linux-arm-kernel

Add a header to collect SIPs and add one SIP call to initialize power
management hardware for the SIP interface defined to access the SPM
handling vcore voltage and ddr rate changes on mt8183 (and most likely
later socs).

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 include/soc/mediatek/mtk_sip.h | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
 create mode 100644 include/soc/mediatek/mtk_sip.h

diff --git a/include/soc/mediatek/mtk_sip.h b/include/soc/mediatek/mtk_sip.h
new file mode 100644
index 0000000..945fc72
--- /dev/null
+++ b/include/soc/mediatek/mtk_sip.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ */
+#ifndef __SOC_MTK_SIP_H
+#define __SOC_MTK_SIP_H
+
+#ifdef CONFIG_ARM64
+#define MTK_SIP_SMC_AARCH_BIT		0x40000000
+#else
+#define MTK_SIP_SMC_AARCH_BIT		0x00000000
+#endif
+
+#define MTK_SIP_SPM			(0x82000506 | MTK_SIP_SMC_AARCH_BIT)
+#define MTK_SIP_SPM_DVFSRC_INIT		0x00
+
+#endif
-- 
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V4 06/13] soc: mediatek: add MT8183 dvfsrc support
  2020-03-13  9:34 ` Henry Chen
  (?)
@ 2020-03-13  9:34   ` Henry Chen
  -1 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Fan Chen, James Liao, Arvin Wang,
	Mike Turquette, devicetree, linux-arm-kernel, linux-mediatek,
	linux-kernel, linux-pm, srv_heupstream, Henry Chen

Add dvfsrc driver for MT8183

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 drivers/soc/mediatek/Kconfig      |  15 ++
 drivers/soc/mediatek/Makefile     |   1 +
 drivers/soc/mediatek/mtk-dvfsrc.c | 434 ++++++++++++++++++++++++++++++++++++++
 include/soc/mediatek/mtk_dvfsrc.h |  30 +++
 4 files changed, 480 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-dvfsrc.c
 create mode 100644 include/soc/mediatek/mtk_dvfsrc.h

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index f837b3c..44808f4 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -16,6 +16,21 @@ config MTK_CMDQ
 	  time limitation, such as updating display configuration during the
 	  vblank.
 
+config MTK_DVFSRC
+	bool "MediaTek DVFSRC Support"
+	depends on ARCH_MEDIATEK
+	default ARCH_MEDIATEK
+	select MTK_INFRACFG
+	select PM_GENERIC_DOMAINS if PM
+	depends on MTK_SCPSYS
+	help
+	  Say yes here to add support for the MediaTek DVFSRC (dynamic voltage
+	  and frequency scaling resource collector) found
+	  on different MediaTek SoCs. The DVFSRC is a proprietary
+	  hardware which is used to collect all the requests from
+	  system and turn into the decision of minimum Vcore voltage
+	  and minimum DRAM frequency to fulfill those requests.
+
 config MTK_PMIC_WRAP
 	tristate "MediaTek PMIC Wrapper Support"
 	depends on RESET_CONTROLLER
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 2b2c2537..84182f0 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
+obj-$(CONFIG_MTK_DVFSRC) += mtk-dvfsrc.o
 obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
 obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-dvfsrc.c b/drivers/soc/mediatek/mtk-dvfsrc.c
new file mode 100644
index 0000000..85b3572
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-dvfsrc.c
@@ -0,0 +1,434 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+#include <linux/arm-smccc.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <soc/mediatek/mtk_dvfsrc.h>
+#include <soc/mediatek/mtk_sip.h>
+#include <dt-bindings/power/mt8183-power.h>
+#include <dt-bindings/soc/mtk,dvfsrc.h>
+#include "mtk-scpsys.h"
+
+#define DVFSRC_IDLE     0x00
+#define DVFSRC_GET_TARGET_LEVEL(x)  (((x) >> 0) & 0x0000ffff)
+#define DVFSRC_GET_CURRENT_LEVEL(x) (((x) >> 16) & 0x0000ffff)
+#define kbps_to_mbps(x) ((x) / 1000)
+
+#define MT8183_DVFSRC_OPP_LP4   0
+#define MT8183_DVFSRC_OPP_LP4X  1
+#define MT8183_DVFSRC_OPP_LP3   2
+
+#define POLL_TIMEOUT        1000
+#define STARTUP_TIME        1
+
+struct dvfsrc_opp {
+	u32 vcore_opp;
+	u32 dram_opp;
+};
+
+struct dvfsrc_domain {
+	u32 id;
+	u32 state;
+};
+
+struct mtk_dvfsrc;
+struct dvfsrc_soc_data {
+	const int *regs;
+	u32 num_opp;
+	u32 num_domains;
+	const struct dvfsrc_opp **opps;
+	struct dvfsrc_domain *domains;
+	int (*get_target_level)(struct mtk_dvfsrc *dvfsrc);
+	int (*get_current_level)(struct mtk_dvfsrc *dvfsrc);
+	u32 (*get_vcore_level)(struct mtk_dvfsrc *dvfsrc);
+	void (*set_dram_bw)(struct mtk_dvfsrc *dvfsrc, u64 bw);
+	void (*set_opp_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
+	void (*set_vcore_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
+	int (*wait_for_opp_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
+	int (*wait_for_vcore_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
+};
+
+struct mtk_dvfsrc {
+	struct device *dev;
+	struct clk *clk_dvfsrc;
+	const struct dvfsrc_soc_data *dvd;
+	int dram_type;
+	void __iomem *regs;
+	struct mutex req_lock;
+	struct mutex pstate_lock;
+	struct notifier_block scpsys_notifier;
+};
+
+static u32 dvfsrc_read(struct mtk_dvfsrc *dvfs, u32 offset)
+{
+	return readl(dvfs->regs + dvfs->dvd->regs[offset]);
+}
+
+static void dvfsrc_write(struct mtk_dvfsrc *dvfs, u32 offset, u32 val)
+{
+	writel(val, dvfs->regs + dvfs->dvd->regs[offset]);
+}
+
+enum dvfsrc_regs {
+	DVFSRC_SW_REQ,
+	DVFSRC_SW_REQ2,
+	DVFSRC_LEVEL,
+	DVFSRC_SW_BW,
+	DVFSRC_LAST,
+};
+
+static const int mt8183_regs[] = {
+	[DVFSRC_SW_REQ] =	0x4,
+	[DVFSRC_SW_REQ2] =	0x8,
+	[DVFSRC_LEVEL] =	0xDC,
+	[DVFSRC_SW_BW] =	0x160,
+	[DVFSRC_LAST] =		0x308,
+};
+
+static const struct dvfsrc_opp *get_current_opp(struct mtk_dvfsrc *dvfsrc)
+{
+	int level;
+
+	level = dvfsrc->dvd->get_current_level(dvfsrc);
+	return &dvfsrc->dvd->opps[dvfsrc->dram_type][level];
+}
+
+static int dvfsrc_is_idle(struct mtk_dvfsrc *dvfsrc)
+{
+	if (!dvfsrc->dvd->get_target_level)
+		return true;
+
+	return dvfsrc->dvd->get_target_level(dvfsrc);
+}
+
+static int dvfsrc_wait_for_vcore_level(struct mtk_dvfsrc *dvfsrc, u32 level)
+{
+	const struct dvfsrc_opp *curr;
+
+	return readx_poll_timeout_atomic(get_current_opp, dvfsrc, curr,
+					 curr->vcore_opp >= level, STARTUP_TIME,
+					 POLL_TIMEOUT);
+}
+
+static int mt8183_wait_for_opp_level(struct mtk_dvfsrc *dvfsrc, u32 level)
+{
+	const struct dvfsrc_opp *target, *curr;
+	int ret;
+
+	target = &dvfsrc->dvd->opps[dvfsrc->dram_type][level];
+	ret = readx_poll_timeout(get_current_opp, dvfsrc, curr,
+				 curr->dram_opp >= target->dram_opp &&
+				 curr->vcore_opp >= target->vcore_opp,
+				 STARTUP_TIME, POLL_TIMEOUT);
+	if (ret < 0) {
+		dev_warn(dvfsrc->dev,
+			 "timeout, target: %u, dram: %d, vcore: %d\n", level,
+			 curr->dram_opp, curr->vcore_opp);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int mt8183_get_target_level(struct mtk_dvfsrc *dvfsrc)
+{
+	return DVFSRC_GET_TARGET_LEVEL(dvfsrc_read(dvfsrc, DVFSRC_LEVEL));
+}
+
+static int mt8183_get_current_level(struct mtk_dvfsrc *dvfsrc)
+{
+	int level;
+
+	/* HW level 0 is begin from 0x10000 */
+	level = DVFSRC_GET_CURRENT_LEVEL(dvfsrc_read(dvfsrc, DVFSRC_LEVEL));
+	/* Array index start from 0 */
+	return ffs(level) - 1;
+}
+
+static u32 mt8183_get_vcore_level(struct mtk_dvfsrc *dvfsrc)
+{
+	return (dvfsrc_read(dvfsrc, DVFSRC_SW_REQ2) >> 2) & 0x3;
+}
+
+static void mt8183_set_dram_bw(struct mtk_dvfsrc *dvfsrc, u64 bw)
+{
+	dvfsrc_write(dvfsrc, DVFSRC_SW_BW, kbps_to_mbps(bw) / 100);
+}
+
+static void mt8183_set_opp_level(struct mtk_dvfsrc *dvfsrc, u32 level)
+{
+	int vcore_opp, dram_opp;
+	const struct dvfsrc_opp *opp;
+
+	/* translate pstate to dvfsrc level, and set it to DVFSRC HW */
+	opp = &dvfsrc->dvd->opps[dvfsrc->dram_type][level];
+	vcore_opp = opp->vcore_opp;
+	dram_opp = opp->dram_opp;
+
+	dev_dbg(dvfsrc->dev, "vcore_opp: %d, dram_opp: %d\n",
+		vcore_opp, dram_opp);
+	dvfsrc_write(dvfsrc, DVFSRC_SW_REQ, dram_opp | vcore_opp << 2);
+}
+
+static void mt8183_set_vcore_level(struct mtk_dvfsrc *dvfsrc, u32 level)
+{
+	dvfsrc_write(dvfsrc, DVFSRC_SW_REQ2, level << 2);
+}
+
+void mtk_dvfsrc_send_request(const struct device *dev, u32 cmd, u64 data)
+{
+	int ret, state;
+	struct mtk_dvfsrc *dvfsrc = dev_get_drvdata(dev);
+
+	dev_dbg(dvfsrc->dev, "cmd: %d, data: %llu\n", cmd, data);
+
+	mutex_lock(&dvfsrc->req_lock);
+
+	switch (cmd) {
+	case MTK_DVFSRC_CMD_BW_REQUEST:
+		dvfsrc->dvd->set_dram_bw(dvfsrc, data);
+		goto out;
+	case MTK_DVFSRC_CMD_OPP_REQUEST:
+		dvfsrc->dvd->set_opp_level(dvfsrc, data);
+		break;
+	case MTK_DVFSRC_CMD_VCORE_REQUEST:
+		dvfsrc->dvd->set_vcore_level(dvfsrc, data);
+		break;
+	default:
+		dev_err(dvfsrc->dev, "unknown command: %d\n", cmd);
+		goto out;
+	}
+
+	/* DVFSRC need to wait at least 2T(~196ns) to handle request
+	 * after recieving command
+	 */
+	udelay(STARTUP_TIME);
+
+	ret = readx_poll_timeout(dvfsrc_is_idle, dvfsrc,
+				 state, state == DVFSRC_IDLE,
+				 STARTUP_TIME, POLL_TIMEOUT);
+
+	if (ret < 0) {
+		dev_warn(dvfsrc->dev,
+			 "%d: idle timeout, data: %llu, last: %d -> %d\n",
+			 cmd, data,
+			 dvfsrc->dvd->get_current_level(dvfsrc),
+			 dvfsrc->dvd->get_target_level(dvfsrc));
+		goto out;
+	}
+
+	if (cmd == MTK_DVFSRC_CMD_OPP_REQUEST)
+		dvfsrc->dvd->wait_for_opp_level(dvfsrc, data);
+	else
+		dvfsrc->dvd->wait_for_vcore_level(dvfsrc, data);
+
+out:
+	mutex_unlock(&dvfsrc->req_lock);
+}
+EXPORT_SYMBOL(mtk_dvfsrc_send_request);
+
+int mtk_dvfsrc_query_info(const struct device *dev, u32 cmd, int *data)
+{
+	struct mtk_dvfsrc *dvfsrc = dev_get_drvdata(dev);
+
+	switch (cmd) {
+	case MTK_DVFSRC_CMD_VCORE_QUERY:
+		*data = dvfsrc->dvd->get_vcore_level(dvfsrc);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(mtk_dvfsrc_query_info);
+
+static int dvfsrc_set_performance(struct notifier_block *b,
+				  unsigned long pstate, void *v)
+{
+	bool match = false;
+	int i;
+	struct mtk_dvfsrc *dvfsrc;
+	struct scp_event_data *sc = v;
+	struct dvfsrc_domain *d;
+	u32 highest;
+
+	if (sc->event_type != MTK_SCPSYS_PSTATE)
+		return 0;
+
+	dvfsrc = container_of(b, struct mtk_dvfsrc, scpsys_notifier);
+
+	d = dvfsrc->dvd->domains;
+
+	if (pstate > dvfsrc->dvd->num_opp) {
+		dev_err(dvfsrc->dev, "pstate out of range = %ld\n", pstate);
+		return 0;
+	}
+
+	mutex_lock(&dvfsrc->pstate_lock);
+
+	for (i = 0, highest = 0; i < dvfsrc->dvd->num_domains; i++, d++) {
+		if (sc->domain_id == d->id) {
+			d->state = pstate;
+			match = true;
+		}
+		highest = max(highest, d->state);
+	}
+
+	if (!match)
+		goto out;
+
+	/* pstat start from level 1, array index start from 0 */
+	mtk_dvfsrc_send_request(dvfsrc->dev, MTK_DVFSRC_CMD_OPP_REQUEST,
+				highest - 1);
+
+out:
+	mutex_unlock(&dvfsrc->pstate_lock);
+	return 0;
+}
+
+static void pstate_notifier_register(struct mtk_dvfsrc *dvfsrc)
+{
+	dvfsrc->scpsys_notifier.notifier_call = dvfsrc_set_performance;
+	register_scpsys_notifier(&dvfsrc->scpsys_notifier);
+}
+
+static int mtk_dvfsrc_probe(struct platform_device *pdev)
+{
+	struct arm_smccc_res ares;
+	struct resource *res;
+	struct mtk_dvfsrc *dvfsrc;
+	int ret;
+
+	dvfsrc = devm_kzalloc(&pdev->dev, sizeof(*dvfsrc), GFP_KERNEL);
+	if (!dvfsrc)
+		return -ENOMEM;
+
+	dvfsrc->dvd = of_device_get_match_data(&pdev->dev);
+	dvfsrc->dev = &pdev->dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	dvfsrc->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(dvfsrc->regs))
+		return PTR_ERR(dvfsrc->regs);
+
+	dvfsrc->clk_dvfsrc = devm_clk_get(dvfsrc->dev, "dvfsrc");
+	if (IS_ERR(dvfsrc->clk_dvfsrc)) {
+		dev_err(dvfsrc->dev, "failed to get clock: %ld\n",
+			PTR_ERR(dvfsrc->clk_dvfsrc));
+		return PTR_ERR(dvfsrc->clk_dvfsrc);
+	}
+
+	ret = clk_prepare_enable(dvfsrc->clk_dvfsrc);
+	if (ret)
+		return ret;
+
+	mutex_init(&dvfsrc->req_lock);
+	mutex_init(&dvfsrc->pstate_lock);
+
+	arm_smccc_smc(MTK_SIP_SPM, MTK_SIP_SPM_DVFSRC_INIT, 0, 0, 0, 0, 0, 0,
+		      &ares);
+
+	if (!ares.a0) {
+		dvfsrc->dram_type = ares.a1;
+		dev_info(dvfsrc->dev, "dram_type: %d\n", dvfsrc->dram_type);
+	} else {
+		dev_err(dvfsrc->dev, "init fails: %lu\n", ares.a0);
+		clk_disable_unprepare(dvfsrc->clk_dvfsrc);
+		return ares.a0;
+	}
+
+	platform_set_drvdata(pdev, dvfsrc);
+	pstate_notifier_register(dvfsrc);
+
+	return devm_of_platform_populate(&pdev->dev);
+}
+
+static const struct dvfsrc_opp dvfsrc_opp_mt8183_lp4[] = {
+	{0, 0}, {0, 1}, {0, 2}, {1, 2},
+};
+
+static const struct dvfsrc_opp dvfsrc_opp_mt8183_lp3[] = {
+	{0, 0}, {0, 1}, {1, 1}, {1, 2},
+};
+
+static const struct dvfsrc_opp *dvfsrc_opp_mt8183[] = {
+	[MT8183_DVFSRC_OPP_LP4] = dvfsrc_opp_mt8183_lp4,
+	[MT8183_DVFSRC_OPP_LP4X] = dvfsrc_opp_mt8183_lp3,
+	[MT8183_DVFSRC_OPP_LP3] = dvfsrc_opp_mt8183_lp3,
+};
+
+static struct dvfsrc_domain dvfsrc_domains_mt8183[] = {
+	{ MT8183_POWER_DOMAIN_MFG_ASYNC, 0 },
+	{ MT8183_POWER_DOMAIN_MFG, 0 },
+	{ MT8183_POWER_DOMAIN_CAM, 0 },
+	{ MT8183_POWER_DOMAIN_DISP, 0 },
+	{ MT8183_POWER_DOMAIN_ISP, 0 },
+	{ MT8183_POWER_DOMAIN_VDEC, 0 },
+	{ MT8183_POWER_DOMAIN_VENC, 0 },
+};
+
+static const struct dvfsrc_soc_data mt8183_data = {
+	.opps = dvfsrc_opp_mt8183,
+	.num_opp = ARRAY_SIZE(dvfsrc_opp_mt8183_lp4),
+	.regs = mt8183_regs,
+	.domains = dvfsrc_domains_mt8183,
+	.num_domains = ARRAY_SIZE(dvfsrc_domains_mt8183),
+	.get_target_level = mt8183_get_target_level,
+	.get_current_level = mt8183_get_current_level,
+	.get_vcore_level = mt8183_get_vcore_level,
+	.set_dram_bw = mt8183_set_dram_bw,
+	.set_opp_level = mt8183_set_opp_level,
+	.set_vcore_level = mt8183_set_vcore_level,
+	.wait_for_opp_level = mt8183_wait_for_opp_level,
+	.wait_for_vcore_level = dvfsrc_wait_for_vcore_level,
+};
+
+static int mtk_dvfsrc_remove(struct platform_device *pdev)
+{
+	struct mtk_dvfsrc *dvfsrc = platform_get_drvdata(pdev);
+
+	clk_disable_unprepare(dvfsrc->clk_dvfsrc);
+
+	return 0;
+}
+
+static const struct of_device_id mtk_dvfsrc_of_match[] = {
+	{
+		.compatible = "mediatek,mt8183-dvfsrc",
+		.data = &mt8183_data,
+	}, {
+		/* sentinel */
+	},
+};
+
+static struct platform_driver mtk_dvfsrc_driver = {
+	.probe	= mtk_dvfsrc_probe,
+	.remove	= mtk_dvfsrc_remove,
+	.driver = {
+		.name = "mtk-dvfsrc",
+		.of_match_table = of_match_ptr(mtk_dvfsrc_of_match),
+	},
+};
+
+static int __init mtk_dvfsrc_init(void)
+{
+	return platform_driver_register(&mtk_dvfsrc_driver);
+}
+subsys_initcall(mtk_dvfsrc_init);
+
+static void __exit mtk_dvfsrc_exit(void)
+{
+	platform_driver_unregister(&mtk_dvfsrc_driver);
+}
+module_exit(mtk_dvfsrc_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MTK DVFSRC driver");
diff --git a/include/soc/mediatek/mtk_dvfsrc.h b/include/soc/mediatek/mtk_dvfsrc.h
new file mode 100644
index 0000000..06ad201
--- /dev/null
+++ b/include/soc/mediatek/mtk_dvfsrc.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ */
+#ifndef __SOC_MTK_DVFSRC_H
+#define __SOC_MTK_DVFSRC_H
+
+#define MTK_DVFSRC_CMD_BW_REQUEST	0
+#define MTK_DVFSRC_CMD_OPP_REQUEST	1
+#define MTK_DVFSRC_CMD_VCORE_REQUEST	2
+
+#define MTK_DVFSRC_CMD_VCORE_QUERY	0
+
+#if IS_ENABLED(CONFIG_MTK_DVFSRC)
+void mtk_dvfsrc_send_request(const struct device *dev, u32 cmd, u64 data);
+int mtk_dvfsrc_query_info(const struct device *dev, u32 cmd, int *data);
+
+#else
+
+static inline void mtk_dvfsrc_send_request(const struct device *dev, u32 cmd,
+					   u64 data)
+{ return -ENODEV; }
+
+static inline int mtk_dvfsrc_query_info(const struct device *dev, u32 cmd,
+					int *data);
+{ return -ENODEV; }
+
+#endif /* CONFIG_MTK_DVFSRC */
+
+#endif
-- 
1.9.1

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

* [PATCH V4 06/13] soc: mediatek: add MT8183 dvfsrc support
@ 2020-03-13  9:34   ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, Henry Chen, Fan Chen,
	devicetree, linux-mediatek, Arvin Wang, linux-arm-kernel

Add dvfsrc driver for MT8183

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 drivers/soc/mediatek/Kconfig      |  15 ++
 drivers/soc/mediatek/Makefile     |   1 +
 drivers/soc/mediatek/mtk-dvfsrc.c | 434 ++++++++++++++++++++++++++++++++++++++
 include/soc/mediatek/mtk_dvfsrc.h |  30 +++
 4 files changed, 480 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-dvfsrc.c
 create mode 100644 include/soc/mediatek/mtk_dvfsrc.h

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index f837b3c..44808f4 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -16,6 +16,21 @@ config MTK_CMDQ
 	  time limitation, such as updating display configuration during the
 	  vblank.
 
+config MTK_DVFSRC
+	bool "MediaTek DVFSRC Support"
+	depends on ARCH_MEDIATEK
+	default ARCH_MEDIATEK
+	select MTK_INFRACFG
+	select PM_GENERIC_DOMAINS if PM
+	depends on MTK_SCPSYS
+	help
+	  Say yes here to add support for the MediaTek DVFSRC (dynamic voltage
+	  and frequency scaling resource collector) found
+	  on different MediaTek SoCs. The DVFSRC is a proprietary
+	  hardware which is used to collect all the requests from
+	  system and turn into the decision of minimum Vcore voltage
+	  and minimum DRAM frequency to fulfill those requests.
+
 config MTK_PMIC_WRAP
 	tristate "MediaTek PMIC Wrapper Support"
 	depends on RESET_CONTROLLER
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 2b2c2537..84182f0 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
+obj-$(CONFIG_MTK_DVFSRC) += mtk-dvfsrc.o
 obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
 obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-dvfsrc.c b/drivers/soc/mediatek/mtk-dvfsrc.c
new file mode 100644
index 0000000..85b3572
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-dvfsrc.c
@@ -0,0 +1,434 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+#include <linux/arm-smccc.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <soc/mediatek/mtk_dvfsrc.h>
+#include <soc/mediatek/mtk_sip.h>
+#include <dt-bindings/power/mt8183-power.h>
+#include <dt-bindings/soc/mtk,dvfsrc.h>
+#include "mtk-scpsys.h"
+
+#define DVFSRC_IDLE     0x00
+#define DVFSRC_GET_TARGET_LEVEL(x)  (((x) >> 0) & 0x0000ffff)
+#define DVFSRC_GET_CURRENT_LEVEL(x) (((x) >> 16) & 0x0000ffff)
+#define kbps_to_mbps(x) ((x) / 1000)
+
+#define MT8183_DVFSRC_OPP_LP4   0
+#define MT8183_DVFSRC_OPP_LP4X  1
+#define MT8183_DVFSRC_OPP_LP3   2
+
+#define POLL_TIMEOUT        1000
+#define STARTUP_TIME        1
+
+struct dvfsrc_opp {
+	u32 vcore_opp;
+	u32 dram_opp;
+};
+
+struct dvfsrc_domain {
+	u32 id;
+	u32 state;
+};
+
+struct mtk_dvfsrc;
+struct dvfsrc_soc_data {
+	const int *regs;
+	u32 num_opp;
+	u32 num_domains;
+	const struct dvfsrc_opp **opps;
+	struct dvfsrc_domain *domains;
+	int (*get_target_level)(struct mtk_dvfsrc *dvfsrc);
+	int (*get_current_level)(struct mtk_dvfsrc *dvfsrc);
+	u32 (*get_vcore_level)(struct mtk_dvfsrc *dvfsrc);
+	void (*set_dram_bw)(struct mtk_dvfsrc *dvfsrc, u64 bw);
+	void (*set_opp_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
+	void (*set_vcore_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
+	int (*wait_for_opp_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
+	int (*wait_for_vcore_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
+};
+
+struct mtk_dvfsrc {
+	struct device *dev;
+	struct clk *clk_dvfsrc;
+	const struct dvfsrc_soc_data *dvd;
+	int dram_type;
+	void __iomem *regs;
+	struct mutex req_lock;
+	struct mutex pstate_lock;
+	struct notifier_block scpsys_notifier;
+};
+
+static u32 dvfsrc_read(struct mtk_dvfsrc *dvfs, u32 offset)
+{
+	return readl(dvfs->regs + dvfs->dvd->regs[offset]);
+}
+
+static void dvfsrc_write(struct mtk_dvfsrc *dvfs, u32 offset, u32 val)
+{
+	writel(val, dvfs->regs + dvfs->dvd->regs[offset]);
+}
+
+enum dvfsrc_regs {
+	DVFSRC_SW_REQ,
+	DVFSRC_SW_REQ2,
+	DVFSRC_LEVEL,
+	DVFSRC_SW_BW,
+	DVFSRC_LAST,
+};
+
+static const int mt8183_regs[] = {
+	[DVFSRC_SW_REQ] =	0x4,
+	[DVFSRC_SW_REQ2] =	0x8,
+	[DVFSRC_LEVEL] =	0xDC,
+	[DVFSRC_SW_BW] =	0x160,
+	[DVFSRC_LAST] =		0x308,
+};
+
+static const struct dvfsrc_opp *get_current_opp(struct mtk_dvfsrc *dvfsrc)
+{
+	int level;
+
+	level = dvfsrc->dvd->get_current_level(dvfsrc);
+	return &dvfsrc->dvd->opps[dvfsrc->dram_type][level];
+}
+
+static int dvfsrc_is_idle(struct mtk_dvfsrc *dvfsrc)
+{
+	if (!dvfsrc->dvd->get_target_level)
+		return true;
+
+	return dvfsrc->dvd->get_target_level(dvfsrc);
+}
+
+static int dvfsrc_wait_for_vcore_level(struct mtk_dvfsrc *dvfsrc, u32 level)
+{
+	const struct dvfsrc_opp *curr;
+
+	return readx_poll_timeout_atomic(get_current_opp, dvfsrc, curr,
+					 curr->vcore_opp >= level, STARTUP_TIME,
+					 POLL_TIMEOUT);
+}
+
+static int mt8183_wait_for_opp_level(struct mtk_dvfsrc *dvfsrc, u32 level)
+{
+	const struct dvfsrc_opp *target, *curr;
+	int ret;
+
+	target = &dvfsrc->dvd->opps[dvfsrc->dram_type][level];
+	ret = readx_poll_timeout(get_current_opp, dvfsrc, curr,
+				 curr->dram_opp >= target->dram_opp &&
+				 curr->vcore_opp >= target->vcore_opp,
+				 STARTUP_TIME, POLL_TIMEOUT);
+	if (ret < 0) {
+		dev_warn(dvfsrc->dev,
+			 "timeout, target: %u, dram: %d, vcore: %d\n", level,
+			 curr->dram_opp, curr->vcore_opp);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int mt8183_get_target_level(struct mtk_dvfsrc *dvfsrc)
+{
+	return DVFSRC_GET_TARGET_LEVEL(dvfsrc_read(dvfsrc, DVFSRC_LEVEL));
+}
+
+static int mt8183_get_current_level(struct mtk_dvfsrc *dvfsrc)
+{
+	int level;
+
+	/* HW level 0 is begin from 0x10000 */
+	level = DVFSRC_GET_CURRENT_LEVEL(dvfsrc_read(dvfsrc, DVFSRC_LEVEL));
+	/* Array index start from 0 */
+	return ffs(level) - 1;
+}
+
+static u32 mt8183_get_vcore_level(struct mtk_dvfsrc *dvfsrc)
+{
+	return (dvfsrc_read(dvfsrc, DVFSRC_SW_REQ2) >> 2) & 0x3;
+}
+
+static void mt8183_set_dram_bw(struct mtk_dvfsrc *dvfsrc, u64 bw)
+{
+	dvfsrc_write(dvfsrc, DVFSRC_SW_BW, kbps_to_mbps(bw) / 100);
+}
+
+static void mt8183_set_opp_level(struct mtk_dvfsrc *dvfsrc, u32 level)
+{
+	int vcore_opp, dram_opp;
+	const struct dvfsrc_opp *opp;
+
+	/* translate pstate to dvfsrc level, and set it to DVFSRC HW */
+	opp = &dvfsrc->dvd->opps[dvfsrc->dram_type][level];
+	vcore_opp = opp->vcore_opp;
+	dram_opp = opp->dram_opp;
+
+	dev_dbg(dvfsrc->dev, "vcore_opp: %d, dram_opp: %d\n",
+		vcore_opp, dram_opp);
+	dvfsrc_write(dvfsrc, DVFSRC_SW_REQ, dram_opp | vcore_opp << 2);
+}
+
+static void mt8183_set_vcore_level(struct mtk_dvfsrc *dvfsrc, u32 level)
+{
+	dvfsrc_write(dvfsrc, DVFSRC_SW_REQ2, level << 2);
+}
+
+void mtk_dvfsrc_send_request(const struct device *dev, u32 cmd, u64 data)
+{
+	int ret, state;
+	struct mtk_dvfsrc *dvfsrc = dev_get_drvdata(dev);
+
+	dev_dbg(dvfsrc->dev, "cmd: %d, data: %llu\n", cmd, data);
+
+	mutex_lock(&dvfsrc->req_lock);
+
+	switch (cmd) {
+	case MTK_DVFSRC_CMD_BW_REQUEST:
+		dvfsrc->dvd->set_dram_bw(dvfsrc, data);
+		goto out;
+	case MTK_DVFSRC_CMD_OPP_REQUEST:
+		dvfsrc->dvd->set_opp_level(dvfsrc, data);
+		break;
+	case MTK_DVFSRC_CMD_VCORE_REQUEST:
+		dvfsrc->dvd->set_vcore_level(dvfsrc, data);
+		break;
+	default:
+		dev_err(dvfsrc->dev, "unknown command: %d\n", cmd);
+		goto out;
+	}
+
+	/* DVFSRC need to wait at least 2T(~196ns) to handle request
+	 * after recieving command
+	 */
+	udelay(STARTUP_TIME);
+
+	ret = readx_poll_timeout(dvfsrc_is_idle, dvfsrc,
+				 state, state == DVFSRC_IDLE,
+				 STARTUP_TIME, POLL_TIMEOUT);
+
+	if (ret < 0) {
+		dev_warn(dvfsrc->dev,
+			 "%d: idle timeout, data: %llu, last: %d -> %d\n",
+			 cmd, data,
+			 dvfsrc->dvd->get_current_level(dvfsrc),
+			 dvfsrc->dvd->get_target_level(dvfsrc));
+		goto out;
+	}
+
+	if (cmd == MTK_DVFSRC_CMD_OPP_REQUEST)
+		dvfsrc->dvd->wait_for_opp_level(dvfsrc, data);
+	else
+		dvfsrc->dvd->wait_for_vcore_level(dvfsrc, data);
+
+out:
+	mutex_unlock(&dvfsrc->req_lock);
+}
+EXPORT_SYMBOL(mtk_dvfsrc_send_request);
+
+int mtk_dvfsrc_query_info(const struct device *dev, u32 cmd, int *data)
+{
+	struct mtk_dvfsrc *dvfsrc = dev_get_drvdata(dev);
+
+	switch (cmd) {
+	case MTK_DVFSRC_CMD_VCORE_QUERY:
+		*data = dvfsrc->dvd->get_vcore_level(dvfsrc);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(mtk_dvfsrc_query_info);
+
+static int dvfsrc_set_performance(struct notifier_block *b,
+				  unsigned long pstate, void *v)
+{
+	bool match = false;
+	int i;
+	struct mtk_dvfsrc *dvfsrc;
+	struct scp_event_data *sc = v;
+	struct dvfsrc_domain *d;
+	u32 highest;
+
+	if (sc->event_type != MTK_SCPSYS_PSTATE)
+		return 0;
+
+	dvfsrc = container_of(b, struct mtk_dvfsrc, scpsys_notifier);
+
+	d = dvfsrc->dvd->domains;
+
+	if (pstate > dvfsrc->dvd->num_opp) {
+		dev_err(dvfsrc->dev, "pstate out of range = %ld\n", pstate);
+		return 0;
+	}
+
+	mutex_lock(&dvfsrc->pstate_lock);
+
+	for (i = 0, highest = 0; i < dvfsrc->dvd->num_domains; i++, d++) {
+		if (sc->domain_id == d->id) {
+			d->state = pstate;
+			match = true;
+		}
+		highest = max(highest, d->state);
+	}
+
+	if (!match)
+		goto out;
+
+	/* pstat start from level 1, array index start from 0 */
+	mtk_dvfsrc_send_request(dvfsrc->dev, MTK_DVFSRC_CMD_OPP_REQUEST,
+				highest - 1);
+
+out:
+	mutex_unlock(&dvfsrc->pstate_lock);
+	return 0;
+}
+
+static void pstate_notifier_register(struct mtk_dvfsrc *dvfsrc)
+{
+	dvfsrc->scpsys_notifier.notifier_call = dvfsrc_set_performance;
+	register_scpsys_notifier(&dvfsrc->scpsys_notifier);
+}
+
+static int mtk_dvfsrc_probe(struct platform_device *pdev)
+{
+	struct arm_smccc_res ares;
+	struct resource *res;
+	struct mtk_dvfsrc *dvfsrc;
+	int ret;
+
+	dvfsrc = devm_kzalloc(&pdev->dev, sizeof(*dvfsrc), GFP_KERNEL);
+	if (!dvfsrc)
+		return -ENOMEM;
+
+	dvfsrc->dvd = of_device_get_match_data(&pdev->dev);
+	dvfsrc->dev = &pdev->dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	dvfsrc->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(dvfsrc->regs))
+		return PTR_ERR(dvfsrc->regs);
+
+	dvfsrc->clk_dvfsrc = devm_clk_get(dvfsrc->dev, "dvfsrc");
+	if (IS_ERR(dvfsrc->clk_dvfsrc)) {
+		dev_err(dvfsrc->dev, "failed to get clock: %ld\n",
+			PTR_ERR(dvfsrc->clk_dvfsrc));
+		return PTR_ERR(dvfsrc->clk_dvfsrc);
+	}
+
+	ret = clk_prepare_enable(dvfsrc->clk_dvfsrc);
+	if (ret)
+		return ret;
+
+	mutex_init(&dvfsrc->req_lock);
+	mutex_init(&dvfsrc->pstate_lock);
+
+	arm_smccc_smc(MTK_SIP_SPM, MTK_SIP_SPM_DVFSRC_INIT, 0, 0, 0, 0, 0, 0,
+		      &ares);
+
+	if (!ares.a0) {
+		dvfsrc->dram_type = ares.a1;
+		dev_info(dvfsrc->dev, "dram_type: %d\n", dvfsrc->dram_type);
+	} else {
+		dev_err(dvfsrc->dev, "init fails: %lu\n", ares.a0);
+		clk_disable_unprepare(dvfsrc->clk_dvfsrc);
+		return ares.a0;
+	}
+
+	platform_set_drvdata(pdev, dvfsrc);
+	pstate_notifier_register(dvfsrc);
+
+	return devm_of_platform_populate(&pdev->dev);
+}
+
+static const struct dvfsrc_opp dvfsrc_opp_mt8183_lp4[] = {
+	{0, 0}, {0, 1}, {0, 2}, {1, 2},
+};
+
+static const struct dvfsrc_opp dvfsrc_opp_mt8183_lp3[] = {
+	{0, 0}, {0, 1}, {1, 1}, {1, 2},
+};
+
+static const struct dvfsrc_opp *dvfsrc_opp_mt8183[] = {
+	[MT8183_DVFSRC_OPP_LP4] = dvfsrc_opp_mt8183_lp4,
+	[MT8183_DVFSRC_OPP_LP4X] = dvfsrc_opp_mt8183_lp3,
+	[MT8183_DVFSRC_OPP_LP3] = dvfsrc_opp_mt8183_lp3,
+};
+
+static struct dvfsrc_domain dvfsrc_domains_mt8183[] = {
+	{ MT8183_POWER_DOMAIN_MFG_ASYNC, 0 },
+	{ MT8183_POWER_DOMAIN_MFG, 0 },
+	{ MT8183_POWER_DOMAIN_CAM, 0 },
+	{ MT8183_POWER_DOMAIN_DISP, 0 },
+	{ MT8183_POWER_DOMAIN_ISP, 0 },
+	{ MT8183_POWER_DOMAIN_VDEC, 0 },
+	{ MT8183_POWER_DOMAIN_VENC, 0 },
+};
+
+static const struct dvfsrc_soc_data mt8183_data = {
+	.opps = dvfsrc_opp_mt8183,
+	.num_opp = ARRAY_SIZE(dvfsrc_opp_mt8183_lp4),
+	.regs = mt8183_regs,
+	.domains = dvfsrc_domains_mt8183,
+	.num_domains = ARRAY_SIZE(dvfsrc_domains_mt8183),
+	.get_target_level = mt8183_get_target_level,
+	.get_current_level = mt8183_get_current_level,
+	.get_vcore_level = mt8183_get_vcore_level,
+	.set_dram_bw = mt8183_set_dram_bw,
+	.set_opp_level = mt8183_set_opp_level,
+	.set_vcore_level = mt8183_set_vcore_level,
+	.wait_for_opp_level = mt8183_wait_for_opp_level,
+	.wait_for_vcore_level = dvfsrc_wait_for_vcore_level,
+};
+
+static int mtk_dvfsrc_remove(struct platform_device *pdev)
+{
+	struct mtk_dvfsrc *dvfsrc = platform_get_drvdata(pdev);
+
+	clk_disable_unprepare(dvfsrc->clk_dvfsrc);
+
+	return 0;
+}
+
+static const struct of_device_id mtk_dvfsrc_of_match[] = {
+	{
+		.compatible = "mediatek,mt8183-dvfsrc",
+		.data = &mt8183_data,
+	}, {
+		/* sentinel */
+	},
+};
+
+static struct platform_driver mtk_dvfsrc_driver = {
+	.probe	= mtk_dvfsrc_probe,
+	.remove	= mtk_dvfsrc_remove,
+	.driver = {
+		.name = "mtk-dvfsrc",
+		.of_match_table = of_match_ptr(mtk_dvfsrc_of_match),
+	},
+};
+
+static int __init mtk_dvfsrc_init(void)
+{
+	return platform_driver_register(&mtk_dvfsrc_driver);
+}
+subsys_initcall(mtk_dvfsrc_init);
+
+static void __exit mtk_dvfsrc_exit(void)
+{
+	platform_driver_unregister(&mtk_dvfsrc_driver);
+}
+module_exit(mtk_dvfsrc_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MTK DVFSRC driver");
diff --git a/include/soc/mediatek/mtk_dvfsrc.h b/include/soc/mediatek/mtk_dvfsrc.h
new file mode 100644
index 0000000..06ad201
--- /dev/null
+++ b/include/soc/mediatek/mtk_dvfsrc.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ */
+#ifndef __SOC_MTK_DVFSRC_H
+#define __SOC_MTK_DVFSRC_H
+
+#define MTK_DVFSRC_CMD_BW_REQUEST	0
+#define MTK_DVFSRC_CMD_OPP_REQUEST	1
+#define MTK_DVFSRC_CMD_VCORE_REQUEST	2
+
+#define MTK_DVFSRC_CMD_VCORE_QUERY	0
+
+#if IS_ENABLED(CONFIG_MTK_DVFSRC)
+void mtk_dvfsrc_send_request(const struct device *dev, u32 cmd, u64 data);
+int mtk_dvfsrc_query_info(const struct device *dev, u32 cmd, int *data);
+
+#else
+
+static inline void mtk_dvfsrc_send_request(const struct device *dev, u32 cmd,
+					   u64 data)
+{ return -ENODEV; }
+
+static inline int mtk_dvfsrc_query_info(const struct device *dev, u32 cmd,
+					int *data);
+{ return -ENODEV; }
+
+#endif /* CONFIG_MTK_DVFSRC */
+
+#endif
-- 
1.9.1
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

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

* [PATCH V4 06/13] soc: mediatek: add MT8183 dvfsrc support
@ 2020-03-13  9:34   ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, Henry Chen, Fan Chen,
	devicetree, linux-mediatek, Arvin Wang, linux-arm-kernel

Add dvfsrc driver for MT8183

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 drivers/soc/mediatek/Kconfig      |  15 ++
 drivers/soc/mediatek/Makefile     |   1 +
 drivers/soc/mediatek/mtk-dvfsrc.c | 434 ++++++++++++++++++++++++++++++++++++++
 include/soc/mediatek/mtk_dvfsrc.h |  30 +++
 4 files changed, 480 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-dvfsrc.c
 create mode 100644 include/soc/mediatek/mtk_dvfsrc.h

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index f837b3c..44808f4 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -16,6 +16,21 @@ config MTK_CMDQ
 	  time limitation, such as updating display configuration during the
 	  vblank.
 
+config MTK_DVFSRC
+	bool "MediaTek DVFSRC Support"
+	depends on ARCH_MEDIATEK
+	default ARCH_MEDIATEK
+	select MTK_INFRACFG
+	select PM_GENERIC_DOMAINS if PM
+	depends on MTK_SCPSYS
+	help
+	  Say yes here to add support for the MediaTek DVFSRC (dynamic voltage
+	  and frequency scaling resource collector) found
+	  on different MediaTek SoCs. The DVFSRC is a proprietary
+	  hardware which is used to collect all the requests from
+	  system and turn into the decision of minimum Vcore voltage
+	  and minimum DRAM frequency to fulfill those requests.
+
 config MTK_PMIC_WRAP
 	tristate "MediaTek PMIC Wrapper Support"
 	depends on RESET_CONTROLLER
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 2b2c2537..84182f0 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
+obj-$(CONFIG_MTK_DVFSRC) += mtk-dvfsrc.o
 obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
 obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-dvfsrc.c b/drivers/soc/mediatek/mtk-dvfsrc.c
new file mode 100644
index 0000000..85b3572
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-dvfsrc.c
@@ -0,0 +1,434 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+#include <linux/arm-smccc.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <soc/mediatek/mtk_dvfsrc.h>
+#include <soc/mediatek/mtk_sip.h>
+#include <dt-bindings/power/mt8183-power.h>
+#include <dt-bindings/soc/mtk,dvfsrc.h>
+#include "mtk-scpsys.h"
+
+#define DVFSRC_IDLE     0x00
+#define DVFSRC_GET_TARGET_LEVEL(x)  (((x) >> 0) & 0x0000ffff)
+#define DVFSRC_GET_CURRENT_LEVEL(x) (((x) >> 16) & 0x0000ffff)
+#define kbps_to_mbps(x) ((x) / 1000)
+
+#define MT8183_DVFSRC_OPP_LP4   0
+#define MT8183_DVFSRC_OPP_LP4X  1
+#define MT8183_DVFSRC_OPP_LP3   2
+
+#define POLL_TIMEOUT        1000
+#define STARTUP_TIME        1
+
+struct dvfsrc_opp {
+	u32 vcore_opp;
+	u32 dram_opp;
+};
+
+struct dvfsrc_domain {
+	u32 id;
+	u32 state;
+};
+
+struct mtk_dvfsrc;
+struct dvfsrc_soc_data {
+	const int *regs;
+	u32 num_opp;
+	u32 num_domains;
+	const struct dvfsrc_opp **opps;
+	struct dvfsrc_domain *domains;
+	int (*get_target_level)(struct mtk_dvfsrc *dvfsrc);
+	int (*get_current_level)(struct mtk_dvfsrc *dvfsrc);
+	u32 (*get_vcore_level)(struct mtk_dvfsrc *dvfsrc);
+	void (*set_dram_bw)(struct mtk_dvfsrc *dvfsrc, u64 bw);
+	void (*set_opp_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
+	void (*set_vcore_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
+	int (*wait_for_opp_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
+	int (*wait_for_vcore_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
+};
+
+struct mtk_dvfsrc {
+	struct device *dev;
+	struct clk *clk_dvfsrc;
+	const struct dvfsrc_soc_data *dvd;
+	int dram_type;
+	void __iomem *regs;
+	struct mutex req_lock;
+	struct mutex pstate_lock;
+	struct notifier_block scpsys_notifier;
+};
+
+static u32 dvfsrc_read(struct mtk_dvfsrc *dvfs, u32 offset)
+{
+	return readl(dvfs->regs + dvfs->dvd->regs[offset]);
+}
+
+static void dvfsrc_write(struct mtk_dvfsrc *dvfs, u32 offset, u32 val)
+{
+	writel(val, dvfs->regs + dvfs->dvd->regs[offset]);
+}
+
+enum dvfsrc_regs {
+	DVFSRC_SW_REQ,
+	DVFSRC_SW_REQ2,
+	DVFSRC_LEVEL,
+	DVFSRC_SW_BW,
+	DVFSRC_LAST,
+};
+
+static const int mt8183_regs[] = {
+	[DVFSRC_SW_REQ] =	0x4,
+	[DVFSRC_SW_REQ2] =	0x8,
+	[DVFSRC_LEVEL] =	0xDC,
+	[DVFSRC_SW_BW] =	0x160,
+	[DVFSRC_LAST] =		0x308,
+};
+
+static const struct dvfsrc_opp *get_current_opp(struct mtk_dvfsrc *dvfsrc)
+{
+	int level;
+
+	level = dvfsrc->dvd->get_current_level(dvfsrc);
+	return &dvfsrc->dvd->opps[dvfsrc->dram_type][level];
+}
+
+static int dvfsrc_is_idle(struct mtk_dvfsrc *dvfsrc)
+{
+	if (!dvfsrc->dvd->get_target_level)
+		return true;
+
+	return dvfsrc->dvd->get_target_level(dvfsrc);
+}
+
+static int dvfsrc_wait_for_vcore_level(struct mtk_dvfsrc *dvfsrc, u32 level)
+{
+	const struct dvfsrc_opp *curr;
+
+	return readx_poll_timeout_atomic(get_current_opp, dvfsrc, curr,
+					 curr->vcore_opp >= level, STARTUP_TIME,
+					 POLL_TIMEOUT);
+}
+
+static int mt8183_wait_for_opp_level(struct mtk_dvfsrc *dvfsrc, u32 level)
+{
+	const struct dvfsrc_opp *target, *curr;
+	int ret;
+
+	target = &dvfsrc->dvd->opps[dvfsrc->dram_type][level];
+	ret = readx_poll_timeout(get_current_opp, dvfsrc, curr,
+				 curr->dram_opp >= target->dram_opp &&
+				 curr->vcore_opp >= target->vcore_opp,
+				 STARTUP_TIME, POLL_TIMEOUT);
+	if (ret < 0) {
+		dev_warn(dvfsrc->dev,
+			 "timeout, target: %u, dram: %d, vcore: %d\n", level,
+			 curr->dram_opp, curr->vcore_opp);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int mt8183_get_target_level(struct mtk_dvfsrc *dvfsrc)
+{
+	return DVFSRC_GET_TARGET_LEVEL(dvfsrc_read(dvfsrc, DVFSRC_LEVEL));
+}
+
+static int mt8183_get_current_level(struct mtk_dvfsrc *dvfsrc)
+{
+	int level;
+
+	/* HW level 0 is begin from 0x10000 */
+	level = DVFSRC_GET_CURRENT_LEVEL(dvfsrc_read(dvfsrc, DVFSRC_LEVEL));
+	/* Array index start from 0 */
+	return ffs(level) - 1;
+}
+
+static u32 mt8183_get_vcore_level(struct mtk_dvfsrc *dvfsrc)
+{
+	return (dvfsrc_read(dvfsrc, DVFSRC_SW_REQ2) >> 2) & 0x3;
+}
+
+static void mt8183_set_dram_bw(struct mtk_dvfsrc *dvfsrc, u64 bw)
+{
+	dvfsrc_write(dvfsrc, DVFSRC_SW_BW, kbps_to_mbps(bw) / 100);
+}
+
+static void mt8183_set_opp_level(struct mtk_dvfsrc *dvfsrc, u32 level)
+{
+	int vcore_opp, dram_opp;
+	const struct dvfsrc_opp *opp;
+
+	/* translate pstate to dvfsrc level, and set it to DVFSRC HW */
+	opp = &dvfsrc->dvd->opps[dvfsrc->dram_type][level];
+	vcore_opp = opp->vcore_opp;
+	dram_opp = opp->dram_opp;
+
+	dev_dbg(dvfsrc->dev, "vcore_opp: %d, dram_opp: %d\n",
+		vcore_opp, dram_opp);
+	dvfsrc_write(dvfsrc, DVFSRC_SW_REQ, dram_opp | vcore_opp << 2);
+}
+
+static void mt8183_set_vcore_level(struct mtk_dvfsrc *dvfsrc, u32 level)
+{
+	dvfsrc_write(dvfsrc, DVFSRC_SW_REQ2, level << 2);
+}
+
+void mtk_dvfsrc_send_request(const struct device *dev, u32 cmd, u64 data)
+{
+	int ret, state;
+	struct mtk_dvfsrc *dvfsrc = dev_get_drvdata(dev);
+
+	dev_dbg(dvfsrc->dev, "cmd: %d, data: %llu\n", cmd, data);
+
+	mutex_lock(&dvfsrc->req_lock);
+
+	switch (cmd) {
+	case MTK_DVFSRC_CMD_BW_REQUEST:
+		dvfsrc->dvd->set_dram_bw(dvfsrc, data);
+		goto out;
+	case MTK_DVFSRC_CMD_OPP_REQUEST:
+		dvfsrc->dvd->set_opp_level(dvfsrc, data);
+		break;
+	case MTK_DVFSRC_CMD_VCORE_REQUEST:
+		dvfsrc->dvd->set_vcore_level(dvfsrc, data);
+		break;
+	default:
+		dev_err(dvfsrc->dev, "unknown command: %d\n", cmd);
+		goto out;
+	}
+
+	/* DVFSRC need to wait at least 2T(~196ns) to handle request
+	 * after recieving command
+	 */
+	udelay(STARTUP_TIME);
+
+	ret = readx_poll_timeout(dvfsrc_is_idle, dvfsrc,
+				 state, state == DVFSRC_IDLE,
+				 STARTUP_TIME, POLL_TIMEOUT);
+
+	if (ret < 0) {
+		dev_warn(dvfsrc->dev,
+			 "%d: idle timeout, data: %llu, last: %d -> %d\n",
+			 cmd, data,
+			 dvfsrc->dvd->get_current_level(dvfsrc),
+			 dvfsrc->dvd->get_target_level(dvfsrc));
+		goto out;
+	}
+
+	if (cmd == MTK_DVFSRC_CMD_OPP_REQUEST)
+		dvfsrc->dvd->wait_for_opp_level(dvfsrc, data);
+	else
+		dvfsrc->dvd->wait_for_vcore_level(dvfsrc, data);
+
+out:
+	mutex_unlock(&dvfsrc->req_lock);
+}
+EXPORT_SYMBOL(mtk_dvfsrc_send_request);
+
+int mtk_dvfsrc_query_info(const struct device *dev, u32 cmd, int *data)
+{
+	struct mtk_dvfsrc *dvfsrc = dev_get_drvdata(dev);
+
+	switch (cmd) {
+	case MTK_DVFSRC_CMD_VCORE_QUERY:
+		*data = dvfsrc->dvd->get_vcore_level(dvfsrc);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(mtk_dvfsrc_query_info);
+
+static int dvfsrc_set_performance(struct notifier_block *b,
+				  unsigned long pstate, void *v)
+{
+	bool match = false;
+	int i;
+	struct mtk_dvfsrc *dvfsrc;
+	struct scp_event_data *sc = v;
+	struct dvfsrc_domain *d;
+	u32 highest;
+
+	if (sc->event_type != MTK_SCPSYS_PSTATE)
+		return 0;
+
+	dvfsrc = container_of(b, struct mtk_dvfsrc, scpsys_notifier);
+
+	d = dvfsrc->dvd->domains;
+
+	if (pstate > dvfsrc->dvd->num_opp) {
+		dev_err(dvfsrc->dev, "pstate out of range = %ld\n", pstate);
+		return 0;
+	}
+
+	mutex_lock(&dvfsrc->pstate_lock);
+
+	for (i = 0, highest = 0; i < dvfsrc->dvd->num_domains; i++, d++) {
+		if (sc->domain_id == d->id) {
+			d->state = pstate;
+			match = true;
+		}
+		highest = max(highest, d->state);
+	}
+
+	if (!match)
+		goto out;
+
+	/* pstat start from level 1, array index start from 0 */
+	mtk_dvfsrc_send_request(dvfsrc->dev, MTK_DVFSRC_CMD_OPP_REQUEST,
+				highest - 1);
+
+out:
+	mutex_unlock(&dvfsrc->pstate_lock);
+	return 0;
+}
+
+static void pstate_notifier_register(struct mtk_dvfsrc *dvfsrc)
+{
+	dvfsrc->scpsys_notifier.notifier_call = dvfsrc_set_performance;
+	register_scpsys_notifier(&dvfsrc->scpsys_notifier);
+}
+
+static int mtk_dvfsrc_probe(struct platform_device *pdev)
+{
+	struct arm_smccc_res ares;
+	struct resource *res;
+	struct mtk_dvfsrc *dvfsrc;
+	int ret;
+
+	dvfsrc = devm_kzalloc(&pdev->dev, sizeof(*dvfsrc), GFP_KERNEL);
+	if (!dvfsrc)
+		return -ENOMEM;
+
+	dvfsrc->dvd = of_device_get_match_data(&pdev->dev);
+	dvfsrc->dev = &pdev->dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	dvfsrc->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(dvfsrc->regs))
+		return PTR_ERR(dvfsrc->regs);
+
+	dvfsrc->clk_dvfsrc = devm_clk_get(dvfsrc->dev, "dvfsrc");
+	if (IS_ERR(dvfsrc->clk_dvfsrc)) {
+		dev_err(dvfsrc->dev, "failed to get clock: %ld\n",
+			PTR_ERR(dvfsrc->clk_dvfsrc));
+		return PTR_ERR(dvfsrc->clk_dvfsrc);
+	}
+
+	ret = clk_prepare_enable(dvfsrc->clk_dvfsrc);
+	if (ret)
+		return ret;
+
+	mutex_init(&dvfsrc->req_lock);
+	mutex_init(&dvfsrc->pstate_lock);
+
+	arm_smccc_smc(MTK_SIP_SPM, MTK_SIP_SPM_DVFSRC_INIT, 0, 0, 0, 0, 0, 0,
+		      &ares);
+
+	if (!ares.a0) {
+		dvfsrc->dram_type = ares.a1;
+		dev_info(dvfsrc->dev, "dram_type: %d\n", dvfsrc->dram_type);
+	} else {
+		dev_err(dvfsrc->dev, "init fails: %lu\n", ares.a0);
+		clk_disable_unprepare(dvfsrc->clk_dvfsrc);
+		return ares.a0;
+	}
+
+	platform_set_drvdata(pdev, dvfsrc);
+	pstate_notifier_register(dvfsrc);
+
+	return devm_of_platform_populate(&pdev->dev);
+}
+
+static const struct dvfsrc_opp dvfsrc_opp_mt8183_lp4[] = {
+	{0, 0}, {0, 1}, {0, 2}, {1, 2},
+};
+
+static const struct dvfsrc_opp dvfsrc_opp_mt8183_lp3[] = {
+	{0, 0}, {0, 1}, {1, 1}, {1, 2},
+};
+
+static const struct dvfsrc_opp *dvfsrc_opp_mt8183[] = {
+	[MT8183_DVFSRC_OPP_LP4] = dvfsrc_opp_mt8183_lp4,
+	[MT8183_DVFSRC_OPP_LP4X] = dvfsrc_opp_mt8183_lp3,
+	[MT8183_DVFSRC_OPP_LP3] = dvfsrc_opp_mt8183_lp3,
+};
+
+static struct dvfsrc_domain dvfsrc_domains_mt8183[] = {
+	{ MT8183_POWER_DOMAIN_MFG_ASYNC, 0 },
+	{ MT8183_POWER_DOMAIN_MFG, 0 },
+	{ MT8183_POWER_DOMAIN_CAM, 0 },
+	{ MT8183_POWER_DOMAIN_DISP, 0 },
+	{ MT8183_POWER_DOMAIN_ISP, 0 },
+	{ MT8183_POWER_DOMAIN_VDEC, 0 },
+	{ MT8183_POWER_DOMAIN_VENC, 0 },
+};
+
+static const struct dvfsrc_soc_data mt8183_data = {
+	.opps = dvfsrc_opp_mt8183,
+	.num_opp = ARRAY_SIZE(dvfsrc_opp_mt8183_lp4),
+	.regs = mt8183_regs,
+	.domains = dvfsrc_domains_mt8183,
+	.num_domains = ARRAY_SIZE(dvfsrc_domains_mt8183),
+	.get_target_level = mt8183_get_target_level,
+	.get_current_level = mt8183_get_current_level,
+	.get_vcore_level = mt8183_get_vcore_level,
+	.set_dram_bw = mt8183_set_dram_bw,
+	.set_opp_level = mt8183_set_opp_level,
+	.set_vcore_level = mt8183_set_vcore_level,
+	.wait_for_opp_level = mt8183_wait_for_opp_level,
+	.wait_for_vcore_level = dvfsrc_wait_for_vcore_level,
+};
+
+static int mtk_dvfsrc_remove(struct platform_device *pdev)
+{
+	struct mtk_dvfsrc *dvfsrc = platform_get_drvdata(pdev);
+
+	clk_disable_unprepare(dvfsrc->clk_dvfsrc);
+
+	return 0;
+}
+
+static const struct of_device_id mtk_dvfsrc_of_match[] = {
+	{
+		.compatible = "mediatek,mt8183-dvfsrc",
+		.data = &mt8183_data,
+	}, {
+		/* sentinel */
+	},
+};
+
+static struct platform_driver mtk_dvfsrc_driver = {
+	.probe	= mtk_dvfsrc_probe,
+	.remove	= mtk_dvfsrc_remove,
+	.driver = {
+		.name = "mtk-dvfsrc",
+		.of_match_table = of_match_ptr(mtk_dvfsrc_of_match),
+	},
+};
+
+static int __init mtk_dvfsrc_init(void)
+{
+	return platform_driver_register(&mtk_dvfsrc_driver);
+}
+subsys_initcall(mtk_dvfsrc_init);
+
+static void __exit mtk_dvfsrc_exit(void)
+{
+	platform_driver_unregister(&mtk_dvfsrc_driver);
+}
+module_exit(mtk_dvfsrc_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MTK DVFSRC driver");
diff --git a/include/soc/mediatek/mtk_dvfsrc.h b/include/soc/mediatek/mtk_dvfsrc.h
new file mode 100644
index 0000000..06ad201
--- /dev/null
+++ b/include/soc/mediatek/mtk_dvfsrc.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ */
+#ifndef __SOC_MTK_DVFSRC_H
+#define __SOC_MTK_DVFSRC_H
+
+#define MTK_DVFSRC_CMD_BW_REQUEST	0
+#define MTK_DVFSRC_CMD_OPP_REQUEST	1
+#define MTK_DVFSRC_CMD_VCORE_REQUEST	2
+
+#define MTK_DVFSRC_CMD_VCORE_QUERY	0
+
+#if IS_ENABLED(CONFIG_MTK_DVFSRC)
+void mtk_dvfsrc_send_request(const struct device *dev, u32 cmd, u64 data);
+int mtk_dvfsrc_query_info(const struct device *dev, u32 cmd, int *data);
+
+#else
+
+static inline void mtk_dvfsrc_send_request(const struct device *dev, u32 cmd,
+					   u64 data)
+{ return -ENODEV; }
+
+static inline int mtk_dvfsrc_query_info(const struct device *dev, u32 cmd,
+					int *data);
+{ return -ENODEV; }
+
+#endif /* CONFIG_MTK_DVFSRC */
+
+#endif
-- 
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V4 07/13] arm64: dts: mt8183: add dvfsrc related nodes
  2020-03-13  9:34 ` Henry Chen
  (?)
@ 2020-03-13  9:34   ` Henry Chen
  -1 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Fan Chen, James Liao, Arvin Wang,
	Mike Turquette, devicetree, linux-arm-kernel, linux-mediatek,
	linux-kernel, linux-pm, srv_heupstream, Henry Chen

Enable dvfsrc on mt8183 platform.

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8183.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index 7bf20ca..c0d08c8 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -159,6 +159,13 @@
 		clock-output-names = "clk26m";
 	};
 
+	dvfsrc@10012000 {
+		compatible = "mediatek,mt8183-dvfsrc";
+		reg = <0 0x10012000 0 0x1000>;
+		clocks = <&infracfg CLK_INFRA_DVFSRC>;
+		clock-names = "dvfsrc";
+	};
+
 	timer {
 		compatible = "arm,armv8-timer";
 		interrupt-parent = <&gic>;
-- 
1.9.1

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

* [PATCH V4 07/13] arm64: dts: mt8183: add dvfsrc related nodes
@ 2020-03-13  9:34   ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, Henry Chen, Fan Chen,
	devicetree, linux-mediatek, Arvin Wang, linux-arm-kernel

Enable dvfsrc on mt8183 platform.

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8183.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index 7bf20ca..c0d08c8 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -159,6 +159,13 @@
 		clock-output-names = "clk26m";
 	};
 
+	dvfsrc@10012000 {
+		compatible = "mediatek,mt8183-dvfsrc";
+		reg = <0 0x10012000 0 0x1000>;
+		clocks = <&infracfg CLK_INFRA_DVFSRC>;
+		clock-names = "dvfsrc";
+	};
+
 	timer {
 		compatible = "arm,armv8-timer";
 		interrupt-parent = <&gic>;
-- 
1.9.1
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

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

* [PATCH V4 07/13] arm64: dts: mt8183: add dvfsrc related nodes
@ 2020-03-13  9:34   ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, Henry Chen, Fan Chen,
	devicetree, linux-mediatek, Arvin Wang, linux-arm-kernel

Enable dvfsrc on mt8183 platform.

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8183.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index 7bf20ca..c0d08c8 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -159,6 +159,13 @@
 		clock-output-names = "clk26m";
 	};
 
+	dvfsrc@10012000 {
+		compatible = "mediatek,mt8183-dvfsrc";
+		reg = <0 0x10012000 0 0x1000>;
+		clocks = <&infracfg CLK_INFRA_DVFSRC>;
+		clock-names = "dvfsrc";
+	};
+
 	timer {
 		compatible = "arm,armv8-timer";
 		interrupt-parent = <&gic>;
-- 
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V4 08/13] dt-bindings: interconnect: add MT8183 interconnect dt-bindings
  2020-03-13  9:34 ` Henry Chen
  (?)
@ 2020-03-13  9:34   ` Henry Chen
  -1 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Fan Chen, James Liao, Arvin Wang,
	Mike Turquette, devicetree, linux-arm-kernel, linux-mediatek,
	linux-kernel, linux-pm, srv_heupstream, Henry Chen

Add interconnect provider dt-bindings for MT8183.

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 .../devicetree/bindings/soc/mediatek/dvfsrc.txt        |  9 +++++++++
 include/dt-bindings/interconnect/mtk,mt8183-emi.h      | 18 ++++++++++++++++++
 2 files changed, 27 insertions(+)
 create mode 100644 include/dt-bindings/interconnect/mtk,mt8183-emi.h

diff --git a/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
index 7f43499..da98ec9 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
+++ b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
@@ -12,6 +12,11 @@ Required Properties:
 - clock-names: Must include the following entries:
 	"dvfsrc": DVFSRC module clock
 - clocks: Must contain an entry for each entry in clock-names.
+- #interconnect-cells : should contain 1
+- interconnect : interconnect providers support dram bandwidth requirements.
+	The provider is able to communicate with the DVFSRC and send the dram
+	bandwidth to it. shall contain only one of the following:
+	"mediatek,mt8183-emi"
 
 Example:
 
@@ -20,4 +25,8 @@ Example:
 		reg = <0 0x10012000 0 0x1000>;
 		clocks = <&infracfg CLK_INFRA_DVFSRC>;
 		clock-names = "dvfsrc";
+		ddr_emi: interconnect {
+			compatible = "mediatek,mt8183-emi";
+			#interconnect-cells = <1>;
+		};
 	};
diff --git a/include/dt-bindings/interconnect/mtk,mt8183-emi.h b/include/dt-bindings/interconnect/mtk,mt8183-emi.h
new file mode 100644
index 0000000..2a54856
--- /dev/null
+++ b/include/dt-bindings/interconnect/mtk,mt8183-emi.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __DT_BINDINGS_INTERCONNECT_MTK_MT8183_EMI_H
+#define __DT_BINDINGS_INTERCONNECT_MTK_MT8183_EMI_H
+
+#define MT8183_SLAVE_DDR_EMI			0
+#define MT8183_MASTER_MCUSYS			1
+#define MT8183_MASTER_GPU			2
+#define MT8183_MASTER_MMSYS			3
+#define MT8183_MASTER_MM_VPU			4
+#define MT8183_MASTER_MM_DISP			5
+#define MT8183_MASTER_MM_VDEC			6
+#define MT8183_MASTER_MM_VENC			7
+#define MT8183_MASTER_MM_CAM			8
+#define MT8183_MASTER_MM_IMG			9
+#define MT8183_MASTER_MM_MDP			10
+
+#endif
-- 
1.9.1

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

* [PATCH V4 08/13] dt-bindings: interconnect: add MT8183 interconnect dt-bindings
@ 2020-03-13  9:34   ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, Henry Chen, Fan Chen,
	devicetree, linux-mediatek, Arvin Wang, linux-arm-kernel

Add interconnect provider dt-bindings for MT8183.

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 .../devicetree/bindings/soc/mediatek/dvfsrc.txt        |  9 +++++++++
 include/dt-bindings/interconnect/mtk,mt8183-emi.h      | 18 ++++++++++++++++++
 2 files changed, 27 insertions(+)
 create mode 100644 include/dt-bindings/interconnect/mtk,mt8183-emi.h

diff --git a/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
index 7f43499..da98ec9 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
+++ b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
@@ -12,6 +12,11 @@ Required Properties:
 - clock-names: Must include the following entries:
 	"dvfsrc": DVFSRC module clock
 - clocks: Must contain an entry for each entry in clock-names.
+- #interconnect-cells : should contain 1
+- interconnect : interconnect providers support dram bandwidth requirements.
+	The provider is able to communicate with the DVFSRC and send the dram
+	bandwidth to it. shall contain only one of the following:
+	"mediatek,mt8183-emi"
 
 Example:
 
@@ -20,4 +25,8 @@ Example:
 		reg = <0 0x10012000 0 0x1000>;
 		clocks = <&infracfg CLK_INFRA_DVFSRC>;
 		clock-names = "dvfsrc";
+		ddr_emi: interconnect {
+			compatible = "mediatek,mt8183-emi";
+			#interconnect-cells = <1>;
+		};
 	};
diff --git a/include/dt-bindings/interconnect/mtk,mt8183-emi.h b/include/dt-bindings/interconnect/mtk,mt8183-emi.h
new file mode 100644
index 0000000..2a54856
--- /dev/null
+++ b/include/dt-bindings/interconnect/mtk,mt8183-emi.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __DT_BINDINGS_INTERCONNECT_MTK_MT8183_EMI_H
+#define __DT_BINDINGS_INTERCONNECT_MTK_MT8183_EMI_H
+
+#define MT8183_SLAVE_DDR_EMI			0
+#define MT8183_MASTER_MCUSYS			1
+#define MT8183_MASTER_GPU			2
+#define MT8183_MASTER_MMSYS			3
+#define MT8183_MASTER_MM_VPU			4
+#define MT8183_MASTER_MM_DISP			5
+#define MT8183_MASTER_MM_VDEC			6
+#define MT8183_MASTER_MM_VENC			7
+#define MT8183_MASTER_MM_CAM			8
+#define MT8183_MASTER_MM_IMG			9
+#define MT8183_MASTER_MM_MDP			10
+
+#endif
-- 
1.9.1
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

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

* [PATCH V4 08/13] dt-bindings: interconnect: add MT8183 interconnect dt-bindings
@ 2020-03-13  9:34   ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, Henry Chen, Fan Chen,
	devicetree, linux-mediatek, Arvin Wang, linux-arm-kernel

Add interconnect provider dt-bindings for MT8183.

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 .../devicetree/bindings/soc/mediatek/dvfsrc.txt        |  9 +++++++++
 include/dt-bindings/interconnect/mtk,mt8183-emi.h      | 18 ++++++++++++++++++
 2 files changed, 27 insertions(+)
 create mode 100644 include/dt-bindings/interconnect/mtk,mt8183-emi.h

diff --git a/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
index 7f43499..da98ec9 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
+++ b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
@@ -12,6 +12,11 @@ Required Properties:
 - clock-names: Must include the following entries:
 	"dvfsrc": DVFSRC module clock
 - clocks: Must contain an entry for each entry in clock-names.
+- #interconnect-cells : should contain 1
+- interconnect : interconnect providers support dram bandwidth requirements.
+	The provider is able to communicate with the DVFSRC and send the dram
+	bandwidth to it. shall contain only one of the following:
+	"mediatek,mt8183-emi"
 
 Example:
 
@@ -20,4 +25,8 @@ Example:
 		reg = <0 0x10012000 0 0x1000>;
 		clocks = <&infracfg CLK_INFRA_DVFSRC>;
 		clock-names = "dvfsrc";
+		ddr_emi: interconnect {
+			compatible = "mediatek,mt8183-emi";
+			#interconnect-cells = <1>;
+		};
 	};
diff --git a/include/dt-bindings/interconnect/mtk,mt8183-emi.h b/include/dt-bindings/interconnect/mtk,mt8183-emi.h
new file mode 100644
index 0000000..2a54856
--- /dev/null
+++ b/include/dt-bindings/interconnect/mtk,mt8183-emi.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __DT_BINDINGS_INTERCONNECT_MTK_MT8183_EMI_H
+#define __DT_BINDINGS_INTERCONNECT_MTK_MT8183_EMI_H
+
+#define MT8183_SLAVE_DDR_EMI			0
+#define MT8183_MASTER_MCUSYS			1
+#define MT8183_MASTER_GPU			2
+#define MT8183_MASTER_MMSYS			3
+#define MT8183_MASTER_MM_VPU			4
+#define MT8183_MASTER_MM_DISP			5
+#define MT8183_MASTER_MM_VDEC			6
+#define MT8183_MASTER_MM_VENC			7
+#define MT8183_MASTER_MM_CAM			8
+#define MT8183_MASTER_MM_IMG			9
+#define MT8183_MASTER_MM_MDP			10
+
+#endif
-- 
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V4 09/13] interconnect: mediatek: Add mt8183 interconnect provider driver
  2020-03-13  9:34 ` Henry Chen
  (?)
@ 2020-03-13  9:34   ` Henry Chen
  -1 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Fan Chen, James Liao, Arvin Wang,
	Mike Turquette, devicetree, linux-arm-kernel, linux-mediatek,
	linux-kernel, linux-pm, srv_heupstream, Henry Chen

Introduce Mediatek MT8183 specific provider driver using the
interconnect framework.

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 drivers/interconnect/Kconfig            |   1 +
 drivers/interconnect/Makefile           |   1 +
 drivers/interconnect/mediatek/Kconfig   |  13 ++
 drivers/interconnect/mediatek/Makefile  |   3 +
 drivers/interconnect/mediatek/mtk-emi.c | 242 ++++++++++++++++++++++++++++++++
 5 files changed, 260 insertions(+)
 create mode 100644 drivers/interconnect/mediatek/Kconfig
 create mode 100644 drivers/interconnect/mediatek/Makefile
 create mode 100644 drivers/interconnect/mediatek/mtk-emi.c

diff --git a/drivers/interconnect/Kconfig b/drivers/interconnect/Kconfig
index bfa4ca3..dd9ecb6 100644
--- a/drivers/interconnect/Kconfig
+++ b/drivers/interconnect/Kconfig
@@ -12,5 +12,6 @@ menuconfig INTERCONNECT
 if INTERCONNECT
 
 source "drivers/interconnect/qcom/Kconfig"
+source "drivers/interconnect/mediatek/Kconfig"
 
 endif
diff --git a/drivers/interconnect/Makefile b/drivers/interconnect/Makefile
index 725029a..330a108 100644
--- a/drivers/interconnect/Makefile
+++ b/drivers/interconnect/Makefile
@@ -5,3 +5,4 @@ icc-core-objs				:= core.o
 
 obj-$(CONFIG_INTERCONNECT)		+= icc-core.o
 obj-$(CONFIG_INTERCONNECT_QCOM)		+= qcom/
+obj-$(CONFIG_INTERCONNECT_MTK)		+= mediatek/
diff --git a/drivers/interconnect/mediatek/Kconfig b/drivers/interconnect/mediatek/Kconfig
new file mode 100644
index 0000000..972d3bb
--- /dev/null
+++ b/drivers/interconnect/mediatek/Kconfig
@@ -0,0 +1,13 @@
+config INTERCONNECT_MTK
+	bool "Mediatek Network-on-Chip interconnect drivers"
+	depends on ARCH_MEDIATEK
+	help
+	  Support for Mediatek's Network-on-Chip interconnect hardware.
+
+config INTERCONNECT_MTK_EMI
+	tristate "Mediatek EMI interconnect driver"
+	depends on INTERCONNECT_MTK
+	depends on (MTK_DVFSRC && OF)
+	help
+	  This is a driver for the Mediatek Network-on-Chip on DVFSRC-based
+	  platforms.
diff --git a/drivers/interconnect/mediatek/Makefile b/drivers/interconnect/mediatek/Makefile
new file mode 100644
index 0000000..353842b
--- /dev/null
+++ b/drivers/interconnect/mediatek/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_INTERCONNECT_MTK_EMI) += mtk-emi.o
\ No newline at end of file
diff --git a/drivers/interconnect/mediatek/mtk-emi.c b/drivers/interconnect/mediatek/mtk-emi.c
new file mode 100644
index 0000000..0a16992
--- /dev/null
+++ b/drivers/interconnect/mediatek/mtk-emi.c
@@ -0,0 +1,242 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ *
+ */
+
+#include <dt-bindings/interconnect/mtk,mt8183-emi.h>
+#include <linux/device.h>
+#include <linux/interconnect-provider.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <soc/mediatek/mtk_dvfsrc.h>
+
+enum mtk_icc_name {
+	SLAVE_DDR_EMI,
+	MASTER_MCUSYS,
+	MASTER_GPUSYS,
+	MASTER_MMSYS,
+	MASTER_MM_VPU,
+	MASTER_MM_DISP,
+	MASTER_MM_VDEC,
+	MASTER_MM_VENC,
+	MASTER_MM_CAM,
+	MASTER_MM_IMG,
+	MASTER_MM_MDP,
+};
+
+#define MT8183_MAX_LINKS	1
+
+/**
+ * struct mtk_icc_node - Mediatek specific interconnect nodes
+ * @name: the node name used in debugfs
+ * @ep: true if the node is an end point.
+ * @id: a unique node identifier
+ * @links: an array of nodes where we can go next while traversing
+ * @num_links: the total number of @links
+ * @buswidth: width of the interconnect between a node and the bus
+ * @sum_avg: current sum aggregate value of all avg bw kBps requests
+ * @max_peak: current max aggregate value of all peak bw kBps requests
+ */
+struct mtk_icc_node {
+	unsigned char *name;
+	bool ep;
+	u16 id;
+	u16 links[MT8183_MAX_LINKS];
+	u16 num_links;
+	u16 buswidth;
+	u64 sum_avg;
+	u64 max_peak;
+};
+
+struct mtk_icc_desc {
+	struct mtk_icc_node **nodes;
+	size_t num_nodes;
+};
+
+#define DEFINE_MNODE(_name, _id, _buswidth, _ep, ...)	\
+		static struct mtk_icc_node _name = {			\
+		.name = #_name,						\
+		.id = _id,						\
+		.buswidth = _buswidth,					\
+		.ep = _ep,						\
+		.num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ })),	\
+}
+
+DEFINE_MNODE(ddr_emi, SLAVE_DDR_EMI, 1024, 1, 0);
+DEFINE_MNODE(mcusys, MASTER_MCUSYS, 256, 0, SLAVE_DDR_EMI);
+DEFINE_MNODE(gpu, MASTER_GPUSYS, 256, 0, SLAVE_DDR_EMI);
+DEFINE_MNODE(mmsys, MASTER_MMSYS, 256, 0, SLAVE_DDR_EMI);
+DEFINE_MNODE(mm_vpu, MASTER_MM_VPU, 128, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_disp, MASTER_MM_DISP, 128, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_vdec, MASTER_MM_VDEC, 128, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_venc, MASTER_MM_VENC, 128, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_cam, MASTER_MM_CAM, 128, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_img, MASTER_MM_IMG, 128, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_mdp, MASTER_MM_MDP, 128, 0, MASTER_MMSYS);
+
+static struct mtk_icc_node *mt8183_icc_nodes[] = {
+	[MT8183_SLAVE_DDR_EMI] = &ddr_emi,
+	[MT8183_MASTER_MCUSYS] = &mcusys,
+	[MT8183_MASTER_GPU] = &gpu,
+	[MT8183_MASTER_MMSYS] = &mmsys,
+	[MT8183_MASTER_MM_VPU] = &mm_vpu,
+	[MT8183_MASTER_MM_DISP] = &mm_disp,
+	[MT8183_MASTER_MM_VDEC] = &mm_vdec,
+	[MT8183_MASTER_MM_VENC] = &mm_venc,
+	[MT8183_MASTER_MM_CAM] = &mm_cam,
+	[MT8183_MASTER_MM_IMG] = &mm_img,
+	[MT8183_MASTER_MM_MDP] = &mm_mdp,
+};
+
+static struct mtk_icc_desc mt8183_icc = {
+	.nodes = mt8183_icc_nodes,
+	.num_nodes = ARRAY_SIZE(mt8183_icc_nodes),
+};
+
+static int emi_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
+			     u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
+{
+	struct mtk_icc_node *in;
+
+	in = node->data;
+
+	*agg_avg += avg_bw;
+	*agg_peak += peak_bw;
+
+	in->sum_avg = *agg_avg;
+	in->max_peak = *agg_peak;
+
+	return 0;
+}
+
+static int emi_icc_set(struct icc_node *src, struct icc_node *dst)
+{
+	int ret = 0;
+	struct mtk_icc_node *node;
+
+	node = dst->data;
+	if (node->ep) {
+		pr_debug("sum_avg (%llu), max_peak (%llu)\n",
+			 node->sum_avg, node->max_peak);
+		mtk_dvfsrc_send_request(src->provider->dev->parent,
+					MTK_DVFSRC_CMD_BW_REQUEST,
+					node->max_peak);
+	}
+
+	return ret;
+}
+
+static int emi_icc_remove(struct platform_device *pdev);
+static int emi_icc_probe(struct platform_device *pdev)
+{
+	int ret;
+	const struct mtk_icc_desc *desc;
+	struct icc_node *node;
+	struct icc_onecell_data *data;
+	struct icc_provider *provider;
+	struct mtk_icc_node **mnodes;
+	size_t num_nodes, i, j;
+
+	desc = of_device_get_match_data(&pdev->dev);
+	if (!desc)
+		return -EINVAL;
+
+	mnodes = desc->nodes;
+	num_nodes = desc->num_nodes;
+
+	provider = devm_kzalloc(&pdev->dev, sizeof(*provider), GFP_KERNEL);
+	if (!provider)
+		return -ENOMEM;
+
+	data = devm_kcalloc(&pdev->dev, num_nodes, sizeof(*node), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	provider->dev = &pdev->dev;
+	provider->set = emi_icc_set;
+	provider->aggregate = emi_icc_aggregate;
+	provider->xlate = of_icc_xlate_onecell;
+	INIT_LIST_HEAD(&provider->nodes);
+	provider->data = data;
+
+	ret = icc_provider_add(provider);
+	if (ret) {
+		dev_err(&pdev->dev, "error adding interconnect provider\n");
+		return ret;
+	}
+
+	for (i = 0; i < num_nodes; i++) {
+		node = icc_node_create(mnodes[i]->id);
+		if (IS_ERR(node)) {
+			ret = PTR_ERR(node);
+			goto err;
+		}
+
+		node->name = mnodes[i]->name;
+		node->data = mnodes[i];
+		icc_node_add(node, provider);
+
+		dev_dbg(&pdev->dev, "registered node %s, num link: %d\n",
+			mnodes[i]->name, mnodes[i]->num_links);
+
+		/* populate links */
+		for (j = 0; j < mnodes[i]->num_links; j++)
+			icc_link_create(node, mnodes[i]->links[j]);
+
+		data->nodes[i] = node;
+	}
+	data->num_nodes = num_nodes;
+
+	platform_set_drvdata(pdev, provider);
+
+	return 0;
+err:
+	emi_icc_remove(pdev);
+	return ret;
+}
+
+static int emi_icc_remove(struct platform_device *pdev)
+{
+	struct icc_provider *provider = platform_get_drvdata(pdev);
+	struct icc_node *n;
+
+	list_for_each_entry(n, &provider->nodes, node_list) {
+		icc_node_del(n);
+		icc_node_destroy(n->id);
+	}
+
+	return icc_provider_del(provider);
+}
+
+static const struct of_device_id emi_icc_of_match[] = {
+	{ .compatible = "mediatek,mt8183-emi", .data = &mt8183_icc },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, emi_icc_of_match);
+
+static struct platform_driver emi_icc_driver = {
+	.probe = emi_icc_probe,
+	.remove = emi_icc_remove,
+	.driver = {
+		.name = "mediatek-emi-icc",
+		.of_match_table = emi_icc_of_match,
+	},
+};
+
+static int __init mtk_emi_icc_init(void)
+{
+	return platform_driver_register(&emi_icc_driver);
+}
+subsys_initcall(mtk_emi_icc_init);
+
+static void __exit mtk_emi_icc_exit(void)
+{
+	platform_driver_unregister(&emi_icc_driver);
+}
+module_exit(mtk_emi_icc_exit);
+
+MODULE_AUTHOR("Henry Chen <henryc.chen@mediatek.com>");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

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

* [PATCH V4 09/13] interconnect: mediatek: Add mt8183 interconnect provider driver
@ 2020-03-13  9:34   ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, Henry Chen, Fan Chen,
	devicetree, linux-mediatek, Arvin Wang, linux-arm-kernel

Introduce Mediatek MT8183 specific provider driver using the
interconnect framework.

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 drivers/interconnect/Kconfig            |   1 +
 drivers/interconnect/Makefile           |   1 +
 drivers/interconnect/mediatek/Kconfig   |  13 ++
 drivers/interconnect/mediatek/Makefile  |   3 +
 drivers/interconnect/mediatek/mtk-emi.c | 242 ++++++++++++++++++++++++++++++++
 5 files changed, 260 insertions(+)
 create mode 100644 drivers/interconnect/mediatek/Kconfig
 create mode 100644 drivers/interconnect/mediatek/Makefile
 create mode 100644 drivers/interconnect/mediatek/mtk-emi.c

diff --git a/drivers/interconnect/Kconfig b/drivers/interconnect/Kconfig
index bfa4ca3..dd9ecb6 100644
--- a/drivers/interconnect/Kconfig
+++ b/drivers/interconnect/Kconfig
@@ -12,5 +12,6 @@ menuconfig INTERCONNECT
 if INTERCONNECT
 
 source "drivers/interconnect/qcom/Kconfig"
+source "drivers/interconnect/mediatek/Kconfig"
 
 endif
diff --git a/drivers/interconnect/Makefile b/drivers/interconnect/Makefile
index 725029a..330a108 100644
--- a/drivers/interconnect/Makefile
+++ b/drivers/interconnect/Makefile
@@ -5,3 +5,4 @@ icc-core-objs				:= core.o
 
 obj-$(CONFIG_INTERCONNECT)		+= icc-core.o
 obj-$(CONFIG_INTERCONNECT_QCOM)		+= qcom/
+obj-$(CONFIG_INTERCONNECT_MTK)		+= mediatek/
diff --git a/drivers/interconnect/mediatek/Kconfig b/drivers/interconnect/mediatek/Kconfig
new file mode 100644
index 0000000..972d3bb
--- /dev/null
+++ b/drivers/interconnect/mediatek/Kconfig
@@ -0,0 +1,13 @@
+config INTERCONNECT_MTK
+	bool "Mediatek Network-on-Chip interconnect drivers"
+	depends on ARCH_MEDIATEK
+	help
+	  Support for Mediatek's Network-on-Chip interconnect hardware.
+
+config INTERCONNECT_MTK_EMI
+	tristate "Mediatek EMI interconnect driver"
+	depends on INTERCONNECT_MTK
+	depends on (MTK_DVFSRC && OF)
+	help
+	  This is a driver for the Mediatek Network-on-Chip on DVFSRC-based
+	  platforms.
diff --git a/drivers/interconnect/mediatek/Makefile b/drivers/interconnect/mediatek/Makefile
new file mode 100644
index 0000000..353842b
--- /dev/null
+++ b/drivers/interconnect/mediatek/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_INTERCONNECT_MTK_EMI) += mtk-emi.o
\ No newline at end of file
diff --git a/drivers/interconnect/mediatek/mtk-emi.c b/drivers/interconnect/mediatek/mtk-emi.c
new file mode 100644
index 0000000..0a16992
--- /dev/null
+++ b/drivers/interconnect/mediatek/mtk-emi.c
@@ -0,0 +1,242 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ *
+ */
+
+#include <dt-bindings/interconnect/mtk,mt8183-emi.h>
+#include <linux/device.h>
+#include <linux/interconnect-provider.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <soc/mediatek/mtk_dvfsrc.h>
+
+enum mtk_icc_name {
+	SLAVE_DDR_EMI,
+	MASTER_MCUSYS,
+	MASTER_GPUSYS,
+	MASTER_MMSYS,
+	MASTER_MM_VPU,
+	MASTER_MM_DISP,
+	MASTER_MM_VDEC,
+	MASTER_MM_VENC,
+	MASTER_MM_CAM,
+	MASTER_MM_IMG,
+	MASTER_MM_MDP,
+};
+
+#define MT8183_MAX_LINKS	1
+
+/**
+ * struct mtk_icc_node - Mediatek specific interconnect nodes
+ * @name: the node name used in debugfs
+ * @ep: true if the node is an end point.
+ * @id: a unique node identifier
+ * @links: an array of nodes where we can go next while traversing
+ * @num_links: the total number of @links
+ * @buswidth: width of the interconnect between a node and the bus
+ * @sum_avg: current sum aggregate value of all avg bw kBps requests
+ * @max_peak: current max aggregate value of all peak bw kBps requests
+ */
+struct mtk_icc_node {
+	unsigned char *name;
+	bool ep;
+	u16 id;
+	u16 links[MT8183_MAX_LINKS];
+	u16 num_links;
+	u16 buswidth;
+	u64 sum_avg;
+	u64 max_peak;
+};
+
+struct mtk_icc_desc {
+	struct mtk_icc_node **nodes;
+	size_t num_nodes;
+};
+
+#define DEFINE_MNODE(_name, _id, _buswidth, _ep, ...)	\
+		static struct mtk_icc_node _name = {			\
+		.name = #_name,						\
+		.id = _id,						\
+		.buswidth = _buswidth,					\
+		.ep = _ep,						\
+		.num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ })),	\
+}
+
+DEFINE_MNODE(ddr_emi, SLAVE_DDR_EMI, 1024, 1, 0);
+DEFINE_MNODE(mcusys, MASTER_MCUSYS, 256, 0, SLAVE_DDR_EMI);
+DEFINE_MNODE(gpu, MASTER_GPUSYS, 256, 0, SLAVE_DDR_EMI);
+DEFINE_MNODE(mmsys, MASTER_MMSYS, 256, 0, SLAVE_DDR_EMI);
+DEFINE_MNODE(mm_vpu, MASTER_MM_VPU, 128, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_disp, MASTER_MM_DISP, 128, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_vdec, MASTER_MM_VDEC, 128, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_venc, MASTER_MM_VENC, 128, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_cam, MASTER_MM_CAM, 128, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_img, MASTER_MM_IMG, 128, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_mdp, MASTER_MM_MDP, 128, 0, MASTER_MMSYS);
+
+static struct mtk_icc_node *mt8183_icc_nodes[] = {
+	[MT8183_SLAVE_DDR_EMI] = &ddr_emi,
+	[MT8183_MASTER_MCUSYS] = &mcusys,
+	[MT8183_MASTER_GPU] = &gpu,
+	[MT8183_MASTER_MMSYS] = &mmsys,
+	[MT8183_MASTER_MM_VPU] = &mm_vpu,
+	[MT8183_MASTER_MM_DISP] = &mm_disp,
+	[MT8183_MASTER_MM_VDEC] = &mm_vdec,
+	[MT8183_MASTER_MM_VENC] = &mm_venc,
+	[MT8183_MASTER_MM_CAM] = &mm_cam,
+	[MT8183_MASTER_MM_IMG] = &mm_img,
+	[MT8183_MASTER_MM_MDP] = &mm_mdp,
+};
+
+static struct mtk_icc_desc mt8183_icc = {
+	.nodes = mt8183_icc_nodes,
+	.num_nodes = ARRAY_SIZE(mt8183_icc_nodes),
+};
+
+static int emi_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
+			     u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
+{
+	struct mtk_icc_node *in;
+
+	in = node->data;
+
+	*agg_avg += avg_bw;
+	*agg_peak += peak_bw;
+
+	in->sum_avg = *agg_avg;
+	in->max_peak = *agg_peak;
+
+	return 0;
+}
+
+static int emi_icc_set(struct icc_node *src, struct icc_node *dst)
+{
+	int ret = 0;
+	struct mtk_icc_node *node;
+
+	node = dst->data;
+	if (node->ep) {
+		pr_debug("sum_avg (%llu), max_peak (%llu)\n",
+			 node->sum_avg, node->max_peak);
+		mtk_dvfsrc_send_request(src->provider->dev->parent,
+					MTK_DVFSRC_CMD_BW_REQUEST,
+					node->max_peak);
+	}
+
+	return ret;
+}
+
+static int emi_icc_remove(struct platform_device *pdev);
+static int emi_icc_probe(struct platform_device *pdev)
+{
+	int ret;
+	const struct mtk_icc_desc *desc;
+	struct icc_node *node;
+	struct icc_onecell_data *data;
+	struct icc_provider *provider;
+	struct mtk_icc_node **mnodes;
+	size_t num_nodes, i, j;
+
+	desc = of_device_get_match_data(&pdev->dev);
+	if (!desc)
+		return -EINVAL;
+
+	mnodes = desc->nodes;
+	num_nodes = desc->num_nodes;
+
+	provider = devm_kzalloc(&pdev->dev, sizeof(*provider), GFP_KERNEL);
+	if (!provider)
+		return -ENOMEM;
+
+	data = devm_kcalloc(&pdev->dev, num_nodes, sizeof(*node), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	provider->dev = &pdev->dev;
+	provider->set = emi_icc_set;
+	provider->aggregate = emi_icc_aggregate;
+	provider->xlate = of_icc_xlate_onecell;
+	INIT_LIST_HEAD(&provider->nodes);
+	provider->data = data;
+
+	ret = icc_provider_add(provider);
+	if (ret) {
+		dev_err(&pdev->dev, "error adding interconnect provider\n");
+		return ret;
+	}
+
+	for (i = 0; i < num_nodes; i++) {
+		node = icc_node_create(mnodes[i]->id);
+		if (IS_ERR(node)) {
+			ret = PTR_ERR(node);
+			goto err;
+		}
+
+		node->name = mnodes[i]->name;
+		node->data = mnodes[i];
+		icc_node_add(node, provider);
+
+		dev_dbg(&pdev->dev, "registered node %s, num link: %d\n",
+			mnodes[i]->name, mnodes[i]->num_links);
+
+		/* populate links */
+		for (j = 0; j < mnodes[i]->num_links; j++)
+			icc_link_create(node, mnodes[i]->links[j]);
+
+		data->nodes[i] = node;
+	}
+	data->num_nodes = num_nodes;
+
+	platform_set_drvdata(pdev, provider);
+
+	return 0;
+err:
+	emi_icc_remove(pdev);
+	return ret;
+}
+
+static int emi_icc_remove(struct platform_device *pdev)
+{
+	struct icc_provider *provider = platform_get_drvdata(pdev);
+	struct icc_node *n;
+
+	list_for_each_entry(n, &provider->nodes, node_list) {
+		icc_node_del(n);
+		icc_node_destroy(n->id);
+	}
+
+	return icc_provider_del(provider);
+}
+
+static const struct of_device_id emi_icc_of_match[] = {
+	{ .compatible = "mediatek,mt8183-emi", .data = &mt8183_icc },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, emi_icc_of_match);
+
+static struct platform_driver emi_icc_driver = {
+	.probe = emi_icc_probe,
+	.remove = emi_icc_remove,
+	.driver = {
+		.name = "mediatek-emi-icc",
+		.of_match_table = emi_icc_of_match,
+	},
+};
+
+static int __init mtk_emi_icc_init(void)
+{
+	return platform_driver_register(&emi_icc_driver);
+}
+subsys_initcall(mtk_emi_icc_init);
+
+static void __exit mtk_emi_icc_exit(void)
+{
+	platform_driver_unregister(&emi_icc_driver);
+}
+module_exit(mtk_emi_icc_exit);
+
+MODULE_AUTHOR("Henry Chen <henryc.chen@mediatek.com>");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

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

* [PATCH V4 09/13] interconnect: mediatek: Add mt8183 interconnect provider driver
@ 2020-03-13  9:34   ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, Henry Chen, Fan Chen,
	devicetree, linux-mediatek, Arvin Wang, linux-arm-kernel

Introduce Mediatek MT8183 specific provider driver using the
interconnect framework.

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 drivers/interconnect/Kconfig            |   1 +
 drivers/interconnect/Makefile           |   1 +
 drivers/interconnect/mediatek/Kconfig   |  13 ++
 drivers/interconnect/mediatek/Makefile  |   3 +
 drivers/interconnect/mediatek/mtk-emi.c | 242 ++++++++++++++++++++++++++++++++
 5 files changed, 260 insertions(+)
 create mode 100644 drivers/interconnect/mediatek/Kconfig
 create mode 100644 drivers/interconnect/mediatek/Makefile
 create mode 100644 drivers/interconnect/mediatek/mtk-emi.c

diff --git a/drivers/interconnect/Kconfig b/drivers/interconnect/Kconfig
index bfa4ca3..dd9ecb6 100644
--- a/drivers/interconnect/Kconfig
+++ b/drivers/interconnect/Kconfig
@@ -12,5 +12,6 @@ menuconfig INTERCONNECT
 if INTERCONNECT
 
 source "drivers/interconnect/qcom/Kconfig"
+source "drivers/interconnect/mediatek/Kconfig"
 
 endif
diff --git a/drivers/interconnect/Makefile b/drivers/interconnect/Makefile
index 725029a..330a108 100644
--- a/drivers/interconnect/Makefile
+++ b/drivers/interconnect/Makefile
@@ -5,3 +5,4 @@ icc-core-objs				:= core.o
 
 obj-$(CONFIG_INTERCONNECT)		+= icc-core.o
 obj-$(CONFIG_INTERCONNECT_QCOM)		+= qcom/
+obj-$(CONFIG_INTERCONNECT_MTK)		+= mediatek/
diff --git a/drivers/interconnect/mediatek/Kconfig b/drivers/interconnect/mediatek/Kconfig
new file mode 100644
index 0000000..972d3bb
--- /dev/null
+++ b/drivers/interconnect/mediatek/Kconfig
@@ -0,0 +1,13 @@
+config INTERCONNECT_MTK
+	bool "Mediatek Network-on-Chip interconnect drivers"
+	depends on ARCH_MEDIATEK
+	help
+	  Support for Mediatek's Network-on-Chip interconnect hardware.
+
+config INTERCONNECT_MTK_EMI
+	tristate "Mediatek EMI interconnect driver"
+	depends on INTERCONNECT_MTK
+	depends on (MTK_DVFSRC && OF)
+	help
+	  This is a driver for the Mediatek Network-on-Chip on DVFSRC-based
+	  platforms.
diff --git a/drivers/interconnect/mediatek/Makefile b/drivers/interconnect/mediatek/Makefile
new file mode 100644
index 0000000..353842b
--- /dev/null
+++ b/drivers/interconnect/mediatek/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_INTERCONNECT_MTK_EMI) += mtk-emi.o
\ No newline at end of file
diff --git a/drivers/interconnect/mediatek/mtk-emi.c b/drivers/interconnect/mediatek/mtk-emi.c
new file mode 100644
index 0000000..0a16992
--- /dev/null
+++ b/drivers/interconnect/mediatek/mtk-emi.c
@@ -0,0 +1,242 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ *
+ */
+
+#include <dt-bindings/interconnect/mtk,mt8183-emi.h>
+#include <linux/device.h>
+#include <linux/interconnect-provider.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <soc/mediatek/mtk_dvfsrc.h>
+
+enum mtk_icc_name {
+	SLAVE_DDR_EMI,
+	MASTER_MCUSYS,
+	MASTER_GPUSYS,
+	MASTER_MMSYS,
+	MASTER_MM_VPU,
+	MASTER_MM_DISP,
+	MASTER_MM_VDEC,
+	MASTER_MM_VENC,
+	MASTER_MM_CAM,
+	MASTER_MM_IMG,
+	MASTER_MM_MDP,
+};
+
+#define MT8183_MAX_LINKS	1
+
+/**
+ * struct mtk_icc_node - Mediatek specific interconnect nodes
+ * @name: the node name used in debugfs
+ * @ep: true if the node is an end point.
+ * @id: a unique node identifier
+ * @links: an array of nodes where we can go next while traversing
+ * @num_links: the total number of @links
+ * @buswidth: width of the interconnect between a node and the bus
+ * @sum_avg: current sum aggregate value of all avg bw kBps requests
+ * @max_peak: current max aggregate value of all peak bw kBps requests
+ */
+struct mtk_icc_node {
+	unsigned char *name;
+	bool ep;
+	u16 id;
+	u16 links[MT8183_MAX_LINKS];
+	u16 num_links;
+	u16 buswidth;
+	u64 sum_avg;
+	u64 max_peak;
+};
+
+struct mtk_icc_desc {
+	struct mtk_icc_node **nodes;
+	size_t num_nodes;
+};
+
+#define DEFINE_MNODE(_name, _id, _buswidth, _ep, ...)	\
+		static struct mtk_icc_node _name = {			\
+		.name = #_name,						\
+		.id = _id,						\
+		.buswidth = _buswidth,					\
+		.ep = _ep,						\
+		.num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ })),	\
+}
+
+DEFINE_MNODE(ddr_emi, SLAVE_DDR_EMI, 1024, 1, 0);
+DEFINE_MNODE(mcusys, MASTER_MCUSYS, 256, 0, SLAVE_DDR_EMI);
+DEFINE_MNODE(gpu, MASTER_GPUSYS, 256, 0, SLAVE_DDR_EMI);
+DEFINE_MNODE(mmsys, MASTER_MMSYS, 256, 0, SLAVE_DDR_EMI);
+DEFINE_MNODE(mm_vpu, MASTER_MM_VPU, 128, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_disp, MASTER_MM_DISP, 128, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_vdec, MASTER_MM_VDEC, 128, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_venc, MASTER_MM_VENC, 128, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_cam, MASTER_MM_CAM, 128, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_img, MASTER_MM_IMG, 128, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_mdp, MASTER_MM_MDP, 128, 0, MASTER_MMSYS);
+
+static struct mtk_icc_node *mt8183_icc_nodes[] = {
+	[MT8183_SLAVE_DDR_EMI] = &ddr_emi,
+	[MT8183_MASTER_MCUSYS] = &mcusys,
+	[MT8183_MASTER_GPU] = &gpu,
+	[MT8183_MASTER_MMSYS] = &mmsys,
+	[MT8183_MASTER_MM_VPU] = &mm_vpu,
+	[MT8183_MASTER_MM_DISP] = &mm_disp,
+	[MT8183_MASTER_MM_VDEC] = &mm_vdec,
+	[MT8183_MASTER_MM_VENC] = &mm_venc,
+	[MT8183_MASTER_MM_CAM] = &mm_cam,
+	[MT8183_MASTER_MM_IMG] = &mm_img,
+	[MT8183_MASTER_MM_MDP] = &mm_mdp,
+};
+
+static struct mtk_icc_desc mt8183_icc = {
+	.nodes = mt8183_icc_nodes,
+	.num_nodes = ARRAY_SIZE(mt8183_icc_nodes),
+};
+
+static int emi_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
+			     u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
+{
+	struct mtk_icc_node *in;
+
+	in = node->data;
+
+	*agg_avg += avg_bw;
+	*agg_peak += peak_bw;
+
+	in->sum_avg = *agg_avg;
+	in->max_peak = *agg_peak;
+
+	return 0;
+}
+
+static int emi_icc_set(struct icc_node *src, struct icc_node *dst)
+{
+	int ret = 0;
+	struct mtk_icc_node *node;
+
+	node = dst->data;
+	if (node->ep) {
+		pr_debug("sum_avg (%llu), max_peak (%llu)\n",
+			 node->sum_avg, node->max_peak);
+		mtk_dvfsrc_send_request(src->provider->dev->parent,
+					MTK_DVFSRC_CMD_BW_REQUEST,
+					node->max_peak);
+	}
+
+	return ret;
+}
+
+static int emi_icc_remove(struct platform_device *pdev);
+static int emi_icc_probe(struct platform_device *pdev)
+{
+	int ret;
+	const struct mtk_icc_desc *desc;
+	struct icc_node *node;
+	struct icc_onecell_data *data;
+	struct icc_provider *provider;
+	struct mtk_icc_node **mnodes;
+	size_t num_nodes, i, j;
+
+	desc = of_device_get_match_data(&pdev->dev);
+	if (!desc)
+		return -EINVAL;
+
+	mnodes = desc->nodes;
+	num_nodes = desc->num_nodes;
+
+	provider = devm_kzalloc(&pdev->dev, sizeof(*provider), GFP_KERNEL);
+	if (!provider)
+		return -ENOMEM;
+
+	data = devm_kcalloc(&pdev->dev, num_nodes, sizeof(*node), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	provider->dev = &pdev->dev;
+	provider->set = emi_icc_set;
+	provider->aggregate = emi_icc_aggregate;
+	provider->xlate = of_icc_xlate_onecell;
+	INIT_LIST_HEAD(&provider->nodes);
+	provider->data = data;
+
+	ret = icc_provider_add(provider);
+	if (ret) {
+		dev_err(&pdev->dev, "error adding interconnect provider\n");
+		return ret;
+	}
+
+	for (i = 0; i < num_nodes; i++) {
+		node = icc_node_create(mnodes[i]->id);
+		if (IS_ERR(node)) {
+			ret = PTR_ERR(node);
+			goto err;
+		}
+
+		node->name = mnodes[i]->name;
+		node->data = mnodes[i];
+		icc_node_add(node, provider);
+
+		dev_dbg(&pdev->dev, "registered node %s, num link: %d\n",
+			mnodes[i]->name, mnodes[i]->num_links);
+
+		/* populate links */
+		for (j = 0; j < mnodes[i]->num_links; j++)
+			icc_link_create(node, mnodes[i]->links[j]);
+
+		data->nodes[i] = node;
+	}
+	data->num_nodes = num_nodes;
+
+	platform_set_drvdata(pdev, provider);
+
+	return 0;
+err:
+	emi_icc_remove(pdev);
+	return ret;
+}
+
+static int emi_icc_remove(struct platform_device *pdev)
+{
+	struct icc_provider *provider = platform_get_drvdata(pdev);
+	struct icc_node *n;
+
+	list_for_each_entry(n, &provider->nodes, node_list) {
+		icc_node_del(n);
+		icc_node_destroy(n->id);
+	}
+
+	return icc_provider_del(provider);
+}
+
+static const struct of_device_id emi_icc_of_match[] = {
+	{ .compatible = "mediatek,mt8183-emi", .data = &mt8183_icc },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, emi_icc_of_match);
+
+static struct platform_driver emi_icc_driver = {
+	.probe = emi_icc_probe,
+	.remove = emi_icc_remove,
+	.driver = {
+		.name = "mediatek-emi-icc",
+		.of_match_table = emi_icc_of_match,
+	},
+};
+
+static int __init mtk_emi_icc_init(void)
+{
+	return platform_driver_register(&emi_icc_driver);
+}
+subsys_initcall(mtk_emi_icc_init);
+
+static void __exit mtk_emi_icc_exit(void)
+{
+	platform_driver_unregister(&emi_icc_driver);
+}
+module_exit(mtk_emi_icc_exit);
+
+MODULE_AUTHOR("Henry Chen <henryc.chen@mediatek.com>");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V4 10/13] arm64: dts: mt8183: add dvfsrc related nodes
  2020-03-13  9:34 ` Henry Chen
  (?)
@ 2020-03-13  9:34   ` Henry Chen
  -1 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Fan Chen, James Liao, Arvin Wang,
	Mike Turquette, devicetree, linux-arm-kernel, linux-mediatek,
	linux-kernel, linux-pm, srv_heupstream, Henry Chen

Add DDR EMI provider dictating dram interconnect bus performance found on
MT8183-based platforms

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8183.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index c0d08c8..57a55a3 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -12,6 +12,7 @@
 #include <dt-bindings/reset-controller/mt8183-resets.h>
 #include "mt8183-pinfunc.h"
 #include <dt-bindings/soc/mtk,dvfsrc.h>
+#include <dt-bindings/interconnect/mtk,mt8183-emi.h>
 
 / {
 	compatible = "mediatek,mt8183";
@@ -164,6 +165,10 @@
 		reg = <0 0x10012000 0 0x1000>;
 		clocks = <&infracfg CLK_INFRA_DVFSRC>;
 		clock-names = "dvfsrc";
+		ddr_emi: interconnect {
+			compatible = "mediatek,mt8183-emi";
+			#interconnect-cells = <1>;
+		};
 	};
 
 	timer {
-- 
1.9.1

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

* [PATCH V4 10/13] arm64: dts: mt8183: add dvfsrc related nodes
@ 2020-03-13  9:34   ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, Henry Chen, Fan Chen,
	devicetree, linux-mediatek, Arvin Wang, linux-arm-kernel

Add DDR EMI provider dictating dram interconnect bus performance found on
MT8183-based platforms

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8183.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index c0d08c8..57a55a3 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -12,6 +12,7 @@
 #include <dt-bindings/reset-controller/mt8183-resets.h>
 #include "mt8183-pinfunc.h"
 #include <dt-bindings/soc/mtk,dvfsrc.h>
+#include <dt-bindings/interconnect/mtk,mt8183-emi.h>
 
 / {
 	compatible = "mediatek,mt8183";
@@ -164,6 +165,10 @@
 		reg = <0 0x10012000 0 0x1000>;
 		clocks = <&infracfg CLK_INFRA_DVFSRC>;
 		clock-names = "dvfsrc";
+		ddr_emi: interconnect {
+			compatible = "mediatek,mt8183-emi";
+			#interconnect-cells = <1>;
+		};
 	};
 
 	timer {
-- 
1.9.1
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

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

* [PATCH V4 10/13] arm64: dts: mt8183: add dvfsrc related nodes
@ 2020-03-13  9:34   ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, Henry Chen, Fan Chen,
	devicetree, linux-mediatek, Arvin Wang, linux-arm-kernel

Add DDR EMI provider dictating dram interconnect bus performance found on
MT8183-based platforms

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8183.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index c0d08c8..57a55a3 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -12,6 +12,7 @@
 #include <dt-bindings/reset-controller/mt8183-resets.h>
 #include "mt8183-pinfunc.h"
 #include <dt-bindings/soc/mtk,dvfsrc.h>
+#include <dt-bindings/interconnect/mtk,mt8183-emi.h>
 
 / {
 	compatible = "mediatek,mt8183";
@@ -164,6 +165,10 @@
 		reg = <0 0x10012000 0 0x1000>;
 		clocks = <&infracfg CLK_INFRA_DVFSRC>;
 		clock-names = "dvfsrc";
+		ddr_emi: interconnect {
+			compatible = "mediatek,mt8183-emi";
+			#interconnect-cells = <1>;
+		};
 	};
 
 	timer {
-- 
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V4 11/13] dt-bindings: regulator: add DVFSRC regulator dt-bindings
  2020-03-13  9:34 ` Henry Chen
@ 2020-03-13  9:34   ` Henry Chen
  -1 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, henryc.chen, Fan Chen,
	devicetree, linux-mediatek, Arvin Wang, linux-arm-kernel

From: "henryc.chen" <henryc.chen@mediatek.com>

Add a regulator as sub device into dvfsrc dt-bindings for MT8183.

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
index da98ec9..80f09c0 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
+++ b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
@@ -17,6 +17,11 @@ Required Properties:
 	The provider is able to communicate with the DVFSRC and send the dram
 	bandwidth to it. shall contain only one of the following:
 	"mediatek,mt8183-emi"
+- regulator : The DVFSRC regulator is modelled as a subdevice of the DVFSRC.
+	Because DVFSRC can request power directly via register read/write, likes
+	vcore which is a core power of mt8183. As such, the DVFSRC regulator
+	requires that DVFSRC nodes be present. shall contain only one of the
+	following: "mediatek,mt8183-dvfsrc-regulator"
 
 Example:
 
@@ -29,4 +34,13 @@ Example:
 			compatible = "mediatek,mt8183-emi";
 			#interconnect-cells = <1>;
 		};
+		dvfsrc-regulator {
+			compatible = "mediatek,mt8183-dvfsrc-regulator";
+			dvfsrc_vcore: dvfsrc-vcore {
+				regulator-name = "dvfsrc-vcore";
+				regulator-min-microvolt = <725000>;
+				regulator-max-microvolt = <800000>;
+				regulator-always-on;
+			};
+		};
 	};
-- 
1.9.1
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

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

* [PATCH V4 11/13] dt-bindings: regulator: add DVFSRC regulator dt-bindings
@ 2020-03-13  9:34   ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, henryc.chen, Fan Chen,
	devicetree, linux-mediatek, Arvin Wang, linux-arm-kernel

From: "henryc.chen" <henryc.chen@mediatek.com>

Add a regulator as sub device into dvfsrc dt-bindings for MT8183.

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
index da98ec9..80f09c0 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
+++ b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
@@ -17,6 +17,11 @@ Required Properties:
 	The provider is able to communicate with the DVFSRC and send the dram
 	bandwidth to it. shall contain only one of the following:
 	"mediatek,mt8183-emi"
+- regulator : The DVFSRC regulator is modelled as a subdevice of the DVFSRC.
+	Because DVFSRC can request power directly via register read/write, likes
+	vcore which is a core power of mt8183. As such, the DVFSRC regulator
+	requires that DVFSRC nodes be present. shall contain only one of the
+	following: "mediatek,mt8183-dvfsrc-regulator"
 
 Example:
 
@@ -29,4 +34,13 @@ Example:
 			compatible = "mediatek,mt8183-emi";
 			#interconnect-cells = <1>;
 		};
+		dvfsrc-regulator {
+			compatible = "mediatek,mt8183-dvfsrc-regulator";
+			dvfsrc_vcore: dvfsrc-vcore {
+				regulator-name = "dvfsrc-vcore";
+				regulator-min-microvolt = <725000>;
+				regulator-max-microvolt = <800000>;
+				regulator-always-on;
+			};
+		};
 	};
-- 
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V4 12/13] regulator: Regulator driver for the Mediatek DVFSRC
  2020-03-13  9:34 ` Henry Chen
@ 2020-03-13  9:34   ` Henry Chen
  -1 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, henryc.chen, Fan Chen,
	devicetree, linux-mediatek, Arvin Wang, linux-arm-kernel

From: "henryc.chen" <henryc.chen@mediatek.com>

Driver for regulators exposed by the DVFSRC (dynamic voltage and
frequency scaling resource collector) found in devices based on
mt8183 and newer platforms.

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 drivers/regulator/Kconfig                |  10 +++
 drivers/regulator/Makefile               |   1 +
 drivers/regulator/mtk-dvfsrc-regulator.c | 119 +++++++++++++++++++++++++++++++
 3 files changed, 130 insertions(+)
 create mode 100644 drivers/regulator/mtk-dvfsrc-regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 074a2ef..3962180 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -680,6 +680,16 @@ config REGULATOR_MT6397
 	  This driver supports the control of different power rails of device
 	  through regulator interface.
 
+config REGULATOR_MTK_DVFSRC
+	tristate "MediaTek DVFSRC regulator driver"
+	depends on MTK_DVFSRC
+	help
+	  Say y here to control regulator by DVFSRC (dynamic voltage
+	  and frequency scaling resource collector).
+	  This driver supports to control regulators via the DVFSRC
+	  of Mediatek. It allows for voting on regulator state
+	  between multiple users.
+
 config REGULATOR_PALMAS
 	tristate "TI Palmas PMIC Regulators"
 	depends on MFD_PALMAS
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index c0d6b96..c15c341 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -85,6 +85,7 @@ obj-$(CONFIG_REGULATOR_MT6323)	+= mt6323-regulator.o
 obj-$(CONFIG_REGULATOR_MT6358)	+= mt6358-regulator.o
 obj-$(CONFIG_REGULATOR_MT6380)	+= mt6380-regulator.o
 obj-$(CONFIG_REGULATOR_MT6397)	+= mt6397-regulator.o
+obj-$(CONFIG_REGULATOR_MTK_DVFSRC) += mtk-dvfsrc-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_RPMH) += qcom-rpmh-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_SMD_RPM) += qcom_smd-regulator.o
diff --git a/drivers/regulator/mtk-dvfsrc-regulator.c b/drivers/regulator/mtk-dvfsrc-regulator.c
new file mode 100644
index 0000000..a7389d5
--- /dev/null
+++ b/drivers/regulator/mtk-dvfsrc-regulator.c
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/of_regulator.h>
+#include <soc/mediatek/mtk_dvfsrc.h>
+
+static inline struct device *to_dvfsrc_dev(struct regulator_dev *rdev)
+{
+	return rdev_get_dev(rdev)->parent->parent;
+}
+
+static int dvfsrc_set_voltage_sel(struct regulator_dev *rdev,
+				   unsigned int selector)
+{
+	struct device *dvfsrc_dev = to_dvfsrc_dev(rdev);
+
+	mtk_dvfsrc_send_request(dvfsrc_dev, MTK_DVFSRC_CMD_VCORE_REQUEST,
+				selector);
+
+	return 0;
+}
+
+static int dvfsrc_get_voltage_sel(struct regulator_dev *rdev)
+{
+	struct device *dvfsrc_dev = to_dvfsrc_dev(rdev);
+	int val, ret;
+
+	ret = mtk_dvfsrc_query_info(dvfsrc_dev, MTK_DVFSRC_CMD_VCORE_QUERY,
+				    &val);
+
+	if (ret != 0)
+		return ret;
+
+	return val;
+}
+
+static struct regulator_ops dvfsrc_vcore_ops = {
+	.list_voltage = regulator_list_voltage_table,
+	.get_voltage_sel = dvfsrc_get_voltage_sel,
+	.set_voltage_sel = dvfsrc_set_voltage_sel,
+};
+
+static const unsigned int mt8183_voltages[] = {
+	725000,
+	800000,
+};
+
+static const struct regulator_desc regulator_mt8183_data = {
+	.name = "dvfsrc-vcore",				\
+	.of_match = of_match_ptr("dvfsrc-vcore"),	\
+	.ops = &dvfsrc_vcore_ops,			\
+	.type = REGULATOR_VOLTAGE,			\
+	.id = 0,					\
+	.owner = THIS_MODULE,				\
+	.n_voltages = ARRAY_SIZE(mt8183_voltages),	\
+	.volt_table = mt8183_voltages,			\
+};
+
+static int dvfsrc_vcore_regulator_probe(struct platform_device *pdev)
+{
+	struct regulator_config config = { };
+	struct regulator_dev *rdev;
+	const struct regulator_desc *init_data;
+
+	init_data = of_device_get_match_data(&pdev->dev);
+	if (!init_data)
+		return -EINVAL;
+
+	config.dev = &pdev->dev;
+	rdev = devm_regulator_register(&pdev->dev, init_data, &config);
+	if (IS_ERR(rdev)) {
+		dev_err(&pdev->dev, "failed to register %s\n",
+			init_data->name);
+		return PTR_ERR(rdev);
+	}
+
+	return 0;
+}
+
+static const struct of_device_id mtk_dvfsrc_regulator_match[] = {
+	{
+		.compatible = "mediatek,mt8183-dvfsrc-regulator",
+		.data = &regulator_mt8183_data,
+	}, {
+		/* sentinel */
+	},
+};
+
+static struct platform_driver mtk_dvfsrc_regulator_driver = {
+	.driver = {
+		.name  = "mtk-dvfsrc-regulator",
+		.of_match_table = mtk_dvfsrc_regulator_match,
+	},
+	.probe = dvfsrc_vcore_regulator_probe,
+};
+
+static int __init mtk_dvfsrc_regulator_init(void)
+{
+	return platform_driver_register(&mtk_dvfsrc_regulator_driver);
+}
+subsys_initcall(mtk_dvfsrc_regulator_init);
+
+static void __exit mtk_dvfsrc_regulator_exit(void)
+{
+	platform_driver_unregister(&mtk_dvfsrc_regulator_driver);
+}
+module_exit(mtk_dvfsrc_regulator_exit);
+
+MODULE_AUTHOR("Arvin wang <arvin.wang@mediatek.com>");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

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

* [PATCH V4 12/13] regulator: Regulator driver for the Mediatek DVFSRC
@ 2020-03-13  9:34   ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, henryc.chen, Fan Chen,
	devicetree, linux-mediatek, Arvin Wang, linux-arm-kernel

From: "henryc.chen" <henryc.chen@mediatek.com>

Driver for regulators exposed by the DVFSRC (dynamic voltage and
frequency scaling resource collector) found in devices based on
mt8183 and newer platforms.

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
 drivers/regulator/Kconfig                |  10 +++
 drivers/regulator/Makefile               |   1 +
 drivers/regulator/mtk-dvfsrc-regulator.c | 119 +++++++++++++++++++++++++++++++
 3 files changed, 130 insertions(+)
 create mode 100644 drivers/regulator/mtk-dvfsrc-regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 074a2ef..3962180 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -680,6 +680,16 @@ config REGULATOR_MT6397
 	  This driver supports the control of different power rails of device
 	  through regulator interface.
 
+config REGULATOR_MTK_DVFSRC
+	tristate "MediaTek DVFSRC regulator driver"
+	depends on MTK_DVFSRC
+	help
+	  Say y here to control regulator by DVFSRC (dynamic voltage
+	  and frequency scaling resource collector).
+	  This driver supports to control regulators via the DVFSRC
+	  of Mediatek. It allows for voting on regulator state
+	  between multiple users.
+
 config REGULATOR_PALMAS
 	tristate "TI Palmas PMIC Regulators"
 	depends on MFD_PALMAS
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index c0d6b96..c15c341 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -85,6 +85,7 @@ obj-$(CONFIG_REGULATOR_MT6323)	+= mt6323-regulator.o
 obj-$(CONFIG_REGULATOR_MT6358)	+= mt6358-regulator.o
 obj-$(CONFIG_REGULATOR_MT6380)	+= mt6380-regulator.o
 obj-$(CONFIG_REGULATOR_MT6397)	+= mt6397-regulator.o
+obj-$(CONFIG_REGULATOR_MTK_DVFSRC) += mtk-dvfsrc-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_RPMH) += qcom-rpmh-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_SMD_RPM) += qcom_smd-regulator.o
diff --git a/drivers/regulator/mtk-dvfsrc-regulator.c b/drivers/regulator/mtk-dvfsrc-regulator.c
new file mode 100644
index 0000000..a7389d5
--- /dev/null
+++ b/drivers/regulator/mtk-dvfsrc-regulator.c
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/of_regulator.h>
+#include <soc/mediatek/mtk_dvfsrc.h>
+
+static inline struct device *to_dvfsrc_dev(struct regulator_dev *rdev)
+{
+	return rdev_get_dev(rdev)->parent->parent;
+}
+
+static int dvfsrc_set_voltage_sel(struct regulator_dev *rdev,
+				   unsigned int selector)
+{
+	struct device *dvfsrc_dev = to_dvfsrc_dev(rdev);
+
+	mtk_dvfsrc_send_request(dvfsrc_dev, MTK_DVFSRC_CMD_VCORE_REQUEST,
+				selector);
+
+	return 0;
+}
+
+static int dvfsrc_get_voltage_sel(struct regulator_dev *rdev)
+{
+	struct device *dvfsrc_dev = to_dvfsrc_dev(rdev);
+	int val, ret;
+
+	ret = mtk_dvfsrc_query_info(dvfsrc_dev, MTK_DVFSRC_CMD_VCORE_QUERY,
+				    &val);
+
+	if (ret != 0)
+		return ret;
+
+	return val;
+}
+
+static struct regulator_ops dvfsrc_vcore_ops = {
+	.list_voltage = regulator_list_voltage_table,
+	.get_voltage_sel = dvfsrc_get_voltage_sel,
+	.set_voltage_sel = dvfsrc_set_voltage_sel,
+};
+
+static const unsigned int mt8183_voltages[] = {
+	725000,
+	800000,
+};
+
+static const struct regulator_desc regulator_mt8183_data = {
+	.name = "dvfsrc-vcore",				\
+	.of_match = of_match_ptr("dvfsrc-vcore"),	\
+	.ops = &dvfsrc_vcore_ops,			\
+	.type = REGULATOR_VOLTAGE,			\
+	.id = 0,					\
+	.owner = THIS_MODULE,				\
+	.n_voltages = ARRAY_SIZE(mt8183_voltages),	\
+	.volt_table = mt8183_voltages,			\
+};
+
+static int dvfsrc_vcore_regulator_probe(struct platform_device *pdev)
+{
+	struct regulator_config config = { };
+	struct regulator_dev *rdev;
+	const struct regulator_desc *init_data;
+
+	init_data = of_device_get_match_data(&pdev->dev);
+	if (!init_data)
+		return -EINVAL;
+
+	config.dev = &pdev->dev;
+	rdev = devm_regulator_register(&pdev->dev, init_data, &config);
+	if (IS_ERR(rdev)) {
+		dev_err(&pdev->dev, "failed to register %s\n",
+			init_data->name);
+		return PTR_ERR(rdev);
+	}
+
+	return 0;
+}
+
+static const struct of_device_id mtk_dvfsrc_regulator_match[] = {
+	{
+		.compatible = "mediatek,mt8183-dvfsrc-regulator",
+		.data = &regulator_mt8183_data,
+	}, {
+		/* sentinel */
+	},
+};
+
+static struct platform_driver mtk_dvfsrc_regulator_driver = {
+	.driver = {
+		.name  = "mtk-dvfsrc-regulator",
+		.of_match_table = mtk_dvfsrc_regulator_match,
+	},
+	.probe = dvfsrc_vcore_regulator_probe,
+};
+
+static int __init mtk_dvfsrc_regulator_init(void)
+{
+	return platform_driver_register(&mtk_dvfsrc_regulator_driver);
+}
+subsys_initcall(mtk_dvfsrc_regulator_init);
+
+static void __exit mtk_dvfsrc_regulator_exit(void)
+{
+	platform_driver_unregister(&mtk_dvfsrc_regulator_driver);
+}
+module_exit(mtk_dvfsrc_regulator_exit);
+
+MODULE_AUTHOR("Arvin wang <arvin.wang@mediatek.com>");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V4 13/13] arm64: dts: mt8183: add dvfsrc regulator nodes
  2020-03-13  9:34 ` Henry Chen
@ 2020-03-13  9:34   ` Henry Chen
  -1 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, henryc.chen, Fan Chen,
	devicetree, linux-mediatek, Arvin Wang, linux-arm-kernel

From: "henryc.chen" <henryc.chen@mediatek.com>

Add dvfsrc regulator nodes which is for MT8183-based platforms

Signed-off-by: Henry chen <henryc.chen@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8183.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index 57a55a3..66a3372 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -169,6 +169,15 @@
 			compatible = "mediatek,mt8183-emi";
 			#interconnect-cells = <1>;
 		};
+		dvfsrc-regulator {
+			compatible = "mediatek,mt8183-dvfsrc-regulator";
+			dvfsrc_vcore: dvfsrc-vcore {
+				regulator-name = "dvfsrc-vcore";
+				regulator-min-microvolt = <725000>;
+				regulator-max-microvolt = <800000>;
+				regulator-always-on;
+			};
+		};
 	};
 
 	timer {
-- 
1.9.1
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

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

* [PATCH V4 13/13] arm64: dts: mt8183: add dvfsrc regulator nodes
@ 2020-03-13  9:34   ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-13  9:34 UTC (permalink / raw)
  To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, linux-pm, linux-kernel, henryc.chen, Fan Chen,
	devicetree, linux-mediatek, Arvin Wang, linux-arm-kernel

From: "henryc.chen" <henryc.chen@mediatek.com>

Add dvfsrc regulator nodes which is for MT8183-based platforms

Signed-off-by: Henry chen <henryc.chen@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8183.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index 57a55a3..66a3372 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -169,6 +169,15 @@
 			compatible = "mediatek,mt8183-emi";
 			#interconnect-cells = <1>;
 		};
+		dvfsrc-regulator {
+			compatible = "mediatek,mt8183-dvfsrc-regulator";
+			dvfsrc_vcore: dvfsrc-vcore {
+				regulator-name = "dvfsrc-vcore";
+				regulator-min-microvolt = <725000>;
+				regulator-max-microvolt = <800000>;
+				regulator-always-on;
+			};
+		};
 	};
 
 	timer {
-- 
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH V4 08/13] dt-bindings: interconnect: add MT8183 interconnect dt-bindings
  2020-03-13  9:34   ` Henry Chen
  (?)
@ 2020-03-20 23:09     ` Rob Herring
  -1 siblings, 0 replies; 66+ messages in thread
From: Rob Herring @ 2020-03-20 23:09 UTC (permalink / raw)
  To: Henry Chen
  Cc: Georgi Djakov, Matthias Brugger, Viresh Kumar, Stephen Boyd,
	Ryan Case, Mark Brown, Mark Rutland, Nicolas Boichat, Fan Chen,
	James Liao, Arvin Wang, Mike Turquette, devicetree,
	linux-arm-kernel, linux-mediatek, linux-kernel, linux-pm,
	srv_heupstream

On Fri, Mar 13, 2020 at 05:34:21PM +0800, Henry Chen wrote:
> Add interconnect provider dt-bindings for MT8183.
> 
> Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
> ---
>  .../devicetree/bindings/soc/mediatek/dvfsrc.txt        |  9 +++++++++
>  include/dt-bindings/interconnect/mtk,mt8183-emi.h      | 18 ++++++++++++++++++
>  2 files changed, 27 insertions(+)
>  create mode 100644 include/dt-bindings/interconnect/mtk,mt8183-emi.h
> 
> diff --git a/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
> index 7f43499..da98ec9 100644
> --- a/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
> +++ b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
> @@ -12,6 +12,11 @@ Required Properties:
>  - clock-names: Must include the following entries:
>  	"dvfsrc": DVFSRC module clock
>  - clocks: Must contain an entry for each entry in clock-names.
> +- #interconnect-cells : should contain 1
> +- interconnect : interconnect providers support dram bandwidth requirements.
> +	The provider is able to communicate with the DVFSRC and send the dram
> +	bandwidth to it. shall contain only one of the following:
> +	"mediatek,mt8183-emi"
>  
>  Example:
>  
> @@ -20,4 +25,8 @@ Example:
>  		reg = <0 0x10012000 0 0x1000>;
>  		clocks = <&infracfg CLK_INFRA_DVFSRC>;
>  		clock-names = "dvfsrc";
> +		ddr_emi: interconnect {
> +			compatible = "mediatek,mt8183-emi";
> +			#interconnect-cells = <1>;

Nodes with a compatible and no defined way to access the hardware always 
look suspicious. Can't you make the parent node an interconnect 
provider.

Rob

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

* Re: [PATCH V4 08/13] dt-bindings: interconnect: add MT8183 interconnect dt-bindings
@ 2020-03-20 23:09     ` Rob Herring
  0 siblings, 0 replies; 66+ messages in thread
From: Rob Herring @ 2020-03-20 23:09 UTC (permalink / raw)
  To: Henry Chen
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, Viresh Kumar, linux-pm, linux-kernel, Stephen Boyd,
	Fan Chen, devicetree, Mark Brown, Ryan Case, Arvin Wang,
	Matthias Brugger, linux-mediatek, Georgi Djakov,
	linux-arm-kernel

On Fri, Mar 13, 2020 at 05:34:21PM +0800, Henry Chen wrote:
> Add interconnect provider dt-bindings for MT8183.
> 
> Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
> ---
>  .../devicetree/bindings/soc/mediatek/dvfsrc.txt        |  9 +++++++++
>  include/dt-bindings/interconnect/mtk,mt8183-emi.h      | 18 ++++++++++++++++++
>  2 files changed, 27 insertions(+)
>  create mode 100644 include/dt-bindings/interconnect/mtk,mt8183-emi.h
> 
> diff --git a/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
> index 7f43499..da98ec9 100644
> --- a/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
> +++ b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
> @@ -12,6 +12,11 @@ Required Properties:
>  - clock-names: Must include the following entries:
>  	"dvfsrc": DVFSRC module clock
>  - clocks: Must contain an entry for each entry in clock-names.
> +- #interconnect-cells : should contain 1
> +- interconnect : interconnect providers support dram bandwidth requirements.
> +	The provider is able to communicate with the DVFSRC and send the dram
> +	bandwidth to it. shall contain only one of the following:
> +	"mediatek,mt8183-emi"
>  
>  Example:
>  
> @@ -20,4 +25,8 @@ Example:
>  		reg = <0 0x10012000 0 0x1000>;
>  		clocks = <&infracfg CLK_INFRA_DVFSRC>;
>  		clock-names = "dvfsrc";
> +		ddr_emi: interconnect {
> +			compatible = "mediatek,mt8183-emi";
> +			#interconnect-cells = <1>;

Nodes with a compatible and no defined way to access the hardware always 
look suspicious. Can't you make the parent node an interconnect 
provider.

Rob

_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

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

* Re: [PATCH V4 08/13] dt-bindings: interconnect: add MT8183 interconnect dt-bindings
@ 2020-03-20 23:09     ` Rob Herring
  0 siblings, 0 replies; 66+ messages in thread
From: Rob Herring @ 2020-03-20 23:09 UTC (permalink / raw)
  To: Henry Chen
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, Viresh Kumar, linux-pm, linux-kernel, Stephen Boyd,
	Fan Chen, devicetree, Mark Brown, Ryan Case, Arvin Wang,
	Matthias Brugger, linux-mediatek, Georgi Djakov,
	linux-arm-kernel

On Fri, Mar 13, 2020 at 05:34:21PM +0800, Henry Chen wrote:
> Add interconnect provider dt-bindings for MT8183.
> 
> Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
> ---
>  .../devicetree/bindings/soc/mediatek/dvfsrc.txt        |  9 +++++++++
>  include/dt-bindings/interconnect/mtk,mt8183-emi.h      | 18 ++++++++++++++++++
>  2 files changed, 27 insertions(+)
>  create mode 100644 include/dt-bindings/interconnect/mtk,mt8183-emi.h
> 
> diff --git a/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
> index 7f43499..da98ec9 100644
> --- a/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
> +++ b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
> @@ -12,6 +12,11 @@ Required Properties:
>  - clock-names: Must include the following entries:
>  	"dvfsrc": DVFSRC module clock
>  - clocks: Must contain an entry for each entry in clock-names.
> +- #interconnect-cells : should contain 1
> +- interconnect : interconnect providers support dram bandwidth requirements.
> +	The provider is able to communicate with the DVFSRC and send the dram
> +	bandwidth to it. shall contain only one of the following:
> +	"mediatek,mt8183-emi"
>  
>  Example:
>  
> @@ -20,4 +25,8 @@ Example:
>  		reg = <0 0x10012000 0 0x1000>;
>  		clocks = <&infracfg CLK_INFRA_DVFSRC>;
>  		clock-names = "dvfsrc";
> +		ddr_emi: interconnect {
> +			compatible = "mediatek,mt8183-emi";
> +			#interconnect-cells = <1>;

Nodes with a compatible and no defined way to access the hardware always 
look suspicious. Can't you make the parent node an interconnect 
provider.

Rob

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH V4 11/13] dt-bindings: regulator: add DVFSRC regulator dt-bindings
  2020-03-13  9:34   ` Henry Chen
  (?)
@ 2020-03-24 20:38     ` Mark Brown
  -1 siblings, 0 replies; 66+ messages in thread
From: Mark Brown @ 2020-03-24 20:38 UTC (permalink / raw)
  To: Henry Chen
  Cc: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Rutland, Nicolas Boichat, Fan Chen,
	James Liao, Arvin Wang, Mike Turquette, devicetree,
	linux-arm-kernel, linux-mediatek, linux-kernel, linux-pm,
	srv_heupstream

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

On Fri, Mar 13, 2020 at 05:34:24PM +0800, Henry Chen wrote:

> +- regulator : The DVFSRC regulator is modelled as a subdevice of the DVFSRC.
> +	Because DVFSRC can request power directly via register read/write, likes
> +	vcore which is a core power of mt8183. As such, the DVFSRC regulator
> +	requires that DVFSRC nodes be present. shall contain only one of the
> +	following: "mediatek,mt8183-dvfsrc-regulator"

Why do we even need a compatible here - it's not adding any new
information to the parent mt8183 node, the compatible is mainly for the
way Linux divides things up rather than a description of the hardware.
We could just say that the regulator node always has a particular name
instead.

It's also not quite true that it contains "only" the compatible - it
also allows the regulator constraints to be defined.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH V4 11/13] dt-bindings: regulator: add DVFSRC regulator dt-bindings
@ 2020-03-24 20:38     ` Mark Brown
  0 siblings, 0 replies; 66+ messages in thread
From: Mark Brown @ 2020-03-24 20:38 UTC (permalink / raw)
  To: Henry Chen
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, Viresh Kumar, linux-pm, linux-kernel, Stephen Boyd,
	Fan Chen, devicetree, Rob Herring, Ryan Case, Arvin Wang,
	Matthias Brugger, linux-mediatek, Georgi Djakov,
	linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 825 bytes --]

On Fri, Mar 13, 2020 at 05:34:24PM +0800, Henry Chen wrote:

> +- regulator : The DVFSRC regulator is modelled as a subdevice of the DVFSRC.
> +	Because DVFSRC can request power directly via register read/write, likes
> +	vcore which is a core power of mt8183. As such, the DVFSRC regulator
> +	requires that DVFSRC nodes be present. shall contain only one of the
> +	following: "mediatek,mt8183-dvfsrc-regulator"

Why do we even need a compatible here - it's not adding any new
information to the parent mt8183 node, the compatible is mainly for the
way Linux divides things up rather than a description of the hardware.
We could just say that the regulator node always has a particular name
instead.

It's also not quite true that it contains "only" the compatible - it
also allows the regulator constraints to be defined.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 170 bytes --]

_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

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

* Re: [PATCH V4 11/13] dt-bindings: regulator: add DVFSRC regulator dt-bindings
@ 2020-03-24 20:38     ` Mark Brown
  0 siblings, 0 replies; 66+ messages in thread
From: Mark Brown @ 2020-03-24 20:38 UTC (permalink / raw)
  To: Henry Chen
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, Viresh Kumar, linux-pm, linux-kernel, Stephen Boyd,
	Fan Chen, devicetree, Rob Herring, Ryan Case, Arvin Wang,
	Matthias Brugger, linux-mediatek, Georgi Djakov,
	linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 825 bytes --]

On Fri, Mar 13, 2020 at 05:34:24PM +0800, Henry Chen wrote:

> +- regulator : The DVFSRC regulator is modelled as a subdevice of the DVFSRC.
> +	Because DVFSRC can request power directly via register read/write, likes
> +	vcore which is a core power of mt8183. As such, the DVFSRC regulator
> +	requires that DVFSRC nodes be present. shall contain only one of the
> +	following: "mediatek,mt8183-dvfsrc-regulator"

Why do we even need a compatible here - it's not adding any new
information to the parent mt8183 node, the compatible is mainly for the
way Linux divides things up rather than a description of the hardware.
We could just say that the regulator node always has a particular name
instead.

It's also not quite true that it contains "only" the compatible - it
also allows the regulator constraints to be defined.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH V4 11/13] dt-bindings: regulator: add DVFSRC regulator dt-bindings
  2020-03-24 20:38     ` Mark Brown
  (?)
@ 2020-03-30  5:19       ` Henry Chen
  -1 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-30  5:19 UTC (permalink / raw)
  To: Mark Brown
  Cc: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
	Stephen Boyd, Ryan Case, Mark Rutland, Nicolas Boichat, Fan Chen,
	James Liao, Arvin Wang, Mike Turquette, devicetree,
	linux-arm-kernel, linux-mediatek, linux-kernel, linux-pm,
	srv_heupstream

Hi Mark,
On Tue, 2020-03-24 at 20:38 +0000, Mark Brown wrote:
> On Fri, Mar 13, 2020 at 05:34:24PM +0800, Henry Chen wrote:
> 
> > +- regulator : The DVFSRC regulator is modelled as a subdevice of the DVFSRC.
> > +	Because DVFSRC can request power directly via register read/write, likes
> > +	vcore which is a core power of mt8183. As such, the DVFSRC regulator
> > +	requires that DVFSRC nodes be present. shall contain only one of the
> > +	following: "mediatek,mt8183-dvfsrc-regulator"
> 
> Why do we even need a compatible here - it's not adding any new
> information to the parent mt8183 node, the compatible is mainly for the
> way Linux divides things up rather than a description of the hardware.
> We could just say that the regulator node always has a particular name
> instead.
Sorry, not quite sure what you mean, because I think DVFSRC is a
regulator provider that can provide vcore voltage control on mt8183, and
it can provide more power control in the next generation Mediatek SOC.
Here I add a sub-node to describe it. Or should I move this node to
regulator folder? 

> 
> It's also not quite true that it contains "only" the compatible - it
> also allows the regulator constraints to be defined.


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

* Re: [PATCH V4 11/13] dt-bindings: regulator: add DVFSRC regulator dt-bindings
@ 2020-03-30  5:19       ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-30  5:19 UTC (permalink / raw)
  To: Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, Viresh Kumar, linux-pm, linux-kernel, Stephen Boyd,
	Fan Chen, devicetree, Rob Herring, Ryan Case, Arvin Wang,
	Matthias Brugger, linux-mediatek, Georgi Djakov,
	linux-arm-kernel

Hi Mark,
On Tue, 2020-03-24 at 20:38 +0000, Mark Brown wrote:
> On Fri, Mar 13, 2020 at 05:34:24PM +0800, Henry Chen wrote:
> 
> > +- regulator : The DVFSRC regulator is modelled as a subdevice of the DVFSRC.
> > +	Because DVFSRC can request power directly via register read/write, likes
> > +	vcore which is a core power of mt8183. As such, the DVFSRC regulator
> > +	requires that DVFSRC nodes be present. shall contain only one of the
> > +	following: "mediatek,mt8183-dvfsrc-regulator"
> 
> Why do we even need a compatible here - it's not adding any new
> information to the parent mt8183 node, the compatible is mainly for the
> way Linux divides things up rather than a description of the hardware.
> We could just say that the regulator node always has a particular name
> instead.
Sorry, not quite sure what you mean, because I think DVFSRC is a
regulator provider that can provide vcore voltage control on mt8183, and
it can provide more power control in the next generation Mediatek SOC.
Here I add a sub-node to describe it. Or should I move this node to
regulator folder? 

> 
> It's also not quite true that it contains "only" the compatible - it
> also allows the regulator constraints to be defined.

_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

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

* Re: [PATCH V4 11/13] dt-bindings: regulator: add DVFSRC regulator dt-bindings
@ 2020-03-30  5:19       ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-03-30  5:19 UTC (permalink / raw)
  To: Mark Brown
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, Viresh Kumar, linux-pm, linux-kernel, Stephen Boyd,
	Fan Chen, devicetree, Rob Herring, Ryan Case, Arvin Wang,
	Matthias Brugger, linux-mediatek, Georgi Djakov,
	linux-arm-kernel

Hi Mark,
On Tue, 2020-03-24 at 20:38 +0000, Mark Brown wrote:
> On Fri, Mar 13, 2020 at 05:34:24PM +0800, Henry Chen wrote:
> 
> > +- regulator : The DVFSRC regulator is modelled as a subdevice of the DVFSRC.
> > +	Because DVFSRC can request power directly via register read/write, likes
> > +	vcore which is a core power of mt8183. As such, the DVFSRC regulator
> > +	requires that DVFSRC nodes be present. shall contain only one of the
> > +	following: "mediatek,mt8183-dvfsrc-regulator"
> 
> Why do we even need a compatible here - it's not adding any new
> information to the parent mt8183 node, the compatible is mainly for the
> way Linux divides things up rather than a description of the hardware.
> We could just say that the regulator node always has a particular name
> instead.
Sorry, not quite sure what you mean, because I think DVFSRC is a
regulator provider that can provide vcore voltage control on mt8183, and
it can provide more power control in the next generation Mediatek SOC.
Here I add a sub-node to describe it. Or should I move this node to
regulator folder? 

> 
> It's also not quite true that it contains "only" the compatible - it
> also allows the regulator constraints to be defined.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH V4 06/13] soc: mediatek: add MT8183 dvfsrc support
  2020-03-13  9:34   ` Henry Chen
  (?)
@ 2020-04-01 14:41     ` Georgi Djakov
  -1 siblings, 0 replies; 66+ messages in thread
From: Georgi Djakov @ 2020-04-01 14:41 UTC (permalink / raw)
  To: Henry Chen
  Cc: Rob Herring, Matthias Brugger, Viresh Kumar, Stephen Boyd,
	Ryan Case, Mark Brown, Mark Rutland, Nicolas Boichat, Fan Chen,
	James Liao, Arvin Wang, Mike Turquette, devicetree,
	linux-arm-kernel, linux-mediatek, linux-kernel, linux-pm,
	srv_heupstream

Hi Henry,

On 3/13/20 11:34, Henry Chen wrote:
> Add dvfsrc driver for MT8183
> 
> Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
> ---
>  drivers/soc/mediatek/Kconfig      |  15 ++
>  drivers/soc/mediatek/Makefile     |   1 +
>  drivers/soc/mediatek/mtk-dvfsrc.c | 434 ++++++++++++++++++++++++++++++++++++++
>  include/soc/mediatek/mtk_dvfsrc.h |  30 +++
>  4 files changed, 480 insertions(+)
>  create mode 100644 drivers/soc/mediatek/mtk-dvfsrc.c
>  create mode 100644 include/soc/mediatek/mtk_dvfsrc.h
> 
> diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> index f837b3c..44808f4 100644
> --- a/drivers/soc/mediatek/Kconfig
> +++ b/drivers/soc/mediatek/Kconfig
> @@ -16,6 +16,21 @@ config MTK_CMDQ
>  	  time limitation, such as updating display configuration during the
>  	  vblank.
>  
> +config MTK_DVFSRC
> +	bool "MediaTek DVFSRC Support"
> +	depends on ARCH_MEDIATEK
> +	default ARCH_MEDIATEK
> +	select MTK_INFRACFG
> +	select PM_GENERIC_DOMAINS if PM
> +	depends on MTK_SCPSYS
> +	help
> +	  Say yes here to add support for the MediaTek DVFSRC (dynamic voltage
> +	  and frequency scaling resource collector) found
> +	  on different MediaTek SoCs. The DVFSRC is a proprietary
> +	  hardware which is used to collect all the requests from
> +	  system and turn into the decision of minimum Vcore voltage
> +	  and minimum DRAM frequency to fulfill those requests.
> +
>  config MTK_PMIC_WRAP
>  	tristate "MediaTek PMIC Wrapper Support"
>  	depends on RESET_CONTROLLER
> diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> index 2b2c2537..84182f0 100644
> --- a/drivers/soc/mediatek/Makefile
> +++ b/drivers/soc/mediatek/Makefile
> @@ -1,4 +1,5 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>  obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
> +obj-$(CONFIG_MTK_DVFSRC) += mtk-dvfsrc.o
>  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
>  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> diff --git a/drivers/soc/mediatek/mtk-dvfsrc.c b/drivers/soc/mediatek/mtk-dvfsrc.c
> new file mode 100644
> index 0000000..85b3572
> --- /dev/null
> +++ b/drivers/soc/mediatek/mtk-dvfsrc.c
> @@ -0,0 +1,434 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2018 MediaTek Inc.
> + */
> +#include <linux/arm-smccc.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +#include <linux/module.h>
> +#include <linux/notifier.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <soc/mediatek/mtk_dvfsrc.h>
> +#include <soc/mediatek/mtk_sip.h>
> +#include <dt-bindings/power/mt8183-power.h>

Looks like this depends on a header which is not part of this patch-set.
It would be nice to list any dependencies in the cover letter.

Thanks,
Georgi

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

* Re: [PATCH V4 06/13] soc: mediatek: add MT8183 dvfsrc support
@ 2020-04-01 14:41     ` Georgi Djakov
  0 siblings, 0 replies; 66+ messages in thread
From: Georgi Djakov @ 2020-04-01 14:41 UTC (permalink / raw)
  To: Henry Chen
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, Viresh Kumar, linux-pm, linux-kernel, Rob Herring,
	Stephen Boyd, Fan Chen, devicetree, Mark Brown, Ryan Case,
	Arvin Wang, Matthias Brugger, linux-mediatek, linux-arm-kernel

Hi Henry,

On 3/13/20 11:34, Henry Chen wrote:
> Add dvfsrc driver for MT8183
> 
> Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
> ---
>  drivers/soc/mediatek/Kconfig      |  15 ++
>  drivers/soc/mediatek/Makefile     |   1 +
>  drivers/soc/mediatek/mtk-dvfsrc.c | 434 ++++++++++++++++++++++++++++++++++++++
>  include/soc/mediatek/mtk_dvfsrc.h |  30 +++
>  4 files changed, 480 insertions(+)
>  create mode 100644 drivers/soc/mediatek/mtk-dvfsrc.c
>  create mode 100644 include/soc/mediatek/mtk_dvfsrc.h
> 
> diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> index f837b3c..44808f4 100644
> --- a/drivers/soc/mediatek/Kconfig
> +++ b/drivers/soc/mediatek/Kconfig
> @@ -16,6 +16,21 @@ config MTK_CMDQ
>  	  time limitation, such as updating display configuration during the
>  	  vblank.
>  
> +config MTK_DVFSRC
> +	bool "MediaTek DVFSRC Support"
> +	depends on ARCH_MEDIATEK
> +	default ARCH_MEDIATEK
> +	select MTK_INFRACFG
> +	select PM_GENERIC_DOMAINS if PM
> +	depends on MTK_SCPSYS
> +	help
> +	  Say yes here to add support for the MediaTek DVFSRC (dynamic voltage
> +	  and frequency scaling resource collector) found
> +	  on different MediaTek SoCs. The DVFSRC is a proprietary
> +	  hardware which is used to collect all the requests from
> +	  system and turn into the decision of minimum Vcore voltage
> +	  and minimum DRAM frequency to fulfill those requests.
> +
>  config MTK_PMIC_WRAP
>  	tristate "MediaTek PMIC Wrapper Support"
>  	depends on RESET_CONTROLLER
> diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> index 2b2c2537..84182f0 100644
> --- a/drivers/soc/mediatek/Makefile
> +++ b/drivers/soc/mediatek/Makefile
> @@ -1,4 +1,5 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>  obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
> +obj-$(CONFIG_MTK_DVFSRC) += mtk-dvfsrc.o
>  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
>  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> diff --git a/drivers/soc/mediatek/mtk-dvfsrc.c b/drivers/soc/mediatek/mtk-dvfsrc.c
> new file mode 100644
> index 0000000..85b3572
> --- /dev/null
> +++ b/drivers/soc/mediatek/mtk-dvfsrc.c
> @@ -0,0 +1,434 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2018 MediaTek Inc.
> + */
> +#include <linux/arm-smccc.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +#include <linux/module.h>
> +#include <linux/notifier.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <soc/mediatek/mtk_dvfsrc.h>
> +#include <soc/mediatek/mtk_sip.h>
> +#include <dt-bindings/power/mt8183-power.h>

Looks like this depends on a header which is not part of this patch-set.
It would be nice to list any dependencies in the cover letter.

Thanks,
Georgi

_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

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

* Re: [PATCH V4 06/13] soc: mediatek: add MT8183 dvfsrc support
@ 2020-04-01 14:41     ` Georgi Djakov
  0 siblings, 0 replies; 66+ messages in thread
From: Georgi Djakov @ 2020-04-01 14:41 UTC (permalink / raw)
  To: Henry Chen
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, Viresh Kumar, linux-pm, linux-kernel, Rob Herring,
	Stephen Boyd, Fan Chen, devicetree, Mark Brown, Ryan Case,
	Arvin Wang, Matthias Brugger, linux-mediatek, linux-arm-kernel

Hi Henry,

On 3/13/20 11:34, Henry Chen wrote:
> Add dvfsrc driver for MT8183
> 
> Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
> ---
>  drivers/soc/mediatek/Kconfig      |  15 ++
>  drivers/soc/mediatek/Makefile     |   1 +
>  drivers/soc/mediatek/mtk-dvfsrc.c | 434 ++++++++++++++++++++++++++++++++++++++
>  include/soc/mediatek/mtk_dvfsrc.h |  30 +++
>  4 files changed, 480 insertions(+)
>  create mode 100644 drivers/soc/mediatek/mtk-dvfsrc.c
>  create mode 100644 include/soc/mediatek/mtk_dvfsrc.h
> 
> diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> index f837b3c..44808f4 100644
> --- a/drivers/soc/mediatek/Kconfig
> +++ b/drivers/soc/mediatek/Kconfig
> @@ -16,6 +16,21 @@ config MTK_CMDQ
>  	  time limitation, such as updating display configuration during the
>  	  vblank.
>  
> +config MTK_DVFSRC
> +	bool "MediaTek DVFSRC Support"
> +	depends on ARCH_MEDIATEK
> +	default ARCH_MEDIATEK
> +	select MTK_INFRACFG
> +	select PM_GENERIC_DOMAINS if PM
> +	depends on MTK_SCPSYS
> +	help
> +	  Say yes here to add support for the MediaTek DVFSRC (dynamic voltage
> +	  and frequency scaling resource collector) found
> +	  on different MediaTek SoCs. The DVFSRC is a proprietary
> +	  hardware which is used to collect all the requests from
> +	  system and turn into the decision of minimum Vcore voltage
> +	  and minimum DRAM frequency to fulfill those requests.
> +
>  config MTK_PMIC_WRAP
>  	tristate "MediaTek PMIC Wrapper Support"
>  	depends on RESET_CONTROLLER
> diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> index 2b2c2537..84182f0 100644
> --- a/drivers/soc/mediatek/Makefile
> +++ b/drivers/soc/mediatek/Makefile
> @@ -1,4 +1,5 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>  obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
> +obj-$(CONFIG_MTK_DVFSRC) += mtk-dvfsrc.o
>  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
>  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> diff --git a/drivers/soc/mediatek/mtk-dvfsrc.c b/drivers/soc/mediatek/mtk-dvfsrc.c
> new file mode 100644
> index 0000000..85b3572
> --- /dev/null
> +++ b/drivers/soc/mediatek/mtk-dvfsrc.c
> @@ -0,0 +1,434 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2018 MediaTek Inc.
> + */
> +#include <linux/arm-smccc.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +#include <linux/module.h>
> +#include <linux/notifier.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <soc/mediatek/mtk_dvfsrc.h>
> +#include <soc/mediatek/mtk_sip.h>
> +#include <dt-bindings/power/mt8183-power.h>

Looks like this depends on a header which is not part of this patch-set.
It would be nice to list any dependencies in the cover letter.

Thanks,
Georgi

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH V4 09/13] interconnect: mediatek: Add mt8183 interconnect provider driver
  2020-03-13  9:34   ` Henry Chen
  (?)
@ 2020-04-01 14:55     ` Georgi Djakov
  -1 siblings, 0 replies; 66+ messages in thread
From: Georgi Djakov @ 2020-04-01 14:55 UTC (permalink / raw)
  To: Henry Chen
  Cc: Rob Herring, Matthias Brugger, Viresh Kumar, Stephen Boyd,
	Ryan Case, Mark Brown, Mark Rutland, Nicolas Boichat, Fan Chen,
	James Liao, Arvin Wang, Mike Turquette, devicetree,
	linux-arm-kernel, linux-mediatek, linux-kernel, linux-pm,
	srv_heupstream

Hi Henry,

Thanks for the patch!

On 3/13/20 11:34, Henry Chen wrote:
> Introduce Mediatek MT8183 specific provider driver using the
> interconnect framework.
> 
> Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
> ---
>  drivers/interconnect/Kconfig            |   1 +
>  drivers/interconnect/Makefile           |   1 +
>  drivers/interconnect/mediatek/Kconfig   |  13 ++
>  drivers/interconnect/mediatek/Makefile  |   3 +
>  drivers/interconnect/mediatek/mtk-emi.c | 242 ++++++++++++++++++++++++++++++++
>  5 files changed, 260 insertions(+)
>  create mode 100644 drivers/interconnect/mediatek/Kconfig
>  create mode 100644 drivers/interconnect/mediatek/Makefile
>  create mode 100644 drivers/interconnect/mediatek/mtk-emi.c
> 
> diff --git a/drivers/interconnect/Kconfig b/drivers/interconnect/Kconfig
> index bfa4ca3..dd9ecb6 100644
> --- a/drivers/interconnect/Kconfig
> +++ b/drivers/interconnect/Kconfig
> @@ -12,5 +12,6 @@ menuconfig INTERCONNECT
>  if INTERCONNECT
>  
>  source "drivers/interconnect/qcom/Kconfig"
> +source "drivers/interconnect/mediatek/Kconfig"
>  
>  endif
> diff --git a/drivers/interconnect/Makefile b/drivers/interconnect/Makefile
> index 725029a..330a108 100644
> --- a/drivers/interconnect/Makefile
> +++ b/drivers/interconnect/Makefile
> @@ -5,3 +5,4 @@ icc-core-objs				:= core.o
>  
>  obj-$(CONFIG_INTERCONNECT)		+= icc-core.o
>  obj-$(CONFIG_INTERCONNECT_QCOM)		+= qcom/
> +obj-$(CONFIG_INTERCONNECT_MTK)		+= mediatek/
> diff --git a/drivers/interconnect/mediatek/Kconfig b/drivers/interconnect/mediatek/Kconfig
> new file mode 100644
> index 0000000..972d3bb
> --- /dev/null
> +++ b/drivers/interconnect/mediatek/Kconfig
> @@ -0,0 +1,13 @@
> +config INTERCONNECT_MTK
> +	bool "Mediatek Network-on-Chip interconnect drivers"
> +	depends on ARCH_MEDIATEK
> +	help
> +	  Support for Mediatek's Network-on-Chip interconnect hardware.
> +
> +config INTERCONNECT_MTK_EMI
> +	tristate "Mediatek EMI interconnect driver"
> +	depends on INTERCONNECT_MTK
> +	depends on (MTK_DVFSRC && OF)
> +	help
> +	  This is a driver for the Mediatek Network-on-Chip on DVFSRC-based
> +	  platforms.
> diff --git a/drivers/interconnect/mediatek/Makefile b/drivers/interconnect/mediatek/Makefile
> new file mode 100644
> index 0000000..353842b
> --- /dev/null
> +++ b/drivers/interconnect/mediatek/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +obj-$(CONFIG_INTERCONNECT_MTK_EMI) += mtk-emi.o
> \ No newline at end of file
> diff --git a/drivers/interconnect/mediatek/mtk-emi.c b/drivers/interconnect/mediatek/mtk-emi.c
> new file mode 100644
> index 0000000..0a16992
> --- /dev/null
> +++ b/drivers/interconnect/mediatek/mtk-emi.c
> @@ -0,0 +1,242 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2019, The Linux Foundation. All rights reserved.

Nit: Maybe 2020?

> + *
> + */
> +
> +#include <dt-bindings/interconnect/mtk,mt8183-emi.h>

Please move this below the all other linux/ headers

> +#include <linux/device.h>
> +#include <linux/interconnect-provider.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/of_platform.h>

Is this needed?

> +#include <linux/platform_device.h>
> +#include <soc/mediatek/mtk_dvfsrc.h>
> +
> +enum mtk_icc_name {
> +	SLAVE_DDR_EMI,
> +	MASTER_MCUSYS,
> +	MASTER_GPUSYS,
> +	MASTER_MMSYS,
> +	MASTER_MM_VPU,
> +	MASTER_MM_DISP,
> +	MASTER_MM_VDEC,
> +	MASTER_MM_VENC,
> +	MASTER_MM_CAM,
> +	MASTER_MM_IMG,
> +	MASTER_MM_MDP,
> +};
> +
> +#define MT8183_MAX_LINKS	1
> +
> +/**
> + * struct mtk_icc_node - Mediatek specific interconnect nodes
> + * @name: the node name used in debugfs
> + * @ep: true if the node is an end point.
> + * @id: a unique node identifier
> + * @links: an array of nodes where we can go next while traversing
> + * @num_links: the total number of @links
> + * @buswidth: width of the interconnect between a node and the bus
> + * @sum_avg: current sum aggregate value of all avg bw kBps requests
> + * @max_peak: current max aggregate value of all peak bw kBps requests
> + */
> +struct mtk_icc_node {
> +	unsigned char *name;
> +	bool ep;
> +	u16 id;
> +	u16 links[MT8183_MAX_LINKS];
> +	u16 num_links;
> +	u16 buswidth;
> +	u64 sum_avg;
> +	u64 max_peak;
> +};
> +
> +struct mtk_icc_desc {
> +	struct mtk_icc_node **nodes;
> +	size_t num_nodes;
> +};
> +
> +#define DEFINE_MNODE(_name, _id, _buswidth, _ep, ...)	\
> +		static struct mtk_icc_node _name = {			\
> +		.name = #_name,						\
> +		.id = _id,						\
> +		.buswidth = _buswidth,					\
> +		.ep = _ep,						\
> +		.num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ })),	\
> +}
> +
> +DEFINE_MNODE(ddr_emi, SLAVE_DDR_EMI, 1024, 1, 0);
> +DEFINE_MNODE(mcusys, MASTER_MCUSYS, 256, 0, SLAVE_DDR_EMI);
> +DEFINE_MNODE(gpu, MASTER_GPUSYS, 256, 0, SLAVE_DDR_EMI);
> +DEFINE_MNODE(mmsys, MASTER_MMSYS, 256, 0, SLAVE_DDR_EMI);
> +DEFINE_MNODE(mm_vpu, MASTER_MM_VPU, 128, 0, MASTER_MMSYS);
> +DEFINE_MNODE(mm_disp, MASTER_MM_DISP, 128, 0, MASTER_MMSYS);
> +DEFINE_MNODE(mm_vdec, MASTER_MM_VDEC, 128, 0, MASTER_MMSYS);
> +DEFINE_MNODE(mm_venc, MASTER_MM_VENC, 128, 0, MASTER_MMSYS);
> +DEFINE_MNODE(mm_cam, MASTER_MM_CAM, 128, 0, MASTER_MMSYS);
> +DEFINE_MNODE(mm_img, MASTER_MM_IMG, 128, 0, MASTER_MMSYS);
> +DEFINE_MNODE(mm_mdp, MASTER_MM_MDP, 128, 0, MASTER_MMSYS);
> +
> +static struct mtk_icc_node *mt8183_icc_nodes[] = {
> +	[MT8183_SLAVE_DDR_EMI] = &ddr_emi,
> +	[MT8183_MASTER_MCUSYS] = &mcusys,
> +	[MT8183_MASTER_GPU] = &gpu,
> +	[MT8183_MASTER_MMSYS] = &mmsys,
> +	[MT8183_MASTER_MM_VPU] = &mm_vpu,
> +	[MT8183_MASTER_MM_DISP] = &mm_disp,
> +	[MT8183_MASTER_MM_VDEC] = &mm_vdec,
> +	[MT8183_MASTER_MM_VENC] = &mm_venc,
> +	[MT8183_MASTER_MM_CAM] = &mm_cam,
> +	[MT8183_MASTER_MM_IMG] = &mm_img,
> +	[MT8183_MASTER_MM_MDP] = &mm_mdp,
> +};
> +
> +static struct mtk_icc_desc mt8183_icc = {

const?

> +	.nodes = mt8183_icc_nodes,
> +	.num_nodes = ARRAY_SIZE(mt8183_icc_nodes),
> +};
> +
> +static int emi_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
> +			     u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
> +{
> +	struct mtk_icc_node *in;
> +
> +	in = node->data;
> +
> +	*agg_avg += avg_bw;
> +	*agg_peak += peak_bw;
> +
> +	in->sum_avg = *agg_avg;
> +	in->max_peak = *agg_peak;
> +
> +	return 0;
> +}
> +
> +static int emi_icc_set(struct icc_node *src, struct icc_node *dst)
> +{
> +	int ret = 0;
> +	struct mtk_icc_node *node;
> +
> +	node = dst->data;
> +	if (node->ep) {
> +		pr_debug("sum_avg (%llu), max_peak (%llu)\n",
> +			 node->sum_avg, node->max_peak);
> +		mtk_dvfsrc_send_request(src->provider->dev->parent,
> +					MTK_DVFSRC_CMD_BW_REQUEST,
> +					node->max_peak);
> +	}
> +
> +	return ret;
> +}
> +
> +static int emi_icc_remove(struct platform_device *pdev);
> +static int emi_icc_probe(struct platform_device *pdev)
> +{
> +	int ret;
> +	const struct mtk_icc_desc *desc;
> +	struct icc_node *node;
> +	struct icc_onecell_data *data;
> +	struct icc_provider *provider;
> +	struct mtk_icc_node **mnodes;
> +	size_t num_nodes, i, j;
> +
> +	desc = of_device_get_match_data(&pdev->dev);
> +	if (!desc)
> +		return -EINVAL;
> +
> +	mnodes = desc->nodes;
> +	num_nodes = desc->num_nodes;
> +
> +	provider = devm_kzalloc(&pdev->dev, sizeof(*provider), GFP_KERNEL);
> +	if (!provider)
> +		return -ENOMEM;
> +
> +	data = devm_kcalloc(&pdev->dev, num_nodes, sizeof(*node), GFP_KERNEL);

This should be:
devm_kzalloc(&pdev->dev, struct_size(data, nodes, num_nodes), GFP_KERNEL);

> +	if (!data)
> +		return -ENOMEM;
> +
> +	provider->dev = &pdev->dev;
> +	provider->set = emi_icc_set;
> +	provider->aggregate = emi_icc_aggregate;
> +	provider->xlate = of_icc_xlate_onecell;
> +	INIT_LIST_HEAD(&provider->nodes);
> +	provider->data = data;
> +
> +	ret = icc_provider_add(provider);
> +	if (ret) {
> +		dev_err(&pdev->dev, "error adding interconnect provider\n");
> +		return ret;
> +	}
> +
> +	for (i = 0; i < num_nodes; i++) {
> +		node = icc_node_create(mnodes[i]->id);
> +		if (IS_ERR(node)) {
> +			ret = PTR_ERR(node);
> +			goto err;
> +		}
> +
> +		node->name = mnodes[i]->name;
> +		node->data = mnodes[i];
> +		icc_node_add(node, provider);
> +
> +		dev_dbg(&pdev->dev, "registered node %s, num link: %d\n",
> +			mnodes[i]->name, mnodes[i]->num_links);

Please remove this.

> +
> +		/* populate links */

Please remove the comment too.

> +		for (j = 0; j < mnodes[i]->num_links; j++)
> +			icc_link_create(node, mnodes[i]->links[j]);
> +
> +		data->nodes[i] = node;
> +	}
> +	data->num_nodes = num_nodes;
> +
> +	platform_set_drvdata(pdev, provider);
> +
> +	return 0;
> +err:
> +	emi_icc_remove(pdev);

This will not work because platform_set_drvdata() is called only when the
probe function completes successfully. So platform_get_drvdata() in
emi_icc_remove() will return NULL.

> +	return ret;
> +}
> +
> +static int emi_icc_remove(struct platform_device *pdev)
> +{
> +	struct icc_provider *provider = platform_get_drvdata(pdev);
> +	struct icc_node *n;
> +
> +	list_for_each_entry(n, &provider->nodes, node_list) {
> +		icc_node_del(n);
> +		icc_node_destroy(n->id);
> +	}

You can use icc_nodes_remove() instead of the above.

Thanks,
Georgi

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

* Re: [PATCH V4 09/13] interconnect: mediatek: Add mt8183 interconnect provider driver
@ 2020-04-01 14:55     ` Georgi Djakov
  0 siblings, 0 replies; 66+ messages in thread
From: Georgi Djakov @ 2020-04-01 14:55 UTC (permalink / raw)
  To: Henry Chen
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, Viresh Kumar, linux-pm, linux-kernel, Rob Herring,
	Stephen Boyd, Fan Chen, devicetree, Mark Brown, Ryan Case,
	Arvin Wang, Matthias Brugger, linux-mediatek, linux-arm-kernel

Hi Henry,

Thanks for the patch!

On 3/13/20 11:34, Henry Chen wrote:
> Introduce Mediatek MT8183 specific provider driver using the
> interconnect framework.
> 
> Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
> ---
>  drivers/interconnect/Kconfig            |   1 +
>  drivers/interconnect/Makefile           |   1 +
>  drivers/interconnect/mediatek/Kconfig   |  13 ++
>  drivers/interconnect/mediatek/Makefile  |   3 +
>  drivers/interconnect/mediatek/mtk-emi.c | 242 ++++++++++++++++++++++++++++++++
>  5 files changed, 260 insertions(+)
>  create mode 100644 drivers/interconnect/mediatek/Kconfig
>  create mode 100644 drivers/interconnect/mediatek/Makefile
>  create mode 100644 drivers/interconnect/mediatek/mtk-emi.c
> 
> diff --git a/drivers/interconnect/Kconfig b/drivers/interconnect/Kconfig
> index bfa4ca3..dd9ecb6 100644
> --- a/drivers/interconnect/Kconfig
> +++ b/drivers/interconnect/Kconfig
> @@ -12,5 +12,6 @@ menuconfig INTERCONNECT
>  if INTERCONNECT
>  
>  source "drivers/interconnect/qcom/Kconfig"
> +source "drivers/interconnect/mediatek/Kconfig"
>  
>  endif
> diff --git a/drivers/interconnect/Makefile b/drivers/interconnect/Makefile
> index 725029a..330a108 100644
> --- a/drivers/interconnect/Makefile
> +++ b/drivers/interconnect/Makefile
> @@ -5,3 +5,4 @@ icc-core-objs				:= core.o
>  
>  obj-$(CONFIG_INTERCONNECT)		+= icc-core.o
>  obj-$(CONFIG_INTERCONNECT_QCOM)		+= qcom/
> +obj-$(CONFIG_INTERCONNECT_MTK)		+= mediatek/
> diff --git a/drivers/interconnect/mediatek/Kconfig b/drivers/interconnect/mediatek/Kconfig
> new file mode 100644
> index 0000000..972d3bb
> --- /dev/null
> +++ b/drivers/interconnect/mediatek/Kconfig
> @@ -0,0 +1,13 @@
> +config INTERCONNECT_MTK
> +	bool "Mediatek Network-on-Chip interconnect drivers"
> +	depends on ARCH_MEDIATEK
> +	help
> +	  Support for Mediatek's Network-on-Chip interconnect hardware.
> +
> +config INTERCONNECT_MTK_EMI
> +	tristate "Mediatek EMI interconnect driver"
> +	depends on INTERCONNECT_MTK
> +	depends on (MTK_DVFSRC && OF)
> +	help
> +	  This is a driver for the Mediatek Network-on-Chip on DVFSRC-based
> +	  platforms.
> diff --git a/drivers/interconnect/mediatek/Makefile b/drivers/interconnect/mediatek/Makefile
> new file mode 100644
> index 0000000..353842b
> --- /dev/null
> +++ b/drivers/interconnect/mediatek/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +obj-$(CONFIG_INTERCONNECT_MTK_EMI) += mtk-emi.o
> \ No newline at end of file
> diff --git a/drivers/interconnect/mediatek/mtk-emi.c b/drivers/interconnect/mediatek/mtk-emi.c
> new file mode 100644
> index 0000000..0a16992
> --- /dev/null
> +++ b/drivers/interconnect/mediatek/mtk-emi.c
> @@ -0,0 +1,242 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2019, The Linux Foundation. All rights reserved.

Nit: Maybe 2020?

> + *
> + */
> +
> +#include <dt-bindings/interconnect/mtk,mt8183-emi.h>

Please move this below the all other linux/ headers

> +#include <linux/device.h>
> +#include <linux/interconnect-provider.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/of_platform.h>

Is this needed?

> +#include <linux/platform_device.h>
> +#include <soc/mediatek/mtk_dvfsrc.h>
> +
> +enum mtk_icc_name {
> +	SLAVE_DDR_EMI,
> +	MASTER_MCUSYS,
> +	MASTER_GPUSYS,
> +	MASTER_MMSYS,
> +	MASTER_MM_VPU,
> +	MASTER_MM_DISP,
> +	MASTER_MM_VDEC,
> +	MASTER_MM_VENC,
> +	MASTER_MM_CAM,
> +	MASTER_MM_IMG,
> +	MASTER_MM_MDP,
> +};
> +
> +#define MT8183_MAX_LINKS	1
> +
> +/**
> + * struct mtk_icc_node - Mediatek specific interconnect nodes
> + * @name: the node name used in debugfs
> + * @ep: true if the node is an end point.
> + * @id: a unique node identifier
> + * @links: an array of nodes where we can go next while traversing
> + * @num_links: the total number of @links
> + * @buswidth: width of the interconnect between a node and the bus
> + * @sum_avg: current sum aggregate value of all avg bw kBps requests
> + * @max_peak: current max aggregate value of all peak bw kBps requests
> + */
> +struct mtk_icc_node {
> +	unsigned char *name;
> +	bool ep;
> +	u16 id;
> +	u16 links[MT8183_MAX_LINKS];
> +	u16 num_links;
> +	u16 buswidth;
> +	u64 sum_avg;
> +	u64 max_peak;
> +};
> +
> +struct mtk_icc_desc {
> +	struct mtk_icc_node **nodes;
> +	size_t num_nodes;
> +};
> +
> +#define DEFINE_MNODE(_name, _id, _buswidth, _ep, ...)	\
> +		static struct mtk_icc_node _name = {			\
> +		.name = #_name,						\
> +		.id = _id,						\
> +		.buswidth = _buswidth,					\
> +		.ep = _ep,						\
> +		.num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ })),	\
> +}
> +
> +DEFINE_MNODE(ddr_emi, SLAVE_DDR_EMI, 1024, 1, 0);
> +DEFINE_MNODE(mcusys, MASTER_MCUSYS, 256, 0, SLAVE_DDR_EMI);
> +DEFINE_MNODE(gpu, MASTER_GPUSYS, 256, 0, SLAVE_DDR_EMI);
> +DEFINE_MNODE(mmsys, MASTER_MMSYS, 256, 0, SLAVE_DDR_EMI);
> +DEFINE_MNODE(mm_vpu, MASTER_MM_VPU, 128, 0, MASTER_MMSYS);
> +DEFINE_MNODE(mm_disp, MASTER_MM_DISP, 128, 0, MASTER_MMSYS);
> +DEFINE_MNODE(mm_vdec, MASTER_MM_VDEC, 128, 0, MASTER_MMSYS);
> +DEFINE_MNODE(mm_venc, MASTER_MM_VENC, 128, 0, MASTER_MMSYS);
> +DEFINE_MNODE(mm_cam, MASTER_MM_CAM, 128, 0, MASTER_MMSYS);
> +DEFINE_MNODE(mm_img, MASTER_MM_IMG, 128, 0, MASTER_MMSYS);
> +DEFINE_MNODE(mm_mdp, MASTER_MM_MDP, 128, 0, MASTER_MMSYS);
> +
> +static struct mtk_icc_node *mt8183_icc_nodes[] = {
> +	[MT8183_SLAVE_DDR_EMI] = &ddr_emi,
> +	[MT8183_MASTER_MCUSYS] = &mcusys,
> +	[MT8183_MASTER_GPU] = &gpu,
> +	[MT8183_MASTER_MMSYS] = &mmsys,
> +	[MT8183_MASTER_MM_VPU] = &mm_vpu,
> +	[MT8183_MASTER_MM_DISP] = &mm_disp,
> +	[MT8183_MASTER_MM_VDEC] = &mm_vdec,
> +	[MT8183_MASTER_MM_VENC] = &mm_venc,
> +	[MT8183_MASTER_MM_CAM] = &mm_cam,
> +	[MT8183_MASTER_MM_IMG] = &mm_img,
> +	[MT8183_MASTER_MM_MDP] = &mm_mdp,
> +};
> +
> +static struct mtk_icc_desc mt8183_icc = {

const?

> +	.nodes = mt8183_icc_nodes,
> +	.num_nodes = ARRAY_SIZE(mt8183_icc_nodes),
> +};
> +
> +static int emi_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
> +			     u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
> +{
> +	struct mtk_icc_node *in;
> +
> +	in = node->data;
> +
> +	*agg_avg += avg_bw;
> +	*agg_peak += peak_bw;
> +
> +	in->sum_avg = *agg_avg;
> +	in->max_peak = *agg_peak;
> +
> +	return 0;
> +}
> +
> +static int emi_icc_set(struct icc_node *src, struct icc_node *dst)
> +{
> +	int ret = 0;
> +	struct mtk_icc_node *node;
> +
> +	node = dst->data;
> +	if (node->ep) {
> +		pr_debug("sum_avg (%llu), max_peak (%llu)\n",
> +			 node->sum_avg, node->max_peak);
> +		mtk_dvfsrc_send_request(src->provider->dev->parent,
> +					MTK_DVFSRC_CMD_BW_REQUEST,
> +					node->max_peak);
> +	}
> +
> +	return ret;
> +}
> +
> +static int emi_icc_remove(struct platform_device *pdev);
> +static int emi_icc_probe(struct platform_device *pdev)
> +{
> +	int ret;
> +	const struct mtk_icc_desc *desc;
> +	struct icc_node *node;
> +	struct icc_onecell_data *data;
> +	struct icc_provider *provider;
> +	struct mtk_icc_node **mnodes;
> +	size_t num_nodes, i, j;
> +
> +	desc = of_device_get_match_data(&pdev->dev);
> +	if (!desc)
> +		return -EINVAL;
> +
> +	mnodes = desc->nodes;
> +	num_nodes = desc->num_nodes;
> +
> +	provider = devm_kzalloc(&pdev->dev, sizeof(*provider), GFP_KERNEL);
> +	if (!provider)
> +		return -ENOMEM;
> +
> +	data = devm_kcalloc(&pdev->dev, num_nodes, sizeof(*node), GFP_KERNEL);

This should be:
devm_kzalloc(&pdev->dev, struct_size(data, nodes, num_nodes), GFP_KERNEL);

> +	if (!data)
> +		return -ENOMEM;
> +
> +	provider->dev = &pdev->dev;
> +	provider->set = emi_icc_set;
> +	provider->aggregate = emi_icc_aggregate;
> +	provider->xlate = of_icc_xlate_onecell;
> +	INIT_LIST_HEAD(&provider->nodes);
> +	provider->data = data;
> +
> +	ret = icc_provider_add(provider);
> +	if (ret) {
> +		dev_err(&pdev->dev, "error adding interconnect provider\n");
> +		return ret;
> +	}
> +
> +	for (i = 0; i < num_nodes; i++) {
> +		node = icc_node_create(mnodes[i]->id);
> +		if (IS_ERR(node)) {
> +			ret = PTR_ERR(node);
> +			goto err;
> +		}
> +
> +		node->name = mnodes[i]->name;
> +		node->data = mnodes[i];
> +		icc_node_add(node, provider);
> +
> +		dev_dbg(&pdev->dev, "registered node %s, num link: %d\n",
> +			mnodes[i]->name, mnodes[i]->num_links);

Please remove this.

> +
> +		/* populate links */

Please remove the comment too.

> +		for (j = 0; j < mnodes[i]->num_links; j++)
> +			icc_link_create(node, mnodes[i]->links[j]);
> +
> +		data->nodes[i] = node;
> +	}
> +	data->num_nodes = num_nodes;
> +
> +	platform_set_drvdata(pdev, provider);
> +
> +	return 0;
> +err:
> +	emi_icc_remove(pdev);

This will not work because platform_set_drvdata() is called only when the
probe function completes successfully. So platform_get_drvdata() in
emi_icc_remove() will return NULL.

> +	return ret;
> +}
> +
> +static int emi_icc_remove(struct platform_device *pdev)
> +{
> +	struct icc_provider *provider = platform_get_drvdata(pdev);
> +	struct icc_node *n;
> +
> +	list_for_each_entry(n, &provider->nodes, node_list) {
> +		icc_node_del(n);
> +		icc_node_destroy(n->id);
> +	}

You can use icc_nodes_remove() instead of the above.

Thanks,
Georgi

_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

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

* Re: [PATCH V4 09/13] interconnect: mediatek: Add mt8183 interconnect provider driver
@ 2020-04-01 14:55     ` Georgi Djakov
  0 siblings, 0 replies; 66+ messages in thread
From: Georgi Djakov @ 2020-04-01 14:55 UTC (permalink / raw)
  To: Henry Chen
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, Viresh Kumar, linux-pm, linux-kernel, Rob Herring,
	Stephen Boyd, Fan Chen, devicetree, Mark Brown, Ryan Case,
	Arvin Wang, Matthias Brugger, linux-mediatek, linux-arm-kernel

Hi Henry,

Thanks for the patch!

On 3/13/20 11:34, Henry Chen wrote:
> Introduce Mediatek MT8183 specific provider driver using the
> interconnect framework.
> 
> Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
> ---
>  drivers/interconnect/Kconfig            |   1 +
>  drivers/interconnect/Makefile           |   1 +
>  drivers/interconnect/mediatek/Kconfig   |  13 ++
>  drivers/interconnect/mediatek/Makefile  |   3 +
>  drivers/interconnect/mediatek/mtk-emi.c | 242 ++++++++++++++++++++++++++++++++
>  5 files changed, 260 insertions(+)
>  create mode 100644 drivers/interconnect/mediatek/Kconfig
>  create mode 100644 drivers/interconnect/mediatek/Makefile
>  create mode 100644 drivers/interconnect/mediatek/mtk-emi.c
> 
> diff --git a/drivers/interconnect/Kconfig b/drivers/interconnect/Kconfig
> index bfa4ca3..dd9ecb6 100644
> --- a/drivers/interconnect/Kconfig
> +++ b/drivers/interconnect/Kconfig
> @@ -12,5 +12,6 @@ menuconfig INTERCONNECT
>  if INTERCONNECT
>  
>  source "drivers/interconnect/qcom/Kconfig"
> +source "drivers/interconnect/mediatek/Kconfig"
>  
>  endif
> diff --git a/drivers/interconnect/Makefile b/drivers/interconnect/Makefile
> index 725029a..330a108 100644
> --- a/drivers/interconnect/Makefile
> +++ b/drivers/interconnect/Makefile
> @@ -5,3 +5,4 @@ icc-core-objs				:= core.o
>  
>  obj-$(CONFIG_INTERCONNECT)		+= icc-core.o
>  obj-$(CONFIG_INTERCONNECT_QCOM)		+= qcom/
> +obj-$(CONFIG_INTERCONNECT_MTK)		+= mediatek/
> diff --git a/drivers/interconnect/mediatek/Kconfig b/drivers/interconnect/mediatek/Kconfig
> new file mode 100644
> index 0000000..972d3bb
> --- /dev/null
> +++ b/drivers/interconnect/mediatek/Kconfig
> @@ -0,0 +1,13 @@
> +config INTERCONNECT_MTK
> +	bool "Mediatek Network-on-Chip interconnect drivers"
> +	depends on ARCH_MEDIATEK
> +	help
> +	  Support for Mediatek's Network-on-Chip interconnect hardware.
> +
> +config INTERCONNECT_MTK_EMI
> +	tristate "Mediatek EMI interconnect driver"
> +	depends on INTERCONNECT_MTK
> +	depends on (MTK_DVFSRC && OF)
> +	help
> +	  This is a driver for the Mediatek Network-on-Chip on DVFSRC-based
> +	  platforms.
> diff --git a/drivers/interconnect/mediatek/Makefile b/drivers/interconnect/mediatek/Makefile
> new file mode 100644
> index 0000000..353842b
> --- /dev/null
> +++ b/drivers/interconnect/mediatek/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +obj-$(CONFIG_INTERCONNECT_MTK_EMI) += mtk-emi.o
> \ No newline at end of file
> diff --git a/drivers/interconnect/mediatek/mtk-emi.c b/drivers/interconnect/mediatek/mtk-emi.c
> new file mode 100644
> index 0000000..0a16992
> --- /dev/null
> +++ b/drivers/interconnect/mediatek/mtk-emi.c
> @@ -0,0 +1,242 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2019, The Linux Foundation. All rights reserved.

Nit: Maybe 2020?

> + *
> + */
> +
> +#include <dt-bindings/interconnect/mtk,mt8183-emi.h>

Please move this below the all other linux/ headers

> +#include <linux/device.h>
> +#include <linux/interconnect-provider.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/of_platform.h>

Is this needed?

> +#include <linux/platform_device.h>
> +#include <soc/mediatek/mtk_dvfsrc.h>
> +
> +enum mtk_icc_name {
> +	SLAVE_DDR_EMI,
> +	MASTER_MCUSYS,
> +	MASTER_GPUSYS,
> +	MASTER_MMSYS,
> +	MASTER_MM_VPU,
> +	MASTER_MM_DISP,
> +	MASTER_MM_VDEC,
> +	MASTER_MM_VENC,
> +	MASTER_MM_CAM,
> +	MASTER_MM_IMG,
> +	MASTER_MM_MDP,
> +};
> +
> +#define MT8183_MAX_LINKS	1
> +
> +/**
> + * struct mtk_icc_node - Mediatek specific interconnect nodes
> + * @name: the node name used in debugfs
> + * @ep: true if the node is an end point.
> + * @id: a unique node identifier
> + * @links: an array of nodes where we can go next while traversing
> + * @num_links: the total number of @links
> + * @buswidth: width of the interconnect between a node and the bus
> + * @sum_avg: current sum aggregate value of all avg bw kBps requests
> + * @max_peak: current max aggregate value of all peak bw kBps requests
> + */
> +struct mtk_icc_node {
> +	unsigned char *name;
> +	bool ep;
> +	u16 id;
> +	u16 links[MT8183_MAX_LINKS];
> +	u16 num_links;
> +	u16 buswidth;
> +	u64 sum_avg;
> +	u64 max_peak;
> +};
> +
> +struct mtk_icc_desc {
> +	struct mtk_icc_node **nodes;
> +	size_t num_nodes;
> +};
> +
> +#define DEFINE_MNODE(_name, _id, _buswidth, _ep, ...)	\
> +		static struct mtk_icc_node _name = {			\
> +		.name = #_name,						\
> +		.id = _id,						\
> +		.buswidth = _buswidth,					\
> +		.ep = _ep,						\
> +		.num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ })),	\
> +}
> +
> +DEFINE_MNODE(ddr_emi, SLAVE_DDR_EMI, 1024, 1, 0);
> +DEFINE_MNODE(mcusys, MASTER_MCUSYS, 256, 0, SLAVE_DDR_EMI);
> +DEFINE_MNODE(gpu, MASTER_GPUSYS, 256, 0, SLAVE_DDR_EMI);
> +DEFINE_MNODE(mmsys, MASTER_MMSYS, 256, 0, SLAVE_DDR_EMI);
> +DEFINE_MNODE(mm_vpu, MASTER_MM_VPU, 128, 0, MASTER_MMSYS);
> +DEFINE_MNODE(mm_disp, MASTER_MM_DISP, 128, 0, MASTER_MMSYS);
> +DEFINE_MNODE(mm_vdec, MASTER_MM_VDEC, 128, 0, MASTER_MMSYS);
> +DEFINE_MNODE(mm_venc, MASTER_MM_VENC, 128, 0, MASTER_MMSYS);
> +DEFINE_MNODE(mm_cam, MASTER_MM_CAM, 128, 0, MASTER_MMSYS);
> +DEFINE_MNODE(mm_img, MASTER_MM_IMG, 128, 0, MASTER_MMSYS);
> +DEFINE_MNODE(mm_mdp, MASTER_MM_MDP, 128, 0, MASTER_MMSYS);
> +
> +static struct mtk_icc_node *mt8183_icc_nodes[] = {
> +	[MT8183_SLAVE_DDR_EMI] = &ddr_emi,
> +	[MT8183_MASTER_MCUSYS] = &mcusys,
> +	[MT8183_MASTER_GPU] = &gpu,
> +	[MT8183_MASTER_MMSYS] = &mmsys,
> +	[MT8183_MASTER_MM_VPU] = &mm_vpu,
> +	[MT8183_MASTER_MM_DISP] = &mm_disp,
> +	[MT8183_MASTER_MM_VDEC] = &mm_vdec,
> +	[MT8183_MASTER_MM_VENC] = &mm_venc,
> +	[MT8183_MASTER_MM_CAM] = &mm_cam,
> +	[MT8183_MASTER_MM_IMG] = &mm_img,
> +	[MT8183_MASTER_MM_MDP] = &mm_mdp,
> +};
> +
> +static struct mtk_icc_desc mt8183_icc = {

const?

> +	.nodes = mt8183_icc_nodes,
> +	.num_nodes = ARRAY_SIZE(mt8183_icc_nodes),
> +};
> +
> +static int emi_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
> +			     u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
> +{
> +	struct mtk_icc_node *in;
> +
> +	in = node->data;
> +
> +	*agg_avg += avg_bw;
> +	*agg_peak += peak_bw;
> +
> +	in->sum_avg = *agg_avg;
> +	in->max_peak = *agg_peak;
> +
> +	return 0;
> +}
> +
> +static int emi_icc_set(struct icc_node *src, struct icc_node *dst)
> +{
> +	int ret = 0;
> +	struct mtk_icc_node *node;
> +
> +	node = dst->data;
> +	if (node->ep) {
> +		pr_debug("sum_avg (%llu), max_peak (%llu)\n",
> +			 node->sum_avg, node->max_peak);
> +		mtk_dvfsrc_send_request(src->provider->dev->parent,
> +					MTK_DVFSRC_CMD_BW_REQUEST,
> +					node->max_peak);
> +	}
> +
> +	return ret;
> +}
> +
> +static int emi_icc_remove(struct platform_device *pdev);
> +static int emi_icc_probe(struct platform_device *pdev)
> +{
> +	int ret;
> +	const struct mtk_icc_desc *desc;
> +	struct icc_node *node;
> +	struct icc_onecell_data *data;
> +	struct icc_provider *provider;
> +	struct mtk_icc_node **mnodes;
> +	size_t num_nodes, i, j;
> +
> +	desc = of_device_get_match_data(&pdev->dev);
> +	if (!desc)
> +		return -EINVAL;
> +
> +	mnodes = desc->nodes;
> +	num_nodes = desc->num_nodes;
> +
> +	provider = devm_kzalloc(&pdev->dev, sizeof(*provider), GFP_KERNEL);
> +	if (!provider)
> +		return -ENOMEM;
> +
> +	data = devm_kcalloc(&pdev->dev, num_nodes, sizeof(*node), GFP_KERNEL);

This should be:
devm_kzalloc(&pdev->dev, struct_size(data, nodes, num_nodes), GFP_KERNEL);

> +	if (!data)
> +		return -ENOMEM;
> +
> +	provider->dev = &pdev->dev;
> +	provider->set = emi_icc_set;
> +	provider->aggregate = emi_icc_aggregate;
> +	provider->xlate = of_icc_xlate_onecell;
> +	INIT_LIST_HEAD(&provider->nodes);
> +	provider->data = data;
> +
> +	ret = icc_provider_add(provider);
> +	if (ret) {
> +		dev_err(&pdev->dev, "error adding interconnect provider\n");
> +		return ret;
> +	}
> +
> +	for (i = 0; i < num_nodes; i++) {
> +		node = icc_node_create(mnodes[i]->id);
> +		if (IS_ERR(node)) {
> +			ret = PTR_ERR(node);
> +			goto err;
> +		}
> +
> +		node->name = mnodes[i]->name;
> +		node->data = mnodes[i];
> +		icc_node_add(node, provider);
> +
> +		dev_dbg(&pdev->dev, "registered node %s, num link: %d\n",
> +			mnodes[i]->name, mnodes[i]->num_links);

Please remove this.

> +
> +		/* populate links */

Please remove the comment too.

> +		for (j = 0; j < mnodes[i]->num_links; j++)
> +			icc_link_create(node, mnodes[i]->links[j]);
> +
> +		data->nodes[i] = node;
> +	}
> +	data->num_nodes = num_nodes;
> +
> +	platform_set_drvdata(pdev, provider);
> +
> +	return 0;
> +err:
> +	emi_icc_remove(pdev);

This will not work because platform_set_drvdata() is called only when the
probe function completes successfully. So platform_get_drvdata() in
emi_icc_remove() will return NULL.

> +	return ret;
> +}
> +
> +static int emi_icc_remove(struct platform_device *pdev)
> +{
> +	struct icc_provider *provider = platform_get_drvdata(pdev);
> +	struct icc_node *n;
> +
> +	list_for_each_entry(n, &provider->nodes, node_list) {
> +		icc_node_del(n);
> +		icc_node_destroy(n->id);
> +	}

You can use icc_nodes_remove() instead of the above.

Thanks,
Georgi

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH V4 00/13] Add driver for dvfsrc, support for active state of scpsys
  2020-03-13  9:34 ` Henry Chen
  (?)
@ 2020-04-01 15:09   ` Georgi Djakov
  -1 siblings, 0 replies; 66+ messages in thread
From: Georgi Djakov @ 2020-04-01 15:09 UTC (permalink / raw)
  To: Henry Chen
  Cc: Rob Herring, Matthias Brugger, Viresh Kumar, Stephen Boyd,
	Ryan Case, Mark Brown, Mark Rutland, Nicolas Boichat, Fan Chen,
	James Liao, Arvin Wang, Mike Turquette, devicetree,
	linux-arm-kernel, linux-mediatek, linux-kernel, linux-pm,
	srv_heupstream

Hi Henry,

On 3/13/20 11:34, Henry Chen wrote:
> The patchsets add support for MediaTek hardware module named DVFSRC
> (dynamic voltage and frequency scaling resource collector). The DVFSRC is
> a HW module which is used to collect all the requests from both software
> and hardware and turn into the decision of minimum operating voltage and
> minimum DRAM frequency to fulfill those requests.
> 
> So, This series is to implement the dvfsrc driver to collect all the
> requests of operating voltage or DRAM bandwidth from other device drivers
> likes GPU/Camera through 3 frameworks basically:
> 
> 1. interconnect framework: to aggregate the bandwidth
>    requirements from different clients
> 
> [1] https://patchwork.kernel.org/cover/10766329/
> 
> Below is the emi bandwidth map of mt8183. There has a hw module "DRAM scheduler"
> which used to control the throughput. The DVFSRC will collect forecast data
> of dram bandwidth from SW consumers(camera/gpu...), and according the forecast
> to change the DRAM frequency
> 
>            ICC provider         ICC Nodes
>                             ----          ----
>            ---------       |CPU |   |--->|VPU |
>   -----   |         |-----> ----    |     ----
>  |DRAM |--|DRAM     |       ----    |     ----
>  |     |--|scheduler|----->|GPU |   |--->|DISP|
>  |     |--|(EMI)    |       ----    |     ----
>  |     |--|         |       -----   |     ----
>   -----   |         |----->|MMSYS|--|--->|VDEC|
>            ---------        -----   |     ----
>              /|\                    |     ----
>               |change DRAM freq     |--->|VENC|
>            ----------               |     ----
>           |  DVFSR   |              |
>           |          |              |     ----
>            ----------               |--->|IMG |
>                                     |     ----
>                                     |     ----
>                                     |--->|CAM |
>                                           ----

It would be useful to also add the above diagram into the commit text of
patch 09/13. By doing so, it will be saved into the history, as cover letters
are discarded.

Thanks,
Georgi

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

* Re: [PATCH V4 00/13] Add driver for dvfsrc, support for active state of scpsys
@ 2020-04-01 15:09   ` Georgi Djakov
  0 siblings, 0 replies; 66+ messages in thread
From: Georgi Djakov @ 2020-04-01 15:09 UTC (permalink / raw)
  To: Henry Chen
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, Viresh Kumar, linux-pm, linux-kernel, Rob Herring,
	Stephen Boyd, Fan Chen, devicetree, Mark Brown, Ryan Case,
	Arvin Wang, Matthias Brugger, linux-mediatek, linux-arm-kernel

Hi Henry,

On 3/13/20 11:34, Henry Chen wrote:
> The patchsets add support for MediaTek hardware module named DVFSRC
> (dynamic voltage and frequency scaling resource collector). The DVFSRC is
> a HW module which is used to collect all the requests from both software
> and hardware and turn into the decision of minimum operating voltage and
> minimum DRAM frequency to fulfill those requests.
> 
> So, This series is to implement the dvfsrc driver to collect all the
> requests of operating voltage or DRAM bandwidth from other device drivers
> likes GPU/Camera through 3 frameworks basically:
> 
> 1. interconnect framework: to aggregate the bandwidth
>    requirements from different clients
> 
> [1] https://patchwork.kernel.org/cover/10766329/
> 
> Below is the emi bandwidth map of mt8183. There has a hw module "DRAM scheduler"
> which used to control the throughput. The DVFSRC will collect forecast data
> of dram bandwidth from SW consumers(camera/gpu...), and according the forecast
> to change the DRAM frequency
> 
>            ICC provider         ICC Nodes
>                             ----          ----
>            ---------       |CPU |   |--->|VPU |
>   -----   |         |-----> ----    |     ----
>  |DRAM |--|DRAM     |       ----    |     ----
>  |     |--|scheduler|----->|GPU |   |--->|DISP|
>  |     |--|(EMI)    |       ----    |     ----
>  |     |--|         |       -----   |     ----
>   -----   |         |----->|MMSYS|--|--->|VDEC|
>            ---------        -----   |     ----
>              /|\                    |     ----
>               |change DRAM freq     |--->|VENC|
>            ----------               |     ----
>           |  DVFSR   |              |
>           |          |              |     ----
>            ----------               |--->|IMG |
>                                     |     ----
>                                     |     ----
>                                     |--->|CAM |
>                                           ----

It would be useful to also add the above diagram into the commit text of
patch 09/13. By doing so, it will be saved into the history, as cover letters
are discarded.

Thanks,
Georgi

_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

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

* Re: [PATCH V4 00/13] Add driver for dvfsrc, support for active state of scpsys
@ 2020-04-01 15:09   ` Georgi Djakov
  0 siblings, 0 replies; 66+ messages in thread
From: Georgi Djakov @ 2020-04-01 15:09 UTC (permalink / raw)
  To: Henry Chen
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, Viresh Kumar, linux-pm, linux-kernel, Rob Herring,
	Stephen Boyd, Fan Chen, devicetree, Mark Brown, Ryan Case,
	Arvin Wang, Matthias Brugger, linux-mediatek, linux-arm-kernel

Hi Henry,

On 3/13/20 11:34, Henry Chen wrote:
> The patchsets add support for MediaTek hardware module named DVFSRC
> (dynamic voltage and frequency scaling resource collector). The DVFSRC is
> a HW module which is used to collect all the requests from both software
> and hardware and turn into the decision of minimum operating voltage and
> minimum DRAM frequency to fulfill those requests.
> 
> So, This series is to implement the dvfsrc driver to collect all the
> requests of operating voltage or DRAM bandwidth from other device drivers
> likes GPU/Camera through 3 frameworks basically:
> 
> 1. interconnect framework: to aggregate the bandwidth
>    requirements from different clients
> 
> [1] https://patchwork.kernel.org/cover/10766329/
> 
> Below is the emi bandwidth map of mt8183. There has a hw module "DRAM scheduler"
> which used to control the throughput. The DVFSRC will collect forecast data
> of dram bandwidth from SW consumers(camera/gpu...), and according the forecast
> to change the DRAM frequency
> 
>            ICC provider         ICC Nodes
>                             ----          ----
>            ---------       |CPU |   |--->|VPU |
>   -----   |         |-----> ----    |     ----
>  |DRAM |--|DRAM     |       ----    |     ----
>  |     |--|scheduler|----->|GPU |   |--->|DISP|
>  |     |--|(EMI)    |       ----    |     ----
>  |     |--|         |       -----   |     ----
>   -----   |         |----->|MMSYS|--|--->|VDEC|
>            ---------        -----   |     ----
>              /|\                    |     ----
>               |change DRAM freq     |--->|VENC|
>            ----------               |     ----
>           |  DVFSR   |              |
>           |          |              |     ----
>            ----------               |--->|IMG |
>                                     |     ----
>                                     |     ----
>                                     |--->|CAM |
>                                           ----

It would be useful to also add the above diagram into the commit text of
patch 09/13. By doing so, it will be saved into the history, as cover letters
are discarded.

Thanks,
Georgi

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH V4 00/13] Add driver for dvfsrc, support for active state of scpsys
  2020-04-01 15:09   ` Georgi Djakov
  (?)
@ 2020-04-02  2:48     ` Henry Chen
  -1 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-04-02  2:48 UTC (permalink / raw)
  To: Georgi Djakov
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, Viresh Kumar, linux-pm, linux-kernel, Rob Herring,
	Stephen Boyd, Fan Chen, devicetree, Mark Brown, Ryan Case,
	Arvin Wang, Matthias Brugger, linux-mediatek, linux-arm-kernel

Hi Georgi,

On Wed, 2020-04-01 at 18:09 +0300, Georgi Djakov wrote:
> Hi Henry,
> 
> On 3/13/20 11:34, Henry Chen wrote:
> > The patchsets add support for MediaTek hardware module named DVFSRC
> > (dynamic voltage and frequency scaling resource collector). The DVFSRC is
> > a HW module which is used to collect all the requests from both software
> > and hardware and turn into the decision of minimum operating voltage and
> > minimum DRAM frequency to fulfill those requests.
> > 
> > So, This series is to implement the dvfsrc driver to collect all the
> > requests of operating voltage or DRAM bandwidth from other device drivers
> > likes GPU/Camera through 3 frameworks basically:
> > 
> > 1. interconnect framework: to aggregate the bandwidth
> >    requirements from different clients
> > 
> > [1] https://patchwork.kernel.org/cover/10766329/
> > 
> > Below is the emi bandwidth map of mt8183. There has a hw module "DRAM scheduler"
> > which used to control the throughput. The DVFSRC will collect forecast data
> > of dram bandwidth from SW consumers(camera/gpu...), and according the forecast
> > to change the DRAM frequency
> > 
> >            ICC provider         ICC Nodes
> >                             ----          ----
> >            ---------       |CPU |   |--->|VPU |
> >   -----   |         |-----> ----    |     ----
> >  |DRAM |--|DRAM     |       ----    |     ----
> >  |     |--|scheduler|----->|GPU |   |--->|DISP|
> >  |     |--|(EMI)    |       ----    |     ----
> >  |     |--|         |       -----   |     ----
> >   -----   |         |----->|MMSYS|--|--->|VDEC|
> >            ---------        -----   |     ----
> >              /|\                    |     ----
> >               |change DRAM freq     |--->|VENC|
> >            ----------               |     ----
> >           |  DVFSR   |              |
> >           |          |              |     ----
> >            ----------               |--->|IMG |
> >                                     |     ----
> >                                     |     ----
> >                                     |--->|CAM |
> >                                           ----
> 
> It would be useful to also add the above diagram into the commit text of
> patch 09/13. By doing so, it will be saved into the history, as cover letters
> are discarded.
OK, thanks.
> 
> Thanks,
> Georgi
> 
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


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

* Re: [PATCH V4 00/13] Add driver for dvfsrc, support for active state of scpsys
@ 2020-04-02  2:48     ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-04-02  2:48 UTC (permalink / raw)
  To: Georgi Djakov
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, Viresh Kumar, Mark Brown, linux-pm, linux-kernel,
	Stephen Boyd, Fan Chen, devicetree, Rob Herring, Ryan Case,
	Arvin Wang, Matthias Brugger, linux-mediatek, linux-arm-kernel

Hi Georgi,

On Wed, 2020-04-01 at 18:09 +0300, Georgi Djakov wrote:
> Hi Henry,
> 
> On 3/13/20 11:34, Henry Chen wrote:
> > The patchsets add support for MediaTek hardware module named DVFSRC
> > (dynamic voltage and frequency scaling resource collector). The DVFSRC is
> > a HW module which is used to collect all the requests from both software
> > and hardware and turn into the decision of minimum operating voltage and
> > minimum DRAM frequency to fulfill those requests.
> > 
> > So, This series is to implement the dvfsrc driver to collect all the
> > requests of operating voltage or DRAM bandwidth from other device drivers
> > likes GPU/Camera through 3 frameworks basically:
> > 
> > 1. interconnect framework: to aggregate the bandwidth
> >    requirements from different clients
> > 
> > [1] https://patchwork.kernel.org/cover/10766329/
> > 
> > Below is the emi bandwidth map of mt8183. There has a hw module "DRAM scheduler"
> > which used to control the throughput. The DVFSRC will collect forecast data
> > of dram bandwidth from SW consumers(camera/gpu...), and according the forecast
> > to change the DRAM frequency
> > 
> >            ICC provider         ICC Nodes
> >                             ----          ----
> >            ---------       |CPU |   |--->|VPU |
> >   -----   |         |-----> ----    |     ----
> >  |DRAM |--|DRAM     |       ----    |     ----
> >  |     |--|scheduler|----->|GPU |   |--->|DISP|
> >  |     |--|(EMI)    |       ----    |     ----
> >  |     |--|         |       -----   |     ----
> >   -----   |         |----->|MMSYS|--|--->|VDEC|
> >            ---------        -----   |     ----
> >              /|\                    |     ----
> >               |change DRAM freq     |--->|VENC|
> >            ----------               |     ----
> >           |  DVFSR   |              |
> >           |          |              |     ----
> >            ----------               |--->|IMG |
> >                                     |     ----
> >                                     |     ----
> >                                     |--->|CAM |
> >                                           ----
> 
> It would be useful to also add the above diagram into the commit text of
> patch 09/13. By doing so, it will be saved into the history, as cover letters
> are discarded.
OK, thanks.
> 
> Thanks,
> Georgi
> 
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek

_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

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

* Re: [PATCH V4 00/13] Add driver for dvfsrc, support for active state of scpsys
@ 2020-04-02  2:48     ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-04-02  2:48 UTC (permalink / raw)
  To: Georgi Djakov
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, Viresh Kumar, Mark Brown, linux-pm, linux-kernel,
	Stephen Boyd, Fan Chen, devicetree, Rob Herring, Ryan Case,
	Arvin Wang, Matthias Brugger, linux-mediatek, linux-arm-kernel

Hi Georgi,

On Wed, 2020-04-01 at 18:09 +0300, Georgi Djakov wrote:
> Hi Henry,
> 
> On 3/13/20 11:34, Henry Chen wrote:
> > The patchsets add support for MediaTek hardware module named DVFSRC
> > (dynamic voltage and frequency scaling resource collector). The DVFSRC is
> > a HW module which is used to collect all the requests from both software
> > and hardware and turn into the decision of minimum operating voltage and
> > minimum DRAM frequency to fulfill those requests.
> > 
> > So, This series is to implement the dvfsrc driver to collect all the
> > requests of operating voltage or DRAM bandwidth from other device drivers
> > likes GPU/Camera through 3 frameworks basically:
> > 
> > 1. interconnect framework: to aggregate the bandwidth
> >    requirements from different clients
> > 
> > [1] https://patchwork.kernel.org/cover/10766329/
> > 
> > Below is the emi bandwidth map of mt8183. There has a hw module "DRAM scheduler"
> > which used to control the throughput. The DVFSRC will collect forecast data
> > of dram bandwidth from SW consumers(camera/gpu...), and according the forecast
> > to change the DRAM frequency
> > 
> >            ICC provider         ICC Nodes
> >                             ----          ----
> >            ---------       |CPU |   |--->|VPU |
> >   -----   |         |-----> ----    |     ----
> >  |DRAM |--|DRAM     |       ----    |     ----
> >  |     |--|scheduler|----->|GPU |   |--->|DISP|
> >  |     |--|(EMI)    |       ----    |     ----
> >  |     |--|         |       -----   |     ----
> >   -----   |         |----->|MMSYS|--|--->|VDEC|
> >            ---------        -----   |     ----
> >              /|\                    |     ----
> >               |change DRAM freq     |--->|VENC|
> >            ----------               |     ----
> >           |  DVFSR   |              |
> >           |          |              |     ----
> >            ----------               |--->|IMG |
> >                                     |     ----
> >                                     |     ----
> >                                     |--->|CAM |
> >                                           ----
> 
> It would be useful to also add the above diagram into the commit text of
> patch 09/13. By doing so, it will be saved into the history, as cover letters
> are discarded.
OK, thanks.
> 
> Thanks,
> Georgi
> 
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH V4 09/13] interconnect: mediatek: Add mt8183 interconnect provider driver
  2020-04-01 14:55     ` Georgi Djakov
  (?)
@ 2020-04-02  2:48       ` Henry Chen
  -1 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-04-02  2:48 UTC (permalink / raw)
  To: Georgi Djakov
  Cc: Rob Herring, Matthias Brugger, Viresh Kumar, Stephen Boyd,
	Ryan Case, Mark Brown, Mark Rutland, Nicolas Boichat, Fan Chen,
	James Liao, Arvin Wang, Mike Turquette, devicetree,
	linux-arm-kernel, linux-mediatek, linux-kernel, linux-pm,
	srv_heupstream

Hi Georgi,

On Wed, 2020-04-01 at 17:55 +0300, Georgi Djakov wrote:
> Hi Henry,
> 
> Thanks for the patch!
> 
> On 3/13/20 11:34, Henry Chen wrote:
> > Introduce Mediatek MT8183 specific provider driver using the
> > interconnect framework.
> > 
> > Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
> > ---
> >  drivers/interconnect/Kconfig            |   1 +
> >  drivers/interconnect/Makefile           |   1 +
> >  drivers/interconnect/mediatek/Kconfig   |  13 ++
> >  drivers/interconnect/mediatek/Makefile  |   3 +
> >  drivers/interconnect/mediatek/mtk-emi.c | 242 ++++++++++++++++++++++++++++++++
> >  5 files changed, 260 insertions(+)
> >  create mode 100644 drivers/interconnect/mediatek/Kconfig
> >  create mode 100644 drivers/interconnect/mediatek/Makefile
> >  create mode 100644 drivers/interconnect/mediatek/mtk-emi.c
> > 
> > diff --git a/drivers/interconnect/Kconfig b/drivers/interconnect/Kconfig
> > index bfa4ca3..dd9ecb6 100644
> > --- a/drivers/interconnect/Kconfig
> > +++ b/drivers/interconnect/Kconfig
> > @@ -12,5 +12,6 @@ menuconfig INTERCONNECT
> >  if INTERCONNECT
> >  
> >  source "drivers/interconnect/qcom/Kconfig"
> > +source "drivers/interconnect/mediatek/Kconfig"
> >  
> >  endif
> > diff --git a/drivers/interconnect/Makefile b/drivers/interconnect/Makefile
> > index 725029a..330a108 100644
> > --- a/drivers/interconnect/Makefile
> > +++ b/drivers/interconnect/Makefile
> > @@ -5,3 +5,4 @@ icc-core-objs				:= core.o
> >  
> >  obj-$(CONFIG_INTERCONNECT)		+= icc-core.o
> >  obj-$(CONFIG_INTERCONNECT_QCOM)		+= qcom/
> > +obj-$(CONFIG_INTERCONNECT_MTK)		+= mediatek/
> > diff --git a/drivers/interconnect/mediatek/Kconfig b/drivers/interconnect/mediatek/Kconfig
> > new file mode 100644
> > index 0000000..972d3bb
> > --- /dev/null
> > +++ b/drivers/interconnect/mediatek/Kconfig
> > @@ -0,0 +1,13 @@
> > +config INTERCONNECT_MTK
> > +	bool "Mediatek Network-on-Chip interconnect drivers"
> > +	depends on ARCH_MEDIATEK
> > +	help
> > +	  Support for Mediatek's Network-on-Chip interconnect hardware.
> > +
> > +config INTERCONNECT_MTK_EMI
> > +	tristate "Mediatek EMI interconnect driver"
> > +	depends on INTERCONNECT_MTK
> > +	depends on (MTK_DVFSRC && OF)
> > +	help
> > +	  This is a driver for the Mediatek Network-on-Chip on DVFSRC-based
> > +	  platforms.
> > diff --git a/drivers/interconnect/mediatek/Makefile b/drivers/interconnect/mediatek/Makefile
> > new file mode 100644
> > index 0000000..353842b
> > --- /dev/null
> > +++ b/drivers/interconnect/mediatek/Makefile
> > @@ -0,0 +1,3 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +
> > +obj-$(CONFIG_INTERCONNECT_MTK_EMI) += mtk-emi.o
> > \ No newline at end of file
> > diff --git a/drivers/interconnect/mediatek/mtk-emi.c b/drivers/interconnect/mediatek/mtk-emi.c
> > new file mode 100644
> > index 0000000..0a16992
> > --- /dev/null
> > +++ b/drivers/interconnect/mediatek/mtk-emi.c
> > @@ -0,0 +1,242 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2019, The Linux Foundation. All rights reserved.
> 
> Nit: Maybe 2020?
Yes, will change to 2020
> 
> > + *
> > + */
> > +
> > +#include <dt-bindings/interconnect/mtk,mt8183-emi.h>
> 
> Please move this below the all other linux/ headers
OK
> 
> > +#include <linux/device.h>
> > +#include <linux/interconnect-provider.h>
> > +#include <linux/module.h>
> > +#include <linux/of_device.h>
> > +#include <linux/of_platform.h>
> 
> Is this needed?
You're right, it not necessary and I will remove this.
> 
> > +#include <linux/platform_device.h>
> > +#include <soc/mediatek/mtk_dvfsrc.h>
> > +
> > +enum mtk_icc_name {
> > +	SLAVE_DDR_EMI,
> > +	MASTER_MCUSYS,
> > +	MASTER_GPUSYS,
> > +	MASTER_MMSYS,
> > +	MASTER_MM_VPU,
> > +	MASTER_MM_DISP,
> > +	MASTER_MM_VDEC,
> > +	MASTER_MM_VENC,
> > +	MASTER_MM_CAM,
> > +	MASTER_MM_IMG,
> > +	MASTER_MM_MDP,
> > +};
> > +
> > +#define MT8183_MAX_LINKS	1
> > +
> > +/**
> > + * struct mtk_icc_node - Mediatek specific interconnect nodes
> > + * @name: the node name used in debugfs
> > + * @ep: true if the node is an end point.
> > + * @id: a unique node identifier
> > + * @links: an array of nodes where we can go next while traversing
> > + * @num_links: the total number of @links
> > + * @buswidth: width of the interconnect between a node and the bus
> > + * @sum_avg: current sum aggregate value of all avg bw kBps requests
> > + * @max_peak: current max aggregate value of all peak bw kBps requests
> > + */
> > +struct mtk_icc_node {
> > +	unsigned char *name;
> > +	bool ep;
> > +	u16 id;
> > +	u16 links[MT8183_MAX_LINKS];
> > +	u16 num_links;
> > +	u16 buswidth;
> > +	u64 sum_avg;
> > +	u64 max_peak;
> > +};
> > +
> > +struct mtk_icc_desc {
> > +	struct mtk_icc_node **nodes;
> > +	size_t num_nodes;
> > +};
> > +
> > +#define DEFINE_MNODE(_name, _id, _buswidth, _ep, ...)	\
> > +		static struct mtk_icc_node _name = {			\
> > +		.name = #_name,						\
> > +		.id = _id,						\
> > +		.buswidth = _buswidth,					\
> > +		.ep = _ep,						\
> > +		.num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ })),	\
> > +}
> > +
> > +DEFINE_MNODE(ddr_emi, SLAVE_DDR_EMI, 1024, 1, 0);
> > +DEFINE_MNODE(mcusys, MASTER_MCUSYS, 256, 0, SLAVE_DDR_EMI);
> > +DEFINE_MNODE(gpu, MASTER_GPUSYS, 256, 0, SLAVE_DDR_EMI);
> > +DEFINE_MNODE(mmsys, MASTER_MMSYS, 256, 0, SLAVE_DDR_EMI);
> > +DEFINE_MNODE(mm_vpu, MASTER_MM_VPU, 128, 0, MASTER_MMSYS);
> > +DEFINE_MNODE(mm_disp, MASTER_MM_DISP, 128, 0, MASTER_MMSYS);
> > +DEFINE_MNODE(mm_vdec, MASTER_MM_VDEC, 128, 0, MASTER_MMSYS);
> > +DEFINE_MNODE(mm_venc, MASTER_MM_VENC, 128, 0, MASTER_MMSYS);
> > +DEFINE_MNODE(mm_cam, MASTER_MM_CAM, 128, 0, MASTER_MMSYS);
> > +DEFINE_MNODE(mm_img, MASTER_MM_IMG, 128, 0, MASTER_MMSYS);
> > +DEFINE_MNODE(mm_mdp, MASTER_MM_MDP, 128, 0, MASTER_MMSYS);
> > +
> > +static struct mtk_icc_node *mt8183_icc_nodes[] = {
> > +	[MT8183_SLAVE_DDR_EMI] = &ddr_emi,
> > +	[MT8183_MASTER_MCUSYS] = &mcusys,
> > +	[MT8183_MASTER_GPU] = &gpu,
> > +	[MT8183_MASTER_MMSYS] = &mmsys,
> > +	[MT8183_MASTER_MM_VPU] = &mm_vpu,
> > +	[MT8183_MASTER_MM_DISP] = &mm_disp,
> > +	[MT8183_MASTER_MM_VDEC] = &mm_vdec,
> > +	[MT8183_MASTER_MM_VENC] = &mm_venc,
> > +	[MT8183_MASTER_MM_CAM] = &mm_cam,
> > +	[MT8183_MASTER_MM_IMG] = &mm_img,
> > +	[MT8183_MASTER_MM_MDP] = &mm_mdp,
> > +};
> > +
> > +static struct mtk_icc_desc mt8183_icc = {
> 
> const?
ok
> 
> > +	.nodes = mt8183_icc_nodes,
> > +	.num_nodes = ARRAY_SIZE(mt8183_icc_nodes),
> > +};
> > +
> > +static int emi_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
> > +			     u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
> > +{
> > +	struct mtk_icc_node *in;
> > +
> > +	in = node->data;
> > +
> > +	*agg_avg += avg_bw;
> > +	*agg_peak += peak_bw;
> > +
> > +	in->sum_avg = *agg_avg;
> > +	in->max_peak = *agg_peak;
> > +
> > +	return 0;
> > +}
> > +
> > +static int emi_icc_set(struct icc_node *src, struct icc_node *dst)
> > +{
> > +	int ret = 0;
> > +	struct mtk_icc_node *node;
> > +
> > +	node = dst->data;
> > +	if (node->ep) {
> > +		pr_debug("sum_avg (%llu), max_peak (%llu)\n",
> > +			 node->sum_avg, node->max_peak);
> > +		mtk_dvfsrc_send_request(src->provider->dev->parent,
> > +					MTK_DVFSRC_CMD_BW_REQUEST,
> > +					node->max_peak);
> > +	}
> > +
> > +	return ret;
> > +}
> > +
> > +static int emi_icc_remove(struct platform_device *pdev);
> > +static int emi_icc_probe(struct platform_device *pdev)
> > +{
> > +	int ret;
> > +	const struct mtk_icc_desc *desc;
> > +	struct icc_node *node;
> > +	struct icc_onecell_data *data;
> > +	struct icc_provider *provider;
> > +	struct mtk_icc_node **mnodes;
> > +	size_t num_nodes, i, j;
> > +
> > +	desc = of_device_get_match_data(&pdev->dev);
> > +	if (!desc)
> > +		return -EINVAL;
> > +
> > +	mnodes = desc->nodes;
> > +	num_nodes = desc->num_nodes;
> > +
> > +	provider = devm_kzalloc(&pdev->dev, sizeof(*provider), GFP_KERNEL);
> > +	if (!provider)
> > +		return -ENOMEM;
> > +
> > +	data = devm_kcalloc(&pdev->dev, num_nodes, sizeof(*node), GFP_KERNEL);
> 
> This should be:
> devm_kzalloc(&pdev->dev, struct_size(data, nodes, num_nodes), GFP_KERNEL);
thanks, will fix this.
> 
> > +	if (!data)
> > +		return -ENOMEM;
> > +
> > +	provider->dev = &pdev->dev;
> > +	provider->set = emi_icc_set;
> > +	provider->aggregate = emi_icc_aggregate;
> > +	provider->xlate = of_icc_xlate_onecell;
> > +	INIT_LIST_HEAD(&provider->nodes);
> > +	provider->data = data;
> > +
> > +	ret = icc_provider_add(provider);
> > +	if (ret) {
> > +		dev_err(&pdev->dev, "error adding interconnect provider\n");
> > +		return ret;
> > +	}
> > +
> > +	for (i = 0; i < num_nodes; i++) {
> > +		node = icc_node_create(mnodes[i]->id);
> > +		if (IS_ERR(node)) {
> > +			ret = PTR_ERR(node);
> > +			goto err;
> > +		}
> > +
> > +		node->name = mnodes[i]->name;
> > +		node->data = mnodes[i];
> > +		icc_node_add(node, provider);
> > +
> > +		dev_dbg(&pdev->dev, "registered node %s, num link: %d\n",
> > +			mnodes[i]->name, mnodes[i]->num_links);
> 
> Please remove this.
ok
> 
> > +
> > +		/* populate links */
> 
> Please remove the comment too.
ok
> 
> > +		for (j = 0; j < mnodes[i]->num_links; j++)
> > +			icc_link_create(node, mnodes[i]->links[j]);
> > +
> > +		data->nodes[i] = node;
> > +	}
> > +	data->num_nodes = num_nodes;
> > +
> > +	platform_set_drvdata(pdev, provider);
> > +
> > +	return 0;
> > +err:
> > +	emi_icc_remove(pdev);
> 
> This will not work because platform_set_drvdata() is called only when the
> probe function completes successfully. So platform_get_drvdata() in
> emi_icc_remove() will return NULL.
> 
> > +	return ret;
> > +}
> > +
> > +static int emi_icc_remove(struct platform_device *pdev)
> > +{
> > +	struct icc_provider *provider = platform_get_drvdata(pdev);
> > +	struct icc_node *n;
> > +
> > +	list_for_each_entry(n, &provider->nodes, node_list) {
> > +		icc_node_del(n);
> > +		icc_node_destroy(n->id);
> > +	}
> 
> You can use icc_nodes_remove() instead of the above.
Got it, thanks for advise.
> 
> Thanks,
> Georgi

Thanks for the review.

Henry

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

* Re: [PATCH V4 09/13] interconnect: mediatek: Add mt8183 interconnect provider driver
@ 2020-04-02  2:48       ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-04-02  2:48 UTC (permalink / raw)
  To: Georgi Djakov
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, Viresh Kumar, linux-pm, linux-kernel, Rob Herring,
	Stephen Boyd, Fan Chen, devicetree, Mark Brown, Ryan Case,
	Arvin Wang, Matthias Brugger, linux-mediatek, linux-arm-kernel

Hi Georgi,

On Wed, 2020-04-01 at 17:55 +0300, Georgi Djakov wrote:
> Hi Henry,
> 
> Thanks for the patch!
> 
> On 3/13/20 11:34, Henry Chen wrote:
> > Introduce Mediatek MT8183 specific provider driver using the
> > interconnect framework.
> > 
> > Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
> > ---
> >  drivers/interconnect/Kconfig            |   1 +
> >  drivers/interconnect/Makefile           |   1 +
> >  drivers/interconnect/mediatek/Kconfig   |  13 ++
> >  drivers/interconnect/mediatek/Makefile  |   3 +
> >  drivers/interconnect/mediatek/mtk-emi.c | 242 ++++++++++++++++++++++++++++++++
> >  5 files changed, 260 insertions(+)
> >  create mode 100644 drivers/interconnect/mediatek/Kconfig
> >  create mode 100644 drivers/interconnect/mediatek/Makefile
> >  create mode 100644 drivers/interconnect/mediatek/mtk-emi.c
> > 
> > diff --git a/drivers/interconnect/Kconfig b/drivers/interconnect/Kconfig
> > index bfa4ca3..dd9ecb6 100644
> > --- a/drivers/interconnect/Kconfig
> > +++ b/drivers/interconnect/Kconfig
> > @@ -12,5 +12,6 @@ menuconfig INTERCONNECT
> >  if INTERCONNECT
> >  
> >  source "drivers/interconnect/qcom/Kconfig"
> > +source "drivers/interconnect/mediatek/Kconfig"
> >  
> >  endif
> > diff --git a/drivers/interconnect/Makefile b/drivers/interconnect/Makefile
> > index 725029a..330a108 100644
> > --- a/drivers/interconnect/Makefile
> > +++ b/drivers/interconnect/Makefile
> > @@ -5,3 +5,4 @@ icc-core-objs				:= core.o
> >  
> >  obj-$(CONFIG_INTERCONNECT)		+= icc-core.o
> >  obj-$(CONFIG_INTERCONNECT_QCOM)		+= qcom/
> > +obj-$(CONFIG_INTERCONNECT_MTK)		+= mediatek/
> > diff --git a/drivers/interconnect/mediatek/Kconfig b/drivers/interconnect/mediatek/Kconfig
> > new file mode 100644
> > index 0000000..972d3bb
> > --- /dev/null
> > +++ b/drivers/interconnect/mediatek/Kconfig
> > @@ -0,0 +1,13 @@
> > +config INTERCONNECT_MTK
> > +	bool "Mediatek Network-on-Chip interconnect drivers"
> > +	depends on ARCH_MEDIATEK
> > +	help
> > +	  Support for Mediatek's Network-on-Chip interconnect hardware.
> > +
> > +config INTERCONNECT_MTK_EMI
> > +	tristate "Mediatek EMI interconnect driver"
> > +	depends on INTERCONNECT_MTK
> > +	depends on (MTK_DVFSRC && OF)
> > +	help
> > +	  This is a driver for the Mediatek Network-on-Chip on DVFSRC-based
> > +	  platforms.
> > diff --git a/drivers/interconnect/mediatek/Makefile b/drivers/interconnect/mediatek/Makefile
> > new file mode 100644
> > index 0000000..353842b
> > --- /dev/null
> > +++ b/drivers/interconnect/mediatek/Makefile
> > @@ -0,0 +1,3 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +
> > +obj-$(CONFIG_INTERCONNECT_MTK_EMI) += mtk-emi.o
> > \ No newline at end of file
> > diff --git a/drivers/interconnect/mediatek/mtk-emi.c b/drivers/interconnect/mediatek/mtk-emi.c
> > new file mode 100644
> > index 0000000..0a16992
> > --- /dev/null
> > +++ b/drivers/interconnect/mediatek/mtk-emi.c
> > @@ -0,0 +1,242 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2019, The Linux Foundation. All rights reserved.
> 
> Nit: Maybe 2020?
Yes, will change to 2020
> 
> > + *
> > + */
> > +
> > +#include <dt-bindings/interconnect/mtk,mt8183-emi.h>
> 
> Please move this below the all other linux/ headers
OK
> 
> > +#include <linux/device.h>
> > +#include <linux/interconnect-provider.h>
> > +#include <linux/module.h>
> > +#include <linux/of_device.h>
> > +#include <linux/of_platform.h>
> 
> Is this needed?
You're right, it not necessary and I will remove this.
> 
> > +#include <linux/platform_device.h>
> > +#include <soc/mediatek/mtk_dvfsrc.h>
> > +
> > +enum mtk_icc_name {
> > +	SLAVE_DDR_EMI,
> > +	MASTER_MCUSYS,
> > +	MASTER_GPUSYS,
> > +	MASTER_MMSYS,
> > +	MASTER_MM_VPU,
> > +	MASTER_MM_DISP,
> > +	MASTER_MM_VDEC,
> > +	MASTER_MM_VENC,
> > +	MASTER_MM_CAM,
> > +	MASTER_MM_IMG,
> > +	MASTER_MM_MDP,
> > +};
> > +
> > +#define MT8183_MAX_LINKS	1
> > +
> > +/**
> > + * struct mtk_icc_node - Mediatek specific interconnect nodes
> > + * @name: the node name used in debugfs
> > + * @ep: true if the node is an end point.
> > + * @id: a unique node identifier
> > + * @links: an array of nodes where we can go next while traversing
> > + * @num_links: the total number of @links
> > + * @buswidth: width of the interconnect between a node and the bus
> > + * @sum_avg: current sum aggregate value of all avg bw kBps requests
> > + * @max_peak: current max aggregate value of all peak bw kBps requests
> > + */
> > +struct mtk_icc_node {
> > +	unsigned char *name;
> > +	bool ep;
> > +	u16 id;
> > +	u16 links[MT8183_MAX_LINKS];
> > +	u16 num_links;
> > +	u16 buswidth;
> > +	u64 sum_avg;
> > +	u64 max_peak;
> > +};
> > +
> > +struct mtk_icc_desc {
> > +	struct mtk_icc_node **nodes;
> > +	size_t num_nodes;
> > +};
> > +
> > +#define DEFINE_MNODE(_name, _id, _buswidth, _ep, ...)	\
> > +		static struct mtk_icc_node _name = {			\
> > +		.name = #_name,						\
> > +		.id = _id,						\
> > +		.buswidth = _buswidth,					\
> > +		.ep = _ep,						\
> > +		.num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ })),	\
> > +}
> > +
> > +DEFINE_MNODE(ddr_emi, SLAVE_DDR_EMI, 1024, 1, 0);
> > +DEFINE_MNODE(mcusys, MASTER_MCUSYS, 256, 0, SLAVE_DDR_EMI);
> > +DEFINE_MNODE(gpu, MASTER_GPUSYS, 256, 0, SLAVE_DDR_EMI);
> > +DEFINE_MNODE(mmsys, MASTER_MMSYS, 256, 0, SLAVE_DDR_EMI);
> > +DEFINE_MNODE(mm_vpu, MASTER_MM_VPU, 128, 0, MASTER_MMSYS);
> > +DEFINE_MNODE(mm_disp, MASTER_MM_DISP, 128, 0, MASTER_MMSYS);
> > +DEFINE_MNODE(mm_vdec, MASTER_MM_VDEC, 128, 0, MASTER_MMSYS);
> > +DEFINE_MNODE(mm_venc, MASTER_MM_VENC, 128, 0, MASTER_MMSYS);
> > +DEFINE_MNODE(mm_cam, MASTER_MM_CAM, 128, 0, MASTER_MMSYS);
> > +DEFINE_MNODE(mm_img, MASTER_MM_IMG, 128, 0, MASTER_MMSYS);
> > +DEFINE_MNODE(mm_mdp, MASTER_MM_MDP, 128, 0, MASTER_MMSYS);
> > +
> > +static struct mtk_icc_node *mt8183_icc_nodes[] = {
> > +	[MT8183_SLAVE_DDR_EMI] = &ddr_emi,
> > +	[MT8183_MASTER_MCUSYS] = &mcusys,
> > +	[MT8183_MASTER_GPU] = &gpu,
> > +	[MT8183_MASTER_MMSYS] = &mmsys,
> > +	[MT8183_MASTER_MM_VPU] = &mm_vpu,
> > +	[MT8183_MASTER_MM_DISP] = &mm_disp,
> > +	[MT8183_MASTER_MM_VDEC] = &mm_vdec,
> > +	[MT8183_MASTER_MM_VENC] = &mm_venc,
> > +	[MT8183_MASTER_MM_CAM] = &mm_cam,
> > +	[MT8183_MASTER_MM_IMG] = &mm_img,
> > +	[MT8183_MASTER_MM_MDP] = &mm_mdp,
> > +};
> > +
> > +static struct mtk_icc_desc mt8183_icc = {
> 
> const?
ok
> 
> > +	.nodes = mt8183_icc_nodes,
> > +	.num_nodes = ARRAY_SIZE(mt8183_icc_nodes),
> > +};
> > +
> > +static int emi_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
> > +			     u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
> > +{
> > +	struct mtk_icc_node *in;
> > +
> > +	in = node->data;
> > +
> > +	*agg_avg += avg_bw;
> > +	*agg_peak += peak_bw;
> > +
> > +	in->sum_avg = *agg_avg;
> > +	in->max_peak = *agg_peak;
> > +
> > +	return 0;
> > +}
> > +
> > +static int emi_icc_set(struct icc_node *src, struct icc_node *dst)
> > +{
> > +	int ret = 0;
> > +	struct mtk_icc_node *node;
> > +
> > +	node = dst->data;
> > +	if (node->ep) {
> > +		pr_debug("sum_avg (%llu), max_peak (%llu)\n",
> > +			 node->sum_avg, node->max_peak);
> > +		mtk_dvfsrc_send_request(src->provider->dev->parent,
> > +					MTK_DVFSRC_CMD_BW_REQUEST,
> > +					node->max_peak);
> > +	}
> > +
> > +	return ret;
> > +}
> > +
> > +static int emi_icc_remove(struct platform_device *pdev);
> > +static int emi_icc_probe(struct platform_device *pdev)
> > +{
> > +	int ret;
> > +	const struct mtk_icc_desc *desc;
> > +	struct icc_node *node;
> > +	struct icc_onecell_data *data;
> > +	struct icc_provider *provider;
> > +	struct mtk_icc_node **mnodes;
> > +	size_t num_nodes, i, j;
> > +
> > +	desc = of_device_get_match_data(&pdev->dev);
> > +	if (!desc)
> > +		return -EINVAL;
> > +
> > +	mnodes = desc->nodes;
> > +	num_nodes = desc->num_nodes;
> > +
> > +	provider = devm_kzalloc(&pdev->dev, sizeof(*provider), GFP_KERNEL);
> > +	if (!provider)
> > +		return -ENOMEM;
> > +
> > +	data = devm_kcalloc(&pdev->dev, num_nodes, sizeof(*node), GFP_KERNEL);
> 
> This should be:
> devm_kzalloc(&pdev->dev, struct_size(data, nodes, num_nodes), GFP_KERNEL);
thanks, will fix this.
> 
> > +	if (!data)
> > +		return -ENOMEM;
> > +
> > +	provider->dev = &pdev->dev;
> > +	provider->set = emi_icc_set;
> > +	provider->aggregate = emi_icc_aggregate;
> > +	provider->xlate = of_icc_xlate_onecell;
> > +	INIT_LIST_HEAD(&provider->nodes);
> > +	provider->data = data;
> > +
> > +	ret = icc_provider_add(provider);
> > +	if (ret) {
> > +		dev_err(&pdev->dev, "error adding interconnect provider\n");
> > +		return ret;
> > +	}
> > +
> > +	for (i = 0; i < num_nodes; i++) {
> > +		node = icc_node_create(mnodes[i]->id);
> > +		if (IS_ERR(node)) {
> > +			ret = PTR_ERR(node);
> > +			goto err;
> > +		}
> > +
> > +		node->name = mnodes[i]->name;
> > +		node->data = mnodes[i];
> > +		icc_node_add(node, provider);
> > +
> > +		dev_dbg(&pdev->dev, "registered node %s, num link: %d\n",
> > +			mnodes[i]->name, mnodes[i]->num_links);
> 
> Please remove this.
ok
> 
> > +
> > +		/* populate links */
> 
> Please remove the comment too.
ok
> 
> > +		for (j = 0; j < mnodes[i]->num_links; j++)
> > +			icc_link_create(node, mnodes[i]->links[j]);
> > +
> > +		data->nodes[i] = node;
> > +	}
> > +	data->num_nodes = num_nodes;
> > +
> > +	platform_set_drvdata(pdev, provider);
> > +
> > +	return 0;
> > +err:
> > +	emi_icc_remove(pdev);
> 
> This will not work because platform_set_drvdata() is called only when the
> probe function completes successfully. So platform_get_drvdata() in
> emi_icc_remove() will return NULL.
> 
> > +	return ret;
> > +}
> > +
> > +static int emi_icc_remove(struct platform_device *pdev)
> > +{
> > +	struct icc_provider *provider = platform_get_drvdata(pdev);
> > +	struct icc_node *n;
> > +
> > +	list_for_each_entry(n, &provider->nodes, node_list) {
> > +		icc_node_del(n);
> > +		icc_node_destroy(n->id);
> > +	}
> 
> You can use icc_nodes_remove() instead of the above.
Got it, thanks for advise.
> 
> Thanks,
> Georgi

Thanks for the review.

Henry
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

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

* Re: [PATCH V4 09/13] interconnect: mediatek: Add mt8183 interconnect provider driver
@ 2020-04-02  2:48       ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-04-02  2:48 UTC (permalink / raw)
  To: Georgi Djakov
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, Viresh Kumar, linux-pm, linux-kernel, Rob Herring,
	Stephen Boyd, Fan Chen, devicetree, Mark Brown, Ryan Case,
	Arvin Wang, Matthias Brugger, linux-mediatek, linux-arm-kernel

Hi Georgi,

On Wed, 2020-04-01 at 17:55 +0300, Georgi Djakov wrote:
> Hi Henry,
> 
> Thanks for the patch!
> 
> On 3/13/20 11:34, Henry Chen wrote:
> > Introduce Mediatek MT8183 specific provider driver using the
> > interconnect framework.
> > 
> > Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
> > ---
> >  drivers/interconnect/Kconfig            |   1 +
> >  drivers/interconnect/Makefile           |   1 +
> >  drivers/interconnect/mediatek/Kconfig   |  13 ++
> >  drivers/interconnect/mediatek/Makefile  |   3 +
> >  drivers/interconnect/mediatek/mtk-emi.c | 242 ++++++++++++++++++++++++++++++++
> >  5 files changed, 260 insertions(+)
> >  create mode 100644 drivers/interconnect/mediatek/Kconfig
> >  create mode 100644 drivers/interconnect/mediatek/Makefile
> >  create mode 100644 drivers/interconnect/mediatek/mtk-emi.c
> > 
> > diff --git a/drivers/interconnect/Kconfig b/drivers/interconnect/Kconfig
> > index bfa4ca3..dd9ecb6 100644
> > --- a/drivers/interconnect/Kconfig
> > +++ b/drivers/interconnect/Kconfig
> > @@ -12,5 +12,6 @@ menuconfig INTERCONNECT
> >  if INTERCONNECT
> >  
> >  source "drivers/interconnect/qcom/Kconfig"
> > +source "drivers/interconnect/mediatek/Kconfig"
> >  
> >  endif
> > diff --git a/drivers/interconnect/Makefile b/drivers/interconnect/Makefile
> > index 725029a..330a108 100644
> > --- a/drivers/interconnect/Makefile
> > +++ b/drivers/interconnect/Makefile
> > @@ -5,3 +5,4 @@ icc-core-objs				:= core.o
> >  
> >  obj-$(CONFIG_INTERCONNECT)		+= icc-core.o
> >  obj-$(CONFIG_INTERCONNECT_QCOM)		+= qcom/
> > +obj-$(CONFIG_INTERCONNECT_MTK)		+= mediatek/
> > diff --git a/drivers/interconnect/mediatek/Kconfig b/drivers/interconnect/mediatek/Kconfig
> > new file mode 100644
> > index 0000000..972d3bb
> > --- /dev/null
> > +++ b/drivers/interconnect/mediatek/Kconfig
> > @@ -0,0 +1,13 @@
> > +config INTERCONNECT_MTK
> > +	bool "Mediatek Network-on-Chip interconnect drivers"
> > +	depends on ARCH_MEDIATEK
> > +	help
> > +	  Support for Mediatek's Network-on-Chip interconnect hardware.
> > +
> > +config INTERCONNECT_MTK_EMI
> > +	tristate "Mediatek EMI interconnect driver"
> > +	depends on INTERCONNECT_MTK
> > +	depends on (MTK_DVFSRC && OF)
> > +	help
> > +	  This is a driver for the Mediatek Network-on-Chip on DVFSRC-based
> > +	  platforms.
> > diff --git a/drivers/interconnect/mediatek/Makefile b/drivers/interconnect/mediatek/Makefile
> > new file mode 100644
> > index 0000000..353842b
> > --- /dev/null
> > +++ b/drivers/interconnect/mediatek/Makefile
> > @@ -0,0 +1,3 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +
> > +obj-$(CONFIG_INTERCONNECT_MTK_EMI) += mtk-emi.o
> > \ No newline at end of file
> > diff --git a/drivers/interconnect/mediatek/mtk-emi.c b/drivers/interconnect/mediatek/mtk-emi.c
> > new file mode 100644
> > index 0000000..0a16992
> > --- /dev/null
> > +++ b/drivers/interconnect/mediatek/mtk-emi.c
> > @@ -0,0 +1,242 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2019, The Linux Foundation. All rights reserved.
> 
> Nit: Maybe 2020?
Yes, will change to 2020
> 
> > + *
> > + */
> > +
> > +#include <dt-bindings/interconnect/mtk,mt8183-emi.h>
> 
> Please move this below the all other linux/ headers
OK
> 
> > +#include <linux/device.h>
> > +#include <linux/interconnect-provider.h>
> > +#include <linux/module.h>
> > +#include <linux/of_device.h>
> > +#include <linux/of_platform.h>
> 
> Is this needed?
You're right, it not necessary and I will remove this.
> 
> > +#include <linux/platform_device.h>
> > +#include <soc/mediatek/mtk_dvfsrc.h>
> > +
> > +enum mtk_icc_name {
> > +	SLAVE_DDR_EMI,
> > +	MASTER_MCUSYS,
> > +	MASTER_GPUSYS,
> > +	MASTER_MMSYS,
> > +	MASTER_MM_VPU,
> > +	MASTER_MM_DISP,
> > +	MASTER_MM_VDEC,
> > +	MASTER_MM_VENC,
> > +	MASTER_MM_CAM,
> > +	MASTER_MM_IMG,
> > +	MASTER_MM_MDP,
> > +};
> > +
> > +#define MT8183_MAX_LINKS	1
> > +
> > +/**
> > + * struct mtk_icc_node - Mediatek specific interconnect nodes
> > + * @name: the node name used in debugfs
> > + * @ep: true if the node is an end point.
> > + * @id: a unique node identifier
> > + * @links: an array of nodes where we can go next while traversing
> > + * @num_links: the total number of @links
> > + * @buswidth: width of the interconnect between a node and the bus
> > + * @sum_avg: current sum aggregate value of all avg bw kBps requests
> > + * @max_peak: current max aggregate value of all peak bw kBps requests
> > + */
> > +struct mtk_icc_node {
> > +	unsigned char *name;
> > +	bool ep;
> > +	u16 id;
> > +	u16 links[MT8183_MAX_LINKS];
> > +	u16 num_links;
> > +	u16 buswidth;
> > +	u64 sum_avg;
> > +	u64 max_peak;
> > +};
> > +
> > +struct mtk_icc_desc {
> > +	struct mtk_icc_node **nodes;
> > +	size_t num_nodes;
> > +};
> > +
> > +#define DEFINE_MNODE(_name, _id, _buswidth, _ep, ...)	\
> > +		static struct mtk_icc_node _name = {			\
> > +		.name = #_name,						\
> > +		.id = _id,						\
> > +		.buswidth = _buswidth,					\
> > +		.ep = _ep,						\
> > +		.num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ })),	\
> > +}
> > +
> > +DEFINE_MNODE(ddr_emi, SLAVE_DDR_EMI, 1024, 1, 0);
> > +DEFINE_MNODE(mcusys, MASTER_MCUSYS, 256, 0, SLAVE_DDR_EMI);
> > +DEFINE_MNODE(gpu, MASTER_GPUSYS, 256, 0, SLAVE_DDR_EMI);
> > +DEFINE_MNODE(mmsys, MASTER_MMSYS, 256, 0, SLAVE_DDR_EMI);
> > +DEFINE_MNODE(mm_vpu, MASTER_MM_VPU, 128, 0, MASTER_MMSYS);
> > +DEFINE_MNODE(mm_disp, MASTER_MM_DISP, 128, 0, MASTER_MMSYS);
> > +DEFINE_MNODE(mm_vdec, MASTER_MM_VDEC, 128, 0, MASTER_MMSYS);
> > +DEFINE_MNODE(mm_venc, MASTER_MM_VENC, 128, 0, MASTER_MMSYS);
> > +DEFINE_MNODE(mm_cam, MASTER_MM_CAM, 128, 0, MASTER_MMSYS);
> > +DEFINE_MNODE(mm_img, MASTER_MM_IMG, 128, 0, MASTER_MMSYS);
> > +DEFINE_MNODE(mm_mdp, MASTER_MM_MDP, 128, 0, MASTER_MMSYS);
> > +
> > +static struct mtk_icc_node *mt8183_icc_nodes[] = {
> > +	[MT8183_SLAVE_DDR_EMI] = &ddr_emi,
> > +	[MT8183_MASTER_MCUSYS] = &mcusys,
> > +	[MT8183_MASTER_GPU] = &gpu,
> > +	[MT8183_MASTER_MMSYS] = &mmsys,
> > +	[MT8183_MASTER_MM_VPU] = &mm_vpu,
> > +	[MT8183_MASTER_MM_DISP] = &mm_disp,
> > +	[MT8183_MASTER_MM_VDEC] = &mm_vdec,
> > +	[MT8183_MASTER_MM_VENC] = &mm_venc,
> > +	[MT8183_MASTER_MM_CAM] = &mm_cam,
> > +	[MT8183_MASTER_MM_IMG] = &mm_img,
> > +	[MT8183_MASTER_MM_MDP] = &mm_mdp,
> > +};
> > +
> > +static struct mtk_icc_desc mt8183_icc = {
> 
> const?
ok
> 
> > +	.nodes = mt8183_icc_nodes,
> > +	.num_nodes = ARRAY_SIZE(mt8183_icc_nodes),
> > +};
> > +
> > +static int emi_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
> > +			     u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
> > +{
> > +	struct mtk_icc_node *in;
> > +
> > +	in = node->data;
> > +
> > +	*agg_avg += avg_bw;
> > +	*agg_peak += peak_bw;
> > +
> > +	in->sum_avg = *agg_avg;
> > +	in->max_peak = *agg_peak;
> > +
> > +	return 0;
> > +}
> > +
> > +static int emi_icc_set(struct icc_node *src, struct icc_node *dst)
> > +{
> > +	int ret = 0;
> > +	struct mtk_icc_node *node;
> > +
> > +	node = dst->data;
> > +	if (node->ep) {
> > +		pr_debug("sum_avg (%llu), max_peak (%llu)\n",
> > +			 node->sum_avg, node->max_peak);
> > +		mtk_dvfsrc_send_request(src->provider->dev->parent,
> > +					MTK_DVFSRC_CMD_BW_REQUEST,
> > +					node->max_peak);
> > +	}
> > +
> > +	return ret;
> > +}
> > +
> > +static int emi_icc_remove(struct platform_device *pdev);
> > +static int emi_icc_probe(struct platform_device *pdev)
> > +{
> > +	int ret;
> > +	const struct mtk_icc_desc *desc;
> > +	struct icc_node *node;
> > +	struct icc_onecell_data *data;
> > +	struct icc_provider *provider;
> > +	struct mtk_icc_node **mnodes;
> > +	size_t num_nodes, i, j;
> > +
> > +	desc = of_device_get_match_data(&pdev->dev);
> > +	if (!desc)
> > +		return -EINVAL;
> > +
> > +	mnodes = desc->nodes;
> > +	num_nodes = desc->num_nodes;
> > +
> > +	provider = devm_kzalloc(&pdev->dev, sizeof(*provider), GFP_KERNEL);
> > +	if (!provider)
> > +		return -ENOMEM;
> > +
> > +	data = devm_kcalloc(&pdev->dev, num_nodes, sizeof(*node), GFP_KERNEL);
> 
> This should be:
> devm_kzalloc(&pdev->dev, struct_size(data, nodes, num_nodes), GFP_KERNEL);
thanks, will fix this.
> 
> > +	if (!data)
> > +		return -ENOMEM;
> > +
> > +	provider->dev = &pdev->dev;
> > +	provider->set = emi_icc_set;
> > +	provider->aggregate = emi_icc_aggregate;
> > +	provider->xlate = of_icc_xlate_onecell;
> > +	INIT_LIST_HEAD(&provider->nodes);
> > +	provider->data = data;
> > +
> > +	ret = icc_provider_add(provider);
> > +	if (ret) {
> > +		dev_err(&pdev->dev, "error adding interconnect provider\n");
> > +		return ret;
> > +	}
> > +
> > +	for (i = 0; i < num_nodes; i++) {
> > +		node = icc_node_create(mnodes[i]->id);
> > +		if (IS_ERR(node)) {
> > +			ret = PTR_ERR(node);
> > +			goto err;
> > +		}
> > +
> > +		node->name = mnodes[i]->name;
> > +		node->data = mnodes[i];
> > +		icc_node_add(node, provider);
> > +
> > +		dev_dbg(&pdev->dev, "registered node %s, num link: %d\n",
> > +			mnodes[i]->name, mnodes[i]->num_links);
> 
> Please remove this.
ok
> 
> > +
> > +		/* populate links */
> 
> Please remove the comment too.
ok
> 
> > +		for (j = 0; j < mnodes[i]->num_links; j++)
> > +			icc_link_create(node, mnodes[i]->links[j]);
> > +
> > +		data->nodes[i] = node;
> > +	}
> > +	data->num_nodes = num_nodes;
> > +
> > +	platform_set_drvdata(pdev, provider);
> > +
> > +	return 0;
> > +err:
> > +	emi_icc_remove(pdev);
> 
> This will not work because platform_set_drvdata() is called only when the
> probe function completes successfully. So platform_get_drvdata() in
> emi_icc_remove() will return NULL.
> 
> > +	return ret;
> > +}
> > +
> > +static int emi_icc_remove(struct platform_device *pdev)
> > +{
> > +	struct icc_provider *provider = platform_get_drvdata(pdev);
> > +	struct icc_node *n;
> > +
> > +	list_for_each_entry(n, &provider->nodes, node_list) {
> > +		icc_node_del(n);
> > +		icc_node_destroy(n->id);
> > +	}
> 
> You can use icc_nodes_remove() instead of the above.
Got it, thanks for advise.
> 
> Thanks,
> Georgi

Thanks for the review.

Henry
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH V4 06/13] soc: mediatek: add MT8183 dvfsrc support
  2020-04-01 14:41     ` Georgi Djakov
  (?)
@ 2020-04-02  2:48       ` Henry Chen
  -1 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-04-02  2:48 UTC (permalink / raw)
  To: Georgi Djakov
  Cc: Rob Herring, Matthias Brugger, Viresh Kumar, Stephen Boyd,
	Ryan Case, Mark Brown, Mark Rutland, Nicolas Boichat, Fan Chen,
	James Liao, Arvin Wang, Mike Turquette, devicetree,
	linux-arm-kernel, linux-mediatek, linux-kernel, linux-pm,
	srv_heupstream

Hi Georgi,

On Wed, 2020-04-01 at 17:41 +0300, Georgi Djakov wrote:
> Hi Henry,
> 
> On 3/13/20 11:34, Henry Chen wrote:
> > Add dvfsrc driver for MT8183
> > 
> > Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
> > ---
> >  drivers/soc/mediatek/Kconfig      |  15 ++
> >  drivers/soc/mediatek/Makefile     |   1 +
> >  drivers/soc/mediatek/mtk-dvfsrc.c | 434 ++++++++++++++++++++++++++++++++++++++
> >  include/soc/mediatek/mtk_dvfsrc.h |  30 +++
> >  4 files changed, 480 insertions(+)
> >  create mode 100644 drivers/soc/mediatek/mtk-dvfsrc.c
> >  create mode 100644 include/soc/mediatek/mtk_dvfsrc.h
> > 
> > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> > index f837b3c..44808f4 100644
> > --- a/drivers/soc/mediatek/Kconfig
> > +++ b/drivers/soc/mediatek/Kconfig
> > @@ -16,6 +16,21 @@ config MTK_CMDQ
> >  	  time limitation, such as updating display configuration during the
> >  	  vblank.
> >  
> > +config MTK_DVFSRC
> > +	bool "MediaTek DVFSRC Support"
> > +	depends on ARCH_MEDIATEK
> > +	default ARCH_MEDIATEK
> > +	select MTK_INFRACFG
> > +	select PM_GENERIC_DOMAINS if PM
> > +	depends on MTK_SCPSYS
> > +	help
> > +	  Say yes here to add support for the MediaTek DVFSRC (dynamic voltage
> > +	  and frequency scaling resource collector) found
> > +	  on different MediaTek SoCs. The DVFSRC is a proprietary
> > +	  hardware which is used to collect all the requests from
> > +	  system and turn into the decision of minimum Vcore voltage
> > +	  and minimum DRAM frequency to fulfill those requests.
> > +
> >  config MTK_PMIC_WRAP
> >  	tristate "MediaTek PMIC Wrapper Support"
> >  	depends on RESET_CONTROLLER
> > diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> > index 2b2c2537..84182f0 100644
> > --- a/drivers/soc/mediatek/Makefile
> > +++ b/drivers/soc/mediatek/Makefile
> > @@ -1,4 +1,5 @@
> >  # SPDX-License-Identifier: GPL-2.0-only
> >  obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
> > +obj-$(CONFIG_MTK_DVFSRC) += mtk-dvfsrc.o
> >  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
> >  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> > diff --git a/drivers/soc/mediatek/mtk-dvfsrc.c b/drivers/soc/mediatek/mtk-dvfsrc.c
> > new file mode 100644
> > index 0000000..85b3572
> > --- /dev/null
> > +++ b/drivers/soc/mediatek/mtk-dvfsrc.c
> > @@ -0,0 +1,434 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2018 MediaTek Inc.
> > + */
> > +#include <linux/arm-smccc.h>
> > +#include <linux/clk.h>
> > +#include <linux/io.h>
> > +#include <linux/iopoll.h>
> > +#include <linux/module.h>
> > +#include <linux/notifier.h>
> > +#include <linux/of_device.h>
> > +#include <linux/platform_device.h>
> > +#include <soc/mediatek/mtk_dvfsrc.h>
> > +#include <soc/mediatek/mtk_sip.h>
> > +#include <dt-bindings/power/mt8183-power.h>
> 
> Looks like this depends on a header which is not part of this patch-set.
> It would be nice to list any dependencies in the cover letter.
> 
> Thanks,
> Georgi

I disregarded to list here. Thanks for your friendly reminder.

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

* Re: [PATCH V4 06/13] soc: mediatek: add MT8183 dvfsrc support
@ 2020-04-02  2:48       ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-04-02  2:48 UTC (permalink / raw)
  To: Georgi Djakov
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, Viresh Kumar, linux-pm, linux-kernel, Rob Herring,
	Stephen Boyd, Fan Chen, devicetree, Mark Brown, Ryan Case,
	Arvin Wang, Matthias Brugger, linux-mediatek, linux-arm-kernel

Hi Georgi,

On Wed, 2020-04-01 at 17:41 +0300, Georgi Djakov wrote:
> Hi Henry,
> 
> On 3/13/20 11:34, Henry Chen wrote:
> > Add dvfsrc driver for MT8183
> > 
> > Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
> > ---
> >  drivers/soc/mediatek/Kconfig      |  15 ++
> >  drivers/soc/mediatek/Makefile     |   1 +
> >  drivers/soc/mediatek/mtk-dvfsrc.c | 434 ++++++++++++++++++++++++++++++++++++++
> >  include/soc/mediatek/mtk_dvfsrc.h |  30 +++
> >  4 files changed, 480 insertions(+)
> >  create mode 100644 drivers/soc/mediatek/mtk-dvfsrc.c
> >  create mode 100644 include/soc/mediatek/mtk_dvfsrc.h
> > 
> > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> > index f837b3c..44808f4 100644
> > --- a/drivers/soc/mediatek/Kconfig
> > +++ b/drivers/soc/mediatek/Kconfig
> > @@ -16,6 +16,21 @@ config MTK_CMDQ
> >  	  time limitation, such as updating display configuration during the
> >  	  vblank.
> >  
> > +config MTK_DVFSRC
> > +	bool "MediaTek DVFSRC Support"
> > +	depends on ARCH_MEDIATEK
> > +	default ARCH_MEDIATEK
> > +	select MTK_INFRACFG
> > +	select PM_GENERIC_DOMAINS if PM
> > +	depends on MTK_SCPSYS
> > +	help
> > +	  Say yes here to add support for the MediaTek DVFSRC (dynamic voltage
> > +	  and frequency scaling resource collector) found
> > +	  on different MediaTek SoCs. The DVFSRC is a proprietary
> > +	  hardware which is used to collect all the requests from
> > +	  system and turn into the decision of minimum Vcore voltage
> > +	  and minimum DRAM frequency to fulfill those requests.
> > +
> >  config MTK_PMIC_WRAP
> >  	tristate "MediaTek PMIC Wrapper Support"
> >  	depends on RESET_CONTROLLER
> > diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> > index 2b2c2537..84182f0 100644
> > --- a/drivers/soc/mediatek/Makefile
> > +++ b/drivers/soc/mediatek/Makefile
> > @@ -1,4 +1,5 @@
> >  # SPDX-License-Identifier: GPL-2.0-only
> >  obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
> > +obj-$(CONFIG_MTK_DVFSRC) += mtk-dvfsrc.o
> >  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
> >  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> > diff --git a/drivers/soc/mediatek/mtk-dvfsrc.c b/drivers/soc/mediatek/mtk-dvfsrc.c
> > new file mode 100644
> > index 0000000..85b3572
> > --- /dev/null
> > +++ b/drivers/soc/mediatek/mtk-dvfsrc.c
> > @@ -0,0 +1,434 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2018 MediaTek Inc.
> > + */
> > +#include <linux/arm-smccc.h>
> > +#include <linux/clk.h>
> > +#include <linux/io.h>
> > +#include <linux/iopoll.h>
> > +#include <linux/module.h>
> > +#include <linux/notifier.h>
> > +#include <linux/of_device.h>
> > +#include <linux/platform_device.h>
> > +#include <soc/mediatek/mtk_dvfsrc.h>
> > +#include <soc/mediatek/mtk_sip.h>
> > +#include <dt-bindings/power/mt8183-power.h>
> 
> Looks like this depends on a header which is not part of this patch-set.
> It would be nice to list any dependencies in the cover letter.
> 
> Thanks,
> Georgi

I disregarded to list here. Thanks for your friendly reminder.
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

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

* Re: [PATCH V4 06/13] soc: mediatek: add MT8183 dvfsrc support
@ 2020-04-02  2:48       ` Henry Chen
  0 siblings, 0 replies; 66+ messages in thread
From: Henry Chen @ 2020-04-02  2:48 UTC (permalink / raw)
  To: Georgi Djakov
  Cc: Mark Rutland, Nicolas Boichat, Mike Turquette, srv_heupstream,
	James Liao, Viresh Kumar, linux-pm, linux-kernel, Rob Herring,
	Stephen Boyd, Fan Chen, devicetree, Mark Brown, Ryan Case,
	Arvin Wang, Matthias Brugger, linux-mediatek, linux-arm-kernel

Hi Georgi,

On Wed, 2020-04-01 at 17:41 +0300, Georgi Djakov wrote:
> Hi Henry,
> 
> On 3/13/20 11:34, Henry Chen wrote:
> > Add dvfsrc driver for MT8183
> > 
> > Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
> > ---
> >  drivers/soc/mediatek/Kconfig      |  15 ++
> >  drivers/soc/mediatek/Makefile     |   1 +
> >  drivers/soc/mediatek/mtk-dvfsrc.c | 434 ++++++++++++++++++++++++++++++++++++++
> >  include/soc/mediatek/mtk_dvfsrc.h |  30 +++
> >  4 files changed, 480 insertions(+)
> >  create mode 100644 drivers/soc/mediatek/mtk-dvfsrc.c
> >  create mode 100644 include/soc/mediatek/mtk_dvfsrc.h
> > 
> > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> > index f837b3c..44808f4 100644
> > --- a/drivers/soc/mediatek/Kconfig
> > +++ b/drivers/soc/mediatek/Kconfig
> > @@ -16,6 +16,21 @@ config MTK_CMDQ
> >  	  time limitation, such as updating display configuration during the
> >  	  vblank.
> >  
> > +config MTK_DVFSRC
> > +	bool "MediaTek DVFSRC Support"
> > +	depends on ARCH_MEDIATEK
> > +	default ARCH_MEDIATEK
> > +	select MTK_INFRACFG
> > +	select PM_GENERIC_DOMAINS if PM
> > +	depends on MTK_SCPSYS
> > +	help
> > +	  Say yes here to add support for the MediaTek DVFSRC (dynamic voltage
> > +	  and frequency scaling resource collector) found
> > +	  on different MediaTek SoCs. The DVFSRC is a proprietary
> > +	  hardware which is used to collect all the requests from
> > +	  system and turn into the decision of minimum Vcore voltage
> > +	  and minimum DRAM frequency to fulfill those requests.
> > +
> >  config MTK_PMIC_WRAP
> >  	tristate "MediaTek PMIC Wrapper Support"
> >  	depends on RESET_CONTROLLER
> > diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> > index 2b2c2537..84182f0 100644
> > --- a/drivers/soc/mediatek/Makefile
> > +++ b/drivers/soc/mediatek/Makefile
> > @@ -1,4 +1,5 @@
> >  # SPDX-License-Identifier: GPL-2.0-only
> >  obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
> > +obj-$(CONFIG_MTK_DVFSRC) += mtk-dvfsrc.o
> >  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
> >  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> > diff --git a/drivers/soc/mediatek/mtk-dvfsrc.c b/drivers/soc/mediatek/mtk-dvfsrc.c
> > new file mode 100644
> > index 0000000..85b3572
> > --- /dev/null
> > +++ b/drivers/soc/mediatek/mtk-dvfsrc.c
> > @@ -0,0 +1,434 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2018 MediaTek Inc.
> > + */
> > +#include <linux/arm-smccc.h>
> > +#include <linux/clk.h>
> > +#include <linux/io.h>
> > +#include <linux/iopoll.h>
> > +#include <linux/module.h>
> > +#include <linux/notifier.h>
> > +#include <linux/of_device.h>
> > +#include <linux/platform_device.h>
> > +#include <soc/mediatek/mtk_dvfsrc.h>
> > +#include <soc/mediatek/mtk_sip.h>
> > +#include <dt-bindings/power/mt8183-power.h>
> 
> Looks like this depends on a header which is not part of this patch-set.
> It would be nice to list any dependencies in the cover letter.
> 
> Thanks,
> Georgi

I disregarded to list here. Thanks for your friendly reminder.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

end of thread, other threads:[~2020-04-02  2:50 UTC | newest]

Thread overview: 66+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-13  9:34 [PATCH V4 00/13] Add driver for dvfsrc, support for active state of scpsys Henry Chen
2020-03-13  9:34 ` Henry Chen
2020-03-13  9:34 ` Henry Chen
2020-03-13  9:34 ` [PATCH V4 01/13] dt-bindings: soc: Add dvfsrc driver bindings Henry Chen
2020-03-13  9:34   ` Henry Chen
2020-03-13  9:34   ` Henry Chen
2020-03-13  9:34 ` [PATCH V4 02/13] dt-bindings: soc: Add opp table on scpsys bindings Henry Chen
2020-03-13  9:34   ` Henry Chen
2020-03-13  9:34   ` Henry Chen
2020-03-13  9:34 ` [PATCH V4 03/13] soc: mediatek: add support for the performance state Henry Chen
2020-03-13  9:34   ` Henry Chen
2020-03-13  9:34   ` Henry Chen
2020-03-13  9:34 ` [PATCH V4 04/13] arm64: dts: mt8183: add performance state support of scpsys Henry Chen
2020-03-13  9:34   ` Henry Chen
2020-03-13  9:34   ` Henry Chen
2020-03-13  9:34 ` [PATCH V4 05/13] soc: mediatek: add header for mediatek SIP interface Henry Chen
2020-03-13  9:34   ` Henry Chen
2020-03-13  9:34   ` Henry Chen
2020-03-13  9:34 ` [PATCH V4 06/13] soc: mediatek: add MT8183 dvfsrc support Henry Chen
2020-03-13  9:34   ` Henry Chen
2020-03-13  9:34   ` Henry Chen
2020-04-01 14:41   ` Georgi Djakov
2020-04-01 14:41     ` Georgi Djakov
2020-04-01 14:41     ` Georgi Djakov
2020-04-02  2:48     ` Henry Chen
2020-04-02  2:48       ` Henry Chen
2020-04-02  2:48       ` Henry Chen
2020-03-13  9:34 ` [PATCH V4 07/13] arm64: dts: mt8183: add dvfsrc related nodes Henry Chen
2020-03-13  9:34   ` Henry Chen
2020-03-13  9:34   ` Henry Chen
2020-03-13  9:34 ` [PATCH V4 08/13] dt-bindings: interconnect: add MT8183 interconnect dt-bindings Henry Chen
2020-03-13  9:34   ` Henry Chen
2020-03-13  9:34   ` Henry Chen
2020-03-20 23:09   ` Rob Herring
2020-03-20 23:09     ` Rob Herring
2020-03-20 23:09     ` Rob Herring
2020-03-13  9:34 ` [PATCH V4 09/13] interconnect: mediatek: Add mt8183 interconnect provider driver Henry Chen
2020-03-13  9:34   ` Henry Chen
2020-03-13  9:34   ` Henry Chen
2020-04-01 14:55   ` Georgi Djakov
2020-04-01 14:55     ` Georgi Djakov
2020-04-01 14:55     ` Georgi Djakov
2020-04-02  2:48     ` Henry Chen
2020-04-02  2:48       ` Henry Chen
2020-04-02  2:48       ` Henry Chen
2020-03-13  9:34 ` [PATCH V4 10/13] arm64: dts: mt8183: add dvfsrc related nodes Henry Chen
2020-03-13  9:34   ` Henry Chen
2020-03-13  9:34   ` Henry Chen
2020-03-13  9:34 ` [PATCH V4 11/13] dt-bindings: regulator: add DVFSRC regulator dt-bindings Henry Chen
2020-03-13  9:34   ` Henry Chen
2020-03-24 20:38   ` Mark Brown
2020-03-24 20:38     ` Mark Brown
2020-03-24 20:38     ` Mark Brown
2020-03-30  5:19     ` Henry Chen
2020-03-30  5:19       ` Henry Chen
2020-03-30  5:19       ` Henry Chen
2020-03-13  9:34 ` [PATCH V4 12/13] regulator: Regulator driver for the Mediatek DVFSRC Henry Chen
2020-03-13  9:34   ` Henry Chen
2020-03-13  9:34 ` [PATCH V4 13/13] arm64: dts: mt8183: add dvfsrc regulator nodes Henry Chen
2020-03-13  9:34   ` Henry Chen
2020-04-01 15:09 ` [PATCH V4 00/13] Add driver for dvfsrc, support for active state of scpsys Georgi Djakov
2020-04-01 15:09   ` Georgi Djakov
2020-04-01 15:09   ` Georgi Djakov
2020-04-02  2:48   ` Henry Chen
2020-04-02  2:48     ` Henry Chen
2020-04-02  2:48     ` Henry Chen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.