Re: [PATCH v2 2/2] clk: qcom: Add lpass clock controller driver for SDM845

2018-08-03 Thread Taniya Das




On 7/7/2018 5:09 AM, Stephen Boyd wrote:

Quoting Taniya Das (2018-07-04 23:55:21)

diff --git a/drivers/clk/qcom/lpasscc-sdm845.c 
b/drivers/clk/qcom/lpasscc-sdm845.c
new file mode 100644
index 000..5285b26
--- /dev/null
+++ b/drivers/clk/qcom/lpasscc-sdm845.c
@@ -0,0 +1,243 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "clk-regmap.h"
+#include "clk-branch.h"
+#include "common.h"
+
+static struct clk_branch gcc_lpass_q6_axi_clk = {
+   .halt_reg = 0x0,
+   .halt_check = BRANCH_HALT,
+   .clkr = {
+   .enable_reg = 0x0,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_lpass_q6_axi_clk",
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
+static struct clk_branch gcc_lpass_sway_clk = {
+   .halt_reg = 0x8,
+   .halt_check = BRANCH_HALT,
+   .clkr = {
+   .enable_reg = 0x8,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_lpass_sway_clk",
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+


Moved the above clocks to GCC driver.


+static struct clk_branch lpass_audio_wrapper_aon_clk = {
+   .halt_reg = 0x098,
+   .halt_check = BRANCH_VOTED,
+   .clkr = {
+   .enable_reg = 0x098,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "lpass_audio_wrapper_aon_clk",
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
+static struct clk_branch lpass_q6ss_ahbm_aon_clk = {
+   .halt_reg = 0x12000,
+   .halt_check = BRANCH_VOTED,


I'll take your word for it.


+   .clkr = {
+   .enable_reg = 0x12000,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "lpass_q6ss_ahbm_aon_clk",
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
+static struct clk_branch lpass_q6ss_ahbs_aon_clk = {
+   .halt_reg = 0x1f000,
+   .halt_check = BRANCH_VOTED,
+   .clkr = {
+   .enable_reg = 0x1f000,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "lpass_q6ss_ahbs_aon_clk",
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
+static struct clk_branch lpass_qdsp6ss_xo_clk = {
+   .halt_reg = 0x18,
+   .halt_check = BRANCH_HALT_SKIP,


Why? Hint, add a comment.



Added a comment in the next patch.


+   .clkr = {
+   .enable_reg = 0x18,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "lpass_qdsp6ss_xo_clk",
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
+static struct clk_branch lpass_qdsp6ss_sleep_clk = {
+   .halt_reg = 0x1c,
+   .halt_check = BRANCH_HALT_SKIP,


Why? Hint, add a comment.


Added a comment in the next patch.




+   .clkr = {
+   .enable_reg = 0x1c,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "lpass_qdsp6ss_sleep_clk",
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
+static struct clk_branch lpass_qdsp6ss_core_clk = {
+   .halt_reg = 0x0,
+   .halt_check = BRANCH_HALT_SKIP,


Again.



Added a comment in the next patch.


+   .clkr = {
+   .enable_reg = 0x0,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "lpass_qdsp6ss_core_clk",
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
+static struct regmap_config lpass_regmap_config = {
+   .reg_bits   = 32,
+   .reg_stride = 4,
+   .val_bits   = 32,
+   .fast_io= true,
+};
+
+static struct clk_regmap *lpass_gcc_sdm845_clocks[] = {
+   [GCC_LPASS_Q6_AXI_CLK] = &gcc_lpass_q6_axi_clk.clkr,
+   [GCC_LPASS_SWAY_CLK] = &gcc_lpass_sway_clk.clkr,
+};
+
+static const struct qcom_cc_desc lpass_gcc_sdm845_desc = {
+   .config = &lpass_regmap_config,
+   .clks = lpass_gcc_sdm845_clocks,
+   .num_clks = ARRAY_SIZE(lpass_gcc_sdm845_clocks),
+};
+
+static struct clk_regmap *lpass_cc_sdm845_clocks[] = {
+   [LPASS_AUDIO_WRAPPER_AON_CLK] = &lpass_audio_wrapper_aon_clk.clkr,
+   [LPASS_Q6SS_AHBM_AON_CLK] = &lpass_

Re: [PATCH v2 1/2] dt-bindings: clock: Introduce QCOM LPASS clock bindings

2018-08-03 Thread Taniya Das




On 7/7/2018 5:12 AM, Stephen Boyd wrote:

Quoting Taniya Das (2018-07-04 23:55:20)

diff --git a/Documentation/devicetree/bindings/clock/qcom,lpasscc.txt 
b/Documentation/devicetree/bindings/clock/qcom,lpasscc.txt
new file mode 100644
index 000..fe7378b
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,lpasscc.txt
@@ -0,0 +1,22 @@
+Qualcomm LPASS Clock Controller Binding
+---
+
+Required properties :
+- compatible   : shall contain "qcom,sdm845-lpasscc"
+- #clock-cells : from common clock binding, shall contain 1.
+- reg  : shall contain base register address and size.
+- reg-names: shall contain the register names of LPASS domain
+   "lpass_gcc", "lpass_cc", "lpass_qdsp6ss".
+
+Example:
+
+The below node has to be defined in the cases where the LPASS peripheral loader
+would bring the subsystem out of reset.
+
+   lpasscc: clock-controller {
+   compatible = "qcom,sdm845-lpasscc";
+   reg = <0x00147000 0x20>, <0x17014000 0x1f004>,


This first reg is inside GCC though? Why isn't it added to the gcc
sdm845 driver? And then the next two might make sense as a different
region, but the reg property ending in 20 looks really weird.

I have moved the GCC registers in the GCC driver with a device tree 
property flag. And also have mapped the lpass_qdsp6ss CC region.



+   <0x17300020 0x20>;
+   reg-names = "lpass_gcc", "lpass_cc", "lpass_qdsp6ss";
+   #clock-cells = <1>;
+   };


--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


[PATCH v3 1/2] dt-bindings: clock: Introduce QCOM LPASS clock bindings

2018-08-03 Thread Taniya Das
Add device tree bindings for Low Power Audio subsystem clock controller for
Qualcomm Technology Inc's SDM845 SoCs.

Signed-off-by: Taniya Das 
---
 .../devicetree/bindings/clock/qcom,gcc.txt |  2 ++
 .../devicetree/bindings/clock/qcom,lpasscc.txt | 33 ++
 include/dt-bindings/clock/qcom,gcc-sdm845.h|  2 ++
 include/dt-bindings/clock/qcom,lpass-sdm845.h  | 16 +++
 4 files changed, 53 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,lpasscc.txt
 create mode 100644 include/dt-bindings/clock/qcom,lpass-sdm845.h

diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.txt 
b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
index 664ea1f..e452abc 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt
+++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
@@ -32,6 +32,8 @@ be part of GCC and hence the TSENS properties can also be
 part of the GCC/clock-controller node.
 For more details on the TSENS properties please refer
 Documentation/devicetree/bindings/thermal/qcom-tsens.txt
+- qcom,lpass-protected : Indicate GCC to be able to access the
+   lpass gcc clock branches.

 Example:
clock-controller@90 {
diff --git a/Documentation/devicetree/bindings/clock/qcom,lpasscc.txt 
b/Documentation/devicetree/bindings/clock/qcom,lpasscc.txt
new file mode 100644
index 000..062e413
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,lpasscc.txt
@@ -0,0 +1,33 @@
+Qualcomm LPASS Clock Controller Binding
+---
+
+Required properties :
+- compatible   : shall contain "qcom,sdm845-lpasscc"
+- #clock-cells : from common clock binding, shall contain 1.
+- reg  : shall contain base register address and size,
+ in the order
+   Index-0 maps to LPASS_CC register region
+   Index-1 maps to LPASS_QDSP6SS register region
+- qcom,lpass-protected : Boolean property to indicate to GCC clock controller
+for the lpass GCC clocks.
+
+Optional properties :
+- reg-names: register names of LPASS domain
+"lpass_cc", "lpass_qdsp6ss".
+
+Example:
+
+The below node has to be defined in the cases where the LPASS peripheral loader
+would bring the subsystem out of reset.
+
+   lpasscc: clock-controller {
+   compatible = "qcom,sdm845-lpasscc";
+   reg = <0x17014000 0x1f004>, <0x1730 0x200>;
+   reg-names = "lpass_cc", "lpass_qdsp6ss";
+   #clock-cells = <1>;
+   };
+
+   gcc: clock-controller@10 {
+   compatible = "qcom,gcc-sdm845";
+   qcom,lpass-protected;
+   };
diff --git a/include/dt-bindings/clock/qcom,gcc-sdm845.h 
b/include/dt-bindings/clock/qcom,gcc-sdm845.h
index f96fc2d..66c4267 100644
--- a/include/dt-bindings/clock/qcom,gcc-sdm845.h
+++ b/include/dt-bindings/clock/qcom,gcc-sdm845.h
@@ -194,6 +194,8 @@
 #define GPLL4  184
 #define GCC_CPUSS_DVM_BUS_CLK  185
 #define GCC_CPUSS_GNOC_CLK 186
+#define GCC_LPASS_Q6_AXI_CLK   187
+#define GCC_LPASS_SWAY_CLK 188

 /* GCC Resets */
 #define GCC_MMSS_BCR   0
diff --git a/include/dt-bindings/clock/qcom,lpass-sdm845.h 
b/include/dt-bindings/clock/qcom,lpass-sdm845.h
new file mode 100644
index 000..015968e
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,lpass-sdm845.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_SDM_LPASS_SDM845_H
+#define _DT_BINDINGS_CLK_SDM_LPASS_SDM845_H
+
+#define LPASS_AUDIO_WRAPPER_AON_CLK0
+#define LPASS_Q6SS_AHBM_AON_CLK1
+#define LPASS_Q6SS_AHBS_AON_CLK2
+#define LPASS_QDSP6SS_XO_CLK   3
+#define LPASS_QDSP6SS_SLEEP_CLK4
+#define LPASS_QDSP6SS_CORE_CLK 5
+
+#endif
--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



[PATCH v3 0/2] Add support for LPASS clock controller for SDM845

2018-08-03 Thread Taniya Das
 [v3]
  * Add a device tree property to identify lpass protected GCC clocks.
  * Update the GCC driver code to register the lpass clocks when the flag is
   defined.
  * Add comment for clocks using the BRANCH_HALT_SKIP flag.
  * Use platform APIs instead of of_address_to_resource.
  * Replace devm_ioremap with devm_ioremap_resource.
  * Use fixed index for 'lpass_cc' & 'lpass_qdsp6ss' in probe.

 [v2]
  * Make gcc_lpass_sway_clk static.
  * Remove using child nodes and use reg-names to differentiate various
domains of LPASS CC.

Add support for the lpass clock controller found on SDM845 based devices.
This would allow lpass peripheral loader drivers to control the clocks to
bring the subsystem out of reset.

Taniya Das (2):
  dt-bindings: clock: Introduce QCOM LPASS clock bindings
  clk: qcom: Add lpass clock controller driver for SDM845

 .../devicetree/bindings/clock/qcom,gcc.txt |   2 +
 .../devicetree/bindings/clock/qcom,lpasscc.txt |  33 
 drivers/clk/qcom/Kconfig   |   9 +
 drivers/clk/qcom/Makefile  |   1 +
 drivers/clk/qcom/gcc-sdm845.c  |  35 
 drivers/clk/qcom/lpasscc-sdm845.c  | 189 +
 include/dt-bindings/clock/qcom,gcc-sdm845.h|   2 +
 include/dt-bindings/clock/qcom,lpass-sdm845.h  |  16 ++
 8 files changed, 287 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,lpasscc.txt
 create mode 100644 drivers/clk/qcom/lpasscc-sdm845.c
 create mode 100644 include/dt-bindings/clock/qcom,lpass-sdm845.h

--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



[PATCH v3 2/2] clk: qcom: Add lpass clock controller driver for SDM845

2018-08-03 Thread Taniya Das
Add support for the lpass clock controller found on SDM845 based devices.
This would allow lpass peripheral loader drivers to control the clocks to
bring the subsystem out of reset.
LPASS clocks present on the global clock controller would be registered
with the clock framework based on the device tree flag.

Signed-off-by: Taniya Das 
---
 drivers/clk/qcom/Kconfig  |   9 ++
 drivers/clk/qcom/Makefile |   1 +
 drivers/clk/qcom/gcc-sdm845.c |  35 +++
 drivers/clk/qcom/lpasscc-sdm845.c | 189 ++
 4 files changed, 234 insertions(+)
 create mode 100644 drivers/clk/qcom/lpasscc-sdm845.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 2b69cf2..7bd940d 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -254,6 +254,15 @@ config SDM_VIDEOCC_845
  Say Y if you want to support video devices and functionality such as
  video encode and decode.

+config SDM_LPASSCC_845
+   tristate "SDM845 LPASS Clock Controller"
+   depends on COMMON_CLK_QCOM
+   select SDM_GCC_845
+   help
+ Support for the LPASS clock controller on SDM845 devices.
+ Say Y if you want to use the LPASS branch clocks of the LPASS clock
+ controller to reset the LPASS subsystem.
+
 config SPMI_PMIC_CLKDIV
tristate "SPMI PMIC clkdiv Support"
depends on (COMMON_CLK_QCOM && SPMI) || COMPILE_TEST
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 599ab91..df2bd1f 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -40,5 +40,6 @@ obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o
 obj-$(CONFIG_QCOM_CLK_RPMH) += clk-rpmh.o
 obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
 obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o
+obj-$(CONFIG_SDM_LPASSCC_845) += lpasscc-sdm845.o
 obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o
 obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o
diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index 0f694ed..068cf53 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -3086,6 +3086,32 @@ enum {
},
 };

+static struct clk_branch gcc_lpass_q6_axi_clk = {
+   .halt_reg = 0x47000,
+   .halt_check = BRANCH_HALT,
+   .clkr = {
+   .enable_reg = 0x47000,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_lpass_q6_axi_clk",
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
+static struct clk_branch gcc_lpass_sway_clk = {
+   .halt_reg = 0x47008,
+   .halt_check = BRANCH_HALT,
+   .clkr = {
+   .enable_reg = 0x47008,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_lpass_sway_clk",
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
 static struct gdsc pcie_0_gdsc = {
.gdscr = 0x6b004,
.pd = {
@@ -3383,6 +3409,8 @@ enum {
[GPLL4] = &gpll4.clkr,
[GCC_CPUSS_DVM_BUS_CLK] = &gcc_cpuss_dvm_bus_clk.clkr,
[GCC_CPUSS_GNOC_CLK] = &gcc_cpuss_gnoc_clk.clkr,
+   [GCC_LPASS_Q6_AXI_CLK] = NULL,
+   [GCC_LPASS_SWAY_CLK] = NULL,
 };

 static const struct qcom_reset_map gcc_sdm845_resets[] = {
@@ -3472,6 +3500,13 @@ static int gcc_sdm845_probe(struct platform_device *pdev)
regmap_update_bits(regmap, 0x09ffc, 0x3, 0x3);
regmap_update_bits(regmap, 0x71028, 0x3, 0x3);

+   if (of_property_read_bool(pdev->dev.of_node, "qcom,lpass-protected")) {
+   gcc_sdm845_clocks[GCC_LPASS_Q6_AXI_CLK] =
+   &gcc_lpass_q6_axi_clk.clkr;
+   gcc_sdm845_clocks[GCC_LPASS_SWAY_CLK] =
+   &gcc_lpass_sway_clk.clkr;
+   }
+
return qcom_cc_really_probe(pdev, &gcc_sdm845_desc, regmap);
 }

diff --git a/drivers/clk/qcom/lpasscc-sdm845.c 
b/drivers/clk/qcom/lpasscc-sdm845.c
new file mode 100644
index 000..6f387f9
--- /dev/null
+++ b/drivers/clk/qcom/lpasscc-sdm845.c
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "clk-regmap.h"
+#include "clk-branch.h"
+#include "common.h"
+
+static struct clk_branch lpass_audio_wrapper_aon_clk = {
+   .halt_reg = 0x098,
+   .halt_check = BRANCH_VOTED,
+   .clkr = {
+   .enable_reg = 0x098,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "lpass_audio_wrapper_aon_clk",
+   .ops = &clk_branch2_ops,
+   },

Re: [PATCH v7 1/2] dt-bindings: cpufreq: Introduce QCOM CPUFREQ Firmware bindings

2018-08-07 Thread Taniya Das




On 8/8/2018 12:54 AM, skan...@codeaurora.org wrote:

On 2018-08-07 04:12, Sudeep Holla wrote:

On Mon, Aug 06, 2018 at 01:54:24PM -0700, skan...@codeaurora.org wrote:

On 2018-08-03 16:46, Stephen Boyd wrote:
>Quoting Taniya Das (2018-07-24 03:42:49)
>>diff --git
>>a/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt
>>b/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt
>>new file mode 100644
>>index 000..22d4355
>>--- /dev/null
>>+++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt
>>@@ -0,0 +1,172 @@
>[...]
>>+
>>+   CPU7: cpu@700 {
>>+   device_type = "cpu";
>>+   compatible = "qcom,kryo385";
>>+   reg = <0x0 0x700>;
>>+   enable-method = "psci";
>>+   next-level-cache = <&L2_700>;
>>+   qcom,freq-domain = <&freq_domain_table1>;
>>+   L2_700: l2-cache {
>>+   compatible = "cache";
>>+   next-level-cache = <&L3_0>;
>>+   };
>>+   };
>>+   };
>>+
>>+   qcom,cpufreq-hw {
>>+   compatible = "qcom,cpufreq-hw";
>>+
>>+   clocks = <&rpmhcc RPMH_CXO_CLK>;
>>+   clock-names = "xo";
>>+
>>+   #address-cells = <2>;
>>+   #size-cells = <2>;
>>+   ranges;
>>+   freq_domain_table0: freq_table0 {
>>+   reg = <0 0x17d43000 0 0x1400>;
>>+   };
>>+
>>+   freq_domain_table1: freq_table1 {
>>+   reg = <0 0x17d45800 0 0x1400>;
>>+   };
>
>Sorry, this is just not proper DT design. The whole node should have a
>reg property, and it should contain two (or three if we're handling the
>L3 clk domain?) different offsets for the different power clusters. The
>problem seems to still be that we don't have a way to map the CPUs to
>the clk domains they're in provided by this hardware block. Making
>subnodes is not the solution.

The problem is mapping clock domains to logical CPUs that CPUfreq 
uses. The

physical CPU to logical CPU mapping can be changed by the kernel (even
through DT if I'm not mistaken). So we need to have a way to tell in DT
which physical CPUs are connected to which CPU freq clock domain.



How about passing CPU freq clock domain id as along with phandle in
qcom,freq-domain ?


Now sure what you mean here. There's no such this as CPUfreq clock 
domain id. It has policies that are made up of logical CPU numbers. 
Logical CPU is not something that you can fix in DT.


-Saravana


Sudeep,

Earlier the design was the freq_domain would take the CPU phandles

freq_domain:
  cpus = <&cpu0 &cpu1>;

--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


[PATCH v3 0/3] Add display clock controller driver for SDM845

2018-06-23 Thread Taniya Das
 [v3]
  * Move frequency table macro to common file,
add the patch along to maintain dependency.

 [v2]
  * Removed unused header file includes.
  * Moved the frequency table macro to a common file [1].
  * Move to pll config to probe.
  * Update SoC name in device tree binding and
also update the Kconfig.

Add support for the display clock controller found on SDM845
based devices. This would allow display drivers to probe and
control their clocks.

Taniya Das (3):
  clk: qcom: Move frequency table macro to common file
  dt-bindings: clock: Introduce QCOM Display clock bindings
  clk: qcom: Add display clock controller driver for SDM845

 .../devicetree/bindings/clock/qcom,dispcc.txt  |  19 +
 drivers/clk/qcom/Kconfig   |  10 +
 drivers/clk/qcom/Makefile  |   1 +
 drivers/clk/qcom/clk-rcg.h |   2 +
 drivers/clk/qcom/dispcc-sdm845.c   | 674 +
 drivers/clk/qcom/gcc-apq8084.c |   2 -
 drivers/clk/qcom/gcc-ipq4019.c |   2 -
 drivers/clk/qcom/gcc-ipq8074.c |   2 -
 drivers/clk/qcom/gcc-msm8916.c |   2 -
 drivers/clk/qcom/gcc-msm8974.c |   2 -
 drivers/clk/qcom/gcc-msm8994.c |   2 -
 drivers/clk/qcom/gcc-msm8996.c |   2 -
 drivers/clk/qcom/gcc-msm8998.c |   2 -
 drivers/clk/qcom/gcc-sdm845.c  |   2 -
 drivers/clk/qcom/mmcc-apq8084.c|   2 -
 drivers/clk/qcom/mmcc-msm8974.c|   2 -
 drivers/clk/qcom/mmcc-msm8996.c|   2 -
 drivers/clk/qcom/videocc-sdm845.c  |   2 -
 include/dt-bindings/clock/qcom,dispcc-sdm845.h |  45 ++
 19 files changed, 751 insertions(+), 26 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,dispcc.txt
 create mode 100644 drivers/clk/qcom/dispcc-sdm845.c
 create mode 100644 include/dt-bindings/clock/qcom,dispcc-sdm845.h

--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



[PATCH v3 1/3] clk: qcom: Move frequency table macro to common file

2018-06-23 Thread Taniya Das
Frequency table macro is used by multiple clock drivers, move frequency
table macro to common header file.

Signed-off-by: Taniya Das 
---
 drivers/clk/qcom/clk-rcg.h| 2 ++
 drivers/clk/qcom/gcc-apq8084.c| 2 --
 drivers/clk/qcom/gcc-ipq4019.c| 2 --
 drivers/clk/qcom/gcc-ipq8074.c| 2 --
 drivers/clk/qcom/gcc-msm8916.c| 2 --
 drivers/clk/qcom/gcc-msm8974.c| 2 --
 drivers/clk/qcom/gcc-msm8994.c| 2 --
 drivers/clk/qcom/gcc-msm8996.c| 2 --
 drivers/clk/qcom/gcc-msm8998.c| 2 --
 drivers/clk/qcom/gcc-sdm845.c | 2 --
 drivers/clk/qcom/mmcc-apq8084.c   | 2 --
 drivers/clk/qcom/mmcc-msm8974.c   | 2 --
 drivers/clk/qcom/mmcc-msm8996.c   | 2 --
 drivers/clk/qcom/videocc-sdm845.c | 2 --
 14 files changed, 2 insertions(+), 26 deletions(-)

diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h
index b209a2f..dbd5a9e 100644
--- a/drivers/clk/qcom/clk-rcg.h
+++ b/drivers/clk/qcom/clk-rcg.h
@@ -7,6 +7,8 @@
 #include 
 #include "clk-regmap.h"

+#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
+
 struct freq_tbl {
unsigned long freq;
u8 src;
diff --git a/drivers/clk/qcom/gcc-apq8084.c b/drivers/clk/qcom/gcc-apq8084.c
index 486d961..9c99a71 100644
--- a/drivers/clk/qcom/gcc-apq8084.c
+++ b/drivers/clk/qcom/gcc-apq8084.c
@@ -106,8 +106,6 @@ enum {
"sleep_clk_src",
 };

-#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
-
 static struct clk_pll gpll0 = {
.l_reg = 0x0004,
.m_reg = 0x0008,
diff --git a/drivers/clk/qcom/gcc-ipq4019.c b/drivers/clk/qcom/gcc-ipq4019.c
index 46cb256..8902ad4 100644
--- a/drivers/clk/qcom/gcc-ipq4019.c
+++ b/drivers/clk/qcom/gcc-ipq4019.c
@@ -179,8 +179,6 @@ struct clk_fepll {
"ddrpllapss",
 };

-#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
-
 static const struct freq_tbl ftbl_gcc_audio_pwm_clk[] = {
F(4800, P_XO, 1, 0, 0),
F(2, P_FEPLL200, 1, 0, 0),
diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c
index 0462f4a..505c626 100644
--- a/drivers/clk/qcom/gcc-ipq8074.c
+++ b/drivers/clk/qcom/gcc-ipq8074.c
@@ -32,8 +32,6 @@
 #include "clk-regmap-mux.h"
 #include "reset.h"

-#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
-
 enum {
P_XO,
P_GPLL0,
diff --git a/drivers/clk/qcom/gcc-msm8916.c b/drivers/clk/qcom/gcc-msm8916.c
index d6c7f50..ac2b0aa 100644
--- a/drivers/clk/qcom/gcc-msm8916.c
+++ b/drivers/clk/qcom/gcc-msm8916.c
@@ -264,8 +264,6 @@ enum {
"sleep_clk",
 };

-#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
-
 static struct clk_pll gpll0 = {
.l_reg = 0x21004,
.m_reg = 0x21008,
diff --git a/drivers/clk/qcom/gcc-msm8974.c b/drivers/clk/qcom/gcc-msm8974.c
index 348e30d..08e2900d 100644
--- a/drivers/clk/qcom/gcc-msm8974.c
+++ b/drivers/clk/qcom/gcc-msm8974.c
@@ -62,8 +62,6 @@ enum {
"gpll4_vote",
 };

-#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
-
 static struct clk_pll gpll0 = {
.l_reg = 0x0004,
.m_reg = 0x0008,
diff --git a/drivers/clk/qcom/gcc-msm8994.c b/drivers/clk/qcom/gcc-msm8994.c
index 1e38efc..53f0f36 100644
--- a/drivers/clk/qcom/gcc-msm8994.c
+++ b/drivers/clk/qcom/gcc-msm8994.c
@@ -57,8 +57,6 @@ enum {
"gpll4",
 };

-#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
-
 static struct clk_fixed_factor xo = {
.mult = 1,
.div = 1,
diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c
index 9f35b3f..9d3756c 100644
--- a/drivers/clk/qcom/gcc-msm8996.c
+++ b/drivers/clk/qcom/gcc-msm8996.c
@@ -32,8 +32,6 @@
 #include "reset.h"
 #include "gdsc.h"

-#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
-
 enum {
P_XO,
P_GPLL0,
diff --git a/drivers/clk/qcom/gcc-msm8998.c b/drivers/clk/qcom/gcc-msm8998.c
index 78d87f5..9f0ae40 100644
--- a/drivers/clk/qcom/gcc-msm8998.c
+++ b/drivers/clk/qcom/gcc-msm8998.c
@@ -25,8 +25,6 @@
 #include "reset.h"
 #include "gdsc.h"

-#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
-
 enum {
P_AUD_REF_CLK,
P_CORE_BI_PLL_TEST_SE,
diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index e78e6f5..19b470f 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -25,8 +25,6 @@
 #include "gdsc.h"
 #include "reset.h"

-#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
-
 enum {
P_BI_TCXO,
P_AUD_REF_CLK,
diff --git a/drivers/clk/qcom/mmcc-apq8084.c b/drivers/clk/qcom/mmcc-apq8084.c
index 30777f9..4ce1d7c 100644
--- a/drivers/clk/qcom/mmcc-apq8084.c
+++ b/drivers/clk/qcom/mmcc-apq8084.c
@@ -219,8 +219,6 @@ enum {
"sleep_clk_src",
 };

-#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
-
 static struct clk

[PATCH v3 3/3] clk: qcom: Add display clock controller driver for SDM845

2018-06-23 Thread Taniya Das
Add support for the display clock controller found on SDM845
based devices. This would allow display drivers to probe and
control their clocks.

Signed-off-by: Taniya Das 
---
 drivers/clk/qcom/Kconfig |  10 +
 drivers/clk/qcom/Makefile|   1 +
 drivers/clk/qcom/dispcc-sdm845.c | 674 +++
 3 files changed, 685 insertions(+)
 create mode 100644 drivers/clk/qcom/dispcc-sdm845.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 9c3480d..7300574 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -245,6 +245,16 @@ config SDM_VIDEOCC_845
  Say Y if you want to support video devices and functionality such as
  video encode and decode.
 
+config SDM_DISPCC_845
+   tristate "SDM845 Display Clock Controller"
+   select SDM_GCC_845
+   depends on COMMON_CLK_QCOM
+   help
+ Support for the display clock controller on Qualcomm Technologies, Inc
+ SDM845 devices.
+ Say Y if you want to support display devices and functionality such as
+ splash screen.
+
 config SPMI_PMIC_CLKDIV
tristate "SPMI PMIC clkdiv Support"
depends on (COMMON_CLK_QCOM && SPMI) || COMPILE_TEST
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 762c011..2b041b2d 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_QCOM_A53PLL) += a53-pll.o
 obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o
 obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o
 obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
+obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o
 obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o
 obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o
 obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o
diff --git a/drivers/clk/qcom/dispcc-sdm845.c b/drivers/clk/qcom/dispcc-sdm845.c
new file mode 100644
index 000..af437e0
--- /dev/null
+++ b/drivers/clk/qcom/dispcc-sdm845.c
@@ -0,0 +1,674 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap-divider.h"
+#include "common.h"
+#include "gdsc.h"
+#include "reset.h"
+
+enum {
+   P_BI_TCXO,
+   P_CORE_BI_PLL_TEST_SE,
+   P_DISP_CC_PLL0_OUT_MAIN,
+   P_DSI0_PHY_PLL_OUT_BYTECLK,
+   P_DSI0_PHY_PLL_OUT_DSICLK,
+   P_DSI1_PHY_PLL_OUT_BYTECLK,
+   P_DSI1_PHY_PLL_OUT_DSICLK,
+   P_GPLL0_OUT_MAIN,
+   P_GPLL0_OUT_MAIN_DIV,
+};
+
+static const struct parent_map disp_cc_parent_map_0[] = {
+   { P_BI_TCXO, 0 },
+   { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
+   { P_DSI1_PHY_PLL_OUT_BYTECLK, 2 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const disp_cc_parent_names_0[] = {
+   "bi_tcxo",
+   "dsi0_phy_pll_out_byteclk",
+   "dsi1_phy_pll_out_byteclk",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map disp_cc_parent_map_2[] = {
+   { P_BI_TCXO, 0 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const disp_cc_parent_names_2[] = {
+   "bi_tcxo",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map disp_cc_parent_map_3[] = {
+   { P_BI_TCXO, 0 },
+   { P_DISP_CC_PLL0_OUT_MAIN, 1 },
+   { P_GPLL0_OUT_MAIN, 4 },
+   { P_GPLL0_OUT_MAIN_DIV, 5 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const disp_cc_parent_names_3[] = {
+   "bi_tcxo",
+   "disp_cc_pll0",
+   "gcc_disp_gpll0_clk_src",
+   "gcc_disp_gpll0_div_clk_src",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map disp_cc_parent_map_4[] = {
+   { P_BI_TCXO, 0 },
+   { P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
+   { P_DSI1_PHY_PLL_OUT_DSICLK, 2 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const disp_cc_parent_names_4[] = {
+   "bi_tcxo",
+   "dsi0_phy_pll_out_dsiclk",
+   "dsi1_phy_pll_out_dsiclk",
+   "core_bi_pll_test_se",
+};
+
+static struct clk_alpha_pll disp_cc_pll0 = {
+   .offset = 0x0,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "disp_cc_pll0",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = &clk_alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
+   .cmd_rcgr = 0x20d0,
+   .mnd_width = 0,
+   .hid_width = 5,
+

[PATCH v3 2/3] dt-bindings: clock: Introduce QCOM Display clock bindings

2018-06-23 Thread Taniya Das
Add device tree bindings for display clock controller for Qualcomm
Technology Inc's SDM845 SoCs.

Signed-off-by: Taniya Das 
Reviewed-by: Rob Herring 
---
 .../devicetree/bindings/clock/qcom,dispcc.txt  | 19 +
 include/dt-bindings/clock/qcom,dispcc-sdm845.h | 45 ++
 2 files changed, 64 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,dispcc.txt
 create mode 100644 include/dt-bindings/clock/qcom,dispcc-sdm845.h

diff --git a/Documentation/devicetree/bindings/clock/qcom,dispcc.txt 
b/Documentation/devicetree/bindings/clock/qcom,dispcc.txt
new file mode 100644
index 000..d639e18
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,dispcc.txt
@@ -0,0 +1,19 @@
+Qualcomm Technologies, Inc. Display Clock Controller Binding
+
+
+Required properties :
+
+- compatible : shall contain "qcom,sdm845-dispcc"
+- reg : shall contain base register location and length.
+- #clock-cells : from common clock binding, shall contain 1.
+- #reset-cells : from common reset binding, shall contain 1.
+- #power-domain-cells : from generic power domain binding, shall contain 1.
+
+Example:
+   dispcc: clock-controller@af0 {
+   compatible = "qcom,sdm845-dispcc";
+   reg = <0xaf0 0x10>;
+   #clock-cells = <1>;
+   #reset-cells = <1>;
+   #power-domain-cells = <1>;
+   };
diff --git a/include/dt-bindings/clock/qcom,dispcc-sdm845.h 
b/include/dt-bindings/clock/qcom,dispcc-sdm845.h
new file mode 100644
index 000..11eed4b
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,dispcc-sdm845.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_SDM_DISP_CC_SDM845_H
+#define _DT_BINDINGS_CLK_SDM_DISP_CC_SDM845_H
+
+/* DISP_CC clock registers */
+#define DISP_CC_MDSS_AHB_CLK   0
+#define DISP_CC_MDSS_AXI_CLK   1
+#define DISP_CC_MDSS_BYTE0_CLK 2
+#define DISP_CC_MDSS_BYTE0_CLK_SRC 3
+#define DISP_CC_MDSS_BYTE0_INTF_CLK4
+#define DISP_CC_MDSS_BYTE1_CLK 5
+#define DISP_CC_MDSS_BYTE1_CLK_SRC 6
+#define DISP_CC_MDSS_BYTE1_INTF_CLK7
+#define DISP_CC_MDSS_ESC0_CLK  8
+#define DISP_CC_MDSS_ESC0_CLK_SRC  9
+#define DISP_CC_MDSS_ESC1_CLK  10
+#define DISP_CC_MDSS_ESC1_CLK_SRC  11
+#define DISP_CC_MDSS_MDP_CLK   12
+#define DISP_CC_MDSS_MDP_CLK_SRC   13
+#define DISP_CC_MDSS_MDP_LUT_CLK   14
+#define DISP_CC_MDSS_PCLK0_CLK 15
+#define DISP_CC_MDSS_PCLK0_CLK_SRC 16
+#define DISP_CC_MDSS_PCLK1_CLK 17
+#define DISP_CC_MDSS_PCLK1_CLK_SRC 18
+#define DISP_CC_MDSS_ROT_CLK   19
+#define DISP_CC_MDSS_ROT_CLK_SRC   20
+#define DISP_CC_MDSS_RSCC_AHB_CLK  21
+#define DISP_CC_MDSS_RSCC_VSYNC_CLK22
+#define DISP_CC_MDSS_VSYNC_CLK 23
+#define DISP_CC_MDSS_VSYNC_CLK_SRC 24
+#define DISP_CC_PLL0   25
+#define DISP_CC_MDSS_BYTE0_DIV_CLK_SRC 26
+#define DISP_CC_MDSS_BYTE1_DIV_CLK_SRC 27
+
+/* DISP_CC Reset */
+#define DISP_CC_MDSS_RSCC_BCR  0
+
+/* DISP_CC GDSCR */
+#define MDSS_GDSC  0
+
+#endif
-- 
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



Re: [PATCH v2 0/2] Add display clock controller driver for SDM845

2018-06-23 Thread Taniya Das

Hello Stephen,

Thanks for the comments.

On 6/19/2018 8:53 PM, Stephen Boyd wrote:

Quoting Taniya Das (2018-06-13 03:33:15)

  [v2]
   * Removed unused header file includes.
   * Moved the frequency table macro to a common file [1].
   * Move to pll config to probe.
   * Update SoC name in device tree binding and
 also update the Kconfig.

Add support for the display clock controller found on SDM845
based devices. This would allow display drivers to probe and
control their clocks.

The Display clock driver depends on the frequency table macro
movement to a common file [1].


Please send that patch along with these patches so the dependency is
clear.



Please check the latest patch series :
 https://lkml.org/lkml/2018/6/23/109



  [1]:  https://lkml.org/lkml/2018/6/13/216



--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


Re: [PATCH v4 0/2] clk: qcom: Add support for RCG to register for DFS

2018-08-28 Thread Taniya Das




On 8/28/2018 2:34 AM, Stephen Boyd wrote:

Quoting Stephen Boyd (2018-08-23 11:25:41)

Quoting Taniya Das (2018-08-22 03:28:31)




H. Ok. That won't work then. recalc_rate() better not try to
populate the frequency table then or it will not work. So I suppose it
needs to fallback to reading the registers and assuming the parent_rate
coming in is the actual frequency of it's parent until the frequency
table pointer is non-NULL. Would that work?


Yes that would work.


Ok.




BTW, does DFS switch parents without software knowing about it?

DFS would not switch until a HW request is sent, but SW would be unware
of the switch except the current_perf_state being updated with the
requested level.

What

happens in that case? Does the QUP driver make sure that the new parent
of this RCG is properly enabled so that it can switch to it when needed?


I am not sure if they poll for any of their QUP HW state to make sure
the switch is complete.


I'm still trying to understand this whole design. Who takes care of the
voltage requirements in this case? The QUP driver as well?



When the QUP driver requires to switch to new performance level, the
first request would be to set_rate()(QUP driver would get the list of
supported frequencies using the clk_round_rate()) which in QCOM clock
driver would take care of setting the required voltage for the new
parent switch.


It would also make sure that the new parent is enabled if the QUP clk is
enabled. That's another concern. Does the PLL turn on automatically when
the RCG switches to it?


Then the QUP driver would request the HW for a new perf switch which
would result to a DFS switch for the QUP clocks.


It sounds like the QUP driver does half of the work via the clk APIs and
then the other half through the DFS register. Maybe the QUP driver
should be registering a clk as well for its DFS register so it can all
be clk API calls here. Something to consider. Anyway, that's not
important to this patch so here's the updated patch.


I've squashed this in and applied the patches.


Thanks Stephen.
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


Re: [PATCH v7 2/2] cpufreq: qcom-hw: Add support for QCOM cpufreq HW driver

2018-08-08 Thread Taniya Das




On 8/8/2018 11:52 AM, Stephen Boyd wrote:

Quoting skan...@codeaurora.org (2018-08-06 13:46:05)

On 2018-08-03 15:24, Stephen Boyd wrote:

Quoting skan...@codeaurora.org (2018-08-03 12:52:48)

On 2018-08-03 12:40, Evan Green wrote:

Hi Taniya,

On Tue, Jul 24, 2018 at 3:44 AM Taniya Das  wrote:


+   if (src)
+   c->table[i].frequency = c->xo_rate * lval /
1000;
+   else
+   c->table[i].frequency = INIT_RATE / 1000;


I don't know much about how this hardware works, but based on the
mask, src has 4 possible values. So does 0 mean INIT_RATE, and 1, 2,
and 3 all mean xo_rate?

Also, is INIT_RATE really constant? It sounds like gpll0 (or
gpll0_out_even?). You're already getting the xo clock, why not get
gpll0's real rate as well?


Actually I was about to comment and say NOT to get clocks just to get
their rate. The XO_RATE is just a multiplication factor. This HW/FW
can
change in the future and make the multiplication factor to 1KHz.


So future changes to this hardware are going to make this register
return the final frequency that we should use? Sounds great! But that
isn't how it's working right now. We need to have XO in the binding
here
so the driver can work with different XO frequencies in case that ever
happens. Same story for GPLL0. Hardcoding this stuff in the driver just
means we'll have to swizzle things in the driver when it changes.


XO being a different frequency in a Qualcomm chip is way way less likely
than anything else we are discussing here. In the 10+years I've been
there this has never changed.

So, how about making this binding optional? If it's not present we can
make assumptions for XO rate and init rate. That'll handle your
hypothetical use case while also being optimized.


Optional properties are almost never correct for clks. Either the clk
goes there or it doesn't go there. The only time it's optional is if the
HW has the choice of generating the clk itself internally or to use an
external clk as input.

In this case, it's not optional, it's actually used so marking it
optional is highly confusing.




We also
can't really control any of the clocks going to this block from Linux
(it's all locked down).


This shouldn't matter. The clocks going to this hardware block are
described by the firmware to the OS by means of the DT node. If the
firmware or the hardware decides to change the input clks then the
binding can have different clk nodes used.


There are tons of clocks that are input to blocks in an SoC that are
never controlled by Linux. Or are expose in DT because they are set up
ahead of time and can't change. So, why make an exception here?


Because the driver doesn't have to hard-code some frequency that can
easily come from the DT, making it more flexible for frequency plan
changes. It doesn't matter about control of clks at all here, so this
comparison is just plain wrong.




The INIT_RATE will
always be 300 MHz independent of what source it's coming from (as in,
if
GPLL0 can't give 300, the HW design will be so that we'll find a
different source).

So, I'd like to remove any clock bindings for this driver.


No. Bindings describe how the hardware is connected. Please don't
remove
clocks from the binding just because probe defer is a concern.


Binding describes hardware controllable by the OS. That's the reality.
Let's not add mandatory clock bindings for clocks that the OS can't do
anything about.



It seems that you believe clks should only be used to turn on/off and
control rates. That is not the whole truth. Sometimes clks are there
just to express the clk frequencies that are present in the design so
that drivers can figure out what to do.



Stephen,

As this clock is not configurable by linux clock drivers and we really 
do not care the parent src(as mentioned by Saravana) to generate the 
300MHz, would it be good to define a fixed rate clock so as to express 
the HW connectivity & frequency?


--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


Re: [PATCH v3 1/2] clk: qcom: Add qspi (Quad SPI) clock defines for sdm845 to header

2018-08-10 Thread Taniya Das




On 7/25/2018 9:31 PM, Rob Herring wrote:

On Tue, Jul 24, 2018 at 10:45:12AM -0700, Douglas Anderson wrote:

These clocks will need to be defined in the clock driver and
referenced in device tree files.

Signed-off-by: Douglas Anderson 
---

Changes in v3: None
Changes in v2: None

  include/dt-bindings/clock/qcom,gcc-sdm845.h | 3 +++
  1 file changed, 3 insertions(+)


Acked-by: Rob Herring 

  Reviewed-by: Taniya Das 


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



--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


Re: [PATCH v3 2/2] clk: qcom: Add qspi (Quad SPI) clocks for sdm845

2018-08-10 Thread Taniya Das




On 7/24/2018 11:15 PM, Douglas Anderson wrote:

Add both the interface and core clock.

Signed-off-by: Douglas Anderson 
(am from https://lore.kernel.org/patchwork/patch/966680/mbox)

---

Changes in v3:
- Removed gcc_parent_names_9 which I had left in (doh!).

Changes in v2:
- Only 19.2, 100, 150, and 300 MHz now.
- All clocks come from MAIN rather than EVEN.
- Use parent map 0 instead of new parent map 9.

  drivers/clk/qcom/gcc-sdm845.c | 56 +++
  1 file changed, 56 insertions(+)

diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index 0f694ed4238a..fc1c6658ad82 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -358,6 +358,28 @@ static struct clk_rcg2 gcc_pcie_phy_refgen_clk_src = {
},
  };
  
+static const struct freq_tbl ftbl_gcc_qspi_core_clk_src[] = {

+   F(1920, P_BI_TCXO, 1, 0, 0),
+   F(1, P_GPLL0_OUT_MAIN, 6, 0, 0),
+   F(15000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+   F(3, P_GPLL0_OUT_MAIN, 2, 0, 0),
+   { }
+};
+
+static struct clk_rcg2 gcc_qspi_core_clk_src = {
+   .cmd_rcgr = 0x4b008,
+   .mnd_width = 0,
+   .hid_width = 5,
+   .parent_map = gcc_parent_map_0,
+   .freq_tbl = ftbl_gcc_qspi_core_clk_src,
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "gcc_qspi_core_clk_src",
+   .parent_names = gcc_parent_names_0,
+   .num_parents = 4,
+   .ops = &clk_rcg2_floor_ops,
+   },
+};
+
  static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = {
F(960, P_BI_TCXO, 2, 0, 0),
F(1920, P_BI_TCXO, 1, 0, 0),
@@ -1935,6 +1957,37 @@ static struct clk_branch gcc_qmip_video_ahb_clk = {
},
  };
  
+static struct clk_branch gcc_qspi_cnoc_periph_ahb_clk = {

+   .halt_reg = 0x4b000,
+   .halt_check = BRANCH_HALT,
+   .clkr = {
+   .enable_reg = 0x4b000,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_qspi_cnoc_periph_ahb_clk",
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
+static struct clk_branch gcc_qspi_core_clk = {
+   .halt_reg = 0x4b004,
+   .halt_check = BRANCH_HALT,
+   .clkr = {
+   .enable_reg = 0x4b004,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_qspi_core_clk",
+   .parent_names = (const char *[]){
+   "gcc_qspi_core_clk_src",
+   },
+   .num_parents = 1,
+   .flags = CLK_SET_RATE_PARENT,
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
  static struct clk_branch gcc_qupv3_wrap0_s0_clk = {
.halt_reg = 0x17030,
.halt_check = BRANCH_HALT_VOTED,
@@ -3383,6 +3436,9 @@ static struct clk_regmap *gcc_sdm845_clocks[] = {
[GPLL4] = &gpll4.clkr,
[GCC_CPUSS_DVM_BUS_CLK] = &gcc_cpuss_dvm_bus_clk.clkr,
[GCC_CPUSS_GNOC_CLK] = &gcc_cpuss_gnoc_clk.clkr,
+   [GCC_QSPI_CORE_CLK_SRC] = &gcc_qspi_core_clk_src.clkr,
+   [GCC_QSPI_CORE_CLK] = &gcc_qspi_core_clk.clkr,
+   [GCC_QSPI_CNOC_PERIPH_AHB_CLK] = &gcc_qspi_cnoc_periph_ahb_clk.clkr,
  };
  
  static const struct qcom_reset_map gcc_sdm845_resets[] = {




Reviewed-by: Taniya Das 

--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


[PATCH v4 2/2] clk: qcom: gcc: Register QUPv3 RCGs for DFS on SDM845

2018-08-10 Thread Taniya Das
QUPv3 clocks support DFS and thus register the RCGs which require support
for the same.

Signed-off-by: Taniya Das 
---
 drivers/clk/qcom/gcc-sdm845.c | 25 +
 1 file changed, 25 insertions(+)

diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index fa1a196..fef6732 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -3458,9 +3458,29 @@ enum {
 };
 MODULE_DEVICE_TABLE(of, gcc_sdm845_match_table);
 
+static struct clk_rcg2 *gcc_dfs_clocks[] = {
+   &gcc_qupv3_wrap0_s0_clk_src,
+   &gcc_qupv3_wrap0_s1_clk_src,
+   &gcc_qupv3_wrap0_s2_clk_src,
+   &gcc_qupv3_wrap0_s3_clk_src,
+   &gcc_qupv3_wrap0_s4_clk_src,
+   &gcc_qupv3_wrap0_s5_clk_src,
+   &gcc_qupv3_wrap0_s6_clk_src,
+   &gcc_qupv3_wrap0_s7_clk_src,
+   &gcc_qupv3_wrap1_s0_clk_src,
+   &gcc_qupv3_wrap1_s1_clk_src,
+   &gcc_qupv3_wrap1_s2_clk_src,
+   &gcc_qupv3_wrap1_s3_clk_src,
+   &gcc_qupv3_wrap1_s4_clk_src,
+   &gcc_qupv3_wrap1_s5_clk_src,
+   &gcc_qupv3_wrap1_s6_clk_src,
+   &gcc_qupv3_wrap1_s7_clk_src,
+};
+
 static int gcc_sdm845_probe(struct platform_device *pdev)
 {
struct regmap *regmap;
+   int ret;
 
regmap = qcom_cc_map(pdev, &gcc_sdm845_desc);
if (IS_ERR(regmap))
@@ -3470,6 +3490,11 @@ static int gcc_sdm845_probe(struct platform_device *pdev)
regmap_update_bits(regmap, 0x09ffc, 0x3, 0x3);
regmap_update_bits(regmap, 0x71028, 0x3, 0x3);
 
+   ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks,
+   ARRAY_SIZE(gcc_dfs_clocks));
+   if (ret)
+   return ret;
+
return qcom_cc_really_probe(pdev, &gcc_sdm845_desc, regmap);
 }
 
-- 
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



[PATCH v4 1/2] clk: qcom: Add support for RCG to register for DFS

2018-08-10 Thread Taniya Das
Dynamic Frequency switch is a feature of clock controller by which request
from peripherals allows automatic switching frequency of input clock
without SW intervention. There are various performance levels associated
with a root clock. When the input performance state changes, the source
clocks and division ratios of the new performance state are loaded on to
RCG via HW and the RCG switches to new clock frequency when the RCG is in
DFS HW enabled mode.

Register the root clock generators(RCG) to switch to use the dfs clock ops
in the cases where DFS is enabled. The clk_round_rate() called by the clock
consumer would invoke the dfs determine clock ops and would read the DFS
performance level registers to identify all the frequencies supported and
update the frequency table. The DFS clock consumers would maintain these
frequency mapping and request the desired performance levels.

Signed-off-by: Taniya Das 
---
 drivers/clk/qcom/clk-rcg.h  |   2 +
 drivers/clk/qcom/clk-rcg2.c | 224 
 2 files changed, 226 insertions(+)

diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h
index dbd5a9e..e6300e0 100644
--- a/drivers/clk/qcom/clk-rcg.h
+++ b/drivers/clk/qcom/clk-rcg.h
@@ -163,4 +163,6 @@ struct clk_rcg2 {
 extern const struct clk_ops clk_gfx3d_ops;
 extern const struct clk_ops clk_rcg2_shared_ops;
 
+extern int qcom_cc_register_rcg_dfs(struct regmap *regmap,
+struct clk_rcg2 **rcgs, int num_clks);
 #endif
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index 52208d4..55a5b58 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -40,6 +41,14 @@
 #define N_REG  0xc
 #define D_REG  0x10
 
+/* Dynamic Frequency Scaling */
+#define MAX_PERF_LEVEL 8
+#define SE_CMD_DFSR_OFFSET 0x14
+#define SE_CMD_DFS_EN  BIT(0)
+#define SE_PERF_DFSR(level)(0x1c + 0x4 * (level))
+#define SE_PERF_M_DFSR(level)  (0x5c + 0x4 * (level))
+#define SE_PERF_N_DFSR(level)  (0x9c + 0x4 * (level))
+
 enum freq_policy {
FLOOR,
CEIL,
@@ -929,3 +938,218 @@ static void clk_rcg2_shared_disable(struct clk_hw *hw)
.set_rate_and_parent = clk_rcg2_shared_set_rate_and_parent,
 };
 EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops);
+
+/* Common APIs to be used for DFS based RCGR */
+static unsigned long clk_rcg2_calculate_freq(struct clk_hw *hw,
+   int level, struct freq_tbl *f)
+{
+   struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+   struct clk_hw *p;
+   unsigned long prate = 0;
+   u32 val, mask, cfg, m_off, n_off, offset, mode;
+   int i, ret, num_parents;
+
+   offset = SE_PERF_DFSR(level);
+   ret = regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + offset, &cfg);
+   if (ret)
+   return ret;
+
+   mask = BIT(rcg->hid_width) - 1;
+   f->pre_div = cfg & mask ? (cfg & mask) : 1;
+
+   mode = cfg & CFG_MODE_MASK;
+   mode >>= CFG_MODE_SHIFT;
+
+   cfg &= CFG_SRC_SEL_MASK;
+   cfg >>= CFG_SRC_SEL_SHIFT;
+
+   num_parents = clk_hw_get_num_parents(hw);
+   for (i = 0; i < num_parents; i++) {
+   if (cfg == rcg->parent_map[i].cfg) {
+   f->src = rcg->parent_map[i].src;
+   p = clk_hw_get_parent_by_index(&rcg->clkr.hw, i);
+   prate = clk_hw_get_rate(p);
+   }
+   }
+
+   if (mode) {
+   /* Calculate M & N values */
+   m_off = SE_PERF_M_DFSR(level);
+   n_off = SE_PERF_N_DFSR(level);
+
+   mask = BIT(rcg->mnd_width) - 1;
+   ret = regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + m_off,
+   &val);
+   if (ret) {
+   pr_err("Failed to read M offset register\n");
+   return ret;
+   }
+   val &= mask;
+   f->m = val;
+
+   ret = regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + n_off,
+   &val);
+   if (ret) {
+   pr_err("Failed to read N offset register\n");
+   return ret;
+   }
+   /* val ~(N-M) */
+   val = ~val;
+   val &= mask;
+   val += f->m;
+   f->n = val;
+   }
+
+   return calc_rate(prate, f->m, f->n, mode, f->pre_div);
+}
+
+static int clk_rcg2_dfs_populate_freq_table(struct clk_rcg2 *rcg)
+{
+   struct freq_tbl *freq_tbl;
+   unsigned long calc_freq;
+   int i;
+
+   freq_tbl = kcalloc(MAX_PERF_LEVEL, sizeof(*freq_tbl),
+   GFP_KERNEL);
+   if (!freq_tbl)
+ 

[PATCH v4 0/2] clk: qcom: Add support for RCG to register for DFS

2018-08-10 Thread Taniya Das
 [v4]
  * Add recalc_clk_ops to calculate the clock frequency reading the current
perf state, also add CLK_GET_RATE_NOCACHE flag.
  * Cleanup 'goto' during mode check in 'clk_rcg2_calculate_freq'.
  * cleanup return from function 'com_cc_register_rcg_dfs'.

 [v3]
  * Rename clk_rcg2_calculate_m_and_n with clk_rcg2_calculate_freq, as this
function would now calculate the frequency.
  * Rename dfs_freq_tbl to freq_tbl.
  * Remove the logic to remove duplicate frequencies.
  * Remove recalc_rate & set_rate clock ops.
  * clk_rcg2_dfs_ops clock ops is static.
  * Override the clock ops only if DFS mode is enabled.
  * qcom_cc_register_rcg_dfs uses regmap instead of device.
  * Few cleanups : Remove DFS probing after registering clocks.
sizeof(*init), sizeof(*freq_tbl).

 [v2]
  * Move the dfs register function 'qcom_cc_register_rcg_dfs'
to clk-rcg2.c instead of common.c
  * At boot read the DFS enable register and override the clk_ops
to be used for dfs or non-dfs RCGs.
  * Remove flag 'dfs_enabled'.
  * Remove functions 'clk_rcg2_dfs_determine_rate_lazy'
  * Remove 'struct dfs_table *dfs_entry'
  * Remove '_freq_tbl_determine_dfs_rate'
  * Combine the function 'clk_index_pre_div_and_mode' and 'calculate_m_and_n'
to a single function and named it 'clk_rcg2_calculate_m_and_n'.
  * Remove taking M/N/PERF offsets as function arguments.
  * Add clocks in gcc-sdm845.c the DFS clock array to register.

 [v1]
   * Update SPDX for files.
   * Add new clk_ops for DFS mode which would be used if dfs is enabled,
 else fall back to the clk_rcg2_shared_ops.
   * Use kcalloc in place kzalloc.
   * Fixed the return type for 'clk_parent_index_pre_div_and_mode' which
 is now renamed to 'clk_index_pre_div_and_mode'.
   * Removed return of -EPERM from 'clk_rcg2_set_rate' and new dfs
 clk_ops is introduced.
   * Pass frequency table entry structure to function calculate_m_and_n.
   * Remove desc from qcom_cc_register_rcg_dfs and instead pass array of
 clk_rcg2.
   * Add a dfs_enable flag to identify if dfs mode is enabled.

In the cases where a RCG requires a Dynamic Frequency switch support
requires to register which would at runtime read the clock perf level
registers to identify the frequencies supported and update the frequency
table accordingly.

Taniya Das (2):
  clk: qcom: Add support for RCG to register for DFS
  clk: qcom: gcc: Register QUPv3 RCGs for DFS on SDM845

 drivers/clk/qcom/clk-rcg.h|   2 +
 drivers/clk/qcom/clk-rcg2.c   | 224 ++
 drivers/clk/qcom/gcc-sdm845.c |  25 +
 3 files changed, 251 insertions(+)

--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



Re: [PATCH] clk: qcom: Add Global Clock controller (GCC) driver for SDM660

2018-08-12 Thread Taniya Das

Hello Craig,

Could you please correct the authorship and also provide the reference 
to code where this is picked from?


On 8/11/2018 1:51 AM, Craig Tatlor wrote:

Add support for the global clock controller found on SDM660
based devices. This should allow most non-multimedia device
drivers to probe and control their clocks.
Based on CAF implementation.

Signed-off-by: Craig Tatlor 
---
  .../devicetree/bindings/clock/qcom,gcc.txt|1 +
  drivers/clk/qcom/Kconfig  |9 +
  drivers/clk/qcom/Makefile |1 +
  drivers/clk/qcom/gcc-sdm660.c | 2479 +
  include/dt-bindings/clock/qcom,gcc-sdm660.h   |  159 ++
  5 files changed, 2649 insertions(+)
  create mode 100644 drivers/clk/qcom/gcc-sdm660.c
  create mode 100644 include/dt-bindings/clock/qcom,gcc-sdm660.h

diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.txt 
b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
index 664ea1fd6c76..e498ad2e8db8 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt
+++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
@@ -19,6 +19,7 @@ Required properties :
"qcom,gcc-msm8996"
"qcom,gcc-msm8998"
"qcom,gcc-mdm9615"
+   "qcom,gcc-sdm660"
"qcom,gcc-sdm845"
  
  - reg : shall contain base register location and length

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 9c3480dcc38a..c4bda6d24c1f 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -226,6 +226,15 @@ config MSM_GCC_8998
  Say Y if you want to use peripheral devices such as UART, SPI,
  i2c, USB, UFS, SD/eMMC, PCIe, etc.
  
+config SDM_GCC_660

+   tristate "SDM660 Global Clock Controller"
+   select QCOM_GDSC
+   depends on COMMON_CLK_QCOM
+   help
+ Support for the global clock controller on SDM660 devices.
+ Say Y if you want to use peripheral devices such as UART, SPI,
+ i2C, USB, UFS, SDDC, PCIe, etc.
+
  config SDM_GCC_845
tristate "SDM845 Global Clock Controller"
select QCOM_GDSC
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 762c01137c2f..6e37d30d7c02 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_QCOM_A53PLL) += a53-pll.o
  obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o
  obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o
  obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
+obj-$(CONFIG_SDM_GCC_660) += gcc-sdm660.o
  obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o
  obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o
  obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o
diff --git a/drivers/clk/qcom/gcc-sdm660.c b/drivers/clk/qcom/gcc-sdm660.c
new file mode 100644
index ..bdb445aa4baa
--- /dev/null
+++ b/drivers/clk/qcom/gcc-sdm660.c
@@ -0,0 +1,2479 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018, Craig Tatlor.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "common.h"
+#include "clk-regmap.h"
+#include "clk-alpha-pll.h"
+#include "clk-rcg.h"
+#include "clk-branch.h"
+#include "reset.h"
+#include "gdsc.h"
+
+#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
+
+enum {
+   P_XO,
+   P_SLEEP_CLK,
+   P_GPLL0,
+   P_GPLL1,
+   P_GPLL4,
+   P_GPLL0_EARLY_DIV,
+   P_GPLL1_EARLY_DIV,
+};
+
+static const struct parent_map gcc_parent_map_xo_gpll0_gpll0_early_div[] = {
+   { P_XO, 0 },
+   { P_GPLL0, 1 },
+   { P_GPLL0_EARLY_DIV, 6 },
+};
+
+static const char * const gcc_parent_names_xo_gpll0_gpll0_early_div[] = {
+   "xo",
+   "gpll0",
+   "gpll0_early_div",
+};
+
+static const struct parent_map gcc_parent_map_xo_gpll0[] = {
+   { P_XO, 0 },
+   { P_GPLL0, 1 },
+};
+
+static const char * const gcc_parent_names_xo_gpll0[] = {
+   "xo",
+   "gpll0",
+};
+
+static const struct parent_map 
gcc_parent_map_xo_gpll0_sleep_clk_gpll0_early_div[] = {
+   { P_XO, 0 },
+   { P_GPLL0, 1 },
+   { P_SLEEP_CLK, 5 },
+   { P_GPLL0_EARLY_DIV, 6 },
+};
+
+static const char * const 
gcc_parent_names_xo_gpll0_sleep_clk_gpll0_early_div[] = {
+   "xo",
+   "gpll0",
+   "sleep_clk",
+   "gpll0_early_div",
+};
+
+static const struct parent_map gcc_parent_map_xo_sleep_clk[] = {
+   { P_XO, 0 },
+   { P_SLEEP_CLK, 5 },
+};
+
+static const char * const gcc_parent_names_xo_sleep_clk[] = {
+   "xo",
+   "sleep_clk",
+};
+
+static const struct parent_map gcc_parent_map_xo_gpll4[] = {
+   { P_XO, 0 },
+   { P_GPLL4, 5 },
+};
+
+static const char * const gcc_parent_names_xo_gpll4[] = {
+   "xo",
+   "gpll4",
+};
+
+static const struct parent_map 
gcc_parent_map

Re: [PATCH v4 0/2] clk: qcom: Add support for RCG to register for DFS

2018-08-21 Thread Taniya Das

Hello Stephen,

Thanks for the changes, I have tested the changes and would require the 
change mentioned below for this to work.


On 8/18/2018 11:31 PM, Taniya Das wrote:

Hello Stephen,

I will test these changes and get back.

On 8/18/2018 7:42 AM, Stephen Boyd wrote:

Quoting Taniya Das (2018-08-10 18:53:54)

  [v4]
   * Add recalc_clk_ops to calculate the clock frequency reading the 
current

 perf state, also add CLK_GET_RATE_NOCACHE flag.
   * Cleanup 'goto' during mode check in 'clk_rcg2_calculate_freq'.
   * cleanup return from function 'com_cc_register_rcg_dfs'.


I want to squash this in. I have only compile tested it. Let me know
what you think.

8<---
diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h
index e6300e05d5df..e5eca8a1abe4 100644
--- a/drivers/clk/qcom/clk-rcg.h
+++ b/drivers/clk/qcom/clk-rcg.h
@@ -163,6 +163,15 @@ extern const struct clk_ops clk_pixel_ops;
  extern const struct clk_ops clk_gfx3d_ops;
  extern const struct clk_ops clk_rcg2_shared_ops;
+struct clk_rcg_dfs_data {
+    struct clk_rcg2 *rcg;
+    struct clk_init_data *init;
+};
+
+#define DEFINE_RCG_DFS(r) \
+    { .rcg = &r##_src, .init = &r##_init }
+
  extern int qcom_cc_register_rcg_dfs(struct regmap *regmap,
- struct clk_rcg2 **rcgs, int num_clks);
+    const struct clk_rcg_dfs_data *rcgs,
+    size_t len);
  #endif
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index 55a5b58cbb15..bbe2a1916296 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -1051,48 +1051,24 @@ static unsigned long
  clk_rcg2_dfs_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
  {
  struct clk_rcg2 *rcg = to_clk_rcg2(hw);
-    u32 cfg, hid_div, m = 0, n = 0, mode = 0, mask, level;
-    int num_parents, i;
-    unsigned long prate;
-
-    regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr +
-    SE_CMD_DFSR_OFFSET, &cfg);
-    level = (GENMASK(4, 1) & cfg) >> 1;
-
-    regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr +
-    SE_PERF_DFSR(level), &cfg);
-    if (rcg->mnd_width) {
-    mask = BIT(rcg->mnd_width) - 1;
-    regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr +
-    SE_PERF_M_DFSR(level), &m);
-    m &= mask;
-    regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr +
-    SE_PERF_N_DFSR(level), &n);
-    n =  ~n;
-    n &= mask;
-    n += m;
-    mode = cfg & CFG_MODE_MASK;
-    mode >>= CFG_MODE_SHIFT;
-    }
+    int ret;
+    u32 level;
-    mask = BIT(rcg->hid_width) - 1;
-    hid_div = cfg >> CFG_SRC_DIV_SHIFT;
-    hid_div &= mask;
-    cfg &= CFG_SRC_SEL_MASK;
-    cfg >>= CFG_SRC_SEL_SHIFT;
+    regmap_read(rcg->clkr.regmap,
+    rcg->cmd_rcgr + SE_CMD_DFSR_OFFSET, &level);
+    level &= GENMASK(4, 1);
+    level >>= 1;
-    num_parents = clk_hw_get_num_parents(hw);
-    for (i = 0; i < num_parents; i++) {
-    if (cfg == rcg->parent_map[i].cfg) {
-    prate = clk_hw_get_rate(
-    clk_hw_get_parent_by_index(&rcg->clkr.hw, i));
-    if (parent_rate != prate)
-    parent_rate = prate;
+    if (!rcg->freq_tbl) {
+    ret = clk_rcg2_dfs_populate_freq_table(rcg);


This function would retrieve the parent_rate and if the parent_rate is 
not ready then it would fail to boot up.


So we have to make sure the parents are registered before these RCGs. 
That also was one reason for me to not populate the frequency table at 
recalc.


We would need this patch to make this work.

 /* GCC clock registers */
-#define GCC_AGGRE_NOC_PCIE_TBU_CLK 0
-#define GCC_AGGRE_UFS_CARD_AXI_CLK 1
-#define GCC_AGGRE_UFS_PHY_AXI_CLK  2
-#define GCC_AGGRE_USB3_PRIM_AXI_CLK3
+#define GPLL0  0
+#define GPLL0_OUT_EVEN 1
+#define GPLL0_OUT_MAIN 2
+#define GPLL4  3
 #define GCC_AGGRE_USB3_SEC_AXI_CLK 4
 #define GCC_BOOT_ROM_AHB_CLK   5
 #define GCC_CAMERA_AHB_CLK 6
@@ -172,9 +172,9 @@
 #define GCC_VIDEO_AHB_CLK  162
 #define GCC_VIDEO_AXI_CLK  163
 #define GCC_VIDEO_XO_CLK   164
-#define GPLL0  165
-#define GPLL0_OUT_EVEN 166
-#define GPLL0_OUT_MAIN 167
+#define GCC_AGGRE_NOC_PCIE_TBU_CLK

Re: [PATCH v4 0/2] clk: qcom: Add support for RCG to register for DFS

2018-08-22 Thread Taniya Das




On 8/21/2018 9:00 PM, Stephen Boyd wrote:

Quoting Taniya Das (2018-08-21 04:36:20)

On 8/18/2018 11:31 PM, Taniya Das wrote:

Hello Stephen,

I will test these changes and get back.

On 8/18/2018 7:42 AM, Stephen Boyd wrote:

Quoting Taniya Das (2018-08-10 18:53:54)

   [v4]
    * Add recalc_clk_ops to calculate the clock frequency reading the
current
  perf state, also add CLK_GET_RATE_NOCACHE flag.
    * Cleanup 'goto' during mode check in 'clk_rcg2_calculate_freq'.
    * cleanup return from function 'com_cc_register_rcg_dfs'.


I want to squash this in. I have only compile tested it. Let me know
what you think.

8<---
diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h
index e6300e05d5df..e5eca8a1abe4 100644
--- a/drivers/clk/qcom/clk-rcg.h
+++ b/drivers/clk/qcom/clk-rcg.h
@@ -163,6 +163,15 @@ extern const struct clk_ops clk_pixel_ops;
   extern const struct clk_ops clk_gfx3d_ops;
   extern const struct clk_ops clk_rcg2_shared_ops;
+struct clk_rcg_dfs_data {
+    struct clk_rcg2 *rcg;
+    struct clk_init_data *init;
+};
+
+#define DEFINE_RCG_DFS(r) \
+    { .rcg = &r##_src, .init = &r##_init }
+
   extern int qcom_cc_register_rcg_dfs(struct regmap *regmap,
- struct clk_rcg2 **rcgs, int num_clks);
+    const struct clk_rcg_dfs_data *rcgs,
+    size_t len);
   #endif
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index 55a5b58cbb15..bbe2a1916296 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -1051,48 +1051,24 @@ static unsigned long
   clk_rcg2_dfs_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
   {
   struct clk_rcg2 *rcg = to_clk_rcg2(hw);
-    u32 cfg, hid_div, m = 0, n = 0, mode = 0, mask, level;
-    int num_parents, i;
-    unsigned long prate;
-
-    regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr +
-    SE_CMD_DFSR_OFFSET, &cfg);
-    level = (GENMASK(4, 1) & cfg) >> 1;
-
-    regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr +
-    SE_PERF_DFSR(level), &cfg);
-    if (rcg->mnd_width) {
-    mask = BIT(rcg->mnd_width) - 1;
-    regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr +
-    SE_PERF_M_DFSR(level), &m);
-    m &= mask;
-    regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr +
-    SE_PERF_N_DFSR(level), &n);
-    n =  ~n;
-    n &= mask;
-    n += m;
-    mode = cfg & CFG_MODE_MASK;
-    mode >>= CFG_MODE_SHIFT;
-    }
+    int ret;
+    u32 level;
-    mask = BIT(rcg->hid_width) - 1;
-    hid_div = cfg >> CFG_SRC_DIV_SHIFT;
-    hid_div &= mask;
-    cfg &= CFG_SRC_SEL_MASK;
-    cfg >>= CFG_SRC_SEL_SHIFT;
+    regmap_read(rcg->clkr.regmap,
+    rcg->cmd_rcgr + SE_CMD_DFSR_OFFSET, &level);
+    level &= GENMASK(4, 1);
+    level >>= 1;
-    num_parents = clk_hw_get_num_parents(hw);
-    for (i = 0; i < num_parents; i++) {
-    if (cfg == rcg->parent_map[i].cfg) {
-    prate = clk_hw_get_rate(
-    clk_hw_get_parent_by_index(&rcg->clkr.hw, i));
-    if (parent_rate != prate)
-    parent_rate = prate;
+    if (!rcg->freq_tbl) {
+    ret = clk_rcg2_dfs_populate_freq_table(rcg);


This function would retrieve the parent_rate and if the parent_rate is
not ready then it would fail to boot up.

So we have to make sure the parents are registered before these RCGs.
That also was one reason for me to not populate the frequency table at
recalc.

We would need this patch to make this work.


H. Ok. That won't work then. recalc_rate() better not try to
populate the frequency table then or it will not work. So I suppose it
needs to fallback to reading the registers and assuming the parent_rate
coming in is the actual frequency of it's parent until the frequency
table pointer is non-NULL. Would that work?


Yes that would work.

BTW, does DFS switch parents without software knowing about it? 
DFS would not switch until a HW request is sent, but SW would be unware 
of the switch except the current_perf_state being updated with the 
requested level.


What

happens in that case? Does the QUP driver make sure that the new parent
of this RCG is properly enabled so that it can switch to it when needed?


I am not sure if they poll for any of their QUP HW state to make sure 
the switch is complete.



I'm still trying to understand this whole design. Who takes care of the
voltage requirements in this case? The QUP driver as well?



When the QUP driver requires to switch to new performance level, the 
first request would be to set_rate()(QUP driver would get the list of 
supported frequencies using the clk_round_rate()) which in QCOM clock 
driver would take care of setting the required voltage for the new 
parent switch.
Then the QUP driver would req

Re: [PATCH v5] clk: qcom: Add display clock controller driver for SDM845

2018-07-27 Thread Taniya Das




On 7/27/2018 3:35 AM, Stephen Boyd wrote:

Quoting Taniya Das (2018-07-23 03:54:35)

Add support for the display clock controller found on SDM845
based devices. This would allow display drivers to probe and
control their clocks.

Signed-off-by: Taniya Das 
---


This is fine to merge as long as you're ok with removing the no rate
cache flag. I can do that myself so you don't have to resend.



Thanks, please go ahead and remove the flags, in case the display 
drivers would require the flags for any proper use case then we could 
think on re-introducing them.


--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


Re: [RFC PATCH 2/2] clk: qcom: Add qspi (Quad SPI) clocks for sdm845

2018-07-19 Thread Taniya Das

Hi Doug,

Please find my comments inline.

On 7/18/2018 11:34 PM, Douglas Anderson wrote:

Add both the interface and core clock.

Signed-off-by: Douglas Anderson 
---

  drivers/clk/qcom/gcc-sdm845.c | 73 +++
  1 file changed, 73 insertions(+)

diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index 0f694ed4238a..2ee96f9bc217 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -162,6 +162,20 @@ static const char * const gcc_parent_names_10[] = {
"core_bi_pll_test_se",
  };
  
+static const struct parent_map gcc_parent_map_9[] = {

+   { P_BI_TCXO, 0 },
+   { P_GPLL0_OUT_MAIN, 1 },
+   { P_GPLL0_OUT_EVEN, 6 },
+   { P_SLEEP_CLK, 7 },


SRC 7 has 'core_bi_pll_test_se' and not 'sleep_clk'.

Please use the 'gcc_parent_map_0'


+};
+
+static const char * const gcc_parent_names_9[] = {
+   "bi_tcxo",
+   "gpll0",
+   "gpll0_out_even",
+   "core_pi_sleep_clk",
+};
+
  static struct clk_alpha_pll gpll0 = {
.offset = 0x0,
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
@@ -358,6 +372,31 @@ static struct clk_rcg2 gcc_pcie_phy_refgen_clk_src = {
},
  };
  
+static const struct freq_tbl ftbl_gcc_qspi_core_clk_src[] = {

+   F(1920, P_BI_TCXO, 1, 0, 0),
+   F(5000, P_GPLL0_OUT_EVEN, 6, 0, 0),
+   F(7500, P_GPLL0_OUT_EVEN, 4, 0, 0),
+   F(1, P_GPLL0_OUT_EVEN, 3, 0, 0),


Is SW planning to use this frequency?


+   F(15000, P_GPLL0_OUT_EVEN, 2, 0, 0),


F(15000, P_GPLL0_OUT_MAIN, 4, 0, 0),


+   F(3, P_GPLL0_OUT_EVEN, 1, 0, 0),


F(3, P_GPLL0_OUT_MAIN, 2, 0, 0),


+   F(4, P_GPLL0_OUT_MAIN, 1.5, 0, 0),

Please remove this, the Max supported frequency is 300MHz.

+   { }
+};
+
+static struct clk_rcg2 gcc_qspi_core_clk_src = {
+   .cmd_rcgr = 0x4b008,
+   .mnd_width = 0,
+   .hid_width = 5,
+   .parent_map = gcc_parent_map_9,
+   .freq_tbl = ftbl_gcc_qspi_core_clk_src,
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "gcc_qspi_core_clk_src",
+   .parent_names = gcc_parent_names_9,
+   .num_parents = 4,
+   .ops = &clk_rcg2_floor_ops,


Could we use the rcg2_ops instead?


+   },
+};
+
  static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = {
F(960, P_BI_TCXO, 2, 0, 0),
F(1920, P_BI_TCXO, 1, 0, 0),
@@ -1935,6 +1974,37 @@ static struct clk_branch gcc_qmip_video_ahb_clk = {
},
  };
  
+static struct clk_branch gcc_qspi_cnoc_periph_ahb_clk = {

+   .halt_reg = 0x4b000,
+   .halt_check = BRANCH_HALT,
+   .clkr = {
+   .enable_reg = 0x4b000,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_qspi_cnoc_periph_ahb_clk",
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
+static struct clk_branch gcc_qspi_core_clk = {
+   .halt_reg = 0x4b004,
+   .halt_check = BRANCH_HALT,
+   .clkr = {
+   .enable_reg = 0x4b004,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_qspi_core_clk",
+   .parent_names = (const char *[]){
+   "gcc_qspi_core_clk_src",
+   },
+   .num_parents = 1,
+   .flags = CLK_SET_RATE_PARENT,
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
  static struct clk_branch gcc_qupv3_wrap0_s0_clk = {
.halt_reg = 0x17030,
.halt_check = BRANCH_HALT_VOTED,
@@ -3383,6 +3453,9 @@ static struct clk_regmap *gcc_sdm845_clocks[] = {
[GPLL4] = &gpll4.clkr,
[GCC_CPUSS_DVM_BUS_CLK] = &gcc_cpuss_dvm_bus_clk.clkr,
[GCC_CPUSS_GNOC_CLK] = &gcc_cpuss_gnoc_clk.clkr,
+   [GCC_QSPI_CORE_CLK_SRC] = &gcc_qspi_core_clk_src.clkr,
+   [GCC_QSPI_CORE_CLK] = &gcc_qspi_core_clk.clkr,
+   [GCC_QSPI_CNOC_PERIPH_AHB_CLK] = &gcc_qspi_cnoc_periph_ahb_clk.clkr,
  };
  
  static const struct qcom_reset_map gcc_sdm845_resets[] = {




--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


Re: [RFC PATCH 2/2] clk: qcom: Add qspi (Quad SPI) clocks for sdm845

2018-07-19 Thread Taniya Das




On 7/19/2018 11:25 PM, Doug Anderson wrote:

Hi,

On Thu, Jul 19, 2018 at 4:04 AM, Taniya Das  wrote:

Hi Doug,

Please find my comments inline.

On 7/18/2018 11:34 PM, Douglas Anderson wrote:


Add both the interface and core clock.

Signed-off-by: Douglas Anderson 
---

   drivers/clk/qcom/gcc-sdm845.c | 73 +++
   1 file changed, 73 insertions(+)

diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index 0f694ed4238a..2ee96f9bc217 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -162,6 +162,20 @@ static const char * const gcc_parent_names_10[] = {
 "core_bi_pll_test_se",
   };
   +static const struct parent_map gcc_parent_map_9[] = {
+   { P_BI_TCXO, 0 },
+   { P_GPLL0_OUT_MAIN, 1 },
+   { P_GPLL0_OUT_EVEN, 6 },
+   { P_SLEEP_CLK, 7 },



SRC 7 has 'core_bi_pll_test_se' and not 'sleep_clk'.

Please use the 'gcc_parent_map_0'


Are you sure?  I'm looking at a doc showing the bitfields of
GCC_QSPI_CORE_CFG_RCGR.  It says:

0x0: bi_tcxo.
0x1: gpll0_out_main.
0x6: gpll0_out_even.
0x7: sleep_clk.

This contrasts with other clocks using 'gcc_parent_map_0' (for
instance "gcc_qupv3_wrap0_s0_clk_src") where 0x7 is simply not listed
in my doc.

...so either my doc is wrong or yours is.  Any way to resolve that?



I am not sure of the document you are referring, but the connectivity 
details I have shared are from the design side and they are ones which 
we have to follow.





+};
+
+static const char * const gcc_parent_names_9[] = {
+   "bi_tcxo",
+   "gpll0",
+   "gpll0_out_even",
+   "core_pi_sleep_clk",
+};
+
   static struct clk_alpha_pll gpll0 = {
 .offset = 0x0,
 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
@@ -358,6 +372,31 @@ static struct clk_rcg2 gcc_pcie_phy_refgen_clk_src =
{
 },
   };
   +static const struct freq_tbl ftbl_gcc_qspi_core_clk_src[] = {
+   F(1920, P_BI_TCXO, 1, 0, 0),
+   F(5000, P_GPLL0_OUT_EVEN, 6, 0, 0),
+   F(7500, P_GPLL0_OUT_EVEN, 4, 0, 0),
+   F(1, P_GPLL0_OUT_EVEN, 3, 0, 0),



Is SW planning to use this frequency?


At the moment I actually am using it.  I haven't done signal analysis,
but in quick testing I couldn't properly read the SPI at faster than a
25 MHz SPI bus which translates to 100 MHz here.  Interestingly, it
seems like folks in your boot team came to the same conclusion since I
see them setting this bus to 100 MHz at
<https://review.coreboot.org/#/c/coreboot/+/25392/25/src/soc/qualcomm/sdm845/bootblock.c>
too.



+   F(15000, P_GPLL0_OUT_EVEN, 2, 0, 0),



F(15000, P_GPLL0_OUT_MAIN, 4, 0, 0),


Sure.  For my edification, is there a reason to use main vs. even?



The frequencies to be generated are also as per design data. These 
source usage depends on timing closure for certain max frequencies.





+   F(3, P_GPLL0_OUT_EVEN, 1, 0, 0),



F(3, P_GPLL0_OUT_MAIN, 2, 0, 0),


No problem.



+   F(4, P_GPLL0_OUT_MAIN, 1.5, 0, 0),


No problem.



Please remove this, the Max supported frequency is 300MHz.


+   { }
+};
+
+static struct clk_rcg2 gcc_qspi_core_clk_src = {
+   .cmd_rcgr = 0x4b008,
+   .mnd_width = 0,
+   .hid_width = 5,
+   .parent_map = gcc_parent_map_9,
+   .freq_tbl = ftbl_gcc_qspi_core_clk_src,
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "gcc_qspi_core_clk_src",
+   .parent_names = gcc_parent_names_9,
+   .num_parents = 4,
+   .ops = &clk_rcg2_floor_ops,



Could we use the rcg2_ops instead?


I'd rather not.  Any reason why you think that'd be a good idea?

Specifically imagine that we have a SPI flash chip that's rated to run
at a max of 20 MHz.  In the device tree we'd ideally want to specify:

   spi-max-frequency = <2000>;

It appears that we need to run the SPI core as 4 times the rate of the
SPI bus, so we'd try to set this clock to 80 MHz.  If we round up
we'll end up at 100 MHz or 150 MHz for the SPI core and have a SPI bus
rate of 25 MHz or 37.5 MHz.  That would violate the whole idea of
"spi-max-frequency".  It's much better to round down to 75 MHz.


In general I've always seen that for safety it's always better the
round clocks down and round voltage up, so I was actually confused by
the fact that most of the clocks in this file used rcg2_ops instead of
clk_rcg2_floor_ops...  I'd be curious if we should we change more of
them to clk_rcg2_floor_ops.  As a random example I'll take
"gcc_sdcc2_apps_clk_src".  If someone happened to have a full sized SD
slot and put an MMC card in then you'd be in trouble.  Why?

For MMC a valid rate to request is 5200.  When the SD card core
r

[RFC PATCH 1/4] clk: qcom: Add support to request power domain state

2018-07-21 Thread Taniya Das
There could be single power domain or multiple power domains associated
with a clock controller. Add powerdomain_class support which would help
vote/unvote for any power domain performance state for a clock frequency
to the genpd framework.
A clock frequency request from a consumer would look for the corresponding
performance corner and thus would aggregate and request the desired
performance state to genpd.

Signed-off-by: Taniya Das 
---
 drivers/clk/qcom/Makefile |   1 +
 drivers/clk/qcom/clk-pd.c | 193 ++
 drivers/clk/qcom/clk-pd.h |  55 +
 3 files changed, 249 insertions(+)
 create mode 100644 drivers/clk/qcom/clk-pd.c
 create mode 100644 drivers/clk/qcom/clk-pd.h

diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 599ab91..336d4da 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -12,6 +12,7 @@ clk-qcom-y += clk-regmap-divider.o
 clk-qcom-y += clk-regmap-mux.o
 clk-qcom-y += clk-regmap-mux-div.o
 clk-qcom-y += reset.o
+clk-qcom-y += clk-pd.o
 clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o
 
 # Keep alphabetically sorted by config
diff --git a/drivers/clk/qcom/clk-pd.c b/drivers/clk/qcom/clk-pd.c
new file mode 100644
index 000..d1f9df3
--- /dev/null
+++ b/drivers/clk/qcom/clk-pd.c
@@ -0,0 +1,193 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "clk-pd.h"
+#include "clk-regmap.h"
+
+struct clk_powerdomain {
+   struct list_head list;
+   struct clk_powerdomain_class *pd;
+};
+
+static LIST_HEAD(clk_pd_list);
+
+/* Find the corner required for a given clock rate */
+static int find_rate_to_corner(struct clk_regmap *rclk, unsigned long rate)
+{
+   int corner;
+
+   for (corner = 0; corner < rclk->pd->num_corners; corner++)
+   if (rate <= rclk->rate_max[corner])
+   break;
+
+   if (corner == rclk->pd->num_corners) {
+   pr_debug("Rate %lu for %s is > than highest Fmax\n", rate,
+rclk->hw.init->name);
+   return -EINVAL;
+   }
+
+   return corner;
+}
+
+static int pd_update_corner_state(struct clk_powerdomain_class *pd)
+{
+   int corner, ret, *state = pd->corner, i;
+   int cur_corner = pd->cur_corner, max_corner = pd->num_corners - 1;
+
+   /* Aggregate the corner */
+   for (corner = max_corner; corner > 0; corner--) {
+   if (pd->corner_votes[corner])
+   break;
+   }
+
+   if (corner == cur_corner)
+   return 0;
+
+   pr_debug("Set performance state to genpd(%s) for state %d, cur_corner 
%d, num_corner %d\n",
+pd->pd_name, state[corner], cur_corner, pd->num_corners);
+
+   for (i = 0; i < pd->num_pd; i++) {
+   ret = dev_pm_genpd_set_performance_state(pd->powerdomain_dev[i],
+state[corner]);
+   if (ret)
+   return ret;
+
+   if (cur_corner == 0 || cur_corner == pd->num_corners) {
+   pd->links[i] = device_link_add(pd->dev,
+   pd->powerdomain_dev[i],
+   DL_FLAG_STATELESS |
+   DL_FLAG_PM_RUNTIME |
+   DL_FLAG_RPM_ACTIVE);
+   if (!pd->links[i])
+   pr_err("Links for %d not created\n", i);
+   }
+
+   if (corner == 0)
+   device_link_del(pd->links[i]);
+   }
+
+   pd->cur_corner = corner;
+
+   return 0;
+}
+
+/* call from prepare & set rate */
+int clk_power_domain_vote_rate(struct clk_regmap *rclk,
+   unsigned long rate)
+{
+   int corner;
+
+   if (!rclk->pd)
+   return 0;
+
+   corner = find_rate_to_corner(rclk, rate);
+   if (corner < 0)
+   return corner;
+
+   mutex_lock(&rclk->pd->lock);
+
+   rclk->pd->corner_votes[corner]++;
+
+   /* update the corner to power domain */
+   if (pd_update_corner_state(rclk->pd) < 0)
+   rclk->pd->corner_votes[corner]--;
+
+   pr_debug("pd(%s) prepare corner_votes_count %d, corner %d\n",
+rclk->pd->pd_name, rclk->pd->corner_votes[corner],
+corner);
+
+   mutex_unlock(&rclk->pd->lock);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(clk_power_domain_vote_rate);
+
+/* call from unprepare & set rate */
+void clk_power_domain_unvote_rate(struct clk_regmap *rclk,
+  unsigned long r

[RFC PATCH 2/4] clk: qcom: Initialize the power domain class for each clock

2018-07-21 Thread Taniya Das
The power domain class is being initialized for clocks which has
an associated power domains before registering the clocks with
the clock framework.

Signed-off-by: Taniya Das 
---
 drivers/clk/qcom/clk-regmap.h |  5 +
 drivers/clk/qcom/common.c | 17 +++--
 2 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/clk/qcom/clk-regmap.h b/drivers/clk/qcom/clk-regmap.h
index 90d95cd..6265d91 100644
--- a/drivers/clk/qcom/clk-regmap.h
+++ b/drivers/clk/qcom/clk-regmap.h
@@ -17,22 +17,27 @@
 #include 
 
 struct regmap;
+struct clk_powerdomain_class;
 
 /**
  * struct clk_regmap - regmap supporting clock
  * @hw:handle between common and hardware-specific interfaces
  * @regmap:regmap to use for regmap helpers and/or by providers
+ * @pd:power domain scaling requirement class
  * @enable_reg: register when using regmap enable/disable ops
  * @enable_mask: mask when using regmap enable/disable ops
  * @enable_is_inverted: flag to indicate set enable_mask bits to disable
  *  when using clock_enable_regmap and friends APIs.
+ * @rate_max:  maximum clock rate in Hz supported at each power domain.
  */
 struct clk_regmap {
struct clk_hw hw;
struct regmap *regmap;
+   struct clk_powerdomain_class *pd;
unsigned int enable_reg;
unsigned int enable_mask;
bool enable_is_inverted;
+   unsigned long *rate_max;
 };
 #define to_clk_regmap(_hw) container_of(_hw, struct clk_regmap, hw)
 
diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c
index 39ce64c..b0684bf 100644
--- a/drivers/clk/qcom/common.c
+++ b/drivers/clk/qcom/common.c
@@ -1,14 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * Copyright (c) 2013-2014, 2018, The Linux Foundation. All rights reserved.
  */
 
 #include 
@@ -20,6 +12,7 @@
 #include 
 
 #include "common.h"
+#include "clk-pd.h"
 #include "clk-rcg.h"
 #include "clk-regmap.h"
 #include "reset.h"
@@ -263,6 +256,10 @@ int qcom_cc_really_probe(struct platform_device *pdev,
if (!rclks[i])
continue;
 
+   ret = clk_power_domain_class_init(dev, rclks[i]->pd);
+   if (ret)
+   return ret;
+
ret = devm_clk_register_regmap(dev, rclks[i]);
if (ret)
return ret;
-- 
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



[RFC PATCH 0/4] clk: qcom: Add support to vote to genpd

2018-07-21 Thread Taniya Das
A clock controller could be connected to single or multiple power domains. Add
support for powerdomain_class which would help associate these power domains to
the RCGs and PLLs in the clock controller. Map the domain and the corresponding
frequencies to the clock(RCG/PLL). The clock frequency request from a consumer
would be mapped to the corresponding performance corner, aggregated at the
clock driver and would be vote/unvoted to the genpd framework for the desired
performance state.

This series add an example of power domain class for sdm845 RCG/PLLs and the
corresponding frequency mappings. This depends on power domain drivers of
SDM845 https://lkml.org/lkml/2018/6/27/7.

Taniya Das (4):
  clk: qcom: Add support to request power domain state
  clk: qcom: Initialize the power domain class for each clock
  clk: qcom: Add prepare/unprepare clock ops for PLL/RCG
  clk: qcom: sdm845: Add Power Domain to RCGs and PLL

 arch/arm64/boot/dts/qcom/sdm845.dtsi |   2 +
 drivers/clk/qcom/Makefile|   1 +
 drivers/clk/qcom/clk-alpha-pll.c |  52 --
 drivers/clk/qcom/clk-pd.c| 193 +++
 drivers/clk/qcom/clk-pd.h|  55 ++
 drivers/clk/qcom/clk-rcg2.c  |  61 +--
 drivers/clk/qcom/clk-regmap.h|   5 +
 drivers/clk/qcom/common.c|  17 ++-
 drivers/clk/qcom/gcc-sdm845.c|  83 ---
 9 files changed, 427 insertions(+), 42 deletions(-)
 create mode 100644 drivers/clk/qcom/clk-pd.c
 create mode 100644 drivers/clk/qcom/clk-pd.h

--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



[RFC PATCH 3/4] clk: qcom: Add prepare/unprepare clock ops for PLL/RCG

2018-07-21 Thread Taniya Das
To put across power domain votes associated with a PLL or RCG, add the
prepare/unprepare clock ops which would map the corresponding performance
state corners for a clock frequency when the clk_prepare/clk_unprepare is
being invoked.
Also update the set_rate clock ops to send across the performance state to
genpd framework when a new frequency is being requested.

Signed-off-by: Taniya Das 
---
 drivers/clk/qcom/clk-alpha-pll.c | 52 +++---
 drivers/clk/qcom/clk-rcg2.c  | 61 +++-
 2 files changed, 96 insertions(+), 17 deletions(-)

diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 3c49a60..c03b6e4 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -1,14 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2015, 2018, The Linux Foundation. All rights reserved.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #include 
@@ -18,6 +10,7 @@
 #include 
 
 #include "clk-alpha-pll.h"
+#include "clk-pd.h"
 #include "common.h"
 
 #define PLL_MODE(p)((p)->offset + 0x0)
@@ -522,7 +515,9 @@ static int __clk_alpha_pll_set_rate(struct clk_hw *hw, 
unsigned long rate,
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
const struct pll_vco *vco;
u32 l, alpha_width = pll_alpha_width(pll);
+   unsigned long old_rate = clk_hw_get_rate(hw);
u64 a;
+   int ret;
 
rate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);
vco = alpha_pll_find_vco(pll, rate);
@@ -531,6 +526,15 @@ static int __clk_alpha_pll_set_rate(struct clk_hw *hw, 
unsigned long rate,
return -EINVAL;
}
 
+   if (clk_hw_is_prepared(hw)) {
+   /* Enforce power domain requirement for new frequency */
+   ret = clk_power_domain_vote_rate(&pll->clkr, rate);
+   if (ret) {
+   pr_err("Failed to vote/set new rate %lu\n", rate);
+   return ret;
+   }
+   }
+
regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);
 
if (alpha_width > ALPHA_BITWIDTH)
@@ -550,7 +554,15 @@ static int __clk_alpha_pll_set_rate(struct clk_hw *hw, 
unsigned long rate,
regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll),
   PLL_ALPHA_EN, PLL_ALPHA_EN);
 
-   return clk_alpha_pll_update_latch(pll, is_enabled);
+   ret = clk_alpha_pll_update_latch(pll, is_enabled);
+   if (ret)
+   old_rate = rate;
+
+   if (clk_hw_is_prepared(hw))
+   /* Release the power domain requirement for old frequency */
+   clk_power_domain_unvote_rate(&pll->clkr, old_rate);
+
+   return ret;
 }
 
 static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -1017,7 +1029,25 @@ static int alpha_pll_fabia_set_rate(struct clk_hw *hw, 
unsigned long rate,
return __clk_alpha_pll_update_latch(pll);
 }
 
+static int clk_alpha_pll_prepare(struct clk_hw *hw)
+{
+   struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+   unsigned long rate = clk_hw_get_rate(hw);
+
+   return clk_power_domain_vote_rate(&pll->clkr, rate);
+}
+
+static void clk_alpha_pll_unprepare(struct clk_hw *hw)
+{
+   struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+   unsigned long rate = clk_hw_get_rate(hw);
+
+   clk_power_domain_unvote_rate(&pll->clkr, rate);
+}
+
 const struct clk_ops clk_alpha_pll_fabia_ops = {
+   .prepare = clk_alpha_pll_prepare,
+   .unprepare = clk_alpha_pll_unprepare,
.enable = alpha_pll_fabia_enable,
.disable = alpha_pll_fabia_disable,
.is_enabled = clk_alpha_pll_is_enabled,
@@ -1028,6 +1058,8 @@ static int alpha_pll_fabia_set_rate(struct clk_hw *hw, 
unsigned long rate,
 EXPORT_SYMBOL_GPL(clk_alpha_pll_fabia_ops);
 
 const struct clk_ops clk_alpha_pll_fixed_fabia_ops = {
+   .prepare = clk_alpha_pll_prepare,
+   .unprepare = clk_alpha_pll_unprepare,
.enable = alpha_pll_fabia_enable,
.disable = alpha_pll_fabia_disable,
.is_enabled = clk_alpha_pll_is_enabled,
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index 52208d4..dc17dbf 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -15,6 +15,7 @@
 
 #include 
 
+#include "clk-pd.h"
 #include "clk-rcg.h"
 #include "common.h"
 
@@ -247,26 +248,46 @@ static 

[RFC PATCH 4/4] clk: qcom: sdm845: Add Power Domain to RCGs and PLL

2018-07-21 Thread Taniya Das
Test code for GCC Power Domain Voting for root clocks/plls.

Signed-off-by: Taniya Das 
---
 arch/arm64/boot/dts/qcom/sdm845.dtsi |  2 +
 drivers/clk/qcom/gcc-sdm845.c| 83 +---
 drivers/clk/qcom/vdd-level.h | 31 ++
 3 files changed, 101 insertions(+), 15 deletions(-)
 create mode 100644 drivers/clk/qcom/vdd-level.h

diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi 
b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 00722b5..742f72a 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -247,6 +247,8 @@
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
+   power-domains = <&rpmhpd SDM845_CX>,
+   <&rpmhpd SDM845_CX_AO>;
};

qupv3_id_0: geniqup@8c {
diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index 0f694ed..60225c1 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -24,6 +24,11 @@
 #include "clk-alpha-pll.h"
 #include "gdsc.h"
 #include "reset.h"
+#include "clk-pd.h"
+#include "vdd-level.h"
+
+#include 
+#include 

 #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }

@@ -162,12 +167,22 @@ enum {
"core_bi_pll_test_se",
 };

+static CLK_POWERDOMAIN_INIT(vdd_cx, VDD_NUM, 1, vdd_corner);
+static CLK_POWERDOMAIN_INIT(vdd_cx_ao, VDD_NUM, 1, vdd_corner);
+
 static struct clk_alpha_pll gpll0 = {
.offset = 0x0,
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
.clkr = {
.enable_reg = 0x52000,
.enable_mask = BIT(0),
+   .pd = &vdd_cx,
+   .rate_max = (unsigned long[VDD_NUM]) {
+   [VDD_MIN] = 61500,
+   [VDD_LOW] = 106600,
+   [VDD_LOW_L1] = 16,
+   [VDD_NOMINAL] = 20,
+   },
.hw.init = &(struct clk_init_data){
.name = "gpll0",
.parent_names = (const char *[]){ "bi_tcxo" },
@@ -183,6 +198,13 @@ enum {
.clkr = {
.enable_reg = 0x52000,
.enable_mask = BIT(4),
+   .pd = &vdd_cx,
+   .rate_max = (unsigned long[VDD_NUM]) {
+   [VDD_MIN] = 61500,
+   [VDD_LOW] = 106600,
+   [VDD_LOW_L1] = 16,
+   [VDD_NOMINAL] = 20,
+   },
.hw.init = &(struct clk_init_data){
.name = "gpll4",
.parent_names = (const char *[]){ "bi_tcxo" },
@@ -226,11 +248,20 @@ enum {
.hid_width = 5,
.parent_map = gcc_parent_map_0,
.freq_tbl = ftbl_gcc_cpuss_ahb_clk_src,
-   .clkr.hw.init = &(struct clk_init_data){
-   .name = "gcc_cpuss_ahb_clk_src",
-   .parent_names = gcc_parent_names_7,
-   .num_parents = 4,
-   .ops = &clk_rcg2_ops,
+   .clkr = {
+   /*  .pd = &vdd_cx_ao,  Remove this for testing */
+   .pd = &vdd_cx,
+   .rate_max = (unsigned long[VDD_NUM]) {
+   [VDD_MIN] = 1920,
+   [VDD_LOW] = 5000,
+   [VDD_NOMINAL] = 1,
+   },
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_cpuss_ahb_clk_src",
+   .parent_names = gcc_parent_names_7,
+   .num_parents = 4,
+   .ops = &clk_rcg2_ops,
+   },
},
 };

@@ -268,11 +299,20 @@ enum {
.hid_width = 5,
.parent_map = gcc_parent_map_1,
.freq_tbl = ftbl_gcc_gp1_clk_src,
-   .clkr.hw.init = &(struct clk_init_data){
-   .name = "gcc_gp1_clk_src",
-   .parent_names = gcc_parent_names_1,
-   .num_parents = 5,
-   .ops = &clk_rcg2_ops,
+   .clkr = {
+   .pd = &vdd_cx_ao,
+   .rate_max = (unsigned long[VDD_NUM]) {
+   [VDD_MIN] = 1920,
+   [VDD_LOWER] = 5000,
+   [VDD_LOW] = 1,
+   [VDD_NOMINAL] = 2,
+   },
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_gp1_clk_src",
+   .parent_names = gcc_parent_names_1,
+   .num_parents = 5,
+   .ops = &clk_rcg2_ops,
+   },
},
 };

@@ -282,11 +322,20

[PATCH v4] Add display clock controller driver for SDM845

2018-07-22 Thread Taniya Das
 [v4]
  * Add comments for the RCGs/CBCRs using the CLK_GET_RATE_NOCACHE flag.

 [v3]
  * Move frequency table macro to common file,
add the patch along to maintain dependency.

 [v2]
  * Removed unused header file includes.
  * Moved the frequency table macro to a common file [1].
  * Move to pll config to probe.
  * Update SoC name in device tree binding and
also update the Kconfig.

Add support for the display clock controller found on SDM845
based devices. This would allow display drivers to probe and
control their clocks.

Taniya Das (1):
  clk: qcom: Add display clock controller driver for SDM845

 drivers/clk/qcom/Kconfig |  10 +
 drivers/clk/qcom/Makefile|   1 +
 drivers/clk/qcom/dispcc-sdm845.c | 686 +++
 3 files changed, 697 insertions(+)
 create mode 100644 drivers/clk/qcom/dispcc-sdm845.c

--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



[PATCH v4] clk: qcom: Add display clock controller driver for SDM845

2018-07-22 Thread Taniya Das
Add support for the display clock controller found on SDM845
based devices. This would allow display drivers to probe and
control their clocks.

Signed-off-by: Taniya Das 
---
 drivers/clk/qcom/Kconfig |  10 +
 drivers/clk/qcom/Makefile|   1 +
 drivers/clk/qcom/dispcc-sdm845.c | 686 +++
 3 files changed, 697 insertions(+)
 create mode 100644 drivers/clk/qcom/dispcc-sdm845.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 2b69cf2..0647686 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -254,6 +254,16 @@ config SDM_VIDEOCC_845
  Say Y if you want to support video devices and functionality such as
  video encode and decode.

+config SDM_DISPCC_845
+   tristate "SDM845 Display Clock Controller"
+   select SDM_GCC_845
+   depends on COMMON_CLK_QCOM
+   help
+ Support for the display clock controller on Qualcomm Technologies, Inc
+ SDM845 devices.
+ Say Y if you want to support display devices and functionality such as
+ splash screen.
+
 config SPMI_PMIC_CLKDIV
tristate "SPMI PMIC clkdiv Support"
depends on (COMMON_CLK_QCOM && SPMI) || COMPILE_TEST
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 599ab91..21a4503 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o
 obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o
 obj-$(CONFIG_QCOM_CLK_RPMH) += clk-rpmh.o
 obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
+obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o
 obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o
 obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o
 obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o
diff --git a/drivers/clk/qcom/dispcc-sdm845.c b/drivers/clk/qcom/dispcc-sdm845.c
new file mode 100644
index 000..266b011
--- /dev/null
+++ b/drivers/clk/qcom/dispcc-sdm845.c
@@ -0,0 +1,686 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap-divider.h"
+#include "common.h"
+#include "gdsc.h"
+#include "reset.h"
+
+enum {
+   P_BI_TCXO,
+   P_CORE_BI_PLL_TEST_SE,
+   P_DISP_CC_PLL0_OUT_MAIN,
+   P_DSI0_PHY_PLL_OUT_BYTECLK,
+   P_DSI0_PHY_PLL_OUT_DSICLK,
+   P_DSI1_PHY_PLL_OUT_BYTECLK,
+   P_DSI1_PHY_PLL_OUT_DSICLK,
+   P_GPLL0_OUT_MAIN,
+   P_GPLL0_OUT_MAIN_DIV,
+};
+
+static const struct parent_map disp_cc_parent_map_0[] = {
+   { P_BI_TCXO, 0 },
+   { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
+   { P_DSI1_PHY_PLL_OUT_BYTECLK, 2 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const disp_cc_parent_names_0[] = {
+   "bi_tcxo",
+   "dsi0_phy_pll_out_byteclk",
+   "dsi1_phy_pll_out_byteclk",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map disp_cc_parent_map_2[] = {
+   { P_BI_TCXO, 0 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const disp_cc_parent_names_2[] = {
+   "bi_tcxo",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map disp_cc_parent_map_3[] = {
+   { P_BI_TCXO, 0 },
+   { P_DISP_CC_PLL0_OUT_MAIN, 1 },
+   { P_GPLL0_OUT_MAIN, 4 },
+   { P_GPLL0_OUT_MAIN_DIV, 5 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const disp_cc_parent_names_3[] = {
+   "bi_tcxo",
+   "disp_cc_pll0",
+   "gcc_disp_gpll0_clk_src",
+   "gcc_disp_gpll0_div_clk_src",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map disp_cc_parent_map_4[] = {
+   { P_BI_TCXO, 0 },
+   { P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
+   { P_DSI1_PHY_PLL_OUT_DSICLK, 2 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const disp_cc_parent_names_4[] = {
+   "bi_tcxo",
+   "dsi0_phy_pll_out_dsiclk",
+   "dsi1_phy_pll_out_dsiclk",
+   "core_bi_pll_test_se",
+};
+
+static struct clk_alpha_pll disp_cc_pll0 = {
+   .offset = 0x0,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "disp_cc_pll0",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = &clk_alpha_pll_fabia_ops,
+   },
+   },
+};
+
+/* Return the HW recalc rate for idle use case */
+static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
+

[PATCH v5] Add display clock controller driver for SDM845

2018-07-23 Thread Taniya Das
 [v5]
  * Initialize pll config before assigining l/alpha values for
pll configure.
  * Add module description.

 [v4]
  * Add comments for the RCGs/CBCRs using the CLK_GET_RATE_NOCACHE flag.

 [v3]
  * Move frequency table macro to common file,
add the patch along to maintain dependency.

 [v2]
  * Removed unused header file includes.
  * Moved the frequency table macro to a common file [1].
  * Move to pll config to probe.
  * Update SoC name in device tree binding and
also update the Kconfig.

Add support for the display clock controller found on SDM845
based devices. This would allow display drivers to probe and
control their clocks.

Taniya Das (1):
  clk: qcom: Add display clock controller driver for SDM845

 drivers/clk/qcom/Kconfig |  10 +
 drivers/clk/qcom/Makefile|   1 +
 drivers/clk/qcom/dispcc-sdm845.c | 687 +++
 3 files changed, 698 insertions(+)
 create mode 100644 drivers/clk/qcom/dispcc-sdm845.c

--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



[PATCH v5] clk: qcom: Add display clock controller driver for SDM845

2018-07-23 Thread Taniya Das
Add support for the display clock controller found on SDM845
based devices. This would allow display drivers to probe and
control their clocks.

Signed-off-by: Taniya Das 
---
 drivers/clk/qcom/Kconfig |  10 +
 drivers/clk/qcom/Makefile|   1 +
 drivers/clk/qcom/dispcc-sdm845.c | 687 +++
 3 files changed, 698 insertions(+)
 create mode 100644 drivers/clk/qcom/dispcc-sdm845.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 2b69cf2..0647686 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -254,6 +254,16 @@ config SDM_VIDEOCC_845
  Say Y if you want to support video devices and functionality such as
  video encode and decode.

+config SDM_DISPCC_845
+   tristate "SDM845 Display Clock Controller"
+   select SDM_GCC_845
+   depends on COMMON_CLK_QCOM
+   help
+ Support for the display clock controller on Qualcomm Technologies, Inc
+ SDM845 devices.
+ Say Y if you want to support display devices and functionality such as
+ splash screen.
+
 config SPMI_PMIC_CLKDIV
tristate "SPMI PMIC clkdiv Support"
depends on (COMMON_CLK_QCOM && SPMI) || COMPILE_TEST
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 599ab91..21a4503 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o
 obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o
 obj-$(CONFIG_QCOM_CLK_RPMH) += clk-rpmh.o
 obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
+obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o
 obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o
 obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o
 obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o
diff --git a/drivers/clk/qcom/dispcc-sdm845.c b/drivers/clk/qcom/dispcc-sdm845.c
new file mode 100644
index 000..31850b6
--- /dev/null
+++ b/drivers/clk/qcom/dispcc-sdm845.c
@@ -0,0 +1,687 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap-divider.h"
+#include "common.h"
+#include "gdsc.h"
+#include "reset.h"
+
+enum {
+   P_BI_TCXO,
+   P_CORE_BI_PLL_TEST_SE,
+   P_DISP_CC_PLL0_OUT_MAIN,
+   P_DSI0_PHY_PLL_OUT_BYTECLK,
+   P_DSI0_PHY_PLL_OUT_DSICLK,
+   P_DSI1_PHY_PLL_OUT_BYTECLK,
+   P_DSI1_PHY_PLL_OUT_DSICLK,
+   P_GPLL0_OUT_MAIN,
+   P_GPLL0_OUT_MAIN_DIV,
+};
+
+static const struct parent_map disp_cc_parent_map_0[] = {
+   { P_BI_TCXO, 0 },
+   { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
+   { P_DSI1_PHY_PLL_OUT_BYTECLK, 2 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const disp_cc_parent_names_0[] = {
+   "bi_tcxo",
+   "dsi0_phy_pll_out_byteclk",
+   "dsi1_phy_pll_out_byteclk",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map disp_cc_parent_map_2[] = {
+   { P_BI_TCXO, 0 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const disp_cc_parent_names_2[] = {
+   "bi_tcxo",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map disp_cc_parent_map_3[] = {
+   { P_BI_TCXO, 0 },
+   { P_DISP_CC_PLL0_OUT_MAIN, 1 },
+   { P_GPLL0_OUT_MAIN, 4 },
+   { P_GPLL0_OUT_MAIN_DIV, 5 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const disp_cc_parent_names_3[] = {
+   "bi_tcxo",
+   "disp_cc_pll0",
+   "gcc_disp_gpll0_clk_src",
+   "gcc_disp_gpll0_div_clk_src",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map disp_cc_parent_map_4[] = {
+   { P_BI_TCXO, 0 },
+   { P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
+   { P_DSI1_PHY_PLL_OUT_DSICLK, 2 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const disp_cc_parent_names_4[] = {
+   "bi_tcxo",
+   "dsi0_phy_pll_out_dsiclk",
+   "dsi1_phy_pll_out_dsiclk",
+   "core_bi_pll_test_se",
+};
+
+static struct clk_alpha_pll disp_cc_pll0 = {
+   .offset = 0x0,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "disp_cc_pll0",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = &clk_alpha_pll_fabia_ops,
+   },
+   },
+};
+
+/* Return the HW recalc rate for idle use case */
+static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
+

Re: [PATCH v2 2/2] clk: qcom: Add qspi (Quad SPI) clocks for sdm845

2018-07-23 Thread Taniya Das




On 7/24/2018 3:24 AM, Douglas Anderson wrote:

Add both the interface and core clock.

Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only 19.2, 100, 150, and 300 MHz now.
- All clocks come from MAIN rather than EVEN.
- Use parent map 0 instead of new parent map 9.

  drivers/clk/qcom/gcc-sdm845.c | 63 +++
  1 file changed, 63 insertions(+)

diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index 0f694ed4238a..5bca634e277a 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -162,6 +162,13 @@ static const char * const gcc_parent_names_10[] = {
"core_bi_pll_test_se",
  };
  
+static const char * const gcc_parent_names_9[] = {

+   "bi_tcxo",
+   "gpll0",
+   "gpll0_out_even",
+   "core_pi_sleep_clk",
+};
+


Please remove this.


  static struct clk_alpha_pll gpll0 = {
.offset = 0x0,
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
@@ -358,6 +365,28 @@ static struct clk_rcg2 gcc_pcie_phy_refgen_clk_src = {
},
  };
  
+static const struct freq_tbl ftbl_gcc_qspi_core_clk_src[] = {

+   F(1920, P_BI_TCXO, 1, 0, 0),
+   F(1, P_GPLL0_OUT_MAIN, 6, 0, 0),
+   F(15000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+   F(3, P_GPLL0_OUT_MAIN, 2, 0, 0),
+   { }
+};
+
+static struct clk_rcg2 gcc_qspi_core_clk_src = {
+   .cmd_rcgr = 0x4b008,
+   .mnd_width = 0,
+   .hid_width = 5,
+   .parent_map = gcc_parent_map_0,
+   .freq_tbl = ftbl_gcc_qspi_core_clk_src,
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "gcc_qspi_core_clk_src",
+   .parent_names = gcc_parent_names_9,

This would point to "gcc_parent_names_0".

+   .num_parents = 4,
+   .ops = &clk_rcg2_floor_ops,
+   },
+};
+
  static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = {
F(960, P_BI_TCXO, 2, 0, 0),
F(1920, P_BI_TCXO, 1, 0, 0),
@@ -1935,6 +1964,37 @@ static struct clk_branch gcc_qmip_video_ahb_clk = {
},
  };
  
+static struct clk_branch gcc_qspi_cnoc_periph_ahb_clk = {

+   .halt_reg = 0x4b000,
+   .halt_check = BRANCH_HALT,
+   .clkr = {
+   .enable_reg = 0x4b000,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_qspi_cnoc_periph_ahb_clk",
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
+static struct clk_branch gcc_qspi_core_clk = {
+   .halt_reg = 0x4b004,
+   .halt_check = BRANCH_HALT,
+   .clkr = {
+   .enable_reg = 0x4b004,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_qspi_core_clk",
+   .parent_names = (const char *[]){
+   "gcc_qspi_core_clk_src",
+   },
+   .num_parents = 1,
+   .flags = CLK_SET_RATE_PARENT,
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
  static struct clk_branch gcc_qupv3_wrap0_s0_clk = {
.halt_reg = 0x17030,
.halt_check = BRANCH_HALT_VOTED,
@@ -3383,6 +3443,9 @@ static struct clk_regmap *gcc_sdm845_clocks[] = {
[GPLL4] = &gpll4.clkr,
[GCC_CPUSS_DVM_BUS_CLK] = &gcc_cpuss_dvm_bus_clk.clkr,
[GCC_CPUSS_GNOC_CLK] = &gcc_cpuss_gnoc_clk.clkr,
+   [GCC_QSPI_CORE_CLK_SRC] = &gcc_qspi_core_clk_src.clkr,
+   [GCC_QSPI_CORE_CLK] = &gcc_qspi_core_clk.clkr,
+   [GCC_QSPI_CNOC_PERIPH_AHB_CLK] = &gcc_qspi_cnoc_periph_ahb_clk.clkr,
  };
  
  static const struct qcom_reset_map gcc_sdm845_resets[] = {




--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


[PATCH v7 0/2] cpufreq: qcom-hw: Add support for QCOM cpufreq HW driver

2018-07-24 Thread Taniya Das
 [v7]
   * Updated the logic to check for related CPUs.

 [v6]
   * Renamed match table 'qcom_cpufreq_hw_match'.
   * Renamed 'qcom_read_lut' to 'qcom_cpufreq_hw_read_lut'.
   * Updated the logic to check for related CPUs at the beginning of the
 'qcom_cpu_resources_init'.
   * Use devm_ioremap_resource instead of devm_ioremap.
   * Update the use of of_node_put to handle error conditions.
   * Use policy->cached_resolved_idx in fast switch callback.
   * Keep precalculated offsets 'reg_bases'.
   * XO clock is taken from Device tree.
   * Update documentation binding for clocks/clock-names.
   * Minor comments in Kconfig.arm.
   * Comments to move dev_info to dev_dbg.

 [v5]
   * Remove mapping different register regions of perf/lut/enable,
 instead map the entire HW region.
   * Add reg_offset/cpufreq_qcom_std_offsets to be supplied as device data.
   * Check of src == 0 during lut read.
   * Add of_node_put(cpu_np) in qcom_get_related_cpus
   * Update the qcom_cpu_resources_init for register offset data,
 and cleanup the related cpus to keep a single copy of CPUfreq.
   * Replace FW with HW, update Kconfig, rename filename qcom-cpufreq-hw.c
   * Update the documentation binding to reflect the changes of mapping the
   * entire HW region.

 [v4]
   * Fixed console messages as per comments.
   * Return error from qcom_resources_init()
 in the cases where failed to get frequency domain.
   * Rename cpu_dev to cpu_np in qcom_resources_init,
 qcom_get_related_cpus(). Also use temp variable freq_np in
 qcom_get_related_cpus().
   * Update qcom_cpufreq_fw_get() to use the policy data to incoporate
 the hotplug use case.
   * Update code to use of fast_switching.
   * Check for !c->max_cores instead of cpumask_empty in
 qcom_get_related_cpus().
   * Update the logic of assigning 'c' to qcom_freq_domain_map[cpu].

 [v3]
   * Remove index check from 'qcom_cpufreq_fw_target_index'.
   * Update the Documentation binding to add the platform specific properties in
 the CPU nodes, node name "qcom,freq-domain".
   * Update return value to '0' from -ENODEV from 'qcom_cpufreq_fw_get'.
   * Update the logic for boost frequency to use local variables instead of
 cpufreq driver data in 'qcom_read_lut'.
   * Update the logic in 'qcom_get_related_cpus' to find the related cpus.
   * Update the reg-names to remove "_base" and also update the binding with the
 description of these registers.
   * Update the logic in 'qcom_resources_init' to address the new device tree
 notation of handling the frequency domain phandles.

 [v2]
   * Fixed the alignment issues in "qcom_cpufreq_fw_target_index" for dev_err 
and
 also for "qcom_cpu_resources_init".
   * Removed ret = 0 from qcom_get_related_cpus and added to check for
 cpu_mask_empty to return -ENOENT.
   * Fixes qcom_cpu_resources_init function
   * Remove initialization of 'index'
   * Check for valid 'c'
   * Removed initialization of 'prev_cc' from 'qcom_read_lut'.

Taniya Das (2):
  dt-bindings: cpufreq: Introduce QCOM CPUFREQ Firmware bindings
  cpufreq: qcom-hw: Add support for QCOM cpufreq HW driver

 .../bindings/cpufreq/cpufreq-qcom-hw.txt   | 172 ++
 drivers/cpufreq/Kconfig.arm|  11 +
 drivers/cpufreq/Makefile   |   1 +
 drivers/cpufreq/qcom-cpufreq-hw.c  | 348 +
 4 files changed, 532 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt
 create mode 100644 drivers/cpufreq/qcom-cpufreq-hw.c

--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



Re: [PATCH v6 2/2] cpufreq: qcom-hw: Add support for QCOM cpufreq HW driver

2018-07-24 Thread Taniya Das

Hello Viresh,

Thanks for your review comments.

On 7/18/2018 11:16 AM, Viresh Kumar wrote:

On 18-07-18, 11:07, Taniya Das wrote:

+static int qcom_cpu_resources_init(struct platform_device *pdev,
+  struct device_node *np, unsigned int cpu,
+  unsigned long xo_rate)
+{
+   struct cpufreq_qcom *c;
+   struct resource res;
+   struct device *dev = &pdev->dev;
+   const u16 *offsets;
+   cpumask_t cpus_related;
+   int ret, i, cpu_r;
+   void __iomem *base;
+
+   cpumask_clear(&cpus_related);
+
+   ret = qcom_get_related_cpus(np, &cpus_related);
+   if (ret) {
+   dev_err(dev, "%s failed to get related CPUs\n", np->name);
+   return ret;
+   }
+
+   /* Related CPUs */
+   cpu_r = cpumask_first(&cpus_related);
+   if (cpu != cpu_r) {
+   qcom_freq_domain_map[cpu] = qcom_freq_domain_map[cpu_r];
+   return 0;
+   }
+
+   c = devm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
+   if (!c)
+   return -ENOMEM;
+
+   offsets = of_device_get_match_data(&pdev->dev);
+   if (!offsets)
+   return -EINVAL;
+
+   if (of_address_to_resource(np, 0, &res))
+   return -ENOMEM;
+
+   base = devm_ioremap_resource(dev, &res);
+   if (!base)
+   return -ENOMEM;
+
+   for (i = REG_ENABLE; i < REG_ARRAY_SIZE; i++)
+   c->reg_bases[i] = base + offsets[i];
+
+   /* HW should be in enabled state to proceed */
+   if (!(readl_relaxed(c->reg_bases[REG_ENABLE]) & 0x1)) {
+   dev_err(dev, "%s cpufreq hardware not enabled\n", np->name);
+   return -ENODEV;
+   }
+
+   cpumask_copy(&c->related_cpus, &cpus_related);
+
+   c->max_cores = cpumask_weight(&c->related_cpus);
+   if (!c->max_cores)
+   return -ENOENT;
+
+   c->xo_rate = xo_rate;
+
+   ret = qcom_cpufreq_hw_read_lut(pdev, c);
+   if (ret) {
+   dev_err(dev, "%s failed to read LUT\n", np->name);
+   return ret;
+   }
+
+   qcom_freq_domain_map[cpu] = c;


Set this for all related CPUs here and then the check at the top of
this routine will be simply:

if (qcom_freq_domain_map[cpu])
 return 0;



Please check the latest series, I have updated the code.


+
+   return 0;
+}
+


--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


[PATCH v7 1/2] dt-bindings: cpufreq: Introduce QCOM CPUFREQ Firmware bindings

2018-07-24 Thread Taniya Das
Add QCOM cpufreq firmware device bindings for Qualcomm Technology Inc's
SoCs. This is required for managing the cpu frequency transitions which are
controlled by the hardware engine.

Signed-off-by: Taniya Das 
---
 .../bindings/cpufreq/cpufreq-qcom-hw.txt   | 172 +
 1 file changed, 172 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt

diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt 
b/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt
new file mode 100644
index 000..22d4355
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt
@@ -0,0 +1,172 @@
+Qualcomm Technologies, Inc. CPUFREQ Bindings
+
+CPUFREQ HW is a hardware engine used by some Qualcomm Technologies, Inc. (QTI)
+SoCs to manage frequency in hardware. It is capable of controlling frequency
+for multiple clusters.
+
+Properties:
+- compatible
+   Usage:  required
+   Value type: 
+   Definition: must be "qcom,cpufreq-hw".
+
+- clocks
+   Usage:  required
+   Value type:  From common clock binding.
+   Definition: clock handle for XO clock.
+
+- clock-names
+   Usage:  required
+   Value type:  From common clock binding.
+   Definition: must be "xo".
+
+* Property qcom,freq-domain
+Devices supporting freq-domain must set their "qcom,freq-domain" property with
+phandle to a freq_domain_table in their DT node.
+
+* Frequency Domain Table Node
+
+This describes the frequency domain belonging to a device.
+This node can have following properties:
+
+- reg
+   Usage:  required
+   Value type: 
+   Definition: Addresses and sizes for the memory of the HW bases.
+
+Example:
+
+Example 1: Dual-cluster, Quad-core per cluster. CPUs within a cluster switch
+DCVS state together.
+
+/ {
+   cpus {
+   #address-cells = <2>;
+   #size-cells = <0>;
+
+   CPU0: cpu@0 {
+   device_type = "cpu";
+   compatible = "qcom,kryo385";
+   reg = <0x0 0x0>;
+   enable-method = "psci";
+   next-level-cache = <&L2_0>;
+   qcom,freq-domain = <&freq_domain_table0>;
+   L2_0: l2-cache {
+   compatible = "cache";
+   next-level-cache = <&L3_0>;
+   L3_0: l3-cache {
+ compatible = "cache";
+   };
+   };
+   };
+
+   CPU1: cpu@100 {
+   device_type = "cpu";
+   compatible = "qcom,kryo385";
+   reg = <0x0 0x100>;
+   enable-method = "psci";
+   next-level-cache = <&L2_100>;
+   qcom,freq-domain = <&freq_domain_table0>;
+   L2_100: l2-cache {
+   compatible = "cache";
+   next-level-cache = <&L3_0>;
+   };
+   };
+
+   CPU2: cpu@200 {
+   device_type = "cpu";
+   compatible = "qcom,kryo385";
+   reg = <0x0 0x200>;
+   enable-method = "psci";
+   next-level-cache = <&L2_200>;
+   qcom,freq-domain = <&freq_domain_table0>;
+   L2_200: l2-cache {
+   compatible = "cache";
+   next-level-cache = <&L3_0>;
+   };
+   };
+
+   CPU3: cpu@300 {
+   device_type = "cpu";
+   compatible = "qcom,kryo385";
+   reg = <0x0 0x300>;
+   enable-method = "psci";
+   next-level-cache = <&L2_300>;
+   qcom,freq-domain = <&freq_domain_table0>;
+   L2_300: l2-cache {
+   compatible = "cache";
+   next-level-cache = <&L3_0>;
+   };
+   };
+
+   CPU4: cpu@400 {
+   device_type = "cpu";
+   compatible = "qcom,kryo385";
+   reg = <0x0 0x400>;
+   enable-method = "psci";
+   next-level-cache = <

[PATCH v7 2/2] cpufreq: qcom-hw: Add support for QCOM cpufreq HW driver

2018-07-24 Thread Taniya Das
The CPUfreq HW present in some QCOM chipsets offloads the steps necessary
for changing the frequency of CPUs. The driver implements the cpufreq
driver interface for this hardware engine.

Signed-off-by: Saravana Kannan 
Signed-off-by: Taniya Das 
---
 drivers/cpufreq/Kconfig.arm   |  11 ++
 drivers/cpufreq/Makefile  |   1 +
 drivers/cpufreq/qcom-cpufreq-hw.c | 348 ++
 3 files changed, 360 insertions(+)
 create mode 100644 drivers/cpufreq/qcom-cpufreq-hw.c

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 0cd8eb7..93a9d72 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -298,3 +298,14 @@ config ARM_PXA2xx_CPUFREQ
  This add the CPUFreq driver support for Intel PXA2xx SOCs.

  If in doubt, say N.
+
+config ARM_QCOM_CPUFREQ_HW
+   bool "QCOM CPUFreq HW driver"
+   depends on ARCH_QCOM
+   help
+Support for the CPUFreq HW driver.
+Some QCOM 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.
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index c1ffeab..ca48a1d 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -85,6 +85,7 @@ obj-$(CONFIG_ARM_TEGRA124_CPUFREQ)+= tegra124-cpufreq.o
 obj-$(CONFIG_ARM_TEGRA186_CPUFREQ) += tegra186-cpufreq.o
 obj-$(CONFIG_ARM_TI_CPUFREQ)   += ti-cpufreq.o
 obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ) += vexpress-spc-cpufreq.o
+obj-$(CONFIG_ARM_QCOM_CPUFREQ_HW)  += qcom-cpufreq-hw.o


 
##
diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c 
b/drivers/cpufreq/qcom-cpufreq-hw.c
new file mode 100644
index 000..ea8f7d1
--- /dev/null
+++ b/drivers/cpufreq/qcom-cpufreq-hw.c
@@ -0,0 +1,348 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define INIT_RATE  3UL
+#define LUT_MAX_ENTRIES40U
+#define CORE_COUNT_VAL(val)(((val) & (GENMASK(18, 16))) >> 16)
+#define LUT_ROW_SIZE   32
+
+enum {
+   REG_ENABLE,
+   REG_LUT_TABLE,
+   REG_PERF_STATE,
+
+   REG_ARRAY_SIZE,
+};
+
+struct cpufreq_qcom {
+   struct cpufreq_frequency_table *table;
+   struct device *dev;
+   void __iomem *reg_bases[REG_ARRAY_SIZE];
+   cpumask_t related_cpus;
+   unsigned int max_cores;
+   unsigned long xo_rate;
+};
+
+static const u16 cpufreq_qcom_std_offsets[REG_ARRAY_SIZE] = {
+   [REG_ENABLE]= 0x0,
+   [REG_LUT_TABLE] = 0x110,
+   [REG_PERF_STATE]= 0x920,
+};
+
+static struct cpufreq_qcom *qcom_freq_domain_map[NR_CPUS];
+
+static int
+qcom_cpufreq_hw_target_index(struct cpufreq_policy *policy,
+unsigned int index)
+{
+   struct cpufreq_qcom *c = policy->driver_data;
+
+   writel_relaxed(index, c->reg_bases[REG_PERF_STATE]);
+
+   return 0;
+}
+
+static unsigned int qcom_cpufreq_hw_get(unsigned int cpu)
+{
+   struct cpufreq_qcom *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 unsigned int
+qcom_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
+   unsigned int target_freq)
+{
+   struct cpufreq_qcom *c = policy->driver_data;
+   int index;
+
+   index = policy->cached_resolved_idx;
+   if (index < 0)
+   return 0;
+
+   writel_relaxed(index, c->reg_bases[REG_PERF_STATE]);
+
+   return policy->freq_table[index].frequency;
+}
+
+static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
+{
+   struct cpufreq_qcom *c;
+
+   c = qcom_freq_domain_map[policy->cpu];
+   if (!c) {
+   pr_err("No scaling support for CPU%d\n", policy->cpu);
+   return -ENODEV;
+   }
+
+   cpumask_copy(policy->cpus, &c->related_cpus);
+
+   policy->fast_switch_possible = true;
+   policy->freq_table = c->table;
+   policy->driver_data = c;
+
+   return 0;
+}
+
+static struct freq_attr *qcom_cpufreq_hw_attr[] = {
+   &cpufreq_freq_attr_scaling_available_freqs,
+   &cpufreq_freq_attr_scaling_boost_f

Re: [PATCH v3 3/3] clk: qcom: Add display clock controller driver for SDM845

2018-07-12 Thread Taniya Das

++ Display driver team,

On 7/9/2018 8:36 PM, Stephen Boyd wrote:

Quoting Taniya Das (2018-07-09 02:34:07)



On 7/9/2018 1:07 PM, Stephen Boyd wrote:

Quoting Taniya Das (2018-07-09 00:07:21)



On 7/9/2018 11:46 AM, Stephen Boyd wrote:


> Why is the nocache flag needed? Applies to all clks in this file.
>

This flag is required for all RCGs whose PLLs are controlled outside the
clock controller. The display code would require the recalculated rate
always.


Right. Why is the PLL controlled outside of the clock controller? The
rate should propagate upward to the PLL from here, so who's going
outside of that?


The DSI0/1 PLL are not part of the display clock controller, but in the
display subsystem which are managed by the DRM drivers. When DRM drivers
query for the rate clock driver should always return the non cached rates.


Why? Is the DSI PLL changing rate all the time, randomly, without going
through the clk APIs to do so?



Hmm, I am afraid I do not have an answer for this, but this was the
requirement to always return the non cached rates from the clock driver.



Ok. Who knows about this requirement? Can we add someone from the
display driver to understand more?


As per my discussions offline with the display teams,

There is a use-case where the clock framework is unaware of the PLL VCO 
frequency change and thus the drivers would query to get the actual HW 
frequency rather than the cached one.


Do you think keeping these flags would have any impact other than always 
getting the non-cached rates?


--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


[PATCH v5 2/2] cpufreq: qcom-hw: Add support for QCOM cpufreq HW driver

2018-07-12 Thread Taniya Das
The CPUfreq HW present in some QCOM chipsets offloads the steps necessary
for changing the frequency of CPUs. The driver implements the cpufreq
driver interface for this hardware engine.

Signed-off-by: Saravana Kannan 
Signed-off-by: Taniya Das 
---
 drivers/cpufreq/Kconfig.arm   |  10 ++
 drivers/cpufreq/Makefile  |   1 +
 drivers/cpufreq/qcom-cpufreq-hw.c | 344 ++
 3 files changed, 355 insertions(+)
 create mode 100644 drivers/cpufreq/qcom-cpufreq-hw.c

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 52f5f1a..141ec3e 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -312,3 +312,13 @@ config ARM_PXA2xx_CPUFREQ
  This add the CPUFreq driver support for Intel PXA2xx SOCs.

  If in doubt, say N.
+
+config ARM_QCOM_CPUFREQ_HW
+   bool "QCOM CPUFreq HW driver"
+   help
+Support for the CPUFreq HW driver.
+Some QCOM 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 interafce to the High-level OS.
+The driver implements the cpufreq driver interface for this HW engine.
+Say Y if you want to support CPUFreq HW.
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index fb4a2ec..1226a3e 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -86,6 +86,7 @@ obj-$(CONFIG_ARM_TEGRA124_CPUFREQ)+= tegra124-cpufreq.o
 obj-$(CONFIG_ARM_TEGRA186_CPUFREQ) += tegra186-cpufreq.o
 obj-$(CONFIG_ARM_TI_CPUFREQ)   += ti-cpufreq.o
 obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ) += vexpress-spc-cpufreq.o
+obj-$(CONFIG_ARM_QCOM_CPUFREQ_HW)  += qcom-cpufreq-hw.o


 
##
diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c 
b/drivers/cpufreq/qcom-cpufreq-hw.c
new file mode 100644
index 000..fa25a95
--- /dev/null
+++ b/drivers/cpufreq/qcom-cpufreq-hw.c
@@ -0,0 +1,344 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define INIT_RATE  3UL
+#define XO_RATE1920UL
+#define LUT_MAX_ENTRIES40U
+#define CORE_COUNT_VAL(val)(((val) & (GENMASK(18, 16))) >> 16)
+#define LUT_ROW_SIZE   32
+
+enum {
+   REG_ENABLE,
+   REG_LUT_TABLE,
+   REG_PERF_STATE,
+
+   REG_ARRAY_SIZE,
+};
+
+struct cpufreq_qcom {
+   struct cpufreq_frequency_table *table;
+   struct device *dev;
+   const u16 *reg_offset;
+   void __iomem *base;
+   cpumask_t related_cpus;
+   unsigned int max_cores;
+};
+
+static u16 cpufreq_qcom_std_offsets[REG_ARRAY_SIZE] = {
+   [REG_ENABLE]= 0x0,
+   [REG_LUT_TABLE] = 0x110,
+   [REG_PERF_STATE]= 0x920,
+};
+
+static struct cpufreq_qcom *qcom_freq_domain_map[NR_CPUS];
+
+static int
+qcom_cpufreq_hw_target_index(struct cpufreq_policy *policy,
+unsigned int index)
+{
+   struct cpufreq_qcom *c = policy->driver_data;
+   unsigned int offset = c->reg_offset[REG_PERF_STATE];
+
+   writel_relaxed(index, c->base + offset);
+
+   return 0;
+}
+
+static unsigned int qcom_cpufreq_hw_get(unsigned int cpu)
+{
+   struct cpufreq_qcom *c;
+   struct cpufreq_policy *policy;
+   unsigned int index, offset;
+
+   policy = cpufreq_cpu_get_raw(cpu);
+   if (!policy)
+   return 0;
+
+   c = policy->driver_data;
+   offset = c->reg_offset[REG_PERF_STATE];
+
+   index = readl_relaxed(c->base + offset);
+   index = min(index, LUT_MAX_ENTRIES - 1);
+
+   return policy->freq_table[index].frequency;
+}
+
+static unsigned int
+qcom_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
+   unsigned int target_freq)
+{
+   struct cpufreq_qcom *c = policy->driver_data;
+   unsigned int offset;
+   int index;
+
+   index = cpufreq_table_find_index_l(policy, target_freq);
+   if (index < 0)
+   return 0;
+
+   offset = c->reg_offset[REG_PERF_STATE];
+
+   writel_relaxed(index, c->base + offset);
+
+   return policy->freq_table[index].frequency;
+}
+
+static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
+{
+   struct cpufreq_qcom *c;
+
+   c = qcom_freq_domain_map[policy->cpu];
+   if (!c) {
+   pr_err("No scaling support for CPU%d\n", policy->cpu);
+   return -ENODEV;
+   }
+
+   cpumask_copy(policy->cpus, &c->related_cpus);
+
+   policy->fast_switch_possible = true;
+   policy->freq_table = c->table;
+   polic

[PATCH v5 0/2] cpufreq: qcom-hw: Add support for QCOM cpufreq HW driver

2018-07-12 Thread Taniya Das
[v5]
  * Remove mapping different register regions of perf/lut/enable,
instead map the entire HW region.
  * Add reg_offset/cpufreq_qcom_std_offsets to be supplied as device data.
  * Check of src == 0 during lut read.
  * Add of_node_put(cpu_np) in qcom_get_related_cpus
  * Update the qcom_cpu_resources_init for register offset data,
and cleanup the related cpus to keep a single copy of CPUfreq.
  * Replace FW with HW, update Kconfig, rename filename qcom-cpufreq-hw.c
  * Update the documentation binding to reflect the changes of mapping the
  * entire HW region.

[v4]
  * Fixed console messages as per comments.
  * Return error from qcom_resources_init()
in the cases where failed to get frequency domain.
  * Rename cpu_dev to cpu_np in qcom_resources_init,
qcom_get_related_cpus(). Also use temp variable freq_np in
qcom_get_related_cpus().
  * Update qcom_cpufreq_fw_get() to use the policy data to incoporate
the hotplug use case.
  * Update code to use of fast_switching.
  * Check for !c->max_cores instead of cpumask_empty in
qcom_get_related_cpus().
  * Update the logic of assigning 'c' to qcom_freq_domain_map[cpu].

 [v3]
  * Remove index check from 'qcom_cpufreq_fw_target_index'.
  * Update the Documentation binding to add the platform specific properties in
the CPU nodes, node name "qcom,freq-domain".
  * Update return value to '0' from -ENODEV from 'qcom_cpufreq_fw_get'.
  * Update the logic for boost frequency to use local variables instead of
cpufreq driver data in 'qcom_read_lut'.
  * Update the logic in 'qcom_get_related_cpus' to find the related cpus.
  * Update the reg-names to remove "_base" and also update the binding with the
description of these registers.
  * Update the logic in 'qcom_resources_init' to address the new device tree
notation of handling the frequency domain phandles.

 [v2]
 * Fixed the alignment issues in "qcom_cpufreq_fw_target_index" for dev_err and
   also for "qcom_cpu_resources_init".
 * Removed ret = 0 from qcom_get_related_cpus and added to check for
   cpu_mask_empty to return -ENOENT.
 * Fixes qcom_cpu_resources_init function
   * Remove initialization of 'index'
   * Check for valid 'c'
 * Removed initialization of 'prev_cc' from 'qcom_read_lut'.
 * Remove initialization of 'ret' from function qcom_resources_init and add
   return -ENODEV based on 'of_get_available_child_count'.
 * Removed initialization of 'rc' from qcom_cpufreq_fw_driver_probe
 * Removed module_exit as this driver would not be used as module, also updated
   the Kconfig to bool from tristate.
 * Updated the subsystem in device tree bindings.

 [v1]
   * Fixed compilation reported by Amit K.

Taniya Das (2):
  dt-bindings: cpufreq: Introduce QCOM CPUFREQ Firmware bindings
  cpufreq: qcom-hw: Add support for QCOM cpufreq HW driver

 .../bindings/cpufreq/cpufreq-qcom-hw.txt   | 158 ++
 drivers/cpufreq/Kconfig.arm|  10 +
 drivers/cpufreq/Makefile   |   1 +
 drivers/cpufreq/qcom-cpufreq-hw.c  | 344 +
 4 files changed, 513 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt
 create mode 100644 drivers/cpufreq/qcom-cpufreq-hw.c

--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



Re: [PATCH v4 2/2] cpufreq: qcom-fw: Add support for QCOM cpufreq FW driver

2018-07-12 Thread Taniya Das

Please help review of the new series[v5] which takes care of the below.

- Remove mapping different register regions of perf/lut/enable,
  instead map the entire HW region.
- Add reg_offset/cpufreq_qcom_std_offsets to be supplied as device data.
- Check of src == 0 during lut read.
- Add of_node_put(cpu_np) in qcom_get_related_cpus
- Update the qcom_cpu_resources_init for register offset data,
  and cleanup the related cpus to keep a single copy of CPUfreq.
- Replace FW with HW, update Kconfig, rename filename qcom-cpufreq-hw.c

On 7/12/2018 2:07 AM, Matthias Kaehlcke wrote:

Hi,

On Tue, Jun 12, 2018 at 04:32:35PM +0530, Taniya Das wrote:

The CPUfreq FW present in some QCOM chipsets offloads the steps necessary
for changing the frequency of CPUs. The driver implements the cpufreq
driver interface for this firmware.

Signed-off-by: Saravana Kannan 
Signed-off-by: Taniya Das 
---
  drivers/cpufreq/Kconfig.arm   |   9 +
  drivers/cpufreq/Makefile  |   1 +
  drivers/cpufreq/qcom-cpufreq-fw.c | 336 ++
  3 files changed, 346 insertions(+)
  create mode 100644 drivers/cpufreq/qcom-cpufreq-fw.c

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 52f5f1a..2683716 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -312,3 +312,12 @@ config ARM_PXA2xx_CPUFREQ
  This add the CPUFreq driver support for Intel PXA2xx SOCs.

  If in doubt, say N.
+
+config ARM_QCOM_CPUFREQ_FW
+   bool "QCOM CPUFreq FW driver"
+   help
+Support for the CPUFreq FW driver.
+The CPUfreq FW preset in some QCOM chipsets offloads the steps
+necessary for changing the frequency of CPUs. The driver
+implements the cpufreq driver interface for this firmware.
+Say Y if you want to support CPUFreq FW.
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index fb4a2ec..34691a2 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -86,6 +86,7 @@ obj-$(CONFIG_ARM_TEGRA124_CPUFREQ)+= tegra124-cpufreq.o
  obj-$(CONFIG_ARM_TEGRA186_CPUFREQ)+= tegra186-cpufreq.o
  obj-$(CONFIG_ARM_TI_CPUFREQ)  += ti-cpufreq.o
  obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ)+= vexpress-spc-cpufreq.o
+obj-$(CONFIG_ARM_QCOM_CPUFREQ_FW)  += qcom-cpufreq-fw.o


  
##
diff --git a/drivers/cpufreq/qcom-cpufreq-fw.c 
b/drivers/cpufreq/qcom-cpufreq-fw.c
new file mode 100644
index 000..62f4452
--- /dev/null
+++ b/drivers/cpufreq/qcom-cpufreq-fw.c
@@ -0,0 +1,336 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define INIT_RATE  3UL
+#define XO_RATE1920UL
+#define LUT_MAX_ENTRIES40U
+#define CORE_COUNT_VAL(val)(((val) & (GENMASK(18, 16))) >> 16)
+#define LUT_ROW_SIZE   32
+
+struct cpufreq_qcom {
+   struct cpufreq_frequency_table *table;
+   struct device *dev;
+   void __iomem *perf_base;
+   void __iomem *lut_base;
+   cpumask_t related_cpus;
+   unsigned int max_cores;


Why *max*_cores? This seems to be the number of CPUs in a cluster and
qcom_read_lut() expects the core count read from the LUT to match
exactly.


+static int qcom_read_lut(struct platform_device *pdev,
+struct cpufreq_qcom *c)
+{
+   struct device *dev = &pdev->dev;
+   u32 data, src, lval, i, core_count, prev_cc, prev_freq, cur_freq;
+
+   c->table = devm_kcalloc(dev, LUT_MAX_ENTRIES + 1,
+   sizeof(*c->table), GFP_KERNEL);
+   if (!c->table)
+   return -ENOMEM;
+
+   for (i = 0; i < LUT_MAX_ENTRIES; i++) {
+   data = readl_relaxed(c->lut_base + i * LUT_ROW_SIZE);
+   src = ((data & GENMASK(31, 30)) >> 30);
+   lval = (data & GENMASK(7, 0));
+   core_count = CORE_COUNT_VAL(data);
+
+   if (!src)
+   c->table[i].frequency = INIT_RATE / 1000;
+   else
+   c->table[i].frequency = XO_RATE * lval / 1000;


nit: any particular reason to use negative logic here? Why not check
for 'src[ != NULL]', which also seems to be the more common case.


+static int qcom_get_related_cpus(struct device_node *np, struct cpumask *m)
+{
+   struct device_node *cpu_np, *freq_np;
+   int cpu;
+
+   for_each_possible_cpu(cpu) {
+   cpu_np = of_cpu_device_node_get(cpu);
+   if (!cpu_np)
+   continue;
+   freq_np = of_parse_phandle(cpu_np, "qcom,freq-domain", 0);
+   if (!freq_np)
+   continue;

[PATCH v5 1/2] dt-bindings: cpufreq: Introduce QCOM CPUFREQ Firmware bindings

2018-07-12 Thread Taniya Das
Add QCOM cpufreq firmware device bindings for Qualcomm Technology Inc's
SoCs. This is required for managing the cpu frequency transitions which are
controlled by the hardware engine.

Signed-off-by: Taniya Das 
---
 .../bindings/cpufreq/cpufreq-qcom-hw.txt   | 158 +
 1 file changed, 158 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt

diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt 
b/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt
new file mode 100644
index 000..52a53e1
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt
@@ -0,0 +1,158 @@
+Qualcomm Technologies, Inc. CPUFREQ Bindings
+
+CPUFREQ HW is a hardware engine used by some Qualcomm Technologies, Inc. (QTI)
+SoCs to manage frequency in hardware. It is capable of controlling frequency
+for multiple clusters.
+
+Properties:
+- compatible
+   Usage:  required
+   Value type: 
+   Definition: must be "qcom,cpufreq-hw".
+
+* Property qcom,freq-domain
+Devices supporting freq-domain must set their "qcom,freq-domain" property with
+phandle to a freq_domain_table in their DT node.
+
+* Frequency Domain Table Node
+
+This describes the frequency domain belonging to a device.
+This node can have following properties:
+
+- reg
+   Usage:  required
+   Value type: 
+   Definition: Addresses and sizes for the memory of the HW bases.
+
+Example:
+
+Example 1: Dual-cluster, Quad-core per cluster. CPUs within a cluster switch
+DCVS state together.
+
+/ {
+   cpus {
+   #address-cells = <2>;
+   #size-cells = <0>;
+
+   CPU0: cpu@0 {
+   device_type = "cpu";
+   compatible = "qcom,kryo385";
+   reg = <0x0 0x0>;
+   enable-method = "psci";
+   next-level-cache = <&L2_0>;
+   qcom,freq-domain = <&freq_domain_table0>;
+   L2_0: l2-cache {
+   compatible = "cache";
+   next-level-cache = <&L3_0>;
+   L3_0: l3-cache {
+ compatible = "cache";
+   };
+   };
+   };
+
+   CPU1: cpu@100 {
+   device_type = "cpu";
+   compatible = "qcom,kryo385";
+   reg = <0x0 0x100>;
+   enable-method = "psci";
+   next-level-cache = <&L2_100>;
+   qcom,freq-domain = <&freq_domain_table0>;
+   L2_100: l2-cache {
+   compatible = "cache";
+   next-level-cache = <&L3_0>;
+   };
+   };
+
+   CPU2: cpu@200 {
+   device_type = "cpu";
+   compatible = "qcom,kryo385";
+   reg = <0x0 0x200>;
+   enable-method = "psci";
+   next-level-cache = <&L2_200>;
+   qcom,freq-domain = <&freq_domain_table0>;
+   L2_200: l2-cache {
+   compatible = "cache";
+   next-level-cache = <&L3_0>;
+   };
+   };
+
+   CPU3: cpu@300 {
+   device_type = "cpu";
+   compatible = "qcom,kryo385";
+   reg = <0x0 0x300>;
+   enable-method = "psci";
+   next-level-cache = <&L2_300>;
+   qcom,freq-domain = <&freq_domain_table0>;
+   L2_300: l2-cache {
+   compatible = "cache";
+   next-level-cache = <&L3_0>;
+   };
+   };
+
+   CPU4: cpu@400 {
+   device_type = "cpu";
+   compatible = "qcom,kryo385";
+   reg = <0x0 0x400>;
+   enable-method = "psci";
+   next-level-cache = <&L2_400>;
+   qcom,freq-domain = <&freq_domain_table1>;
+   L2_400: l2-cache {
+   compatible = "cache";
+   next-level-cache = <&L3_0>;
+ 

Re: [PATCH v2 1/2] clk: qcom: Add support for RCG to register for DFS

2018-07-15 Thread Taniya Das

Hello Stephen,

Thanks for your review comments.

On 7/9/2018 12:34 PM, Stephen Boyd wrote:

Quoting Taniya Das (2018-06-28 04:47:30)

Dynamic Frequency switch is a feature of clock controller by which request
from peripherals allows automatic switching frequency of input clock.
There are various performance levels associated to a root clock generator.
Register the root clock generators(RCG) to switch to use the dfs clock ops
in the cases where DFS is enabled.
The DFS clock ops would at runtime read the clock perf level registers to
identify the frequencies supported and update the frequency table
accordingly.


But nobody is really using the frequency table except for
clk_round_rate()? Can you add some comments into the commit text and the
code indicating how it works in hardware? I think the way it works is by
having DFS enabled in the clock controller, and then another register in
the QUP register space controls the index that the clk configures itself
for. But I'm not clear on if the RCG registers are updated when DFS
frequency is set, or if anything is visible from the clk controller
hardware besides being in DFS mode and the frequency plan.




Sure, added few more details in the next series.


Signed-off-by: Taniya Das 
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index 52208d4..25b0560 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -929,3 +938,208 @@ static void clk_rcg2_shared_disable(struct clk_hw *hw)
 .set_rate_and_parent = clk_rcg2_shared_set_rate_and_parent,
  };
  EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops);
+
+/* Common APIs to be used for DFS based RCGR */
+static int clk_rcg2_calculate_m_and_n(struct clk_hw *hw, u32 *mode,
+   unsigned long *prate, int level, struct freq_tbl *f)
+{
+   struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+   struct clk_hw *phw;


Just 'p' for parent is good.



Taken care in the next patch.


+   u32 val, mask, cfg, m_off, n_off, offset;
+   int i, ret, num_parents;
+
+   offset = SE_PERF_DFSR(level);
+   ret = regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + offset, &cfg);
+   if (ret)
+   return ret;
+
+   mask = BIT(rcg->hid_width) - 1;
+   f->pre_div = cfg & mask ? (cfg & mask) : 1;
+
+   *mode = cfg & CFG_MODE_MASK;
+   *mode >>= CFG_MODE_SHIFT;
+
+   cfg &= CFG_SRC_SEL_MASK;
+   cfg >>= CFG_SRC_SEL_SHIFT;
+
+   num_parents = clk_hw_get_num_parents(hw);
+   for (i = 0; i < num_parents; i++) {
+   if (cfg == rcg->parent_map[i].cfg) {
+   f->src = rcg->parent_map[i].src;
+   phw = clk_hw_get_parent_by_index(&rcg->clkr.hw, i);
+   *prate = clk_hw_get_rate(phw);
+   }
+   }
+
+   if (!*mode)
+   return 0;
+
+   /* Calculate M & N values */
+   m_off = SE_PERF_M_DFSR(level);
+   n_off = SE_PERF_N_DFSR(level);
+
+   mask = BIT(rcg->mnd_width) - 1;
+   ret =  regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + m_off, &val);


Why weird space before regmap_read?



removed.


+   if (ret) {
+   pr_err("Failed to read M offset register\n");
+   return ret;
+   }
+   val &= mask;
+   f->m  = val;
+
+   ret = regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + n_off, &val);
+   if (ret) {
+   pr_err("Failed to read N offset register\n");
+   return ret;
+   }
+   /* val ~(N-M) */
+   val = ~val;
+   val &= mask;
+   val += f->m;
+   f->n = val;
+
+   return 0;
+}
+
+static int clk_rcg2_dfs_populate_freq_table(struct clk_rcg2 *rcg)
+{
+   struct freq_tbl *dfs_freq_tbl;
+   int i, j, ret = 0;
+   unsigned long calc_freq, prate = 0;
+   u32 mode = 0;
+
+   dfs_freq_tbl = kcalloc(MAX_PERF_LEVEL, sizeof(struct freq_tbl),


sizeof(*dfs_freq_tbl) or just call it freq_tbl. We know it's dfs
already.



Fixed in the next patch.


+   GFP_KERNEL);
+   if (!dfs_freq_tbl)
+   return -ENOMEM;
+
+   for (i = 0; i < MAX_PERF_LEVEL; i++) {
+   ret = clk_rcg2_calculate_m_and_n(&rcg->clkr.hw, &mode, &prate,
+i, &dfs_freq_tbl[i]);


Why can't this function return the frequency? Or 0 if it failed for some
reason?



Sure, have taken care in the next patch.


+   if (ret) {
+   kfree(dfs_freq_tbl);
+   return ret;
+   }
+
+   calc_freq = calc_rate(prate, dfs_freq_tbl[i].m,
+   dfs_freq_tbl[i].n, mode,
+   dfs_freq_tbl[i].pre_div);


Because this is not so good looking.


+   /* Check for dupl

[PATCH v3 0/2] clk: qcom: Add support for RCG to register for DFS

2018-07-15 Thread Taniya Das
 [v3]
  * Rename clk_rcg2_calculate_m_and_n with clk_rcg2_calculate_freq, as this
function would now calculate the frequency.
  * Rename dfs_freq_tbl to freq_tbl.
  * Remove the logic to remove duplicate frequencies.
  * Remove recalc_rate & set_rate clock ops.
  * clk_rcg2_dfs_ops clock ops is static.
  * Override the clock ops only if DFS mode is enabled.
  * qcom_cc_register_rcg_dfs uses regmap instead of device.
  * Few cleanups : Remove DFS probing after registering clocks.
sizeof(*init), sizeof(*freq_tbl).

 [v2]
  * Move the dfs register function 'qcom_cc_register_rcg_dfs'
to clk-rcg2.c instead of common.c
  * At boot read the DFS enable register and override the clk_ops
to be used for dfs or non-dfs RCGs.
  * Remove flag 'dfs_enabled'.
  * Remove functions 'clk_rcg2_dfs_determine_rate_lazy'
  * Remove 'struct dfs_table *dfs_entry'
  * Remove '_freq_tbl_determine_dfs_rate'
  * Combine the function 'clk_index_pre_div_and_mode' and 'calculate_m_and_n'
to a single function and named it 'clk_rcg2_calculate_m_and_n'.
  * Remove taking M/N/PERF offsets as function arguments.
  * Add clocks in gcc-sdm845.c the DFS clock array to register.

 [v1]
   * Update SPDX for files.
   * Add new clk_ops for DFS mode which would be used if dfs is enabled,
 else fall back to the clk_rcg2_shared_ops.
   * Use kcalloc in place kzalloc.
   * Fixed the return type for 'clk_parent_index_pre_div_and_mode' which
 is now renamed to 'clk_index_pre_div_and_mode'.
   * Removed return of -EPERM from 'clk_rcg2_set_rate' and new dfs
 clk_ops is introduced.
   * Pass frequency table entry structure to function calculate_m_and_n.
   * Remove desc from qcom_cc_register_rcg_dfs and instead pass array of
 clk_rcg2.
   * Add a dfs_enable flag to identify if dfs mode is enabled.

In the cases where a RCG requires a Dynamic Frequency switch support
requires to register which would at runtime read the clock perf level
registers to identify the frequencies supported and update the frequency
table accordingly.

Taniya Das (2):
  clk: qcom: Add support for RCG to register for DFS
  clk: qcom: gcc: Register QUPv3 RCGs for DFS on SDM845

 drivers/clk/qcom/clk-rcg.h|   2 +
 drivers/clk/qcom/clk-rcg2.c   | 173 ++
 drivers/clk/qcom/gcc-sdm845.c |  25 ++
 3 files changed, 200 insertions(+)

--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



[PATCH v3 1/2] clk: qcom: Add support for RCG to register for DFS

2018-07-15 Thread Taniya Das
Dynamic Frequency switch is a feature of clock controller by which request
from peripherals allows automatic switching frequency of input clock
without SW intervention. There are various performance levels associated
with a root clock. When the input performance state changes, the source
clocks and division ratios of the new performance state are loaded on to
RCG via HW and the RCG switches to new clock frequency when the RCG is in
DFS HW enabled mode.

Register the root clock generators(RCG) to switch to use the dfs clock ops
in the cases where DFS is enabled. The clk_round_rate() called by the clock
consumer would invoke the dfs determine clock ops and would read the DFS
performance level registers to identify all the frequencies supported and
update the frequency table. The DFS clock consumers would maintain these
frequency mapping and request the desired performance levels.

Signed-off-by: Taniya Das 
---
 drivers/clk/qcom/clk-rcg.h  |   2 +
 drivers/clk/qcom/clk-rcg2.c | 173 
 2 files changed, 175 insertions(+)

diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h
index b209a2f..bffb625 100644
--- a/drivers/clk/qcom/clk-rcg.h
+++ b/drivers/clk/qcom/clk-rcg.h
@@ -161,4 +161,6 @@ struct clk_rcg2 {
 extern const struct clk_ops clk_gfx3d_ops;
 extern const struct clk_ops clk_rcg2_shared_ops;

+extern int qcom_cc_register_rcg_dfs(struct regmap *regmap,
+struct clk_rcg2 **rcgs, int num_clks);
 #endif
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index 52208d4..f8f1417 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 

 #include 

@@ -40,6 +41,14 @@
 #define N_REG  0xc
 #define D_REG  0x10

+/* Dynamic Frequency Scaling */
+#define MAX_PERF_LEVEL 8
+#define SE_CMD_DFSR_OFFSET 0x14
+#define SE_CMD_DFS_EN  BIT(0)
+#define SE_PERF_DFSR(level)(0x1c + 0x4 * (level))
+#define SE_PERF_M_DFSR(level)  (0x5c + 0x4 * (level))
+#define SE_PERF_N_DFSR(level)  (0x9c + 0x4 * (level))
+
 enum freq_policy {
FLOOR,
CEIL,
@@ -929,3 +938,167 @@ static void clk_rcg2_shared_disable(struct clk_hw *hw)
.set_rate_and_parent = clk_rcg2_shared_set_rate_and_parent,
 };
 EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops);
+
+/* Common APIs to be used for DFS based RCGR */
+static unsigned long clk_rcg2_calculate_freq(struct clk_hw *hw,
+   int level, struct freq_tbl *f)
+{
+   struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+   struct clk_hw *p;
+   unsigned long prate = 0;
+   u32 val, mask, cfg, m_off, n_off, offset, mode;
+   int i, ret, num_parents;
+
+   offset = SE_PERF_DFSR(level);
+   ret = regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + offset, &cfg);
+   if (ret)
+   return ret;
+
+   mask = BIT(rcg->hid_width) - 1;
+   f->pre_div = cfg & mask ? (cfg & mask) : 1;
+
+   mode = cfg & CFG_MODE_MASK;
+   mode >>= CFG_MODE_SHIFT;
+
+   cfg &= CFG_SRC_SEL_MASK;
+   cfg >>= CFG_SRC_SEL_SHIFT;
+
+   num_parents = clk_hw_get_num_parents(hw);
+   for (i = 0; i < num_parents; i++) {
+   if (cfg == rcg->parent_map[i].cfg) {
+   f->src = rcg->parent_map[i].src;
+   p = clk_hw_get_parent_by_index(&rcg->clkr.hw, i);
+   prate = clk_hw_get_rate(p);
+   }
+   }
+
+   if (!mode)
+   goto done;
+
+   /* Calculate M & N values */
+   m_off = SE_PERF_M_DFSR(level);
+   n_off = SE_PERF_N_DFSR(level);
+
+   mask = BIT(rcg->mnd_width) - 1;
+   ret = regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + m_off, &val);
+   if (ret) {
+   pr_err("Failed to read M offset register\n");
+   return ret;
+   }
+   val &= mask;
+   f->m = val;
+
+   ret = regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + n_off, &val);
+   if (ret) {
+   pr_err("Failed to read N offset register\n");
+   return ret;
+   }
+   /* val ~(N-M) */
+   val = ~val;
+   val &= mask;
+   val += f->m;
+   f->n = val;
+done:
+   return calc_rate(prate, f->m, f->n, mode, f->pre_div);
+}
+
+static int clk_rcg2_dfs_populate_freq_table(struct clk_rcg2 *rcg)
+{
+   struct freq_tbl *freq_tbl;
+   unsigned long calc_freq;
+   int i;
+
+   freq_tbl = kcalloc(MAX_PERF_LEVEL, sizeof(*freq_tbl),
+   GFP_KERNEL);
+   if (!freq_tbl)
+   return -ENOMEM;
+
+   for (i = 0; i < MAX_PERF_LEVEL; i++) {
+   calc_freq = clk_rcg2_calculate_freq(&rcg->clkr.hw,
+ 

[PATCH v3 2/2] clk: qcom: gcc: Register QUPv3 RCGs for DFS on SDM845

2018-07-15 Thread Taniya Das
QUPv3 clocks support DFS and thus register the RCGs which require support
for the same.

Signed-off-by: Taniya Das 
---
 drivers/clk/qcom/gcc-sdm845.c | 25 +
 1 file changed, 25 insertions(+)

diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index 0f694ed..305deca 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -3460,9 +3460,29 @@ enum {
 };
 MODULE_DEVICE_TABLE(of, gcc_sdm845_match_table);

+static struct clk_rcg2 *gcc_dfs_clocks[] = {
+   &gcc_qupv3_wrap0_s0_clk_src,
+   &gcc_qupv3_wrap0_s1_clk_src,
+   &gcc_qupv3_wrap0_s2_clk_src,
+   &gcc_qupv3_wrap0_s3_clk_src,
+   &gcc_qupv3_wrap0_s4_clk_src,
+   &gcc_qupv3_wrap0_s5_clk_src,
+   &gcc_qupv3_wrap0_s6_clk_src,
+   &gcc_qupv3_wrap0_s7_clk_src,
+   &gcc_qupv3_wrap1_s0_clk_src,
+   &gcc_qupv3_wrap1_s1_clk_src,
+   &gcc_qupv3_wrap1_s2_clk_src,
+   &gcc_qupv3_wrap1_s3_clk_src,
+   &gcc_qupv3_wrap1_s4_clk_src,
+   &gcc_qupv3_wrap1_s5_clk_src,
+   &gcc_qupv3_wrap1_s6_clk_src,
+   &gcc_qupv3_wrap1_s7_clk_src,
+};
+
 static int gcc_sdm845_probe(struct platform_device *pdev)
 {
struct regmap *regmap;
+   int ret;

regmap = qcom_cc_map(pdev, &gcc_sdm845_desc);
if (IS_ERR(regmap))
@@ -3472,6 +3492,11 @@ static int gcc_sdm845_probe(struct platform_device *pdev)
regmap_update_bits(regmap, 0x09ffc, 0x3, 0x3);
regmap_update_bits(regmap, 0x71028, 0x3, 0x3);

+   ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks,
+   ARRAY_SIZE(gcc_dfs_clocks));
+   if (ret)
+   return ret;
+
return qcom_cc_really_probe(pdev, &gcc_sdm845_desc, regmap);
 }

--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



[PATCH] clk: qcom: Update SPDX headers for common files

2018-07-15 Thread Taniya Das
SPDX headers updated for common/branch/pll/regmap files.

Signed-off-by: Taniya Das 
---
 drivers/clk/qcom/clk-alpha-pll.c | 10 +-
 drivers/clk/qcom/clk-alpha-pll.h | 14 ++
 drivers/clk/qcom/clk-branch.c| 10 +-
 drivers/clk/qcom/clk-branch.h| 14 ++
 drivers/clk/qcom/clk-regmap.c| 10 +-
 drivers/clk/qcom/clk-regmap.h| 14 ++
 drivers/clk/qcom/common.c| 10 +-
 drivers/clk/qcom/common.h| 15 +++
 8 files changed, 13 insertions(+), 84 deletions(-)

diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 3c49a60..a91d97c 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -1,14 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2015, 2018, The Linux Foundation. All rights reserved.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */

 #include 
diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
index f981b48..66755f0 100644
--- a/drivers/clk/qcom/clk-alpha-pll.h
+++ b/drivers/clk/qcom/clk-alpha-pll.h
@@ -1,15 +1,5 @@
-/*
- * Copyright (c) 2015, 2018, The Linux Foundation. All rights reserved.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (c) 2015, 2018, The Linux Foundation. All rights reserved. */

 #ifndef __QCOM_CLK_ALPHA_PLL_H__
 #define __QCOM_CLK_ALPHA_PLL_H__
diff --git a/drivers/clk/qcom/clk-branch.c b/drivers/clk/qcom/clk-branch.c
index c58c553..bc2205c 100644
--- a/drivers/clk/qcom/clk-branch.c
+++ b/drivers/clk/qcom/clk-branch.c
@@ -1,14 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */

 #include 
diff --git a/drivers/clk/qcom/clk-branch.h b/drivers/clk/qcom/clk-branch.h
index 1702efb..b3561e0 100644
--- a/drivers/clk/qcom/clk-branch.h
+++ b/drivers/clk/qcom/clk-branch.h
@@ -1,15 +1,5 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved. */

 #ifndef __QCOM_CLK_BRANCH_H__
 #define __QCOM_CLK_BRANCH_H__
diff --git a/drivers/clk/qcom/clk-regmap.c b/drivers/clk/qcom/clk-regmap.c
index 1c856d3..ce80db2 100644
--- a/drivers/clk/qcom/clk-regmap.c
+++ b/drivers/clk/qcom/clk-regmap.c
@@ -1,14 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2014, The Linux Foundation. All rights reserved.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */

 #include 
diff --git a/drivers/clk/qcom/clk-regmap.h b/drivers/clk/qcom/clk-regmap.h
index 90d95cd..6cfc1bc 100644
--- a/drivers/clk/qcom/clk-regmap.h
+++ b/drivers/clk/qcom/clk-regmap.h
@@ -1,15 +1,5 @@
-/*
- * Copyright

Re: [PATCH v3 3/3] clk: qcom: Add display clock controller driver for SDM845

2018-07-15 Thread Taniya Das

Hello Stephen,

On 7/13/2018 1:55 PM, spa...@codeaurora.org wrote:

On 2018-07-13 01:11, Stephen Boyd wrote:

Quoting Taniya Das (2018-07-12 10:21:33)

++ Display driver team,

On 7/9/2018 8:36 PM, Stephen Boyd wrote:
> Quoting Taniya Das (2018-07-09 02:34:07)
>>
>>
>> On 7/9/2018 1:07 PM, Stephen Boyd wrote:
>>> Quoting Taniya Das (2018-07-09 00:07:21)
>>>>
>>>>
>>>> On 7/9/2018 11:46 AM, Stephen Boyd wrote:
>>>>>>
>>>>>> > Why is the nocache flag needed? Applies to all clks in 
this file.

>>>>>> >
>>>>>>
>>>>>> This flag is required for all RCGs whose PLLs are controlled 
outside the
>>>>>> clock controller. The display code would require the 
recalculated rate

>>>>>> always.
>>>>>
>>>>> Right. Why is the PLL controlled outside of the clock 
controller? The

>>>>> rate should propagate upward to the PLL from here, so who's going
>>>>> outside of that?
>>>>>
>>>> The DSI0/1 PLL are not part of the display clock controller, but 
in the
>>>> display subsystem which are managed by the DRM drivers. When DRM 
drivers
>>>> query for the rate clock driver should always return the non 
cached rates.

>>>
>>> Why? Is the DSI PLL changing rate all the time, randomly, without 
going

>>> through the clk APIs to do so?
>>>
>>
>> Hmm, I am afraid I do not have an answer for this, but this was the
>> requirement to always return the non cached rates from the clock 
driver.

>>
>
> Ok. Who knows about this requirement? Can we add someone from the
> display driver to understand more?
>
As per my discussions offline with the display teams,

There is a use-case where the clock framework is unaware of the PLL VCO
frequency change and thus the drivers would query to get the actual HW
frequency rather than the cached one.

Do you think keeping these flags would have any impact other than always
getting the non-cached rates?



The flag will make it so clk_get_rate() works in spite of something
changing the frequency behind the framework's back, but I want to
understand what and why it's changing without framework involvement. We
shouldn't need the flag here, because this flag is typically for clks
that are controlled by some other entity that the kernel doesn't have
control over. In this case, it seems like we have full control of the
clk tree for the display PLL down to this clk, so it should be perfectly
fine to not have this flag. The presence of the flag means that the
display driver is doing something wrong.


These clocks are sourced from DSI PLL. In dsi command mode there is an 
idle use case when there
is no activity on display, we switch of the source DSI PLL to save power 
by calling clk_disable_unprepare().
In this scenario if some client queries the clk_get_rate(), then if 
NO_CACHE flag is used the clk
driver will return the cached rate which is some non-zero value set when 
we last called clk_set_rate(),
before enabling the clock, whereas actually in HW this clk is disabled. 
So we used the NO_CACHE flag
for the call to land in clk_recalc_rate and we return zero if the PLL is 
disabled.
I remember some customer had scripts that runs through all the clocks 
during idle screen scenario
and call clk_get_rate(), where they complained display clk_get_rate 
returns none zero value.





Do you think the clock driver needs any update for flag for the next series?


--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


Re: [PATCH 2/2] dt-bindings: clock: Introduce QCOM RPMh clock bindings

2018-04-08 Thread Taniya Das

Thanks Stephen for the review.

On 4/6/2018 4:50 AM, Stephen Boyd wrote:

Quoting Taniya Das (2018-03-28 23:17:53)

diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmh.txt 
b/Documentation/devicetree/bindings/clock/qcom,rpmh.txt
new file mode 100644
index 000..8222c88
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,rpmh.txt


Can the file name be qcom,rpmh-clk?



Sure will update the file name.


@@ -0,0 +1,22 @@
+Qualcomm Technologies, Inc. RPMh Clocks
+---
+
+Resource Power Manager Hardened (RPMh) manages shared resources on
+some Qualcomm Technologies Inc. SoCs. It accepts clock requests from
+other hardware subsystems via RSC to control clocks.
+
+Required properties :
+- compatible : shall contain "qcom,rpmh-clk-sdm845"
+
+- #clock-cells : must contain 1
+
+Example :
+
+#include 
+
+   &apps_rsc {



+   clock_rpmh: qcom,rpmhclk {


Should say clock-controller for node name.



Would fix it in the next patch.


+   compatible = "qcom,rpmh-clk-sdm845";
+   #clock-cells = <1>;


Is this tabbed out correctly?



Will fix the tabs in the next patch.


+   };
+   };


--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


[PATCH v2 0/2] Add QCOM RPMh Clock driver

2018-04-08 Thread Taniya Das
 [v2]
  * Addressed comments from Stephen
  * Addressed comments from Evan

This patch series adds a driver and device tree documentation binding
for the clock control via Resource Power Manager-hardened (RPMh) on some
Qualcomm Technologies, Inc, SoCs such as SDM845. The clock RPMh driver
would send requests for the RPMh managed clock resources.

The RPMh clock driver depends upon the RPMh driver [1] and command DB
driver [2] which are both still undergoing review.

Thanks,
Taniya

[1]: https://lkml.org/lkml/2018/3/9/979
[2]: https://lkml.org/lkml/2018/3/14/787

Amit Nischal (2):
  clk: qcom: clk-rpmh: Add QCOM RPMh clock driver
  dt-bindings: clock: Introduce QCOM RPMh clock bindings

 .../devicetree/bindings/clock/qcom,rpmh-clk.txt |  22 ++
 drivers/clk/qcom/Kconfig|   9 +
 drivers/clk/qcom/Makefile   |   1 +
 drivers/clk/qcom/clk-rpmh.c | 394 +
 include/dt-bindings/clock/qcom,rpmh.h   |  25 ++
 5 files changed, 451 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,rpmh-clk.txt
 create mode 100644 drivers/clk/qcom/clk-rpmh.c
 create mode 100644 include/dt-bindings/clock/qcom,rpmh.h

--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



[[PATCH v2] 1/2] clk: qcom: clk-rpmh: Add QCOM RPMh clock driver

2018-04-08 Thread Taniya Das
From: Amit Nischal 

Add the RPMh clock driver to control the RPMh managed clock resources on
some of the Qualcomm Technologies, Inc. SoCs.

Signed-off-by: David Collins 
Signed-off-by: Amit Nischal 
Signed-off-by: Taniya Das 
---
 drivers/clk/qcom/Kconfig  |   9 +
 drivers/clk/qcom/Makefile |   1 +
 drivers/clk/qcom/clk-rpmh.c   | 394 ++
 include/dt-bindings/clock/qcom,rpmh.h |  25 +++
 4 files changed, 429 insertions(+)
 create mode 100644 drivers/clk/qcom/clk-rpmh.c
 create mode 100644 include/dt-bindings/clock/qcom,rpmh.h

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index fbf4532..3697a6a 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -112,6 +112,15 @@ config IPQ_GCC_8074
  i2c, USB, SD/eMMC, etc. Select this for the root clock
  of ipq8074.
 
+config MSM_CLK_RPMH
+   tristate "RPMh Clock Driver"
+   depends on COMMON_CLK_QCOM && QCOM_RPMH
+   help
+RPMh manages shared resources on some Qualcomm Technologies, Inc.
+SoCs. It accepts requests from other hardware subsystems via RSC.
+Say Y if you want to support the clocks exposed by RPMh on
+platforms such as sdm845.
+
 config MSM_GCC_8660
tristate "MSM8660 Global Clock Controller"
depends on COMMON_CLK_QCOM
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 230332c..b7da05b 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_IPQ_GCC_8074) += gcc-ipq8074.o
 obj-$(CONFIG_IPQ_LCC_806X) += lcc-ipq806x.o
 obj-$(CONFIG_MDM_GCC_9615) += gcc-mdm9615.o
 obj-$(CONFIG_MDM_LCC_9615) += lcc-mdm9615.o
+obj-$(CONFIG_MSM_CLK_RPMH) += clk-rpmh.o
 obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o
 obj-$(CONFIG_MSM_GCC_8916) += gcc-msm8916.o
 obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o
diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c
new file mode 100644
index 000..763401f
--- /dev/null
+++ b/drivers/clk/qcom/clk-rpmh.c
@@ -0,0 +1,394 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "common.h"
+#include "clk-regmap.h"
+
+#define CLK_RPMH_ARC_EN_OFFSET 0
+#define CLK_RPMH_VRM_EN_OFFSET 4
+#define CLK_RPMH_VRM_OFF_VAL 0
+#define CLK_RPMH_VRM_ON_VAL 1
+#define CLK_RPMH_APPS_RSC_AO_STATE_MASK (BIT(RPMH_WAKE_ONLY_STATE) | \
+BIT(RPMH_ACTIVE_ONLY_STATE))
+#define CLK_RPMH_APPS_RSC_STATE_MASK (BIT(RPMH_WAKE_ONLY_STATE) | \
+ BIT(RPMH_ACTIVE_ONLY_STATE) | \
+ BIT(RPMH_SLEEP_STATE))
+struct clk_rpmh {
+   struct clk_hw hw;
+   const char *res_name;
+   u32 res_addr;
+   u32 res_en_offset;
+   u32 res_on_val;
+   u32 res_off_val;
+   u32 state;
+   u32 aggr_state;
+   u32 last_sent_aggr_state;
+   u32 valid_state_mask;
+   struct rpmh_client *rpmh_client;
+   unsigned long rate;
+   struct clk_rpmh *peer;
+};
+
+struct rpmh_cc {
+   struct clk_onecell_data data;
+   struct clk *clks[];
+};
+
+struct clk_rpmh_desc {
+   struct clk_hw **clks;
+   size_t num_clks;
+};
+
+static DEFINE_MUTEX(rpmh_clk_lock);
+
+#define __DEFINE_CLK_RPMH(_platform, _name, _name_active, _res_name, \
+ _res_en_offset, _res_on, _res_off, _rate, \
+ _state_mask, _state_on_mask)\
+   static struct clk_rpmh _platform##_##_name_active;\
+   static struct clk_rpmh _platform##_##_name = {\
+   .res_name = _res_name,\
+   .res_en_offset = _res_en_offset,  \
+   .res_on_val = _res_on,\
+   .res_off_val = _res_off,  \
+   .rate = _rate,\
+   .peer = &_platform##_##_name_active,  \
+   .valid_state_mask = _state_mask,  \
+   .hw.init = &(struct clk_init_data){   \
+   .ops = &clk_rpmh_ops, \
+   .name = #_name,   \
+   },\
+   };\
+   static struct clk_rpmh _platform##_##_name_active = { \
+   .res_name = _res_name,

[[PATCH v2] 2/2] dt-bindings: clock: Introduce QCOM RPMh clock bindings

2018-04-08 Thread Taniya Das
From: Amit Nischal 

Add RPMh clock device bindings for Qualcomm Technology Inc's SoCs. These
devices would be used for communicating resource state requests to control
the clocks managed by RPMh.

Signed-off-by: Amit Nischal 
Signed-off-by: Taniya Das 
---
 .../devicetree/bindings/clock/qcom,rpmh-clk.txt| 22 ++
 1 file changed, 22 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,rpmh-clk.txt

diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmh-clk.txt 
b/Documentation/devicetree/bindings/clock/qcom,rpmh-clk.txt
new file mode 100644
index 000..4ade82b
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,rpmh-clk.txt
@@ -0,0 +1,22 @@
+Qualcomm Technologies, Inc. RPMh Clocks
+---
+
+Resource Power Manager Hardened (RPMh) manages shared resources on
+some Qualcomm Technologies Inc. SoCs. It accepts clock requests from
+other hardware subsystems via RSC to control clocks.
+
+Required properties :
+- compatible : shall contain "qcom,rpmh-clk-sdm845"
+
+- #clock-cells : must contain 1
+
+Example :
+
+#include 
+
+   &apps_rsc {
+   rpmh: clock-controller {
+   compatible = "qcom,rpmh-clk-sdm845";
+   #clock-cells = <1>;
+   };
+   };
-- 
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



[PATCH v2 0/3] Update reset and poll logic for GDSCs

2018-04-09 Thread Taniya Das
 [v2]
  * Addressed review comments given in v1 series

This series implements the below logic for the GDSCs

 1. logic to reset the AON logic before or assert/deassert the block
   control reset removing the clamp io for few GDSCs on SDM845 SoC.
 2. It also introduces the requirement to poll for higher timeout values
   for few of the GDSCs.
 3. There is a new poll register for the GDSCs on SDM845 SoCs which needs
   to be polled for the correct hardware status of the GDSCs.

Amit Nischal (3):
  clk: qcom: gdsc: Add support to reset AON and block reset logic
  clk: qcom: gdsc: Add support to poll for higher timeout value
  clk: qcom: gdsc: Add support to poll CFG register to check GDSC state

 drivers/clk/qcom/gdsc.c | 63 +++--
 drivers/clk/qcom/gdsc.h |  5 +++-
 2 files changed, 60 insertions(+), 8 deletions(-)

--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



[PATCH v2 3/3] clk: qcom: gdsc: Add support to poll CFG register to check GDSC state

2018-04-09 Thread Taniya Das
From: Amit Nischal 

The default behavior of the GDSC enable/disable sequence is to
poll the status bits of either the actual GDSCR or the
corresponding HW_CTRL registers.

On targets which have support for a CFG_GDSCR register, the
status bits might not show the correct state of the GDSC,
especially in the disable sequence, where the status bit
will be cleared even before the core is completely power
collapsed. On targets with this issue, poll the power on/off
bits in the CFG_GDSCR register instead to correctly determine
the GDSC state.

Signed-off-by: Amit Nischal 
Signed-off-by: Taniya Das 
---
 drivers/clk/qcom/gdsc.c | 39 +++
 drivers/clk/qcom/gdsc.h |  1 +
 2 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
index cb61c15..2dda2d5 100644
--- a/drivers/clk/qcom/gdsc.c
+++ b/drivers/clk/qcom/gdsc.c
@@ -33,6 +33,11 @@
 #define GMEM_CLAMP_IO_MASK BIT(0)
 #define GMEM_RESET_MASKBIT(4)

+/* CFG_GDSCR */
+#define GDSC_POWER_UP_COMPLETE BIT(16)
+#define GDSC_POWER_DOWN_COMPLETE   BIT(15)
+#define CFG_GDSCR_OFFSET   0x4
+
 /* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */
 #define EN_REST_WAIT_VAL   (0x2 << 20)
 #define EN_FEW_WAIT_VAL(0x8 << 16)
@@ -64,18 +69,43 @@ static int gdsc_hwctrl(struct gdsc *sc, bool en)
return regmap_update_bits(sc->regmap, sc->gdscr, HW_CONTROL_MASK, val);
 }

+static int gdsc_is_enabled_by_poll_cfg_reg(struct gdsc *sc, bool en)
+{
+   u32 val;
+   int ret;
+
+   ret = regmap_read(sc->regmap, sc->gdscr + CFG_GDSCR_OFFSET, &val);
+   if (ret)
+   return ret;
+
+   if (en)
+   return !!(val & GDSC_POWER_UP_COMPLETE);
+
+   return !(val & GDSC_POWER_DOWN_COMPLETE);
+}
+
 static int gdsc_poll_status(struct gdsc *sc, unsigned int reg, bool en)
 {
ktime_t start;

start = ktime_get();
do {
-   if (gdsc_is_enabled(sc, reg) == en)
-   return 0;
+   if (sc->flags & POLL_CFG_GDSCR) {
+   if (gdsc_is_enabled_by_poll_cfg_reg(sc, en) == en)
+   return 0;
+   } else {
+   if (gdsc_is_enabled(sc, reg) == en)
+   return 0;
+   }
} while (ktime_us_delta(ktime_get(), start) < TIMEOUT_US);

-   if (gdsc_is_enabled(sc, reg) == en)
-   return 0;
+   if (sc->flags & POLL_CFG_GDSCR) {
+   if (gdsc_is_enabled_by_poll_cfg_reg(sc, en) == en)
+   return 0;
+   } else {
+   if (gdsc_is_enabled(sc, reg) == en)
+   return 0;
+   }

return -ETIMEDOUT;
 }
@@ -254,6 +284,7 @@ static int gdsc_disable(struct generic_pm_domain *domain)
udelay(1);

reg = sc->gds_hw_ctrl ? sc->gds_hw_ctrl : sc->gdscr;
+
ret = gdsc_poll_status(sc, reg, true);
if (ret)
return ret;
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
index 9279278..0f992e8 100644
--- a/drivers/clk/qcom/gdsc.h
+++ b/drivers/clk/qcom/gdsc.h
@@ -55,6 +55,7 @@ struct gdsc {
 #define HW_CTRLBIT(2)
 #define SW_RESET   BIT(3)
 #define AON_RESET  BIT(4)
+#define POLL_CFG_GDSCR  BIT(5)
struct reset_controller_dev *rcdev;
unsigned int*resets;
unsigned intreset_count;
--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



[PATCH v2 0/3] Update reset and poll logic for GDSCs

2018-04-09 Thread Taniya Das
 [v2]
  * Addressed review comments given in v1 series

This series implements the below logic for the GDSCs

 1. logic to reset the AON logic before or assert/deassert the block
   control reset removing the clamp io for few GDSCs on SDM845 SoC.
 2. It also introduces the requirement to poll for higher timeout values
   for few of the GDSCs.
 3. There is a new poll register for the GDSCs on SDM845 SoCs which needs
   to be polled for the correct hardware status of the GDSCs.

Amit Nischal (3):
  clk: qcom: gdsc: Add support to reset AON and block reset logic
  clk: qcom: gdsc: Add support to poll for higher timeout value
  clk: qcom: gdsc: Add support to poll CFG register to check GDSC state

 drivers/clk/qcom/gdsc.c | 63 +++--
 drivers/clk/qcom/gdsc.h |  5 +++-
 2 files changed, 60 insertions(+), 8 deletions(-)

--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



[PATCH v2 2/3] clk: qcom: gdsc: Add support to poll for higher timeout value

2018-04-09 Thread Taniya Das
From: Amit Nischal 

For some gdscs, it might take longer time up to 500us for updating their
status. Update the timeout value for all GDSC polling status.

Signed-off-by: Amit Nischal 
Signed-off-by: Taniya Das 
---
 drivers/clk/qcom/gdsc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
index 266fefa..cb61c15 100644
--- a/drivers/clk/qcom/gdsc.c
+++ b/drivers/clk/qcom/gdsc.c
@@ -41,7 +41,7 @@
 #define RETAIN_MEM BIT(14)
 #define RETAIN_PERIPH  BIT(13)

-#define TIMEOUT_US 100
+#define TIMEOUT_US 500

 #define domain_to_gdsc(domain) container_of(domain, struct gdsc, pd)

--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



[PATCH v2 1/3] clk: qcom: gdsc: Add support to reset AON and block reset logic

2018-04-09 Thread Taniya Das
From: Amit Nischal 

For some of the gdsc power domains, there could be need to reset the
AON logic or assert/deassert the block control reset before removing
the clamp_io. Add support for the same by introducing new flags
SW_RESET and AON_RESET. Both SW reset and AON reset requires to be
asserted for at least 1us before being de-asserted.

Signed-off-by: Taniya Das 
Signed-off-by: Amit Nischal 
---
 drivers/clk/qcom/gdsc.c | 22 --
 drivers/clk/qcom/gdsc.h |  4 +++-
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
index a4f3580..266fefa 100644
--- a/drivers/clk/qcom/gdsc.c
+++ b/drivers/clk/qcom/gdsc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015, 2017-2018, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -31,6 +31,7 @@
 #define HW_CONTROL_MASKBIT(1)
 #define SW_COLLAPSE_MASK   BIT(0)
 #define GMEM_CLAMP_IO_MASK BIT(0)
+#define GMEM_RESET_MASKBIT(4)

 /* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */
 #define EN_REST_WAIT_VAL   (0x2 << 20)
@@ -166,6 +167,14 @@ static inline void gdsc_assert_clamp_io(struct gdsc *sc)
   GMEM_CLAMP_IO_MASK, 1);
 }

+static inline void gdsc_assert_reset_aon(struct gdsc *sc)
+{
+   regmap_update_bits(sc->regmap, sc->clamp_io_ctrl,
+  GMEM_RESET_MASK, 1);
+   udelay(1);
+   regmap_update_bits(sc->regmap, sc->clamp_io_ctrl,
+  GMEM_RESET_MASK, 0);
+}
 static int gdsc_enable(struct generic_pm_domain *domain)
 {
struct gdsc *sc = domain_to_gdsc(domain);
@@ -174,8 +183,17 @@ static int gdsc_enable(struct generic_pm_domain *domain)
if (sc->pwrsts == PWRSTS_ON)
return gdsc_deassert_reset(sc);

-   if (sc->flags & CLAMP_IO)
+   if (sc->flags & SW_RESET) {
+   gdsc_assert_reset(sc);
+   udelay(1);
+   gdsc_deassert_reset(sc);
+   }
+
+   if (sc->flags & CLAMP_IO) {
+   if (sc->flags & AON_RESET)
+   gdsc_assert_reset_aon(sc);
gdsc_deassert_clamp_io(sc);
+   }

ret = gdsc_toggle_logic(sc, true);
if (ret)
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
index 3964834..9279278 100644
--- a/drivers/clk/qcom/gdsc.h
+++ b/drivers/clk/qcom/gdsc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015, 2017-2018, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -53,6 +53,8 @@ struct gdsc {
 #define VOTABLEBIT(0)
 #define CLAMP_IO   BIT(1)
 #define HW_CTRLBIT(2)
+#define SW_RESET   BIT(3)
+#define AON_RESET  BIT(4)
struct reset_controller_dev *rcdev;
unsigned int*resets;
unsigned intreset_count;
--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



Re: [PATCH 2/3] clk: qcom: gdsc: Add support to poll for higher timeout value

2018-04-09 Thread Taniya Das

Hello Stephen,

Thanks for the review comments.

On 4/6/2018 4:54 AM, Stephen Boyd wrote:

Quoting Taniya Das (2018-04-02 03:45:44)

From: Amit Nischal 

For some gdscs, it might take longer time up to 500us for
updating their status. So add support for the same by
defining a new flag 'GDS_TIMEOUT' to mark such gdsc in
order to poll their status for longer timeout value.

Signed-off-by: Amit Nischal 
Signed-off-by: Taniya Das 
---


Let's just increase the timeout to 500 if it's required? This is a
timeout, so we're not really expecting to hit it anyway so optimizing
the uncommon case is not useful.
--


Will fix this in the next series.


To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


Re: [PATCH 3/3] clk: qcom: gdsc: Add support to poll CFG register to check GDSC state

2018-04-09 Thread Taniya Das

Hello Stephen,

Thanks for the review comments.

On 4/6/2018 10:10 PM, Stephen Boyd wrote:

Quoting Taniya Das (2018-04-02 03:45:45)

diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
index e89584e..e0c83ba 100644
--- a/drivers/clk/qcom/gdsc.c
+++ b/drivers/clk/qcom/gdsc.c
@@ -83,6 +88,38 @@ static int gdsc_poll_status(struct gdsc *sc, unsigned int 
reg, bool en)
 return -ETIMEDOUT;
  }

+static int gdsc_is_enabled_by_poll_cfg_reg(struct gdsc *sc, bool en)
+{
+   u32 val;
+   int ret;
+
+   ret = regmap_read(sc->regmap, sc->gdscr + CFG_GDSCR_OFFSET, &val);
+   if (ret)
+   return ret;
+
+   if (en)
+   return !!(val & GDSC_POWER_UP_COMPLETE);
+   else
+   return !(val & GDSC_POWER_DOWN_COMPLETE);


Make this into

if (en)
return ...

return ...



Will fix this in the next series.


+}
+
+static int gdsc_poll_cfg_status(struct gdsc *sc, bool en)
+{
+   ktime_t start = ktime_get();
+   ktime_t timeout =
+   (sc->flags & GDS_TIMEOUT) ? TIMEOUT_US_GDS : TIMEOUT_US;
+
+   do {
+   if (gdsc_is_enabled_by_poll_cfg_reg(sc, en) == en)
+   return 0;
+   } while (ktime_us_delta(ktime_get(), start) < timeout);
+
+   if (gdsc_is_enabled_by_poll_cfg_reg(sc, en) == en)
+   return 0;
+
+   return -ETIMEDOUT;
+}
+
  static int gdsc_toggle_logic(struct gdsc *sc, bool en)
  {
 int ret;
@@ -106,6 +143,9 @@ static int gdsc_toggle_logic(struct gdsc *sc, bool en)
 return 0;
 }

+   if (sc->flags & POLL_CFG_GDSCR)
+   return gdsc_poll_cfg_status(sc, en);
+
 if (sc->gds_hw_ctrl) {
 status_reg = sc->gds_hw_ctrl;
 /*
@@ -258,8 +298,12 @@ static int gdsc_disable(struct generic_pm_domain *domain)
  */
 udelay(1);

-   reg = sc->gds_hw_ctrl ? sc->gds_hw_ctrl : sc->gdscr;
-   ret = gdsc_poll_status(sc, reg, true);
+   if (sc->flags & POLL_CFG_GDSCR) {
+   ret = gdsc_poll_cfg_status(sc, true);
+   } else {
+   reg = sc->gds_hw_ctrl ? sc->gds_hw_ctrl : sc->gdscr;
+   ret = gdsc_poll_status(sc, reg, true);
+   }


Maybe this can be pushed into the gdsc_poll_status() function so that
we can keep the "how do we poll status bit" logic in one place.



Yes, I will push the logic in the gdsc_poll_status() in the next series.


 if (ret)
 return ret;
 }


--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


[PATCH v4 0/2] Add QCOM graphics clock controller driver for SDM845

2018-11-24 Thread Taniya Das
Changes in v4:
* Cleanup the GPUCC code to keep only the clocks which would be requested
  from the GPU client SW.
* Clean up of code as well as header file clock IDs.
* Due to the above cleanup the patches to enable/disable clocks for GPU GDSC
  requirement is not supported : https://patchwork.kernel.org/patch/10563889/
* The GPU_GX RCG support is also removed from the main driver, so the 
corresponding
  RCG ops are removed : https://patchwork.kernel.org/patch/10563891/

Changes in v3:
* Modified the determine_rate() op to use the min/max rate range
  to round the requested rate within the set_rate range. With this,
  requested set rate will always stay within the limits.

Changes in v2:
Addressed review comments given by Stephen: https://lkml.org/lkml/2018/6/6/294
* Introduce clk_rcg2_gfx3d_determine_rate ops to return the best parent
  as 'gpucc_pll0_even' and best parent rate as twice of the requested rate
  always. This will eliminate the need of frequency table as source and
  div-2 are fixed for gfx3d_clk_src.
  Also modified the clk_rcg2_set_rate ops to configure the fixed source and
  div.
* Add support to check if requested rate falls within allowed set_rate range.
  This will not let the source gpucc_pll0 to go out of the supported range
  and also client can request the rate within the range.
* Fixed comment text in probe function and added module description for GPUCC
  driver.

The graphics clock driver depends upon the below change.
https://lkml.org/lkml/2018/6/23/108

Changes in v1:
This patch series adds support for graphics clock controller for SDM845.
Below is the brief description for each change:

1. For some of the GDSCs, there is requirement to enable/disable the
   few clocks before turning on/off the gdsc power domain. This patch
   will add support to enable/disable the clock associated with the
   gdsc along with power domain on/off callbacks.

2. To turn on the gpu_gx_gdsc, there is a hardware requirement to
   turn on the root clock (GFX3D RCG) first which would be the turn
   on signal for the gdsc along with the SW_COLLAPSE. As per the
   current implementation of clk_rcg2_shared_ops, it clears the
   root_enable bit in the enable() clock ops. But due to the above
   said requirement for GFX3D shared RCG, root_enable bit would be
   already set by gdsc driver and rcg2_shared_ops should not clear
   the root unless the disable() is called.

   This patch add support for the same by reusing the existing
   clk_rcg2_shared_ops and deriving "clk_rcg2_gfx3d_ops" clk_ops
   for GFX3D clock to take care of the root set/clear requirement.

3. Add device tree bindings for graphics clock controller for SDM845.

4. Add graphics clock controller (GPUCC) driver for SDM845.

[v1] : https://lore.kernel.org/patchwork/project/lkml/list/?series=348697
[v2] : https://lore.kernel.org/patchwork/project/lkml/list/?series=359012

Amit Nischal (2):
  dt-bindings: clock: Introduce QCOM Graphics clock bindings
  clk: qcom: Add graphics clock controller driver for SDM845

 .../devicetree/bindings/clock/qcom,gpucc.txt   |  18 ++
 drivers/clk/qcom/Kconfig   |   9 +
 drivers/clk/qcom/Makefile  |   1 +
 drivers/clk/qcom/gpucc-sdm845.c| 231 +
 include/dt-bindings/clock/qcom,gpucc-sdm845.h  |  24 +++
 5 files changed, 283 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,gpucc.txt
 create mode 100644 drivers/clk/qcom/gpucc-sdm845.c
 create mode 100644 include/dt-bindings/clock/qcom,gpucc-sdm845.h

--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



[PATCH v4 2/2] clk: qcom: Add graphics clock controller driver for SDM845

2018-11-24 Thread Taniya Das
From: Amit Nischal 

Add support for the graphics clock controller found on SDM845
based devices. This would allow graphics drivers to probe and
control their clocks.

Signed-off-by: Amit Nischal 
Signed-off-by: Taniya Das 
---
 drivers/clk/qcom/Kconfig|   9 ++
 drivers/clk/qcom/Makefile   |   1 +
 drivers/clk/qcom/gpucc-sdm845.c | 231 
 3 files changed, 241 insertions(+)
 create mode 100644 drivers/clk/qcom/gpucc-sdm845.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index a611531..6f3e466 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -273,6 +273,15 @@ config SDM_GCC_845
  Say Y if you want to use peripheral devices such as UART, SPI,
  i2C, USB, UFS, SDDC, PCIe, etc.

+config SDM_GPUCC_845
+   tristate "SDM845 Graphics Clock Controller"
+   depends on COMMON_CLK_QCOM
+   select SDM_GCC_845
+   help
+ Support for the graphics clock controller on SDM845 devices.
+ Say Y if you want to support graphics controller devices and
+ functionality such as 3D graphics.
+
 config SDM_VIDEOCC_845
tristate "SDM845 Video Clock Controller"
depends on COMMON_CLK_QCOM
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 981882e..6ed2827 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o
 obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o
 obj-$(CONFIG_SDM_GCC_660) += gcc-sdm660.o
 obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o
+obj-$(CONFIG_SDM_GPUCC_845) += gpucc-sdm845.o
 obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o
 obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o
 obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o
diff --git a/drivers/clk/qcom/gpucc-sdm845.c b/drivers/clk/qcom/gpucc-sdm845.c
new file mode 100644
index 000..11222f4
--- /dev/null
+++ b/drivers/clk/qcom/gpucc-sdm845.c
@@ -0,0 +1,231 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "common.h"
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "gdsc.h"
+
+#define CX_GMU_CBCR_SLEEP_MASK 0xf
+#define CX_GMU_CBCR_SLEEP_SHIFT4
+#define CX_GMU_CBCR_WAKE_MASK  0xf
+#define CX_GMU_CBCR_WAKE_SHIFT 8
+#define CLK_DIS_WAIT_SHIFT 12
+#define CLK_DIS_WAIT_MASK  (0xf << CLK_DIS_WAIT_SHIFT)
+
+enum {
+   P_BI_TCXO,
+   P_CORE_BI_PLL_TEST_SE,
+   P_GPLL0_OUT_MAIN,
+   P_GPLL0_OUT_MAIN_DIV,
+   P_GPU_CC_PLL1_OUT_EVEN,
+   P_GPU_CC_PLL1_OUT_MAIN,
+   P_GPU_CC_PLL1_OUT_ODD,
+};
+
+static const struct parent_map gpu_cc_parent_map_0[] = {
+   { P_BI_TCXO, 0 },
+   { P_GPU_CC_PLL1_OUT_MAIN, 3 },
+   { P_GPLL0_OUT_MAIN, 5 },
+   { P_GPLL0_OUT_MAIN_DIV, 6 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gpu_cc_parent_names_0[] = {
+   "bi_tcxo",
+   "gpu_cc_pll1",
+   "gcc_gpu_gpll0_clk_src",
+   "gcc_gpu_gpll0_div_clk_src",
+   "core_bi_pll_test_se",
+};
+
+static const struct alpha_pll_config gpu_cc_pll1_config = {
+   .l = 0x1a,
+   .alpha = 0xaab,
+};
+
+static struct clk_alpha_pll gpu_cc_pll1 = {
+   .offset = 0x100,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "gpu_cc_pll1",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = &clk_alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
+   F(1920, P_BI_TCXO, 1, 0, 0),
+   F(2, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0),
+   F(5, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0),
+   { }
+};
+
+static struct clk_rcg2 gpu_cc_gmu_clk_src = {
+   .cmd_rcgr = 0x1120,
+   .mnd_width = 0,
+   .hid_width = 5,
+   .parent_map = gpu_cc_parent_map_0,
+   .freq_tbl = ftbl_gpu_cc_gmu_clk_src,
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "gpu_cc_gmu_clk_src",
+   .parent_names = gpu_cc_parent_names_0,
+   .num_parents = 6,
+   .ops = &clk_rcg2_shared_ops,
+   },
+};
+
+static struct clk_branch gpu_cc_cx_gmu_clk = {
+   .halt_reg = 0x1098,
+   .halt_check = BRANCH_HALT,
+   .clkr = {
+   .enable_reg = 0x1098,
+   .enable_mask = BIT(0),
+   .hw.in

[PATCH v4 1/2] dt-bindings: clock: Introduce QCOM Graphics clock bindings

2018-11-24 Thread Taniya Das
From: Amit Nischal 

Add device tree bindings for graphics clock controller for
Qualcomm Technology Inc's SDM845 SoCs.

Signed-off-by: Amit Nischal 
---
 .../devicetree/bindings/clock/qcom,gpucc.txt   | 18 
 include/dt-bindings/clock/qcom,gpucc-sdm845.h  | 24 ++
 2 files changed, 42 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,gpucc.txt
 create mode 100644 include/dt-bindings/clock/qcom,gpucc-sdm845.h

diff --git a/Documentation/devicetree/bindings/clock/qcom,gpucc.txt 
b/Documentation/devicetree/bindings/clock/qcom,gpucc.txt
new file mode 100644
index 000..93752db
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,gpucc.txt
@@ -0,0 +1,18 @@
+Qualcomm Graphics Clock & Reset Controller Binding
+--
+
+Required properties :
+- compatible : shall contain "qcom,sdm845-gpucc".
+- reg : shall contain base register location and length.
+- #clock-cells : from common clock binding, shall contain 1.
+- #reset-cells : from common reset binding, shall contain 1.
+- #power-domain-cells : from generic power domain binding, shall contain 1.
+
+Example:
+   gpucc: clock-controller@509 {
+   compatible = "qcom,sdm845-gpucc";
+   reg = <0x509 0x9000>;
+   #clock-cells = <1>;
+   #reset-cells = <1>;
+   #power-domain-cells = <1>;
+   };
diff --git a/include/dt-bindings/clock/qcom,gpucc-sdm845.h 
b/include/dt-bindings/clock/qcom,gpucc-sdm845.h
new file mode 100644
index 000..9690d90
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,gpucc-sdm845.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_SDM_GPU_CC_SDM845_H
+#define _DT_BINDINGS_CLK_SDM_GPU_CC_SDM845_H
+
+/* GPU_CC clock registers */
+#define GPU_CC_CX_GMU_CLK  0
+#define GPU_CC_CXO_CLK 1
+#define GPU_CC_GMU_CLK_SRC 2
+#define GPU_CC_PLL13
+
+/* GPU_CC Resets */
+#define GPUCC_GPU_CC_CX_BCR0
+#define GPUCC_GPU_CC_GMU_BCR   1
+#define GPUCC_GPU_CC_XO_BCR2
+
+/* GPU_CC GDSCRs */
+#define GPU_CX_GDSC0
+#define GPU_GX_GDSC1
+
+#endif
--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



[PATCH v10 1/2] dt-bindings: cpufreq: Introduce QCOM CPUFREQ Firmware bindings

2018-11-21 Thread Taniya Das
Add QCOM cpufreq firmware device bindings for Qualcomm Technology Inc's
SoCs. This is required for managing the cpu frequency transitions which are
controlled by the hardware engine.

Signed-off-by: Taniya Das 
---
 .../bindings/cpufreq/cpufreq-qcom-hw.txt   | 172 +
 1 file changed, 172 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt

diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt 
b/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt
new file mode 100644
index 000..90e396b
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt
@@ -0,0 +1,172 @@
+Qualcomm Technologies, Inc. CPUFREQ Bindings
+
+CPUFREQ HW is a hardware engine used by some Qualcomm Technologies, Inc. (QTI)
+SoCs to manage frequency in hardware. It is capable of controlling frequency
+for multiple clusters.
+
+Properties:
+- compatible
+   Usage:  required
+   Value type: 
+   Definition: must be "qcom,cpufreq-hw".
+
+- clocks
+   Usage:  required
+   Value type:  From common clock binding.
+   Definition: clock handle for XO clock and GPLL0 clock.
+
+- clock-names
+   Usage:  required
+   Value type:  From common clock binding.
+   Definition: must be "xo", "cpu_clk".
+
+- reg
+   Usage:  required
+   Value type: 
+   Definition: Addresses and sizes for the memory of the HW bases in
+   each frequency domain.
+- reg-names
+   Usage:  Optional
+   Value type: 
+   Definition: Frequency domain name i.e.
+   "freq-domain0", "freq-domain1".
+
+- freq-domain-cells:
+   Usage:  required.
+   Definition: Number of cells in a freqency domain specifier.
+
+* Property qcom,freq-domain
+Devices supporting freq-domain must set their "qcom,freq-domain" property with
+phandle to a cpufreq_hw followed by the Domain ID(0/1) in the CPU DT node.
+
+
+Example:
+
+Example 1: Dual-cluster, Quad-core per cluster. CPUs within a cluster switch
+DCVS state together.
+
+/ {
+   cpus {
+   #address-cells = <2>;
+   #size-cells = <0>;
+
+   CPU0: cpu@0 {
+   device_type = "cpu";
+   compatible = "qcom,kryo385";
+   reg = <0x0 0x0>;
+   enable-method = "psci";
+   next-level-cache = <&L2_0>;
+   qcom,freq-domain = <&cpufreq_hw 0>;
+   L2_0: l2-cache {
+   compatible = "cache";
+   next-level-cache = <&L3_0>;
+   L3_0: l3-cache {
+ compatible = "cache";
+   };
+   };
+   };
+
+   CPU1: cpu@100 {
+   device_type = "cpu";
+   compatible = "qcom,kryo385";
+   reg = <0x0 0x100>;
+   enable-method = "psci";
+   next-level-cache = <&L2_100>;
+   qcom,freq-domain = <&cpufreq_hw 0>;
+   L2_100: l2-cache {
+   compatible = "cache";
+   next-level-cache = <&L3_0>;
+   };
+   };
+
+   CPU2: cpu@200 {
+   device_type = "cpu";
+   compatible = "qcom,kryo385";
+   reg = <0x0 0x200>;
+   enable-method = "psci";
+   next-level-cache = <&L2_200>;
+   qcom,freq-domain = <&cpufreq_hw 0>;
+   L2_200: l2-cache {
+   compatible = "cache";
+   next-level-cache = <&L3_0>;
+   };
+   };
+
+   CPU3: cpu@300 {
+   device_type = "cpu";
+   compatible = "qcom,kryo385";
+   reg = <0x0 0x300>;
+   enable-method = "psci";
+   next-level-cache = <&L2_300>;
+   qcom,freq-domain = <&cpufreq_hw 0>;
+   L2_300: l2-cache {
+   compatible = "cache";
+   next-level-cache = <&L3_0>;
+   };
+   };
+
+   CPU4: cpu@400

[PATCH v10 2/2] cpufreq: qcom-hw: Add support for QCOM cpufreq HW driver

2018-11-21 Thread Taniya Das
The CPUfreq HW present in some QCOM chipsets offloads the steps necessary
for changing the frequency of CPUs. The driver implements the cpufreq
driver interface for this hardware engine.

Signed-off-by: Saravana Kannan 
Signed-off-by: Taniya Das 
---
 drivers/cpufreq/Kconfig.arm   |  11 ++
 drivers/cpufreq/Makefile  |   1 +
 drivers/cpufreq/qcom-cpufreq-hw.c | 346 ++
 3 files changed, 358 insertions(+)
 create mode 100644 drivers/cpufreq/qcom-cpufreq-hw.c

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 4e1131e..688f102 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -114,6 +114,17 @@ config ARM_QCOM_CPUFREQ_KRYO

  If in doubt, say N.

+config ARM_QCOM_CPUFREQ_HW
+   tristate "QCOM CPUFreq HW driver"
+   depends on ARCH_QCOM || COMPILE_TEST
+   help
+ Support for the CPUFreq HW driver.
+ Some QCOM 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_S3C_CPUFREQ
bool
help
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index d5ee456..789b2e0 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -62,6 +62,7 @@ obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)   += omap-cpufreq.o
 obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)   += pxa2xx-cpufreq.o
 obj-$(CONFIG_PXA3xx)   += pxa3xx-cpufreq.o
 obj-$(CONFIG_ARM_QCOM_CPUFREQ_KRYO)+= qcom-cpufreq-kryo.o
+obj-$(CONFIG_ARM_QCOM_CPUFREQ_HW)  += qcom-cpufreq-hw.o
 obj-$(CONFIG_ARM_S3C2410_CPUFREQ)  += s3c2410-cpufreq.o
 obj-$(CONFIG_ARM_S3C2412_CPUFREQ)  += s3c2412-cpufreq.o
 obj-$(CONFIG_ARM_S3C2416_CPUFREQ)  += s3c2416-cpufreq.o
diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c 
b/drivers/cpufreq/qcom-cpufreq-hw.c
new file mode 100644
index 000..6390e85
--- /dev/null
+++ b/drivers/cpufreq/qcom-cpufreq-hw.c
@@ -0,0 +1,346 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define LUT_MAX_ENTRIES40U
+#define CORE_COUNT_VAL(val)(((val) & (GENMASK(18, 16))) >> 16)
+#define LUT_ROW_SIZE   32
+#define CLK_HW_DIV 2
+
+/* Register offsets */
+#define REG_ENABLE 0x0
+#define REG_LUT_TABLE  0x110
+#define REG_PERF_STATE 0x920
+
+struct cpufreq_qcom {
+   struct cpufreq_frequency_table *table;
+   void __iomem *perf_base;
+   cpumask_t related_cpus;
+   unsigned int max_cores;
+   unsigned long xo_rate;
+   unsigned long cpu_hw_rate;
+};
+
+static struct cpufreq_qcom *qcom_freq_domain_map[NR_CPUS];
+
+static int
+qcom_cpufreq_hw_target_index(struct cpufreq_policy *policy,
+unsigned int index)
+{
+   struct cpufreq_qcom *c = policy->driver_data;
+
+   writel_relaxed(index, c->perf_base);
+
+   return 0;
+}
+
+static unsigned int qcom_cpufreq_hw_get(unsigned int cpu)
+{
+   struct cpufreq_qcom *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->perf_base);
+   index = min(index, LUT_MAX_ENTRIES - 1);
+
+   return policy->freq_table[index].frequency;
+}
+
+static unsigned int
+qcom_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
+   unsigned int target_freq)
+{
+   struct cpufreq_qcom *c = policy->driver_data;
+   int index;
+
+   index = policy->cached_resolved_idx;
+   if (index < 0)
+   return 0;
+
+   writel_relaxed(index, c->perf_base);
+
+   return policy->freq_table[index].frequency;
+}
+
+static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
+{
+   struct cpufreq_qcom *c;
+
+   c = qcom_freq_domain_map[policy->cpu];
+   if (!c) {
+   pr_err("No scaling support for CPU%d\n", policy->cpu);
+   return -ENODEV;
+   }
+
+   cpumask_copy(policy->cpus, &c->related_cpus);
+
+   policy->fast_switch_possible = true;
+   policy->freq_table = c->table;
+   policy->driver_data = c;
+
+   return 0;
+}
+
+static struct freq_attr *qcom_cpufreq_hw_attr[] = {
+   &cpufreq_freq_attr_scaling_available_freqs,
+   &cpufreq_freq_attr_scaling_boost_freqs,
+   NULL
+};
+
+static struct cpufreq_driver cpufreq_qcom_hw_driver = {
+   .flags  = CPUFREQ_STICK

[PATCH v10 0/2] cpufreq: qcom-hw: Add support for QCOM cpufreq HW driver

2018-11-21 Thread Taniya Das
 [v10]
  * Update Documentation binding for cpufreq node.
  * Make the driver 'tristate' instead of 'bool' and update code.
  * Update the clock name to reflect the hardware name.
  * Remove support for varying offset.

 [v9]
  * Update the Documentation binding for freq-domain-cells & cpufreq node.
  * Address comments in Kconfig.arm & Makefile.
  * Remove include file & MODULE_DESCRIPTION not required.
  * Fix the code for 'of_node_put(cpu_np)'.

 [v8]
   * Address comments to update code to take cpufreq_hw phandle and index from
 the CPU nodes.
   * Updated the Documentation for the above change in DT.
   * Updated logic for assigning 'qcom_freq_domain_map' for related CPUs.
   * Clock input to the HW block is taken from DT which has been updated in
 code and Device tree documentation.

 [v7]
   * Updated the logic to check for related CPUs.

 [v6]
   * Renamed match table 'qcom_cpufreq_hw_match'.
   * Renamed 'qcom_read_lut' to 'qcom_cpufreq_hw_read_lut'.
   * Updated the logic to check for related CPUs at the beginning of the
 'qcom_cpu_resources_init'.
   * Use devm_ioremap_resource instead of devm_ioremap.
   * Update the use of of_node_put to handle error conditions.
   * Use policy->cached_resolved_idx in fast switch callback.
   * Keep precalculated offsets 'reg_bases'.
   * XO clock is taken from Device tree.
   * Update documentation binding for clocks/clock-names.
   * Minor comments in Kconfig.arm.
   * Comments to move dev_info to dev_dbg.

 [v5]
   * Remove mapping different register regions of perf/lut/enable,
 instead map the entire HW region.
   * Add reg_offset/cpufreq_qcom_std_offsets to be supplied as device data.
   * Check of src == 0 during lut read.
   * Add of_node_put(cpu_np) in qcom_get_related_cpus
   * Update the qcom_cpu_resources_init for register offset data,
 and cleanup the related cpus to keep a single copy of CPUfreq.
   * Replace FW with HW, update Kconfig, rename filename qcom-cpufreq-hw.c
   * Update the documentation binding to reflect the changes of mapping the
   * entire HW region.

 [v4]
   * Fixed console messages as per comments.
   * Return error from qcom_resources_init()
 in the cases where failed to get frequency domain.
   * Rename cpu_dev to cpu_np in qcom_resources_init,
 qcom_get_related_cpus(). Also use temp variable freq_np in
 qcom_get_related_cpus().
   * Update qcom_cpufreq_fw_get() to use the policy data to incoporate
 the hotplug use case.
   * Update code to use of fast_switching.
   * Check for !c->max_cores instead of cpumask_empty in
 qcom_get_related_cpus().
   * Update the logic of assigning 'c' to qcom_freq_domain_map[cpu].

 [v3]
   * Remove index check from 'qcom_cpufreq_fw_target_index'.
   * Update the Documentation binding to add the platform specific properties in
 the CPU nodes, node name "qcom,freq-domain".
   * Update return value to '0' from -ENODEV from 'qcom_cpufreq_fw_get'.
   * Update the logic for boost frequency to use local variables instead of
 cpufreq driver data in 'qcom_read_lut'.
   * Update the logic in 'qcom_get_related_cpus' to find the related cpus.
   * Update the reg-names to remove "_base" and also update the binding with the
 description of these registers.
   * Update the logic in 'qcom_resources_init' to address the new device tree
 notation of handling the frequency domain phandles.

 [v2]
   * Fixed the alignment issues in "qcom_cpufreq_fw_target_index" for dev_err 
and
 also for "qcom_cpu_resources_init".
   * Removed ret = 0 from qcom_get_related_cpus and added to check for
     cpu_mask_empty to return -ENOENT.
   * Fixes qcom_cpu_resources_init function
   * Remove initialization of 'index'
   * Check for valid 'c'
   * Removed initialization of 'prev_cc' from 'qcom_read_lut'.

Taniya Das (2):
  dt-bindings: cpufreq: Introduce QCOM CPUFREQ Firmware bindings
  cpufreq: qcom-hw: Add support for QCOM cpufreq HW driver

 .../bindings/cpufreq/cpufreq-qcom-hw.txt   | 172 ++
 drivers/cpufreq/Kconfig.arm|  11 +
 drivers/cpufreq/Makefile   |   1 +
 drivers/cpufreq/qcom-cpufreq-hw.c  | 346 +
 4 files changed, 530 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt
 create mode 100644 drivers/cpufreq/qcom-cpufreq-hw.c

--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



Re: [PATCH v9 2/2] clk: qcom: Add lpass clock controller driver for SDM845

2018-11-21 Thread Taniya Das

Hello Stephen,

On 11/22/2018 12:37 AM, Stephen Boyd wrote:

Quoting Taniya Das (2018-11-09 17:44:16)

diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index f133b7f..ba8ff99 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -3153,6 +3153,34 @@ enum {
 },
  };

+static struct clk_branch gcc_lpass_q6_axi_clk = {
+   .halt_reg = 0x47000,
+   .halt_check = BRANCH_HALT,
+   .clkr = {
+   .enable_reg = 0x47000,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_lpass_q6_axi_clk",
+   .flags = CLK_IS_CRITICAL,
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
+static struct clk_branch gcc_lpass_sway_clk = {
+   .halt_reg = 0x47008,
+   .halt_check = BRANCH_HALT,
+   .clkr = {
+   .enable_reg = 0x47008,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_lpass_sway_clk",
+   .flags = CLK_IS_CRITICAL,
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
  static struct gdsc pcie_0_gdsc = {
 .gdscr = 0x6b004,
 .pd = {
@@ -3453,6 +3481,8 @@ enum {
 [GCC_QSPI_CORE_CLK_SRC] = &gcc_qspi_core_clk_src.clkr,
 [GCC_QSPI_CORE_CLK] = &gcc_qspi_core_clk.clkr,
 [GCC_QSPI_CNOC_PERIPH_AHB_CLK] = &gcc_qspi_cnoc_periph_ahb_clk.clkr,
+   [GCC_LPASS_Q6_AXI_CLK] = &gcc_lpass_q6_axi_clk.clkr,
+   [GCC_LPASS_SWAY_CLK] = &gcc_lpass_sway_clk.clkr,


Sigh, more coordination with sdm845 mtp problems here due to the
clks being protected by firmware. I guess I can just merge this and the
mtp dts bits will land in Andy's tree during the same merge window? Or I
may need to take the dts bits for this into clk tree so that the broken
time is only between two commits.


  };

  static const struct qcom_reset_map gcc_sdm845_resets[] = {
diff --git a/drivers/clk/qcom/lpasscc-sdm845.c 
b/drivers/clk/qcom/lpasscc-sdm845.c
new file mode 100644
index 000..2ef7f2a
--- /dev/null
+++ b/drivers/clk/qcom/lpasscc-sdm845.c
@@ -0,0 +1,192 @@

[...]

+
+static const struct of_device_id lpass_cc_sdm845_match_table[] = {
+   { .compatible = "qcom,sdm845-lpasscc" },
+   { }
+};
+MODULE_DEVICE_TABLE(of, lpass_cc_sdm845_match_table);


Move this down to the before the driver structure please.



Would do it in the next patch.


+
+static int lpass_cc_sdm845_probe(struct platform_device *pdev)
+{
+   const struct qcom_cc_desc *desc;
+   int ret;
+
+   lpass_regmap_config.name = "cc";
+   desc = &lpass_cc_sdm845_desc;
+
+   ret = lpass_clocks_sdm845_probe(pdev, 0, desc);
+   if (ret)
+   return ret;
+
+   lpass_regmap_config.name = "qdsp6ss";
+   desc = &lpass_qdsp6ss_sdm845_desc;
+
+   return lpass_clocks_sdm845_probe(pdev, 1, desc);
+}
+
+static struct platform_driver lpass_cc_sdm845_driver = {
+   .probe  = lpass_cc_sdm845_probe,
+   .driver = {
+   .name   = "sdm845-lpasscc",
+   .of_match_table = lpass_cc_sdm845_match_table,
+   },
+};
+
+static int __init lpass_cc_sdm845_init(void)
+{
+   return platform_driver_register(&lpass_cc_sdm845_driver);
+}
+subsys_initcall(lpass_cc_sdm845_init);
+
+static void __exit lpass_cc_sdm845_exit(void)
+{
+   platform_driver_unregister(&lpass_cc_sdm845_driver);
+}
+module_exit(lpass_cc_sdm845_exit);
+
+MODULE_LICENSE("GPL v2");


MODULE_DESCRIPTION?


Would add it in the next patch.

--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


Re: [PATCH v9 1/2] dt-bindings: clock: Introduce QCOM LPASS clock bindings

2018-11-21 Thread Taniya Das

Hello Rob,

On 11/13/2018 5:49 AM, Rob Herring wrote:

On Sat, Nov 10, 2018 at 07:14:15AM +0530, Taniya Das wrote:

Add device tree bindings for Low Power Audio subsystem clock controller for
Qualcomm Technology Inc's SDM845 SoCs.

Signed-off-by: Taniya Das 
---
  .../devicetree/bindings/clock/qcom,gcc.txt | 16 +


Seems like a separate change?



Sure, would spilt it in the next patch.


  .../devicetree/bindings/clock/qcom,lpasscc.txt | 26 ++
  include/dt-bindings/clock/qcom,gcc-sdm845.h|  2 ++
  include/dt-bindings/clock/qcom,lpass-sdm845.h  | 16 +
  4 files changed, 60 insertions(+)
  create mode 100644 Documentation/devicetree/bindings/clock/qcom,lpasscc.txt
  create mode 100644 include/dt-bindings/clock/qcom,lpass-sdm845.h

diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.txt 
b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
index 52d9345..8661c3c 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt
+++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
@@ -35,6 +35,8 @@ be part of GCC and hence the TSENS properties can also be
  part of the GCC/clock-controller node.
  For more details on the TSENS properties please refer
  Documentation/devicetree/bindings/thermal/qcom-tsens.txt
+- protected-clocks : Protected clock specifier list as per common clock
+ binding.

  Example:
clock-controller@90 {
@@ -55,3 +57,17 @@ Example of GCC with TSENS properties:
#reset-cells = <1>;
#thermal-sensor-cells = <1>;
};
+
+Example of GCC with protected-clocks properties:
+   clock-controller@10 {
+   compatible = "qcom,gcc-sdm845";
+   reg = <0x10 0x1f>;
+   #clock-cells = <1>;
+   #reset-cells = <1>;
+   #power-domain-cells = <1>;
+   protected-clocks = ,
+  ,
+  ,
+  ,
+  ;
+   };
diff --git a/Documentation/devicetree/bindings/clock/qcom,lpasscc.txt 
b/Documentation/devicetree/bindings/clock/qcom,lpasscc.txt
new file mode 100644
index 000..b9e9787
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,lpasscc.txt
@@ -0,0 +1,26 @@
+Qualcomm LPASS Clock Controller Binding
+---
+
+Required properties :
+- compatible   : shall contain "qcom,sdm845-lpasscc"
+- #clock-cells : from common clock binding, shall contain 1.
+- reg  : shall contain base register address and size,
+ in the order
+   Index-0 maps to LPASS_CC register region
+   Index-1 maps to LPASS_QDSP6SS register region


No input clocks?



There are no input clocks required.


+
+Optional properties :
+- reg-names: register names of LPASS domain
+"cc", "qdsp6ss".
+
+Example:
+
+The below node has to be defined in the cases where the LPASS peripheral loader
+would bring the subsystem out of reset.
+
+   lpasscc: clock-controller@17014000 {
+   compatible = "qcom,sdm845-lpasscc";
+   reg = <0x17014000 0x1f004>, <0x1730 0x200>;
+   reg-names = "cc", "qdsp6ss";
+   #clock-cells = <1>;
+   };
diff --git a/include/dt-bindings/clock/qcom,gcc-sdm845.h 
b/include/dt-bindings/clock/qcom,gcc-sdm845.h
index b8eae5a..968fa65 100644
--- a/include/dt-bindings/clock/qcom,gcc-sdm845.h
+++ b/include/dt-bindings/clock/qcom,gcc-sdm845.h
@@ -197,6 +197,8 @@
  #define GCC_QSPI_CORE_CLK_SRC 187
  #define GCC_QSPI_CORE_CLK 188
  #define GCC_QSPI_CNOC_PERIPH_AHB_CLK  189
+#define GCC_LPASS_Q6_AXI_CLK   190
+#define GCC_LPASS_SWAY_CLK 191

  /* GCC Resets */
  #define GCC_MMSS_BCR  0
diff --git a/include/dt-bindings/clock/qcom,lpass-sdm845.h 
b/include/dt-bindings/clock/qcom,lpass-sdm845.h
new file mode 100644
index 000..015968e
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,lpass-sdm845.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_SDM_LPASS_SDM845_H
+#define _DT_BINDINGS_CLK_SDM_LPASS_SDM845_H
+
+#define LPASS_AUDIO_WRAPPER_AON_CLK0
+#define LPASS_Q6SS_AHBM_AON_CLK1
+#define LPASS_Q6SS_AHBS_AON_CLK2
+#define LPASS_QDSP6SS_XO_CLK   3
+#define LPASS_QDSP6SS_SLEEP_CLK4
+#define LPASS_QDSP6SS_COR

[PATCH v10 2/3] dt-bindings: clock: Introduce QCOM LPASS clock bindings

2018-11-21 Thread Taniya Das
Add device tree bindings for Low Power Audio subsystem clock controller for
Qualcomm Technology Inc's SDM845 SoCs.

Signed-off-by: Taniya Das 
---
 .../devicetree/bindings/clock/qcom,gcc.txt |  4 +++-
 .../devicetree/bindings/clock/qcom,lpasscc.txt | 26 ++
 include/dt-bindings/clock/qcom,gcc-sdm845.h|  2 ++
 include/dt-bindings/clock/qcom,lpass-sdm845.h  | 15 +
 4 files changed, 46 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,lpasscc.txt
 create mode 100644 include/dt-bindings/clock/qcom,lpass-sdm845.h

diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.txt 
b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
index 5e37de9..8661c3c 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt
+++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
@@ -67,5 +67,7 @@ Example of GCC with protected-clocks properties:
#power-domain-cells = <1>;
protected-clocks = ,
   ,
-  ;
+  ,
+  ,
+  ;
};
diff --git a/Documentation/devicetree/bindings/clock/qcom,lpasscc.txt 
b/Documentation/devicetree/bindings/clock/qcom,lpasscc.txt
new file mode 100644
index 000..b9e9787
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,lpasscc.txt
@@ -0,0 +1,26 @@
+Qualcomm LPASS Clock Controller Binding
+---
+
+Required properties :
+- compatible   : shall contain "qcom,sdm845-lpasscc"
+- #clock-cells : from common clock binding, shall contain 1.
+- reg  : shall contain base register address and size,
+ in the order
+   Index-0 maps to LPASS_CC register region
+   Index-1 maps to LPASS_QDSP6SS register region
+
+Optional properties :
+- reg-names: register names of LPASS domain
+"cc", "qdsp6ss".
+
+Example:
+
+The below node has to be defined in the cases where the LPASS peripheral loader
+would bring the subsystem out of reset.
+
+   lpasscc: clock-controller@17014000 {
+   compatible = "qcom,sdm845-lpasscc";
+   reg = <0x17014000 0x1f004>, <0x1730 0x200>;
+   reg-names = "cc", "qdsp6ss";
+   #clock-cells = <1>;
+   };
diff --git a/include/dt-bindings/clock/qcom,gcc-sdm845.h 
b/include/dt-bindings/clock/qcom,gcc-sdm845.h
index b8eae5a..968fa65 100644
--- a/include/dt-bindings/clock/qcom,gcc-sdm845.h
+++ b/include/dt-bindings/clock/qcom,gcc-sdm845.h
@@ -197,6 +197,8 @@
 #define GCC_QSPI_CORE_CLK_SRC  187
 #define GCC_QSPI_CORE_CLK  188
 #define GCC_QSPI_CNOC_PERIPH_AHB_CLK   189
+#define GCC_LPASS_Q6_AXI_CLK   190
+#define GCC_LPASS_SWAY_CLK 191

 /* GCC Resets */
 #define GCC_MMSS_BCR   0
diff --git a/include/dt-bindings/clock/qcom,lpass-sdm845.h 
b/include/dt-bindings/clock/qcom,lpass-sdm845.h
new file mode 100644
index 000..6590508
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,lpass-sdm845.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_SDM_LPASS_SDM845_H
+#define _DT_BINDINGS_CLK_SDM_LPASS_SDM845_H
+
+#define LPASS_Q6SS_AHBM_AON_CLK0
+#define LPASS_Q6SS_AHBS_AON_CLK1
+#define LPASS_QDSP6SS_XO_CLK   2
+#define LPASS_QDSP6SS_SLEEP_CLK3
+#define LPASS_QDSP6SS_CORE_CLK 4
+
+#endif
--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



[PATCH v10 0/3] Add support for LPASS clock controller for SDM845

2018-11-21 Thread Taniya Das
 [v10]
  * Separate change to add  protected-clocks list in GCC binding.
  * Remove the clock support 'LPASS_AUDIO_WRAPPER_AON_CLK' as it is always ON
  clock.
  * Add few comments for module description and match table.

 [v9]
  * Update GCC documentation binding with the protected-clocks list.
  * Update the GCC code to add the GCC lpass clocks.
  * This depends on the acceptance of
  https://lore.kernel.org/lkml/20181105194011.43770-1-swb...@chromium.org/

 [v8]
  * Add CLK_IS_CRITICAL for GCC lpass clocks for lpass clocks access to go
  through always.

 [v7]
  * Cleanup header file inclusions.
  * Move the comments along with the flags.
  * Update the commit with details for CLK_IGNORE_UNUSED.

 [v6]
  * Update the logic to register the lpass clocks when the device tree property
   is not present.
  * Add the CLK_IGNORE_UNUSED flag for the lpass clocks to not gate the clocks
   at late_init.

 [v5]
  * Address the comments in device tree binding to update the reg-names,
update the unit address in lpass clock node example and also
add reg property for the gcc clock node.
  * Update the lpass driver to take care of the reg-names.

 [v4]
  * Update the description in GCC Documentation binding for
  'qcom,lpass-protected'.
  * Remove 'qcom,lpass-protected' from LPASS Documentation binding.
  * Update KConfig to use Low Power Audio Subsystem.
  * Add module_exit() and also update return value for
devm_ioremap_resource failure.

 [v3]
  * Add a device tree property to identify lpass protected GCC clocks.
  * Update the GCC driver code to register the lpass clocks when the flag is
   defined.
  * Add comment for clocks using the BRANCH_HALT_SKIP flag.
  * Use platform APIs instead of of_address_to_resource.
  * Replace devm_ioremap with devm_ioremap_resource.
  * Use fixed index for 'lpass_cc' & 'lpass_qdsp6ss' in probe.

 [v2]
  * Make gcc_lpass_sway_clk static.
  * Remove using child nodes and use reg-names to differentiate various
domains of LPASS CC.

Add support for the lpass clock controller found on SDM845 based devices.
This would allow lpass peripheral loader drivers to control the clocks to
bring the subsystem out of reset.

Taniya Das (3):
  dt-bindings: clock: Update GCC bindings for protected-clocks
  dt-bindings: clock: Introduce QCOM LPASS clock bindings
  clk: qcom: Add lpass clock controller driver for SDM845

 .../devicetree/bindings/clock/qcom,gcc.txt |  16 ++
 .../devicetree/bindings/clock/qcom,lpasscc.txt |  26 +++
 drivers/clk/qcom/Kconfig   |   9 ++
 drivers/clk/qcom/Makefile  |   1 +
 drivers/clk/qcom/gcc-sdm845.c  |  30 
 drivers/clk/qcom/lpasscc-sdm845.c  | 179 +
 include/dt-bindings/clock/qcom,gcc-sdm845.h|   2 +
 include/dt-bindings/clock/qcom,lpass-sdm845.h  |  15 ++
 8 files changed, 278 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,lpasscc.txt
 create mode 100644 drivers/clk/qcom/lpasscc-sdm845.c
 create mode 100644 include/dt-bindings/clock/qcom,lpass-sdm845.h

--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



[PATCH v10 1/3] dt-bindings: clock: Update GCC bindings for protected-clocks

2018-11-21 Thread Taniya Das
Add protected-clocks list which could used to specify the clocks to be
bypassed on certain devices.

Signed-off-by: Taniya Das 
---
 Documentation/devicetree/bindings/clock/qcom,gcc.txt | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.txt 
b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
index 52d9345..5e37de9 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt
+++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
@@ -35,6 +35,8 @@ be part of GCC and hence the TSENS properties can also be
 part of the GCC/clock-controller node.
 For more details on the TSENS properties please refer
 Documentation/devicetree/bindings/thermal/qcom-tsens.txt
+- protected-clocks : Protected clock specifier list as per common clock
+ binding.

 Example:
clock-controller@90 {
@@ -55,3 +57,15 @@ Example of GCC with TSENS properties:
#reset-cells = <1>;
#thermal-sensor-cells = <1>;
};
+
+Example of GCC with protected-clocks properties:
+   clock-controller@10 {
+   compatible = "qcom,gcc-sdm845";
+   reg = <0x10 0x1f>;
+   #clock-cells = <1>;
+   #reset-cells = <1>;
+   #power-domain-cells = <1>;
+   protected-clocks = ,
+  ,
+  ;
+   };
--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



[PATCH v10 3/3] clk: qcom: Add lpass clock controller driver for SDM845

2018-11-21 Thread Taniya Das
Add support for the lpass clock controller found on SDM845 based devices.
This would allow lpass peripheral loader drivers to control the clocks to
bring the subsystem out of reset.
LPASS clocks present on the global clock controller would be registered
with the clock framework based on the protected-clock flag. Also do not
gate these clocks if they are left unused, as the lpass clocks require
the global clock controller lpass clocks to be enabled before they are
accessed. Mark the GCC lpass clocks as CRITICAL, for the LPASS clock
access.

Signed-off-by: Taniya Das 
---
 drivers/clk/qcom/Kconfig  |   9 ++
 drivers/clk/qcom/Makefile |   1 +
 drivers/clk/qcom/gcc-sdm845.c |  30 +++
 drivers/clk/qcom/lpasscc-sdm845.c | 179 ++
 4 files changed, 219 insertions(+)
 create mode 100644 drivers/clk/qcom/lpasscc-sdm845.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index a611531..23adc4c 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -293,6 +293,15 @@ config SDM_DISPCC_845
  Say Y if you want to support display devices and functionality such as
  splash screen.

+config SDM_LPASSCC_845
+   tristate "SDM845 Low Power Audio Subsystem (LPAAS) Clock Controller"
+   depends on COMMON_CLK_QCOM
+   select SDM_GCC_845
+   help
+ Support for the LPASS clock controller on SDM845 devices.
+ Say Y if you want to use the LPASS branch clocks of the LPASS clock
+ controller to reset the LPASS subsystem.
+
 config SPMI_PMIC_CLKDIV
tristate "SPMI PMIC clkdiv Support"
depends on (COMMON_CLK_QCOM && SPMI) || COMPILE_TEST
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 981882e..3d530b1 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o
 obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o
 obj-$(CONFIG_SDM_GCC_660) += gcc-sdm660.o
 obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o
+obj-$(CONFIG_SDM_LPASSCC_845) += lpasscc-sdm845.o
 obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o
 obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o
 obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o
diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index f133b7f..ba8ff99 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -3153,6 +3153,34 @@ enum {
},
 };

+static struct clk_branch gcc_lpass_q6_axi_clk = {
+   .halt_reg = 0x47000,
+   .halt_check = BRANCH_HALT,
+   .clkr = {
+   .enable_reg = 0x47000,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_lpass_q6_axi_clk",
+   .flags = CLK_IS_CRITICAL,
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
+static struct clk_branch gcc_lpass_sway_clk = {
+   .halt_reg = 0x47008,
+   .halt_check = BRANCH_HALT,
+   .clkr = {
+   .enable_reg = 0x47008,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_lpass_sway_clk",
+   .flags = CLK_IS_CRITICAL,
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
 static struct gdsc pcie_0_gdsc = {
.gdscr = 0x6b004,
.pd = {
@@ -3453,6 +3481,8 @@ enum {
[GCC_QSPI_CORE_CLK_SRC] = &gcc_qspi_core_clk_src.clkr,
[GCC_QSPI_CORE_CLK] = &gcc_qspi_core_clk.clkr,
[GCC_QSPI_CNOC_PERIPH_AHB_CLK] = &gcc_qspi_cnoc_periph_ahb_clk.clkr,
+   [GCC_LPASS_Q6_AXI_CLK] = &gcc_lpass_q6_axi_clk.clkr,
+   [GCC_LPASS_SWAY_CLK] = &gcc_lpass_sway_clk.clkr,
 };

 static const struct qcom_reset_map gcc_sdm845_resets[] = {
diff --git a/drivers/clk/qcom/lpasscc-sdm845.c 
b/drivers/clk/qcom/lpasscc-sdm845.c
new file mode 100644
index 000..9c63542
--- /dev/null
+++ b/drivers/clk/qcom/lpasscc-sdm845.c
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "clk-regmap.h"
+#include "clk-branch.h"
+#include "common.h"
+
+static struct clk_branch lpass_q6ss_ahbm_aon_clk = {
+   .halt_reg = 0x12000,
+   .halt_check = BRANCH_VOTED,
+   .clkr = {
+   .enable_reg = 0x12000,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "lpass_q6ss_ahbm_aon_clk",
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
+static struct clk_branch lpass_q6ss_ahbs_aon_clk = {
+   .halt_reg = 0x1f000,
+   .halt_check = BRANCH_VOTED,
+   .clkr

Re: [PATCH v3 1/4] clk: qcom: gdsc: Add support to enable/disable the clocks with GDSC

2018-11-19 Thread Taniya Das

Hello Stephen,

On 11/5/2018 12:04 PM, Stephen Boyd wrote:

Quoting Amit Nischal (2018-08-12 23:33:04)

For some of the GDSCs, there is a requirement to enable/disable the
few clocks before turning on/off the gdsc power domain. Add support
for the same by specifying a list of clk_hw pointers per gdsc and
enable/disable them along with power domain on/off callbacks.

Signed-off-by: Amit Nischal 


In v1 of this patch series I asked for much more information in this
commit text. Please add it here. I won't apply this patch until the
justification is put into this commit text.



Would surely add more details.


---
  drivers/clk/qcom/gdsc.c | 44 
  drivers/clk/qcom/gdsc.h |  5 +
  2 files changed, 49 insertions(+)

diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
index a077133..b6adca1 100644
--- a/drivers/clk/qcom/gdsc.c
+++ b/drivers/clk/qcom/gdsc.c
@@ -12,6 +12,8 @@
   */
  
  #include 

+#include 
+#include 


This makes me unhappy. It's almost always a problem when we see clk.h
and clk-provider.h included in the same file, so if gdsc has to call clk
APIs to operate correctly, then we should do that by having the gdsc
code get clks properly instead of directly reaching into the clk_hw
structure to get a clk pointer. This means we should have the gdsc code
ask the clk framework to convert a clk_hw pointer into a clk pointer
because of how so intimately connected the gdsc is to clks on this SoC.
But given all that, I'm still trying to understand why we need to do
this within the gdsc code.

Adding these clk calls to the gdsc seems like we're attaching at the
wrong abstraction level. Especially if the reason we do it is to make it
easier for the GPU driver to handle dependencies. I hope that's not the
case. Either way, it would make more sense to me if we made genpds for
the clks and genpds for the gdscs and then associated the clk genpds
with the gdsc genpds so that when a gdsc is enabled the clk domain that
it depends on is enabled first. Then we have a generic solution for
connecting clks to gdscs that doesn't require us to add more logic to
the gdsc driver and avoids having clk providers do clk consumer things.
Instead, it's all handled outside of this driver by specifying a domain
dependency. It may turn out that such a solution would still need a way
to make clk domains in the clk driver, and it will probably need to do
that by converting clk_hw structures into clk pointers, but it would be
good to do that anyway.

So in summary, I believe we should end up at a point where we have clk
domains and power domains (gdscs) all supported with genpds, and then we
can connect them together however they're connected by linking the
genpds to each other. Device drivers wouldn't really need to care how
they're connected, as long as those genpds are attached to their device
then the driver would be able to enable/disable them through runtime PM.
But I can see how this may be hard to do for this patch series, so in
the spirit of progress and getting things done, it would be OK with me
if the gdsc code called some new clk API to convert a clk_hw pointer
into a clk pointer and then did the same enable/disable things it's
doing in this patch. This whole patch would need to be completely
untangled and ripped out later when we have clk domains but at least we
could get something working now while we work on making clk domains and
plumbing them into genpds and runtime PM.



Yes, I agree with your points above, but as genpds currently cannot have 
a way to take in clock handles, this was the way we chose.


I would add a new clock API as suggested and submit the next series.

--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


Re: [PATCH v3 4/4] clk: qcom: Add graphics clock controller driver for SDM845

2018-11-19 Thread Taniya Das

Hello Stephen,

On 11/5/2018 12:07 PM, Stephen Boyd wrote:

Quoting Amit Nischal (2018-08-12 23:33:07)

+
+static int gpu_cc_sdm845_probe(struct platform_device *pdev)
+{
+   struct regmap *regmap;
+   unsigned int value, mask;
+   int ret;
+
+   regmap = qcom_cc_map(pdev, &gpu_cc_sdm845_desc);
+   if (IS_ERR(regmap))
+   return PTR_ERR(regmap);
+
+   clk_fabia_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config);
+   clk_fabia_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
+
+   /*
+* Configure gpu_cc_cx_gmu_clk with recommended
+* wakeup/sleep settings
+*/
+   mask = CX_GMU_CBCR_WAKE_MASK << CX_GMU_CBCR_WAKE_SHIFT;
+   mask |= CX_GMU_CBCR_SLEEP_MASK << CX_GMU_CBCR_SLEEP_SHIFT;
+   value = 0xf << CX_GMU_CBCR_WAKE_SHIFT | 0xf << CX_GMU_CBCR_SLEEP_SHIFT;
+   regmap_update_bits(regmap, 0x1098, mask, value);
+
+   ret = qcom_cc_really_probe(pdev, &gpu_cc_sdm845_desc, regmap);
+   if (ret)
+   return ret;
+
+   /* Configure clk_dis_wait for gpu_cx_gdsc */
+   regmap_update_bits(regmap, 0x106c, CLK_DIS_WAIT_MASK,
+   8 << CLK_DIS_WAIT_SHIFT);


Is there a reason this is done after clks are registered? I'd think we
would want to do it before.



Yes, it could be done before, would move it.


+
+   /* Set supported range of frequencies for gfx3d clock */
+   clk_hw_set_rate_range(&gpu_cc_gx_gfx3d_clk_src.clkr.hw, 18000,
+   71000);
+
+   return 0;
+}


--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


Re: [PATCH v11 2/2] cpufreq: qcom-hw: Add support for QCOM cpufreq HW driver

2018-12-04 Thread Taniya Das

Hello Stephen, Viresh

Thanks for the code and suggestions.

Having a NR_DOMAINS '2' makes the driver not scalable for re-use.
This assumption is only true for the current version of the HW and do 
not intend to update/clean-up this logic again. So want to stick keeping 
current logic of having the *qcom_freq_domain_map[NR_CPUS].


On 12/5/2018 4:35 AM, Stephen Boyd wrote:

Quoting Stephen Boyd (2018-12-04 14:28:11)

Quoting Viresh Kumar (2018-12-03 21:12:31)

Hi Taniya,

Sorry that I haven't been reviewing it much from last few iterations as I was
letting others get this into a better shape. Thanks for your efforts..

On 02-12-18, 09:25, Taniya Das wrote:

+++ b/drivers/cpufreq/qcom-cpufreq-hw.c



+struct cpufreq_qcom {
+ struct cpufreq_frequency_table *table;
+ void __iomem *perf_state_reg;
+ cpumask_t related_cpus;
+};
+
+static struct cpufreq_qcom *qcom_freq_domain_map[NR_CPUS];


Now that the code is much more simplified, I am not sure if you need this
per-cpu structure at all. The only place where you are using it is in
qcom_cpufreq_hw_cpu_init() and probe(). Why not merge qcom_cpu_resources_init()
completely into qcom_cpufreq_hw_cpu_init() and get rid of this structure
entirely ?



Good point. Here's an untested patch to handle that. It removes the
related functionality and makes an array of pointers to the domains that
are created each time qcom_cpu_resources_init() is called.

---8<

diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c 
b/drivers/cpufreq/qcom-cpufreq-hw.c
index 8dc6b73c2f22..04e7cfd70316 100644
--- a/drivers/cpufreq/qcom-cpufreq-hw.c
+++ b/drivers/cpufreq/qcom-cpufreq-hw.c
@@ -23,14 +23,14 @@
  #define REG_LUT_TABLE  0x110
  #define REG_PERF_STATE 0x920
  
+#define MAX_FREQ_DOMAINS   2

+
  struct cpufreq_qcom {
 struct cpufreq_frequency_table *table;
 void __iomem *perf_state_reg;
 cpumask_t related_cpus;
  };
  
-static struct cpufreq_qcom *qcom_freq_domain_map[NR_CPUS];

-
  static int qcom_cpufreq_hw_target_index(struct cpufreq_policy *policy,
 unsigned int index)
  {
@@ -76,9 +76,14 @@ static unsigned int qcom_cpufreq_hw_fast_switch(struct 
cpufreq_policy *policy,
  
  static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)

  {
+   struct cpufreq_qcom **freq_domain_map;
 struct cpufreq_qcom *c;
  
-   c = qcom_freq_domain_map[policy->cpu];

+   freq_domain_map = cpufreq_get_driver_data();
+   if (!freq_domain_map)
+   return -ENODEV;
+
+   c = freq_domain_map[policy->cpu];


And this fails now because it indexes based on cpu number. We have to
parse the frequency domain out of the cpunode again to fix that.

Here's the updated (still untested) patch and I also just allocated the
freq domain array up front instead of in each domain init routine to
simplify some more.

diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c 
b/drivers/cpufreq/qcom-cpufreq-hw.c
index 8dc6b73c2f22..bc0d734f7e3c 100644
--- a/drivers/cpufreq/qcom-cpufreq-hw.c
+++ b/drivers/cpufreq/qcom-cpufreq-hw.c
@@ -23,14 +23,14 @@
  #define REG_LUT_TABLE 0x110
  #define REG_PERF_STATE0x920
  
+#define MAX_FREQ_DOMAINS		2

+
  struct cpufreq_qcom {
struct cpufreq_frequency_table *table;
void __iomem *perf_state_reg;
cpumask_t related_cpus;
  };
  
-static struct cpufreq_qcom *qcom_freq_domain_map[NR_CPUS];

-
  static int qcom_cpufreq_hw_target_index(struct cpufreq_policy *policy,
unsigned int index)
  {
@@ -76,9 +76,26 @@ static unsigned int qcom_cpufreq_hw_fast_switch(struct 
cpufreq_policy *policy,
  
  static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)

  {
-   struct cpufreq_qcom *c;
+   struct cpufreq_qcom *freq_domain_map, *c;
+   struct device_node *cpu_np;
+   struct of_phandle_args args;
+   int ret;
+
+   freq_domain_map = cpufreq_get_driver_data();
+   if (!freq_domain_map)
+   return -ENODEV;
+
+   cpu_np = of_cpu_device_node_get(policy->cpu);
+   if (!cpu_np)
+   return -ENODEV;
+
+   ret = of_parse_phandle_with_args(cpu_np, "qcom,freq-domain",
+"#freq-domain-cells", 0, &args);
+   of_node_put(cpu_np);
+   if (ret)
+   return ret;
  
-	c = qcom_freq_domain_map[policy->cpu];

+   c = &freq_domain_map[args.args[0]];
if (!c) {
pr_err("No scaling support for CPU%d\n", policy->cpu);
return -ENODEV;
@@ -171,43 +188,15 @@ static int qcom_cpufreq_hw_read_lut(struct device *dev, 
struct cpufreq_qcom *c,
return 0;
  }
  
-static void qcom_get_related_cpus(int index, struct cpumask *m)

-{
-   struct device_node *cpu_np;
-   struct of_phandle_args args;
- 

[PATCH] arm64: dts: sdm845: Add lpasscc node

2018-12-05 Thread Taniya Das
This adds the low pass audio clock controller node to sdm845 based on
the example in the bindings.

Signed-off-by: Taniya Das 
---
 arch/arm64/boot/dts/qcom/sdm845-mtp.dts | 4 +++-
 arch/arm64/boot/dts/qcom/sdm845.dtsi| 8 
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts 
b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
index b3def03..cf73f3c 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
@@ -346,7 +346,9 @@
 &gcc {
protected-clocks = ,
   ,
-  ;
+  ,
+  ,
+  ;
 };

 &i2c10 {
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi 
b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 1419b00..a3db089 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -7,6 +7,7 @@

 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1264,6 +1265,13 @@
#power-domain-cells = <1>;
};

+   lpasscc: clock-controller@17014000 {
+   compatible = "qcom,sdm845-lpasscc";
+   reg = <0x17014000 0x1f004>, <0x1730 0x200>;
+   reg-names = "cc", "qdsp6ss";
+   #clock-cells = <1>;
+   };
+
tsens0: thermal-sensor@c263000 {
compatible = "qcom,sdm845-tsens", "qcom,tsens-v2";
reg = <0xc263000 0x1ff>, /* TM */
--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



[PATCH] clk: qcom: Remove LPASS_CC config for GCC lpass clocks

2018-12-05 Thread Taniya Das
The GCC lpass clocks are updated as protected, so clean up the ifdefers.

Signed-off-by: Taniya Das 
---
 drivers/clk/qcom/gcc-sdm845.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index c782e62..ba8ff99 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -3153,8 +3153,6 @@ enum {
},
 };

-/* TODO: Remove after DTS updated to protect these */
-#ifdef CONFIG_SDM_LPASSCC_845
 static struct clk_branch gcc_lpass_q6_axi_clk = {
.halt_reg = 0x47000,
.halt_check = BRANCH_HALT,
@@ -3182,7 +3180,6 @@ enum {
},
},
 };
-#endif

 static struct gdsc pcie_0_gdsc = {
.gdscr = 0x6b004,
@@ -3484,10 +3481,8 @@ enum {
[GCC_QSPI_CORE_CLK_SRC] = &gcc_qspi_core_clk_src.clkr,
[GCC_QSPI_CORE_CLK] = &gcc_qspi_core_clk.clkr,
[GCC_QSPI_CNOC_PERIPH_AHB_CLK] = &gcc_qspi_cnoc_periph_ahb_clk.clkr,
-#ifdef CONFIG_SDM_LPASSCC_845
[GCC_LPASS_Q6_AXI_CLK] = &gcc_lpass_q6_axi_clk.clkr,
[GCC_LPASS_SWAY_CLK] = &gcc_lpass_sway_clk.clkr,
-#endif
 };

 static const struct qcom_reset_map gcc_sdm845_resets[] = {
--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



Re: [PATCH v10 3/3] clk: qcom: Add lpass clock controller driver for SDM845

2018-11-30 Thread Taniya Das

Hello Stephen,

On 11/27/2018 2:44 PM, Stephen Boyd wrote:

Quoting Taniya Das (2018-11-21 23:53:41)

+
+static struct clk_branch lpass_qdsp6ss_core_clk = {
+   .halt_reg = 0x20,
+   /* CLK_OFF would not toggle until LPASS is not out of reset */


Is this really "CLK_OFF won't toggle until LPASS it out of reset"?



Would take care of it, in the next series.

--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


Re: [PATCH v10 3/3] clk: qcom: Add lpass clock controller driver for SDM845

2018-11-30 Thread Taniya Das

Hello Stephen,

On 11/29/2018 2:40 AM, Stephen Boyd wrote:

Quoting Taniya Das (2018-11-21 23:53:41)

diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index f133b7f..ba8ff99 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -3153,6 +3153,34 @@ enum {
 },
  };

+static struct clk_branch gcc_lpass_q6_axi_clk = {
+   .halt_reg = 0x47000,
+   .halt_check = BRANCH_HALT,
+   .clkr = {
+   .enable_reg = 0x47000,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_lpass_q6_axi_clk",
+   .flags = CLK_IS_CRITICAL,
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
+static struct clk_branch gcc_lpass_sway_clk = {
+   .halt_reg = 0x47008,
+   .halt_check = BRANCH_HALT,
+   .clkr = {
+   .enable_reg = 0x47008,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_lpass_sway_clk",
+   .flags = CLK_IS_CRITICAL,
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
  static struct gdsc pcie_0_gdsc = {
 .gdscr = 0x6b004,
 .pd = {
@@ -3453,6 +3481,8 @@ enum {
 [GCC_QSPI_CORE_CLK_SRC] = &gcc_qspi_core_clk_src.clkr,
 [GCC_QSPI_CORE_CLK] = &gcc_qspi_core_clk.clkr,
 [GCC_QSPI_CNOC_PERIPH_AHB_CLK] = &gcc_qspi_cnoc_periph_ahb_clk.clkr,
+   [GCC_LPASS_Q6_AXI_CLK] = &gcc_lpass_q6_axi_clk.clkr,
+   [GCC_LPASS_SWAY_CLK] = &gcc_lpass_sway_clk.clkr,


I have one single idea to avoid the integration nightmare with dts
needing another update for this on platforms where these can't be
touched. It's not perfect, but we can throw these clks and usage of the
clks behind an #ifdef CONFIG_SDM_LPASSCC_845 and then let the dts parts
match up with the clk driver parts in linux-next. After everything is
merged together, someone can turn on the knobs for LPASS clk controller
and make sure they have the right dts bits to mark them as protected.



Sure, would keep it under the ifdefer and would clean it up later.

--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


[PATCH v11 0/3] Add support for LPASS clock controller for SDM845

2018-11-30 Thread Taniya Das
 [v11]
  * Add the GCC LPASS clocks only if LPASSCC config is present.
  * Update the comment in lpasscc driver.

 [v10]
  * Separate change to add  protected-clocks list in GCC binding.
  * Remove the clock support 'LPASS_AUDIO_WRAPPER_AON_CLK' as it is always ON
  clock.
  * Add few comments for module description and match table.

 [v9]
  * Update GCC documentation binding with the protected-clocks list.
  * Update the GCC code to add the GCC lpass clocks.
  * This depends on the acceptance of
  https://lore.kernel.org/lkml/20181105194011.43770-1-swb...@chromium.org/

 [v8]
  * Add CLK_IS_CRITICAL for GCC lpass clocks for lpass clocks access to go
  through always.

 [v7]
  * Cleanup header file inclusions.
  * Move the comments along with the flags.
  * Update the commit with details for CLK_IGNORE_UNUSED.

 [v6]
  * Update the logic to register the lpass clocks when the device tree property
   is not present.
  * Add the CLK_IGNORE_UNUSED flag for the lpass clocks to not gate the clocks
   at late_init.

 [v5]
  * Address the comments in device tree binding to update the reg-names,
update the unit address in lpass clock node example and also
add reg property for the gcc clock node.
  * Update the lpass driver to take care of the reg-names.

 [v4]
  * Update the description in GCC Documentation binding for
  'qcom,lpass-protected'.
  * Remove 'qcom,lpass-protected' from LPASS Documentation binding.
  * Update KConfig to use Low Power Audio Subsystem.
  * Add module_exit() and also update return value for
devm_ioremap_resource failure.

 [v3]
  * Add a device tree property to identify lpass protected GCC clocks.
  * Update the GCC driver code to register the lpass clocks when the flag is
   defined.
  * Add comment for clocks using the BRANCH_HALT_SKIP flag.
  * Use platform APIs instead of of_address_to_resource.
  * Replace devm_ioremap with devm_ioremap_resource.
  * Use fixed index for 'lpass_cc' & 'lpass_qdsp6ss' in probe.

 [v2]
  * Make gcc_lpass_sway_clk static.
  * Remove using child nodes and use reg-names to differentiate various
domains of LPASS CC.

Add support for the lpass clock controller found on SDM845 based devices.
This would allow lpass peripheral loader drivers to control the clocks to
bring the subsystem out of reset.

Taniya Das (3):
  dt-bindings: clock: Update GCC bindings for protected-clocks
  dt-bindings: clock: Introduce QCOM LPASS clock bindings
  clk: qcom: Add lpass clock controller driver for SDM845

 .../devicetree/bindings/clock/qcom,gcc.txt |  16 ++
 .../devicetree/bindings/clock/qcom,lpasscc.txt |  26 +++
 drivers/clk/qcom/Kconfig   |   9 ++
 drivers/clk/qcom/Makefile  |   1 +
 drivers/clk/qcom/gcc-sdm845.c  |  32 
 drivers/clk/qcom/lpasscc-sdm845.c  | 179 +
 include/dt-bindings/clock/qcom,gcc-sdm845.h|   2 +
 include/dt-bindings/clock/qcom,lpass-sdm845.h  |  15 ++
 8 files changed, 280 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,lpasscc.txt
 create mode 100644 drivers/clk/qcom/lpasscc-sdm845.c
 create mode 100644 include/dt-bindings/clock/qcom,lpass-sdm845.h

--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



[PATCH v11 2/3] dt-bindings: clock: Introduce QCOM LPASS clock bindings

2018-11-30 Thread Taniya Das
Add device tree bindings for Low Power Audio subsystem clock controller for
Qualcomm Technology Inc's SDM845 SoCs.

Reviewed-by: Rob Herring 
Signed-off-by: Taniya Das 
---
 .../devicetree/bindings/clock/qcom,gcc.txt |  4 +++-
 .../devicetree/bindings/clock/qcom,lpasscc.txt | 26 ++
 include/dt-bindings/clock/qcom,gcc-sdm845.h|  2 ++
 include/dt-bindings/clock/qcom,lpass-sdm845.h  | 15 +
 4 files changed, 46 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,lpasscc.txt
 create mode 100644 include/dt-bindings/clock/qcom,lpass-sdm845.h

diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.txt 
b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
index 5e37de9..8661c3c 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt
+++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
@@ -67,5 +67,7 @@ Example of GCC with protected-clocks properties:
#power-domain-cells = <1>;
protected-clocks = ,
   ,
-  ;
+  ,
+  ,
+  ;
};
diff --git a/Documentation/devicetree/bindings/clock/qcom,lpasscc.txt 
b/Documentation/devicetree/bindings/clock/qcom,lpasscc.txt
new file mode 100644
index 000..b9e9787
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,lpasscc.txt
@@ -0,0 +1,26 @@
+Qualcomm LPASS Clock Controller Binding
+---
+
+Required properties :
+- compatible   : shall contain "qcom,sdm845-lpasscc"
+- #clock-cells : from common clock binding, shall contain 1.
+- reg  : shall contain base register address and size,
+ in the order
+   Index-0 maps to LPASS_CC register region
+   Index-1 maps to LPASS_QDSP6SS register region
+
+Optional properties :
+- reg-names: register names of LPASS domain
+"cc", "qdsp6ss".
+
+Example:
+
+The below node has to be defined in the cases where the LPASS peripheral loader
+would bring the subsystem out of reset.
+
+   lpasscc: clock-controller@17014000 {
+   compatible = "qcom,sdm845-lpasscc";
+   reg = <0x17014000 0x1f004>, <0x1730 0x200>;
+   reg-names = "cc", "qdsp6ss";
+   #clock-cells = <1>;
+   };
diff --git a/include/dt-bindings/clock/qcom,gcc-sdm845.h 
b/include/dt-bindings/clock/qcom,gcc-sdm845.h
index b8eae5a..968fa65 100644
--- a/include/dt-bindings/clock/qcom,gcc-sdm845.h
+++ b/include/dt-bindings/clock/qcom,gcc-sdm845.h
@@ -197,6 +197,8 @@
 #define GCC_QSPI_CORE_CLK_SRC  187
 #define GCC_QSPI_CORE_CLK  188
 #define GCC_QSPI_CNOC_PERIPH_AHB_CLK   189
+#define GCC_LPASS_Q6_AXI_CLK   190
+#define GCC_LPASS_SWAY_CLK 191

 /* GCC Resets */
 #define GCC_MMSS_BCR   0
diff --git a/include/dt-bindings/clock/qcom,lpass-sdm845.h 
b/include/dt-bindings/clock/qcom,lpass-sdm845.h
new file mode 100644
index 000..6590508
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,lpass-sdm845.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_SDM_LPASS_SDM845_H
+#define _DT_BINDINGS_CLK_SDM_LPASS_SDM845_H
+
+#define LPASS_Q6SS_AHBM_AON_CLK0
+#define LPASS_Q6SS_AHBS_AON_CLK1
+#define LPASS_QDSP6SS_XO_CLK   2
+#define LPASS_QDSP6SS_SLEEP_CLK3
+#define LPASS_QDSP6SS_CORE_CLK 4
+
+#endif
--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



[PATCH v11 3/3] clk: qcom: Add lpass clock controller driver for SDM845

2018-11-30 Thread Taniya Das
Add support for the lpass clock controller found on SDM845 based devices.
This would allow lpass peripheral loader drivers to control the clocks to
bring the subsystem out of reset.
LPASS clocks present on the global clock controller would be registered
with the clock framework based on the protected-clock flag. Also do not
gate these clocks if they are left unused, as the lpass clocks require
the global clock controller lpass clocks to be enabled before they are
accessed. Mark the GCC lpass clocks as CRITICAL, for the LPASS clock
access.

Signed-off-by: Taniya Das 
---
 drivers/clk/qcom/Kconfig  |   9 ++
 drivers/clk/qcom/Makefile |   1 +
 drivers/clk/qcom/gcc-sdm845.c |  32 +++
 drivers/clk/qcom/lpasscc-sdm845.c | 179 ++
 4 files changed, 221 insertions(+)
 create mode 100644 drivers/clk/qcom/lpasscc-sdm845.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 6f3e466..d87a22e 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -302,6 +302,15 @@ config SDM_DISPCC_845
  Say Y if you want to support display devices and functionality such as
  splash screen.

+config SDM_LPASSCC_845
+   tristate "SDM845 Low Power Audio Subsystem (LPAAS) Clock Controller"
+   depends on COMMON_CLK_QCOM
+   select SDM_GCC_845
+   help
+ Support for the LPASS clock controller on SDM845 devices.
+ Say Y if you want to use the LPASS branch clocks of the LPASS clock
+ controller to reset the LPASS subsystem.
+
 config SPMI_PMIC_CLKDIV
tristate "SPMI PMIC clkdiv Support"
depends on (COMMON_CLK_QCOM && SPMI) || COMPILE_TEST
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 6ed2827..ee8d069 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o
 obj-$(CONFIG_SDM_GCC_660) += gcc-sdm660.o
 obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o
 obj-$(CONFIG_SDM_GPUCC_845) += gpucc-sdm845.o
+obj-$(CONFIG_SDM_LPASSCC_845) += lpasscc-sdm845.o
 obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o
 obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o
 obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o
diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index f133b7f..db90f9b 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -3153,6 +3153,34 @@ enum {
},
 };

+static struct clk_branch gcc_lpass_q6_axi_clk = {
+   .halt_reg = 0x47000,
+   .halt_check = BRANCH_HALT,
+   .clkr = {
+   .enable_reg = 0x47000,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_lpass_q6_axi_clk",
+   .flags = CLK_IS_CRITICAL,
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
+static struct clk_branch gcc_lpass_sway_clk = {
+   .halt_reg = 0x47008,
+   .halt_check = BRANCH_HALT,
+   .clkr = {
+   .enable_reg = 0x47008,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_lpass_sway_clk",
+   .flags = CLK_IS_CRITICAL,
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
 static struct gdsc pcie_0_gdsc = {
.gdscr = 0x6b004,
.pd = {
@@ -3453,6 +3481,10 @@ enum {
[GCC_QSPI_CORE_CLK_SRC] = &gcc_qspi_core_clk_src.clkr,
[GCC_QSPI_CORE_CLK] = &gcc_qspi_core_clk.clkr,
[GCC_QSPI_CNOC_PERIPH_AHB_CLK] = &gcc_qspi_cnoc_periph_ahb_clk.clkr,
+#ifdef CONFIG_SDM_LPASSCC_845
+   [GCC_LPASS_Q6_AXI_CLK] = &gcc_lpass_q6_axi_clk.clkr,
+   [GCC_LPASS_SWAY_CLK] = &gcc_lpass_sway_clk.clkr,
+#endif
 };

 static const struct qcom_reset_map gcc_sdm845_resets[] = {
diff --git a/drivers/clk/qcom/lpasscc-sdm845.c 
b/drivers/clk/qcom/lpasscc-sdm845.c
new file mode 100644
index 000..e246b99
--- /dev/null
+++ b/drivers/clk/qcom/lpasscc-sdm845.c
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "clk-regmap.h"
+#include "clk-branch.h"
+#include "common.h"
+
+static struct clk_branch lpass_q6ss_ahbm_aon_clk = {
+   .halt_reg = 0x12000,
+   .halt_check = BRANCH_VOTED,
+   .clkr = {
+   .enable_reg = 0x12000,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "lpass_q6ss_ahbm_aon_clk",
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
+static struct clk_branch lpass_q6ss_ahbs_aon_clk = {
+   .halt_reg = 0x1f00

[PATCH v11 1/3] dt-bindings: clock: Update GCC bindings for protected-clocks

2018-11-30 Thread Taniya Das
Add protected-clocks list which could used to specify the clocks to be
bypassed on certain devices.

Reviewed-by: Rob Herring 
Signed-off-by: Taniya Das 
---
 Documentation/devicetree/bindings/clock/qcom,gcc.txt | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.txt 
b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
index 52d9345..5e37de9 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt
+++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
@@ -35,6 +35,8 @@ be part of GCC and hence the TSENS properties can also be
 part of the GCC/clock-controller node.
 For more details on the TSENS properties please refer
 Documentation/devicetree/bindings/thermal/qcom-tsens.txt
+- protected-clocks : Protected clock specifier list as per common clock
+ binding.

 Example:
clock-controller@90 {
@@ -55,3 +57,15 @@ Example of GCC with TSENS properties:
#reset-cells = <1>;
#thermal-sensor-cells = <1>;
};
+
+Example of GCC with protected-clocks properties:
+   clock-controller@10 {
+   compatible = "qcom,gcc-sdm845";
+   reg = <0x10 0x1f>;
+   #clock-cells = <1>;
+   #reset-cells = <1>;
+   #power-domain-cells = <1>;
+   protected-clocks = ,
+  ,
+  ;
+   };
--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



Re: [PATCH v10 1/2] dt-bindings: cpufreq: Introduce QCOM CPUFREQ Firmware bindings

2018-12-01 Thread Taniya Das

Hello Rob,

On 11/27/2018 12:28 AM, Rob Herring wrote:

On Wed, Nov 21, 2018 at 10:02:36AM -0800, Matthias Kaehlcke wrote:

On Wed, Nov 21, 2018 at 04:12:46PM +0530, Taniya Das wrote:

Add QCOM cpufreq firmware device bindings for Qualcomm Technology Inc's
SoCs. This is required for managing the cpu frequency transitions which are
controlled by the hardware engine.

Signed-off-by: Taniya Das 
---
  .../bindings/cpufreq/cpufreq-qcom-hw.txt   | 172 +
  1 file changed, 172 insertions(+)
  create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt

diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt 
b/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt
new file mode 100644
index 000..90e396b
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt
@@ -0,0 +1,172 @@
+Qualcomm Technologies, Inc. CPUFREQ Bindings
+
+CPUFREQ HW is a hardware engine used by some Qualcomm Technologies, Inc. (QTI)
+SoCs to manage frequency in hardware. It is capable of controlling frequency
+for multiple clusters.
+
+Properties:
+- compatible
+   Usage:  required
+   Value type: 
+   Definition: must be "qcom,cpufreq-hw".
+
+- clocks
+   Usage:  required
+   Value type:  From common clock binding.
+   Definition: clock handle for XO clock and GPLL0 clock.
+
+- clock-names
+   Usage:  required
+   Value type:  From common clock binding.
+   Definition: must be "xo", "cpu_clk".
+
+- reg
+   Usage:  required
+   Value type: 
+   Definition: Addresses and sizes for the memory of the HW bases in
+   each frequency domain.
+- reg-names
+   Usage:  Optional
+   Value type: 
+   Definition: Frequency domain name i.e.
+   "freq-domain0", "freq-domain1".
+
+- freq-domain-cells:
+   Usage:  required.
+   Definition: Number of cells in a freqency domain specifier.
+
+* Property qcom,freq-domain
+Devices supporting freq-domain must set their "qcom,freq-domain" property with
+phandle to a cpufreq_hw followed by the Domain ID(0/1) in the CPU DT node.
+
+
+Example:
+
+Example 1: Dual-cluster, Quad-core per cluster. CPUs within a cluster switch
+DCVS state together.
+
+/ {
+   cpus {
+   #address-cells = <2>;
+   #size-cells = <0>;
+
+   CPU0: cpu@0 {
+   device_type = "cpu";
+   compatible = "qcom,kryo385";
+   reg = <0x0 0x0>;
+   enable-method = "psci";
+   next-level-cache = <&L2_0>;
+   qcom,freq-domain = <&cpufreq_hw 0>;
+   L2_0: l2-cache {
+   compatible = "cache";
+   next-level-cache = <&L3_0>;
+   L3_0: l3-cache {
+ compatible = "cache";
+   };
+   };
+   };
+
+   CPU1: cpu@100 {
+   device_type = "cpu";
+   compatible = "qcom,kryo385";
+   reg = <0x0 0x100>;
+   enable-method = "psci";
+   next-level-cache = <&L2_100>;
+   qcom,freq-domain = <&cpufreq_hw 0>;
+   L2_100: l2-cache {
+   compatible = "cache";
+   next-level-cache = <&L3_0>;
+   };
+   };
+
+   CPU2: cpu@200 {
+   device_type = "cpu";
+   compatible = "qcom,kryo385";
+   reg = <0x0 0x200>;
+   enable-method = "psci";
+   next-level-cache = <&L2_200>;
+   qcom,freq-domain = <&cpufreq_hw 0>;
+   L2_200: l2-cache {
+   compatible = "cache";
+   next-level-cache = <&L3_0>;
+   };
+   };
+
+   CPU3: cpu@300 {
+   device_type = "cpu";
+   compatible = "qcom,kryo385";
+   reg = <0x0 0x300>;
+   enable-method = "psci";
+   next-level-cache = <&L2_300>;
+   qcom,freq-domain = <&cpufreq_hw 0>;
+   L2_300: l2-cache {
+

Re: [PATCH v10 1/2] dt-bindings: cpufreq: Introduce QCOM CPUFREQ Firmware bindings

2018-12-01 Thread Taniya Das

Hello Matthias,

On 11/21/2018 11:32 PM, Matthias Kaehlcke wrote:

On Wed, Nov 21, 2018 at 04:12:46PM +0530, Taniya Das wrote:

Add QCOM cpufreq firmware device bindings for Qualcomm Technology Inc's
SoCs. This is required for managing the cpu frequency transitions which are
controlled by the hardware engine.

Signed-off-by: Taniya Das 
---
  .../bindings/cpufreq/cpufreq-qcom-hw.txt   | 172 +
  1 file changed, 172 insertions(+)
  create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt

diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt 
b/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt
new file mode 100644
index 000..90e396b
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt
@@ -0,0 +1,172 @@
+Qualcomm Technologies, Inc. CPUFREQ Bindings
+
+CPUFREQ HW is a hardware engine used by some Qualcomm Technologies, Inc. (QTI)
+SoCs to manage frequency in hardware. It is capable of controlling frequency
+for multiple clusters.
+
+Properties:
+- compatible
+   Usage:  required
+   Value type: 
+   Definition: must be "qcom,cpufreq-hw".
+
+- clocks
+   Usage:  required
+   Value type:  From common clock binding.
+   Definition: clock handle for XO clock and GPLL0 clock.
+
+- clock-names
+   Usage:  required
+   Value type:  From common clock binding.
+   Definition: must be "xo", "cpu_clk".
+
+- reg
+   Usage:  required
+   Value type: 
+   Definition: Addresses and sizes for the memory of the HW bases in
+   each frequency domain.
+- reg-names
+   Usage:  Optional
+   Value type: 
+   Definition: Frequency domain name i.e.
+   "freq-domain0", "freq-domain1".
+
+- freq-domain-cells:
+   Usage:  required.
+   Definition: Number of cells in a freqency domain specifier.
+
+* Property qcom,freq-domain
+Devices supporting freq-domain must set their "qcom,freq-domain" property with
+phandle to a cpufreq_hw followed by the Domain ID(0/1) in the CPU DT node.
+
+
+Example:
+
+Example 1: Dual-cluster, Quad-core per cluster. CPUs within a cluster switch
+DCVS state together.
+
+/ {
+   cpus {
+   #address-cells = <2>;
+   #size-cells = <0>;
+
+   CPU0: cpu@0 {
+   device_type = "cpu";
+   compatible = "qcom,kryo385";
+   reg = <0x0 0x0>;
+   enable-method = "psci";
+   next-level-cache = <&L2_0>;
+   qcom,freq-domain = <&cpufreq_hw 0>;
+   L2_0: l2-cache {
+   compatible = "cache";
+   next-level-cache = <&L3_0>;
+   L3_0: l3-cache {
+ compatible = "cache";
+   };
+   };
+   };
+
+   CPU1: cpu@100 {
+   device_type = "cpu";
+   compatible = "qcom,kryo385";
+   reg = <0x0 0x100>;
+   enable-method = "psci";
+   next-level-cache = <&L2_100>;
+   qcom,freq-domain = <&cpufreq_hw 0>;
+   L2_100: l2-cache {
+   compatible = "cache";
+   next-level-cache = <&L3_0>;
+   };
+   };
+
+   CPU2: cpu@200 {
+   device_type = "cpu";
+   compatible = "qcom,kryo385";
+   reg = <0x0 0x200>;
+   enable-method = "psci";
+   next-level-cache = <&L2_200>;
+   qcom,freq-domain = <&cpufreq_hw 0>;
+   L2_200: l2-cache {
+   compatible = "cache";
+   next-level-cache = <&L3_0>;
+   };
+   };
+
+   CPU3: cpu@300 {
+   device_type = "cpu";
+   compatible = "qcom,kryo385";
+   reg = <0x0 0x300>;
+   enable-method = "psci";
+   next-level-cache = <&L2_300>;
+   qcom,freq-domain = <&cpufreq_hw 0>;
+   L2_300: l2-cache {
+   compatible = "cache";

Re: [PATCH v10 2/2] cpufreq: qcom-hw: Add support for QCOM cpufreq HW driver

2018-12-01 Thread Taniya Das

Hello Matthias,

On 11/22/2018 12:11 AM, Matthias Kaehlcke wrote:

Hi Taniya,

thanks for respinning, a few nits inline.

On Wed, Nov 21, 2018 at 04:12:47PM +0530, Taniya Das wrote:

The CPUfreq HW present in some QCOM chipsets offloads the steps necessary
for changing the frequency of CPUs. The driver implements the cpufreq
driver interface for this hardware engine.

Signed-off-by: Saravana Kannan 
Signed-off-by: Taniya Das 
---
  drivers/cpufreq/Kconfig.arm   |  11 ++
  drivers/cpufreq/Makefile  |   1 +
  drivers/cpufreq/qcom-cpufreq-hw.c | 346 ++
  3 files changed, 358 insertions(+)
  create mode 100644 drivers/cpufreq/qcom-cpufreq-hw.c

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 4e1131e..688f102 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -114,6 +114,17 @@ config ARM_QCOM_CPUFREQ_KRYO

  If in doubt, say N.

+config ARM_QCOM_CPUFREQ_HW
+   tristate "QCOM CPUFreq HW driver"
+   depends on ARCH_QCOM || COMPILE_TEST
+   help
+ Support for the CPUFreq HW driver.
+ Some QCOM 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_S3C_CPUFREQ
bool
help
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index d5ee456..789b2e0 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -62,6 +62,7 @@ obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)   += omap-cpufreq.o
  obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)  += pxa2xx-cpufreq.o
  obj-$(CONFIG_PXA3xx)  += pxa3xx-cpufreq.o
  obj-$(CONFIG_ARM_QCOM_CPUFREQ_KRYO)   += qcom-cpufreq-kryo.o
+obj-$(CONFIG_ARM_QCOM_CPUFREQ_HW)  += qcom-cpufreq-hw.o
  obj-$(CONFIG_ARM_S3C2410_CPUFREQ) += s3c2410-cpufreq.o
  obj-$(CONFIG_ARM_S3C2412_CPUFREQ) += s3c2412-cpufreq.o
  obj-$(CONFIG_ARM_S3C2416_CPUFREQ) += s3c2416-cpufreq.o
diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c 
b/drivers/cpufreq/qcom-cpufreq-hw.c
new file mode 100644
index 000..6390e85
--- /dev/null
+++ b/drivers/cpufreq/qcom-cpufreq-hw.c
@@ -0,0 +1,346 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define LUT_MAX_ENTRIES40U
+#define CORE_COUNT_VAL(val)(((val) & (GENMASK(18, 16))) >> 16)
+#define LUT_ROW_SIZE   32
+#define CLK_HW_DIV 2
+
+/* Register offsets */
+#define REG_ENABLE 0x0
+#define REG_LUT_TABLE  0x110
+#define REG_PERF_STATE 0x920
+
+struct cpufreq_qcom {
+   struct cpufreq_frequency_table *table;
+   void __iomem *perf_base;


nit: is this really a base address? It's the address of the perf state
register, right? Better name it 'perf_state_reg'/'reg_perf_state' or
similar (just 'perf_state' might be confusing, I'd expect a variable
with this name to hold a state, not an address).



I have updated the name to "perf_state_reg".


+   cpumask_t related_cpus;
+   unsigned int max_cores;
+   unsigned long xo_rate;
+   unsigned long cpu_hw_rate;
+};
+
+static struct cpufreq_qcom *qcom_freq_domain_map[NR_CPUS];
+
+static int
+qcom_cpufreq_hw_target_index(struct cpufreq_policy *policy,
+unsigned int index)
+{
+   struct cpufreq_qcom *c = policy->driver_data;
+
+   writel_relaxed(index, c->perf_base);
+
+   return 0;
+}
+
+static unsigned int qcom_cpufreq_hw_get(unsigned int cpu)
+{
+   struct cpufreq_qcom *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->perf_base);
+   index = min(index, LUT_MAX_ENTRIES - 1);
+
+   return policy->freq_table[index].frequency;
+}
+
+static unsigned int
+qcom_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
+   unsigned int target_freq)
+{
+   struct cpufreq_qcom *c = policy->driver_data;
+   int index;
+
+   index = policy->cached_resolved_idx;
+   if (index < 0)
+   return 0;
+
+   writel_relaxed(index, c->perf_base);
+
+   return policy->freq_table[index].frequency;
+}
+
+static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
+{
+   struct cpufreq_qcom *c;
+
+   c = qcom_freq_domain_map[policy->cpu];
+   if (!c) {
+   pr_err("No scaling support for CPU%d\n&quo

Re: [PATCH v10 2/2] cpufreq: qcom-hw: Add support for QCOM cpufreq HW driver

2018-12-01 Thread Taniya Das

Hello Stephen,

Thanks for the patch, I have updated the latest series with the patch 
and few comments from Matthias.


On 11/21/2018 11:53 PM, Stephen Boyd wrote:

Quoting Taniya Das (2018-11-21 02:42:47)

diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index d5ee456..789b2e0 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -62,6 +62,7 @@ obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)   += omap-cpufreq.o
  obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)   += pxa2xx-cpufreq.o
  obj-$(CONFIG_PXA3xx)   += pxa3xx-cpufreq.o
  obj-$(CONFIG_ARM_QCOM_CPUFREQ_KRYO)+= qcom-cpufreq-kryo.o
+obj-$(CONFIG_ARM_QCOM_CPUFREQ_HW)  += qcom-cpufreq-hw.o


This isn't alphabetically sorted.


  obj-$(CONFIG_ARM_S3C2410_CPUFREQ)  += s3c2410-cpufreq.o
  obj-$(CONFIG_ARM_S3C2412_CPUFREQ)  += s3c2412-cpufreq.o
  obj-$(CONFIG_ARM_S3C2416_CPUFREQ)  += s3c2416-cpufreq.o
diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c 
b/drivers/cpufreq/qcom-cpufreq-hw.c
new file mode 100644
index 000..6390e85
--- /dev/null
+++ b/drivers/cpufreq/qcom-cpufreq-hw.c
@@ -0,0 +1,346 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define LUT_MAX_ENTRIES40U
+#define CORE_COUNT_VAL(val)(((val) & (GENMASK(18, 16))) >> 16)
+#define LUT_ROW_SIZE   32
+#define CLK_HW_DIV 2
+
+/* Register offsets */
+#define REG_ENABLE 0x0
+#define REG_LUT_TABLE  0x110
+#define REG_PERF_STATE 0x920
+
+struct cpufreq_qcom {
+   struct cpufreq_frequency_table *table;
+   void __iomem *perf_base;
+   cpumask_t related_cpus;
+   unsigned int max_cores;
+   unsigned long xo_rate;
+   unsigned long cpu_hw_rate;
+};
+
+static struct cpufreq_qcom *qcom_freq_domain_map[NR_CPUS];
+
+static int
+qcom_cpufreq_hw_target_index(struct cpufreq_policy *policy,
+unsigned int index)
+{
+   struct cpufreq_qcom *c = policy->driver_data;
+
+   writel_relaxed(index, c->perf_base);
+


This isn't using the pointer directly though.


+   return 0;
+}
+
+static unsigned int qcom_cpufreq_hw_get(unsigned int cpu)
+{
+   struct cpufreq_qcom *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->perf_base);
+   index = min(index, LUT_MAX_ENTRIES - 1);
+
+   return policy->freq_table[index].frequency;
+}
+
+static unsigned int
+qcom_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
+   unsigned int target_freq)
+{
+   struct cpufreq_qcom *c = policy->driver_data;
+   int index;
+
+   index = policy->cached_resolved_idx;
+   if (index < 0)
+   return 0;
+
+   writel_relaxed(index, c->perf_base);
+
+   return policy->freq_table[index].frequency;
+}
+
+static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
+{
+   struct cpufreq_qcom *c;
+
+   c = qcom_freq_domain_map[policy->cpu];
+   if (!c) {
+   pr_err("No scaling support for CPU%d\n", policy->cpu);
+   return -ENODEV;
+   }
+
+   cpumask_copy(policy->cpus, &c->related_cpus);
+
+   policy->fast_switch_possible = true;
+   policy->freq_table = c->table;
+   policy->driver_data = c;
+
+   return 0;
+}
+
+static struct freq_attr *qcom_cpufreq_hw_attr[] = {
+   &cpufreq_freq_attr_scaling_available_freqs,
+   &cpufreq_freq_attr_scaling_boost_freqs,
+   NULL
+};
+
+static struct cpufreq_driver cpufreq_qcom_hw_driver = {
+   .flags  = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK |
+ CPUFREQ_HAVE_GOVERNOR_PER_POLICY,
+   .verify = cpufreq_generic_frequency_table_verify,
+   .target_index   = qcom_cpufreq_hw_target_index,
+   .get= qcom_cpufreq_hw_get,
+   .init   = qcom_cpufreq_hw_cpu_init,
+   .fast_switch= qcom_cpufreq_hw_fast_switch,
+   .name   = "qcom-cpufreq-hw",
+   .attr   = qcom_cpufreq_hw_attr,
+   .boost_enabled  = true,
+};
+
+static int qcom_cpufreq_hw_read_lut(struct platform_device *pdev,
+   struct cpufreq_qcom *c, void __iomem *base)
+{
+   struct device *dev = &pdev->dev;
+   u32 data, src, lval, i, core_count, prev_cc, prev_freq, cur_freq;
+
+   c->table = devm_kcalloc(dev, LUT_MAX_ENTRIES + 1,
+   sizeof(*c->table), GFP_KERNEL);
+   if (!c->table)
+   return -ENOMEM;
+
+   for (i = 0; i < LUT_MAX_ENTRIES; i

[PATCH v11 0/2] cpufreq: qcom-hw: Add support for QCOM cpufreq HW

2018-12-01 Thread Taniya Das
 [v11]
   * Updated the code logic as per Stephen.
   * Default boost enabled is removed.
   * Update the clock name to use "alternate" for GPLL0 source in code and
 Documentation binding.
   * Module description updated.
   * perf_base updated to perf_state_reg.

 [v10]
  * Update Documentation binding for cpufreq node.
  * Make the driver 'tristate' instead of 'bool' and update code.
  * Update the clock name to reflect the hardware name.
  * Remove support for varying offset.

 [v9]
  * Update the Documentation binding for freq-domain-cells & cpufreq node.
  * Address comments in Kconfig.arm & Makefile.
  * Remove include file & MODULE_DESCRIPTION not required.
  * Fix the code for 'of_node_put(cpu_np)'.

 [v8]
   * Address comments to update code to take cpufreq_hw phandle and index from
 the CPU nodes.
   * Updated the Documentation for the above change in DT.
   * Updated logic for assigning 'qcom_freq_domain_map' for related CPUs.
   * Clock input to the HW block is taken from DT which has been updated in
 code and Device tree documentation.

 [v7]
   * Updated the logic to check for related CPUs.

 [v6]
   * Renamed match table 'qcom_cpufreq_hw_match'.
   * Renamed 'qcom_read_lut' to 'qcom_cpufreq_hw_read_lut'.
   * Updated the logic to check for related CPUs at the beginning of the
 'qcom_cpu_resources_init'.
   * Use devm_ioremap_resource instead of devm_ioremap.
   * Update the use of of_node_put to handle error conditions.
   * Use policy->cached_resolved_idx in fast switch callback.
   * Keep precalculated offsets 'reg_bases'.
   * XO clock is taken from Device tree.
   * Update documentation binding for clocks/clock-names.
   * Minor comments in Kconfig.arm.
   * Comments to move dev_info to dev_dbg.

 [v5]
   * Remove mapping different register regions of perf/lut/enable,
 instead map the entire HW region.
   * Add reg_offset/cpufreq_qcom_std_offsets to be supplied as device data.
   * Check of src == 0 during lut read.
   * Add of_node_put(cpu_np) in qcom_get_related_cpus
   * Update the qcom_cpu_resources_init for register offset data,
 and cleanup the related cpus to keep a single copy of CPUfreq.
   * Replace FW with HW, update Kconfig, rename filename qcom-cpufreq-hw.c
   * Update the documentation binding to reflect the changes of mapping the
   * entire HW region.

 [v4]
   * Fixed console messages as per comments.
   * Return error from qcom_resources_init()
 in the cases where failed to get frequency domain.
   * Rename cpu_dev to cpu_np in qcom_resources_init,
 qcom_get_related_cpus(). Also use temp variable freq_np in
 qcom_get_related_cpus().
   * Update qcom_cpufreq_fw_get() to use the policy data to incoporate
 the hotplug use case.
   * Update code to use of fast_switching.
   * Check for !c->max_cores instead of cpumask_empty in
 qcom_get_related_cpus().
   * Update the logic of assigning 'c' to qcom_freq_domain_map[cpu].

 [v3]
   * Remove index check from 'qcom_cpufreq_fw_target_index'.
   * Update the Documentation binding to add the platform specific properties in
 the CPU nodes, node name "qcom,freq-domain".
   * Update return value to '0' from -ENODEV from 'qcom_cpufreq_fw_get'.
   * Update the logic for boost frequency to use local variables instead of
 cpufreq driver data in 'qcom_read_lut'.
   * Update the logic in 'qcom_get_related_cpus' to find the related cpus.
   * Update the reg-names to remove "_base" and also update the binding with the
 description of these registers.
   * Update the logic in 'qcom_resources_init' to address the new device tree
 notation of handling the frequency domain phandles.

 [v2]
   * Fixed the alignment issues in "qcom_cpufreq_fw_target_index" for dev_err 
and
 also for "qcom_cpu_resources_init".
   * Removed ret = 0 from qcom_get_related_cpus and added to check for
 cpu_mask_empty to return -ENOENT.
   * Fixes qcom_cpu_resources_init function
   * Remove initialization of 'index'
   * Check for valid 'c'
   * Removed initialization of 'prev_cc' from 'qcom_read_lut'.

Taniya Das (2):
  dt-bindings: cpufreq: Introduce QCOM CPUFREQ Firmware bindings
  cpufreq: qcom-hw: Add support for QCOM cpufreq HW driver

 .../bindings/cpufreq/cpufreq-qcom-hw.txt   | 172 +++
 drivers/cpufreq/Kconfig.arm|  11 +
 drivers/cpufreq/Makefile   |   1 +
 drivers/cpufreq/qcom-cpufreq-hw.c  | 334 +
 4 files changed, 518 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt
 create mode 100644 drivers/cpufreq/qcom-cpufreq-hw.c

--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



[PATCH v11 1/2] dt-bindings: cpufreq: Introduce QCOM CPUFREQ Firmware bindings

2018-12-01 Thread Taniya Das
Add QCOM cpufreq firmware device bindings for Qualcomm Technology Inc's
SoCs. This is required for managing the cpu frequency transitions which are
controlled by the hardware engine.

Signed-off-by: Taniya Das 
---
 .../bindings/cpufreq/cpufreq-qcom-hw.txt   | 172 +
 1 file changed, 172 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt

diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt 
b/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt
new file mode 100644
index 000..2b82965
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt
@@ -0,0 +1,172 @@
+Qualcomm Technologies, Inc. CPUFREQ Bindings
+
+CPUFREQ HW is a hardware engine used by some Qualcomm Technologies, Inc. (QTI)
+SoCs to manage frequency in hardware. It is capable of controlling frequency
+for multiple clusters.
+
+Properties:
+- compatible
+   Usage:  required
+   Value type: 
+   Definition: must be "qcom,cpufreq-hw".
+
+- clocks
+   Usage:  required
+   Value type:  From common clock binding.
+   Definition: clock handle for XO clock and GPLL0 clock.
+
+- clock-names
+   Usage:  required
+   Value type:  From common clock binding.
+   Definition: must be "xo", "alternate".
+
+- reg
+   Usage:  required
+   Value type: 
+   Definition: Addresses and sizes for the memory of the HW bases in
+   each frequency domain.
+- reg-names
+   Usage:  Optional
+   Value type: 
+   Definition: Frequency domain name i.e.
+   "freq-domain0", "freq-domain1".
+
+- freq-domain-cells:
+   Usage:  required.
+   Definition: Number of cells in a freqency domain specifier.
+
+* Property qcom,freq-domain
+Devices supporting freq-domain must set their "qcom,freq-domain" property with
+phandle to a cpufreq_hw followed by the Domain ID(0/1) in the CPU DT node.
+
+
+Example:
+
+Example 1: Dual-cluster, Quad-core per cluster. CPUs within a cluster switch
+DCVS state together.
+
+/ {
+   cpus {
+   #address-cells = <2>;
+   #size-cells = <0>;
+
+   CPU0: cpu@0 {
+   device_type = "cpu";
+   compatible = "qcom,kryo385";
+   reg = <0x0 0x0>;
+   enable-method = "psci";
+   next-level-cache = <&L2_0>;
+   qcom,freq-domain = <&cpufreq_hw 0>;
+   L2_0: l2-cache {
+   compatible = "cache";
+   next-level-cache = <&L3_0>;
+   L3_0: l3-cache {
+ compatible = "cache";
+   };
+   };
+   };
+
+   CPU1: cpu@100 {
+   device_type = "cpu";
+   compatible = "qcom,kryo385";
+   reg = <0x0 0x100>;
+   enable-method = "psci";
+   next-level-cache = <&L2_100>;
+   qcom,freq-domain = <&cpufreq_hw 0>;
+   L2_100: l2-cache {
+   compatible = "cache";
+   next-level-cache = <&L3_0>;
+   };
+   };
+
+   CPU2: cpu@200 {
+   device_type = "cpu";
+   compatible = "qcom,kryo385";
+   reg = <0x0 0x200>;
+   enable-method = "psci";
+   next-level-cache = <&L2_200>;
+   qcom,freq-domain = <&cpufreq_hw 0>;
+   L2_200: l2-cache {
+   compatible = "cache";
+   next-level-cache = <&L3_0>;
+   };
+   };
+
+   CPU3: cpu@300 {
+   device_type = "cpu";
+   compatible = "qcom,kryo385";
+   reg = <0x0 0x300>;
+   enable-method = "psci";
+   next-level-cache = <&L2_300>;
+   qcom,freq-domain = <&cpufreq_hw 0>;
+   L2_300: l2-cache {
+   compatible = "cache";
+   next-level-cache = <&L3_0>;
+   };
+

[PATCH v11 2/2] cpufreq: qcom-hw: Add support for QCOM cpufreq HW driver

2018-12-01 Thread Taniya Das
The CPUfreq HW present in some QCOM chipsets offloads the steps necessary
for changing the frequency of CPUs. The driver implements the cpufreq
driver interface for this hardware engine.

Signed-off-by: Saravana Kannan 
Signed-off-by: Stephen Boyd 
Signed-off-by: Taniya Das 
---
 drivers/cpufreq/Kconfig.arm   |  11 ++
 drivers/cpufreq/Makefile  |   1 +
 drivers/cpufreq/qcom-cpufreq-hw.c | 334 ++
 3 files changed, 346 insertions(+)
 create mode 100644 drivers/cpufreq/qcom-cpufreq-hw.c

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 4e1131e..688f102 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -114,6 +114,17 @@ config ARM_QCOM_CPUFREQ_KRYO

  If in doubt, say N.

+config ARM_QCOM_CPUFREQ_HW
+   tristate "QCOM CPUFreq HW driver"
+   depends on ARCH_QCOM || COMPILE_TEST
+   help
+ Support for the CPUFreq HW driver.
+ Some QCOM 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_S3C_CPUFREQ
bool
help
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index d5ee456..08c071b 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -61,6 +61,7 @@ obj-$(CONFIG_MACH_MVEBU_V7)   += mvebu-cpufreq.o
 obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)+= omap-cpufreq.o
 obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)   += pxa2xx-cpufreq.o
 obj-$(CONFIG_PXA3xx)   += pxa3xx-cpufreq.o
+obj-$(CONFIG_ARM_QCOM_CPUFREQ_HW)  += qcom-cpufreq-hw.o
 obj-$(CONFIG_ARM_QCOM_CPUFREQ_KRYO)+= qcom-cpufreq-kryo.o
 obj-$(CONFIG_ARM_S3C2410_CPUFREQ)  += s3c2410-cpufreq.o
 obj-$(CONFIG_ARM_S3C2412_CPUFREQ)  += s3c2412-cpufreq.o
diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c 
b/drivers/cpufreq/qcom-cpufreq-hw.c
new file mode 100644
index 000..8dc6b73
--- /dev/null
+++ b/drivers/cpufreq/qcom-cpufreq-hw.c
@@ -0,0 +1,334 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define LUT_MAX_ENTRIES40U
+#define LUT_SRCGENMASK(31, 30)
+#define LUT_L_VAL  GENMASK(7, 0)
+#define LUT_CORE_COUNT GENMASK(18, 16)
+#define LUT_ROW_SIZE   32
+#define CLK_HW_DIV 2
+
+/* Register offsets */
+#define REG_ENABLE 0x0
+#define REG_LUT_TABLE  0x110
+#define REG_PERF_STATE 0x920
+
+struct cpufreq_qcom {
+   struct cpufreq_frequency_table *table;
+   void __iomem *perf_state_reg;
+   cpumask_t related_cpus;
+};
+
+static struct cpufreq_qcom *qcom_freq_domain_map[NR_CPUS];
+
+static int qcom_cpufreq_hw_target_index(struct cpufreq_policy *policy,
+   unsigned int index)
+{
+   void __iomem *perf_state_reg = policy->driver_data;
+
+   writel_relaxed(index, perf_state_reg);
+
+   return 0;
+}
+
+static unsigned int qcom_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 unsigned int qcom_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
+   unsigned int target_freq)
+{
+   void __iomem *perf_state_reg = policy->driver_data;
+   int index;
+
+   index = policy->cached_resolved_idx;
+   if (index < 0)
+   return 0;
+
+   writel_relaxed(index, perf_state_reg);
+
+   return policy->freq_table[index].frequency;
+}
+
+static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
+{
+   struct cpufreq_qcom *c;
+
+   c = qcom_freq_domain_map[policy->cpu];
+   if (!c) {
+   pr_err("No scaling support for CPU%d\n", policy->cpu);
+   return -ENODEV;
+   }
+
+   cpumask_copy(policy->cpus, &c->related_cpus);
+
+   policy->fast_switch_possible = true;
+   policy->freq_table = c->table;
+   policy->driver_data = c->perf_state_reg;
+
+   return 0;
+}
+
+static struct freq_attr *qcom_cpufreq_hw_attr[] = {
+   &cpufreq_freq_attr_scaling_available_freqs,
+   &cpufreq_freq_attr_scaling_boost_freqs,
+   NU

Re: [PATCH v11 2/2] cpufreq: qcom-hw: Add support for QCOM cpufreq HW driver

2018-12-04 Thread Taniya Das

Hello Viresh,

On 12/4/2018 10:42 AM, Viresh Kumar wrote:

Hi Taniya,

Sorry that I haven't been reviewing it much from last few iterations as I was
letting others get this into a better shape. Thanks for your efforts..

On 02-12-18, 09:25, Taniya Das wrote:

+++ b/drivers/cpufreq/qcom-cpufreq-hw.c



+struct cpufreq_qcom {
+   struct cpufreq_frequency_table *table;
+   void __iomem *perf_state_reg;
+   cpumask_t related_cpus;
+};
+
+static struct cpufreq_qcom *qcom_freq_domain_map[NR_CPUS];


Now that the code is much more simplified, I am not sure if you need this
per-cpu structure at all. The only place where you are using it is in
qcom_cpufreq_hw_cpu_init() and probe(). Why not merge qcom_cpu_resources_init()
completely into qcom_cpufreq_hw_cpu_init() and get rid of this structure
entirely ?



Yes, we still would require the per-cpu.

--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


[PATCH v9 2/2] clk: qcom: Add lpass clock controller driver for SDM845

2018-11-09 Thread Taniya Das
Add support for the lpass clock controller found on SDM845 based devices.
This would allow lpass peripheral loader drivers to control the clocks to
bring the subsystem out of reset.
LPASS clocks present on the global clock controller would be registered
with the clock framework based on the protected-clock flag. Also do not
gate these clocks if they are left unused, as the lpass clocks require
the global clock controller lpass clocks to be enabled before they are
accessed. Mark the GCC lpass clocks as CRITICAL, for the LPASS clock
access.

Signed-off-by: Taniya Das 
---
 drivers/clk/qcom/Kconfig  |   9 ++
 drivers/clk/qcom/Makefile |   1 +
 drivers/clk/qcom/gcc-sdm845.c |  30 ++
 drivers/clk/qcom/lpasscc-sdm845.c | 192 ++
 4 files changed, 232 insertions(+)
 create mode 100644 drivers/clk/qcom/lpasscc-sdm845.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index a611531..23adc4c 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -293,6 +293,15 @@ config SDM_DISPCC_845
  Say Y if you want to support display devices and functionality such as
  splash screen.

+config SDM_LPASSCC_845
+   tristate "SDM845 Low Power Audio Subsystem (LPAAS) Clock Controller"
+   depends on COMMON_CLK_QCOM
+   select SDM_GCC_845
+   help
+ Support for the LPASS clock controller on SDM845 devices.
+ Say Y if you want to use the LPASS branch clocks of the LPASS clock
+ controller to reset the LPASS subsystem.
+
 config SPMI_PMIC_CLKDIV
tristate "SPMI PMIC clkdiv Support"
depends on (COMMON_CLK_QCOM && SPMI) || COMPILE_TEST
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 981882e..3d530b1 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o
 obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o
 obj-$(CONFIG_SDM_GCC_660) += gcc-sdm660.o
 obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o
+obj-$(CONFIG_SDM_LPASSCC_845) += lpasscc-sdm845.o
 obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o
 obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o
 obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o
diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index f133b7f..ba8ff99 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -3153,6 +3153,34 @@ enum {
},
 };

+static struct clk_branch gcc_lpass_q6_axi_clk = {
+   .halt_reg = 0x47000,
+   .halt_check = BRANCH_HALT,
+   .clkr = {
+   .enable_reg = 0x47000,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_lpass_q6_axi_clk",
+   .flags = CLK_IS_CRITICAL,
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
+static struct clk_branch gcc_lpass_sway_clk = {
+   .halt_reg = 0x47008,
+   .halt_check = BRANCH_HALT,
+   .clkr = {
+   .enable_reg = 0x47008,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_lpass_sway_clk",
+   .flags = CLK_IS_CRITICAL,
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
 static struct gdsc pcie_0_gdsc = {
.gdscr = 0x6b004,
.pd = {
@@ -3453,6 +3481,8 @@ enum {
[GCC_QSPI_CORE_CLK_SRC] = &gcc_qspi_core_clk_src.clkr,
[GCC_QSPI_CORE_CLK] = &gcc_qspi_core_clk.clkr,
[GCC_QSPI_CNOC_PERIPH_AHB_CLK] = &gcc_qspi_cnoc_periph_ahb_clk.clkr,
+   [GCC_LPASS_Q6_AXI_CLK] = &gcc_lpass_q6_axi_clk.clkr,
+   [GCC_LPASS_SWAY_CLK] = &gcc_lpass_sway_clk.clkr,
 };

 static const struct qcom_reset_map gcc_sdm845_resets[] = {
diff --git a/drivers/clk/qcom/lpasscc-sdm845.c 
b/drivers/clk/qcom/lpasscc-sdm845.c
new file mode 100644
index 000..2ef7f2a
--- /dev/null
+++ b/drivers/clk/qcom/lpasscc-sdm845.c
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "clk-regmap.h"
+#include "clk-branch.h"
+#include "common.h"
+
+static struct clk_branch lpass_audio_wrapper_aon_clk = {
+   .halt_reg = 0x098,
+   .halt_check = BRANCH_VOTED,
+   .clkr = {
+   .enable_reg = 0x098,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "lpass_audio_wrapper_aon_clk",
+   .ops = &clk_branch2_ops,
+   },
+   },
+};
+
+static struct clk_branch lpass_q6ss_ahbm_aon_clk = {
+   .halt_reg = 0x12000,
+   .halt_check = BRANCH_VOTED,
+   .clkr

[PATCH v9 0/2] Add support for LPASS clock controller for SDM845

2018-11-09 Thread Taniya Das
 [v9]
  * Update GCC documentation binding with the protected-clocks list.
  * Update the GCC code to add the GCC lpass clocks.
  * This depends on the acceptance of
  https://lore.kernel.org/lkml/20181105194011.43770-1-swb...@chromium.org/

 [v8]
  * Add CLK_IS_CRITICAL for GCC lpass clocks for lpass clocks access to go
  through always.

 [v7]
  * Cleanup header file inclusions.
  * Move the comments along with the flags.
  * Update the commit with details for CLK_IGNORE_UNUSED.

 [v6]
  * Update the logic to register the lpass clocks when the device tree property
   is not present.
  * Add the CLK_IGNORE_UNUSED flag for the lpass clocks to not gate the clocks
   at late_init.

 [v5]
  * Address the comments in device tree binding to update the reg-names,
update the unit address in lpass clock node example and also
add reg property for the gcc clock node.
  * Update the lpass driver to take care of the reg-names.

 [v4]
  * Update the description in GCC Documentation binding for
  'qcom,lpass-protected'.
  * Remove 'qcom,lpass-protected' from LPASS Documentation binding.
  * Update KConfig to use Low Power Audio Subsystem.
  * Add module_exit() and also update return value for
devm_ioremap_resource failure.

 [v3]
  * Add a device tree property to identify lpass protected GCC clocks.
  * Update the GCC driver code to register the lpass clocks when the flag is
   defined.
  * Add comment for clocks using the BRANCH_HALT_SKIP flag.
  * Use platform APIs instead of of_address_to_resource.
  * Replace devm_ioremap with devm_ioremap_resource.
  * Use fixed index for 'lpass_cc' & 'lpass_qdsp6ss' in probe.

 [v2]
  * Make gcc_lpass_sway_clk static.
  * Remove using child nodes and use reg-names to differentiate various
domains of LPASS CC.

Add support for the lpass clock controller found on SDM845 based devices.
This would allow lpass peripheral loader drivers to control the clocks to
bring the subsystem out of reset.

Taniya Das (2):
  dt-bindings: clock: Introduce QCOM LPASS clock bindings
  clk: qcom: Add lpass clock controller driver for SDM845

 .../devicetree/bindings/clock/qcom,gcc.txt |  16 ++
 .../devicetree/bindings/clock/qcom,lpasscc.txt |  26 +++
 drivers/clk/qcom/Kconfig   |   9 +
 drivers/clk/qcom/Makefile  |   1 +
 drivers/clk/qcom/gcc-sdm845.c  |  30 
 drivers/clk/qcom/lpasscc-sdm845.c  | 192 +
 include/dt-bindings/clock/qcom,gcc-sdm845.h|   2 +
 include/dt-bindings/clock/qcom,lpass-sdm845.h  |  16 ++
 8 files changed, 292 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,lpasscc.txt
 create mode 100644 drivers/clk/qcom/lpasscc-sdm845.c
 create mode 100644 include/dt-bindings/clock/qcom,lpass-sdm845.h

--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



[PATCH v9 1/2] dt-bindings: clock: Introduce QCOM LPASS clock bindings

2018-11-09 Thread Taniya Das
Add device tree bindings for Low Power Audio subsystem clock controller for
Qualcomm Technology Inc's SDM845 SoCs.

Signed-off-by: Taniya Das 
---
 .../devicetree/bindings/clock/qcom,gcc.txt | 16 +
 .../devicetree/bindings/clock/qcom,lpasscc.txt | 26 ++
 include/dt-bindings/clock/qcom,gcc-sdm845.h|  2 ++
 include/dt-bindings/clock/qcom,lpass-sdm845.h  | 16 +
 4 files changed, 60 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,lpasscc.txt
 create mode 100644 include/dt-bindings/clock/qcom,lpass-sdm845.h

diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.txt 
b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
index 52d9345..8661c3c 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt
+++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
@@ -35,6 +35,8 @@ be part of GCC and hence the TSENS properties can also be
 part of the GCC/clock-controller node.
 For more details on the TSENS properties please refer
 Documentation/devicetree/bindings/thermal/qcom-tsens.txt
+- protected-clocks : Protected clock specifier list as per common clock
+ binding.

 Example:
clock-controller@90 {
@@ -55,3 +57,17 @@ Example of GCC with TSENS properties:
#reset-cells = <1>;
#thermal-sensor-cells = <1>;
};
+
+Example of GCC with protected-clocks properties:
+   clock-controller@10 {
+   compatible = "qcom,gcc-sdm845";
+   reg = <0x10 0x1f>;
+   #clock-cells = <1>;
+   #reset-cells = <1>;
+   #power-domain-cells = <1>;
+   protected-clocks = ,
+  ,
+  ,
+  ,
+  ;
+   };
diff --git a/Documentation/devicetree/bindings/clock/qcom,lpasscc.txt 
b/Documentation/devicetree/bindings/clock/qcom,lpasscc.txt
new file mode 100644
index 000..b9e9787
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,lpasscc.txt
@@ -0,0 +1,26 @@
+Qualcomm LPASS Clock Controller Binding
+---
+
+Required properties :
+- compatible   : shall contain "qcom,sdm845-lpasscc"
+- #clock-cells : from common clock binding, shall contain 1.
+- reg  : shall contain base register address and size,
+ in the order
+   Index-0 maps to LPASS_CC register region
+   Index-1 maps to LPASS_QDSP6SS register region
+
+Optional properties :
+- reg-names: register names of LPASS domain
+"cc", "qdsp6ss".
+
+Example:
+
+The below node has to be defined in the cases where the LPASS peripheral loader
+would bring the subsystem out of reset.
+
+   lpasscc: clock-controller@17014000 {
+   compatible = "qcom,sdm845-lpasscc";
+   reg = <0x17014000 0x1f004>, <0x1730 0x200>;
+   reg-names = "cc", "qdsp6ss";
+   #clock-cells = <1>;
+   };
diff --git a/include/dt-bindings/clock/qcom,gcc-sdm845.h 
b/include/dt-bindings/clock/qcom,gcc-sdm845.h
index b8eae5a..968fa65 100644
--- a/include/dt-bindings/clock/qcom,gcc-sdm845.h
+++ b/include/dt-bindings/clock/qcom,gcc-sdm845.h
@@ -197,6 +197,8 @@
 #define GCC_QSPI_CORE_CLK_SRC  187
 #define GCC_QSPI_CORE_CLK  188
 #define GCC_QSPI_CNOC_PERIPH_AHB_CLK   189
+#define GCC_LPASS_Q6_AXI_CLK   190
+#define GCC_LPASS_SWAY_CLK 191

 /* GCC Resets */
 #define GCC_MMSS_BCR   0
diff --git a/include/dt-bindings/clock/qcom,lpass-sdm845.h 
b/include/dt-bindings/clock/qcom,lpass-sdm845.h
new file mode 100644
index 000..015968e
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,lpass-sdm845.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_SDM_LPASS_SDM845_H
+#define _DT_BINDINGS_CLK_SDM_LPASS_SDM845_H
+
+#define LPASS_AUDIO_WRAPPER_AON_CLK0
+#define LPASS_Q6SS_AHBM_AON_CLK1
+#define LPASS_Q6SS_AHBS_AON_CLK2
+#define LPASS_QDSP6SS_XO_CLK   3
+#define LPASS_QDSP6SS_SLEEP_CLK4
+#define LPASS_QDSP6SS_CORE_CLK 5
+
+#endif
--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



Re: [PATCH] clk: qcom: gcc: Fix board clock node name

2018-11-10 Thread Taniya Das

Hello Vinod,

On 11/9/2018 3:20 PM, Vinod Koul wrote:

Device tree node name are not supposed to have "_" in them so fix the
node name use of xo_board to xo-board

Fixes: 652f1813c113 ("clk: qcom: gcc: Add global clock controller driver for 
QCS404")
Signed-off-by: Vinod Koul 
---

Steve: RobH pointed this on DTS patches, would be great if you can pick this
as a fix

  drivers/clk/qcom/gcc-qcs404.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/qcom/gcc-qcs404.c b/drivers/clk/qcom/gcc-qcs404.c
index e4ca6a45f313..ef1b267cb058 100644
--- a/drivers/clk/qcom/gcc-qcs404.c
+++ b/drivers/clk/qcom/gcc-qcs404.c
@@ -265,7 +265,7 @@ static struct clk_fixed_factor cxo = {
.div = 1,
.hw.init = &(struct clk_init_data){
.name = "cxo",
-   .parent_names = (const char *[]){ "xo_board" },
+   .parent_names = (const char *[]){ "xo-board" },
.num_parents = 1,
.ops = &clk_fixed_factor_ops,
},



This fixed clock needs to be removed, once the RPM<->SMD clocks are 
added. Why not have this clock part of the device Tree?


--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


Re: [PATCH 2/2] cpufreq: qcom-hw: Add support for QCOM cpufreq HW driver

2018-11-11 Thread Taniya Das

Hello Stephen,

Thanks for your comments.

On 11/4/2018 9:50 AM, Stephen Boyd wrote:

Quoting Taniya Das (2018-11-02 20:06:00)

Hello Stephen,

On 10/18/2018 5:02 AM, Stephen Boyd wrote:

Quoting Taniya Das (2018-10-11 04:36:01)

--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -121,6 +121,17 @@ config ARM_QCOM_CPUFREQ_KRYO

If in doubt, say N.

+config ARM_QCOM_CPUFREQ_HW
+   bool "QCOM CPUFreq HW driver"


Is there any reason this can't be a module?



We do not have any use cases where we need to support it as module.


Ok, so it could easily be tristate then? Why not allow it?



I have checked other vendors CPUfreq drivers and those too support only 
"bool".





diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c 
b/drivers/cpufreq/qcom-cpufreq-hw.c
new file mode 100644
index 000..fe1c264
--- /dev/null
+++ b/drivers/cpufreq/qcom-cpufreq-hw.c
@@ -0,0 +1,354 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */

[...]

+
+static const u16 cpufreq_qcom_std_offsets[REG_ARRAY_SIZE] = {


Is this going to change in the future?



Yes, they could change and that was the reason to introduce the offsets.
This was discussed earlier too with Sudeep and was to add them.


+   [REG_ENABLE]= 0x0,


This is only used once? Maybe it could be removed.


+   [REG_LUT_TABLE] = 0x110,


And this is only used during probe to figure out the supported
frequencies. So we definitely don't need to store around the registers
after probe in an array of iomem pointers. The only one that we need
after probe is the one below.


+   [REG_PERF_STATE]= 0x920,
+};
+


As these address offsets could change, so I am of the opinion to leave 
them as it is.



+static struct cpufreq_qcom *qcom_freq_domain_map[NR_CPUS];
+
+static int
+qcom_cpufreq_hw_target_index(struct cpufreq_policy *policy,
+unsigned int index)
+{
+   struct cpufreq_qcom *c = policy->driver_data;
+
+   writel_relaxed(index, c->reg_bases[REG_PERF_STATE]);


Why can't we avoid the indirection here and store the perf_state pointer
in probe? Then we don't have to indirect through a table to perform the
register write.



As the offsets could change and that was the reason to add this.


With fast switching we can avoid incurring any extra instructions, so
please make another iomem pointer in the cpufreq_qcom struct just for
writing the index or if possible, just pass the iomem pointer that
points to the REG_PERF_STATE as the policy->driver_data variable here.
Then we have the address in hand without any extra load. If my
understanding is correct, we don't need to keep around anything besides
this register address anyway so we should be able to just load it and
write it immediately.



The c->reg_bases[] is just an index to the updated bases addresses. I am 
not clear as to why it would incur an extra instruction.


The below code would already take care of it.

+   for (i = REG_ENABLE; i < REG_ARRAY_SIZE; i++)
+   c->reg_bases[i] = base + offsets[i];
+

--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


Re: [PATCH v3 3/3] clk: qcom: Add display clock controller driver for SDM845

2018-07-08 Thread Taniya Das

Hello Stephen,

Thanks for your review comments.

On 7/9/2018 5:24 AM, Stephen Boyd wrote:

Quoting Taniya Das (2018-06-23 07:19:27)

diff --git a/drivers/clk/qcom/dispcc-sdm845.c b/drivers/clk/qcom/dispcc-sdm845.c
new file mode 100644
index 000..af437e0
--- /dev/null
+++ b/drivers/clk/qcom/dispcc-sdm845.c
@@ -0,0 +1,674 @@
+// SPDX-License-Identifier: GPL-2.0

[...]

+static struct clk_alpha_pll disp_cc_pll0 = {
+   .offset = 0x0,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "disp_cc_pll0",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = &clk_alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
+   .cmd_rcgr = 0x20d0,
+   .mnd_width = 0,
+   .hid_width = 5,
+   .parent_map = disp_cc_parent_map_0,
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "disp_cc_mdss_byte0_clk_src",
+   .parent_names = disp_cc_parent_names_0,
+   .num_parents = 4,
+   .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,


Why is there the no cache flag? Last time I asked I don't think I got
any answer, and there isn't a comment here so please at least add a
comment to the code so we don't forget.



I think you missed my comment from the earlier email. I would add the 
comment and submit again.


> Why is the nocache flag needed? Applies to all clks in this file.
>

This flag is required for all RCGs whose PLLs are controlled outside the 
clock controller. The display code would require the recalculated rate 
always.



+   .ops = &clk_byte2_ops,
+   },
+};
+
+static struct clk_rcg2 disp_cc_mdss_byte1_clk_src = {
+   .cmd_rcgr = 0x20ec,
+   .mnd_width = 0,
+   .hid_width = 5,
+   .parent_map = disp_cc_parent_map_0,
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "disp_cc_mdss_byte1_clk_src",
+   .parent_names = disp_cc_parent_names_0,
+   .num_parents = 4,
+   .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
+   .ops = &clk_byte2_ops,
+   },
+};
+
+static const struct freq_tbl ftbl_disp_cc_mdss_esc0_clk_src[] = {
+   F(1920, P_BI_TCXO, 1, 0, 0),
+   { }
+};
+
+static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
+   .cmd_rcgr = 0x2108,
+   .mnd_width = 0,
+   .hid_width = 5,
+   .parent_map = disp_cc_parent_map_0,
+   .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "disp_cc_mdss_esc0_clk_src",
+   .parent_names = disp_cc_parent_names_0,
+   .num_parents = 4,
+   .ops = &clk_rcg2_ops,
+   },
+};
+
+static struct clk_rcg2 disp_cc_mdss_esc1_clk_src = {
+   .cmd_rcgr = 0x2120,
+   .mnd_width = 0,
+   .hid_width = 5,
+   .parent_map = disp_cc_parent_map_0,
+   .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "disp_cc_mdss_esc1_clk_src",
+   .parent_names = disp_cc_parent_names_0,
+   .num_parents = 4,
+   .ops = &clk_rcg2_ops,
+   },
+};
+

[...]

+
+MODULE_LICENSE("GPL v2");


MODULE_DESCRIPTION?



--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


Re: [PATCH v3 3/3] clk: qcom: Add display clock controller driver for SDM845

2018-07-09 Thread Taniya Das




On 7/9/2018 11:46 AM, Stephen Boyd wrote:

Quoting Taniya Das (2018-07-08 20:38:03)

Hello Stephen,

Thanks for your review comments.

On 7/9/2018 5:24 AM, Stephen Boyd wrote:

Quoting Taniya Das (2018-06-23 07:19:27)

diff --git a/drivers/clk/qcom/dispcc-sdm845.c b/drivers/clk/qcom/dispcc-sdm845.c
new file mode 100644
index 000..af437e0
--- /dev/null
+++ b/drivers/clk/qcom/dispcc-sdm845.c
@@ -0,0 +1,674 @@
+// SPDX-License-Identifier: GPL-2.0

[...]

+static struct clk_alpha_pll disp_cc_pll0 = {
+   .offset = 0x0,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "disp_cc_pll0",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = &clk_alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
+   .cmd_rcgr = 0x20d0,
+   .mnd_width = 0,
+   .hid_width = 5,
+   .parent_map = disp_cc_parent_map_0,
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "disp_cc_mdss_byte0_clk_src",
+   .parent_names = disp_cc_parent_names_0,
+   .num_parents = 4,
+   .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,


Why is there the no cache flag? Last time I asked I don't think I got
any answer, and there isn't a comment here so please at least add a
comment to the code so we don't forget.



I think you missed my comment from the earlier email. I would add the
comment and submit again.


Hmm.. ok.



  > Why is the nocache flag needed? Applies to all clks in this file.
  >

This flag is required for all RCGs whose PLLs are controlled outside the
clock controller. The display code would require the recalculated rate
always.


Right. Why is the PLL controlled outside of the clock controller? The
rate should propagate upward to the PLL from here, so who's going
outside of that?

The DSI0/1 PLL are not part of the display clock controller, but in the 
display subsystem which are managed by the DRM drivers. When DRM drivers

query for the rate clock driver should always return the non cached rates.
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


Re: [PATCH v3 3/3] clk: qcom: Add display clock controller driver for SDM845

2018-07-09 Thread Taniya Das




On 7/9/2018 1:07 PM, Stephen Boyd wrote:

Quoting Taniya Das (2018-07-09 00:07:21)



On 7/9/2018 11:46 AM, Stephen Boyd wrote:


   > Why is the nocache flag needed? Applies to all clks in this file.
   >

This flag is required for all RCGs whose PLLs are controlled outside the
clock controller. The display code would require the recalculated rate
always.


Right. Why is the PLL controlled outside of the clock controller? The
rate should propagate upward to the PLL from here, so who's going
outside of that?


The DSI0/1 PLL are not part of the display clock controller, but in the
display subsystem which are managed by the DRM drivers. When DRM drivers
query for the rate clock driver should always return the non cached rates.


Why? Is the DSI PLL changing rate all the time, randomly, without going
through the clk APIs to do so?



Hmm, I am afraid I do not have an answer for this, but this was the 
requirement to always return the non cached rates from the clock driver.



--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--


[PATCH v2 0/2] clk: qcom: Add support for RCG to register for DFS

2018-06-28 Thread Taniya Das
 [v2]
  * Move the dfs register function 'qcom_cc_register_rcg_dfs'
to clk-rcg2.c instead of common.c
  * At boot read the DFS enable register and override the clk_ops
to be used for dfs or non-dfs RCGs.
  * Remove flag 'dfs_enabled'.
  * Remove functions 'clk_rcg2_dfs_determine_rate_lazy'
  * Remove 'struct dfs_table *dfs_entry'
  * Remove '_freq_tbl_determine_dfs_rate'
  * Combine the function 'clk_index_pre_div_and_mode' and 'calculate_m_and_n'
to a single function and named it 'clk_rcg2_calculate_m_and_n'.
  * Remove taking M/N/PERF offsets as function arguments.
  * Add clocks in gcc-sdm845.c the DFS clock array to register.

 [v1]
   * Update SPDX for files.
   * Add new clk_ops for DFS mode which would be used if dfs is enabled,
 else fall back to the clk_rcg2_shared_ops.
   * Use kcalloc in place kzalloc.
   * Fixed the return type for 'clk_parent_index_pre_div_and_mode' which
 is now renamed to 'clk_index_pre_div_and_mode'.
   * Removed return of -EPERM from 'clk_rcg2_set_rate' and new dfs
 clk_ops is introduced.
   * Pass frequency table entry structure to function calculate_m_and_n.
   * Remove desc from qcom_cc_register_rcg_dfs and instead pass array of
 clk_rcg2.
   * Add a dfs_enable flag to identify if dfs mode is enabled.

In the cases where a RCG requires a Dynamic Frequency switch support
requires to register which would at runtime read the clock perf level
registers to identify the frequencies supported and update the frequency
table accordingly.

Taniya Das (2):
  clk: qcom: Add support for RCG to register for DFS
  clk: qcom: gcc: Register QUPv3 RCGs for DFS on SDM845

 drivers/clk/qcom/clk-rcg.h|   5 +
 drivers/clk/qcom/clk-rcg2.c   | 214 ++
 drivers/clk/qcom/common.c |  14 +--
 drivers/clk/qcom/common.h |  16 +---
 drivers/clk/qcom/gcc-sdm845.c |  27 +-
 5 files changed, 250 insertions(+), 26 deletions(-)

--
Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
of the Code Aurora Forum, hosted by the  Linux Foundation.



  1   2   3   4   5   >