Re: [PATCH v10] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2021-03-12 Thread Hector Yuan
On Sun, 2021-01-31 at 11:34 +0100, Matthias Brugger wrote:
> 
> On 29/12/2020 07:17, Hector Yuan wrote:
> > The CPUfreq HW present in some Mediatek chipsets offloads the steps 
> > necessary for changing the frequency of CPUs. 
> > The driver implements the cpufreq driver interface for this hardware 
> > engine. 
> > This patch depends on MT6779 DTS patchset[1] submitted by Hanks Chen.
> 
> This dependency got resolved, the patch is mainline since v5.11. Please delete
> it in further revisions of the patch set to minimize confusion.
> 
> Thanks!
> 
Thanks, I will remove this dependency in the next version. 
> > 
> > From v8 to v9, there are three more modifications.
> > 1. Based on patchset[2], align binding with scmi for performance domain.
> > 2. Add the CPUFREQ fast switch function support and define DVFS latency.
> > 3. Based on patchser[3], add energy model API parameter for mW.
> > 
> > From v7 to v8, there are three more patches based on patchset v8[4].
> > This patchset is about to register power table to Energy model for EAS and 
> > thermal usage.
> > 1. EM CPU power table
> > - Register energy model table for EAS and thermal cooling device usage.
> > - Read the coresponding LUT for power table.
> > 2. SVS initialization
> > - The SVS(Smart Voltage Scaling) engine is a hardware which is
> >   used to calculate optimized voltage values for CPU power domain.
> >   DVFS driver could apply those optimized voltage values to reduce power 
> > consumption.
> > - Driver will polling if HW engine is done for SVS initialization.
> >   After that, driver will read power table and register it to EAS.
> > - CPUs must be in power on state when doing SVS. Use pm_qos to block 
> > cpu-idle state for SVS initializing.
> > 3. Cooling device flag
> > - Add cooling device flag for thermal
> > 
> > [1]  https://lkml.org/lkml/2020/8/4/1094
> > [2]  
> > https://lore.kernel.org/lkml/20201116181356.804590-1-sudeep.ho...@arm.com/
> > [3]  
> > https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git/commit/?h=linux-next=c250d50fe2ce627ca9805d9c8ac11cbbf922a4a6
> > [4]  https://lkml.org/lkml/2020/9/23/384
> > 
> > 
> > Hector.Yuan (2):
> >   cpufreq: mediatek-hw: Add support for CPUFREQ HW
> >   dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW
> > 
> >  .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |  116 ++
> >  drivers/cpufreq/Kconfig.arm|   12 +
> >  drivers/cpufreq/Makefile   |1 +
> >  drivers/cpufreq/mediatek-cpufreq-hw.c  |  370 
> > 
> >  4 files changed, 499 insertions(+)
> >  create mode 100644 
> > Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> >  create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw.c
> > 



[PATCH v11 2/2] dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

2021-03-12 Thread Hector Yuan
From: "Hector.Yuan" 

Add devicetree bindings for MediaTek HW driver.

Signed-off-by: Hector.Yuan 
---
 .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |  127 
 1 file changed, 127 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml

diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml 
b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
new file mode 100644
index 000..0f3ad47
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
@@ -0,0 +1,127 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/cpufreq/cpufreq-mediatek-hw.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek's CPUFREQ Bindings
+
+maintainers:
+  - Hector Yuan 
+
+description:
+  CPUFREQ HW is a hardware engine used by MediaTek
+  SoCs to manage frequency in hardware. It is capable of controlling frequency
+  for multiple clusters.
+
+properties:
+  compatible:
+const: mediatek,cpufreq-hw
+
+  reg:
+minItems: 1
+maxItems: 2
+description: |
+  Addresses and sizes for the memory of the
+  HW bases in each frequency domain.
+
+  "#performance-domain-cells":
+description:
+  Number of cells in a performance domain specifier. Typically 0 for nodes
+  representing a single performance domain and 1 for nodes providing
+  multiple performance domains (e.g. performance controllers), but can be
+  any value as specified by device tree binding documentation of particular
+  provider.
+enum: [ 0, 1 ]
+
+required:
+  - compatible
+  - reg
+  - "#performance-domain-cells"
+
+additionalProperties: true
+
+examples:
+  - |
+cpus {
+#address-cells = <1>;
+#size-cells = <0>;
+
+cpu0: cpu@0 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+performance-domains = < 0>;
+reg = <0x000>;
+};
+
+cpu1: cpu@100 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+performance-domains = < 0>;
+reg = <0x100>;
+};
+
+cpu2: cpu@200 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+performance-domains = < 0>;
+reg = <0x200>;
+};
+
+cpu3: cpu@300 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+performance-domains = < 0>;
+reg = <0x300>;
+};
+
+cpu4: cpu@400 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+performance-domains = < 1>;
+reg = <0x400>;
+};
+
+cpu5: cpu@500 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+performance-domains = < 1>;
+reg = <0x500>;
+};
+
+cpu6: cpu@600 {
+device_type = "cpu";
+compatible = "arm,cortex-a75";
+enable-method = "psci";
+performance-domains = < 1>;
+reg = <0x600>;
+};
+
+cpu7: cpu@700 {
+device_type = "cpu";
+compatible = "arm,cortex-a75";
+enable-method = "psci";
+performance-domains = < 1>;
+reg = <0x700>;
+};
+};
+
+/* ... */
+
+soc {
+#address-cells = <2>;
+#size-cells = <2>;
+
+performance: performance-controller@11bc00 {
+compatible = "mediatek,cpufreq-hw";
+reg = <0 0x0011bc10 0 0x120>, <0 0x0011bd30 0 0x120>;
+
+#performance-domain-cells = <1>;
+};
+};
-- 
1.7.9.5



[PATCH v11 1/2] cpufreq: mediatek-hw: Add support for CPUFREQ HW

2021-03-12 Thread Hector Yuan
From: "Hector.Yuan" 

Add cpufreq HW support.

Signed-off-by: Hector.Yuan 
---
 drivers/cpufreq/Kconfig.arm   |   12 ++
 drivers/cpufreq/Makefile  |1 +
 drivers/cpufreq/mediatek-cpufreq-hw.c |  370 +
 3 files changed, 383 insertions(+)
 create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw.c

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index e65e0a4..1b950a8 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -123,6 +123,18 @@ config ARM_MEDIATEK_CPUFREQ
help
  This adds the CPUFreq driver support for MediaTek SoCs.
 
+config ARM_MEDIATEK_CPUFREQ_HW
+   tristate "MediaTek CPUFreq HW driver"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   default m
+   help
+ Support for the CPUFreq HW driver.
+ Some MediaTek chipsets have a HW engine to offload the steps
+ necessary for changing the frequency of the CPUs. Firmware loaded
+ in this engine exposes a programming interface to the OS.
+ The driver implements the cpufreq interface for this HW engine.
+ Say Y if you want to support CPUFreq HW.
+
 config ARM_OMAP2PLUS_CPUFREQ
bool "TI OMAP2+"
depends on ARCH_OMAP2PLUS
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 27d3bd7..48ee585 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ)   += 
imx6q-cpufreq.o
 obj-$(CONFIG_ARM_IMX_CPUFREQ_DT)   += imx-cpufreq-dt.o
 obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o
 obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ) += mediatek-cpufreq.o
+obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ_HW)  += mediatek-cpufreq-hw.o
 obj-$(CONFIG_MACH_MVEBU_V7)+= mvebu-cpufreq.o
 obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)+= omap-cpufreq.o
 obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)   += pxa2xx-cpufreq.o
diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c 
b/drivers/cpufreq/mediatek-cpufreq-hw.c
new file mode 100644
index 000..6f3a461
--- /dev/null
+++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
@@ -0,0 +1,370 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define LUT_MAX_ENTRIES32U
+#define LUT_FREQ   GENMASK(11, 0)
+#define LUT_ROW_SIZE   0x4
+#define CPUFREQ_HW_STATUS  BIT(0)
+#define SVS_HW_STATUS  BIT(1)
+#define POLL_USEC  1000
+#define TIMEOUT_USEC   30
+
+enum {
+   REG_FREQ_LUT_TABLE,
+   REG_FREQ_ENABLE,
+   REG_FREQ_PERF_STATE,
+   REG_FREQ_HW_STATE,
+   REG_EM_POWER_TBL,
+   REG_FREQ_LATENCY,
+
+   REG_ARRAY_SIZE,
+};
+
+struct cpufreq_mtk {
+   struct cpufreq_frequency_table *table;
+   void __iomem *reg_bases[REG_ARRAY_SIZE];
+   int nr_opp;
+   cpumask_t related_cpus;
+};
+
+static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = {
+   [REG_FREQ_LUT_TABLE]= 0x0,
+   [REG_FREQ_ENABLE]   = 0x84,
+   [REG_FREQ_PERF_STATE]   = 0x88,
+   [REG_FREQ_HW_STATE] = 0x8c,
+   [REG_EM_POWER_TBL]  = 0x90,
+   [REG_FREQ_LATENCY]  = 0x110,
+};
+
+static struct cpufreq_mtk *mtk_freq_domain_map[NR_CPUS];
+
+static int __maybe_unused
+mtk_cpufreq_get_cpu_power(unsigned long *mW,
+ unsigned long *KHz, struct device *cpu_dev)
+{
+   struct cpufreq_mtk *c = mtk_freq_domain_map[cpu_dev->id];
+   int i;
+
+   for (i = 0; i < c->nr_opp; i++) {
+   if (c->table[i].frequency < *KHz)
+   break;
+   }
+   i--;
+
+   *KHz = c->table[i].frequency;
+   *mW = readl_relaxed(c->reg_bases[REG_EM_POWER_TBL] +
+   i * LUT_ROW_SIZE) / 1000;
+
+   return 0;
+}
+
+static int mtk_cpufreq_hw_target_index(struct cpufreq_policy *policy,
+  unsigned int index)
+{
+   struct cpufreq_mtk *c = policy->driver_data;
+
+   writel_relaxed(index, c->reg_bases[REG_FREQ_PERF_STATE]);
+
+   return 0;
+}
+
+static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)
+{
+   struct cpufreq_mtk *c;
+   unsigned int index;
+
+   c = mtk_freq_domain_map[cpu];
+
+   index = readl_relaxed(c->reg_bases[REG_FREQ_PERF_STATE]);
+   index = min(index, LUT_MAX_ENTRIES - 1);
+
+   return c->table[index].frequency;
+}
+
+static unsigned int mtk_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
+  unsigned int target_freq)
+{
+   struct cpufreq_mtk *c = policy->driver_data;
+   unsigned int index;
+
+   index = cpufreq_table_find_index_dl(policy, target_freq);
+
+   writel_relaxed(index, c->reg_bases[REG_FREQ_PERF_STATE]);
+
+   

[PATCH v11] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2021-03-12 Thread Hector Yuan
The CPUfreq HW present in some Mediatek chipsets offloads the steps necessary 
for changing the frequency of CPUs. 
The driver implements the cpufreq driver interface for this hardware engine. 

>From v8 to v9, there are three more modifications.
1. Based on patchset[1], align binding with scmi for performance domain.
2. Add the CPUFREQ fast switch function support and define DVFS latency.
3. Based on patchser[2], add energy model API parameter for mW.

>From v7 to v8, there are three more patches based on patchset v8[3].
This patchset is about to register power table to Energy model for EAS and 
thermal usage.
1. EM CPU power table
- Register energy model table for EAS and thermal cooling device usage.
- Read the coresponding LUT for power table.
2. SVS initialization
- The SVS(Smart Voltage Scaling) engine is a hardware which is
  used to calculate optimized voltage values for CPU power domain.
  DVFS driver could apply those optimized voltage values to reduce power 
consumption.
- Driver will polling if HW engine is done for SVS initialization.
  After that, driver will read power table and register it to EAS.
- CPUs must be in power on state when doing SVS. Use pm_qos to block cpu-idle 
state for SVS initializing.
3. Cooling device flag
- Add cooling device flag for thermal

[1]  https://lore.kernel.org/lkml/20201116181356.804590-1-sudeep.ho...@arm.com/
[2]  
https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git/commit/?h=linux-next=c250d50fe2ce627ca9805d9c8ac11cbbf922a4a6
[3]  https://lkml.org/lkml/2020/9/23/384


Hector.Yuan (2):
  cpufreq: mediatek-hw: Add support for CPUFREQ HW
  dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

 .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |  127 +++
 drivers/cpufreq/Kconfig.arm|   12 +
 drivers/cpufreq/Makefile   |1 +
 drivers/cpufreq/mediatek-cpufreq-hw.c  |  370 
 4 files changed, 510 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
 create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw.c


[PATCH v10 1/2] cpufreq: mediatek-hw: Add support for CPUFREQ HW

2020-12-28 Thread Hector Yuan
From: "Hector.Yuan" 

Add cpufreq HW support.

Signed-off-by: Hector.Yuan 
---
 drivers/cpufreq/Kconfig.arm   |   12 ++
 drivers/cpufreq/Makefile  |1 +
 drivers/cpufreq/mediatek-cpufreq-hw.c |  370 +
 3 files changed, 383 insertions(+)
 create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw.c

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 015ec0c..3031471 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -123,6 +123,18 @@ config ARM_MEDIATEK_CPUFREQ
help
  This adds the CPUFreq driver support for MediaTek SoCs.
 
+config ARM_MEDIATEK_CPUFREQ_HW
+   tristate "MediaTek CPUFreq HW driver"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   default m
+   help
+ Support for the CPUFreq HW driver.
+ Some MediaTek chipsets have a HW engine to offload the steps
+ necessary for changing the frequency of the CPUs. Firmware loaded
+ in this engine exposes a programming interface to the OS.
+ The driver implements the cpufreq interface for this HW engine.
+ Say Y if you want to support CPUFreq HW.
+
 config ARM_OMAP2PLUS_CPUFREQ
bool "TI OMAP2+"
depends on ARCH_OMAP2PLUS
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index f1b7e3d..ffc61cd 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ)   += 
imx6q-cpufreq.o
 obj-$(CONFIG_ARM_IMX_CPUFREQ_DT)   += imx-cpufreq-dt.o
 obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o
 obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ) += mediatek-cpufreq.o
+obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ_HW)  += mediatek-cpufreq-hw.o
 obj-$(CONFIG_MACH_MVEBU_V7)+= mvebu-cpufreq.o
 obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)+= omap-cpufreq.o
 obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)   += pxa2xx-cpufreq.o
diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c 
b/drivers/cpufreq/mediatek-cpufreq-hw.c
new file mode 100644
index 000..604af18
--- /dev/null
+++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
@@ -0,0 +1,370 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define LUT_MAX_ENTRIES32U
+#define LUT_FREQ   GENMASK(11, 0)
+#define LUT_ROW_SIZE   0x4
+#define CPUFREQ_HW_STATUS  BIT(0)
+#define SVS_HW_STATUS  BIT(1)
+#define POLL_USEC  1000
+#define TIMEOUT_USEC   30
+
+enum {
+   REG_FREQ_LUT_TABLE,
+   REG_FREQ_ENABLE,
+   REG_FREQ_PERF_STATE,
+   REG_FREQ_HW_STATE,
+   REG_EM_POWER_TBL,
+   REG_FREQ_LATENCY,
+
+   REG_ARRAY_SIZE,
+};
+
+struct cpufreq_mtk {
+   struct cpufreq_frequency_table *table;
+   void __iomem *reg_bases[REG_ARRAY_SIZE];
+   int nr_opp;
+   cpumask_t related_cpus;
+};
+
+static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = {
+   [REG_FREQ_LUT_TABLE]= 0x0,
+   [REG_FREQ_ENABLE]   = 0x84,
+   [REG_FREQ_PERF_STATE]   = 0x88,
+   [REG_FREQ_HW_STATE] = 0x8c,
+   [REG_EM_POWER_TBL]  = 0x90,
+   [REG_FREQ_LATENCY]  = 0x110,
+};
+
+static struct cpufreq_mtk *mtk_freq_domain_map[NR_CPUS];
+
+static int __maybe_unused
+mtk_cpufreq_get_cpu_power(unsigned long *mW,
+ unsigned long *KHz, struct device *cpu_dev)
+{
+   struct cpufreq_mtk *c = mtk_freq_domain_map[cpu_dev->id];
+   int i;
+
+   for (i = 0; i < c->nr_opp; i++) {
+   if (c->table[i].frequency < *KHz)
+   break;
+   }
+   i--;
+
+   *KHz = c->table[i].frequency;
+   *mW = readl_relaxed(c->reg_bases[REG_EM_POWER_TBL] +
+   i * LUT_ROW_SIZE) / 1000;
+
+   return 0;
+}
+
+static int mtk_cpufreq_hw_target_index(struct cpufreq_policy *policy,
+  unsigned int index)
+{
+   struct cpufreq_mtk *c = policy->driver_data;
+
+   writel_relaxed(index, c->reg_bases[REG_FREQ_PERF_STATE]);
+
+   return 0;
+}
+
+static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)
+{
+   struct cpufreq_mtk *c;
+   unsigned int index;
+
+   c = mtk_freq_domain_map[cpu];
+
+   index = readl_relaxed(c->reg_bases[REG_FREQ_PERF_STATE]);
+   index = min(index, LUT_MAX_ENTRIES - 1);
+
+   return c->table[index].frequency;
+}
+
+static unsigned int mtk_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
+  unsigned int target_freq)
+{
+   struct cpufreq_mtk *c = policy->driver_data;
+   unsigned int index;
+
+   index = cpufreq_table_find_index_dl(policy, target_freq);
+
+   writel_relaxed(index, c->reg_bases[REG_FREQ_PERF_STATE]);
+
+   

[PATCH v10] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2020-12-28 Thread Hector Yuan
The CPUfreq HW present in some Mediatek chipsets offloads the steps necessary 
for changing the frequency of CPUs. 
The driver implements the cpufreq driver interface for this hardware engine. 
This patch depends on MT6779 DTS patchset[1] submitted by Hanks Chen.

>From v8 to v9, there are three more modifications.
1. Based on patchset[2], align binding with scmi for performance domain.
2. Add the CPUFREQ fast switch function support and define DVFS latency.
3. Based on patchser[3], add energy model API parameter for mW.

>From v7 to v8, there are three more patches based on patchset v8[4].
This patchset is about to register power table to Energy model for EAS and 
thermal usage.
1. EM CPU power table
- Register energy model table for EAS and thermal cooling device usage.
- Read the coresponding LUT for power table.
2. SVS initialization
- The SVS(Smart Voltage Scaling) engine is a hardware which is
  used to calculate optimized voltage values for CPU power domain.
  DVFS driver could apply those optimized voltage values to reduce power 
consumption.
- Driver will polling if HW engine is done for SVS initialization.
  After that, driver will read power table and register it to EAS.
- CPUs must be in power on state when doing SVS. Use pm_qos to block cpu-idle 
state for SVS initializing.
3. Cooling device flag
- Add cooling device flag for thermal

[1]  https://lkml.org/lkml/2020/8/4/1094
[2]  https://lore.kernel.org/lkml/20201116181356.804590-1-sudeep.ho...@arm.com/
[3]  
https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git/commit/?h=linux-next=c250d50fe2ce627ca9805d9c8ac11cbbf922a4a6
[4]  https://lkml.org/lkml/2020/9/23/384


Hector.Yuan (2):
  cpufreq: mediatek-hw: Add support for CPUFREQ HW
  dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

 .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |  116 ++
 drivers/cpufreq/Kconfig.arm|   12 +
 drivers/cpufreq/Makefile   |1 +
 drivers/cpufreq/mediatek-cpufreq-hw.c  |  370 
 4 files changed, 499 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
 create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw.c



[PATCH v10 2/2] dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

2020-12-28 Thread Hector Yuan
From: "Hector.Yuan" 

Add devicetree bindings for MediaTek HW driver.

Signed-off-by: Hector.Yuan 
---
 .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |  116 
 1 file changed, 116 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml

diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml 
b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
new file mode 100644
index 000..53e0eb3
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
@@ -0,0 +1,116 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/cpufreq/cpufreq-mediatek-hw.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek's CPUFREQ Bindings
+
+maintainers:
+  - Hector Yuan 
+
+description:
+  CPUFREQ HW is a hardware engine used by MediaTek
+  SoCs to manage frequency in hardware. It is capable of controlling frequency
+  for multiple clusters.
+
+properties:
+  compatible:
+const: mediatek,cpufreq-hw
+
+  reg:
+minItems: 1
+maxItems: 2
+description: |
+  Addresses and sizes for the memory of the
+  HW bases in each frequency domain.
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: true
+
+examples:
+  - |
+cpus {
+#address-cells = <1>;
+#size-cells = <0>;
+
+cpu0: cpu@0 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+performance-domains = < 0>;
+reg = <0x000>;
+};
+
+cpu1: cpu@100 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+performance-domains = < 0>;
+reg = <0x100>;
+};
+
+cpu2: cpu@200 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+performance-domains = < 0>;
+reg = <0x200>;
+};
+
+cpu3: cpu@300 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+performance-domains = < 0>;
+reg = <0x300>;
+};
+
+cpu4: cpu@400 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+performance-domains = < 1>;
+reg = <0x400>;
+};
+
+cpu5: cpu@500 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+performance-domains = < 1>;
+reg = <0x500>;
+};
+
+cpu6: cpu@600 {
+device_type = "cpu";
+compatible = "arm,cortex-a75";
+enable-method = "psci";
+performance-domains = < 1>;
+reg = <0x600>;
+};
+
+cpu7: cpu@700 {
+device_type = "cpu";
+compatible = "arm,cortex-a75";
+enable-method = "psci";
+performance-domains = < 1>;
+reg = <0x700>;
+};
+};
+
+/* ... */
+
+soc {
+#address-cells = <2>;
+#size-cells = <2>;
+
+performance: performance-controller@11bc00 {
+compatible = "mediatek,cpufreq-hw";
+reg = <0 0x0011bc10 0 0x120>, <0 0x0011bd30 0 0x120>;
+#performance-domain-cells = <1>;
+};
+};
-- 
1.7.9.5



[PATCH v9] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2020-12-09 Thread Hector Yuan
The CPUfreq HW present in some Mediatek chipsets offloads the steps necessary 
for changing the frequency of CPUs. 
The driver implements the cpufreq driver interface for this hardware engine. 
This patch depends on MT6779 DTS patchset[1] submitted by Hanks Chen.

>From v8 to v9, there are three more modifications.
1. Based on patchset[2], align binding with scmi for performance domain.
2. Add the CPUFREQ fast switch function support and define DVFS latency.
3. Based on patchser[3], add energy model API parameter for mW.

>From v7 to v8, there are three more patches based on patchset v8[4].
This patchset is about to register power table to Energy model for EAS and 
thermal usage.
1. EM CPU power table
- Register energy model table for EAS and thermal cooling device usage.
- Read the coresponding LUT for power table.
2. SVS initialization
- The SVS(Smart Voltage Scaling) engine is a hardware which is
  used to calculate optimized voltage values for CPU power domain.
  DVFS driver could apply those optimized voltage values to reduce power 
consumption.
- Driver will polling if HW engine is done for SVS initialization.
  After that, driver will read power table and register it to EAS.
- CPUs must be in power on state when doing SVS. Use pm_qos to block cpu-idle 
state for SVS initializing.
3. Cooling device flag
- Add cooling device flag for thermal

[1]  https://lkml.org/lkml/2020/8/4/1094
[2]  https://lore.kernel.org/lkml/20201116181356.804590-1-sudeep.ho...@arm.com/
[3]  
https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git/commit/?h=linux-next=c250d50fe2ce627ca9805d9c8ac11cbbf922a4a6
[4]  https://lkml.org/lkml/2020/9/23/384


Hector.Yuan (2):
  cpufreq: mediatek-hw: Add support for CPUFREQ HW
  dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

 .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |  112 ++
 drivers/cpufreq/Kconfig.arm|   12 +
 drivers/cpufreq/Makefile   |1 +
 drivers/cpufreq/mediatek-cpufreq-hw.c  |  370 
 4 files changed, 495 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
 create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw.c



[PATCH v9 1/2] cpufreq: mediatek-hw: Add support for CPUFREQ HW

2020-12-09 Thread Hector Yuan
From: "Hector.Yuan" 

Add cpufreq HW support.

Signed-off-by: Hector.Yuan 
---
 drivers/cpufreq/Kconfig.arm   |   12 ++
 drivers/cpufreq/Makefile  |1 +
 drivers/cpufreq/mediatek-cpufreq-hw.c |  370 +
 3 files changed, 383 insertions(+)
 create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw.c

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 015ec0c..3031471 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -123,6 +123,18 @@ config ARM_MEDIATEK_CPUFREQ
help
  This adds the CPUFreq driver support for MediaTek SoCs.
 
+config ARM_MEDIATEK_CPUFREQ_HW
+   tristate "MediaTek CPUFreq HW driver"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   default m
+   help
+ Support for the CPUFreq HW driver.
+ Some MediaTek chipsets have a HW engine to offload the steps
+ necessary for changing the frequency of the CPUs. Firmware loaded
+ in this engine exposes a programming interface to the OS.
+ The driver implements the cpufreq interface for this HW engine.
+ Say Y if you want to support CPUFreq HW.
+
 config ARM_OMAP2PLUS_CPUFREQ
bool "TI OMAP2+"
depends on ARCH_OMAP2PLUS
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index f1b7e3d..ffc61cd 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ)   += 
imx6q-cpufreq.o
 obj-$(CONFIG_ARM_IMX_CPUFREQ_DT)   += imx-cpufreq-dt.o
 obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o
 obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ) += mediatek-cpufreq.o
+obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ_HW)  += mediatek-cpufreq-hw.o
 obj-$(CONFIG_MACH_MVEBU_V7)+= mvebu-cpufreq.o
 obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)+= omap-cpufreq.o
 obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)   += pxa2xx-cpufreq.o
diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c 
b/drivers/cpufreq/mediatek-cpufreq-hw.c
new file mode 100644
index 000..604af18
--- /dev/null
+++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
@@ -0,0 +1,370 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define LUT_MAX_ENTRIES32U
+#define LUT_FREQ   GENMASK(11, 0)
+#define LUT_ROW_SIZE   0x4
+#define CPUFREQ_HW_STATUS  BIT(0)
+#define SVS_HW_STATUS  BIT(1)
+#define POLL_USEC  1000
+#define TIMEOUT_USEC   30
+
+enum {
+   REG_FREQ_LUT_TABLE,
+   REG_FREQ_ENABLE,
+   REG_FREQ_PERF_STATE,
+   REG_FREQ_HW_STATE,
+   REG_EM_POWER_TBL,
+   REG_FREQ_LATENCY,
+
+   REG_ARRAY_SIZE,
+};
+
+struct cpufreq_mtk {
+   struct cpufreq_frequency_table *table;
+   void __iomem *reg_bases[REG_ARRAY_SIZE];
+   int nr_opp;
+   cpumask_t related_cpus;
+};
+
+static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = {
+   [REG_FREQ_LUT_TABLE]= 0x0,
+   [REG_FREQ_ENABLE]   = 0x84,
+   [REG_FREQ_PERF_STATE]   = 0x88,
+   [REG_FREQ_HW_STATE] = 0x8c,
+   [REG_EM_POWER_TBL]  = 0x90,
+   [REG_FREQ_LATENCY]  = 0x110,
+};
+
+static struct cpufreq_mtk *mtk_freq_domain_map[NR_CPUS];
+
+static int __maybe_unused
+mtk_cpufreq_get_cpu_power(unsigned long *mW,
+ unsigned long *KHz, struct device *cpu_dev)
+{
+   struct cpufreq_mtk *c = mtk_freq_domain_map[cpu_dev->id];
+   int i;
+
+   for (i = 0; i < c->nr_opp; i++) {
+   if (c->table[i].frequency < *KHz)
+   break;
+   }
+   i--;
+
+   *KHz = c->table[i].frequency;
+   *mW = readl_relaxed(c->reg_bases[REG_EM_POWER_TBL] +
+   i * LUT_ROW_SIZE) / 1000;
+
+   return 0;
+}
+
+static int mtk_cpufreq_hw_target_index(struct cpufreq_policy *policy,
+  unsigned int index)
+{
+   struct cpufreq_mtk *c = policy->driver_data;
+
+   writel_relaxed(index, c->reg_bases[REG_FREQ_PERF_STATE]);
+
+   return 0;
+}
+
+static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)
+{
+   struct cpufreq_mtk *c;
+   unsigned int index;
+
+   c = mtk_freq_domain_map[cpu];
+
+   index = readl_relaxed(c->reg_bases[REG_FREQ_PERF_STATE]);
+   index = min(index, LUT_MAX_ENTRIES - 1);
+
+   return c->table[index].frequency;
+}
+
+static unsigned int mtk_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
+  unsigned int target_freq)
+{
+   struct cpufreq_mtk *c = policy->driver_data;
+   unsigned int index;
+
+   index = cpufreq_table_find_index_dl(policy, target_freq);
+
+   writel_relaxed(index, c->reg_bases[REG_FREQ_PERF_STATE]);
+
+   

[PATCH v9 2/2] dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

2020-12-09 Thread Hector Yuan
From: "Hector.Yuan" 

Add devicetree bindings for MediaTek HW driver.

Signed-off-by: Hector.Yuan 
---
 .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |  112 
 1 file changed, 112 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml

diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml 
b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
new file mode 100644
index 000..1ce2a17
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
@@ -0,0 +1,112 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/cpufreq/cpufreq-mediatek-hw.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek's CPUFREQ Bindings
+
+maintainers:
+  - Hector Yuan 
+
+description:
+  CPUFREQ HW is a hardware engine used by MediaTek
+  SoCs to manage frequency in hardware. It is capable of controlling frequency
+  for multiple clusters.
+
+properties:
+  compatible:
+const: mediatek,cpufreq-hw
+
+  reg:
+minItems: 1
+maxItems: 2
+description: |
+  Addresses and sizes for the memory of the HW bases in each frequency 
domain.
+
+required:
+  - compatible
+  - reg
+
+examples:
+  - |
+cpus {
+#address-cells = <1>;
+#size-cells = <0>;
+
+cpu0: cpu@0 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+performance-domains = < 0>;
+reg = <0x000>;
+};
+
+cpu1: cpu@100 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+performance-domains = < 0>;
+reg = <0x100>;
+};
+
+cpu2: cpu@200 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+performance-domains = < 0>;
+reg = <0x200>;
+};
+
+cpu3: cpu@300 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+performance-domains = < 0>;
+reg = <0x300>;
+};
+
+cpu4: cpu@400 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+performance-domains = < 1>;
+reg = <0x400>;
+};
+
+cpu5: cpu@500 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+performance-domains = < 1>;
+reg = <0x500>;
+};
+
+cpu6: cpu@600 {
+device_type = "cpu";
+compatible = "arm,cortex-a75";
+enable-method = "psci";
+performance-domains = < 1>;
+reg = <0x600>;
+};
+
+cpu7: cpu@700 {
+device_type = "cpu";
+compatible = "arm,cortex-a75";
+enable-method = "psci";
+performance-domains = < 1>;
+reg = <0x700>;
+};
+};
+
+/* ... */
+
+soc {
+#address-cells = <2>;
+#size-cells = <2>;
+performance: performance-controller@11bc00 {
+compatible = "mediatek,cpufreq-hw";
+reg = <0 0x0011bc10 0 0x120>, <0 0x0011bd30 0 0x120>;
+#performance-domain-cells = <1>;
+};
+};
-- 
1.7.9.5



Re: [PATCH v8 1/3] cpufreq: mediatek-hw: Add support for CPUFREQ HW

2020-11-19 Thread Hector Yuan
On Thu, 2020-11-19 at 12:41 +, Lukasz Luba wrote:
> Hi Hector,
> 
> On 10/26/20 8:19 AM, Hector Yuan wrote:
> > From: "Hector.Yuan" 
> > 
> > Add cpufreq HW support.
> > 
> > Signed-off-by: Hector.Yuan 
> 
> [snip]
> 
> > +
> > +static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
> > +{
> > +   struct cpufreq_mtk *c;
> > +   struct device *cpu_dev;
> > +   struct em_data_callback em_cb = EM_DATA_CB(mtk_cpufreq_get_cpu_power);
> > +   struct pm_qos_request *qos_request;
> > +   int sig, pwr_hw = CPUFREQ_HW_STATUS | SVS_HW_STATUS;
> > +
> > +   qos_request = kzalloc(sizeof(*qos_request), GFP_KERNEL);
> > +   if (!qos_request)
> > +   return -ENOMEM;
> > +
> > +   cpu_dev = get_cpu_device(policy->cpu);
> > +   if (!cpu_dev) {
> > +   pr_err("failed to get cpu%d device\n", policy->cpu);
> > +   return -ENODEV;
> > +   }
> > +
> > +   c = mtk_freq_domain_map[policy->cpu];
> > +   if (!c) {
> > +   pr_err("No scaling support for CPU%d\n", policy->cpu);
> > +   return -ENODEV;
> > +   }
> > +
> > +   cpumask_copy(policy->cpus, >related_cpus);
> > +
> > +   policy->freq_table = c->table;
> > +   policy->driver_data = c;
> 
> To control frequency transition rate in schedutil, you might
> be interested in setting:
> 
> policy->cpuinfo.transition_latency = ;
> 
> Example, when this latency value comes from FW [1]
> 
OK, I will add it in v9.
> > +
> > +   /* Let CPUs leave idle-off state for SVS CPU initializing */
> > +   cpu_latency_qos_add_request(qos_request, 0);
> > +
> > +   /* HW should be in enabled state to proceed now */
> > +   writel_relaxed(0x1, c->reg_bases[REG_FREQ_ENABLE]);
> > +
> > +   if (readl_poll_timeout(c->reg_bases[REG_FREQ_HW_STATE], sig,
> > +  (sig & pwr_hw) == pwr_hw, POLL_USEC,
> > +  TIMEOUT_USEC)) {
> > +   if (!(sig & CPUFREQ_HW_STATUS)) {
> > +   pr_info("cpufreq hardware of CPU%d is not enabled\n",
> > +   policy->cpu);
> > +   return -ENODEV;
> > +   }
> > +
> > +   pr_info("SVS of CPU%d is not enabled\n", policy->cpu);
> > +   }
> > +
> > +   em_dev_register_perf_domain(cpu_dev, c->nr_opp, _cb, policy->cpus);
> 
> Please keep in mind that this is going to be changed soon with a new
> argument: 'milliwatts'. It's queued in pm/linux-next [2].
> 
OK, thanks for the remind.
> Regards,
> Lukasz
> 
> [1] 
> https://elixir.bootlin.com/linux/latest/source/drivers/cpufreq/scmi-cpufreq.c#L194
> [2] 
> https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git/commit/?h=linux-next=c250d50fe2ce627ca9805d9c8ac11cbbf922a4a6
> 



[PATCH v8 1/3] cpufreq: mediatek-hw: Add support for CPUFREQ HW

2020-10-26 Thread Hector Yuan
From: "Hector.Yuan" 

Add cpufreq HW support.

Signed-off-by: Hector.Yuan 
---
 drivers/cpufreq/Kconfig.arm   |   12 ++
 drivers/cpufreq/Makefile  |1 +
 drivers/cpufreq/mediatek-cpufreq-hw.c |  343 +
 3 files changed, 356 insertions(+)
 create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw.c

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index cb72fb5..b9d17c5 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -123,6 +123,18 @@ config ARM_MEDIATEK_CPUFREQ
help
  This adds the CPUFreq driver support for MediaTek SoCs.
 
+config ARM_MEDIATEK_CPUFREQ_HW
+   tristate "MediaTek CPUFreq HW driver"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   default m
+   help
+ Support for the CPUFreq HW driver.
+ Some MediaTek chipsets have a HW engine to offload the steps
+ necessary for changing the frequency of the CPUs. Firmware loaded
+ in this engine exposes a programming interface to the OS.
+ The driver implements the cpufreq interface for this HW engine.
+ Say Y if you want to support CPUFreq HW.
+
 config ARM_OMAP2PLUS_CPUFREQ
bool "TI OMAP2+"
depends on ARCH_OMAP2PLUS
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index f1b7e3d..ffc61cd 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ)   += 
imx6q-cpufreq.o
 obj-$(CONFIG_ARM_IMX_CPUFREQ_DT)   += imx-cpufreq-dt.o
 obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o
 obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ) += mediatek-cpufreq.o
+obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ_HW)  += mediatek-cpufreq-hw.o
 obj-$(CONFIG_MACH_MVEBU_V7)+= mvebu-cpufreq.o
 obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)+= omap-cpufreq.o
 obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)   += pxa2xx-cpufreq.o
diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c 
b/drivers/cpufreq/mediatek-cpufreq-hw.c
new file mode 100644
index 000..3af36b0
--- /dev/null
+++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
@@ -0,0 +1,343 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define LUT_MAX_ENTRIES32U
+#define LUT_FREQ   GENMASK(11, 0)
+#define LUT_ROW_SIZE   0x4
+#define CPUFREQ_HW_STATUS  BIT(0)
+#define SVS_HW_STATUS  BIT(1)
+#define POLL_USEC  1000
+#define TIMEOUT_USEC   30
+
+enum {
+   REG_FREQ_LUT_TABLE,
+   REG_FREQ_ENABLE,
+   REG_FREQ_PERF_STATE,
+   REG_FREQ_HW_STATE,
+   REG_EM_POWER_TBL,
+
+   REG_ARRAY_SIZE,
+};
+
+struct cpufreq_mtk {
+   struct cpufreq_frequency_table *table;
+   void __iomem *reg_bases[REG_ARRAY_SIZE];
+   int nr_opp;
+   cpumask_t related_cpus;
+};
+
+static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = {
+   [REG_FREQ_LUT_TABLE]= 0x0,
+   [REG_FREQ_ENABLE]   = 0x84,
+   [REG_FREQ_PERF_STATE]   = 0x88,
+   [REG_FREQ_HW_STATE] = 0x8c,
+   [REG_EM_POWER_TBL]  = 0x3D0,
+};
+
+static struct cpufreq_mtk *mtk_freq_domain_map[NR_CPUS];
+
+static int mtk_cpufreq_get_cpu_power(unsigned long *mW,
+unsigned long *KHz, struct device *cpu_dev)
+{
+   struct cpufreq_mtk *c = mtk_freq_domain_map[cpu_dev->id];
+   int i;
+
+   for (i = 0; i < c->nr_opp; i++) {
+   if (c->table[i].frequency < *KHz)
+   break;
+   }
+   i--;
+
+   *KHz = c->table[i].frequency;
+   *mW = readl_relaxed(c->reg_bases[REG_EM_POWER_TBL] +
+   i * LUT_ROW_SIZE) / 1000;
+
+   return 0;
+}
+
+static int mtk_cpufreq_hw_target_index(struct cpufreq_policy *policy,
+  unsigned int index)
+{
+   struct cpufreq_mtk *c = policy->driver_data;
+
+   writel_relaxed(index, c->reg_bases[REG_FREQ_PERF_STATE]);
+
+   return 0;
+}
+
+static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)
+{
+   struct cpufreq_mtk *c;
+   unsigned int index;
+
+   c = mtk_freq_domain_map[cpu];
+
+   index = readl_relaxed(c->reg_bases[REG_FREQ_PERF_STATE]);
+   index = min(index, LUT_MAX_ENTRIES - 1);
+
+   return c->table[index].frequency;
+}
+
+static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
+{
+   struct cpufreq_mtk *c;
+   struct device *cpu_dev;
+   struct em_data_callback em_cb = EM_DATA_CB(mtk_cpufreq_get_cpu_power);
+   struct pm_qos_request *qos_request;
+   int sig, pwr_hw = CPUFREQ_HW_STATUS | SVS_HW_STATUS;
+
+   qos_request = kzalloc(sizeof(*qos_request), GFP_KERNEL);
+   if (!qos_request)
+   return -ENOMEM;
+
+   

[PATCH v8] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2020-10-26 Thread Hector Yuan
The CPUfreq HW present in some Mediatek chipsets offloads the steps necessary 
for changing the frequency of CPUs. 
The driver implements the cpufreq driver interface for this hardware engine. 
This patch depends on MT6779 DTS patch[1] submitted by Hanks Chen.

From v7 to v8, there are three more patches based on patchset[2].
This patchset is about to register power table to Energy model for EAS and 
thermal usage.
1. EM CPU power table
- Register energy model table for EAS and thermal cooling device usage.
- Read the coresponding LUT for power table.
2. SVS initialization
- The SVS(Smart Voltage Scaling) engine is a hardware which is
  used to calculate optimized voltage values for CPU power domain.
  DVFS driver could apply those optimized voltage values to reduce power 
consumption.
- Driver will polling if HW engine is done for SVS initialization.
  After that, driver will read power table and register it to EAS.
- CPUs must be in power on state when doing SVS. Use pm_qos to block cpu-idle 
state for SVS initializing.
3. Cooling device flag
- Add cooling device flag for thermal

[1] https://lkml.org/lkml/2020/8/4/1094
[2] https://lkml.org/lkml/2020/9/23/384


Hector.Yuan (3):
  cpufreq: mediatek-hw: Add support for CPUFREQ HW
  dt-bindings: arm: cpus: Document 'mediatek,freq-domain' property
  dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

 Documentation/devicetree/bindings/arm/cpus.yaml|6 +
 .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |  113 +++
 drivers/cpufreq/Kconfig.arm|   12 +
 drivers/cpufreq/Makefile   |1 +
 drivers/cpufreq/mediatek-cpufreq-hw.c  |  343 
 5 files changed, 475 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
 create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw.c

[PATCH v8 3/3] dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

2020-10-26 Thread Hector Yuan
From: "Hector.Yuan" 

Add devicetree bindings for MediaTek HW driver.

Signed-off-by: Hector.Yuan 
---
 .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |  113 
 1 file changed, 113 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml

diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml 
b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
new file mode 100644
index 000..32d2ad4
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
@@ -0,0 +1,113 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/cpufreq/cpufreq-mediatek-hw.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek's CPUFREQ Bindings
+
+maintainers:
+  - Hector Yuan 
+
+description:
+  CPUFREQ HW is a hardware engine used by MediaTek
+  SoCs to manage frequency in hardware. It is capable of controlling frequency
+  for multiple clusters.
+
+properties:
+  compatible:
+const: mediatek,cpufreq-hw
+
+  reg:
+minItems: 1
+maxItems: 2
+description: |
+  Addresses and sizes for the memory of the HW bases in each frequency 
domain.
+
+required:
+  - compatible
+  - reg
+
+examples:
+  - |
+cpus {
+#address-cells = <1>;
+#size-cells = <0>;
+
+cpu0: cpu@0 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mediatek,freq-domain = <_hw 0>;
+reg = <0x000>;
+};
+
+cpu1: cpu@100 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mediatek,freq-domain = <_hw 0>;
+reg = <0x100>;
+};
+
+cpu2: cpu@200 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mediatek,freq-domain = <_hw 0>;
+reg = <0x200>;
+};
+
+cpu3: cpu@300 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mediatek,freq-domain = <_hw 0>;
+reg = <0x300>;
+};
+
+cpu4: cpu@400 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mediatek,freq-domain = <_hw 1>;
+reg = <0x400>;
+};
+
+cpu5: cpu@500 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mediatek,freq-domain = <_hw 1>;
+reg = <0x500>;
+};
+
+cpu6: cpu@600 {
+device_type = "cpu";
+compatible = "arm,cortex-a75";
+enable-method = "psci";
+mediatek,freq-domain = <_hw 1>;
+reg = <0x600>;
+};
+
+cpu7: cpu@700 {
+device_type = "cpu";
+compatible = "arm,cortex-a75";
+enable-method = "psci";
+mediatek,freq-domain = <_hw 1>;
+reg = <0x700>;
+};
+};
+
+/* ... */
+
+soc {
+#address-cells = <2>;
+#size-cells = <2>;
+
+cpufreq_hw: cpufreq@11bc00 {
+compatible = "mediatek,cpufreq-hw";
+reg = <0 0x11bc10 0 0x8c>,
+   <0 0x11bca0 0 0x8c>;
+};
+};
-- 
1.7.9.5


[PATCH v8 2/3] dt-bindings: arm: cpus: Document 'mediatek,freq-domain' property

2020-10-26 Thread Hector Yuan
From: "Hector.Yuan" 

Add devicetree documentation for 'mediatek,freq-domain' property specific
to Mediatek CPUs. This property is used to reference the CPUFREQ node
along with the domain id.

Signed-off-by: Hector.Yuan 
---
 Documentation/devicetree/bindings/arm/cpus.yaml |6 ++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/cpus.yaml 
b/Documentation/devicetree/bindings/arm/cpus.yaml
index 1222bf1..e995b26 100644
--- a/Documentation/devicetree/bindings/arm/cpus.yaml
+++ b/Documentation/devicetree/bindings/arm/cpus.yaml
@@ -255,6 +255,12 @@ properties:
 
   where voltage is in V, frequency is in MHz.
 
+  mediatek,freq-domain:
+$ref: '/schemas/types.yaml#/definitions/phandle-array'
+description:
+  CPUs supporting freq-domain must set their "mediatek,freq-domain" 
property
+  with phandle to a cpufreq_hw node followed by the domain id.
+
   power-domains:
 $ref: '/schemas/types.yaml#/definitions/phandle-array'
 description:
-- 
1.7.9.5


Re: [PATCH v1] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2020-10-26 Thread Hector Yuan
On Fri, 2020-10-23 at 14:57 +0530, Viresh Kumar wrote:
> On 23-10-20, 17:08, Hector Yuan wrote:
> > On Fri, 2020-10-23 at 13:58 +0530, Viresh Kumar wrote:
> > > On 23-10-20, 16:24, Hector Yuan wrote:
> > > > This patchset includes 6 patches and depends on the MT6779 DTS patch[1] 
> > > > submitted by Hanks Chen.
> > > > The first 3 patches are for CPUFREQ HW driver and device tree binding, 
> > > > which are already sent before separately [2][3]. For binding part, I 
> > > > add a new patch to add property in cpu schema.
> > > > Besides, we add three more patches including EM power table, SVS CPU 
> > > > initialize, and cooling device.
> > > 
> > > And even after so many versions of these you chose to name this V1. It
> > > is very difficult for reviewers to find time to review your stuff, and
> > > they expect some sort of summary from you on what exactly changed from
> > > last version and you also need to name the current version currently.
> > > 
> > > This should have been V8 and you should have added a "V7->V8 diff:"
> > > section here, naming all the changes you did. Please send that as
> > > reply to this email, so I can see what really changed.
> > > 
> > Hi, Viresh
> > 
> > Sorry for your inconvenience.
> > #1~#3 is for cpufreq driver we have reviewed and the bindings which
> > separate freq domain to CPU schema.There is no change for the driver
> > itself.
> >   1. cpufreq: mediatek-hw: Add support for CPUFREQ HW
> >   2. dt-bindings: arm: cpus: Document 'mtk,freq-domain' property
> >   3. dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW
> > 
> > #4~#6 is for other CPU features, i.e. SVS [1]
> >   4. cpufreq: mediatek-hw: register EM power table
> >   5. cpufreq: mediatek-hw: Add SVS CPU initialization
> >   6. cpufreq: mediatek-hw: Add cooling dev flag
> > 
> > I supposed that it could be more clean to separate #4~#6 in another
> > patchset.May I know is it okay to you? Or I should merge all of changes
> > into v8 like you mentioned? Thank you.
> 
> Merge them all together and explain any special features (like SVS) in
> the commit log. It will also help in future when people want to
> understand your driver. Explain whatever is worth explaining there and
> is not straight forward.
> 
> Thanks for the details.
> 
OK, I will merge all changes in v8. And explain details in cover-letter.
Thank you. 



Re: [PATCH v1 3/6] dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

2020-10-26 Thread Hector Yuan
On Fri, 2020-10-23 at 14:05 +0530, Viresh Kumar wrote:
> On 23-10-20, 16:24, Hector Yuan wrote:
> > From: "Hector.Yuan" 
> > 
> > Add devicetree bindings for MediaTek HW driver.
> > 
> > Signed-off-by: Hector.Yuan 
> > ---
> >  .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |   46 
> > 
> >  1 file changed, 46 insertions(+)
> >  create mode 100644 
> > Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> > 
> > diff --git 
> > a/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml 
> > b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> > new file mode 100644
> > index 000..a99f44f
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> > @@ -0,0 +1,46 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/cpufreq/cpufreq-mediatek-hw.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: MediaTek's CPUFREQ Bindings
> > +
> > +maintainers:
> > +  - Hector Yuan 
> > +
> > +description:
> > +  CPUFREQ HW is a hardware engine used by MediaTek
> > +  SoCs to manage frequency in hardware. It is capable of controlling 
> > frequency
> > +  for multiple clusters.
> > +
> > +properties:
> > +  compatible:
> > +const: mediatek,cpufreq-hw
> > +
> > +  reg:
> > +minItems: 1
> > +maxItems: 2
> > +description: |
> > +  Addresses and sizes for the memory of the HW bases in each frequency 
> > domain.
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +
> > +examples:
> > +  - |
> > +soc {
> > +#address-cells = <2>;
> > +#size-cells = <2>;
> > +
> > +cpufreq_hw: cpufreq@11bc00 {
> > +compatible = "mediatek,cpufreq-hw";
> > +reg = <0 0x11bc10 0 0x8c>,
> > +   <0 0x11bca0 0 0x8c>;
> > +};
> > +};
> 
> You still need to keep the CPU specific part here and explain how this
> block is going to get used using the other binding you added.
> 
OK, will add cpu part here in v8.




Re: [PATCH v1 2/6] dt-bindings: arm: cpus: Document 'mtk,freq-domain' property

2020-10-26 Thread Hector Yuan
On Fri, 2020-10-23 at 13:59 +0530, Viresh Kumar wrote:
> On 23-10-20, 16:24, Hector Yuan wrote:
> > From: "Hector.Yuan" 
> > 
> > Add devicetree documentation for 'mtk,freq-domain' property specific
> > to Mediatek CPUs. This property is used to reference the CPUFREQ node
> > along with the domain id.
> > 
> > Signed-off-by: Hector.Yuan 
> > ---
> >  Documentation/devicetree/bindings/arm/cpus.yaml |6 ++
> >  1 file changed, 6 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/arm/cpus.yaml 
> > b/Documentation/devicetree/bindings/arm/cpus.yaml
> > index 1222bf1..06a6f5b 100644
> > --- a/Documentation/devicetree/bindings/arm/cpus.yaml
> > +++ b/Documentation/devicetree/bindings/arm/cpus.yaml
> > @@ -255,6 +255,12 @@ properties:
> >  
> >where voltage is in V, frequency is in MHz.
> >  
> > +  mtk-freq-domain:
> > +$ref: '/schemas/types.yaml#/definitions/phandle-array'
> > +description:
> > +  CPUs supporting freq-domain must set their "mtk-freq-domain" property
> > +  with phandle to a cpufreq_hw node followed by the domain id.
> > +
> 
> Name should have been mtk,freq-domain I believe. Rob will confirm the
> rest.
> 
OK, will name it as mediatek,freq-domain. Thank you.

> >power-domains:
> >  $ref: '/schemas/types.yaml#/definitions/phandle-array'
> >  description:
> > -- 
> > 1.7.9.5
> 



Re: [PATCH v1 3/6] dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

2020-10-26 Thread Hector Yuan
On Fri, 2020-10-23 at 11:15 -0500, Rob Herring wrote:
> On Fri, 23 Oct 2020 16:24:50 +0800, Hector Yuan wrote:
> > From: "Hector.Yuan" 
> > 
> > Add devicetree bindings for MediaTek HW driver.
> > 
> > Signed-off-by: Hector.Yuan 
> > ---
> >  .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |   46 
> > 
> >  1 file changed, 46 insertions(+)
> >  create mode 100644 
> > Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> > 
> 
> 
> My bot found errors running 'make dt_binding_check' on your patch:
> 
> yamllint warnings/errors:
> ./Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml:46:1: 
> [warning] too many blank lines (4 > 1) (empty-lines)
> 
> dtschema/dtc warnings/errors:
> 
> 
> See https://patchwork.ozlabs.org/patch/1386572
> 
> The base for the patch is generally the last rc1. Any dependencies
> should be noted.
> 
> If you already ran 'make dt_binding_check' and didn't see the above
> error(s), then make sure 'yamllint' is installed and dt-schema is up to
> date:
> 
> pip3 install dtschema --upgrade
> 
> Please check and re-submit.
> 
OK, will fix this warning in v8.




Re: [PATCH v1 2/6] dt-bindings: arm: cpus: Document 'mtk,freq-domain' property

2020-10-26 Thread Hector Yuan
On Fri, 2020-10-23 at 11:20 -0500, Rob Herring wrote:
> +Sudeep
> 
> On Fri, Oct 23, 2020 at 04:24:49PM +0800, Hector Yuan wrote:
> > From: "Hector.Yuan" 
> > 
> > Add devicetree documentation for 'mtk,freq-domain' property specific
> > to Mediatek CPUs. This property is used to reference the CPUFREQ node
> > along with the domain id.
> 
> Okay, now we've got the same thing being done for Mediatek, QCom, and 
> SCMI. This needs to be a common binding.
> 
OK, thank you. I will pay attention for this. But still
"mediatek,freq-domain" in v8.

> > Signed-off-by: Hector.Yuan 
> > ---
> >  Documentation/devicetree/bindings/arm/cpus.yaml |6 ++
> >  1 file changed, 6 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/arm/cpus.yaml 
> > b/Documentation/devicetree/bindings/arm/cpus.yaml
> > index 1222bf1..06a6f5b 100644
> > --- a/Documentation/devicetree/bindings/arm/cpus.yaml
> > +++ b/Documentation/devicetree/bindings/arm/cpus.yaml
> > @@ -255,6 +255,12 @@ properties:
> >  
> >where voltage is in V, frequency is in MHz.
> >  
> > +  mtk-freq-domain:
> 
> I expect this to change, but still not right form: ,
> 
> mtk is not the registered vendor.
> 
OK, will modify this in v8.(use the previous pacthset and merge all
changes)

> > +$ref: '/schemas/types.yaml#/definitions/phandle-array'
> > +description:
> > +  CPUs supporting freq-domain must set their "mtk-freq-domain" property
> > +  with phandle to a cpufreq_hw node followed by the domain id.
> > +
> >power-domains:
> >  $ref: '/schemas/types.yaml#/definitions/phandle-array'
> >  description:
> > -- 
> > 1.7.9.5



Re: [PATCH v1] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2020-10-23 Thread Hector Yuan
On Fri, 2020-10-23 at 13:58 +0530, Viresh Kumar wrote:
> On 23-10-20, 16:24, Hector Yuan wrote:
> > This patchset includes 6 patches and depends on the MT6779 DTS patch[1] 
> > submitted by Hanks Chen.
> > The first 3 patches are for CPUFREQ HW driver and device tree binding, 
> > which are already sent before separately [2][3]. For binding part, I add a 
> > new patch to add property in cpu schema.
> > Besides, we add three more patches including EM power table, SVS CPU 
> > initialize, and cooling device.
> 
> And even after so many versions of these you chose to name this V1. It
> is very difficult for reviewers to find time to review your stuff, and
> they expect some sort of summary from you on what exactly changed from
> last version and you also need to name the current version currently.
> 
> This should have been V8 and you should have added a "V7->V8 diff:"
> section here, naming all the changes you did. Please send that as
> reply to this email, so I can see what really changed.
> 
Hi, Viresh

Sorry for your inconvenience.
#1~#3 is for cpufreq driver we have reviewed and the bindings which
separate freq domain to CPU schema.There is no change for the driver
itself.
  1. cpufreq: mediatek-hw: Add support for CPUFREQ HW
  2. dt-bindings: arm: cpus: Document 'mtk,freq-domain' property
  3. dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

#4~#6 is for other CPU features, i.e. SVS [1]
  4. cpufreq: mediatek-hw: register EM power table
  5. cpufreq: mediatek-hw: Add SVS CPU initialization
  6. cpufreq: mediatek-hw: Add cooling dev flag

I supposed that it could be more clean to separate #4~#6 in another
patchset.May I know is it okay to you? Or I should merge all of changes
into v8 like you mentioned? Thank you.

[1]
https://patchwork.kernel.org/project/linux-mediatek/patch/20190906100514.30803-4-roger.lu%40mediatek.com/


[PATCH v1 3/6] dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

2020-10-23 Thread Hector Yuan
From: "Hector.Yuan" 

Add devicetree bindings for MediaTek HW driver.

Signed-off-by: Hector.Yuan 
---
 .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |   46 
 1 file changed, 46 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml

diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml 
b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
new file mode 100644
index 000..a99f44f
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/cpufreq/cpufreq-mediatek-hw.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek's CPUFREQ Bindings
+
+maintainers:
+  - Hector Yuan 
+
+description:
+  CPUFREQ HW is a hardware engine used by MediaTek
+  SoCs to manage frequency in hardware. It is capable of controlling frequency
+  for multiple clusters.
+
+properties:
+  compatible:
+const: mediatek,cpufreq-hw
+
+  reg:
+minItems: 1
+maxItems: 2
+description: |
+  Addresses and sizes for the memory of the HW bases in each frequency 
domain.
+
+required:
+  - compatible
+  - reg
+
+examples:
+  - |
+soc {
+#address-cells = <2>;
+#size-cells = <2>;
+
+cpufreq_hw: cpufreq@11bc00 {
+compatible = "mediatek,cpufreq-hw";
+reg = <0 0x11bc10 0 0x8c>,
+   <0 0x11bca0 0 0x8c>;
+};
+};
+
+
+
+
-- 
1.7.9.5


[PATCH v1 6/6] cpufreq: mediatek-hw: Add cooling dev flag

2020-10-23 Thread Hector Yuan
From: "Hector.Yuan" 

Add cooling device flag for thermal throttle

Signed-off-by: Hector.Yuan 
---
 drivers/cpufreq/mediatek-cpufreq-hw.c |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c 
b/drivers/cpufreq/mediatek-cpufreq-hw.c
index 15fba20..665f220f 100644
--- a/drivers/cpufreq/mediatek-cpufreq-hw.c
+++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
@@ -165,7 +165,8 @@ static int mtk_cpufreq_hw_cpu_exit(struct cpufreq_policy 
*policy)
 
 static struct cpufreq_driver cpufreq_mtk_hw_driver = {
.flags  = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK |
- CPUFREQ_HAVE_GOVERNOR_PER_POLICY,
+ CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
+ CPUFREQ_IS_COOLING_DEV,
.verify = cpufreq_generic_frequency_table_verify,
.target_index   = mtk_cpufreq_hw_target_index,
.get= mtk_cpufreq_hw_get,
-- 
1.7.9.5


[PATCH v1 4/6] cpufreq: mediatek-hw: register EM power table

2020-10-23 Thread Hector Yuan
From: "Hector.Yuan" 

Register energy model table for EAS and thermal cooling device usage

Signed-off-by: Hector.Yuan 
---
 drivers/cpufreq/mediatek-cpufreq-hw.c |   58 ++---
 1 file changed, 46 insertions(+), 12 deletions(-)

diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c 
b/drivers/cpufreq/mediatek-cpufreq-hw.c
index 74449da..241d93f 100644
--- a/drivers/cpufreq/mediatek-cpufreq-hw.c
+++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
@@ -5,6 +5,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -17,9 +18,10 @@
 #define LUT_ROW_SIZE   0x4
 
 enum {
-   REG_LUT_TABLE,
-   REG_ENABLE,
-   REG_PERF_STATE,
+   REG_FREQ_LUT_TABLE,
+   REG_FREQ_ENABLE,
+   REG_FREQ_PERF_STATE,
+   REG_EM_POWER_TBL,
 
REG_ARRAY_SIZE,
 };
@@ -27,23 +29,44 @@ enum {
 struct cpufreq_mtk {
struct cpufreq_frequency_table *table;
void __iomem *reg_bases[REG_ARRAY_SIZE];
+   int nr_opp;
cpumask_t related_cpus;
 };
 
 static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = {
-   [REG_LUT_TABLE] = 0x0,
-   [REG_ENABLE]= 0x84,
-   [REG_PERF_STATE]= 0x88,
+   [REG_FREQ_LUT_TABLE]= 0x0,
+   [REG_FREQ_ENABLE]   = 0x84,
+   [REG_FREQ_PERF_STATE]   = 0x88,
+   [REG_EM_POWER_TBL]  = 0x3D0,
 };
 
 static struct cpufreq_mtk *mtk_freq_domain_map[NR_CPUS];
 
+static int mtk_cpufreq_get_cpu_power(unsigned long *mW,
+unsigned long *KHz, struct device *cpu_dev)
+{
+   struct cpufreq_mtk *c = mtk_freq_domain_map[cpu_dev->id];
+   int i;
+
+   for (i = 0; i < c->nr_opp; i++) {
+   if (c->table[i].frequency < *KHz)
+   break;
+   }
+   i--;
+
+   *KHz = c->table[i].frequency;
+   *mW = readl_relaxed(c->reg_bases[REG_EM_POWER_TBL] +
+   i * LUT_ROW_SIZE) / 1000;
+
+   return 0;
+}
+
 static int mtk_cpufreq_hw_target_index(struct cpufreq_policy *policy,
   unsigned int index)
 {
struct cpufreq_mtk *c = policy->driver_data;
 
-   writel_relaxed(index, c->reg_bases[REG_PERF_STATE]);
+   writel_relaxed(index, c->reg_bases[REG_FREQ_PERF_STATE]);
 
return 0;
 }
@@ -55,7 +78,7 @@ static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)
 
c = mtk_freq_domain_map[cpu];
 
-   index = readl_relaxed(c->reg_bases[REG_PERF_STATE]);
+   index = readl_relaxed(c->reg_bases[REG_FREQ_PERF_STATE]);
index = min(index, LUT_MAX_ENTRIES - 1);
 
return c->table[index].frequency;
@@ -64,6 +87,14 @@ static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)
 static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
 {
struct cpufreq_mtk *c;
+   struct device *cpu_dev;
+   struct em_data_callback em_cb = EM_DATA_CB(mtk_cpufreq_get_cpu_power);
+
+   cpu_dev = get_cpu_device(policy->cpu);
+   if (!cpu_dev) {
+   pr_err("failed to get cpu%d device\n", policy->cpu);
+   return -ENODEV;
+   }
 
c = mtk_freq_domain_map[policy->cpu];
if (!c) {
@@ -77,7 +108,9 @@ static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy 
*policy)
policy->driver_data = c;
 
/* HW should be in enabled state to proceed now */
-   writel_relaxed(0x1, c->reg_bases[REG_ENABLE]);
+   writel_relaxed(0x1, c->reg_bases[REG_FREQ_ENABLE]);
+
+   em_dev_register_perf_domain(cpu_dev, c->nr_opp, _cb, policy->cpus);
 
return 0;
 }
@@ -93,7 +126,7 @@ static int mtk_cpufreq_hw_cpu_exit(struct cpufreq_policy 
*policy)
}
 
/* HW should be in paused state now */
-   writel_relaxed(0x0, c->reg_bases[REG_ENABLE]);
+   writel_relaxed(0x0, c->reg_bases[REG_FREQ_ENABLE]);
 
return 0;
 }
@@ -122,7 +155,7 @@ static int mtk_cpu_create_freq_table(struct platform_device 
*pdev,
if (!c->table)
return -ENOMEM;
 
-   base_table = c->reg_bases[REG_LUT_TABLE];
+   base_table = c->reg_bases[REG_FREQ_LUT_TABLE];
 
for (i = 0; i < LUT_MAX_ENTRIES; i++) {
data = readl_relaxed(base_table + (i * LUT_ROW_SIZE));
@@ -140,6 +173,7 @@ static int mtk_cpu_create_freq_table(struct platform_device 
*pdev,
}
 
c->table[i].frequency = CPUFREQ_TABLE_END;
+   c->nr_opp = i;
 
return 0;
 }
@@ -191,7 +225,7 @@ static int mtk_cpu_resources_init(struct platform_device 
*pdev,
if (IS_ERR(base))
return PTR_ERR(base);
 
-   for (i = REG_LUT_TABLE; i < REG_ARRAY_SIZE; i++)
+   for (i = REG_FREQ_LUT_TABLE; i < REG_ARRAY_SIZE; i++)
c->reg_bases[i] = base + offsets[i];
 
ret = mtk_get_related_cpus(index, c);
-- 
1.7.9.5


[PATCH v1 1/6] cpufreq: mediatek-hw: Add support for CPUFREQ HW

2020-10-23 Thread Hector Yuan
From: "Hector.Yuan" 

Add cpufreq HW support.

Signed-off-by: Hector.Yuan 
---
 drivers/cpufreq/Kconfig.arm   |   12 ++
 drivers/cpufreq/Makefile  |1 +
 drivers/cpufreq/mediatek-cpufreq-hw.c |  276 +
 3 files changed, 289 insertions(+)
 create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw.c

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index cb72fb5..b9d17c5 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -123,6 +123,18 @@ config ARM_MEDIATEK_CPUFREQ
help
  This adds the CPUFreq driver support for MediaTek SoCs.
 
+config ARM_MEDIATEK_CPUFREQ_HW
+   tristate "MediaTek CPUFreq HW driver"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   default m
+   help
+ Support for the CPUFreq HW driver.
+ Some MediaTek chipsets have a HW engine to offload the steps
+ necessary for changing the frequency of the CPUs. Firmware loaded
+ in this engine exposes a programming interface to the OS.
+ The driver implements the cpufreq interface for this HW engine.
+ Say Y if you want to support CPUFreq HW.
+
 config ARM_OMAP2PLUS_CPUFREQ
bool "TI OMAP2+"
depends on ARCH_OMAP2PLUS
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index f1b7e3d..ffc61cd 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ)   += 
imx6q-cpufreq.o
 obj-$(CONFIG_ARM_IMX_CPUFREQ_DT)   += imx-cpufreq-dt.o
 obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o
 obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ) += mediatek-cpufreq.o
+obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ_HW)  += mediatek-cpufreq-hw.o
 obj-$(CONFIG_MACH_MVEBU_V7)+= mvebu-cpufreq.o
 obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)+= omap-cpufreq.o
 obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)   += pxa2xx-cpufreq.o
diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c 
b/drivers/cpufreq/mediatek-cpufreq-hw.c
new file mode 100644
index 000..74449da
--- /dev/null
+++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
@@ -0,0 +1,276 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define LUT_MAX_ENTRIES32U
+#define LUT_FREQ   GENMASK(11, 0)
+#define LUT_ROW_SIZE   0x4
+
+enum {
+   REG_LUT_TABLE,
+   REG_ENABLE,
+   REG_PERF_STATE,
+
+   REG_ARRAY_SIZE,
+};
+
+struct cpufreq_mtk {
+   struct cpufreq_frequency_table *table;
+   void __iomem *reg_bases[REG_ARRAY_SIZE];
+   cpumask_t related_cpus;
+};
+
+static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = {
+   [REG_LUT_TABLE] = 0x0,
+   [REG_ENABLE]= 0x84,
+   [REG_PERF_STATE]= 0x88,
+};
+
+static struct cpufreq_mtk *mtk_freq_domain_map[NR_CPUS];
+
+static int mtk_cpufreq_hw_target_index(struct cpufreq_policy *policy,
+  unsigned int index)
+{
+   struct cpufreq_mtk *c = policy->driver_data;
+
+   writel_relaxed(index, c->reg_bases[REG_PERF_STATE]);
+
+   return 0;
+}
+
+static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)
+{
+   struct cpufreq_mtk *c;
+   unsigned int index;
+
+   c = mtk_freq_domain_map[cpu];
+
+   index = readl_relaxed(c->reg_bases[REG_PERF_STATE]);
+   index = min(index, LUT_MAX_ENTRIES - 1);
+
+   return c->table[index].frequency;
+}
+
+static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
+{
+   struct cpufreq_mtk *c;
+
+   c = mtk_freq_domain_map[policy->cpu];
+   if (!c) {
+   pr_err("No scaling support for CPU%d\n", policy->cpu);
+   return -ENODEV;
+   }
+
+   cpumask_copy(policy->cpus, >related_cpus);
+
+   policy->freq_table = c->table;
+   policy->driver_data = c;
+
+   /* HW should be in enabled state to proceed now */
+   writel_relaxed(0x1, c->reg_bases[REG_ENABLE]);
+
+   return 0;
+}
+
+static int mtk_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy)
+{
+   struct cpufreq_mtk *c;
+
+   c = mtk_freq_domain_map[policy->cpu];
+   if (!c) {
+   pr_err("No scaling support for CPU%d\n", policy->cpu);
+   return -ENODEV;
+   }
+
+   /* HW should be in paused state now */
+   writel_relaxed(0x0, c->reg_bases[REG_ENABLE]);
+
+   return 0;
+}
+
+static struct cpufreq_driver cpufreq_mtk_hw_driver = {
+   .flags  = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK |
+ CPUFREQ_HAVE_GOVERNOR_PER_POLICY,
+   .verify = cpufreq_generic_frequency_table_verify,
+   .target_index   = mtk_cpufreq_hw_target_index,
+   .get= mtk_cpufreq_hw_get,
+   .init   = mtk_cpufreq_hw_cpu_init,
+   .exit   = 

[PATCH v1] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2020-10-23 Thread Hector Yuan
This patchset includes 6 patches and depends on the MT6779 DTS patch[1] 
submitted by Hanks Chen.
The first 3 patches are for CPUFREQ HW driver and device tree binding, which 
are already sent before separately [2][3]. For binding part, I add a new patch 
to add property in cpu schema.
Besides, we add three more patches including EM power table, SVS CPU 
initialize, and cooling device.

[1] https://lkml.org/lkml/2020/8/4/1094
[2] https://lkml.org/lkml/2020/9/10/13 (already reviewed by Viresh) [3] 
https://lkml.org/lkml/2020/9/23/384


Hector.Yuan (6):
  cpufreq: mediatek-hw: Add support for CPUFREQ HW
  dt-bindings: arm: cpus: Document 'mtk,freq-domain' property
  dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW
  cpufreq: mediatek-hw: register EM power table
  cpufreq: mediatek-hw: Add SVS CPU initialization
  cpufreq: mediatek-hw: Add cooling dev flag

 Documentation/devicetree/bindings/arm/cpus.yaml|6 +
 .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |   46 +++
 drivers/cpufreq/Kconfig.arm|   12 +
 drivers/cpufreq/Makefile   |1 +
 drivers/cpufreq/mediatek-cpufreq-hw.c  |  343 
 5 files changed, 408 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
 create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw.c

[PATCH v1 5/6] cpufreq: mediatek-hw: Add SVS CPU initialization

2020-10-23 Thread Hector Yuan
From: "Hector.Yuan" 

Use pm_qos to block cpu-idle state for SVS initializing.
CPUs must be in power on state when doing SVS.
Add polling ack while coufreq hw is ready.(SVS init done)

Signed-off-by: Hector.Yuan 
---
 drivers/cpufreq/mediatek-cpufreq-hw.c |   32 
 1 file changed, 32 insertions(+)

diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c 
b/drivers/cpufreq/mediatek-cpufreq-hw.c
index 241d93f..15fba20 100644
--- a/drivers/cpufreq/mediatek-cpufreq-hw.c
+++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
@@ -7,20 +7,27 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #define LUT_MAX_ENTRIES32U
 #define LUT_FREQ   GENMASK(11, 0)
 #define LUT_ROW_SIZE   0x4
+#define CPUFREQ_HW_STATUS  BIT(0)
+#define SVS_HW_STATUS  BIT(1)
+#define POLL_USEC  1000
+#define TIMEOUT_USEC   30
 
 enum {
REG_FREQ_LUT_TABLE,
REG_FREQ_ENABLE,
REG_FREQ_PERF_STATE,
+   REG_FREQ_HW_STATE,
REG_EM_POWER_TBL,
 
REG_ARRAY_SIZE,
@@ -37,6 +44,7 @@ struct cpufreq_mtk {
[REG_FREQ_LUT_TABLE]= 0x0,
[REG_FREQ_ENABLE]   = 0x84,
[REG_FREQ_PERF_STATE]   = 0x88,
+   [REG_FREQ_HW_STATE] = 0x8c,
[REG_EM_POWER_TBL]  = 0x3D0,
 };
 
@@ -89,6 +97,12 @@ static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy 
*policy)
struct cpufreq_mtk *c;
struct device *cpu_dev;
struct em_data_callback em_cb = EM_DATA_CB(mtk_cpufreq_get_cpu_power);
+   struct pm_qos_request *qos_request;
+   int sig, pwr_hw = CPUFREQ_HW_STATUS | SVS_HW_STATUS;
+
+   qos_request = kzalloc(sizeof(*qos_request), GFP_KERNEL);
+   if (!qos_request)
+   return -ENOMEM;
 
cpu_dev = get_cpu_device(policy->cpu);
if (!cpu_dev) {
@@ -107,11 +121,29 @@ static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy 
*policy)
policy->freq_table = c->table;
policy->driver_data = c;
 
+   /* Let CPUs leave idle-off state for SVS CPU initializing */
+   cpu_latency_qos_add_request(qos_request, 0);
+
/* HW should be in enabled state to proceed now */
writel_relaxed(0x1, c->reg_bases[REG_FREQ_ENABLE]);
 
+   if (readl_poll_timeout(c->reg_bases[REG_FREQ_HW_STATE], sig,
+  (sig & pwr_hw) == pwr_hw, POLL_USEC,
+  TIMEOUT_USEC)) {
+   if (!(sig & CPUFREQ_HW_STATUS)) {
+   pr_info("cpufreq hardware of CPU%d is not enabled\n",
+   policy->cpu);
+   return -ENODEV;
+   }
+
+   pr_info("SVS of CPU%d is not enabled\n", policy->cpu);
+   }
+
em_dev_register_perf_domain(cpu_dev, c->nr_opp, _cb, policy->cpus);
 
+   cpu_latency_qos_remove_request(qos_request);
+   kfree(qos_request);
+
return 0;
 }
 
-- 
1.7.9.5


[PATCH v1 2/6] dt-bindings: arm: cpus: Document 'mtk,freq-domain' property

2020-10-23 Thread Hector Yuan
From: "Hector.Yuan" 

Add devicetree documentation for 'mtk,freq-domain' property specific
to Mediatek CPUs. This property is used to reference the CPUFREQ node
along with the domain id.

Signed-off-by: Hector.Yuan 
---
 Documentation/devicetree/bindings/arm/cpus.yaml |6 ++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/cpus.yaml 
b/Documentation/devicetree/bindings/arm/cpus.yaml
index 1222bf1..06a6f5b 100644
--- a/Documentation/devicetree/bindings/arm/cpus.yaml
+++ b/Documentation/devicetree/bindings/arm/cpus.yaml
@@ -255,6 +255,12 @@ properties:
 
   where voltage is in V, frequency is in MHz.
 
+  mtk-freq-domain:
+$ref: '/schemas/types.yaml#/definitions/phandle-array'
+description:
+  CPUs supporting freq-domain must set their "mtk-freq-domain" property
+  with phandle to a cpufreq_hw node followed by the domain id.
+
   power-domains:
 $ref: '/schemas/types.yaml#/definitions/phandle-array'
 description:
-- 
1.7.9.5


Re: [PATCH v3 1/2] dt-bindings: arm: cpus: Document 'qcom,freq-domain' property

2020-10-20 Thread Hector Yuan
Hi, Manivannan

On Tue, 2020-10-20 at 21:09 +0530, Manivannan Sadhasivam wrote:
> Add devicetree documentation for 'qcom,freq-domain' property specific
> to Qualcomm CPUs. This property is used to reference the CPUFREQ node
> along with Domain ID (0/1).
> 
> Signed-off-by: Manivannan Sadhasivam 
> ---
>  Documentation/devicetree/bindings/arm/cpus.yaml | 6 ++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/cpus.yaml 
> b/Documentation/devicetree/bindings/arm/cpus.yaml
> index 1222bf1831fa..f40564bf004f 100644
> --- a/Documentation/devicetree/bindings/arm/cpus.yaml
> +++ b/Documentation/devicetree/bindings/arm/cpus.yaml
> @@ -290,6 +290,12 @@ properties:
>  
>* arm/msm/qcom,kpss-acc.txt
>  
> +  qcom,freq-domain:
Do you mind to change "qcom, freq-domain" to common naming? or drop the
prefix. So that we can use this CPU node and map it to each freq-domain.
Thanks a lot. 

> +$ref: '/schemas/types.yaml#/definitions/phandle-array'
> +description: |
> +  CPUs supporting freq-domain must set their "qcom,freq-domain" property
> +  with phandle to a cpufreq_hw node followed by the Domain ID(0/1).
> +
>rockchip,pmu:
>  $ref: '/schemas/types.yaml#/definitions/phandle'
>  description: |



[PATCH v2] cpufreq: mediatek-hw: Register EM power table

2020-10-15 Thread Hector Yuan
Register to energy model framework with CPU power efficiency table.

This patch depends on Mediatek cpufreq HW driver patch submitted by Hector Yuan.
 https://lkml.org/lkml/2020/9/10/13


Hector.Yuan (1):
  cpufreq: mediatek-hw: Register EM power table

 drivers/cpufreq/mediatek-cpufreq-hw.c |   58 ++---
 1 file changed, 46 insertions(+), 12 deletions(-)

[PATCH v2 1/1] cpufreq: mediatek-hw: Register EM power table

2020-10-15 Thread Hector Yuan
From: "Hector.Yuan" 

Register CPU power table to energy model framework

Signed-off-by: Hector.Yuan 
---
 drivers/cpufreq/mediatek-cpufreq-hw.c |   58 ++---
 1 file changed, 46 insertions(+), 12 deletions(-)

diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c 
b/drivers/cpufreq/mediatek-cpufreq-hw.c
index 8fa12e5..379a5f4 100644
--- a/drivers/cpufreq/mediatek-cpufreq-hw.c
+++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
@@ -5,6 +5,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -17,9 +18,10 @@
 #define LUT_ROW_SIZE   0x4
 
 enum {
-   REG_LUT_TABLE,
-   REG_ENABLE,
-   REG_PERF_STATE,
+   REG_FREQ_LUT_TABLE,
+   REG_FREQ_ENABLE,
+   REG_FREQ_PERF_STATE,
+   REG_EM_POWER_TBL,
 
REG_ARRAY_SIZE,
 };
@@ -27,23 +29,44 @@ enum {
 struct cpufreq_mtk {
struct cpufreq_frequency_table *table;
void __iomem *reg_bases[REG_ARRAY_SIZE];
+   int nr_opp;
cpumask_t related_cpus;
 };
 
 static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = {
-   [REG_LUT_TABLE] = 0x0,
-   [REG_ENABLE]= 0x84,
-   [REG_PERF_STATE]= 0x88,
+   [REG_FREQ_LUT_TABLE]= 0x0,
+   [REG_FREQ_ENABLE]   = 0x84,
+   [REG_FREQ_PERF_STATE]   = 0x88,
+   [REG_EM_POWER_TBL]  = 0x3D0,
 };
 
 static struct cpufreq_mtk *mtk_freq_domain_map[NR_CPUS];
 
+static int mtk_cpufreq_get_cpu_power(unsigned long *mW,
+unsigned long *KHz, struct device *cpu_dev)
+{
+   struct cpufreq_mtk *c = mtk_freq_domain_map[cpu_dev->id];
+   int i;
+
+   for (i = 0; i < c->nr_opp; i++) {
+   if (c->table[i].frequency < *KHz)
+   break;
+   }
+   i--;
+
+   *KHz = c->table[i].frequency;
+   *mW = readl_relaxed(c->reg_bases[REG_EM_POWER_TBL] +
+   i * LUT_ROW_SIZE) / 1000;
+
+   return 0;
+}
+
 static int mtk_cpufreq_hw_target_index(struct cpufreq_policy *policy,
   unsigned int index)
 {
struct cpufreq_mtk *c = policy->driver_data;
 
-   writel_relaxed(index, c->reg_bases[REG_PERF_STATE]);
+   writel_relaxed(index, c->reg_bases[REG_FREQ_PERF_STATE]);
 
return 0;
 }
@@ -55,7 +78,7 @@ static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)
 
c = mtk_freq_domain_map[cpu];
 
-   index = readl_relaxed(c->reg_bases[REG_PERF_STATE]);
+   index = readl_relaxed(c->reg_bases[REG_FREQ_PERF_STATE]);
index = min(index, LUT_MAX_ENTRIES - 1);
 
return c->table[index].frequency;
@@ -64,6 +87,14 @@ static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)
 static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
 {
struct cpufreq_mtk *c;
+   struct device *cpu_dev;
+   struct em_data_callback em_cb = EM_DATA_CB(mtk_cpufreq_get_cpu_power);
+
+   cpu_dev = get_cpu_device(policy->cpu);
+   if (!cpu_dev) {
+   pr_err("failed to get cpu%d device\n", policy->cpu);
+   return -ENODEV;
+   }
 
c = mtk_freq_domain_map[policy->cpu];
if (!c) {
@@ -77,7 +108,9 @@ static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy 
*policy)
policy->driver_data = c;
 
/* HW should be in enabled state to proceed now */
-   writel_relaxed(0x1, c->reg_bases[REG_ENABLE]);
+   writel_relaxed(0x1, c->reg_bases[REG_FREQ_ENABLE]);
+
+   em_dev_register_perf_domain(cpu_dev, c->nr_opp, _cb, policy->cpus);
 
return 0;
 }
@@ -93,7 +126,7 @@ static int mtk_cpufreq_hw_cpu_exit(struct cpufreq_policy 
*policy)
}
 
/* HW should be in paused state now */
-   writel_relaxed(0x0, c->reg_bases[REG_ENABLE]);
+   writel_relaxed(0x0, c->reg_bases[REG_FREQ_ENABLE]);
 
return 0;
 }
@@ -122,7 +155,7 @@ static int mtk_cpu_create_freq_table(struct platform_device 
*pdev,
if (!c->table)
return -ENOMEM;
 
-   base_table = c->reg_bases[REG_LUT_TABLE];
+   base_table = c->reg_bases[REG_FREQ_LUT_TABLE];
 
for (i = 0; i < LUT_MAX_ENTRIES; i++) {
data = readl_relaxed(base_table + (i * LUT_ROW_SIZE));
@@ -140,6 +173,7 @@ static int mtk_cpu_create_freq_table(struct platform_device 
*pdev,
}
 
c->table[i].frequency = CPUFREQ_TABLE_END;
+   c->nr_opp = i;
 
return 0;
 }
@@ -192,7 +226,7 @@ static int mtk_cpu_resources_init(struct platform_device 
*pdev,
if (IS_ERR(base))
return PTR_ERR(base);
 
-   for (i = REG_LUT_TABLE; i < REG_ARRAY_SIZE; i++)
+   for (i = REG_FREQ_LUT_TABLE; i < REG_ARRAY_SIZE; i++)
c->reg_bases[i] = base + offsets[i];
 
ret = mtk_get_related_cpus(index, c);
-- 
1.7.9.5


Re: [PATCH v1 1/1] cpufreq: mediatek-hw: Register EM power table

2020-10-08 Thread Hector Yuan
On Fri, 2020-10-09 at 09:49 +0530, Viresh Kumar wrote:
> On 08-10-20, 20:13, Hector Yuan wrote:
> > From: "Hector.Yuan" 
> > 
> > Register CPU power table to energy model framework
> > 
> > Signed-off-by: Hector.Yuan 
> > ---
> >  drivers/cpufreq/mediatek-cpufreq-hw.c |   50 
> > +
> >  1 file changed, 38 insertions(+), 12 deletions(-)
> 
> I don't see this file in mainline. What am I missing ?
> 
Hi, Viresh:

Yes, I base on my patches which is currently reviewed by Rob for the
Device tree part.
As I mentioned in cover letter.

This patch depends on Mediatek cpufreq HW driver patch submitted by
Hector Yuan.
 https://lkml.org/lkml/2020/9/10/13

I have asked your approval for sending my new patches based on it and
you said it's okay to you.
I will stop sending new patches if you have any concerns.
Thank you so much.


Re: [PATCH v1 1/1] cpufreq: mediatek-hw: Register EM power table

2020-10-08 Thread Hector Yuan
On Thu, 2020-10-08 at 13:55 +0100, Lukasz Luba wrote:
> Hi Hector,
> 
> On 10/8/20 1:13 PM, Hector Yuan wrote:
> > From: "Hector.Yuan" 
> > 
> > Register CPU power table to energy model framework
> > 
> > Signed-off-by: Hector.Yuan 
> > ---
> >   drivers/cpufreq/mediatek-cpufreq-hw.c |   50 
> > +
> >   1 file changed, 38 insertions(+), 12 deletions(-)
> > 
> > diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c 
> > b/drivers/cpufreq/mediatek-cpufreq-hw.c
> > index 8fa12e5..3808ea0 100644
> > --- a/drivers/cpufreq/mediatek-cpufreq-hw.c
> > +++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
> > @@ -5,6 +5,7 @@
> >   
> >   #include 
> >   #include 
> > +#include 
> >   #include 
> >   #include 
> >   #include 
> > @@ -17,9 +18,10 @@
> >   #define LUT_ROW_SIZE  0x4
> >   
> >   enum {
> > -   REG_LUT_TABLE,
> > -   REG_ENABLE,
> > -   REG_PERF_STATE,
> > +   REG_FREQ_LUT_TABLE,
> > +   REG_FREQ_ENABLE,
> > +   REG_FREQ_PERF_STATE,
> > +   REG_EM_POWER_TBL,
> >   
> > REG_ARRAY_SIZE,
> >   };
> > @@ -27,23 +29,44 @@ enum {
> >   struct cpufreq_mtk {
> > struct cpufreq_frequency_table *table;
> > void __iomem *reg_bases[REG_ARRAY_SIZE];
> > +   int nr_opp;
> > cpumask_t related_cpus;
> >   };
> >   
> >   static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = {
> > -   [REG_LUT_TABLE] = 0x0,
> > -   [REG_ENABLE]= 0x84,
> > -   [REG_PERF_STATE]= 0x88,
> > +   [REG_FREQ_LUT_TABLE]= 0x0,
> > +   [REG_FREQ_ENABLE]   = 0x84,
> > +   [REG_FREQ_PERF_STATE]   = 0x88,
> > +   [REG_EM_POWER_TBL]  = 0x3D0,
> >   };
> >   
> >   static struct cpufreq_mtk *mtk_freq_domain_map[NR_CPUS];
> >   
> > +static int mtk_cpufreq_get_cpu_power(unsigned long *mW,
> > +unsigned long *KHz, int cpu)
> > +{
> > +   struct cpufreq_mtk *c = mtk_freq_domain_map[cpu];
> > +   int i;
> > +
> > +   for (i = 0; i < c->nr_opp; i++) {
> > +   if (c->table[i].frequency < *KHz)
> > +   break;
> > +   }
> > +   i--;
> > +
> > +   *KHz = c->table[i].frequency;
> > +   *mW = readl_relaxed(c->reg_bases[REG_EM_POWER_TBL] +
> > +   i * LUT_ROW_SIZE) / 1000;
> > +
> > +   return 0;
> > +}
> > +
> >   static int mtk_cpufreq_hw_target_index(struct cpufreq_policy *policy,
> >unsigned int index)
> >   {
> > struct cpufreq_mtk *c = policy->driver_data;
> >   
> > -   writel_relaxed(index, c->reg_bases[REG_PERF_STATE]);
> > +   writel_relaxed(index, c->reg_bases[REG_FREQ_PERF_STATE]);
> >   
> > return 0;
> >   }
> > @@ -55,7 +78,7 @@ static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)
> >   
> > c = mtk_freq_domain_map[cpu];
> >   
> > -   index = readl_relaxed(c->reg_bases[REG_PERF_STATE]);
> > +   index = readl_relaxed(c->reg_bases[REG_FREQ_PERF_STATE]);
> > index = min(index, LUT_MAX_ENTRIES - 1);
> >   
> > return c->table[index].frequency;
> > @@ -64,6 +87,7 @@ static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)
> >   static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
> >   {
> > struct cpufreq_mtk *c;
> > +   struct em_data_callback em_cb = EM_DATA_CB(mtk_cpufreq_get_cpu_power);
> >   
> > c = mtk_freq_domain_map[policy->cpu];
> > if (!c) {
> > @@ -77,7 +101,8 @@ static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy 
> > *policy)
> > policy->driver_data = c;
> >   
> > /* HW should be in enabled state to proceed now */
> > -   writel_relaxed(0x1, c->reg_bases[REG_ENABLE]);
> > +   writel_relaxed(0x1, c->reg_bases[REG_FREQ_ENABLE]);
> > +   em_register_perf_domain(policy->cpus, c->nr_opp, _cb);
> 
> 
> The function name has changed recently (v5.9-rc1) to:
> em_dev_register_perf_domain()
> 
> Please check your base kernel tree and update.
> 
> Regards,
> Lukasz
> 
OK, will check my base kernel and update this.
Thank you.



[PATCH v1] cpufreq: mediatek-hw: Register EM power table

2020-10-08 Thread Hector Yuan
Register to energy model framework with CPU power efficiency table.

This patch depends on Mediatek cpufreq HW driver patch submitted by Hector Yuan.
 https://lkml.org/lkml/2020/9/10/13


Hector.Yuan (1):
  cpufreq: mediatek-hw: Register EM power table

 drivers/cpufreq/mediatek-cpufreq-hw.c |   50 +
 1 file changed, 38 insertions(+), 12 deletions(-)

[PATCH v1 1/1] cpufreq: mediatek-hw: Register EM power table

2020-10-08 Thread Hector Yuan
From: "Hector.Yuan" 

Register CPU power table to energy model framework

Signed-off-by: Hector.Yuan 
---
 drivers/cpufreq/mediatek-cpufreq-hw.c |   50 +
 1 file changed, 38 insertions(+), 12 deletions(-)

diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c 
b/drivers/cpufreq/mediatek-cpufreq-hw.c
index 8fa12e5..3808ea0 100644
--- a/drivers/cpufreq/mediatek-cpufreq-hw.c
+++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
@@ -5,6 +5,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -17,9 +18,10 @@
 #define LUT_ROW_SIZE   0x4
 
 enum {
-   REG_LUT_TABLE,
-   REG_ENABLE,
-   REG_PERF_STATE,
+   REG_FREQ_LUT_TABLE,
+   REG_FREQ_ENABLE,
+   REG_FREQ_PERF_STATE,
+   REG_EM_POWER_TBL,
 
REG_ARRAY_SIZE,
 };
@@ -27,23 +29,44 @@ enum {
 struct cpufreq_mtk {
struct cpufreq_frequency_table *table;
void __iomem *reg_bases[REG_ARRAY_SIZE];
+   int nr_opp;
cpumask_t related_cpus;
 };
 
 static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = {
-   [REG_LUT_TABLE] = 0x0,
-   [REG_ENABLE]= 0x84,
-   [REG_PERF_STATE]= 0x88,
+   [REG_FREQ_LUT_TABLE]= 0x0,
+   [REG_FREQ_ENABLE]   = 0x84,
+   [REG_FREQ_PERF_STATE]   = 0x88,
+   [REG_EM_POWER_TBL]  = 0x3D0,
 };
 
 static struct cpufreq_mtk *mtk_freq_domain_map[NR_CPUS];
 
+static int mtk_cpufreq_get_cpu_power(unsigned long *mW,
+unsigned long *KHz, int cpu)
+{
+   struct cpufreq_mtk *c = mtk_freq_domain_map[cpu];
+   int i;
+
+   for (i = 0; i < c->nr_opp; i++) {
+   if (c->table[i].frequency < *KHz)
+   break;
+   }
+   i--;
+
+   *KHz = c->table[i].frequency;
+   *mW = readl_relaxed(c->reg_bases[REG_EM_POWER_TBL] +
+   i * LUT_ROW_SIZE) / 1000;
+
+   return 0;
+}
+
 static int mtk_cpufreq_hw_target_index(struct cpufreq_policy *policy,
   unsigned int index)
 {
struct cpufreq_mtk *c = policy->driver_data;
 
-   writel_relaxed(index, c->reg_bases[REG_PERF_STATE]);
+   writel_relaxed(index, c->reg_bases[REG_FREQ_PERF_STATE]);
 
return 0;
 }
@@ -55,7 +78,7 @@ static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)
 
c = mtk_freq_domain_map[cpu];
 
-   index = readl_relaxed(c->reg_bases[REG_PERF_STATE]);
+   index = readl_relaxed(c->reg_bases[REG_FREQ_PERF_STATE]);
index = min(index, LUT_MAX_ENTRIES - 1);
 
return c->table[index].frequency;
@@ -64,6 +87,7 @@ static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)
 static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
 {
struct cpufreq_mtk *c;
+   struct em_data_callback em_cb = EM_DATA_CB(mtk_cpufreq_get_cpu_power);
 
c = mtk_freq_domain_map[policy->cpu];
if (!c) {
@@ -77,7 +101,8 @@ static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy 
*policy)
policy->driver_data = c;
 
/* HW should be in enabled state to proceed now */
-   writel_relaxed(0x1, c->reg_bases[REG_ENABLE]);
+   writel_relaxed(0x1, c->reg_bases[REG_FREQ_ENABLE]);
+   em_register_perf_domain(policy->cpus, c->nr_opp, _cb);
 
return 0;
 }
@@ -93,7 +118,7 @@ static int mtk_cpufreq_hw_cpu_exit(struct cpufreq_policy 
*policy)
}
 
/* HW should be in paused state now */
-   writel_relaxed(0x0, c->reg_bases[REG_ENABLE]);
+   writel_relaxed(0x0, c->reg_bases[REG_FREQ_ENABLE]);
 
return 0;
 }
@@ -122,7 +147,7 @@ static int mtk_cpu_create_freq_table(struct platform_device 
*pdev,
if (!c->table)
return -ENOMEM;
 
-   base_table = c->reg_bases[REG_LUT_TABLE];
+   base_table = c->reg_bases[REG_FREQ_LUT_TABLE];
 
for (i = 0; i < LUT_MAX_ENTRIES; i++) {
data = readl_relaxed(base_table + (i * LUT_ROW_SIZE));
@@ -140,6 +165,7 @@ static int mtk_cpu_create_freq_table(struct platform_device 
*pdev,
}
 
c->table[i].frequency = CPUFREQ_TABLE_END;
+   c->nr_opp = i;
 
return 0;
 }
@@ -192,7 +218,7 @@ static int mtk_cpu_resources_init(struct platform_device 
*pdev,
if (IS_ERR(base))
return PTR_ERR(base);
 
-   for (i = REG_LUT_TABLE; i < REG_ARRAY_SIZE; i++)
+   for (i = REG_FREQ_LUT_TABLE; i < REG_ARRAY_SIZE; i++)
c->reg_bases[i] = base + offsets[i];
 
ret = mtk_get_related_cpus(index, c);
-- 
1.7.9.5


Re: [PATCH v7 2/2] dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

2020-10-04 Thread Hector Yuan
On Fri, 2020-09-25 at 15:25 +0800, Hector Yuan wrote:
> Hi, Rob sir:
> 
> Yes, my patch follows
> Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt way to
> define frequency domain.
> Is it OK to you if I use the same way to do?
> And if there exist any schema problem, please kindly let me know how to
> fix it.
> 
> My patch reference
> Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml
> to use the cpu node.
> https://elixir.bootlin.com/linux/v5.9-rc6/source/Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml
> 
> Thanks a lot.
> 
Hi, Rob sir:

Sorry to bother you, may we know your comment for this.
Thanks so much. 

> On Fri, 2020-09-25 at 11:45 +0530, Viresh Kumar wrote:
> > On 25-09-20, 10:27, Hector Yuan wrote:
> > > Hi, Viresh & Rob Sir:
> > > 
> > > I will change frequency domain to below and define it in cpufreq_hw
> > > schema rather than cpu node.
> > > 
> > > mediatek,freq-domain-0 = <>, <>;
> > 
> > I think it would be better to do it the standard way we have done it 
> > elsewhere.
> > i.e. follow Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt, 
> > that
> > is similar to what you did earlier.
> > 
> 



Re: [PATCH v7 2/2] dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

2020-09-25 Thread Hector Yuan
Hi, Rob sir:

Yes, my patch follows
Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt way to
define frequency domain.
Is it OK to you if I use the same way to do?
And if there exist any schema problem, please kindly let me know how to
fix it.

My patch reference
Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml
to use the cpu node.
https://elixir.bootlin.com/linux/v5.9-rc6/source/Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml

Thanks a lot.

On Fri, 2020-09-25 at 11:45 +0530, Viresh Kumar wrote:
> On 25-09-20, 10:27, Hector Yuan wrote:
> > Hi, Viresh & Rob Sir:
> > 
> > I will change frequency domain to below and define it in cpufreq_hw
> > schema rather than cpu node.
> > 
> > mediatek,freq-domain-0 = <>, <>;
> 
> I think it would be better to do it the standard way we have done it 
> elsewhere.
> i.e. follow Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt, 
> that
> is similar to what you did earlier.
> 



Re: [PATCH v7 2/2] dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

2020-09-24 Thread Hector Yuan
Hi, Viresh & Rob Sir:

I will change frequency domain to below and define it in cpufreq_hw
schema rather than cpu node.

mediatek,freq-domain-0 = <>, <>;

Is it OK to you?
Or you think OPP define is a better solution?

opp-table-0 {
compatible = "mediatek,hw-operating-points", "operating-points-v2";
};

Thank you for the opinions.



On Wed, 2020-09-23 at 21:10 +0800, Hector Yuan wrote:
> On Tue, 2020-09-22 at 14:28 -0600, Rob Herring wrote:
> > On Thu, Sep 10, 2020 at 12:31:02PM +0800, Hector Yuan wrote:
> > > From: "Hector.Yuan" 
> > > 
> > > Add devicetree bindings for MediaTek HW driver.
> > > 
> > > Signed-off-by: Hector.Yuan 
> > > ---
> > >  .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |  141 
> > > 
> > >  1 file changed, 141 insertions(+)
> > >  create mode 100644 
> > > Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> > > 
> > > diff --git 
> > > a/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml 
> > > b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> > > new file mode 100644
> > > index 000..118a163
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> > > @@ -0,0 +1,141 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id: http://devicetree.org/schemas/cpufreq/cpufreq-mediatek-hw.yaml#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: MediaTek's CPUFREQ Bindings
> > > +
> > > +maintainers:
> > > +  - Hector Yuan 
> > > +
> > > +description:
> > > +  CPUFREQ HW is a hardware engine used by MediaTek
> > > +  SoCs to manage frequency in hardware. It is capable of controlling 
> > > frequency
> > > +  for multiple clusters.
> > > +
> > > +properties:
> > > +  compatible:
> > > +const: "mediatek,cpufreq-hw"
> > 
> > Needs to be SoC specific. This stuff is never constant from one SoC to 
> > the next. 'cpufreq' is a Linuxism. What's the block called in the 
> > datasheet? Use that.
> > 
> OK, will use mediatek,sspm-dvfs-mt6779 instead.
> > Don't need quotes either.
> > 
> OK, will remove it.
> > > +
> > > +  reg:
> > > +minItems: 1
> > > +maxItems: 2
> > > +description: |
> > > +  Addresses and sizes for the memory of the HW bases in each 
> > > frequency domain.
> > > +
> > > +  reg-names:
> > > +items:
> > > +  - const: "freq-domain0"
> > > +  - const: "freq-domain1"
> > 
> > Kind of pointless to have names based on the index. Drop 'reg-names'.
> > 
> OK, will drop it.
> > > +description: |
> > > +  Frequency domain name. i.e.
> > > +  "freq-domain0", "freq-domain1".
> > > +
> > > +  "#freq-domain-cells":
> > > +const: 1
> > > +description: |
> > > +  Number of cells in a freqency domain specifier.
> > 
> > You don't need this. It's not a common binding that's going to vary.
> > 
> OK, will remove it.
> > > +
> > > +  mtk-freq-domain:
> > > +maxItems: 1
> > > +description: |
> > > +  Define this cpu belongs to which frequency domain. i.e.
> > > +  cpu0-3 belong to frequency domain0,
> > > +  cpu4-6 belong to frequency domain1.
> > 
> > This property doesn't go in the 'mediatek,cpufreq-hw' node. You would 
> > need a separate schema. However, I think the easiest thing to do here is 
> > something like this:
> > 
> > mediatek,freq-domain-0 = <>, <>;
> > 
> Sorry, may I know the reason and the details about how to separate
> schema? Thank you very much.
> 
> The numbers of frequency domain may be vary from different projects. If
> I do the easier way, I may need to implement extra loop to check how
> many frequency domain.
> > Or you could just re-use the OPP binding with just 0 entries:
> > 
> > opp-table-0 {
> >   compatible = "mediatek,hw-operating-points", "operating-points-v2";
> > };
> > opp-table-1 {
> >   compatible = "mediatek,hw-operating-points", "operating-points-v2";
> > };
> > 
> In previous review stage, already abandon OPP

Re: [PATCH v7 2/2] dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

2020-09-23 Thread Hector Yuan
On Wed, 2020-09-23 at 21:10 +0800, Hector Yuan wrote:
> On Tue, 2020-09-22 at 14:28 -0600, Rob Herring wrote:
> > On Thu, Sep 10, 2020 at 12:31:02PM +0800, Hector Yuan wrote:
> > > From: "Hector.Yuan" 
> > > 
> > > Add devicetree bindings for MediaTek HW driver.
> > > 
> > > Signed-off-by: Hector.Yuan 
> > > ---
> > >  .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |  141 
> > > 
> > >  1 file changed, 141 insertions(+)
> > >  create mode 100644 
> > > Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> > > 
> > > diff --git 
> > > a/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml 
> > > b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> > > new file mode 100644
> > > index 000..118a163
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> > > @@ -0,0 +1,141 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id: http://devicetree.org/schemas/cpufreq/cpufreq-mediatek-hw.yaml#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: MediaTek's CPUFREQ Bindings
> > > +
> > > +maintainers:
> > > +  - Hector Yuan 
> > > +
> > > +description:
> > > +  CPUFREQ HW is a hardware engine used by MediaTek
> > > +  SoCs to manage frequency in hardware. It is capable of controlling 
> > > frequency
> > > +  for multiple clusters.
> > > +
> > > +properties:
> > > +  compatible:
> > > +const: "mediatek,cpufreq-hw"
> > 
> > Needs to be SoC specific. This stuff is never constant from one SoC to 
> > the next. 'cpufreq' is a Linuxism. What's the block called in the 
> > datasheet? Use that.
> > 
> OK, will use mediatek,sspm-dvfs-mt6779 instead.
> > Don't need quotes either.
> > 
> OK, will remove it.
> > > +
> > > +  reg:
> > > +minItems: 1
> > > +maxItems: 2
> > > +description: |
> > > +  Addresses and sizes for the memory of the HW bases in each 
> > > frequency domain.
> > > +
> > > +  reg-names:
> > > +items:
> > > +  - const: "freq-domain0"
> > > +  - const: "freq-domain1"
> > 
> > Kind of pointless to have names based on the index. Drop 'reg-names'.
> > 
> OK, will drop it.
> > > +description: |
> > > +  Frequency domain name. i.e.
> > > +  "freq-domain0", "freq-domain1".
> > > +
> > > +  "#freq-domain-cells":
> > > +const: 1
> > > +description: |
> > > +  Number of cells in a freqency domain specifier.
> > 
> > You don't need this. It's not a common binding that's going to vary.
> > 
> OK, will remove it.
> > > +
> > > +  mtk-freq-domain:
> > > +maxItems: 1
> > > +description: |
> > > +  Define this cpu belongs to which frequency domain. i.e.
> > > +  cpu0-3 belong to frequency domain0,
> > > +  cpu4-6 belong to frequency domain1.
> > 
> > This property doesn't go in the 'mediatek,cpufreq-hw' node. You would 
> > need a separate schema. However, I think the easiest thing to do here is 
> > something like this:
> > 
> > mediatek,freq-domain-0 = <>, <>;
> > 
> Sorry, may I know the reason and the details about how to separate
> schema? Thank you very much.
> 
Actually, I referenced the thermal-cooling-devices and send my yaml for
review.
https://elixir.bootlin.com/linux/v5.9-rc6/source/Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml
It used cpu node for cooling device, and thermal schema use it.
Appreciated for any details.

> The numbers of frequency domain may be vary from different projects. If
> I do the easier way, I may need to implement extra loop to check how
> many frequency domain.
> > Or you could just re-use the OPP binding with just 0 entries:
> > 
> > opp-table-0 {
> >   compatible = "mediatek,hw-operating-points", "operating-points-v2";
> > };
> > opp-table-1 {
> >   compatible = "mediatek,hw-operating-points", "operating-points-v2";
> > };
> > 
> In previous review stage, already abandon OPP framework in driver code.
> Will check with Viresh to see if its OK to add OP

Re: [PATCH v7 2/2] dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

2020-09-23 Thread Hector Yuan
On Tue, 2020-09-22 at 14:28 -0600, Rob Herring wrote:
> On Thu, Sep 10, 2020 at 12:31:02PM +0800, Hector Yuan wrote:
> > From: "Hector.Yuan" 
> > 
> > Add devicetree bindings for MediaTek HW driver.
> > 
> > Signed-off-by: Hector.Yuan 
> > ---
> >  .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |  141 
> > 
> >  1 file changed, 141 insertions(+)
> >  create mode 100644 
> > Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> > 
> > diff --git 
> > a/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml 
> > b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> > new file mode 100644
> > index 000..118a163
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> > @@ -0,0 +1,141 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/cpufreq/cpufreq-mediatek-hw.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: MediaTek's CPUFREQ Bindings
> > +
> > +maintainers:
> > +  - Hector Yuan 
> > +
> > +description:
> > +  CPUFREQ HW is a hardware engine used by MediaTek
> > +  SoCs to manage frequency in hardware. It is capable of controlling 
> > frequency
> > +  for multiple clusters.
> > +
> > +properties:
> > +  compatible:
> > +const: "mediatek,cpufreq-hw"
> 
> Needs to be SoC specific. This stuff is never constant from one SoC to 
> the next. 'cpufreq' is a Linuxism. What's the block called in the 
> datasheet? Use that.
> 
OK, will use mediatek,sspm-dvfs-mt6779 instead.
> Don't need quotes either.
> 
OK, will remove it.
> > +
> > +  reg:
> > +minItems: 1
> > +maxItems: 2
> > +description: |
> > +  Addresses and sizes for the memory of the HW bases in each frequency 
> > domain.
> > +
> > +  reg-names:
> > +items:
> > +  - const: "freq-domain0"
> > +  - const: "freq-domain1"
> 
> Kind of pointless to have names based on the index. Drop 'reg-names'.
> 
OK, will drop it.
> > +description: |
> > +  Frequency domain name. i.e.
> > +  "freq-domain0", "freq-domain1".
> > +
> > +  "#freq-domain-cells":
> > +const: 1
> > +description: |
> > +  Number of cells in a freqency domain specifier.
> 
> You don't need this. It's not a common binding that's going to vary.
> 
OK, will remove it.
> > +
> > +  mtk-freq-domain:
> > +maxItems: 1
> > +description: |
> > +  Define this cpu belongs to which frequency domain. i.e.
> > +  cpu0-3 belong to frequency domain0,
> > +  cpu4-6 belong to frequency domain1.
> 
> This property doesn't go in the 'mediatek,cpufreq-hw' node. You would 
> need a separate schema. However, I think the easiest thing to do here is 
> something like this:
> 
> mediatek,freq-domain-0 = <>, <>;
> 
Sorry, may I know the reason and the details about how to separate
schema? Thank you very much.

The numbers of frequency domain may be vary from different projects. If
I do the easier way, I may need to implement extra loop to check how
many frequency domain.
> Or you could just re-use the OPP binding with just 0 entries:
> 
> opp-table-0 {
>   compatible = "mediatek,hw-operating-points", "operating-points-v2";
> };
> opp-table-1 {
>   compatible = "mediatek,hw-operating-points", "operating-points-v2";
> };
> 
In previous review stage, already abandon OPP framework in driver code.
Will check with Viresh to see if its OK to add OPP back.
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - reg-names
> > +  - "#freq-domain-cells"
> > +
> > +examples:
> > +  - |
> > +cpus {
> > +#address-cells = <1>;
> > +#size-cells = <0>;
> > +
> > +cpu0: cpu@0 {
> > +device_type = "cpu";
> > +compatible = "arm,cortex-a55";
> > +enable-method = "psci";
> > +mtk-freq-domain = <_hw 0>;
> > +reg = <0x000>;
> > +};
> > +
> > +cpu1: cpu@1 {
> 
> Unit address is wrong.
> 
OK, will modify to "cpu1 : cpu@100" if we still decide to put
freq_domain in CPU node.
> >

Re: [PATCH v7 2/2] dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

2020-09-20 Thread Hector Yuan
Hi, Rob sir:

Sorry to bother you, may I have your review comment for the binding
part?
Appreciated.

On Thu, 2020-09-10 at 12:31 +0800, Hector Yuan wrote:
> From: "Hector.Yuan" 
> 
> Add devicetree bindings for MediaTek HW driver.
> 
> Signed-off-by: Hector.Yuan 
> ---
>  .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |  141 
> 
>  1 file changed, 141 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> 
> diff --git 
> a/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml 
> b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> new file mode 100644
> index 000..118a163
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> @@ -0,0 +1,141 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/cpufreq/cpufreq-mediatek-hw.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek's CPUFREQ Bindings
> +
> +maintainers:
> +  - Hector Yuan 
> +
> +description:
> +  CPUFREQ HW is a hardware engine used by MediaTek
> +  SoCs to manage frequency in hardware. It is capable of controlling 
> frequency
> +  for multiple clusters.
> +
> +properties:
> +  compatible:
> +const: "mediatek,cpufreq-hw"
> +
> +  reg:
> +minItems: 1
> +maxItems: 2
> +description: |
> +  Addresses and sizes for the memory of the HW bases in each frequency 
> domain.
> +
> +  reg-names:
> +items:
> +  - const: "freq-domain0"
> +  - const: "freq-domain1"
> +description: |
> +  Frequency domain name. i.e.
> +  "freq-domain0", "freq-domain1".
> +
> +  "#freq-domain-cells":
> +const: 1
> +description: |
> +  Number of cells in a freqency domain specifier.
> +
> +  mtk-freq-domain:
> +maxItems: 1
> +description: |
> +  Define this cpu belongs to which frequency domain. i.e.
> +  cpu0-3 belong to frequency domain0,
> +  cpu4-6 belong to frequency domain1.
> +
> +required:
> +  - compatible
> +  - reg
> +  - reg-names
> +  - "#freq-domain-cells"
> +
> +examples:
> +  - |
> +cpus {
> +#address-cells = <1>;
> +#size-cells = <0>;
> +
> +cpu0: cpu@0 {
> +device_type = "cpu";
> +compatible = "arm,cortex-a55";
> +enable-method = "psci";
> +mtk-freq-domain = <_hw 0>;
> +reg = <0x000>;
> +};
> +
> +cpu1: cpu@1 {
> +device_type = "cpu";
> +compatible = "arm,cortex-a55";
> +enable-method = "psci";
> +mtk-freq-domain = <_hw 0>;
> +reg = <0x100>;
> +};
> +
> +cpu2: cpu@2 {
> +device_type = "cpu";
> +compatible = "arm,cortex-a55";
> +enable-method = "psci";
> +mtk-freq-domain = <_hw 0>;
> +reg = <0x200>;
> +};
> +
> +cpu3: cpu@3 {
> +device_type = "cpu";
> +compatible = "arm,cortex-a55";
> +enable-method = "psci";
> +mtk-freq-domain = <_hw 0>;
> +reg = <0x300>;
> +};
> +
> +cpu4: cpu@4 {
> +device_type = "cpu";
> +compatible = "arm,cortex-a55";
> +enable-method = "psci";
> +mtk-freq-domain = <_hw 1>;
> +reg = <0x400>;
> +};
> +
> +cpu5: cpu@5 {
> +device_type = "cpu";
> +compatible = "arm,cortex-a55";
> +enable-method = "psci";
> +mtk-freq-domain = <_hw 1>;
> +reg = <0x500>;
> +};
> +
> +cpu6: cpu@6 {
> +device_type = "cpu";
> +compatible = "arm,cortex-a75";
> +enable-method = "psci";
> +mtk-freq-domain = <_hw 1>;
> +reg = <0x600>;
> +};
> +
> +cpu7: cpu@7 {
> +device_type = "cpu";
> +compatible = "arm,cortex-a75";
> +enable-method = "psci";
> +mtk-freq-domain = <_hw 1>;
> +reg = <0x700>;
> +};
> +};
> +
> +/* ... */
> +
> +soc {
> +#address-cells = <2>;
> +#size-cells = <2>;
> +
> +cpufreq_hw: cpufreq@11bc00 {
> +compatible = "mediatek,cpufreq-hw";
> +reg = <0 0x11bc10 0 0x8c>,
> +   <0 0x11bca0 0 0x8c>;
> +reg-names = "freq-domain0", "freq-domain1";
> +#freq-domain-cells = <1>;
> +};
> +};
> +
> +
> +
> +



Re: [PATCH v7] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2020-09-16 Thread Hector Yuan
Hi, Rob sir:

Sorry to bother you, may I have your review comment for the binding
part?
Appreciated.

On Wed, 2020-09-16 at 19:39 +0800, Hector Yuan wrote:
> Hi, Rob sir:
> 
> Sorry to bother you, may I have your review comment for the binding
> part?
> Appreciated.
> 
> On Thu, 2020-09-10 at 11:04 +0530, Viresh Kumar wrote:
> > On 10-09-20, 13:30, Hector Yuan wrote:
> > > On Thu, 2020-09-10 at 10:33 +0530, Viresh Kumar wrote:
> > > > On 10-09-20, 12:31, Hector Yuan wrote:
> > > > > The CPUfreq HW present in some Mediatek chipsets offloads the steps 
> > > > > necessary for changing the frequency of CPUs. 
> > > > > The driver implements the cpufreq driver interface for this hardware 
> > > > > engine. 
> > > > > 
> > > > > This patch depends on the MT6779 DTS patch submitted by Hanks Chen
> > > > >  https://lkml.org/lkml/2020/8/4/1094
> > > > 
> > > > Thanks for hanging there. Looks good to me. I will apply it once Rob
> > > > Ack's the binding patch.
> > > > 
> > > 
> > > Many thanks for your help. May I know if you can add Reviewed-by tag to
> > > this patch set.
> > 
> > Since this patchset is going to get merged via my tree (ARM cpufreq
> > tree), a reviewed-by isn't required here. I will queue it up for
> > 5.10-rc1 after I receive an Ack from Rob.
> > 
> > > I would like to prepare some patches for more features
> > > based on this. Is that okay to you? Thanks again.
> > 
> > That should be fine.
> > 
> 
> 



Re: [PATCH v7] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2020-09-16 Thread Hector Yuan
Hi, Rob sir:

Sorry to bother you, may I have your review comment for the binding
part?
Appreciated.

On Thu, 2020-09-10 at 11:04 +0530, Viresh Kumar wrote:
> On 10-09-20, 13:30, Hector Yuan wrote:
> > On Thu, 2020-09-10 at 10:33 +0530, Viresh Kumar wrote:
> > > On 10-09-20, 12:31, Hector Yuan wrote:
> > > > The CPUfreq HW present in some Mediatek chipsets offloads the steps 
> > > > necessary for changing the frequency of CPUs. 
> > > > The driver implements the cpufreq driver interface for this hardware 
> > > > engine. 
> > > > 
> > > > This patch depends on the MT6779 DTS patch submitted by Hanks Chen
> > > >  https://lkml.org/lkml/2020/8/4/1094
> > > 
> > > Thanks for hanging there. Looks good to me. I will apply it once Rob
> > > Ack's the binding patch.
> > > 
> > 
> > Many thanks for your help. May I know if you can add Reviewed-by tag to
> > this patch set.
> 
> Since this patchset is going to get merged via my tree (ARM cpufreq
> tree), a reviewed-by isn't required here. I will queue it up for
> 5.10-rc1 after I receive an Ack from Rob.
> 
> > I would like to prepare some patches for more features
> > based on this. Is that okay to you? Thanks again.
> 
> That should be fine.
> 




Re: [PATCH v7] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2020-09-09 Thread Hector Yuan
On Thu, 2020-09-10 at 10:33 +0530, Viresh Kumar wrote:
> On 10-09-20, 12:31, Hector Yuan wrote:
> > The CPUfreq HW present in some Mediatek chipsets offloads the steps 
> > necessary for changing the frequency of CPUs. 
> > The driver implements the cpufreq driver interface for this hardware 
> > engine. 
> > 
> > This patch depends on the MT6779 DTS patch submitted by Hanks Chen
> >  https://lkml.org/lkml/2020/8/4/1094
> 
> Thanks for hanging there. Looks good to me. I will apply it once Rob
> Ack's the binding patch.
> 

Many thanks for your help. May I know if you can add Reviewed-by tag to
this patch set. I would like to prepare some patches for more features
based on this. Is that okay to you? Thanks again.


[PATCH v7] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2020-09-09 Thread Hector Yuan
The CPUfreq HW present in some Mediatek chipsets offloads the steps necessary 
for changing the frequency of CPUs. 
The driver implements the cpufreq driver interface for this hardware engine. 

This patch depends on the MT6779 DTS patch submitted by Hanks Chen
 https://lkml.org/lkml/2020/8/4/1094


Hector.Yuan (2):
  cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver
  dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

 .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |  141 ++
 drivers/cpufreq/Kconfig.arm|   12 +
 drivers/cpufreq/Makefile   |1 +
 drivers/cpufreq/mediatek-cpufreq-hw.c  |  277 
 4 files changed, 431 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
 create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw.c

[PATCH v7 2/2] dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

2020-09-09 Thread Hector Yuan
From: "Hector.Yuan" 

Add devicetree bindings for MediaTek HW driver.

Signed-off-by: Hector.Yuan 
---
 .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |  141 
 1 file changed, 141 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml

diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml 
b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
new file mode 100644
index 000..118a163
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
@@ -0,0 +1,141 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/cpufreq/cpufreq-mediatek-hw.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek's CPUFREQ Bindings
+
+maintainers:
+  - Hector Yuan 
+
+description:
+  CPUFREQ HW is a hardware engine used by MediaTek
+  SoCs to manage frequency in hardware. It is capable of controlling frequency
+  for multiple clusters.
+
+properties:
+  compatible:
+const: "mediatek,cpufreq-hw"
+
+  reg:
+minItems: 1
+maxItems: 2
+description: |
+  Addresses and sizes for the memory of the HW bases in each frequency 
domain.
+
+  reg-names:
+items:
+  - const: "freq-domain0"
+  - const: "freq-domain1"
+description: |
+  Frequency domain name. i.e.
+  "freq-domain0", "freq-domain1".
+
+  "#freq-domain-cells":
+const: 1
+description: |
+  Number of cells in a freqency domain specifier.
+
+  mtk-freq-domain:
+maxItems: 1
+description: |
+  Define this cpu belongs to which frequency domain. i.e.
+  cpu0-3 belong to frequency domain0,
+  cpu4-6 belong to frequency domain1.
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - "#freq-domain-cells"
+
+examples:
+  - |
+cpus {
+#address-cells = <1>;
+#size-cells = <0>;
+
+cpu0: cpu@0 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mtk-freq-domain = <_hw 0>;
+reg = <0x000>;
+};
+
+cpu1: cpu@1 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mtk-freq-domain = <_hw 0>;
+reg = <0x100>;
+};
+
+cpu2: cpu@2 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mtk-freq-domain = <_hw 0>;
+reg = <0x200>;
+};
+
+cpu3: cpu@3 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mtk-freq-domain = <_hw 0>;
+reg = <0x300>;
+};
+
+cpu4: cpu@4 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mtk-freq-domain = <_hw 1>;
+reg = <0x400>;
+};
+
+cpu5: cpu@5 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mtk-freq-domain = <_hw 1>;
+reg = <0x500>;
+};
+
+cpu6: cpu@6 {
+device_type = "cpu";
+compatible = "arm,cortex-a75";
+enable-method = "psci";
+mtk-freq-domain = <_hw 1>;
+reg = <0x600>;
+};
+
+cpu7: cpu@7 {
+device_type = "cpu";
+compatible = "arm,cortex-a75";
+enable-method = "psci";
+mtk-freq-domain = <_hw 1>;
+reg = <0x700>;
+};
+};
+
+/* ... */
+
+soc {
+#address-cells = <2>;
+#size-cells = <2>;
+
+cpufreq_hw: cpufreq@11bc00 {
+compatible = "mediatek,cpufreq-hw";
+reg = <0 0x11bc10 0 0x8c>,
+   <0 0x11bca0 0 0x8c>;
+reg-names = "freq-domain0", "freq-domain1";
+#freq-domain-cells = <1>;
+};
+};
+
+
+
+
-- 
1.7.9.5


[PATCH v7 1/2] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2020-09-09 Thread Hector Yuan
From: "Hector.Yuan" 

Add MT6779 cpufreq HW support.

Signed-off-by: Hector.Yuan 
---
 drivers/cpufreq/Kconfig.arm   |   12 ++
 drivers/cpufreq/Makefile  |1 +
 drivers/cpufreq/mediatek-cpufreq-hw.c |  277 +
 3 files changed, 290 insertions(+)
 create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw.c

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index c6cbfc8..8e58c12 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -121,6 +121,18 @@ config ARM_MEDIATEK_CPUFREQ
help
  This adds the CPUFreq driver support for MediaTek SoCs.
 
+config ARM_MEDIATEK_CPUFREQ_HW
+   tristate "MediaTek CPUFreq HW driver"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   default m
+   help
+ Support for the CPUFreq HW driver.
+ Some MediaTek chipsets have a HW engine to offload the steps
+ necessary for changing the frequency of the CPUs. Firmware loaded
+ in this engine exposes a programming interface to the OS.
+ The driver implements the cpufreq interface for this HW engine.
+ Say Y if you want to support CPUFreq HW.
+
 config ARM_OMAP2PLUS_CPUFREQ
bool "TI OMAP2+"
depends on ARCH_OMAP2PLUS
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index f6670c4..dc1f371 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ)   += 
imx6q-cpufreq.o
 obj-$(CONFIG_ARM_IMX_CPUFREQ_DT)   += imx-cpufreq-dt.o
 obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o
 obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ) += mediatek-cpufreq.o
+obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ_HW)  += mediatek-cpufreq-hw.o
 obj-$(CONFIG_MACH_MVEBU_V7)+= mvebu-cpufreq.o
 obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)+= omap-cpufreq.o
 obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)   += pxa2xx-cpufreq.o
diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c 
b/drivers/cpufreq/mediatek-cpufreq-hw.c
new file mode 100644
index 000..8fa12e5
--- /dev/null
+++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
@@ -0,0 +1,277 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define LUT_MAX_ENTRIES32U
+#define LUT_FREQ   GENMASK(11, 0)
+#define LUT_ROW_SIZE   0x4
+
+enum {
+   REG_LUT_TABLE,
+   REG_ENABLE,
+   REG_PERF_STATE,
+
+   REG_ARRAY_SIZE,
+};
+
+struct cpufreq_mtk {
+   struct cpufreq_frequency_table *table;
+   void __iomem *reg_bases[REG_ARRAY_SIZE];
+   cpumask_t related_cpus;
+};
+
+static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = {
+   [REG_LUT_TABLE] = 0x0,
+   [REG_ENABLE]= 0x84,
+   [REG_PERF_STATE]= 0x88,
+};
+
+static struct cpufreq_mtk *mtk_freq_domain_map[NR_CPUS];
+
+static int mtk_cpufreq_hw_target_index(struct cpufreq_policy *policy,
+  unsigned int index)
+{
+   struct cpufreq_mtk *c = policy->driver_data;
+
+   writel_relaxed(index, c->reg_bases[REG_PERF_STATE]);
+
+   return 0;
+}
+
+static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)
+{
+   struct cpufreq_mtk *c;
+   unsigned int index;
+
+   c = mtk_freq_domain_map[cpu];
+
+   index = readl_relaxed(c->reg_bases[REG_PERF_STATE]);
+   index = min(index, LUT_MAX_ENTRIES - 1);
+
+   return c->table[index].frequency;
+}
+
+static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
+{
+   struct cpufreq_mtk *c;
+
+   c = mtk_freq_domain_map[policy->cpu];
+   if (!c) {
+   pr_err("No scaling support for CPU%d\n", policy->cpu);
+   return -ENODEV;
+   }
+
+   cpumask_copy(policy->cpus, >related_cpus);
+
+   policy->freq_table = c->table;
+   policy->driver_data = c;
+
+   /* HW should be in enabled state to proceed now */
+   writel_relaxed(0x1, c->reg_bases[REG_ENABLE]);
+
+   return 0;
+}
+
+static int mtk_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy)
+{
+   struct cpufreq_mtk *c;
+
+   c = mtk_freq_domain_map[policy->cpu];
+   if (!c) {
+   pr_err("No scaling support for CPU%d\n", policy->cpu);
+   return -ENODEV;
+   }
+
+   /* HW should be in paused state now */
+   writel_relaxed(0x0, c->reg_bases[REG_ENABLE]);
+
+   return 0;
+}
+
+static struct cpufreq_driver cpufreq_mtk_hw_driver = {
+   .flags  = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK |
+ CPUFREQ_HAVE_GOVERNOR_PER_POLICY,
+   .verify = cpufreq_generic_frequency_table_verify,
+   .target_index   = mtk_cpufreq_hw_target_index,
+   .get= mtk_cpufreq_hw_get,
+   .init   = mtk_cpufreq_hw_cpu_init,
+   .exit   = 

Re: [PATCH v6 1/2] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2020-09-09 Thread Hector Yuan
On Thu, 2020-09-10 at 09:12 +0530, Viresh Kumar wrote:
> On 09-09-20, 21:34, Hector Yuan wrote:
> > +static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)
> > +{
> > +   struct cpufreq_mtk *c;
> > +   struct cpufreq_policy *policy;
> > +   unsigned int index;
> > +
> > +   policy = cpufreq_cpu_get_raw(cpu);
> > +   if (!policy)
> > +   return 0;
> 
> Why didn't you drop policy as we discussed in previous version ?
> 
Sorry I missed that. Thank you.
> > +   c = mtk_freq_domain_map[cpu];
> > +
> > +   index = readl_relaxed(c->reg_bases[REG_PERF_STATE]);
> > +   index = min(index, LUT_MAX_ENTRIES - 1);
> > +
> > +   return policy->freq_table[index].frequency;
> 
> policy->freq_table and c->table are same, isn't it ?
> 
Yes, you are right.
> > +}
> > +
> > +static struct platform_driver mtk_cpufreq_hw_driver = {
> > +   .probe = mtk_cpufreq_hw_driver_probe,
> > +   .remove = mtk_cpufreq_hw_driver_remove,
> > +   .driver = {
> > +   .name = "mtk-cpufreq-hw",
> > +   .of_match_table = mtk_cpufreq_hw_match,
> > +   },
> > +};
> > +
> 
> Remove this blank line.
> 
OK
> > +module_platform_driver(mtk_cpufreq_hw_driver);
> > +
> > +MODULE_DESCRIPTION("mtk CPUFREQ HW Driver");
> 
> Maybe write this is "Mediatek cpufreq-hw driver" ?
> 
OK
> > +MODULE_LICENSE("GPL v2");
> > -- 
> > 1.7.9.5
> 



[PATCH v6 2/2] dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

2020-09-09 Thread Hector Yuan
From: "Hector.Yuan" 

Add devicetree bindings for MediaTek HW driver.

Signed-off-by: Hector.Yuan 
---
 .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |  141 
 1 file changed, 141 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml

diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml 
b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
new file mode 100644
index 000..118a163
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
@@ -0,0 +1,141 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/cpufreq/cpufreq-mediatek-hw.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek's CPUFREQ Bindings
+
+maintainers:
+  - Hector Yuan 
+
+description:
+  CPUFREQ HW is a hardware engine used by MediaTek
+  SoCs to manage frequency in hardware. It is capable of controlling frequency
+  for multiple clusters.
+
+properties:
+  compatible:
+const: "mediatek,cpufreq-hw"
+
+  reg:
+minItems: 1
+maxItems: 2
+description: |
+  Addresses and sizes for the memory of the HW bases in each frequency 
domain.
+
+  reg-names:
+items:
+  - const: "freq-domain0"
+  - const: "freq-domain1"
+description: |
+  Frequency domain name. i.e.
+  "freq-domain0", "freq-domain1".
+
+  "#freq-domain-cells":
+const: 1
+description: |
+  Number of cells in a freqency domain specifier.
+
+  mtk-freq-domain:
+maxItems: 1
+description: |
+  Define this cpu belongs to which frequency domain. i.e.
+  cpu0-3 belong to frequency domain0,
+  cpu4-6 belong to frequency domain1.
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - "#freq-domain-cells"
+
+examples:
+  - |
+cpus {
+#address-cells = <1>;
+#size-cells = <0>;
+
+cpu0: cpu@0 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mtk-freq-domain = <_hw 0>;
+reg = <0x000>;
+};
+
+cpu1: cpu@1 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mtk-freq-domain = <_hw 0>;
+reg = <0x100>;
+};
+
+cpu2: cpu@2 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mtk-freq-domain = <_hw 0>;
+reg = <0x200>;
+};
+
+cpu3: cpu@3 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mtk-freq-domain = <_hw 0>;
+reg = <0x300>;
+};
+
+cpu4: cpu@4 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mtk-freq-domain = <_hw 1>;
+reg = <0x400>;
+};
+
+cpu5: cpu@5 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mtk-freq-domain = <_hw 1>;
+reg = <0x500>;
+};
+
+cpu6: cpu@6 {
+device_type = "cpu";
+compatible = "arm,cortex-a75";
+enable-method = "psci";
+mtk-freq-domain = <_hw 1>;
+reg = <0x600>;
+};
+
+cpu7: cpu@7 {
+device_type = "cpu";
+compatible = "arm,cortex-a75";
+enable-method = "psci";
+mtk-freq-domain = <_hw 1>;
+reg = <0x700>;
+};
+};
+
+/* ... */
+
+soc {
+#address-cells = <2>;
+#size-cells = <2>;
+
+cpufreq_hw: cpufreq@11bc00 {
+compatible = "mediatek,cpufreq-hw";
+reg = <0 0x11bc10 0 0x8c>,
+   <0 0x11bca0 0 0x8c>;
+reg-names = "freq-domain0", "freq-domain1";
+#freq-domain-cells = <1>;
+};
+};
+
+
+
+
-- 
1.7.9.5


[PATCH v6] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2020-09-09 Thread Hector Yuan
The CPUfreq HW present in some Mediatek chipsets offloads the steps necessary 
for changing the frequency of CPUs. 
The driver implements the cpufreq driver interface for this hardware engine. 

This patch depends on the MT6779 DTS patch submitted by Hanks Chen
 https://lkml.org/lkml/2020/8/4/1094


Hector.Yuan (2):
  cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver
  dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

 .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |  141 ++
 drivers/cpufreq/Kconfig.arm|   12 +
 drivers/cpufreq/Makefile   |1 +
 drivers/cpufreq/mediatek-cpufreq-hw.c  |  283 
 4 files changed, 437 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
 create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw.c

[PATCH v6 1/2] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2020-09-09 Thread Hector Yuan
From: "Hector.Yuan" 

Add MT6779 cpufreq HW support.

Signed-off-by: Hector.Yuan 
---
 drivers/cpufreq/Kconfig.arm   |   12 ++
 drivers/cpufreq/Makefile  |1 +
 drivers/cpufreq/mediatek-cpufreq-hw.c |  283 +
 3 files changed, 296 insertions(+)
 create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw.c

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index c6cbfc8..8e58c12 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -121,6 +121,18 @@ config ARM_MEDIATEK_CPUFREQ
help
  This adds the CPUFreq driver support for MediaTek SoCs.
 
+config ARM_MEDIATEK_CPUFREQ_HW
+   tristate "MediaTek CPUFreq HW driver"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   default m
+   help
+ Support for the CPUFreq HW driver.
+ Some MediaTek chipsets have a HW engine to offload the steps
+ necessary for changing the frequency of the CPUs. Firmware loaded
+ in this engine exposes a programming interface to the OS.
+ The driver implements the cpufreq interface for this HW engine.
+ Say Y if you want to support CPUFreq HW.
+
 config ARM_OMAP2PLUS_CPUFREQ
bool "TI OMAP2+"
depends on ARCH_OMAP2PLUS
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index f6670c4..dc1f371 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ)   += 
imx6q-cpufreq.o
 obj-$(CONFIG_ARM_IMX_CPUFREQ_DT)   += imx-cpufreq-dt.o
 obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o
 obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ) += mediatek-cpufreq.o
+obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ_HW)  += mediatek-cpufreq-hw.o
 obj-$(CONFIG_MACH_MVEBU_V7)+= mvebu-cpufreq.o
 obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)+= omap-cpufreq.o
 obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)   += pxa2xx-cpufreq.o
diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c 
b/drivers/cpufreq/mediatek-cpufreq-hw.c
new file mode 100644
index 000..ce6b592
--- /dev/null
+++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
@@ -0,0 +1,283 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define LUT_MAX_ENTRIES32U
+#define LUT_FREQ   GENMASK(11, 0)
+#define LUT_ROW_SIZE   0x4
+
+enum {
+   REG_LUT_TABLE,
+   REG_ENABLE,
+   REG_PERF_STATE,
+
+   REG_ARRAY_SIZE,
+};
+
+struct cpufreq_mtk {
+   struct cpufreq_frequency_table *table;
+   void __iomem *reg_bases[REG_ARRAY_SIZE];
+   cpumask_t related_cpus;
+};
+
+static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = {
+   [REG_LUT_TABLE] = 0x0,
+   [REG_ENABLE]= 0x84,
+   [REG_PERF_STATE]= 0x88,
+};
+
+static struct cpufreq_mtk *mtk_freq_domain_map[NR_CPUS];
+
+static int mtk_cpufreq_hw_target_index(struct cpufreq_policy *policy,
+  unsigned int index)
+{
+   struct cpufreq_mtk *c = policy->driver_data;
+
+   writel_relaxed(index, c->reg_bases[REG_PERF_STATE]);
+
+   return 0;
+}
+
+static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)
+{
+   struct cpufreq_mtk *c;
+   struct cpufreq_policy *policy;
+   unsigned int index;
+
+   policy = cpufreq_cpu_get_raw(cpu);
+   if (!policy)
+   return 0;
+
+   c = mtk_freq_domain_map[cpu];
+
+   index = readl_relaxed(c->reg_bases[REG_PERF_STATE]);
+   index = min(index, LUT_MAX_ENTRIES - 1);
+
+   return policy->freq_table[index].frequency;
+}
+
+static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
+{
+   struct cpufreq_mtk *c;
+
+   c = mtk_freq_domain_map[policy->cpu];
+   if (!c) {
+   pr_err("No scaling support for CPU%d\n", policy->cpu);
+   return -ENODEV;
+   }
+
+   cpumask_copy(policy->cpus, >related_cpus);
+
+   policy->freq_table = c->table;
+   policy->driver_data = c;
+
+   /* HW should be in enabled state to proceed now */
+   writel_relaxed(0x1, c->reg_bases[REG_ENABLE]);
+
+   return 0;
+}
+
+static int mtk_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy)
+{
+   struct cpufreq_mtk *c;
+
+   c = mtk_freq_domain_map[policy->cpu];
+   if (!c) {
+   pr_err("No scaling support for CPU%d\n", policy->cpu);
+   return -ENODEV;
+   }
+
+   /* HW should be in paused state now */
+   writel_relaxed(0x0, c->reg_bases[REG_ENABLE]);
+
+   return 0;
+}
+
+static struct cpufreq_driver cpufreq_mtk_hw_driver = {
+   .flags  = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK |
+ CPUFREQ_HAVE_GOVERNOR_PER_POLICY,
+   .verify = cpufreq_generic_frequency_table_verify,
+   .target_index   = 

Re: [PATCH v5 1/2] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2020-09-09 Thread Hector Yuan
On Wed, 2020-09-09 at 16:59 +0530, Viresh Kumar wrote:
> On 09-09-20, 17:51, Hector Yuan wrote:
> > From: "Hector.Yuan" 
> > 
> > Add MT6779 cpufreq HW support.
> > 
> > Signed-off-by: Hector.Yuan 
> > ---
> >  drivers/cpufreq/Kconfig.arm   |   12 ++
> >  drivers/cpufreq/Makefile  |1 +
> >  drivers/cpufreq/mediatek-cpufreq-hw.c |  289 
> > +
> >  3 files changed, 302 insertions(+)
> >  create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw.c
> > 
> > diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
> > index c6cbfc8..8e58c12 100644
> > --- a/drivers/cpufreq/Kconfig.arm
> > +++ b/drivers/cpufreq/Kconfig.arm
> > @@ -121,6 +121,18 @@ config ARM_MEDIATEK_CPUFREQ
> > help
> >   This adds the CPUFreq driver support for MediaTek SoCs.
> >  
> > +config ARM_MEDIATEK_CPUFREQ_HW
> > +   tristate "MediaTek CPUFreq HW driver"
> > +   depends on ARCH_MEDIATEK || COMPILE_TEST
> > +   default m
> > +   help
> > + Support for the CPUFreq HW driver.
> > + Some MediaTek chipsets have a HW engine to offload the steps
> > + necessary for changing the frequency of the CPUs. Firmware loaded
> > + in this engine exposes a programming interface to the OS.
> > + The driver implements the cpufreq interface for this HW engine.
> > + Say Y if you want to support CPUFreq HW.
> > +
> >  config ARM_OMAP2PLUS_CPUFREQ
> > bool "TI OMAP2+"
> > depends on ARCH_OMAP2PLUS
> > diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
> > index f6670c4..dc1f371 100644
> > --- a/drivers/cpufreq/Makefile
> > +++ b/drivers/cpufreq/Makefile
> > @@ -57,6 +57,7 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ)   += 
> > imx6q-cpufreq.o
> >  obj-$(CONFIG_ARM_IMX_CPUFREQ_DT)   += imx-cpufreq-dt.o
> >  obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o
> >  obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ) += mediatek-cpufreq.o
> > +obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ_HW)  += mediatek-cpufreq-hw.o
> >  obj-$(CONFIG_MACH_MVEBU_V7)+= mvebu-cpufreq.o
> >  obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)+= omap-cpufreq.o
> >  obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)   += pxa2xx-cpufreq.o
> > diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c 
> > b/drivers/cpufreq/mediatek-cpufreq-hw.c
> > new file mode 100644
> > index 000..ae4b38b
> > --- /dev/null
> > +++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
> > @@ -0,0 +1,289 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2020 MediaTek Inc.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define LUT_MAX_ENTRIES32U
> > +#define LUT_FREQ   GENMASK(11, 0)
> > +#define LUT_ROW_SIZE   0x4
> > +
> > +enum {
> > +   REG_LUT_TABLE,
> > +   REG_ENABLE,
> > +   REG_PERF_STATE,
> > +
> > +   REG_ARRAY_SIZE,
> > +};
> > +
> > +struct cpufreq_mtk {
> > +   struct cpufreq_frequency_table *table;
> > +   void __iomem *reg_bases[REG_ARRAY_SIZE];
> > +   cpumask_t related_cpus;
> > +};
> > +
> > +static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = {
> > +   [REG_LUT_TABLE] = 0x0,
> > +   [REG_ENABLE]= 0x84,
> > +   [REG_PERF_STATE]= 0x88,
> > +};
> > +
> > +static struct cpufreq_mtk *mtk_freq_domain_map[NR_CPUS];
> > +
> > +static int mtk_cpufreq_hw_target_index(struct cpufreq_policy *policy,
> > +  unsigned int index)
> > +{
> > +   struct cpufreq_mtk *c = policy->driver_data;
> > +
> > +   writel_relaxed(index, c->reg_bases[REG_PERF_STATE]);
> > +   arch_set_freq_scale(policy->related_cpus,
> > +   policy->freq_table[index].frequency,
> > +   policy->cpuinfo.max_freq);
> 
> Please drop the arch_set_freq_scale() stuff. This is getting moved to
> cpufreq core in another series and will be done by core code for
> everyone. Sorry I forgot to mention that earlier.
> 
OK, will remove it, Thank you.
> > +
> > +   return 0;
> > +}
> > +
> > +static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)
> > +{
> > +   struct cpufreq_mtk *c;
> > +   struct cpufreq_policy *policy;
> > +   unsigned int index;
> >

[PATCH v5 1/2] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2020-09-09 Thread Hector Yuan
From: "Hector.Yuan" 

Add MT6779 cpufreq HW support.

Signed-off-by: Hector.Yuan 
---
 drivers/cpufreq/Kconfig.arm   |   12 ++
 drivers/cpufreq/Makefile  |1 +
 drivers/cpufreq/mediatek-cpufreq-hw.c |  289 +
 3 files changed, 302 insertions(+)
 create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw.c

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index c6cbfc8..8e58c12 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -121,6 +121,18 @@ config ARM_MEDIATEK_CPUFREQ
help
  This adds the CPUFreq driver support for MediaTek SoCs.
 
+config ARM_MEDIATEK_CPUFREQ_HW
+   tristate "MediaTek CPUFreq HW driver"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   default m
+   help
+ Support for the CPUFreq HW driver.
+ Some MediaTek chipsets have a HW engine to offload the steps
+ necessary for changing the frequency of the CPUs. Firmware loaded
+ in this engine exposes a programming interface to the OS.
+ The driver implements the cpufreq interface for this HW engine.
+ Say Y if you want to support CPUFreq HW.
+
 config ARM_OMAP2PLUS_CPUFREQ
bool "TI OMAP2+"
depends on ARCH_OMAP2PLUS
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index f6670c4..dc1f371 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ)   += 
imx6q-cpufreq.o
 obj-$(CONFIG_ARM_IMX_CPUFREQ_DT)   += imx-cpufreq-dt.o
 obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o
 obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ) += mediatek-cpufreq.o
+obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ_HW)  += mediatek-cpufreq-hw.o
 obj-$(CONFIG_MACH_MVEBU_V7)+= mvebu-cpufreq.o
 obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)+= omap-cpufreq.o
 obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)   += pxa2xx-cpufreq.o
diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c 
b/drivers/cpufreq/mediatek-cpufreq-hw.c
new file mode 100644
index 000..ae4b38b
--- /dev/null
+++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
@@ -0,0 +1,289 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define LUT_MAX_ENTRIES32U
+#define LUT_FREQ   GENMASK(11, 0)
+#define LUT_ROW_SIZE   0x4
+
+enum {
+   REG_LUT_TABLE,
+   REG_ENABLE,
+   REG_PERF_STATE,
+
+   REG_ARRAY_SIZE,
+};
+
+struct cpufreq_mtk {
+   struct cpufreq_frequency_table *table;
+   void __iomem *reg_bases[REG_ARRAY_SIZE];
+   cpumask_t related_cpus;
+};
+
+static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = {
+   [REG_LUT_TABLE] = 0x0,
+   [REG_ENABLE]= 0x84,
+   [REG_PERF_STATE]= 0x88,
+};
+
+static struct cpufreq_mtk *mtk_freq_domain_map[NR_CPUS];
+
+static int mtk_cpufreq_hw_target_index(struct cpufreq_policy *policy,
+  unsigned int index)
+{
+   struct cpufreq_mtk *c = policy->driver_data;
+
+   writel_relaxed(index, c->reg_bases[REG_PERF_STATE]);
+   arch_set_freq_scale(policy->related_cpus,
+   policy->freq_table[index].frequency,
+   policy->cpuinfo.max_freq);
+
+   return 0;
+}
+
+static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)
+{
+   struct cpufreq_mtk *c;
+   struct cpufreq_policy *policy;
+   unsigned int index;
+
+   policy = cpufreq_cpu_get_raw(cpu);
+   if (!policy)
+   return 0;
+
+   c = policy->driver_data;
+
+   index = readl_relaxed(c->reg_bases[REG_PERF_STATE]);
+   index = min(index, LUT_MAX_ENTRIES - 1);
+
+   return policy->freq_table[index].frequency;
+}
+
+static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
+{
+   struct cpufreq_mtk *c;
+   struct device *cpu_dev;
+
+   cpu_dev = get_cpu_device(policy->cpu);
+   if (!cpu_dev) {
+   pr_err("%s: failed to get cpu%d device\n", __func__,
+  policy->cpu);
+   return -ENODEV;
+   }
+
+   c = mtk_freq_domain_map[policy->cpu];
+   if (!c) {
+   pr_err("No scaling support for CPU%d\n", policy->cpu);
+   return -ENODEV;
+   }
+
+   cpumask_copy(policy->cpus, >related_cpus);
+
+   policy->freq_table = c->table;
+   policy->driver_data = c;
+
+   /* HW should be in enabled state to proceed now */
+   writel_relaxed(0x1, c->reg_bases[REG_ENABLE]);
+
+   return 0;
+}
+
+static struct cpufreq_driver cpufreq_mtk_hw_driver = {
+   .flags  = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK |
+ CPUFREQ_HAVE_GOVERNOR_PER_POLICY,
+   .verify = cpufreq_generic_frequency_table_verify,
+   .target_index   = 

[PATCH v5] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2020-09-09 Thread Hector Yuan
The CPUfreq HW present in some Mediatek chipsets offloads the steps necessary 
for changing the frequency of CPUs. 
The driver implements the cpufreq driver interface for this hardware engine. 

This patch depends on the MT6799 DTS patch submitted by Hanks Chen
 https://lkml.org/lkml/2020/8/4/1094
 

Hector.Yuan (2):
  cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver
  dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

 .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |  141 ++
 drivers/cpufreq/Kconfig.arm|   12 +
 drivers/cpufreq/Makefile   |1 +
 drivers/cpufreq/mediatek-cpufreq-hw.c  |  289 
 4 files changed, 443 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
 create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw.c

[PATCH v5 2/2] dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

2020-09-09 Thread Hector Yuan
From: "Hector.Yuan" 

Add devicetree bindings for MediaTek HW driver.

Signed-off-by: Hector.Yuan 
---
 .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |  141 
 1 file changed, 141 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml

diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml 
b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
new file mode 100644
index 000..118a163
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
@@ -0,0 +1,141 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/cpufreq/cpufreq-mediatek-hw.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek's CPUFREQ Bindings
+
+maintainers:
+  - Hector Yuan 
+
+description:
+  CPUFREQ HW is a hardware engine used by MediaTek
+  SoCs to manage frequency in hardware. It is capable of controlling frequency
+  for multiple clusters.
+
+properties:
+  compatible:
+const: "mediatek,cpufreq-hw"
+
+  reg:
+minItems: 1
+maxItems: 2
+description: |
+  Addresses and sizes for the memory of the HW bases in each frequency 
domain.
+
+  reg-names:
+items:
+  - const: "freq-domain0"
+  - const: "freq-domain1"
+description: |
+  Frequency domain name. i.e.
+  "freq-domain0", "freq-domain1".
+
+  "#freq-domain-cells":
+const: 1
+description: |
+  Number of cells in a freqency domain specifier.
+
+  mtk-freq-domain:
+maxItems: 1
+description: |
+  Define this cpu belongs to which frequency domain. i.e.
+  cpu0-3 belong to frequency domain0,
+  cpu4-6 belong to frequency domain1.
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - "#freq-domain-cells"
+
+examples:
+  - |
+cpus {
+#address-cells = <1>;
+#size-cells = <0>;
+
+cpu0: cpu@0 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mtk-freq-domain = <_hw 0>;
+reg = <0x000>;
+};
+
+cpu1: cpu@1 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mtk-freq-domain = <_hw 0>;
+reg = <0x100>;
+};
+
+cpu2: cpu@2 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mtk-freq-domain = <_hw 0>;
+reg = <0x200>;
+};
+
+cpu3: cpu@3 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mtk-freq-domain = <_hw 0>;
+reg = <0x300>;
+};
+
+cpu4: cpu@4 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mtk-freq-domain = <_hw 1>;
+reg = <0x400>;
+};
+
+cpu5: cpu@5 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mtk-freq-domain = <_hw 1>;
+reg = <0x500>;
+};
+
+cpu6: cpu@6 {
+device_type = "cpu";
+compatible = "arm,cortex-a75";
+enable-method = "psci";
+mtk-freq-domain = <_hw 1>;
+reg = <0x600>;
+};
+
+cpu7: cpu@7 {
+device_type = "cpu";
+compatible = "arm,cortex-a75";
+enable-method = "psci";
+mtk-freq-domain = <_hw 1>;
+reg = <0x700>;
+};
+};
+
+/* ... */
+
+soc {
+#address-cells = <2>;
+#size-cells = <2>;
+
+cpufreq_hw: cpufreq@11bc00 {
+compatible = "mediatek,cpufreq-hw";
+reg = <0 0x11bc10 0 0x8c>,
+   <0 0x11bca0 0 0x8c>;
+reg-names = "freq-domain0", "freq-domain1";
+#freq-domain-cells = <1>;
+};
+};
+
+
+
+
-- 
1.7.9.5


Re: [PATCH v4 1/2] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2020-09-08 Thread Hector Yuan
On Tue, 2020-09-08 at 16:43 +0530, Viresh Kumar wrote:
> On 08-09-20, 19:10, Hector Yuan wrote:
> > OK, I will define the corresponding exit function. 
> 
> Also please add remove() corresponding to probe().
> 
OK, thanks for your kind reminder.



Re: [PATCH v4 2/2] dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

2020-09-08 Thread Hector Yuan
On Tue, 2020-09-08 at 15:37 +0530, Viresh Kumar wrote:
> On 08-09-20, 15:35, Hector Yuan wrote:
> > From: "Hector.Yuan" 
> > 
> > Add devicetree bindings for MediaTek HW driver.
> > 
> > Signed-off-by: Hector.Yuan 
> > ---
> >  .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |  141 
> > 
> >  1 file changed, 141 insertions(+)
> >  create mode 100644 
> > Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> > 
> > diff --git 
> > a/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml 
> > b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> > new file mode 100644
> > index 000..5be5867
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> > @@ -0,0 +1,141 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/cpufreq/cpufreq-mediatek-hw.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: MediaTek's CPUFREQ Bindings
> > +
> > +maintainers:
> > +  - Hector Yuan 
> > +
> > +description:
> > +  CPUFREQ HW is a hardware engine used by MediaTek
> > +  SoCs to manage frequency in hardware. It is capable of controlling 
> > frequency
> > +  for multiple clusters.
> > +
> > +properties:
> > +  compatible:
> > +const: mediatek,cpufreq-hw
> 
> Missing "" here ?
> 
OK, will add it in v5.
> > +
> > +  reg:
> > +minItems: 1
> > +maxItems: 2
> > +description: |
> > +  Addresses and sizes for the memory of the HW bases in each frequency 
> > domain.
> > +
> > +  reg-names:
> > +items:
> > +  - const: "freq-domain0"
> > +  - const: "freq-domain1"
> > +description: |
> > +  Frequency domain name. i.e.
> > +  "freq-domain0", "freq-domain1".
> > +
> > +  "#freq-domain-cells":
> > +const: 1
> > +description: |
> > +  Number of cells in a freqency domain specifier.
> > +
> > +  mtk-freq-domain:
> > +maxItems: 1
> > +description: |
> > +  Define this cpu belongs to which frequency domain. i.e.
> > +  cpu0-3 belong to frequency domain0,
> > +  cpu4-6 belong to frequency domain1.
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - reg-names
> > +  - "#freq-domain-cells"
> > +
> > +examples:
> > +  - |
> > +cpus {
> > +#address-cells = <1>;
> > +#size-cells = <0>;
> > +
> > +cpu0: cpu@0 {
> > +device_type = "cpu";
> > +compatible = "arm,cortex-a55";
> > +enable-method = "psci";
> > +mtk-freq-domain = <_hw 0>;
> > +reg = <0x000>;
> > +};
> > +
> > +cpu1: cpu@1 {
> > +device_type = "cpu";
> > +compatible = "arm,cortex-a55";
> > +enable-method = "psci";
> > +mtk-freq-domain = <_hw 0>;
> > +reg = <0x100>;
> > +};
> > +
> > +cpu2: cpu@2 {
> > +device_type = "cpu";
> > +compatible = "arm,cortex-a55";
> > +enable-method = "psci";
> > +mtk-freq-domain = <_hw 0>;
> > +reg = <0x200>;
> > +};
> > +
> > +cpu3: cpu@3 {
> > +device_type = "cpu";
> > +compatible = "arm,cortex-a55";
> > +enable-method = "psci";
> > +mtk-freq-domain = <_hw 0>;
> > +reg = <0x300>;
> > +};
> > +
> > +cpu4: cpu@4 {
> > +device_type = "cpu";
> > +compatible = "arm,cortex-a55";
> > +enable-method = "psci";
> > +mtk-freq-domain = <_hw 1>;
> > +reg = <0x400>;
> > +};
> > +
> > +cpu5: cpu@5 {
> > +device_type = "cpu";
> > +compatible = &q

Re: [PATCH v4 1/2] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2020-09-08 Thread Hector Yuan
On Tue, 2020-09-08 at 15:57 +0530, Viresh Kumar wrote:
> On 08-09-20, 15:35, Hector Yuan wrote:
> > From: "Hector.Yuan" 
> > 
> > Add MT6779 cpufreq HW support.
> > 
> > Signed-off-by: Hector.Yuan 
> > ---
> >  drivers/cpufreq/Kconfig.arm   |   12 ++
> >  drivers/cpufreq/Makefile  |1 +
> >  drivers/cpufreq/mediatek-cpufreq-hw.c |  294 
> > +
> >  3 files changed, 307 insertions(+)
> >  create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw.c
> > 
> > diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
> > index c6cbfc8..8e58c12 100644
> > --- a/drivers/cpufreq/Kconfig.arm
> > +++ b/drivers/cpufreq/Kconfig.arm
> > @@ -121,6 +121,18 @@ config ARM_MEDIATEK_CPUFREQ
> > help
> >   This adds the CPUFreq driver support for MediaTek SoCs.
> >  
> > +config ARM_MEDIATEK_CPUFREQ_HW
> > +   tristate "MediaTek CPUFreq HW driver"
> > +   depends on ARCH_MEDIATEK || COMPILE_TEST
> > +   default m
> > +   help
> > + Support for the CPUFreq HW driver.
> > + Some MediaTek chipsets have a HW engine to offload the steps
> > + necessary for changing the frequency of the CPUs. Firmware loaded
> > + in this engine exposes a programming interface to the OS.
> > + The driver implements the cpufreq interface for this HW engine.
> > + Say Y if you want to support CPUFreq HW.
> > +
> >  config ARM_OMAP2PLUS_CPUFREQ
> > bool "TI OMAP2+"
> > depends on ARCH_OMAP2PLUS
> > diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
> > index f6670c4..dc1f371 100644
> > --- a/drivers/cpufreq/Makefile
> > +++ b/drivers/cpufreq/Makefile
> > @@ -57,6 +57,7 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ)   += 
> > imx6q-cpufreq.o
> >  obj-$(CONFIG_ARM_IMX_CPUFREQ_DT)   += imx-cpufreq-dt.o
> >  obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o
> >  obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ) += mediatek-cpufreq.o
> > +obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ_HW)  += mediatek-cpufreq-hw.o
> >  obj-$(CONFIG_MACH_MVEBU_V7)+= mvebu-cpufreq.o
> >  obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)+= omap-cpufreq.o
> >  obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)   += pxa2xx-cpufreq.o
> > diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c 
> > b/drivers/cpufreq/mediatek-cpufreq-hw.c
> > new file mode 100644
> > index 000..61040b8
> > --- /dev/null
> > +++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
> > @@ -0,0 +1,294 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2020 MediaTek Inc.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define LUT_MAX_ENTRIES32U
> > +#define LUT_FREQ   GENMASK(11, 0)
> > +#define LUT_ROW_SIZE   0x4
> > +
> > +enum {
> > +   REG_LUT_TABLE,
> > +   REG_ENABLE,
> > +   REG_PERF_STATE,
> > +
> > +   REG_ARRAY_SIZE,
> > +};
> > +
> > +struct cpufreq_mtk {
> > +   struct cpufreq_frequency_table *table;
> > +   void __iomem *reg_bases[REG_ARRAY_SIZE];
> > +   cpumask_t related_cpus;
> > +};
> > +
> > +static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = {
> > +   [REG_LUT_TABLE] = 0x0,
> > +   [REG_ENABLE]= 0x84,
> > +   [REG_PERF_STATE]= 0x88,
> > +};
> > +
> > +static struct cpufreq_mtk *mtk_freq_domain_map[NR_CPUS];
> > +
> > +static int mtk_cpufreq_hw_target_index(struct cpufreq_policy *policy,
> > +  unsigned int index)
> > +{
> > +   struct cpufreq_mtk *c = policy->driver_data;
> > +
> > +   writel_relaxed(index, c->reg_bases[REG_PERF_STATE]);
> > +   arch_set_freq_scale(policy->related_cpus,
> > +   policy->freq_table[index].frequency,
> > +   policy->cpuinfo.max_freq);
> > +
> > +   return 0;
> > +}
> > +
> > +static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)
> > +{
> > +   struct cpufreq_mtk *c;
> > +   struct cpufreq_policy *policy;
> > +   unsigned int index;
> > +
> > +   policy = cpufreq_cpu_get_raw(cpu);
> > +   if (!policy)
> > +   return 0;
> > +
> > +   c = policy->driver_data;
> > +
> > +   index = readl_relaxed(c->reg_bases[REG_PERF_STATE]);

[PATCH v4 1/2] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2020-09-08 Thread Hector Yuan
From: "Hector.Yuan" 

Add MT6779 cpufreq HW support.

Signed-off-by: Hector.Yuan 
---
 drivers/cpufreq/Kconfig.arm   |   12 ++
 drivers/cpufreq/Makefile  |1 +
 drivers/cpufreq/mediatek-cpufreq-hw.c |  294 +
 3 files changed, 307 insertions(+)
 create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw.c

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index c6cbfc8..8e58c12 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -121,6 +121,18 @@ config ARM_MEDIATEK_CPUFREQ
help
  This adds the CPUFreq driver support for MediaTek SoCs.
 
+config ARM_MEDIATEK_CPUFREQ_HW
+   tristate "MediaTek CPUFreq HW driver"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   default m
+   help
+ Support for the CPUFreq HW driver.
+ Some MediaTek chipsets have a HW engine to offload the steps
+ necessary for changing the frequency of the CPUs. Firmware loaded
+ in this engine exposes a programming interface to the OS.
+ The driver implements the cpufreq interface for this HW engine.
+ Say Y if you want to support CPUFreq HW.
+
 config ARM_OMAP2PLUS_CPUFREQ
bool "TI OMAP2+"
depends on ARCH_OMAP2PLUS
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index f6670c4..dc1f371 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ)   += 
imx6q-cpufreq.o
 obj-$(CONFIG_ARM_IMX_CPUFREQ_DT)   += imx-cpufreq-dt.o
 obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o
 obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ) += mediatek-cpufreq.o
+obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ_HW)  += mediatek-cpufreq-hw.o
 obj-$(CONFIG_MACH_MVEBU_V7)+= mvebu-cpufreq.o
 obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)+= omap-cpufreq.o
 obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)   += pxa2xx-cpufreq.o
diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c 
b/drivers/cpufreq/mediatek-cpufreq-hw.c
new file mode 100644
index 000..61040b8
--- /dev/null
+++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
@@ -0,0 +1,294 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define LUT_MAX_ENTRIES32U
+#define LUT_FREQ   GENMASK(11, 0)
+#define LUT_ROW_SIZE   0x4
+
+enum {
+   REG_LUT_TABLE,
+   REG_ENABLE,
+   REG_PERF_STATE,
+
+   REG_ARRAY_SIZE,
+};
+
+struct cpufreq_mtk {
+   struct cpufreq_frequency_table *table;
+   void __iomem *reg_bases[REG_ARRAY_SIZE];
+   cpumask_t related_cpus;
+};
+
+static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = {
+   [REG_LUT_TABLE] = 0x0,
+   [REG_ENABLE]= 0x84,
+   [REG_PERF_STATE]= 0x88,
+};
+
+static struct cpufreq_mtk *mtk_freq_domain_map[NR_CPUS];
+
+static int mtk_cpufreq_hw_target_index(struct cpufreq_policy *policy,
+  unsigned int index)
+{
+   struct cpufreq_mtk *c = policy->driver_data;
+
+   writel_relaxed(index, c->reg_bases[REG_PERF_STATE]);
+   arch_set_freq_scale(policy->related_cpus,
+   policy->freq_table[index].frequency,
+   policy->cpuinfo.max_freq);
+
+   return 0;
+}
+
+static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)
+{
+   struct cpufreq_mtk *c;
+   struct cpufreq_policy *policy;
+   unsigned int index;
+
+   policy = cpufreq_cpu_get_raw(cpu);
+   if (!policy)
+   return 0;
+
+   c = policy->driver_data;
+
+   index = readl_relaxed(c->reg_bases[REG_PERF_STATE]);
+   index = min(index, LUT_MAX_ENTRIES - 1);
+
+   return policy->freq_table[index].frequency;
+}
+
+static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
+{
+   struct cpufreq_mtk *c;
+   struct device *cpu_dev;
+
+   cpu_dev = get_cpu_device(policy->cpu);
+   if (!cpu_dev) {
+   pr_err("%s: failed to get cpu%d device\n", __func__,
+  policy->cpu);
+   return -ENODEV;
+   }
+
+   c = mtk_freq_domain_map[policy->cpu];
+   if (!c) {
+   pr_err("No scaling support for CPU%d\n", policy->cpu);
+   return -ENODEV;
+   }
+
+   cpumask_copy(policy->cpus, >related_cpus);
+
+   policy->freq_table = c->table;
+   policy->driver_data = c;
+
+   /* HW should be in enabled state to proceed now */
+   writel_relaxed(0x1, c->reg_bases[REG_ENABLE]);
+
+   return 0;
+}
+
+static struct freq_attr *mtk_cpufreq_hw_attr[] = {
+   _freq_attr_scaling_available_freqs,
+   NULL
+};
+
+static struct cpufreq_driver cpufreq_mtk_hw_driver = {
+   .flags  = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK |
+ 

[PATCH v4 2/2] dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

2020-09-08 Thread Hector Yuan
From: "Hector.Yuan" 

Add devicetree bindings for MediaTek HW driver.

Signed-off-by: Hector.Yuan 
---
 .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |  141 
 1 file changed, 141 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml

diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml 
b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
new file mode 100644
index 000..5be5867
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
@@ -0,0 +1,141 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/cpufreq/cpufreq-mediatek-hw.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek's CPUFREQ Bindings
+
+maintainers:
+  - Hector Yuan 
+
+description:
+  CPUFREQ HW is a hardware engine used by MediaTek
+  SoCs to manage frequency in hardware. It is capable of controlling frequency
+  for multiple clusters.
+
+properties:
+  compatible:
+const: mediatek,cpufreq-hw
+
+  reg:
+minItems: 1
+maxItems: 2
+description: |
+  Addresses and sizes for the memory of the HW bases in each frequency 
domain.
+
+  reg-names:
+items:
+  - const: "freq-domain0"
+  - const: "freq-domain1"
+description: |
+  Frequency domain name. i.e.
+  "freq-domain0", "freq-domain1".
+
+  "#freq-domain-cells":
+const: 1
+description: |
+  Number of cells in a freqency domain specifier.
+
+  mtk-freq-domain:
+maxItems: 1
+description: |
+  Define this cpu belongs to which frequency domain. i.e.
+  cpu0-3 belong to frequency domain0,
+  cpu4-6 belong to frequency domain1.
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - "#freq-domain-cells"
+
+examples:
+  - |
+cpus {
+#address-cells = <1>;
+#size-cells = <0>;
+
+cpu0: cpu@0 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mtk-freq-domain = <_hw 0>;
+reg = <0x000>;
+};
+
+cpu1: cpu@1 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mtk-freq-domain = <_hw 0>;
+reg = <0x100>;
+};
+
+cpu2: cpu@2 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mtk-freq-domain = <_hw 0>;
+reg = <0x200>;
+};
+
+cpu3: cpu@3 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mtk-freq-domain = <_hw 0>;
+reg = <0x300>;
+};
+
+cpu4: cpu@4 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mtk-freq-domain = <_hw 1>;
+reg = <0x400>;
+};
+
+cpu5: cpu@5 {
+device_type = "cpu";
+compatible = "arm,cortex-a55";
+enable-method = "psci";
+mtk-freq-domain = <_hw 1>;
+reg = <0x500>;
+};
+
+cpu6: cpu@6 {
+device_type = "cpu";
+compatible = "arm,cortex-a75";
+enable-method = "psci";
+mtk-freq-domain = <_hw 1>;
+reg = <0x600>;
+};
+
+cpu7: cpu@7 {
+device_type = "cpu";
+compatible = "arm,cortex-a75";
+enable-method = "psci";
+mtk-freq-domain = <_hw 1>;
+reg = <0x700>;
+};
+};
+
+/* ... */
+
+soc {
+#address-cells = <2>;
+#size-cells = <2>;
+
+cpufreq_hw: cpufreq@11bc00 {
+compatible = "mediatek,cpufreq-hw";
+reg = <0 0x11bc10 0 0x8c>,
+   <0 0x11bca0 0 0x8c>;
+reg-names = "freq-domain0", "freq-domain1";
+#freq-domain-cells = <1>;
+};
+};
+
+
+
+
-- 
1.7.9.5


[PATCH v4] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2020-09-08 Thread Hector Yuan
This patch depends on the MT6799 DTS patch submitted by Hanks Chen
 https://lkml.org/lkml/2020/8/4/1094


Hector.Yuan (2):
  cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver
  dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

 .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |  141 ++
 drivers/cpufreq/Kconfig.arm|   12 +
 drivers/cpufreq/Makefile   |1 +
 drivers/cpufreq/mediatek-cpufreq-hw.c  |  294 
 4 files changed, 448 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
 create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw.c

Re: [PATCH v2 1/2] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2020-08-27 Thread Hector Yuan
On Thu, 2020-08-27 at 09:56 +0530, Viresh Kumar wrote:
> On 26-08-20, 20:57, Hector Yuan wrote:
> > On Mon, 2020-08-24 at 15:36 +0530, Viresh Kumar wrote:
> > > On 13-08-20, 15:07, Hector Yuan wrote:
> > > >  CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM=m
> > > >  CONFIG_ARM_ARMADA_37XX_CPUFREQ=y
> > > > +CONFIG_ARM_MEDIATEK_CPUFREQ_HW=m
> > > 
> > > What about a 'default m' in Kconfig itself ?
> > > OK, will update in V3.
> 
> Hector, you need to remove (or not add) the right bracket (>) before the
> beginning of your lines. This makes it incredibly difficult to read.

OK, I get it. Sorry for the inconvenience.
> > > > +   for (i = 0; i < LUT_MAX_ENTRIES; i++) {
> > > > +   data = readl_relaxed(base + (i * LUT_ROW_SIZE));
> > > > +   freq = FIELD_GET(LUT_FREQ, data) * 1000;
> > > > +   volt = FIELD_GET(LUT_VOLT, data);
> > > > +   if (freq != prev_freq) {
> > > > +   table[i].frequency = freq;
> > > > +   dev_pm_opp_add(cpu_dev, freq * 1000, volt);
> > > 
> > > Why are you adding OPPs here and rather why using OPP specific stuff
> > > at all in the driver ?
> > > yes, the opp information is read from CPU HW engine.Then add it to the 
> > > CPU dev OPP one by one.  
> 
> I asked a different question, why are you adding OPPs ? You don't need the 
> OPPs
> at all in my opinion. You can just create the frequency table and that's it.

I just add OPP info to OPP framework so that others modules can get it
from OPP framework.
But like you said, I don't need it in this driver. I will remove this
code segment in V4.
I already send V3 yesterday but not including this modification.

> > > > +   for_each_possible_cpu(cpu) {
> > > > +   cpu_np = of_cpu_device_node_get(cpu);
> > > > +   if (!cpu_np)
> > > > +   continue;
> > > > +
> > > > +   ret = of_parse_phandle_with_args(cpu_np, 
> > > > "mtk,freq-domain",
> > > 
> > > Where are bindings of this node and how does this look ?
> > > Can refer to the same patch series, I split it to another patch.Each cpu 
> > > will be group into one frequency domain for the CPU DVFS. 
> 
> That binding only defines "mediatek,cpufreq-hw" and not "mtk,freq-domain".

Please refer to the dt binding in V3, thank you.  (lkml not show up yet,
so I post the below link instead)
https://www.spinics.net/lists/arm-kernel/msg832592.html
> 



Re: [PATCH v2 1/2] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2020-08-26 Thread Hector Yuan
On Mon, 2020-08-24 at 15:36 +0530, Viresh Kumar wrote:
> On 13-08-20, 15:07, Hector Yuan wrote:
> > From: "Hector.Yuan" 
> > 
> > Add MT6779 cpufreq HW support.
> > 
> > Signed-off-by: Hector.Yuan 
> > ---
> >  arch/arm64/configs/defconfig  |1 +
> >  drivers/cpufreq/Kconfig.arm   |   11 ++
> >  drivers/cpufreq/Makefile  |1 +
> >  drivers/cpufreq/mediatek-cpufreq-hw.c |  255 
> > +
> >  4 files changed, 268 insertions(+)
> >  create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw.c
> > 
> > diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> > index 883e8ba..866a1bf 100644
> > --- a/arch/arm64/configs/defconfig
> > +++ b/arch/arm64/configs/defconfig
> > @@ -86,6 +86,7 @@ CONFIG_CPUFREQ_DT=y
> >  CONFIG_ACPI_CPPC_CPUFREQ=m
> >  CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM=m
> >  CONFIG_ARM_ARMADA_37XX_CPUFREQ=y
> > +CONFIG_ARM_MEDIATEK_CPUFREQ_HW=m
> 
> What about a 'default m' in Kconfig itself ?
> OK, will update in V3.
> >  CONFIG_ARM_SCPI_CPUFREQ=y
> >  CONFIG_ARM_IMX_CPUFREQ_DT=m
> >  CONFIG_ARM_QCOM_CPUFREQ_NVMEM=y
> > diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
> > index c6cbfc8..81f1cc1 100644
> > --- a/drivers/cpufreq/Kconfig.arm
> > +++ b/drivers/cpufreq/Kconfig.arm
> > @@ -121,6 +121,17 @@ config ARM_MEDIATEK_CPUFREQ
> > help
> >   This adds the CPUFreq driver support for MediaTek SoCs.
> >  
> > +config ARM_MEDIATEK_CPUFREQ_HW
> > +   tristate "MediaTek CPUFreq HW driver"
> > +   depends on ARCH_MEDIATEK || COMPILE_TEST
> > +   help
> > + Support for the CPUFreq HW driver.
> > + Some MediaTek chipsets have a HW engine to offload the steps
> > + necessary for changing the frequency of the CPUs. Firmware loaded
> > + in this engine exposes a programming interface to the OS.
> > + The driver implements the cpufreq interface for this HW engine.
> > + Say Y if you want to support CPUFreq HW.
> > +
> >  config ARM_OMAP2PLUS_CPUFREQ
> > bool "TI OMAP2+"
> > depends on ARCH_OMAP2PLUS
> > diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
> > index f6670c4..dc1f371 100644
> > --- a/drivers/cpufreq/Makefile
> > +++ b/drivers/cpufreq/Makefile
> > @@ -57,6 +57,7 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ)   += 
> > imx6q-cpufreq.o
> >  obj-$(CONFIG_ARM_IMX_CPUFREQ_DT)   += imx-cpufreq-dt.o
> >  obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o
> >  obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ) += mediatek-cpufreq.o
> > +obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ_HW)  += mediatek-cpufreq-hw.o
> >  obj-$(CONFIG_MACH_MVEBU_V7)+= mvebu-cpufreq.o
> >  obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)+= omap-cpufreq.o
> >  obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)   += pxa2xx-cpufreq.o
> > diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c 
> > b/drivers/cpufreq/mediatek-cpufreq-hw.c
> > new file mode 100644
> > index 000..6752db9
> > --- /dev/null
> > +++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
> > @@ -0,0 +1,255 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2020 MediaTek Inc.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define LUT_MAX_ENTRIES32U
> > +#define LUT_FREQ   GENMASK(11, 0)
> > +#define LUT_VOLT   GENMASK(28, 12)
> > +#define LUT_ROW_SIZE   0x4
> > +
> > +/* Register offsets */
> > +#define REG_ENABLE 0x84
> > +#define REG_PERF_STATE 0x88
> > +
> > +static struct platform_device *global_pdev;
> 
> Use cpufreq_driver->driver_data for this, it is already used in other
> drivers for similar use.
> OK, I see.will update in V3.
> > +static int mtk_cpufreq_hw_target_index(struct cpufreq_policy *policy,
> > +  unsigned int index)
> > +{
> > +   void __iomem *perf_state_reg = policy->driver_data;
> > +   unsigned long freq = policy->freq_table[index].frequency;
> > +
> > +   writel_relaxed(index, perf_state_reg);
> > +   arch_set_freq_scale(policy->related_cpus, freq,
> > +   policy->cpuinfo.max_freq);
> > +   return 0;
> > +}
> > +

Re: [PATCH v2 2/2] dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

2020-08-26 Thread Hector Yuan
On Mon, 2020-08-24 at 20:04 -0600, Rob Herring wrote:
> On Thu, Aug 13, 2020 at 03:07:55PM +0800, Hector Yuan wrote:
> > From: "Hector.Yuan" 
> > 
> > Add devicetree bindings for MediaTek HW driver.
> > 
> > Signed-off-by: Hector.Yuan 
> > ---
> >  .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |   61 
> > 
> >  1 file changed, 61 insertions(+)
> >  create mode 100644 
> > Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> > 
> > diff --git 
> > a/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml 
> > b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> > new file mode 100644
> > index 000..59bb24e
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> > @@ -0,0 +1,61 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/cpufreq/cpufreq-mediatek-hw.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: MediaTek's CPUFREQ Bindings
> > +
> > +maintainers:
> > +  - Hector Yuan 
> > +
> > +description:
> > +  CPUFREQ HW is a hardware engine used by MediaTek
> > +  SoCs to manage frequency in hardware. It is capable of controlling 
> > frequency
> > +  for multiple clusters.
> > +
> > +properties:
> > +  compatible:
> > +const: mediatek,cpufreq-hw
> > +
> > +  reg:
> > +minItems: 1
> > +maxItems: 2
> > +description: |
> > +  Addresses and sizes for the memory of the HW bases in each frequency 
> > domain.
> > +
> > +  reg-names:
> > +items:
> > +  - const: "freq-domain0"
> > +  - const: "freq-domain1"
> 
> Not all that useful of a name given it's based on the index.
Let me explain this index is about to map cpus to each frequency control
domain. Will update details usage in V3. Thank you.
> > +description: |
> > +  Frequency domain name.
> > +
> > +  "#freq-domain-cells":
> > +const: 1
> > +description: |
> > +  Number of cells in a freqency domain specifier.
> 
> What's this for?
> Like the previous mentioned, this is for index mapping. will update in V3. 
> Thank you.
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - reg-names
> > +  - "#freq-domain-cells"
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +soc {
> > +#address-cells = <2>;
> > +#size-cells = <2>;
> > +
> > +cpufreq_hw: cpufreq@11bc00 {
> > +compatible = "mediatek,cpufreq-hw";
> > +reg = <0 0x11bc10 0 0x8c>,
> > +   <0 0x11bca0 0 0x8c>;
> > +reg-names = "freq-domain0", "freq-domain1";
> > +#freq-domain-cells = <1>;
> > +};
> > +};
> > +
> > -- 
> > 1.7.9.5



[PATCH v1] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2020-08-13 Thread Hector Yuan
The CPUfreq HW present in some Mediatek chipsets offloads
the steps necessary for changing the frequency of CPUs.
The driver implements the cpufreq driver interface for
this hardware engine. 

This patch depends on the MT6779 DTS patch submitted by Hanks Chen
 https://lkml.org/lkml/2020/8/4/1094


Hector.Yuan (2):
  dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW
  cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

 .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |   61 +
 arch/arm64/configs/defconfig   |1 +
 drivers/cpufreq/Kconfig.arm|   11 +
 drivers/cpufreq/Makefile   |1 +
 drivers/cpufreq/mediatek-cpufreq-hw.c  |  255 
 5 files changed, 329 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
 create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw.c


[PATCH v2 1/2] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW driver

2020-08-13 Thread Hector Yuan
From: "Hector.Yuan" 

Add MT6779 cpufreq HW support.

Signed-off-by: Hector.Yuan 
---
 arch/arm64/configs/defconfig  |1 +
 drivers/cpufreq/Kconfig.arm   |   11 ++
 drivers/cpufreq/Makefile  |1 +
 drivers/cpufreq/mediatek-cpufreq-hw.c |  255 +
 4 files changed, 268 insertions(+)
 create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw.c

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 883e8ba..866a1bf 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -86,6 +86,7 @@ CONFIG_CPUFREQ_DT=y
 CONFIG_ACPI_CPPC_CPUFREQ=m
 CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM=m
 CONFIG_ARM_ARMADA_37XX_CPUFREQ=y
+CONFIG_ARM_MEDIATEK_CPUFREQ_HW=m
 CONFIG_ARM_SCPI_CPUFREQ=y
 CONFIG_ARM_IMX_CPUFREQ_DT=m
 CONFIG_ARM_QCOM_CPUFREQ_NVMEM=y
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index c6cbfc8..81f1cc1 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -121,6 +121,17 @@ config ARM_MEDIATEK_CPUFREQ
help
  This adds the CPUFreq driver support for MediaTek SoCs.
 
+config ARM_MEDIATEK_CPUFREQ_HW
+   tristate "MediaTek CPUFreq HW driver"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   help
+ Support for the CPUFreq HW driver.
+ Some MediaTek chipsets have a HW engine to offload the steps
+ necessary for changing the frequency of the CPUs. Firmware loaded
+ in this engine exposes a programming interface to the OS.
+ The driver implements the cpufreq interface for this HW engine.
+ Say Y if you want to support CPUFreq HW.
+
 config ARM_OMAP2PLUS_CPUFREQ
bool "TI OMAP2+"
depends on ARCH_OMAP2PLUS
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index f6670c4..dc1f371 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ)   += 
imx6q-cpufreq.o
 obj-$(CONFIG_ARM_IMX_CPUFREQ_DT)   += imx-cpufreq-dt.o
 obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o
 obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ) += mediatek-cpufreq.o
+obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ_HW)  += mediatek-cpufreq-hw.o
 obj-$(CONFIG_MACH_MVEBU_V7)+= mvebu-cpufreq.o
 obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)+= omap-cpufreq.o
 obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)   += pxa2xx-cpufreq.o
diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c 
b/drivers/cpufreq/mediatek-cpufreq-hw.c
new file mode 100644
index 000..6752db9
--- /dev/null
+++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
@@ -0,0 +1,255 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define LUT_MAX_ENTRIES32U
+#define LUT_FREQ   GENMASK(11, 0)
+#define LUT_VOLT   GENMASK(28, 12)
+#define LUT_ROW_SIZE   0x4
+
+/* Register offsets */
+#define REG_ENABLE 0x84
+#define REG_PERF_STATE 0x88
+
+static struct platform_device *global_pdev;
+static int mtk_cpufreq_hw_target_index(struct cpufreq_policy *policy,
+  unsigned int index)
+{
+   void __iomem *perf_state_reg = policy->driver_data;
+   unsigned long freq = policy->freq_table[index].frequency;
+
+   writel_relaxed(index, perf_state_reg);
+   arch_set_freq_scale(policy->related_cpus, freq,
+   policy->cpuinfo.max_freq);
+   return 0;
+}
+
+static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)
+{
+   void __iomem *perf_state_reg;
+   struct cpufreq_policy *policy;
+   unsigned int index;
+
+   policy = cpufreq_cpu_get_raw(cpu);
+   if (!policy)
+   return 0;
+
+   perf_state_reg = policy->driver_data;
+
+   index = readl_relaxed(perf_state_reg);
+   index = min(index, LUT_MAX_ENTRIES - 1);
+
+   return policy->freq_table[index].frequency;
+}
+
+static int mtk_cpufreq_hw_read_lut(struct device *cpu_dev,
+  struct cpufreq_policy *policy,
+  void __iomem *base)
+{
+   u32 data;
+   u32 freq, volt, prev_freq = 0;
+   int i = 0;
+   struct cpufreq_frequency_table  *table;
+
+   table = kcalloc(LUT_MAX_ENTRIES + 1, sizeof(*table), GFP_KERNEL);
+   if (!table)
+   return -ENOMEM;
+
+   for (i = 0; i < LUT_MAX_ENTRIES; i++) {
+   data = readl_relaxed(base + (i * LUT_ROW_SIZE));
+   freq = FIELD_GET(LUT_FREQ, data) * 1000;
+   volt = FIELD_GET(LUT_VOLT, data);
+   if (freq != prev_freq) {
+   table[i].frequency = freq;
+   dev_pm_opp_add(cpu_dev, freq * 1000, volt);
+   dev_dbg(cpu_dev, "index=%d freq=%d, volt=%d\n", i,
+   

[PATCH v2 2/2] dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW

2020-08-13 Thread Hector Yuan
From: "Hector.Yuan" 

Add devicetree bindings for MediaTek HW driver.

Signed-off-by: Hector.Yuan 
---
 .../bindings/cpufreq/cpufreq-mediatek-hw.yaml  |   61 
 1 file changed, 61 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml

diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml 
b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
new file mode 100644
index 000..59bb24e
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
@@ -0,0 +1,61 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/cpufreq/cpufreq-mediatek-hw.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek's CPUFREQ Bindings
+
+maintainers:
+  - Hector Yuan 
+
+description:
+  CPUFREQ HW is a hardware engine used by MediaTek
+  SoCs to manage frequency in hardware. It is capable of controlling frequency
+  for multiple clusters.
+
+properties:
+  compatible:
+const: mediatek,cpufreq-hw
+
+  reg:
+minItems: 1
+maxItems: 2
+description: |
+  Addresses and sizes for the memory of the HW bases in each frequency 
domain.
+
+  reg-names:
+items:
+  - const: "freq-domain0"
+  - const: "freq-domain1"
+description: |
+  Frequency domain name.
+
+  "#freq-domain-cells":
+const: 1
+description: |
+  Number of cells in a freqency domain specifier.
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - "#freq-domain-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+soc {
+#address-cells = <2>;
+#size-cells = <2>;
+
+cpufreq_hw: cpufreq@11bc00 {
+compatible = "mediatek,cpufreq-hw";
+reg = <0 0x11bc10 0 0x8c>,
+   <0 0x11bca0 0 0x8c>;
+reg-names = "freq-domain0", "freq-domain1";
+#freq-domain-cells = <1>;
+};
+};
+
-- 
1.7.9.5