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

2018-08-13 Thread 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 
---
 drivers/clk/qcom/Kconfig|   9 +
 drivers/clk/qcom/Makefile   |   1 +
 drivers/clk/qcom/gpucc-sdm845.c | 438 
 3 files changed, 448 insertions(+)
 create mode 100644 drivers/clk/qcom/gpucc-sdm845.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 0647686..1595464 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -244,6 +244,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 c4ed36f..93c1089 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -42,5 +42,6 @@ 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_GPUCC_845) += gpucc-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/gpucc-sdm845.c b/drivers/clk/qcom/gpucc-sdm845.c
new file mode 100644
index 000..7a11b70
--- /dev/null
+++ b/drivers/clk/qcom/gpucc-sdm845.c
@@ -0,0 +1,438 @@
+// 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_PLL0_OUT_EVEN,
+   P_GPU_CC_PLL0_OUT_MAIN,
+   P_GPU_CC_PLL0_OUT_ODD,
+   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_PLL0_OUT_MAIN, 1 },
+   { 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_pll0",
+   "gpu_cc_pll1",
+   "gcc_gpu_gpll0_clk_src",
+   "gcc_gpu_gpll0_div_clk_src",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map gpu_cc_parent_map_1[] = {
+   { P_BI_TCXO, 0 },
+   { P_GPU_CC_PLL0_OUT_EVEN, 1 },
+   { P_GPU_CC_PLL0_OUT_ODD, 2 },
+   { P_GPU_CC_PLL1_OUT_EVEN, 3 },
+   { P_GPU_CC_PLL1_OUT_ODD, 4 },
+   { P_GPLL0_OUT_MAIN, 5 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gpu_cc_parent_names_1[] = {
+   "bi_tcxo",
+   "gpu_cc_pll0_out_even",
+   "gpu_cc_pll0_out_odd",
+   "gpu_cc_pll1_out_even",
+   "gpu_cc_pll1_out_odd",
+   "gcc_gpu_gpll0_clk_src",
+   "core_bi_pll_test_se",
+};
+
+static const struct alpha_pll_config gpu_cc_pll0_config = {
+   .l = 0x1d,
+   .alpha = 0x2aaa,
+};
+
+static const struct alpha_pll_config gpu_cc_pll1_config = {
+   .l = 0x1a,
+   .alpha = 0xaab,
+};
+
+static struct clk_alpha_pll gpu_cc_pll0 = {
+   .offset = 0x0,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "gpu_cc_pll0",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static const struct clk_div_table post_div_table_fabia_even[] = {
+   { 0x0, 1 },
+};
+
+static struct clk_alpha_pll_postd

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

2018-08-13 Thread 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 
---
 drivers/clk/qcom/Kconfig|   9 +
 drivers/clk/qcom/Makefile   |   1 +
 drivers/clk/qcom/gpucc-sdm845.c | 438 
 3 files changed, 448 insertions(+)
 create mode 100644 drivers/clk/qcom/gpucc-sdm845.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 0647686..1595464 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -244,6 +244,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 c4ed36f..93c1089 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -42,5 +42,6 @@ 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_GPUCC_845) += gpucc-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/gpucc-sdm845.c b/drivers/clk/qcom/gpucc-sdm845.c
new file mode 100644
index 000..7a11b70
--- /dev/null
+++ b/drivers/clk/qcom/gpucc-sdm845.c
@@ -0,0 +1,438 @@
+// 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_PLL0_OUT_EVEN,
+   P_GPU_CC_PLL0_OUT_MAIN,
+   P_GPU_CC_PLL0_OUT_ODD,
+   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_PLL0_OUT_MAIN, 1 },
+   { 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_pll0",
+   "gpu_cc_pll1",
+   "gcc_gpu_gpll0_clk_src",
+   "gcc_gpu_gpll0_div_clk_src",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map gpu_cc_parent_map_1[] = {
+   { P_BI_TCXO, 0 },
+   { P_GPU_CC_PLL0_OUT_EVEN, 1 },
+   { P_GPU_CC_PLL0_OUT_ODD, 2 },
+   { P_GPU_CC_PLL1_OUT_EVEN, 3 },
+   { P_GPU_CC_PLL1_OUT_ODD, 4 },
+   { P_GPLL0_OUT_MAIN, 5 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gpu_cc_parent_names_1[] = {
+   "bi_tcxo",
+   "gpu_cc_pll0_out_even",
+   "gpu_cc_pll0_out_odd",
+   "gpu_cc_pll1_out_even",
+   "gpu_cc_pll1_out_odd",
+   "gcc_gpu_gpll0_clk_src",
+   "core_bi_pll_test_se",
+};
+
+static const struct alpha_pll_config gpu_cc_pll0_config = {
+   .l = 0x1d,
+   .alpha = 0x2aaa,
+};
+
+static const struct alpha_pll_config gpu_cc_pll1_config = {
+   .l = 0x1a,
+   .alpha = 0xaab,
+};
+
+static struct clk_alpha_pll gpu_cc_pll0 = {
+   .offset = 0x0,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "gpu_cc_pll0",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static const struct clk_div_table post_div_table_fabia_even[] = {
+   { 0x0, 1 },
+};
+
+static struct clk_alpha_pll_postd

[PATCH v3 3/4] dt-bindings: clock: Introduce QCOM Graphics clock bindings

2018-08-13 Thread 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  | 38 ++
 2 files changed, 56 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..643b42a
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,gpucc-sdm845.h
@@ -0,0 +1,38 @@
+/* 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_CRC_AHB_CLK 0
+#define GPU_CC_CX_APB_CLK  1
+#define GPU_CC_CX_GFX3D_CLK2
+#define GPU_CC_CX_GFX3D_SLV_CLK3
+#define GPU_CC_CX_GMU_CLK  4
+#define GPU_CC_CX_SNOC_DVM_CLK 5
+#define GPU_CC_CXO_CLK 6
+#define GPU_CC_GMU_CLK_SRC 7
+#define GPU_CC_GX_GMU_CLK  8
+#define GPU_CC_GX_GFX3D_CLK_SRC9
+#define GPU_CC_GX_GFX3D_CLK10
+#define GPU_CC_PLL011
+#define GPU_CC_PLL0_OUT_EVEN   12
+#define GPU_CC_PLL113
+
+/* GPU_CC Resets */
+#define GPUCC_GPU_CC_ACD_BCR   0
+#define GPUCC_GPU_CC_CX_BCR1
+#define GPUCC_GPU_CC_GFX3D_AON_BCR 2
+#define GPUCC_GPU_CC_GMU_BCR   3
+#define GPUCC_GPU_CC_GX_BCR4
+#define GPUCC_GPU_CC_SPDM_BCR  5
+#define GPUCC_GPU_CC_XO_BCR6
+
+/* 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 Code Aurora Forum, hosted by The Linux Foundation



[PATCH v3 3/4] dt-bindings: clock: Introduce QCOM Graphics clock bindings

2018-08-13 Thread 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  | 38 ++
 2 files changed, 56 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..643b42a
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,gpucc-sdm845.h
@@ -0,0 +1,38 @@
+/* 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_CRC_AHB_CLK 0
+#define GPU_CC_CX_APB_CLK  1
+#define GPU_CC_CX_GFX3D_CLK2
+#define GPU_CC_CX_GFX3D_SLV_CLK3
+#define GPU_CC_CX_GMU_CLK  4
+#define GPU_CC_CX_SNOC_DVM_CLK 5
+#define GPU_CC_CXO_CLK 6
+#define GPU_CC_GMU_CLK_SRC 7
+#define GPU_CC_GX_GMU_CLK  8
+#define GPU_CC_GX_GFX3D_CLK_SRC9
+#define GPU_CC_GX_GFX3D_CLK10
+#define GPU_CC_PLL011
+#define GPU_CC_PLL0_OUT_EVEN   12
+#define GPU_CC_PLL113
+
+/* GPU_CC Resets */
+#define GPUCC_GPU_CC_ACD_BCR   0
+#define GPUCC_GPU_CC_CX_BCR1
+#define GPUCC_GPU_CC_GFX3D_AON_BCR 2
+#define GPUCC_GPU_CC_GMU_BCR   3
+#define GPUCC_GPU_CC_GX_BCR4
+#define GPUCC_GPU_CC_SPDM_BCR  5
+#define GPUCC_GPU_CC_XO_BCR6
+
+/* 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 Code Aurora Forum, hosted by The Linux Foundation



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

2018-08-13 Thread Amit Nischal
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 
---
 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 
 #include 
 #include 
 #include 
@@ -208,11 +210,41 @@ static inline void gdsc_assert_reset_aon(struct gdsc *sc)
regmap_update_bits(sc->regmap, sc->clamp_io_ctrl,
   GMEM_RESET_MASK, 0);
 }
+
+static int gdsc_clk_prepare_enable(struct gdsc *sc)
+{
+   int i, ret;
+
+   for (i = 0; i < sc->clk_count; i++) {
+   ret = clk_prepare_enable(sc->clk_hws[i]->clk);
+   if (ret) {
+   for (i--; i >= 0; i--)
+   clk_disable_unprepare(sc->clk_hws[i]->clk);
+   return ret;
+   }
+   }
+   return 0;
+}
+
+static void gdsc_clk_disable_unprepare(struct gdsc *sc)
+{
+   int i;
+
+   for (i = 0; i < sc->clk_count; i++)
+   clk_disable_unprepare(sc->clk_hws[i]->clk);
+}
+
 static int gdsc_enable(struct generic_pm_domain *domain)
 {
struct gdsc *sc = domain_to_gdsc(domain);
int ret;
 
+   if (sc->clk_count) {
+   ret = gdsc_clk_prepare_enable(sc);
+   if (ret)
+   return ret;
+   }
+
if (sc->pwrsts == PWRSTS_ON)
return gdsc_deassert_reset(sc);
 
@@ -260,6 +292,9 @@ static int gdsc_enable(struct generic_pm_domain *domain)
udelay(1);
}
 
+   if (sc->clk_count)
+   gdsc_clk_disable_unprepare(sc);
+
return 0;
 }
 
@@ -268,6 +303,12 @@ static int gdsc_disable(struct generic_pm_domain *domain)
struct gdsc *sc = domain_to_gdsc(domain);
int ret;
 
+   if (sc->clk_count) {
+   ret = gdsc_clk_prepare_enable(sc);
+   if (ret)
+   return ret;
+   }
+
if (sc->pwrsts == PWRSTS_ON)
return gdsc_assert_reset(sc);
 
@@ -299,6 +340,9 @@ static int gdsc_disable(struct generic_pm_domain *domain)
if (sc->flags & CLAMP_IO)
gdsc_assert_clamp_io(sc);
 
+   if (sc->clk_count)
+   gdsc_clk_disable_unprepare(sc);
+
return 0;
 }
 
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
index bd1f2c7..59957d7 100644
--- a/drivers/clk/qcom/gdsc.h
+++ b/drivers/clk/qcom/gdsc.h
@@ -17,6 +17,7 @@
 #include 
 #include 
 
+struct clk_hw;
 struct regmap;
 struct reset_controller_dev;
 
@@ -32,6 +33,8 @@
  * @resets: ids of resets associated with this gdsc
  * @reset_count: number of @resets
  * @rcdev: reset controller
+ * @clk_count: number of associated clocks
+ * @clk_hws: clk_hw pointers for associated clocks with gdsc
  */
 struct gdsc {
struct generic_pm_domainpd;
@@ -60,6 +63,8 @@ struct gdsc {
struct reset_controller_dev *rcdev;
unsigned int*resets;
unsigned intreset_count;
+   unsigned intclk_count;
+   struct clk_hw   *clk_hws[];
 };
 
 struct gdsc_desc {
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



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

2018-08-13 Thread Amit Nischal
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 
---
 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 
 #include 
 #include 
 #include 
@@ -208,11 +210,41 @@ static inline void gdsc_assert_reset_aon(struct gdsc *sc)
regmap_update_bits(sc->regmap, sc->clamp_io_ctrl,
   GMEM_RESET_MASK, 0);
 }
+
+static int gdsc_clk_prepare_enable(struct gdsc *sc)
+{
+   int i, ret;
+
+   for (i = 0; i < sc->clk_count; i++) {
+   ret = clk_prepare_enable(sc->clk_hws[i]->clk);
+   if (ret) {
+   for (i--; i >= 0; i--)
+   clk_disable_unprepare(sc->clk_hws[i]->clk);
+   return ret;
+   }
+   }
+   return 0;
+}
+
+static void gdsc_clk_disable_unprepare(struct gdsc *sc)
+{
+   int i;
+
+   for (i = 0; i < sc->clk_count; i++)
+   clk_disable_unprepare(sc->clk_hws[i]->clk);
+}
+
 static int gdsc_enable(struct generic_pm_domain *domain)
 {
struct gdsc *sc = domain_to_gdsc(domain);
int ret;
 
+   if (sc->clk_count) {
+   ret = gdsc_clk_prepare_enable(sc);
+   if (ret)
+   return ret;
+   }
+
if (sc->pwrsts == PWRSTS_ON)
return gdsc_deassert_reset(sc);
 
@@ -260,6 +292,9 @@ static int gdsc_enable(struct generic_pm_domain *domain)
udelay(1);
}
 
+   if (sc->clk_count)
+   gdsc_clk_disable_unprepare(sc);
+
return 0;
 }
 
@@ -268,6 +303,12 @@ static int gdsc_disable(struct generic_pm_domain *domain)
struct gdsc *sc = domain_to_gdsc(domain);
int ret;
 
+   if (sc->clk_count) {
+   ret = gdsc_clk_prepare_enable(sc);
+   if (ret)
+   return ret;
+   }
+
if (sc->pwrsts == PWRSTS_ON)
return gdsc_assert_reset(sc);
 
@@ -299,6 +340,9 @@ static int gdsc_disable(struct generic_pm_domain *domain)
if (sc->flags & CLAMP_IO)
gdsc_assert_clamp_io(sc);
 
+   if (sc->clk_count)
+   gdsc_clk_disable_unprepare(sc);
+
return 0;
 }
 
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
index bd1f2c7..59957d7 100644
--- a/drivers/clk/qcom/gdsc.h
+++ b/drivers/clk/qcom/gdsc.h
@@ -17,6 +17,7 @@
 #include 
 #include 
 
+struct clk_hw;
 struct regmap;
 struct reset_controller_dev;
 
@@ -32,6 +33,8 @@
  * @resets: ids of resets associated with this gdsc
  * @reset_count: number of @resets
  * @rcdev: reset controller
+ * @clk_count: number of associated clocks
+ * @clk_hws: clk_hw pointers for associated clocks with gdsc
  */
 struct gdsc {
struct generic_pm_domainpd;
@@ -60,6 +63,8 @@ struct gdsc {
struct reset_controller_dev *rcdev;
unsigned int*resets;
unsigned intreset_count;
+   unsigned intclk_count;
+   struct clk_hw   *clk_hws[];
 };
 
 struct gdsc_desc {
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



[PATCH v3 0/4] Add QCOM graphics clock controller driver for SDM845

2018-08-13 Thread Amit Nischal
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 (4):
  clk: qcom: gdsc: Add support to enable/disable the clocks with GDSC
  clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845
  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/clk-rcg.h |   1 +
 drivers/clk/qcom/clk-rcg2.c|  86 +++-
 drivers/clk/qcom/gdsc.c|  44 +++
 drivers/clk/qcom/gdsc.h|   5 +
 drivers/clk/qcom/gpucc-sdm845.c| 438 +
 include/dt-bindings/clock/qcom,gpucc-sdm845.h  |  38 ++
 9 files changed, 638 insertions(+), 2 deletions(-)
 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 Code Aurora Forum, hosted by The Linux Foundation



[PATCH v3 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845

2018-08-13 Thread Amit Nischal
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 op. But due to the above
said requirement for GFX3D shared RCG, root_enable bit would be
already set by gdsc driver and clk_rcg2_shared_enable()should
not clear the root unless the disable is called.

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.

Signed-off-by: Amit Nischal 
---
 drivers/clk/qcom/clk-rcg.h  |  1 +
 drivers/clk/qcom/clk-rcg2.c | 86 +++--
 2 files changed, 85 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h
index dbd5a9e..081eca9 100644
--- a/drivers/clk/qcom/clk-rcg.h
+++ b/drivers/clk/qcom/clk-rcg.h
@@ -162,5 +162,6 @@ struct clk_rcg2 {
 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;
+extern const struct clk_ops clk_rcg2_gfx3d_ops;

 #endif
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index 52208d4..a57ce00 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -866,7 +866,7 @@ static int clk_rcg2_shared_set_rate_and_parent(struct 
clk_hw *hw,
return clk_rcg2_shared_set_rate(hw, rate, parent_rate);
 }

-static int clk_rcg2_shared_enable(struct clk_hw *hw)
+static int __clk_rcg2_shared_enable(struct clk_hw *hw)
 {
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
int ret;
@@ -879,7 +879,14 @@ static int clk_rcg2_shared_enable(struct clk_hw *hw)
if (ret)
return ret;

-   ret = update_config(rcg);
+   return update_config(rcg);
+}
+
+static int clk_rcg2_shared_enable(struct clk_hw *hw)
+{
+   int ret;
+
+   ret = __clk_rcg2_shared_enable(hw);
if (ret)
return ret;

@@ -929,3 +936,78 @@ 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);
+
+static int clk_rcg2_gfx3d_enable(struct clk_hw *hw)
+{
+   return __clk_rcg2_shared_enable(hw);
+}
+
+static int clk_rcg2_gfx3d_determine_rate(struct clk_hw *hw,
+   struct clk_rate_request *req)
+{
+   struct clk_rate_request parent_req = { };
+   struct clk_hw *p;
+   unsigned long rate = req->rate;
+   int ret;
+
+   rate = clamp(rate, req->min_rate, req->max_rate);
+
+   /* Get fixed parent - GPU_CC_PLL0_OUT_EVEN */
+   p = clk_hw_get_parent_by_index(hw, 1);
+
+   /* Parent should always run at twice of the requested rate */
+   parent_req.rate = 2 * rate;
+
+   ret = __clk_determine_rate(req->best_parent_hw, _req);
+   if (ret)
+   return ret;
+
+   req->best_parent_hw = p;
+   req->best_parent_rate = parent_req.rate;
+   req->rate = parent_req.rate / 2;
+
+   return 0;
+}
+
+static int clk_rcg2_gfx3d_set_rate(struct clk_hw *hw, unsigned long rate,
+   unsigned long parent_rate)
+{
+   struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+   int ret;
+   u32 cfg;
+
+   /* Configure fixed SRC and DIV */
+   cfg = rcg->parent_map[1].cfg << CFG_SRC_SEL_SHIFT;
+   cfg |= 0x3 << CFG_SRC_DIV_SHIFT;
+
+   ret = regmap_write(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, cfg);
+   if (ret)
+   return ret;
+
+   /*
+* In case clock is disabled, update the SRC and DIV only
+* and return without configuration update.
+*/
+   if (!__clk_is_enabled(hw->clk))
+   return 0;
+
+   return update_config(rcg);
+}
+
+static int clk_rcg2_gfx3d_set_rate_and_parent(struct clk_hw *hw,
+   unsigned long rate, unsigned long parent_rate, u8 index)
+{
+   return clk_rcg2_gfx3d_set_rate(hw, rate, parent_rate);
+}
+
+const struct clk_ops clk_rcg2_gfx3d_ops = {
+   .enable = clk_rcg2_gfx3d_enable,
+   .disable = clk_rcg2_shared_disable,
+   .get_parent = clk_rcg2_get_parent,
+   .set_parent = clk_rcg2_set_parent,
+   .recalc_rate = clk_rcg2_recalc_rate,
+   .determine_rate = clk_rcg2_gfx3d_determine_rate,
+   .set_rate = clk_rcg2_gfx3d_set_rate,
+   .set_rate_and_parent = clk_rcg2_gfx3d_set_rate_and_parent,
+};
+EXPORT_SYMBOL_GPL(clk_rcg2_gfx3d_ops);
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



[PATCH v3 0/4] Add QCOM graphics clock controller driver for SDM845

2018-08-13 Thread Amit Nischal
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 (4):
  clk: qcom: gdsc: Add support to enable/disable the clocks with GDSC
  clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845
  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/clk-rcg.h |   1 +
 drivers/clk/qcom/clk-rcg2.c|  86 +++-
 drivers/clk/qcom/gdsc.c|  44 +++
 drivers/clk/qcom/gdsc.h|   5 +
 drivers/clk/qcom/gpucc-sdm845.c| 438 +
 include/dt-bindings/clock/qcom,gpucc-sdm845.h  |  38 ++
 9 files changed, 638 insertions(+), 2 deletions(-)
 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 Code Aurora Forum, hosted by The Linux Foundation



[PATCH v3 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845

2018-08-13 Thread Amit Nischal
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 op. But due to the above
said requirement for GFX3D shared RCG, root_enable bit would be
already set by gdsc driver and clk_rcg2_shared_enable()should
not clear the root unless the disable is called.

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.

Signed-off-by: Amit Nischal 
---
 drivers/clk/qcom/clk-rcg.h  |  1 +
 drivers/clk/qcom/clk-rcg2.c | 86 +++--
 2 files changed, 85 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h
index dbd5a9e..081eca9 100644
--- a/drivers/clk/qcom/clk-rcg.h
+++ b/drivers/clk/qcom/clk-rcg.h
@@ -162,5 +162,6 @@ struct clk_rcg2 {
 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;
+extern const struct clk_ops clk_rcg2_gfx3d_ops;

 #endif
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index 52208d4..a57ce00 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -866,7 +866,7 @@ static int clk_rcg2_shared_set_rate_and_parent(struct 
clk_hw *hw,
return clk_rcg2_shared_set_rate(hw, rate, parent_rate);
 }

-static int clk_rcg2_shared_enable(struct clk_hw *hw)
+static int __clk_rcg2_shared_enable(struct clk_hw *hw)
 {
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
int ret;
@@ -879,7 +879,14 @@ static int clk_rcg2_shared_enable(struct clk_hw *hw)
if (ret)
return ret;

-   ret = update_config(rcg);
+   return update_config(rcg);
+}
+
+static int clk_rcg2_shared_enable(struct clk_hw *hw)
+{
+   int ret;
+
+   ret = __clk_rcg2_shared_enable(hw);
if (ret)
return ret;

@@ -929,3 +936,78 @@ 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);
+
+static int clk_rcg2_gfx3d_enable(struct clk_hw *hw)
+{
+   return __clk_rcg2_shared_enable(hw);
+}
+
+static int clk_rcg2_gfx3d_determine_rate(struct clk_hw *hw,
+   struct clk_rate_request *req)
+{
+   struct clk_rate_request parent_req = { };
+   struct clk_hw *p;
+   unsigned long rate = req->rate;
+   int ret;
+
+   rate = clamp(rate, req->min_rate, req->max_rate);
+
+   /* Get fixed parent - GPU_CC_PLL0_OUT_EVEN */
+   p = clk_hw_get_parent_by_index(hw, 1);
+
+   /* Parent should always run at twice of the requested rate */
+   parent_req.rate = 2 * rate;
+
+   ret = __clk_determine_rate(req->best_parent_hw, _req);
+   if (ret)
+   return ret;
+
+   req->best_parent_hw = p;
+   req->best_parent_rate = parent_req.rate;
+   req->rate = parent_req.rate / 2;
+
+   return 0;
+}
+
+static int clk_rcg2_gfx3d_set_rate(struct clk_hw *hw, unsigned long rate,
+   unsigned long parent_rate)
+{
+   struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+   int ret;
+   u32 cfg;
+
+   /* Configure fixed SRC and DIV */
+   cfg = rcg->parent_map[1].cfg << CFG_SRC_SEL_SHIFT;
+   cfg |= 0x3 << CFG_SRC_DIV_SHIFT;
+
+   ret = regmap_write(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, cfg);
+   if (ret)
+   return ret;
+
+   /*
+* In case clock is disabled, update the SRC and DIV only
+* and return without configuration update.
+*/
+   if (!__clk_is_enabled(hw->clk))
+   return 0;
+
+   return update_config(rcg);
+}
+
+static int clk_rcg2_gfx3d_set_rate_and_parent(struct clk_hw *hw,
+   unsigned long rate, unsigned long parent_rate, u8 index)
+{
+   return clk_rcg2_gfx3d_set_rate(hw, rate, parent_rate);
+}
+
+const struct clk_ops clk_rcg2_gfx3d_ops = {
+   .enable = clk_rcg2_gfx3d_enable,
+   .disable = clk_rcg2_shared_disable,
+   .get_parent = clk_rcg2_get_parent,
+   .set_parent = clk_rcg2_set_parent,
+   .recalc_rate = clk_rcg2_recalc_rate,
+   .determine_rate = clk_rcg2_gfx3d_determine_rate,
+   .set_rate = clk_rcg2_gfx3d_set_rate,
+   .set_rate_and_parent = clk_rcg2_gfx3d_set_rate_and_parent,
+};
+EXPORT_SYMBOL_GPL(clk_rcg2_gfx3d_ops);
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



Re: [PATCH 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845

2018-08-13 Thread Amit Nischal

On 2018-08-08 11:28, Stephen Boyd wrote:

Quoting Jordan Crouse (2018-08-06 08:04:37)

On Mon, Aug 06, 2018 at 02:37:18PM +0530, Amit Nischal wrote:
> On 2018-08-03 04:14, Stephen Boyd wrote:
> >Quoting Amit Nischal (2018-07-30 04:28:56)
> >>On 2018-07-25 12:28, Stephen Boyd wrote:
> >>>
> >>> Ok. Sounds good! Is the rate range call really needed? It can't be
> >>> determined in the PLL code with some table or avoided by making sure
> >>> GPU
> >>> uses OPP table with only approved frequencies?
> >>>
> >>
> >>Currently fabia PLL code does not have any table to check this and
> >>intention
> >>was to avoid relying on the client to call set_rate with only approved
> >>frequencies so we have added the set_rate_range() call in the GPUCC
> >>driver
> >>in order to set the rate range.
> >>
> >
> >But GPU will use OPP so it doesn't seem like it really buys us anything
> >here. And it really doesn't matter when the clk driver implementation
> >doesn't use the min/max to clamp the values of the round_rate()
> >call. Is
> >that being done here? I need to double check. I would be more convinced
> >if the implementation was looking at min/max to constrain the rate
> >requested.
> >
>
> So our understanding is that GPU(client) driver will always call the
> set_rate with approved frequencies only and we can completely rely
> on the
> client. Is our understanding is correct?


First: on sdm845 the software doesn't set the GPU clocks - we rely on 
the GMU
firmware to do that on our behalf but for the GPU at least this is an 
academic

exercise.


So what is this GPU clk driver for then?



But that said: traditionally we've expected that the clock driver 
correctly
clamp the requested rate to the correct values. In the past we have 
taken
advantage of this and we may in the future. I don't think it is 
reasonable
to require the leaf driver to only pass "approved" frequencies 
especially
since we depend on our own OPP table that may or may not be similar to 
the

one used by the clock driver.



Ok. Sounds like things can't be kept in sync between the clk driver and
the OPP tables. Why is that hard to do?

Either way, I'd be fine if the code actually used the frequency limits
to round the rate to something within range, but I don't recall seeing
that being done here. So if the min/max limits stay, the clk driver
should round to within that range.



Thanks Stephen for your suggestion. I have modified the existing
determine_rate() op to use the min/max limits and round the requested
rate so that it stays withing the set_rate range. I will submit the
same in the next patch series.



--
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


Re: [PATCH 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845

2018-08-13 Thread Amit Nischal

On 2018-08-08 11:28, Stephen Boyd wrote:

Quoting Jordan Crouse (2018-08-06 08:04:37)

On Mon, Aug 06, 2018 at 02:37:18PM +0530, Amit Nischal wrote:
> On 2018-08-03 04:14, Stephen Boyd wrote:
> >Quoting Amit Nischal (2018-07-30 04:28:56)
> >>On 2018-07-25 12:28, Stephen Boyd wrote:
> >>>
> >>> Ok. Sounds good! Is the rate range call really needed? It can't be
> >>> determined in the PLL code with some table or avoided by making sure
> >>> GPU
> >>> uses OPP table with only approved frequencies?
> >>>
> >>
> >>Currently fabia PLL code does not have any table to check this and
> >>intention
> >>was to avoid relying on the client to call set_rate with only approved
> >>frequencies so we have added the set_rate_range() call in the GPUCC
> >>driver
> >>in order to set the rate range.
> >>
> >
> >But GPU will use OPP so it doesn't seem like it really buys us anything
> >here. And it really doesn't matter when the clk driver implementation
> >doesn't use the min/max to clamp the values of the round_rate()
> >call. Is
> >that being done here? I need to double check. I would be more convinced
> >if the implementation was looking at min/max to constrain the rate
> >requested.
> >
>
> So our understanding is that GPU(client) driver will always call the
> set_rate with approved frequencies only and we can completely rely
> on the
> client. Is our understanding is correct?


First: on sdm845 the software doesn't set the GPU clocks - we rely on 
the GMU
firmware to do that on our behalf but for the GPU at least this is an 
academic

exercise.


So what is this GPU clk driver for then?



But that said: traditionally we've expected that the clock driver 
correctly
clamp the requested rate to the correct values. In the past we have 
taken
advantage of this and we may in the future. I don't think it is 
reasonable
to require the leaf driver to only pass "approved" frequencies 
especially
since we depend on our own OPP table that may or may not be similar to 
the

one used by the clock driver.



Ok. Sounds like things can't be kept in sync between the clk driver and
the OPP tables. Why is that hard to do?

Either way, I'd be fine if the code actually used the frequency limits
to round the rate to something within range, but I don't recall seeing
that being done here. So if the min/max limits stay, the clk driver
should round to within that range.



Thanks Stephen for your suggestion. I have modified the existing
determine_rate() op to use the min/max limits and round the requested
rate so that it stays withing the set_rate range. I will submit the
same in the next patch series.



--
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


[PATCH v3] clk: qcom: Add camera clock controller driver for SDM845

2018-08-08 Thread Amit Nischal
Add support for the camera clock controller found on SDM845
based devices. This would allow camera drivers to probe and
control their clocks.

Signed-off-by: Amit Nischal 
---
 drivers/clk/qcom/Kconfig|8 +
 drivers/clk/qcom/Makefile   |1 +
 drivers/clk/qcom/camcc-sdm845.c | 1745 +++
 3 files changed, 1754 insertions(+)
 create mode 100644 drivers/clk/qcom/camcc-sdm845.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 1595464..f551432 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -235,6 +235,14 @@ 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_CAMCC_845
+   tristate "SDM845 Camera Clock Controller"
+   depends on COMMON_CLK_QCOM
+   select SDM_GCC_845
+   help
+ Support for the camera clock controller on SDM845 devices.
+ Say Y if you want to support camera devices and camera functionality.
+
 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 93c1089..ada8750 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -41,6 +41,7 @@ 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_CAMCC_845) += camcc-sdm845.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
diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c
new file mode 100644
index 000..1b2cefe
--- /dev/null
+++ b/drivers/clk/qcom/camcc-sdm845.c
@@ -0,0 +1,1745 @@
+// 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-rcg.h"
+#include "clk-regmap.h"
+#include "gdsc.h"
+
+enum {
+   P_BI_TCXO,
+   P_CAM_CC_PLL0_OUT_EVEN,
+   P_CAM_CC_PLL1_OUT_EVEN,
+   P_CAM_CC_PLL2_OUT_EVEN,
+   P_CAM_CC_PLL3_OUT_EVEN,
+   P_CORE_BI_PLL_TEST_SE,
+};
+
+static const struct parent_map cam_cc_parent_map_0[] = {
+   { P_BI_TCXO, 0 },
+   { P_CAM_CC_PLL2_OUT_EVEN, 1 },
+   { P_CAM_CC_PLL1_OUT_EVEN, 2 },
+   { P_CAM_CC_PLL3_OUT_EVEN, 5 },
+   { P_CAM_CC_PLL0_OUT_EVEN, 6 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const cam_cc_parent_names_0[] = {
+   "bi_tcxo",
+   "cam_cc_pll2_out_even",
+   "cam_cc_pll1_out_even",
+   "cam_cc_pll3_out_even",
+   "cam_cc_pll0_out_even",
+   "core_bi_pll_test_se",
+};
+
+static struct clk_alpha_pll cam_cc_pll0 = {
+   .offset = 0x0,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll0",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static const struct clk_div_table post_div_table_fabia_even[] = {
+   { 0x0, 1 },
+   { 0x1, 2 },
+   { }
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = {
+   .offset = 0x0,
+   .post_div_shift = 8,
+   .post_div_table = post_div_table_fabia_even,
+   .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+   .width = 4,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll0_out_even",
+   .parent_names = (const char *[]){ "cam_cc_pll0" },
+   .num_parents = 1,
+   .ops = _alpha_pll_postdiv_fabia_ops,
+   },
+};
+
+static struct clk_alpha_pll cam_cc_pll1 = {
+   .offset = 0x1000,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll1",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = {
+   .offset = 0x1000,
+   .post_div_shift = 8,
+   .post_div_table = post_div_table_fabia_even,
+   .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+   .width = 4,
+   .

[PATCH v3] clk: qcom: Add camera clock controller driver for SDM845

2018-08-08 Thread Amit Nischal
Add support for the camera clock controller found on SDM845
based devices. This would allow camera drivers to probe and
control their clocks.

Signed-off-by: Amit Nischal 
---
 drivers/clk/qcom/Kconfig|8 +
 drivers/clk/qcom/Makefile   |1 +
 drivers/clk/qcom/camcc-sdm845.c | 1745 +++
 3 files changed, 1754 insertions(+)
 create mode 100644 drivers/clk/qcom/camcc-sdm845.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 1595464..f551432 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -235,6 +235,14 @@ 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_CAMCC_845
+   tristate "SDM845 Camera Clock Controller"
+   depends on COMMON_CLK_QCOM
+   select SDM_GCC_845
+   help
+ Support for the camera clock controller on SDM845 devices.
+ Say Y if you want to support camera devices and camera functionality.
+
 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 93c1089..ada8750 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -41,6 +41,7 @@ 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_CAMCC_845) += camcc-sdm845.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
diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c
new file mode 100644
index 000..1b2cefe
--- /dev/null
+++ b/drivers/clk/qcom/camcc-sdm845.c
@@ -0,0 +1,1745 @@
+// 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-rcg.h"
+#include "clk-regmap.h"
+#include "gdsc.h"
+
+enum {
+   P_BI_TCXO,
+   P_CAM_CC_PLL0_OUT_EVEN,
+   P_CAM_CC_PLL1_OUT_EVEN,
+   P_CAM_CC_PLL2_OUT_EVEN,
+   P_CAM_CC_PLL3_OUT_EVEN,
+   P_CORE_BI_PLL_TEST_SE,
+};
+
+static const struct parent_map cam_cc_parent_map_0[] = {
+   { P_BI_TCXO, 0 },
+   { P_CAM_CC_PLL2_OUT_EVEN, 1 },
+   { P_CAM_CC_PLL1_OUT_EVEN, 2 },
+   { P_CAM_CC_PLL3_OUT_EVEN, 5 },
+   { P_CAM_CC_PLL0_OUT_EVEN, 6 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const cam_cc_parent_names_0[] = {
+   "bi_tcxo",
+   "cam_cc_pll2_out_even",
+   "cam_cc_pll1_out_even",
+   "cam_cc_pll3_out_even",
+   "cam_cc_pll0_out_even",
+   "core_bi_pll_test_se",
+};
+
+static struct clk_alpha_pll cam_cc_pll0 = {
+   .offset = 0x0,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll0",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static const struct clk_div_table post_div_table_fabia_even[] = {
+   { 0x0, 1 },
+   { 0x1, 2 },
+   { }
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = {
+   .offset = 0x0,
+   .post_div_shift = 8,
+   .post_div_table = post_div_table_fabia_even,
+   .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+   .width = 4,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll0_out_even",
+   .parent_names = (const char *[]){ "cam_cc_pll0" },
+   .num_parents = 1,
+   .ops = _alpha_pll_postdiv_fabia_ops,
+   },
+};
+
+static struct clk_alpha_pll cam_cc_pll1 = {
+   .offset = 0x1000,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll1",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = {
+   .offset = 0x1000,
+   .post_div_shift = 8,
+   .post_div_table = post_div_table_fabia_even,
+   .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+   .width = 4,
+   .

[PATCH v3] Add QCOM camera clock controller driver

2018-08-08 Thread Amit Nischal
Changes in v3:
1. Mentioned the name of the non-fixed PLL in the comment text.

Changes in v2:
Addressed below review comments - https://lkml.org/lkml/2018/7/23/377
1. Add comment to use clk_rcg2_shared_ops and CLK_SET_RATE_PARENT flag.
2. Replace commas with semicolon for PLL configuration in probe function.

Changes in v1:
This patch series adds a driver and device tree documentation binding
for the camera clock controller on some Qualcomm Technologies, Inc, SoCs
such as SDM845. This would allow camera drivers to probe and control
their clocks.

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

Amit Nischal (1):
  clk: qcom: Add camera clock controller driver for SDM845

 drivers/clk/qcom/Kconfig|8 +
 drivers/clk/qcom/Makefile   |1 +
 drivers/clk/qcom/camcc-sdm845.c | 1745 +++
 3 files changed, 1754 insertions(+)
 create mode 100644 drivers/clk/qcom/camcc-sdm845.c

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



[PATCH v3] Add QCOM camera clock controller driver

2018-08-08 Thread Amit Nischal
Changes in v3:
1. Mentioned the name of the non-fixed PLL in the comment text.

Changes in v2:
Addressed below review comments - https://lkml.org/lkml/2018/7/23/377
1. Add comment to use clk_rcg2_shared_ops and CLK_SET_RATE_PARENT flag.
2. Replace commas with semicolon for PLL configuration in probe function.

Changes in v1:
This patch series adds a driver and device tree documentation binding
for the camera clock controller on some Qualcomm Technologies, Inc, SoCs
such as SDM845. This would allow camera drivers to probe and control
their clocks.

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

Amit Nischal (1):
  clk: qcom: Add camera clock controller driver for SDM845

 drivers/clk/qcom/Kconfig|8 +
 drivers/clk/qcom/Makefile   |1 +
 drivers/clk/qcom/camcc-sdm845.c | 1745 +++
 3 files changed, 1754 insertions(+)
 create mode 100644 drivers/clk/qcom/camcc-sdm845.c

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



Re: [PATCH v2] clk: qcom: Add camera clock controller driver for SDM845

2018-08-08 Thread Amit Nischal

On 2018-08-02 22:30, Stephen Boyd wrote:

Quoting Amit Nischal (2018-07-30 02:22:20)
diff --git a/drivers/clk/qcom/camcc-sdm845.c 
b/drivers/clk/qcom/camcc-sdm845.c

new file mode 100644
index 000..702ca66
--- /dev/null
+++ b/drivers/clk/qcom/camcc-sdm845.c
@@ -0,0 +1,1744 @@
+   },
+};
+
+static const struct freq_tbl ftbl_cam_cc_bps_clk_src[] = {
+   F(1920, P_BI_TCXO, 1, 0, 0),
+   F(1, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0),
+   F(2, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0),
+   F(40400, P_CAM_CC_PLL1_OUT_EVEN, 2, 0, 0),
+   F(48000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0),
+   F(6, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0),
+   { }
+};
+
+/*
+ * As per HW design, some of the CAMCC RCGs needs to
+ * move to XO clock during their clock disable so using


Per hw design sure, but what about hw design is causing this?


The RCGs which sources to the CBCRs further connected to the
camera memory blocks needs to be moved to XO clock during
clock disable. This is required to power down the camera memories
gracefully as these memories cannot be powered down instantly.
And after memory power down, HW will gate the clock.




+ * clk_rcg2_shared_ops for such RCGs.
+ * Also, use CLK_SET_RATE_PARENT flag for the RCGs which
+ * have non-fixed PLL as parent source and requires


Mention the PLL that isn't fixed?



Yes sure. I will mention the PLL's name in the next patch.


+ * reconfiguration of the PLL frequency.
+ */
+static struct clk_rcg2 cam_cc_bps_clk_src = {
+   .cmd_rcgr = 0x600c,
+   .mnd_width = 0,

--
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


Re: [PATCH v2] clk: qcom: Add camera clock controller driver for SDM845

2018-08-08 Thread Amit Nischal

On 2018-08-02 22:30, Stephen Boyd wrote:

Quoting Amit Nischal (2018-07-30 02:22:20)
diff --git a/drivers/clk/qcom/camcc-sdm845.c 
b/drivers/clk/qcom/camcc-sdm845.c

new file mode 100644
index 000..702ca66
--- /dev/null
+++ b/drivers/clk/qcom/camcc-sdm845.c
@@ -0,0 +1,1744 @@
+   },
+};
+
+static const struct freq_tbl ftbl_cam_cc_bps_clk_src[] = {
+   F(1920, P_BI_TCXO, 1, 0, 0),
+   F(1, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0),
+   F(2, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0),
+   F(40400, P_CAM_CC_PLL1_OUT_EVEN, 2, 0, 0),
+   F(48000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0),
+   F(6, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0),
+   { }
+};
+
+/*
+ * As per HW design, some of the CAMCC RCGs needs to
+ * move to XO clock during their clock disable so using


Per hw design sure, but what about hw design is causing this?


The RCGs which sources to the CBCRs further connected to the
camera memory blocks needs to be moved to XO clock during
clock disable. This is required to power down the camera memories
gracefully as these memories cannot be powered down instantly.
And after memory power down, HW will gate the clock.




+ * clk_rcg2_shared_ops for such RCGs.
+ * Also, use CLK_SET_RATE_PARENT flag for the RCGs which
+ * have non-fixed PLL as parent source and requires


Mention the PLL that isn't fixed?



Yes sure. I will mention the PLL's name in the next patch.


+ * reconfiguration of the PLL frequency.
+ */
+static struct clk_rcg2 cam_cc_bps_clk_src = {
+   .cmd_rcgr = 0x600c,
+   .mnd_width = 0,

--
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


Re: [PATCH 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845

2018-08-06 Thread Amit Nischal

On 2018-08-03 04:14, Stephen Boyd wrote:

Quoting Amit Nischal (2018-07-30 04:28:56)

On 2018-07-25 12:28, Stephen Boyd wrote:
>
> Ok. Sounds good! Is the rate range call really needed? It can't be
> determined in the PLL code with some table or avoided by making sure
> GPU
> uses OPP table with only approved frequencies?
>

Currently fabia PLL code does not have any table to check this and
intention
was to avoid relying on the client to call set_rate with only approved
frequencies so we have added the set_rate_range() call in the GPUCC
driver
in order to set the rate range.



But GPU will use OPP so it doesn't seem like it really buys us anything
here. And it really doesn't matter when the clk driver implementation
doesn't use the min/max to clamp the values of the round_rate() call. 
Is

that being done here? I need to double check. I would be more convinced
if the implementation was looking at min/max to constrain the rate
requested.



So our understanding is that GPU(client) driver will always call the
set_rate with approved frequencies only and we can completely rely on 
the

client. Is our understanding is correct?


--
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


Re: [PATCH 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845

2018-08-06 Thread Amit Nischal

On 2018-08-03 04:14, Stephen Boyd wrote:

Quoting Amit Nischal (2018-07-30 04:28:56)

On 2018-07-25 12:28, Stephen Boyd wrote:
>
> Ok. Sounds good! Is the rate range call really needed? It can't be
> determined in the PLL code with some table or avoided by making sure
> GPU
> uses OPP table with only approved frequencies?
>

Currently fabia PLL code does not have any table to check this and
intention
was to avoid relying on the client to call set_rate with only approved
frequencies so we have added the set_rate_range() call in the GPUCC
driver
in order to set the rate range.



But GPU will use OPP so it doesn't seem like it really buys us anything
here. And it really doesn't matter when the clk driver implementation
doesn't use the min/max to clamp the values of the round_rate() call. 
Is

that being done here? I need to double check. I would be more convinced
if the implementation was looking at min/max to constrain the rate
requested.



So our understanding is that GPU(client) driver will always call the
set_rate with approved frequencies only and we can completely rely on 
the

client. Is our understanding is correct?


--
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


Re: [PATCH 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845

2018-07-30 Thread Amit Nischal

On 2018-07-25 12:28, Stephen Boyd wrote:

Quoting Amit Nischal (2018-07-12 05:30:21)

On 2018-07-09 11:45, Stephen Boyd wrote:
> Quoting Amit Nischal (2018-06-06 04:41:46)
>> 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() and set_rate() 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.
>>
>
> It sounds like the GDSC enable is ANDed with the RCG's root enable
> bit?

Here, the root clock (GFX3D RCG) needs to be enabled first before
writing to SW_COLLAPSE bit of the GDSC. RCG's CLK_ON signal would
power up the GDSC.

> Does the RCG need to be clocking for the GDSC to actually turn on?
> Or is it purely that the enable bit is logically combined that way so
> that if the RCG is parented to a PLL that's off the GDSC will still
> turn
> on?
>

Yes, the RCG needs to be clocking for the GPU_GX GDSC to actually turn
on.


Cool, please add these details to the commit text.


Thanks. I will add these details in the commit text in the next patch 
series.






>> 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.
>
> Anyway, this patch will probably significantly change given that the
> RCG
> is a glorified div-2 that muxes between a safe CXO speed and a
> configurable PLL frequency. A lot of the logic can probably just be
> hardcoded then.
>

Thanks for the suggestion.
We are planning to introduce the "clk_rcg2_gfx3d_determine_rate" op
which will
always return the best parent as ‘GPU_CC_PLL0_OUT_EVEN’ and 
best_parent
rate equal to twice of the requested rate. With this approach 
frequency

table
for rcg2 structure would not be required as all the supported
frequencies would
be derived from the GPU_CC_PLL0_OUT_EVEN src with a divider of 2.

Also, we will add support to check the requested rate if falls within
allowed
set_rate range. This will make sure that the source PLL would not go 
out

of
the supported range. set_rate_range would be set by the GPUCC driver
with min/max
value by calling below API.

clk_hw_set_rate_range(_cc_gx_gfx3d_clk_src.clkr.hw, 18000,
71000)


Ok. Sounds good! Is the rate range call really needed? It can't be
determined in the PLL code with some table or avoided by making sure 
GPU

uses OPP table with only approved frequencies?



Currently fabia PLL code does not have any table to check this and 
intention

was to avoid relying on the client to call set_rate with only approved
frequencies so we have added the set_rate_range() call in the GPUCC 
driver

in order to set the rate range.


--
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


Re: [PATCH 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845

2018-07-30 Thread Amit Nischal

On 2018-07-25 12:28, Stephen Boyd wrote:

Quoting Amit Nischal (2018-07-12 05:30:21)

On 2018-07-09 11:45, Stephen Boyd wrote:
> Quoting Amit Nischal (2018-06-06 04:41:46)
>> 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() and set_rate() 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.
>>
>
> It sounds like the GDSC enable is ANDed with the RCG's root enable
> bit?

Here, the root clock (GFX3D RCG) needs to be enabled first before
writing to SW_COLLAPSE bit of the GDSC. RCG's CLK_ON signal would
power up the GDSC.

> Does the RCG need to be clocking for the GDSC to actually turn on?
> Or is it purely that the enable bit is logically combined that way so
> that if the RCG is parented to a PLL that's off the GDSC will still
> turn
> on?
>

Yes, the RCG needs to be clocking for the GPU_GX GDSC to actually turn
on.


Cool, please add these details to the commit text.


Thanks. I will add these details in the commit text in the next patch 
series.






>> 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.
>
> Anyway, this patch will probably significantly change given that the
> RCG
> is a glorified div-2 that muxes between a safe CXO speed and a
> configurable PLL frequency. A lot of the logic can probably just be
> hardcoded then.
>

Thanks for the suggestion.
We are planning to introduce the "clk_rcg2_gfx3d_determine_rate" op
which will
always return the best parent as ‘GPU_CC_PLL0_OUT_EVEN’ and 
best_parent
rate equal to twice of the requested rate. With this approach 
frequency

table
for rcg2 structure would not be required as all the supported
frequencies would
be derived from the GPU_CC_PLL0_OUT_EVEN src with a divider of 2.

Also, we will add support to check the requested rate if falls within
allowed
set_rate range. This will make sure that the source PLL would not go 
out

of
the supported range. set_rate_range would be set by the GPUCC driver
with min/max
value by calling below API.

clk_hw_set_rate_range(_cc_gx_gfx3d_clk_src.clkr.hw, 18000,
71000)


Ok. Sounds good! Is the rate range call really needed? It can't be
determined in the PLL code with some table or avoided by making sure 
GPU

uses OPP table with only approved frequencies?



Currently fabia PLL code does not have any table to check this and 
intention

was to avoid relying on the client to call set_rate with only approved
frequencies so we have added the set_rate_range() call in the GPUCC 
driver

in order to set the rate range.


--
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


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

2018-07-30 Thread Amit Nischal

On 2018-07-25 12:22, Stephen Boyd wrote:

Quoting Amit Nischal (2018-07-12 05:23:48)

On 2018-07-09 11:04, Stephen Boyd wrote:
> Quoting Amit Nischal (2018-06-06 04:41:45)
>> 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
>
> Why is there a requirement? Do the clks need to be in hw control mode
> or
> they can't be turned off when the GDSC is off? It's hard for me to
> understand with these vague statements.
>

This requirement is primarily to turn on the GPU GX GDSC and these
clocks
do not need to be in HW control mode and clock disable is not related
with the GDSC.


Ok that's good to know.



To turn on the GX GDSC, root clock (GFX3D RCG) needs to be enabled 
first

before writing to SW_COLLAPSE bit of the GDSC. The CLK_ON signal from
RCG
would power up the GPU GX GDSC.


Can you please put this specific information in the commit text instead
of making a vague statement about GDSC hardware configurations?

Does anything go wrong if the GDSC is enabled from genpd but doesn't
actually turn on until the GFX3D RCG root bit is enabled or disabled by
the clk enable call? I suppose we won't know if the GDSC is enabled or
not until the clk is enabled? Maybe we should make the clk enable of 
the

RCG for GPU go check the GDSC status bit as well to make sure it's
toggling on or off?


As per the current design, before turning on the GDSC(writing to the 
GDSCR
register) we are setting the ROOT_EN bit of RCG and GDSC's status will 
be

still off without clk_enable call to RCG even though we enable the GDSC.
clk_enable for RCG is CLK_ON signal for the GPU_GX_GDSC.



Also, does the RCG turn on when the GX GDSC is off? I think we may be
able to rely on the GPU driver to "do the right thing" and enable the
GPU CX GDSC first, then the RCG and branch for the GFX3D clk, and then
the GPU GX GDSC for the core GPU logic. Then we don't need to do
anything special in the GDSC code for this.


Its a GPU_GX_GDSC requirement to enable the RCG first and then GX_GDSC.
We want all of this sequence to be done by the GDSC driver so that 
client

only call for clk_apis for the clock branch. For clients, It will be
extra overhead to follow the below sequence.
GPU_CX_GDSC enable -> Enable RCG -> Enable GPU_GX_GDSC -> Enable Branch.






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

2018-07-30 Thread Amit Nischal

On 2018-07-25 12:22, Stephen Boyd wrote:

Quoting Amit Nischal (2018-07-12 05:23:48)

On 2018-07-09 11:04, Stephen Boyd wrote:
> Quoting Amit Nischal (2018-06-06 04:41:45)
>> 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
>
> Why is there a requirement? Do the clks need to be in hw control mode
> or
> they can't be turned off when the GDSC is off? It's hard for me to
> understand with these vague statements.
>

This requirement is primarily to turn on the GPU GX GDSC and these
clocks
do not need to be in HW control mode and clock disable is not related
with the GDSC.


Ok that's good to know.



To turn on the GX GDSC, root clock (GFX3D RCG) needs to be enabled 
first

before writing to SW_COLLAPSE bit of the GDSC. The CLK_ON signal from
RCG
would power up the GPU GX GDSC.


Can you please put this specific information in the commit text instead
of making a vague statement about GDSC hardware configurations?

Does anything go wrong if the GDSC is enabled from genpd but doesn't
actually turn on until the GFX3D RCG root bit is enabled or disabled by
the clk enable call? I suppose we won't know if the GDSC is enabled or
not until the clk is enabled? Maybe we should make the clk enable of 
the

RCG for GPU go check the GDSC status bit as well to make sure it's
toggling on or off?


As per the current design, before turning on the GDSC(writing to the 
GDSCR
register) we are setting the ROOT_EN bit of RCG and GDSC's status will 
be

still off without clk_enable call to RCG even though we enable the GDSC.
clk_enable for RCG is CLK_ON signal for the GPU_GX_GDSC.



Also, does the RCG turn on when the GX GDSC is off? I think we may be
able to rely on the GPU driver to "do the right thing" and enable the
GPU CX GDSC first, then the RCG and branch for the GFX3D clk, and then
the GPU GX GDSC for the core GPU logic. Then we don't need to do
anything special in the GDSC code for this.


Its a GPU_GX_GDSC requirement to enable the RCG first and then GX_GDSC.
We want all of this sequence to be done by the GDSC driver so that 
client

only call for clk_apis for the clock branch. For clients, It will be
extra overhead to follow the below sequence.
GPU_CX_GDSC enable -> Enable RCG -> Enable GPU_GX_GDSC -> Enable Branch.






[PATCH v2] Add QCOM camera clock controller driver

2018-07-30 Thread Amit Nischal
Changes in v2:
Addressed below review comments - https://lkml.org/lkml/2018/7/23/377
1. Add comment to use clk_rcg2_shared_ops and CLK_SET_RATE_PARENT flag.
2. Replace commas with semicolon for PLL configuration in probe function.

Changes in v1:
This patch series adds a driver and device tree documentation binding
for the camera clock controller on some Qualcomm Technologies, Inc, SoCs
such as SDM845. This would allow camera drivers to probe and control
their clocks.

[v1] : https://lkml.org/lkml/2018/7/23/377

Amit Nischal (1):
  clk: qcom: Add camera clock controller driver for SDM845

 drivers/clk/qcom/Kconfig|8 +
 drivers/clk/qcom/Makefile   |1 +
 drivers/clk/qcom/camcc-sdm845.c | 1744 +++
 3 files changed, 1753 insertions(+)
 create mode 100644 drivers/clk/qcom/camcc-sdm845.c

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



[PATCH v2] clk: qcom: Add camera clock controller driver for SDM845

2018-07-30 Thread Amit Nischal
Add support for the camera clock controller found on SDM845
based devices. This would allow camera drivers to probe and
control their clocks.

Signed-off-by: Amit Nischal 
---
 drivers/clk/qcom/Kconfig|8 +
 drivers/clk/qcom/Makefile   |1 +
 drivers/clk/qcom/camcc-sdm845.c | 1744 +++
 3 files changed, 1753 insertions(+)
 create mode 100644 drivers/clk/qcom/camcc-sdm845.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 7b32a33..85babc5 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -235,6 +235,14 @@ 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_CAMCC_845
+   tristate "SDM845 Camera Clock Controller"
+   depends on COMMON_CLK_QCOM
+   select SDM_GCC_845
+   help
+ Support for the camera clock controller on SDM845 devices.
+ Say Y if you want to support camera devices and camera functionality.
+
 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 1818d9f..fab1a47 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -40,6 +40,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_CAMCC_845) += camcc-sdm845.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
diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c
new file mode 100644
index 000..702ca66
--- /dev/null
+++ b/drivers/clk/qcom/camcc-sdm845.c
@@ -0,0 +1,1744 @@
+// 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-rcg.h"
+#include "clk-regmap.h"
+#include "gdsc.h"
+
+enum {
+   P_BI_TCXO,
+   P_CAM_CC_PLL0_OUT_EVEN,
+   P_CAM_CC_PLL1_OUT_EVEN,
+   P_CAM_CC_PLL2_OUT_EVEN,
+   P_CAM_CC_PLL3_OUT_EVEN,
+   P_CORE_BI_PLL_TEST_SE,
+};
+
+static const struct parent_map cam_cc_parent_map_0[] = {
+   { P_BI_TCXO, 0 },
+   { P_CAM_CC_PLL2_OUT_EVEN, 1 },
+   { P_CAM_CC_PLL1_OUT_EVEN, 2 },
+   { P_CAM_CC_PLL3_OUT_EVEN, 5 },
+   { P_CAM_CC_PLL0_OUT_EVEN, 6 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const cam_cc_parent_names_0[] = {
+   "bi_tcxo",
+   "cam_cc_pll2_out_even",
+   "cam_cc_pll1_out_even",
+   "cam_cc_pll3_out_even",
+   "cam_cc_pll0_out_even",
+   "core_bi_pll_test_se",
+};
+
+static struct clk_alpha_pll cam_cc_pll0 = {
+   .offset = 0x0,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll0",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static const struct clk_div_table post_div_table_fabia_even[] = {
+   { 0x0, 1 },
+   { 0x1, 2 },
+   { }
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = {
+   .offset = 0x0,
+   .post_div_shift = 8,
+   .post_div_table = post_div_table_fabia_even,
+   .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+   .width = 4,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll0_out_even",
+   .parent_names = (const char *[]){ "cam_cc_pll0" },
+   .num_parents = 1,
+   .ops = _alpha_pll_postdiv_fabia_ops,
+   },
+};
+
+static struct clk_alpha_pll cam_cc_pll1 = {
+   .offset = 0x1000,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll1",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = {
+   .offset = 0x1000,
+   .post_div_shift = 8,
+   .post_div_table = post_div_table_fabia_even,
+   .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+   .w

[PATCH v2] Add QCOM camera clock controller driver

2018-07-30 Thread Amit Nischal
Changes in v2:
Addressed below review comments - https://lkml.org/lkml/2018/7/23/377
1. Add comment to use clk_rcg2_shared_ops and CLK_SET_RATE_PARENT flag.
2. Replace commas with semicolon for PLL configuration in probe function.

Changes in v1:
This patch series adds a driver and device tree documentation binding
for the camera clock controller on some Qualcomm Technologies, Inc, SoCs
such as SDM845. This would allow camera drivers to probe and control
their clocks.

[v1] : https://lkml.org/lkml/2018/7/23/377

Amit Nischal (1):
  clk: qcom: Add camera clock controller driver for SDM845

 drivers/clk/qcom/Kconfig|8 +
 drivers/clk/qcom/Makefile   |1 +
 drivers/clk/qcom/camcc-sdm845.c | 1744 +++
 3 files changed, 1753 insertions(+)
 create mode 100644 drivers/clk/qcom/camcc-sdm845.c

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



[PATCH v2] clk: qcom: Add camera clock controller driver for SDM845

2018-07-30 Thread Amit Nischal
Add support for the camera clock controller found on SDM845
based devices. This would allow camera drivers to probe and
control their clocks.

Signed-off-by: Amit Nischal 
---
 drivers/clk/qcom/Kconfig|8 +
 drivers/clk/qcom/Makefile   |1 +
 drivers/clk/qcom/camcc-sdm845.c | 1744 +++
 3 files changed, 1753 insertions(+)
 create mode 100644 drivers/clk/qcom/camcc-sdm845.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 7b32a33..85babc5 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -235,6 +235,14 @@ 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_CAMCC_845
+   tristate "SDM845 Camera Clock Controller"
+   depends on COMMON_CLK_QCOM
+   select SDM_GCC_845
+   help
+ Support for the camera clock controller on SDM845 devices.
+ Say Y if you want to support camera devices and camera functionality.
+
 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 1818d9f..fab1a47 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -40,6 +40,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_CAMCC_845) += camcc-sdm845.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
diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c
new file mode 100644
index 000..702ca66
--- /dev/null
+++ b/drivers/clk/qcom/camcc-sdm845.c
@@ -0,0 +1,1744 @@
+// 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-rcg.h"
+#include "clk-regmap.h"
+#include "gdsc.h"
+
+enum {
+   P_BI_TCXO,
+   P_CAM_CC_PLL0_OUT_EVEN,
+   P_CAM_CC_PLL1_OUT_EVEN,
+   P_CAM_CC_PLL2_OUT_EVEN,
+   P_CAM_CC_PLL3_OUT_EVEN,
+   P_CORE_BI_PLL_TEST_SE,
+};
+
+static const struct parent_map cam_cc_parent_map_0[] = {
+   { P_BI_TCXO, 0 },
+   { P_CAM_CC_PLL2_OUT_EVEN, 1 },
+   { P_CAM_CC_PLL1_OUT_EVEN, 2 },
+   { P_CAM_CC_PLL3_OUT_EVEN, 5 },
+   { P_CAM_CC_PLL0_OUT_EVEN, 6 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const cam_cc_parent_names_0[] = {
+   "bi_tcxo",
+   "cam_cc_pll2_out_even",
+   "cam_cc_pll1_out_even",
+   "cam_cc_pll3_out_even",
+   "cam_cc_pll0_out_even",
+   "core_bi_pll_test_se",
+};
+
+static struct clk_alpha_pll cam_cc_pll0 = {
+   .offset = 0x0,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll0",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static const struct clk_div_table post_div_table_fabia_even[] = {
+   { 0x0, 1 },
+   { 0x1, 2 },
+   { }
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = {
+   .offset = 0x0,
+   .post_div_shift = 8,
+   .post_div_table = post_div_table_fabia_even,
+   .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+   .width = 4,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll0_out_even",
+   .parent_names = (const char *[]){ "cam_cc_pll0" },
+   .num_parents = 1,
+   .ops = _alpha_pll_postdiv_fabia_ops,
+   },
+};
+
+static struct clk_alpha_pll cam_cc_pll1 = {
+   .offset = 0x1000,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll1",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = {
+   .offset = 0x1000,
+   .post_div_shift = 8,
+   .post_div_table = post_div_table_fabia_even,
+   .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+   .w

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

2018-07-30 Thread Amit Nischal

On 2018-07-26 22:52, Stephen Boyd wrote:

Quoting Amit Nischal (2018-07-23 04:26:33)
diff --git a/drivers/clk/qcom/camcc-sdm845.c 
b/drivers/clk/qcom/camcc-sdm845.c

new file mode 100644
index 000..61e5ec2
--- /dev/null
+++ b/drivers/clk/qcom/camcc-sdm845.c
@@ -0,0 +1,1736 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include 


Is this include used?


This is not required. I will remove this in next patch series.




+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "common.h"
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "gdsc.h"
+
+enum {
+   P_BI_TCXO,
+   P_CAM_CC_PLL0_OUT_EVEN,
+   P_CAM_CC_PLL1_OUT_EVEN,
+   P_CAM_CC_PLL2_OUT_EVEN,
+   P_CAM_CC_PLL3_OUT_EVEN,
+   P_CORE_BI_PLL_TEST_SE,
+};
+
+static const struct parent_map cam_cc_parent_map_0[] = {
+   { P_BI_TCXO, 0 },
+   { P_CAM_CC_PLL2_OUT_EVEN, 1 },
+   { P_CAM_CC_PLL1_OUT_EVEN, 2 },
+   { P_CAM_CC_PLL3_OUT_EVEN, 5 },
+   { P_CAM_CC_PLL0_OUT_EVEN, 6 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const cam_cc_parent_names_0[] = {
+   "bi_tcxo",
+   "cam_cc_pll2_out_even",
+   "cam_cc_pll1_out_even",
+   "cam_cc_pll3_out_even",
+   "cam_cc_pll0_out_even",
+   "core_bi_pll_test_se",
+};
+
+static struct clk_alpha_pll cam_cc_pll0 = {
+   .offset = 0x0,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll0",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static const struct clk_div_table post_div_table_fabia_even[] = {
+   { 0x0, 1 },
+   { 0x1, 2 },
+   { }
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = {
+   .offset = 0x0,
+   .post_div_shift = 8,
+   .post_div_table = post_div_table_fabia_even,
+   .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+   .width = 4,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll0_out_even",
+   .parent_names = (const char *[]){ "cam_cc_pll0" },
+   .num_parents = 1,
+   .ops = _alpha_pll_postdiv_fabia_ops,
+   },
+};
+
+static struct clk_alpha_pll cam_cc_pll1 = {
+   .offset = 0x1000,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll1",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = {
+   .offset = 0x1000,
+   .post_div_shift = 8,
+   .post_div_table = post_div_table_fabia_even,
+   .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+   .width = 4,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll1_out_even",
+   .parent_names = (const char *[]){ "cam_cc_pll1" },
+   .num_parents = 1,
+   .ops = _alpha_pll_postdiv_fabia_ops,
+   },
+};
+
+static struct clk_alpha_pll cam_cc_pll2 = {
+   .offset = 0x2000,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll2",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll2_out_even = {
+   .offset = 0x2000,
+   .post_div_shift = 8,
+   .post_div_table = post_div_table_fabia_even,
+   .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+   .width = 4,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll2_out_even",
+   .parent_names = (const char *[]){ "cam_cc_pll2" },
+   .num_parents = 1,
+   .ops = _alpha_pll_postdiv_fabia_ops,
+   },
+};
+
+static struct clk_alpha_pll cam_cc_pll3 = {
+   .offset = 0x3000,
+   .regs = clk_al

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

2018-07-30 Thread Amit Nischal

On 2018-07-26 22:52, Stephen Boyd wrote:

Quoting Amit Nischal (2018-07-23 04:26:33)
diff --git a/drivers/clk/qcom/camcc-sdm845.c 
b/drivers/clk/qcom/camcc-sdm845.c

new file mode 100644
index 000..61e5ec2
--- /dev/null
+++ b/drivers/clk/qcom/camcc-sdm845.c
@@ -0,0 +1,1736 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include 


Is this include used?


This is not required. I will remove this in next patch series.




+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "common.h"
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "gdsc.h"
+
+enum {
+   P_BI_TCXO,
+   P_CAM_CC_PLL0_OUT_EVEN,
+   P_CAM_CC_PLL1_OUT_EVEN,
+   P_CAM_CC_PLL2_OUT_EVEN,
+   P_CAM_CC_PLL3_OUT_EVEN,
+   P_CORE_BI_PLL_TEST_SE,
+};
+
+static const struct parent_map cam_cc_parent_map_0[] = {
+   { P_BI_TCXO, 0 },
+   { P_CAM_CC_PLL2_OUT_EVEN, 1 },
+   { P_CAM_CC_PLL1_OUT_EVEN, 2 },
+   { P_CAM_CC_PLL3_OUT_EVEN, 5 },
+   { P_CAM_CC_PLL0_OUT_EVEN, 6 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const cam_cc_parent_names_0[] = {
+   "bi_tcxo",
+   "cam_cc_pll2_out_even",
+   "cam_cc_pll1_out_even",
+   "cam_cc_pll3_out_even",
+   "cam_cc_pll0_out_even",
+   "core_bi_pll_test_se",
+};
+
+static struct clk_alpha_pll cam_cc_pll0 = {
+   .offset = 0x0,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll0",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static const struct clk_div_table post_div_table_fabia_even[] = {
+   { 0x0, 1 },
+   { 0x1, 2 },
+   { }
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = {
+   .offset = 0x0,
+   .post_div_shift = 8,
+   .post_div_table = post_div_table_fabia_even,
+   .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+   .width = 4,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll0_out_even",
+   .parent_names = (const char *[]){ "cam_cc_pll0" },
+   .num_parents = 1,
+   .ops = _alpha_pll_postdiv_fabia_ops,
+   },
+};
+
+static struct clk_alpha_pll cam_cc_pll1 = {
+   .offset = 0x1000,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll1",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = {
+   .offset = 0x1000,
+   .post_div_shift = 8,
+   .post_div_table = post_div_table_fabia_even,
+   .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+   .width = 4,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll1_out_even",
+   .parent_names = (const char *[]){ "cam_cc_pll1" },
+   .num_parents = 1,
+   .ops = _alpha_pll_postdiv_fabia_ops,
+   },
+};
+
+static struct clk_alpha_pll cam_cc_pll2 = {
+   .offset = 0x2000,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll2",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll2_out_even = {
+   .offset = 0x2000,
+   .post_div_shift = 8,
+   .post_div_table = post_div_table_fabia_even,
+   .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+   .width = 4,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll2_out_even",
+   .parent_names = (const char *[]){ "cam_cc_pll2" },
+   .num_parents = 1,
+   .ops = _alpha_pll_postdiv_fabia_ops,
+   },
+};
+
+static struct clk_alpha_pll cam_cc_pll3 = {
+   .offset = 0x3000,
+   .regs = clk_al

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

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

Signed-off-by: Amit Nischal 
---
 drivers/clk/qcom/Kconfig|8 +
 drivers/clk/qcom/Makefile   |1 +
 drivers/clk/qcom/camcc-sdm845.c | 1736 +++
 3 files changed, 1745 insertions(+)
 create mode 100644 drivers/clk/qcom/camcc-sdm845.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 7b32a33..85babc5 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -235,6 +235,14 @@ 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_CAMCC_845
+   tristate "SDM845 Camera Clock Controller"
+   depends on COMMON_CLK_QCOM
+   select SDM_GCC_845
+   help
+ Support for the camera clock controller on SDM845 devices.
+ Say Y if you want to support camera devices and camera functionality.
+
 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 1818d9f..fab1a47 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -40,6 +40,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_CAMCC_845) += camcc-sdm845.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
diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c
new file mode 100644
index 000..61e5ec2
--- /dev/null
+++ b/drivers/clk/qcom/camcc-sdm845.c
@@ -0,0 +1,1736 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "common.h"
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "gdsc.h"
+
+enum {
+   P_BI_TCXO,
+   P_CAM_CC_PLL0_OUT_EVEN,
+   P_CAM_CC_PLL1_OUT_EVEN,
+   P_CAM_CC_PLL2_OUT_EVEN,
+   P_CAM_CC_PLL3_OUT_EVEN,
+   P_CORE_BI_PLL_TEST_SE,
+};
+
+static const struct parent_map cam_cc_parent_map_0[] = {
+   { P_BI_TCXO, 0 },
+   { P_CAM_CC_PLL2_OUT_EVEN, 1 },
+   { P_CAM_CC_PLL1_OUT_EVEN, 2 },
+   { P_CAM_CC_PLL3_OUT_EVEN, 5 },
+   { P_CAM_CC_PLL0_OUT_EVEN, 6 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const cam_cc_parent_names_0[] = {
+   "bi_tcxo",
+   "cam_cc_pll2_out_even",
+   "cam_cc_pll1_out_even",
+   "cam_cc_pll3_out_even",
+   "cam_cc_pll0_out_even",
+   "core_bi_pll_test_se",
+};
+
+static struct clk_alpha_pll cam_cc_pll0 = {
+   .offset = 0x0,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll0",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static const struct clk_div_table post_div_table_fabia_even[] = {
+   { 0x0, 1 },
+   { 0x1, 2 },
+   { }
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = {
+   .offset = 0x0,
+   .post_div_shift = 8,
+   .post_div_table = post_div_table_fabia_even,
+   .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+   .width = 4,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll0_out_even",
+   .parent_names = (const char *[]){ "cam_cc_pll0" },
+   .num_parents = 1,
+   .ops = _alpha_pll_postdiv_fabia_ops,
+   },
+};
+
+static struct clk_alpha_pll cam_cc_pll1 = {
+   .offset = 0x1000,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll1",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = {
+   .offset = 0x1000,
+   .post_div_shift = 8,
+   .post_div_table = post_div_table_fabia_even,
+   .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+   .w

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

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

Signed-off-by: Amit Nischal 
---
 drivers/clk/qcom/Kconfig|8 +
 drivers/clk/qcom/Makefile   |1 +
 drivers/clk/qcom/camcc-sdm845.c | 1736 +++
 3 files changed, 1745 insertions(+)
 create mode 100644 drivers/clk/qcom/camcc-sdm845.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 7b32a33..85babc5 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -235,6 +235,14 @@ 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_CAMCC_845
+   tristate "SDM845 Camera Clock Controller"
+   depends on COMMON_CLK_QCOM
+   select SDM_GCC_845
+   help
+ Support for the camera clock controller on SDM845 devices.
+ Say Y if you want to support camera devices and camera functionality.
+
 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 1818d9f..fab1a47 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -40,6 +40,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_CAMCC_845) += camcc-sdm845.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
diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c
new file mode 100644
index 000..61e5ec2
--- /dev/null
+++ b/drivers/clk/qcom/camcc-sdm845.c
@@ -0,0 +1,1736 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "common.h"
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "gdsc.h"
+
+enum {
+   P_BI_TCXO,
+   P_CAM_CC_PLL0_OUT_EVEN,
+   P_CAM_CC_PLL1_OUT_EVEN,
+   P_CAM_CC_PLL2_OUT_EVEN,
+   P_CAM_CC_PLL3_OUT_EVEN,
+   P_CORE_BI_PLL_TEST_SE,
+};
+
+static const struct parent_map cam_cc_parent_map_0[] = {
+   { P_BI_TCXO, 0 },
+   { P_CAM_CC_PLL2_OUT_EVEN, 1 },
+   { P_CAM_CC_PLL1_OUT_EVEN, 2 },
+   { P_CAM_CC_PLL3_OUT_EVEN, 5 },
+   { P_CAM_CC_PLL0_OUT_EVEN, 6 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const cam_cc_parent_names_0[] = {
+   "bi_tcxo",
+   "cam_cc_pll2_out_even",
+   "cam_cc_pll1_out_even",
+   "cam_cc_pll3_out_even",
+   "cam_cc_pll0_out_even",
+   "core_bi_pll_test_se",
+};
+
+static struct clk_alpha_pll cam_cc_pll0 = {
+   .offset = 0x0,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll0",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static const struct clk_div_table post_div_table_fabia_even[] = {
+   { 0x0, 1 },
+   { 0x1, 2 },
+   { }
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = {
+   .offset = 0x0,
+   .post_div_shift = 8,
+   .post_div_table = post_div_table_fabia_even,
+   .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+   .width = 4,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll0_out_even",
+   .parent_names = (const char *[]){ "cam_cc_pll0" },
+   .num_parents = 1,
+   .ops = _alpha_pll_postdiv_fabia_ops,
+   },
+};
+
+static struct clk_alpha_pll cam_cc_pll1 = {
+   .offset = 0x1000,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "cam_cc_pll1",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = {
+   .offset = 0x1000,
+   .post_div_shift = 8,
+   .post_div_table = post_div_table_fabia_even,
+   .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+   .w

[PATCH 0/2] Add QCOM camera clock controller driver

2018-07-23 Thread Amit Nischal
This patch series adds a driver and device tree documentation binding
for the camera clock controller on some Qualcomm Technologies, Inc, SoCs
such as SDM845. This would allow camera drivers to probe and control their
clocks.

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

 .../devicetree/bindings/clock/qcom,camcc.txt   |   18 +
 drivers/clk/qcom/Kconfig   |8 +
 drivers/clk/qcom/Makefile  |1 +
 drivers/clk/qcom/camcc-sdm845.c| 1736 
 include/dt-bindings/clock/qcom,camcc-sdm845.h  |  116 ++
 5 files changed, 1879 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,camcc.txt
 create mode 100644 drivers/clk/qcom/camcc-sdm845.c
 create mode 100644 include/dt-bindings/clock/qcom,camcc-sdm845.h

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



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

2018-07-23 Thread Amit Nischal
Add device tree bindings for camera clock controller for
Qualcomm Technology Inc's SDM845 SoCs.

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

diff --git a/Documentation/devicetree/bindings/clock/qcom,camcc.txt 
b/Documentation/devicetree/bindings/clock/qcom,camcc.txt
new file mode 100644
index 000..c5eb669
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,camcc.txt
@@ -0,0 +1,18 @@
+Qualcomm Camera Clock & Reset Controller Binding
+
+
+Required properties :
+- compatible : shall contain "qcom,sdm845-camcc".
+- 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:
+   camcc: clock-controller@ad0 {
+   compatible = "qcom,sdm845-camcc";
+   reg = <0xad0 0x1>;
+   #clock-cells = <1>;
+   #reset-cells = <1>;
+   #power-domain-cells = <1>;
+   };
diff --git a/include/dt-bindings/clock/qcom,camcc-sdm845.h 
b/include/dt-bindings/clock/qcom,camcc-sdm845.h
new file mode 100644
index 000..4f7a2d2
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,camcc-sdm845.h
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_SDM_CAM_CC_SDM845_H
+#define _DT_BINDINGS_CLK_SDM_CAM_CC_SDM845_H
+
+/* CAM_CC clock registers */
+#define CAM_CC_BPS_AHB_CLK 0
+#define CAM_CC_BPS_AREG_CLK1
+#define CAM_CC_BPS_AXI_CLK 2
+#define CAM_CC_BPS_CLK 3
+#define CAM_CC_BPS_CLK_SRC 4
+#define CAM_CC_CAMNOC_ATB_CLK  5
+#define CAM_CC_CAMNOC_AXI_CLK  6
+#define CAM_CC_CCI_CLK 7
+#define CAM_CC_CCI_CLK_SRC 8
+#define CAM_CC_CPAS_AHB_CLK9
+#define CAM_CC_CPHY_RX_CLK_SRC 10
+#define CAM_CC_CSI0PHYTIMER_CLK11
+#define CAM_CC_CSI0PHYTIMER_CLK_SRC12
+#define CAM_CC_CSI1PHYTIMER_CLK13
+#define CAM_CC_CSI1PHYTIMER_CLK_SRC14
+#define CAM_CC_CSI2PHYTIMER_CLK15
+#define CAM_CC_CSI2PHYTIMER_CLK_SRC16
+#define CAM_CC_CSI3PHYTIMER_CLK17
+#define CAM_CC_CSI3PHYTIMER_CLK_SRC18
+#define CAM_CC_CSIPHY0_CLK 19
+#define CAM_CC_CSIPHY1_CLK 20
+#define CAM_CC_CSIPHY2_CLK 21
+#define CAM_CC_CSIPHY3_CLK 22
+#define CAM_CC_FAST_AHB_CLK_SRC23
+#define CAM_CC_FD_CORE_CLK 24
+#define CAM_CC_FD_CORE_CLK_SRC 25
+#define CAM_CC_FD_CORE_UAR_CLK 26
+#define CAM_CC_ICP_APB_CLK 27
+#define CAM_CC_ICP_ATB_CLK 28
+#define CAM_CC_ICP_CLK 29
+#define CAM_CC_ICP_CLK_SRC 30
+#define CAM_CC_ICP_CTI_CLK 31
+#define CAM_CC_ICP_TS_CLK  32
+#define CAM_CC_IFE_0_AXI_CLK   33
+#define CAM_CC_IFE_0_CLK   34
+#define CAM_CC_IFE_0_CLK_SRC   35
+#define CAM_CC_IFE_0_CPHY_RX_CLK   36
+#define CAM_CC_IFE_0_CSID_CLK  37
+#define CAM_CC_IFE_0_CSID_CLK_SRC  38
+#define CAM_CC_IFE_0_DSP_CLK   39
+#define CAM_CC_IFE_1_AXI_CLK   40
+#define CAM_CC_IFE_1_CLK   41
+#define CAM_CC_IFE_1_CLK_SRC   42
+#define CAM_CC_IFE_1_CPHY_RX_CLK   43
+#define CAM_CC_IFE_1_CSID_CLK  44
+#define CAM_CC_IFE_1_CSID_CLK_SRC  45
+#define CAM_CC_IFE_1_DSP_CLK   46
+#define CAM_CC_IFE_LITE_CLK47
+#define CAM_CC_IFE_LITE_CLK_SRC48
+#define CAM_CC_IFE_LITE_CPHY_RX_CLK49
+#define CAM_CC_IFE_LITE_CSID_CLK   

[PATCH 0/2] Add QCOM camera clock controller driver

2018-07-23 Thread Amit Nischal
This patch series adds a driver and device tree documentation binding
for the camera clock controller on some Qualcomm Technologies, Inc, SoCs
such as SDM845. This would allow camera drivers to probe and control their
clocks.

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

 .../devicetree/bindings/clock/qcom,camcc.txt   |   18 +
 drivers/clk/qcom/Kconfig   |8 +
 drivers/clk/qcom/Makefile  |1 +
 drivers/clk/qcom/camcc-sdm845.c| 1736 
 include/dt-bindings/clock/qcom,camcc-sdm845.h  |  116 ++
 5 files changed, 1879 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,camcc.txt
 create mode 100644 drivers/clk/qcom/camcc-sdm845.c
 create mode 100644 include/dt-bindings/clock/qcom,camcc-sdm845.h

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



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

2018-07-23 Thread Amit Nischal
Add device tree bindings for camera clock controller for
Qualcomm Technology Inc's SDM845 SoCs.

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

diff --git a/Documentation/devicetree/bindings/clock/qcom,camcc.txt 
b/Documentation/devicetree/bindings/clock/qcom,camcc.txt
new file mode 100644
index 000..c5eb669
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,camcc.txt
@@ -0,0 +1,18 @@
+Qualcomm Camera Clock & Reset Controller Binding
+
+
+Required properties :
+- compatible : shall contain "qcom,sdm845-camcc".
+- 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:
+   camcc: clock-controller@ad0 {
+   compatible = "qcom,sdm845-camcc";
+   reg = <0xad0 0x1>;
+   #clock-cells = <1>;
+   #reset-cells = <1>;
+   #power-domain-cells = <1>;
+   };
diff --git a/include/dt-bindings/clock/qcom,camcc-sdm845.h 
b/include/dt-bindings/clock/qcom,camcc-sdm845.h
new file mode 100644
index 000..4f7a2d2
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,camcc-sdm845.h
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_SDM_CAM_CC_SDM845_H
+#define _DT_BINDINGS_CLK_SDM_CAM_CC_SDM845_H
+
+/* CAM_CC clock registers */
+#define CAM_CC_BPS_AHB_CLK 0
+#define CAM_CC_BPS_AREG_CLK1
+#define CAM_CC_BPS_AXI_CLK 2
+#define CAM_CC_BPS_CLK 3
+#define CAM_CC_BPS_CLK_SRC 4
+#define CAM_CC_CAMNOC_ATB_CLK  5
+#define CAM_CC_CAMNOC_AXI_CLK  6
+#define CAM_CC_CCI_CLK 7
+#define CAM_CC_CCI_CLK_SRC 8
+#define CAM_CC_CPAS_AHB_CLK9
+#define CAM_CC_CPHY_RX_CLK_SRC 10
+#define CAM_CC_CSI0PHYTIMER_CLK11
+#define CAM_CC_CSI0PHYTIMER_CLK_SRC12
+#define CAM_CC_CSI1PHYTIMER_CLK13
+#define CAM_CC_CSI1PHYTIMER_CLK_SRC14
+#define CAM_CC_CSI2PHYTIMER_CLK15
+#define CAM_CC_CSI2PHYTIMER_CLK_SRC16
+#define CAM_CC_CSI3PHYTIMER_CLK17
+#define CAM_CC_CSI3PHYTIMER_CLK_SRC18
+#define CAM_CC_CSIPHY0_CLK 19
+#define CAM_CC_CSIPHY1_CLK 20
+#define CAM_CC_CSIPHY2_CLK 21
+#define CAM_CC_CSIPHY3_CLK 22
+#define CAM_CC_FAST_AHB_CLK_SRC23
+#define CAM_CC_FD_CORE_CLK 24
+#define CAM_CC_FD_CORE_CLK_SRC 25
+#define CAM_CC_FD_CORE_UAR_CLK 26
+#define CAM_CC_ICP_APB_CLK 27
+#define CAM_CC_ICP_ATB_CLK 28
+#define CAM_CC_ICP_CLK 29
+#define CAM_CC_ICP_CLK_SRC 30
+#define CAM_CC_ICP_CTI_CLK 31
+#define CAM_CC_ICP_TS_CLK  32
+#define CAM_CC_IFE_0_AXI_CLK   33
+#define CAM_CC_IFE_0_CLK   34
+#define CAM_CC_IFE_0_CLK_SRC   35
+#define CAM_CC_IFE_0_CPHY_RX_CLK   36
+#define CAM_CC_IFE_0_CSID_CLK  37
+#define CAM_CC_IFE_0_CSID_CLK_SRC  38
+#define CAM_CC_IFE_0_DSP_CLK   39
+#define CAM_CC_IFE_1_AXI_CLK   40
+#define CAM_CC_IFE_1_CLK   41
+#define CAM_CC_IFE_1_CLK_SRC   42
+#define CAM_CC_IFE_1_CPHY_RX_CLK   43
+#define CAM_CC_IFE_1_CSID_CLK  44
+#define CAM_CC_IFE_1_CSID_CLK_SRC  45
+#define CAM_CC_IFE_1_DSP_CLK   46
+#define CAM_CC_IFE_LITE_CLK47
+#define CAM_CC_IFE_LITE_CLK_SRC48
+#define CAM_CC_IFE_LITE_CPHY_RX_CLK49
+#define CAM_CC_IFE_LITE_CSID_CLK   

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

2018-07-12 Thread 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 
---
 drivers/clk/qcom/Kconfig|   9 +
 drivers/clk/qcom/Makefile   |   1 +
 drivers/clk/qcom/gpucc-sdm845.c | 438 
 3 files changed, 448 insertions(+)
 create mode 100644 drivers/clk/qcom/gpucc-sdm845.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 9c3480d..193c2f5 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -235,6 +235,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 32d17c2..8aa2bc9 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -40,5 +40,6 @@ 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_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
diff --git a/drivers/clk/qcom/gpucc-sdm845.c b/drivers/clk/qcom/gpucc-sdm845.c
new file mode 100644
index 000..7a11b70
--- /dev/null
+++ b/drivers/clk/qcom/gpucc-sdm845.c
@@ -0,0 +1,438 @@
+// 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_PLL0_OUT_EVEN,
+   P_GPU_CC_PLL0_OUT_MAIN,
+   P_GPU_CC_PLL0_OUT_ODD,
+   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_PLL0_OUT_MAIN, 1 },
+   { 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_pll0",
+   "gpu_cc_pll1",
+   "gcc_gpu_gpll0_clk_src",
+   "gcc_gpu_gpll0_div_clk_src",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map gpu_cc_parent_map_1[] = {
+   { P_BI_TCXO, 0 },
+   { P_GPU_CC_PLL0_OUT_EVEN, 1 },
+   { P_GPU_CC_PLL0_OUT_ODD, 2 },
+   { P_GPU_CC_PLL1_OUT_EVEN, 3 },
+   { P_GPU_CC_PLL1_OUT_ODD, 4 },
+   { P_GPLL0_OUT_MAIN, 5 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gpu_cc_parent_names_1[] = {
+   "bi_tcxo",
+   "gpu_cc_pll0_out_even",
+   "gpu_cc_pll0_out_odd",
+   "gpu_cc_pll1_out_even",
+   "gpu_cc_pll1_out_odd",
+   "gcc_gpu_gpll0_clk_src",
+   "core_bi_pll_test_se",
+};
+
+static const struct alpha_pll_config gpu_cc_pll0_config = {
+   .l = 0x1d,
+   .alpha = 0x2aaa,
+};
+
+static const struct alpha_pll_config gpu_cc_pll1_config = {
+   .l = 0x1a,
+   .alpha = 0xaab,
+};
+
+static struct clk_alpha_pll gpu_cc_pll0 = {
+   .offset = 0x0,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "gpu_cc_pll0",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static const struct clk_div_table post_div_table_fabia_even[] = {
+   { 0x0, 1 },
+};
+
+static struct clk_alpha_pll_postd

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

2018-07-12 Thread 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 
---
 drivers/clk/qcom/Kconfig|   9 +
 drivers/clk/qcom/Makefile   |   1 +
 drivers/clk/qcom/gpucc-sdm845.c | 438 
 3 files changed, 448 insertions(+)
 create mode 100644 drivers/clk/qcom/gpucc-sdm845.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 9c3480d..193c2f5 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -235,6 +235,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 32d17c2..8aa2bc9 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -40,5 +40,6 @@ 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_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
diff --git a/drivers/clk/qcom/gpucc-sdm845.c b/drivers/clk/qcom/gpucc-sdm845.c
new file mode 100644
index 000..7a11b70
--- /dev/null
+++ b/drivers/clk/qcom/gpucc-sdm845.c
@@ -0,0 +1,438 @@
+// 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_PLL0_OUT_EVEN,
+   P_GPU_CC_PLL0_OUT_MAIN,
+   P_GPU_CC_PLL0_OUT_ODD,
+   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_PLL0_OUT_MAIN, 1 },
+   { 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_pll0",
+   "gpu_cc_pll1",
+   "gcc_gpu_gpll0_clk_src",
+   "gcc_gpu_gpll0_div_clk_src",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map gpu_cc_parent_map_1[] = {
+   { P_BI_TCXO, 0 },
+   { P_GPU_CC_PLL0_OUT_EVEN, 1 },
+   { P_GPU_CC_PLL0_OUT_ODD, 2 },
+   { P_GPU_CC_PLL1_OUT_EVEN, 3 },
+   { P_GPU_CC_PLL1_OUT_ODD, 4 },
+   { P_GPLL0_OUT_MAIN, 5 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gpu_cc_parent_names_1[] = {
+   "bi_tcxo",
+   "gpu_cc_pll0_out_even",
+   "gpu_cc_pll0_out_odd",
+   "gpu_cc_pll1_out_even",
+   "gpu_cc_pll1_out_odd",
+   "gcc_gpu_gpll0_clk_src",
+   "core_bi_pll_test_se",
+};
+
+static const struct alpha_pll_config gpu_cc_pll0_config = {
+   .l = 0x1d,
+   .alpha = 0x2aaa,
+};
+
+static const struct alpha_pll_config gpu_cc_pll1_config = {
+   .l = 0x1a,
+   .alpha = 0xaab,
+};
+
+static struct clk_alpha_pll gpu_cc_pll0 = {
+   .offset = 0x0,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "gpu_cc_pll0",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static const struct clk_div_table post_div_table_fabia_even[] = {
+   { 0x0, 1 },
+};
+
+static struct clk_alpha_pll_postd

[PATCH v2 3/4] dt-bindings: clock: Introduce QCOM Graphics clock bindings

2018-07-12 Thread 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  | 38 ++
 2 files changed, 56 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..b9cbce5
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,gpucc-sdm845.h
@@ -0,0 +1,38 @@
+/* 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_CRC_AHB_CLK 0
+#define GPU_CC_CX_APB_CLK  1
+#define GPU_CC_CX_GFX3D_CLK2
+#define GPU_CC_CX_GFX3D_SLV_CLK3
+#define GPU_CC_CX_GMU_CLK  4
+#define GPU_CC_CX_SNOC_DVM_CLK 5
+#define GPU_CC_CXO_CLK 6
+#define GPU_CC_GMU_CLK_SRC 7
+#define GPU_CC_GX_GMU_CLK  8
+#define GPU_CC_GX_GFX3D_CLK_SRC9
+#define GPU_CC_GX_GFX3D_CLK10
+#define GPU_CC_PLL011
+#define GPU_CC_PLL0_OUT_EVEN   12
+#define GPU_CC_PLL113
+
+/* GPU_CC Resets */
+#define GPUCC_GPU_CC_ACD_BCR   0
+#define GPUCC_GPU_CC_CX_BCR1
+#define GPUCC_GPU_CC_GFX3D_AON_BCR 2
+#define GPUCC_GPU_CC_GMU_BCR   3
+#define GPUCC_GPU_CC_GX_BCR4
+#define GPUCC_GPU_CC_SPDM_BCR  5
+#define GPUCC_GPU_CC_XO_BCR6
+
+/* 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 Code Aurora Forum, hosted by The Linux Foundation



[PATCH v2 3/4] dt-bindings: clock: Introduce QCOM Graphics clock bindings

2018-07-12 Thread 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  | 38 ++
 2 files changed, 56 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..b9cbce5
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,gpucc-sdm845.h
@@ -0,0 +1,38 @@
+/* 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_CRC_AHB_CLK 0
+#define GPU_CC_CX_APB_CLK  1
+#define GPU_CC_CX_GFX3D_CLK2
+#define GPU_CC_CX_GFX3D_SLV_CLK3
+#define GPU_CC_CX_GMU_CLK  4
+#define GPU_CC_CX_SNOC_DVM_CLK 5
+#define GPU_CC_CXO_CLK 6
+#define GPU_CC_GMU_CLK_SRC 7
+#define GPU_CC_GX_GMU_CLK  8
+#define GPU_CC_GX_GFX3D_CLK_SRC9
+#define GPU_CC_GX_GFX3D_CLK10
+#define GPU_CC_PLL011
+#define GPU_CC_PLL0_OUT_EVEN   12
+#define GPU_CC_PLL113
+
+/* GPU_CC Resets */
+#define GPUCC_GPU_CC_ACD_BCR   0
+#define GPUCC_GPU_CC_CX_BCR1
+#define GPUCC_GPU_CC_GFX3D_AON_BCR 2
+#define GPUCC_GPU_CC_GMU_BCR   3
+#define GPUCC_GPU_CC_GX_BCR4
+#define GPUCC_GPU_CC_SPDM_BCR  5
+#define GPUCC_GPU_CC_XO_BCR6
+
+/* 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 Code Aurora Forum, hosted by The Linux Foundation



[PATCH v2 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845

2018-07-12 Thread Amit Nischal
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 op. But due to the above
said requirement for GFX3D shared RCG, root_enable bit would be
already set by gdsc driver and clk_rcg2_shared_enable()should
not clear the root unless the disable is called.

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.

Signed-off-by: Amit Nischal 
---
 drivers/clk/qcom/clk-rcg.h  |  1 +
 drivers/clk/qcom/clk-rcg2.c | 87 +++--
 2 files changed, 86 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h
index b209a2f..c8c9558 100644
--- a/drivers/clk/qcom/clk-rcg.h
+++ b/drivers/clk/qcom/clk-rcg.h
@@ -160,5 +160,6 @@ struct clk_rcg2 {
 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;
+extern const struct clk_ops clk_rcg2_gfx3d_ops;

 #endif
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index 52208d4..667edd9 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -866,7 +866,7 @@ static int clk_rcg2_shared_set_rate_and_parent(struct 
clk_hw *hw,
return clk_rcg2_shared_set_rate(hw, rate, parent_rate);
 }

-static int clk_rcg2_shared_enable(struct clk_hw *hw)
+static int __clk_rcg2_shared_enable(struct clk_hw *hw)
 {
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
int ret;
@@ -879,7 +879,14 @@ static int clk_rcg2_shared_enable(struct clk_hw *hw)
if (ret)
return ret;

-   ret = update_config(rcg);
+   return update_config(rcg);
+}
+
+static int clk_rcg2_shared_enable(struct clk_hw *hw)
+{
+   int ret;
+
+   ret = __clk_rcg2_shared_enable(hw);
if (ret)
return ret;

@@ -929,3 +936,79 @@ 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);
+
+static int clk_rcg2_gfx3d_enable(struct clk_hw *hw)
+{
+   return __clk_rcg2_shared_enable(hw);
+}
+
+static int clk_rcg2_gfx3d_determine_rate(struct clk_hw *hw,
+   struct clk_rate_request *req)
+{
+   struct clk_rate_request parent_req = { };
+   struct clk_hw *p;
+   unsigned long rate = req->rate;
+   int ret;
+
+   if (rate < req->min_rate || rate > req->max_rate)
+   return -EINVAL;
+
+   /* Get fixed parent - GPU_CC_PLL0_OUT_EVEN */
+   p = clk_hw_get_parent_by_index(hw, 1);
+
+   /* Parent should always run at twice of the requested rate */
+   parent_req.rate = 2 * req->rate;
+
+   ret = __clk_determine_rate(req->best_parent_hw, _req);
+   if (ret)
+   return ret;
+
+   req->best_parent_hw = p;
+   req->best_parent_rate = parent_req.rate;
+   req->rate = parent_req.rate / 2;
+
+   return 0;
+}
+
+static int clk_rcg2_gfx3d_set_rate(struct clk_hw *hw, unsigned long rate,
+   unsigned long parent_rate)
+{
+   struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+   int ret;
+   u32 cfg;
+
+   /* Configure fixed SRC and DIV */
+   cfg = rcg->parent_map[1].cfg << CFG_SRC_SEL_SHIFT;
+   cfg |= 0x3 << CFG_SRC_DIV_SHIFT;
+
+   ret = regmap_write(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, cfg);
+   if (ret)
+   return ret;
+
+   /*
+* In case clock is disabled, update the SRC and DIV only
+* and return without configuration update.
+*/
+   if (!__clk_is_enabled(hw->clk))
+   return 0;
+
+   return update_config(rcg);
+}
+
+static int clk_rcg2_gfx3d_set_rate_and_parent(struct clk_hw *hw,
+   unsigned long rate, unsigned long parent_rate, u8 index)
+{
+   return clk_rcg2_gfx3d_set_rate(hw, rate, parent_rate);
+}
+
+const struct clk_ops clk_rcg2_gfx3d_ops = {
+   .enable = clk_rcg2_gfx3d_enable,
+   .disable = clk_rcg2_shared_disable,
+   .get_parent = clk_rcg2_get_parent,
+   .set_parent = clk_rcg2_set_parent,
+   .recalc_rate = clk_rcg2_recalc_rate,
+   .determine_rate = clk_rcg2_gfx3d_determine_rate,
+   .set_rate = clk_rcg2_gfx3d_set_rate,
+   .set_rate_and_parent = clk_rcg2_gfx3d_set_rate_and_parent,
+};
+EXPORT_SYMBOL_GPL(clk_rcg2_gfx3d_ops);
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



[PATCH v2 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845

2018-07-12 Thread Amit Nischal
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 op. But due to the above
said requirement for GFX3D shared RCG, root_enable bit would be
already set by gdsc driver and clk_rcg2_shared_enable()should
not clear the root unless the disable is called.

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.

Signed-off-by: Amit Nischal 
---
 drivers/clk/qcom/clk-rcg.h  |  1 +
 drivers/clk/qcom/clk-rcg2.c | 87 +++--
 2 files changed, 86 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h
index b209a2f..c8c9558 100644
--- a/drivers/clk/qcom/clk-rcg.h
+++ b/drivers/clk/qcom/clk-rcg.h
@@ -160,5 +160,6 @@ struct clk_rcg2 {
 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;
+extern const struct clk_ops clk_rcg2_gfx3d_ops;

 #endif
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index 52208d4..667edd9 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -866,7 +866,7 @@ static int clk_rcg2_shared_set_rate_and_parent(struct 
clk_hw *hw,
return clk_rcg2_shared_set_rate(hw, rate, parent_rate);
 }

-static int clk_rcg2_shared_enable(struct clk_hw *hw)
+static int __clk_rcg2_shared_enable(struct clk_hw *hw)
 {
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
int ret;
@@ -879,7 +879,14 @@ static int clk_rcg2_shared_enable(struct clk_hw *hw)
if (ret)
return ret;

-   ret = update_config(rcg);
+   return update_config(rcg);
+}
+
+static int clk_rcg2_shared_enable(struct clk_hw *hw)
+{
+   int ret;
+
+   ret = __clk_rcg2_shared_enable(hw);
if (ret)
return ret;

@@ -929,3 +936,79 @@ 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);
+
+static int clk_rcg2_gfx3d_enable(struct clk_hw *hw)
+{
+   return __clk_rcg2_shared_enable(hw);
+}
+
+static int clk_rcg2_gfx3d_determine_rate(struct clk_hw *hw,
+   struct clk_rate_request *req)
+{
+   struct clk_rate_request parent_req = { };
+   struct clk_hw *p;
+   unsigned long rate = req->rate;
+   int ret;
+
+   if (rate < req->min_rate || rate > req->max_rate)
+   return -EINVAL;
+
+   /* Get fixed parent - GPU_CC_PLL0_OUT_EVEN */
+   p = clk_hw_get_parent_by_index(hw, 1);
+
+   /* Parent should always run at twice of the requested rate */
+   parent_req.rate = 2 * req->rate;
+
+   ret = __clk_determine_rate(req->best_parent_hw, _req);
+   if (ret)
+   return ret;
+
+   req->best_parent_hw = p;
+   req->best_parent_rate = parent_req.rate;
+   req->rate = parent_req.rate / 2;
+
+   return 0;
+}
+
+static int clk_rcg2_gfx3d_set_rate(struct clk_hw *hw, unsigned long rate,
+   unsigned long parent_rate)
+{
+   struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+   int ret;
+   u32 cfg;
+
+   /* Configure fixed SRC and DIV */
+   cfg = rcg->parent_map[1].cfg << CFG_SRC_SEL_SHIFT;
+   cfg |= 0x3 << CFG_SRC_DIV_SHIFT;
+
+   ret = regmap_write(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, cfg);
+   if (ret)
+   return ret;
+
+   /*
+* In case clock is disabled, update the SRC and DIV only
+* and return without configuration update.
+*/
+   if (!__clk_is_enabled(hw->clk))
+   return 0;
+
+   return update_config(rcg);
+}
+
+static int clk_rcg2_gfx3d_set_rate_and_parent(struct clk_hw *hw,
+   unsigned long rate, unsigned long parent_rate, u8 index)
+{
+   return clk_rcg2_gfx3d_set_rate(hw, rate, parent_rate);
+}
+
+const struct clk_ops clk_rcg2_gfx3d_ops = {
+   .enable = clk_rcg2_gfx3d_enable,
+   .disable = clk_rcg2_shared_disable,
+   .get_parent = clk_rcg2_get_parent,
+   .set_parent = clk_rcg2_set_parent,
+   .recalc_rate = clk_rcg2_recalc_rate,
+   .determine_rate = clk_rcg2_gfx3d_determine_rate,
+   .set_rate = clk_rcg2_gfx3d_set_rate,
+   .set_rate_and_parent = clk_rcg2_gfx3d_set_rate_and_parent,
+};
+EXPORT_SYMBOL_GPL(clk_rcg2_gfx3d_ops);
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



[PATCH v2 0/4] Add QCOM graphics clock controller driver for SDM845

2018-07-12 Thread Amit Nischal
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://lkml.org/lkml/2018/6/6/294

Amit Nischal (4):
  clk: qcom: gdsc: Add support to enable/disable the clocks with GDSC
  clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845
  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/clk-rcg.h |   1 +
 drivers/clk/qcom/clk-rcg2.c|  87 +++-
 drivers/clk/qcom/gdsc.c|  44 +++
 drivers/clk/qcom/gdsc.h|   5 +
 drivers/clk/qcom/gpucc-sdm845.c| 438 +
 include/dt-bindings/clock/qcom,gpucc-sdm845.h  |  38 ++
 9 files changed, 639 insertions(+), 2 deletions(-)
 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 Code Aurora Forum, hosted by The Linux Foundation



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

2018-07-12 Thread Amit Nischal
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 
---
 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 
 #include 
 #include 
 #include 
@@ -208,11 +210,41 @@ static inline void gdsc_assert_reset_aon(struct gdsc *sc)
regmap_update_bits(sc->regmap, sc->clamp_io_ctrl,
   GMEM_RESET_MASK, 0);
 }
+
+static int gdsc_clk_prepare_enable(struct gdsc *sc)
+{
+   int i, ret;
+
+   for (i = 0; i < sc->clk_count; i++) {
+   ret = clk_prepare_enable(sc->clk_hws[i]->clk);
+   if (ret) {
+   for (i--; i >= 0; i--)
+   clk_disable_unprepare(sc->clk_hws[i]->clk);
+   return ret;
+   }
+   }
+   return 0;
+}
+
+static void gdsc_clk_disable_unprepare(struct gdsc *sc)
+{
+   int i;
+
+   for (i = 0; i < sc->clk_count; i++)
+   clk_disable_unprepare(sc->clk_hws[i]->clk);
+}
+
 static int gdsc_enable(struct generic_pm_domain *domain)
 {
struct gdsc *sc = domain_to_gdsc(domain);
int ret;
 
+   if (sc->clk_count) {
+   ret = gdsc_clk_prepare_enable(sc);
+   if (ret)
+   return ret;
+   }
+
if (sc->pwrsts == PWRSTS_ON)
return gdsc_deassert_reset(sc);
 
@@ -260,6 +292,9 @@ static int gdsc_enable(struct generic_pm_domain *domain)
udelay(1);
}
 
+   if (sc->clk_count)
+   gdsc_clk_disable_unprepare(sc);
+
return 0;
 }
 
@@ -268,6 +303,12 @@ static int gdsc_disable(struct generic_pm_domain *domain)
struct gdsc *sc = domain_to_gdsc(domain);
int ret;
 
+   if (sc->clk_count) {
+   ret = gdsc_clk_prepare_enable(sc);
+   if (ret)
+   return ret;
+   }
+
if (sc->pwrsts == PWRSTS_ON)
return gdsc_assert_reset(sc);
 
@@ -299,6 +340,9 @@ static int gdsc_disable(struct generic_pm_domain *domain)
if (sc->flags & CLAMP_IO)
gdsc_assert_clamp_io(sc);
 
+   if (sc->clk_count)
+   gdsc_clk_disable_unprepare(sc);
+
return 0;
 }
 
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
index bd1f2c7..59957d7 100644
--- a/drivers/clk/qcom/gdsc.h
+++ b/drivers/clk/qcom/gdsc.h
@@ -17,6 +17,7 @@
 #include 
 #include 
 
+struct clk_hw;
 struct regmap;
 struct reset_controller_dev;
 
@@ -32,6 +33,8 @@
  * @resets: ids of resets associated with this gdsc
  * @reset_count: number of @resets
  * @rcdev: reset controller
+ * @clk_count: number of associated clocks
+ * @clk_hws: clk_hw pointers for associated clocks with gdsc
  */
 struct gdsc {
struct generic_pm_domainpd;
@@ -60,6 +63,8 @@ struct gdsc {
struct reset_controller_dev *rcdev;
unsigned int*resets;
unsigned intreset_count;
+   unsigned intclk_count;
+   struct clk_hw   *clk_hws[];
 };
 
 struct gdsc_desc {
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



[PATCH v2 0/4] Add QCOM graphics clock controller driver for SDM845

2018-07-12 Thread Amit Nischal
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://lkml.org/lkml/2018/6/6/294

Amit Nischal (4):
  clk: qcom: gdsc: Add support to enable/disable the clocks with GDSC
  clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845
  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/clk-rcg.h |   1 +
 drivers/clk/qcom/clk-rcg2.c|  87 +++-
 drivers/clk/qcom/gdsc.c|  44 +++
 drivers/clk/qcom/gdsc.h|   5 +
 drivers/clk/qcom/gpucc-sdm845.c| 438 +
 include/dt-bindings/clock/qcom,gpucc-sdm845.h  |  38 ++
 9 files changed, 639 insertions(+), 2 deletions(-)
 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 Code Aurora Forum, hosted by The Linux Foundation



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

2018-07-12 Thread Amit Nischal
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 
---
 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 
 #include 
 #include 
 #include 
@@ -208,11 +210,41 @@ static inline void gdsc_assert_reset_aon(struct gdsc *sc)
regmap_update_bits(sc->regmap, sc->clamp_io_ctrl,
   GMEM_RESET_MASK, 0);
 }
+
+static int gdsc_clk_prepare_enable(struct gdsc *sc)
+{
+   int i, ret;
+
+   for (i = 0; i < sc->clk_count; i++) {
+   ret = clk_prepare_enable(sc->clk_hws[i]->clk);
+   if (ret) {
+   for (i--; i >= 0; i--)
+   clk_disable_unprepare(sc->clk_hws[i]->clk);
+   return ret;
+   }
+   }
+   return 0;
+}
+
+static void gdsc_clk_disable_unprepare(struct gdsc *sc)
+{
+   int i;
+
+   for (i = 0; i < sc->clk_count; i++)
+   clk_disable_unprepare(sc->clk_hws[i]->clk);
+}
+
 static int gdsc_enable(struct generic_pm_domain *domain)
 {
struct gdsc *sc = domain_to_gdsc(domain);
int ret;
 
+   if (sc->clk_count) {
+   ret = gdsc_clk_prepare_enable(sc);
+   if (ret)
+   return ret;
+   }
+
if (sc->pwrsts == PWRSTS_ON)
return gdsc_deassert_reset(sc);
 
@@ -260,6 +292,9 @@ static int gdsc_enable(struct generic_pm_domain *domain)
udelay(1);
}
 
+   if (sc->clk_count)
+   gdsc_clk_disable_unprepare(sc);
+
return 0;
 }
 
@@ -268,6 +303,12 @@ static int gdsc_disable(struct generic_pm_domain *domain)
struct gdsc *sc = domain_to_gdsc(domain);
int ret;
 
+   if (sc->clk_count) {
+   ret = gdsc_clk_prepare_enable(sc);
+   if (ret)
+   return ret;
+   }
+
if (sc->pwrsts == PWRSTS_ON)
return gdsc_assert_reset(sc);
 
@@ -299,6 +340,9 @@ static int gdsc_disable(struct generic_pm_domain *domain)
if (sc->flags & CLAMP_IO)
gdsc_assert_clamp_io(sc);
 
+   if (sc->clk_count)
+   gdsc_clk_disable_unprepare(sc);
+
return 0;
 }
 
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
index bd1f2c7..59957d7 100644
--- a/drivers/clk/qcom/gdsc.h
+++ b/drivers/clk/qcom/gdsc.h
@@ -17,6 +17,7 @@
 #include 
 #include 
 
+struct clk_hw;
 struct regmap;
 struct reset_controller_dev;
 
@@ -32,6 +33,8 @@
  * @resets: ids of resets associated with this gdsc
  * @reset_count: number of @resets
  * @rcdev: reset controller
+ * @clk_count: number of associated clocks
+ * @clk_hws: clk_hw pointers for associated clocks with gdsc
  */
 struct gdsc {
struct generic_pm_domainpd;
@@ -60,6 +63,8 @@ struct gdsc {
struct reset_controller_dev *rcdev;
unsigned int*resets;
unsigned intreset_count;
+   unsigned intclk_count;
+   struct clk_hw   *clk_hws[];
 };
 
 struct gdsc_desc {
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



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

2018-07-12 Thread Amit Nischal

On 2018-07-09 11:37, Stephen Boyd wrote:

Quoting Amit Nischal (2018-06-06 04:41:48)
diff --git a/drivers/clk/qcom/gpucc-sdm845.c 
b/drivers/clk/qcom/gpucc-sdm845.c

new file mode 100644
index 000..81f8926
--- /dev/null
+++ b/drivers/clk/qcom/gpucc-sdm845.c
@@ -0,0 +1,441 @@
+// 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)
+
+#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }


This should be removed and series can depend on Taniya's patch.



Yes sure. I will do the required change and will submit the next
patch series.


+
+enum {
+   P_BI_TCXO,
+   P_CORE_BI_PLL_TEST_SE,
+   P_GPLL0_OUT_MAIN,
+   P_GPLL0_OUT_MAIN_DIV,

[...]

+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "gpu_cc_pll0",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static const struct clk_div_table post_div_table_fabia_even[] = {
+   { 0x0, 1 },
+   {},


Drop the trailing comma, it's a sentinel presumably.



Will fix this in the next patch series.


+};
+
+static struct clk_alpha_pll_postdiv gpu_cc_pll0_out_even = {
+   .offset = 0x0,
+   .post_div_shift = 8,
+   .post_div_table = post_div_table_fabia_even,
+   .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+   .width = 4,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "gpu_cc_pll0_out_even",
+   .parent_names = (const char *[]){ "gpu_cc_pll0" },
+   .num_parents = 1,
+   .flags = CLK_SET_RATE_PARENT,
+   .ops = _alpha_pll_postdiv_fabia_ops,
+   },
+};
+
+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 = _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 = _rcg2_shared_ops,
+   },
+};
+
+static const struct freq_tbl ftbl_gpu_cc_gx_gfx3d_clk_src[] = {
+   F(18000, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),
+   F(25700, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),
+   F(34200, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),
+   F(41400, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),
+   F(52000, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),
+   F(59600, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),
+   F(67500, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),
+   F(71000, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),


Do we really need to encode anything here in this table? Why can't we
have clk_ops that hardcode this clk to be a div-2 that passes the
frequency up to the parent source? Then this frequency table doesn't
need to be here at all, and can live in DT as an OPP table used by the
GPU driver.



Thanks for the suggestion.
I will address the same in the next patch series where
"clk_rcg2_gfx3d_determine_rate" op will always return the best parent as
‘GPU_CC_PLL0_OUT_EVEN’ and best_parent rate equal to twice of the 
requested rate.

This will eliminate the need of frequency table.


+   { }
+};
+
+static struct clk_rcg2 gpu_cc_gx_gfx3d_clk_src = {
+   .cmd_rcgr = 0x101c,
+   .mnd_width = 0,
+   .hid_wi

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

2018-07-12 Thread Amit Nischal

On 2018-07-09 11:37, Stephen Boyd wrote:

Quoting Amit Nischal (2018-06-06 04:41:48)
diff --git a/drivers/clk/qcom/gpucc-sdm845.c 
b/drivers/clk/qcom/gpucc-sdm845.c

new file mode 100644
index 000..81f8926
--- /dev/null
+++ b/drivers/clk/qcom/gpucc-sdm845.c
@@ -0,0 +1,441 @@
+// 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)
+
+#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }


This should be removed and series can depend on Taniya's patch.



Yes sure. I will do the required change and will submit the next
patch series.


+
+enum {
+   P_BI_TCXO,
+   P_CORE_BI_PLL_TEST_SE,
+   P_GPLL0_OUT_MAIN,
+   P_GPLL0_OUT_MAIN_DIV,

[...]

+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "gpu_cc_pll0",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static const struct clk_div_table post_div_table_fabia_even[] = {
+   { 0x0, 1 },
+   {},


Drop the trailing comma, it's a sentinel presumably.



Will fix this in the next patch series.


+};
+
+static struct clk_alpha_pll_postdiv gpu_cc_pll0_out_even = {
+   .offset = 0x0,
+   .post_div_shift = 8,
+   .post_div_table = post_div_table_fabia_even,
+   .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+   .width = 4,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "gpu_cc_pll0_out_even",
+   .parent_names = (const char *[]){ "gpu_cc_pll0" },
+   .num_parents = 1,
+   .flags = CLK_SET_RATE_PARENT,
+   .ops = _alpha_pll_postdiv_fabia_ops,
+   },
+};
+
+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 = _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 = _rcg2_shared_ops,
+   },
+};
+
+static const struct freq_tbl ftbl_gpu_cc_gx_gfx3d_clk_src[] = {
+   F(18000, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),
+   F(25700, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),
+   F(34200, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),
+   F(41400, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),
+   F(52000, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),
+   F(59600, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),
+   F(67500, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),
+   F(71000, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),


Do we really need to encode anything here in this table? Why can't we
have clk_ops that hardcode this clk to be a div-2 that passes the
frequency up to the parent source? Then this frequency table doesn't
need to be here at all, and can live in DT as an OPP table used by the
GPU driver.



Thanks for the suggestion.
I will address the same in the next patch series where
"clk_rcg2_gfx3d_determine_rate" op will always return the best parent as
‘GPU_CC_PLL0_OUT_EVEN’ and best_parent rate equal to twice of the 
requested rate.

This will eliminate the need of frequency table.


+   { }
+};
+
+static struct clk_rcg2 gpu_cc_gx_gfx3d_clk_src = {
+   .cmd_rcgr = 0x101c,
+   .mnd_width = 0,
+   .hid_wi

Re: [PATCH 3/4] dt-bindings: clock: Introduce QCOM Graphics clock bindings

2018-07-12 Thread Amit Nischal

On 2018-07-09 11:08, Stephen Boyd wrote:

Quoting Amit Nischal (2018-06-06 04:41:47)
diff --git a/Documentation/devicetree/bindings/clock/qcom,gpucc.txt 
b/Documentation/devicetree/bindings/clock/qcom,gpucc.txt

new file mode 100644
index 000..e311219
--- /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 {


Drop the double '@'


Oh. I will fix this in next patch series.




+   compatible = "qcom,sdm845-gpucc";
+   reg = <0x509 0x9000>;
+   #clock-cells = <1>;
+   #reset-cells = <1>;
+   #power-domain-cells = <1>;
+   };

--
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


Re: [PATCH 3/4] dt-bindings: clock: Introduce QCOM Graphics clock bindings

2018-07-12 Thread Amit Nischal

On 2018-07-09 11:08, Stephen Boyd wrote:

Quoting Amit Nischal (2018-06-06 04:41:47)
diff --git a/Documentation/devicetree/bindings/clock/qcom,gpucc.txt 
b/Documentation/devicetree/bindings/clock/qcom,gpucc.txt

new file mode 100644
index 000..e311219
--- /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 {


Drop the double '@'


Oh. I will fix this in next patch series.




+   compatible = "qcom,sdm845-gpucc";
+   reg = <0x509 0x9000>;
+   #clock-cells = <1>;
+   #reset-cells = <1>;
+   #power-domain-cells = <1>;
+   };

--
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


Re: [PATCH 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845

2018-07-12 Thread Amit Nischal

On 2018-07-09 11:45, Stephen Boyd wrote:

Quoting Amit Nischal (2018-06-06 04:41:46)

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() and set_rate() 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.



It sounds like the GDSC enable is ANDed with the RCG's root enable
bit?


Here, the root clock (GFX3D RCG) needs to be enabled first before
writing to SW_COLLAPSE bit of the GDSC. RCG's CLK_ON signal would
power up the GDSC.


Does the RCG need to be clocking for the GDSC to actually turn on?
Or is it purely that the enable bit is logically combined that way so
that if the RCG is parented to a PLL that's off the GDSC will still 
turn

on?



Yes, the RCG needs to be clocking for the GPU_GX GDSC to actually turn 
on.



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.


Anyway, this patch will probably significantly change given that the 
RCG

is a glorified div-2 that muxes between a safe CXO speed and a
configurable PLL frequency. A lot of the logic can probably just be
hardcoded then.



Thanks for the suggestion.
We are planning to introduce the "clk_rcg2_gfx3d_determine_rate" op 
which will

always return the best parent as ‘GPU_CC_PLL0_OUT_EVEN’ and best_parent
rate equal to twice of the requested rate. With this approach frequency 
table
for rcg2 structure would not be required as all the supported 
frequencies would

be derived from the GPU_CC_PLL0_OUT_EVEN src with a divider of 2.

Also, we will add support to check the requested rate if falls within 
allowed
set_rate range. This will make sure that the source PLL would not go out 
of
the supported range. set_rate_range would be set by the GPUCC driver 
with min/max

value by calling below API.

clk_hw_set_rate_range(_cc_gx_gfx3d_clk_src.clkr.hw, 18000, 
71000)




Signed-off-by: Amit Nischal 


Patch looks sane.
--
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


Re: [PATCH 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845

2018-07-12 Thread Amit Nischal

On 2018-07-09 11:45, Stephen Boyd wrote:

Quoting Amit Nischal (2018-06-06 04:41:46)

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() and set_rate() 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.



It sounds like the GDSC enable is ANDed with the RCG's root enable
bit?


Here, the root clock (GFX3D RCG) needs to be enabled first before
writing to SW_COLLAPSE bit of the GDSC. RCG's CLK_ON signal would
power up the GDSC.


Does the RCG need to be clocking for the GDSC to actually turn on?
Or is it purely that the enable bit is logically combined that way so
that if the RCG is parented to a PLL that's off the GDSC will still 
turn

on?



Yes, the RCG needs to be clocking for the GPU_GX GDSC to actually turn 
on.



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.


Anyway, this patch will probably significantly change given that the 
RCG

is a glorified div-2 that muxes between a safe CXO speed and a
configurable PLL frequency. A lot of the logic can probably just be
hardcoded then.



Thanks for the suggestion.
We are planning to introduce the "clk_rcg2_gfx3d_determine_rate" op 
which will

always return the best parent as ‘GPU_CC_PLL0_OUT_EVEN’ and best_parent
rate equal to twice of the requested rate. With this approach frequency 
table
for rcg2 structure would not be required as all the supported 
frequencies would

be derived from the GPU_CC_PLL0_OUT_EVEN src with a divider of 2.

Also, we will add support to check the requested rate if falls within 
allowed
set_rate range. This will make sure that the source PLL would not go out 
of
the supported range. set_rate_range would be set by the GPUCC driver 
with min/max

value by calling below API.

clk_hw_set_rate_range(_cc_gx_gfx3d_clk_src.clkr.hw, 18000, 
71000)




Signed-off-by: Amit Nischal 


Patch looks sane.
--
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


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

2018-07-12 Thread Amit Nischal

Hi Stephen,

Thanks for the review comments.

Regards,
Amit

On 2018-07-09 11:04, Stephen Boyd wrote:

Quoting Amit Nischal (2018-06-06 04:41:45)

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


Why is there a requirement? Do the clks need to be in hw control mode 
or

they can't be turned off when the GDSC is off? It's hard for me to
understand with these vague statements.



This requirement is primarily to turn on the GPU GX GDSC and these 
clocks

do not need to be in HW control mode and clock disable is not related
with the GDSC.

To turn on the GX GDSC, root clock (GFX3D RCG) needs to be enabled first
before writing to SW_COLLAPSE bit of the GDSC. The CLK_ON signal from 
RCG

would power up the GPU GX GDSC.



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 
---
 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 


Ugh.


+#include 


Both, really?



Above includes are required else we get a compilation error as below:
error: dereferencing pointer to incomplete type
   ret = clk_prepare_enable(sc->clk_hws[i]->clk);
  ^


 #include 
 #include 
 #include 
@@ -208,11 +210,41 @@ static inline void gdsc_assert_reset_aon(struct 
gdsc *sc)

regmap_update_bits(sc->regmap, sc->clamp_io_ctrl,
   GMEM_RESET_MASK, 0);
 }
+
+static int gdsc_clk_prepare_enable(struct gdsc *sc)
+{
+   int i, ret;
+
+   for (i = 0; i < sc->clk_count; i++) {
+   ret = clk_prepare_enable(sc->clk_hws[i]->clk);
+   if (ret) {
+   for (i--; i >= 0; i--)
+   
clk_disable_unprepare(sc->clk_hws[i]->clk);

+   return ret;
+   }
+   }
+   return 0;
+}
+


Looks an awful lot like bulk_enable clk API.


As mentioned above, ROOT_EN bit of GFX3D RCG needs to be enabled first 
to
turn on the GDSC. We want this enable to happen only through clock 
framework

API in order to avoid stability issues.


--
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


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

2018-07-12 Thread Amit Nischal

Hi Stephen,

Thanks for the review comments.

Regards,
Amit

On 2018-07-09 11:04, Stephen Boyd wrote:

Quoting Amit Nischal (2018-06-06 04:41:45)

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


Why is there a requirement? Do the clks need to be in hw control mode 
or

they can't be turned off when the GDSC is off? It's hard for me to
understand with these vague statements.



This requirement is primarily to turn on the GPU GX GDSC and these 
clocks

do not need to be in HW control mode and clock disable is not related
with the GDSC.

To turn on the GX GDSC, root clock (GFX3D RCG) needs to be enabled first
before writing to SW_COLLAPSE bit of the GDSC. The CLK_ON signal from 
RCG

would power up the GPU GX GDSC.



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 
---
 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 


Ugh.


+#include 


Both, really?



Above includes are required else we get a compilation error as below:
error: dereferencing pointer to incomplete type
   ret = clk_prepare_enable(sc->clk_hws[i]->clk);
  ^


 #include 
 #include 
 #include 
@@ -208,11 +210,41 @@ static inline void gdsc_assert_reset_aon(struct 
gdsc *sc)

regmap_update_bits(sc->regmap, sc->clamp_io_ctrl,
   GMEM_RESET_MASK, 0);
 }
+
+static int gdsc_clk_prepare_enable(struct gdsc *sc)
+{
+   int i, ret;
+
+   for (i = 0; i < sc->clk_count; i++) {
+   ret = clk_prepare_enable(sc->clk_hws[i]->clk);
+   if (ret) {
+   for (i--; i >= 0; i--)
+   
clk_disable_unprepare(sc->clk_hws[i]->clk);

+   return ret;
+   }
+   }
+   return 0;
+}
+


Looks an awful lot like bulk_enable clk API.


As mentioned above, ROOT_EN bit of GFX3D RCG needs to be enabled first 
to
turn on the GDSC. We want this enable to happen only through clock 
framework

API in order to avoid stability issues.


--
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


[PATCH v3] clk: qcom: Enable clocks which needs to be always on for SDM845

2018-06-11 Thread Amit Nischal
There are certain clocks which needs to be always enabled for system
operation. Add support for the same by adding 'CLK_IS_CRITICAL' flag
for such clocks.

Signed-off-by: Amit Nischal 
---

Changes in v3:
* Addressed review comments by Stephen to associate 'CLK_IS_CRITICAL'
  flag for the clocks which are required to be always ON.
* Added two gcc_cpuss* critical clocks and remove direct clock enable
  for them from gcc probe function.

Changes in v2:
* Fix target name in kernel configuration help text for SDM845 GCC
  clock driver.

[v1]: https://lkml.org/lkml/2018/5/28/171
[v2]: https://lkml.org/lkml/2018/5/29/43

 drivers/clk/qcom/gcc-sdm845.c   | 43 ++---
 include/dt-bindings/clock/qcom,gcc-sdm845.h |  2 ++
 2 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index e78e6f5..0f694ed 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -1103,6 +1103,7 @@ enum {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_camera_ahb_clk",
+   .flags = CLK_IS_CRITICAL,
.ops = _branch2_ops,
},
},
@@ -1129,6 +1130,7 @@ enum {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_camera_xo_clk",
+   .flags = CLK_IS_CRITICAL,
.ops = _branch2_ops,
},
},
@@ -1270,6 +1272,7 @@ enum {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_disp_ahb_clk",
+   .flags = CLK_IS_CRITICAL,
.ops = _branch2_ops,
},
},
@@ -1328,6 +1331,7 @@ enum {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_disp_xo_clk",
+   .flags = CLK_IS_CRITICAL,
.ops = _branch2_ops,
},
},
@@ -1397,6 +1401,7 @@ enum {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_gpu_cfg_ahb_clk",
+   .flags = CLK_IS_CRITICAL,
.ops = _branch2_ops,
},
},
@@ -2985,6 +2990,7 @@ enum {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_video_ahb_clk",
+   .flags = CLK_IS_CRITICAL,
.ops = _branch2_ops,
},
},
@@ -3011,6 +3017,7 @@ enum {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_video_xo_clk",
+   .flags = CLK_IS_CRITICAL,
.ops = _branch2_ops,
},
},
@@ -3049,6 +3056,36 @@ enum {
},
 };

+static struct clk_branch gcc_cpuss_dvm_bus_clk = {
+   .halt_reg = 0x48190,
+   .halt_check = BRANCH_HALT,
+   .clkr = {
+   .enable_reg = 0x48190,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_cpuss_dvm_bus_clk",
+   .flags = CLK_IS_CRITICAL,
+   .ops = _branch2_ops,
+   },
+   },
+};
+
+static struct clk_branch gcc_cpuss_gnoc_clk = {
+   .halt_reg = 0x48004,
+   .halt_check = BRANCH_HALT_VOTED,
+   .hwcg_reg = 0x48004,
+   .hwcg_bit = 1,
+   .clkr = {
+   .enable_reg = 0x52004,
+   .enable_mask = BIT(22),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_cpuss_gnoc_clk",
+   .flags = CLK_IS_CRITICAL,
+   .ops = _branch2_ops,
+   },
+   },
+};
+
 static struct gdsc pcie_0_gdsc = {
.gdscr = 0x6b004,
.pd = {
@@ -3344,6 +3381,8 @@ enum {
[GPLL0] = ,
[GPLL0_OUT_EVEN] = _out_even.clkr,
[GPLL4] = ,
+   [GCC_CPUSS_DVM_BUS_CLK] = _cpuss_dvm_bus_clk.clkr,
+   [GCC_CPUSS_GNOC_CLK] = _cpuss_gnoc_clk.clkr,
 };

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

-   /* Enable CPUSS clocks */
-   regmap_update_bits(regmap, 0x48190, BIT(0), 0x1);
-   regmap_update_bits(regmap, 0x52004, BIT(22), 0x1);
-
return qcom_cc_really_probe(pdev, _sdm845_desc, regmap);
 }

diff --

[PATCH v3] clk: qcom: Enable clocks which needs to be always on for SDM845

2018-06-11 Thread Amit Nischal
There are certain clocks which needs to be always enabled for system
operation. Add support for the same by adding 'CLK_IS_CRITICAL' flag
for such clocks.

Signed-off-by: Amit Nischal 
---

Changes in v3:
* Addressed review comments by Stephen to associate 'CLK_IS_CRITICAL'
  flag for the clocks which are required to be always ON.
* Added two gcc_cpuss* critical clocks and remove direct clock enable
  for them from gcc probe function.

Changes in v2:
* Fix target name in kernel configuration help text for SDM845 GCC
  clock driver.

[v1]: https://lkml.org/lkml/2018/5/28/171
[v2]: https://lkml.org/lkml/2018/5/29/43

 drivers/clk/qcom/gcc-sdm845.c   | 43 ++---
 include/dt-bindings/clock/qcom,gcc-sdm845.h |  2 ++
 2 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index e78e6f5..0f694ed 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -1103,6 +1103,7 @@ enum {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_camera_ahb_clk",
+   .flags = CLK_IS_CRITICAL,
.ops = _branch2_ops,
},
},
@@ -1129,6 +1130,7 @@ enum {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_camera_xo_clk",
+   .flags = CLK_IS_CRITICAL,
.ops = _branch2_ops,
},
},
@@ -1270,6 +1272,7 @@ enum {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_disp_ahb_clk",
+   .flags = CLK_IS_CRITICAL,
.ops = _branch2_ops,
},
},
@@ -1328,6 +1331,7 @@ enum {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_disp_xo_clk",
+   .flags = CLK_IS_CRITICAL,
.ops = _branch2_ops,
},
},
@@ -1397,6 +1401,7 @@ enum {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_gpu_cfg_ahb_clk",
+   .flags = CLK_IS_CRITICAL,
.ops = _branch2_ops,
},
},
@@ -2985,6 +2990,7 @@ enum {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_video_ahb_clk",
+   .flags = CLK_IS_CRITICAL,
.ops = _branch2_ops,
},
},
@@ -3011,6 +3017,7 @@ enum {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_video_xo_clk",
+   .flags = CLK_IS_CRITICAL,
.ops = _branch2_ops,
},
},
@@ -3049,6 +3056,36 @@ enum {
},
 };

+static struct clk_branch gcc_cpuss_dvm_bus_clk = {
+   .halt_reg = 0x48190,
+   .halt_check = BRANCH_HALT,
+   .clkr = {
+   .enable_reg = 0x48190,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_cpuss_dvm_bus_clk",
+   .flags = CLK_IS_CRITICAL,
+   .ops = _branch2_ops,
+   },
+   },
+};
+
+static struct clk_branch gcc_cpuss_gnoc_clk = {
+   .halt_reg = 0x48004,
+   .halt_check = BRANCH_HALT_VOTED,
+   .hwcg_reg = 0x48004,
+   .hwcg_bit = 1,
+   .clkr = {
+   .enable_reg = 0x52004,
+   .enable_mask = BIT(22),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_cpuss_gnoc_clk",
+   .flags = CLK_IS_CRITICAL,
+   .ops = _branch2_ops,
+   },
+   },
+};
+
 static struct gdsc pcie_0_gdsc = {
.gdscr = 0x6b004,
.pd = {
@@ -3344,6 +3381,8 @@ enum {
[GPLL0] = ,
[GPLL0_OUT_EVEN] = _out_even.clkr,
[GPLL4] = ,
+   [GCC_CPUSS_DVM_BUS_CLK] = _cpuss_dvm_bus_clk.clkr,
+   [GCC_CPUSS_GNOC_CLK] = _cpuss_gnoc_clk.clkr,
 };

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

-   /* Enable CPUSS clocks */
-   regmap_update_bits(regmap, 0x48190, BIT(0), 0x1);
-   regmap_update_bits(regmap, 0x52004, BIT(22), 0x1);
-
return qcom_cc_really_probe(pdev, _sdm845_desc, regmap);
 }

diff --

Re: [PATCH v2] clk: qcom: Enable clocks which needs to be always on for SDM845

2018-06-11 Thread Amit Nischal

On 2018-06-01 22:06, Stephen Boyd wrote:

Quoting Amit Nischal (2018-05-28 23:07:46)

There are certain clocks which needs to be always enabled for system
operation. Remove support for such clocks from the clock driver and
enable them explicitly gcc driver probe. Also fix the target name in
kernel configuration description for SDM845 gcc driver.


This is why we have CLK_IS_CRITICAL.



Signed-off-by: Amit Nischal 
---
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index fc3edd1..79e9144 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -231,7 +231,7 @@ config SDM_GCC_845
select QCOM_GDSC
depends on COMMON_CLK_QCOM
help
- Support for the global clock controller on msm8998 devices.
+ Support for the global clock controller on SDM845 devices.
  Say Y if you want to use peripheral devices such as UART, 
SPI,

  I2C, USB, UFS, SDDC, PCIe, etc.



This can be its own patch.



Thanks for fixing above as this is already in the clk-next branch
under commit "77122d".

diff --git a/drivers/clk/qcom/gcc-sdm845.c 
b/drivers/clk/qcom/gcc-sdm845.c

index e78e6f5..b40aafc 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -3433,9 +3327,16 @@ static int gcc_sdm845_probe(struct 
platform_device *pdev)

regmap_update_bits(regmap, 0x09ffc, 0x3, 0x3);
regmap_update_bits(regmap, 0x71028, 0x3, 0x3);

-   /* Enable CPUSS clocks */
-   regmap_update_bits(regmap, 0x48190, BIT(0), 0x1);
-   regmap_update_bits(regmap, 0x52004, BIT(22), 0x1);
+   /* Enable clocks which are required to be always ON */
+   regmap_update_bits(regmap, 0xb004, BIT(0), BIT(0));
+   regmap_update_bits(regmap, 0xb008, BIT(0), BIT(0));
+   regmap_update_bits(regmap, 0xb00c, BIT(0), BIT(0));
+   regmap_update_bits(regmap, 0xb028, BIT(0), BIT(0));
+   regmap_update_bits(regmap, 0xb02c, BIT(0), BIT(0));
+   regmap_update_bits(regmap, 0xb030, BIT(0), BIT(0));
+   regmap_update_bits(regmap, 0x48190, BIT(0), BIT(0));
+   regmap_update_bits(regmap, 0x52004, BIT(22), BIT(22));
+   regmap_update_bits(regmap, 0x71004, BIT(0), BIT(0));


Let's do CLK_IS_CRITICAL flag instead. That has the added benefit of
checking to make sure the halt bit toggles correctly so the clks are
verified to be enabled.



I will submit the next patch for all above-listed clocks with
CLK_IS_CRITICAL flag.



return qcom_cc_really_probe(pdev, _sdm845_desc, regmap);
 }
diff --git a/include/dt-bindings/clock/qcom,gcc-sdm845.h 
b/include/dt-bindings/clock/qcom,gcc-sdm845.h

index aca6126..6330c3f 100644
--- a/include/dt-bindings/clock/qcom,gcc-sdm845.h
+++ b/include/dt-bindings/clock/qcom,gcc-sdm845.h
@@ -13,185 +13,178 @@
 #define GCC_AGGRE_USB3_PRIM_AXI_CLK3
 #define GCC_AGGRE_USB3_SEC_AXI_CLK 4
 #define GCC_BOOT_ROM_AHB_CLK   5
-#define GCC_CAMERA_AHB_CLK 6


Don't do this. Things should only be added to here, not removed or
reshuffled.


-#define GCC_CAMERA_AXI_CLK 7
-#define GCC_CAMERA_XO_CLK  8
-#define GCC_CE1_AHB_CLK   
 9

--
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


Re: [PATCH v2] clk: qcom: Enable clocks which needs to be always on for SDM845

2018-06-11 Thread Amit Nischal

On 2018-06-01 22:06, Stephen Boyd wrote:

Quoting Amit Nischal (2018-05-28 23:07:46)

There are certain clocks which needs to be always enabled for system
operation. Remove support for such clocks from the clock driver and
enable them explicitly gcc driver probe. Also fix the target name in
kernel configuration description for SDM845 gcc driver.


This is why we have CLK_IS_CRITICAL.



Signed-off-by: Amit Nischal 
---
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index fc3edd1..79e9144 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -231,7 +231,7 @@ config SDM_GCC_845
select QCOM_GDSC
depends on COMMON_CLK_QCOM
help
- Support for the global clock controller on msm8998 devices.
+ Support for the global clock controller on SDM845 devices.
  Say Y if you want to use peripheral devices such as UART, 
SPI,

  I2C, USB, UFS, SDDC, PCIe, etc.



This can be its own patch.



Thanks for fixing above as this is already in the clk-next branch
under commit "77122d".

diff --git a/drivers/clk/qcom/gcc-sdm845.c 
b/drivers/clk/qcom/gcc-sdm845.c

index e78e6f5..b40aafc 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -3433,9 +3327,16 @@ static int gcc_sdm845_probe(struct 
platform_device *pdev)

regmap_update_bits(regmap, 0x09ffc, 0x3, 0x3);
regmap_update_bits(regmap, 0x71028, 0x3, 0x3);

-   /* Enable CPUSS clocks */
-   regmap_update_bits(regmap, 0x48190, BIT(0), 0x1);
-   regmap_update_bits(regmap, 0x52004, BIT(22), 0x1);
+   /* Enable clocks which are required to be always ON */
+   regmap_update_bits(regmap, 0xb004, BIT(0), BIT(0));
+   regmap_update_bits(regmap, 0xb008, BIT(0), BIT(0));
+   regmap_update_bits(regmap, 0xb00c, BIT(0), BIT(0));
+   regmap_update_bits(regmap, 0xb028, BIT(0), BIT(0));
+   regmap_update_bits(regmap, 0xb02c, BIT(0), BIT(0));
+   regmap_update_bits(regmap, 0xb030, BIT(0), BIT(0));
+   regmap_update_bits(regmap, 0x48190, BIT(0), BIT(0));
+   regmap_update_bits(regmap, 0x52004, BIT(22), BIT(22));
+   regmap_update_bits(regmap, 0x71004, BIT(0), BIT(0));


Let's do CLK_IS_CRITICAL flag instead. That has the added benefit of
checking to make sure the halt bit toggles correctly so the clks are
verified to be enabled.



I will submit the next patch for all above-listed clocks with
CLK_IS_CRITICAL flag.



return qcom_cc_really_probe(pdev, _sdm845_desc, regmap);
 }
diff --git a/include/dt-bindings/clock/qcom,gcc-sdm845.h 
b/include/dt-bindings/clock/qcom,gcc-sdm845.h

index aca6126..6330c3f 100644
--- a/include/dt-bindings/clock/qcom,gcc-sdm845.h
+++ b/include/dt-bindings/clock/qcom,gcc-sdm845.h
@@ -13,185 +13,178 @@
 #define GCC_AGGRE_USB3_PRIM_AXI_CLK3
 #define GCC_AGGRE_USB3_SEC_AXI_CLK 4
 #define GCC_BOOT_ROM_AHB_CLK   5
-#define GCC_CAMERA_AHB_CLK 6


Don't do this. Things should only be added to here, not removed or
reshuffled.


-#define GCC_CAMERA_AXI_CLK 7
-#define GCC_CAMERA_XO_CLK  8
-#define GCC_CE1_AHB_CLK   
 9

--
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


[PATCH 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845

2018-06-06 Thread Amit Nischal
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() and set_rate() 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.

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.

Signed-off-by: Amit Nischal 
---
 drivers/clk/qcom/clk-rcg.h  |  1 +
 drivers/clk/qcom/clk-rcg2.c | 78 +
 2 files changed, 58 insertions(+), 21 deletions(-)

diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h
index b209a2f..c8c9558 100644
--- a/drivers/clk/qcom/clk-rcg.h
+++ b/drivers/clk/qcom/clk-rcg.h
@@ -160,5 +160,6 @@ struct clk_rcg2 {
 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;
+extern const struct clk_ops clk_rcg2_gfx3d_ops;

 #endif
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index 52208d4..491e710 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -823,28 +823,12 @@ static int clk_rcg2_clear_force_enable(struct clk_hw *hw)
CMD_ROOT_EN, 0);
 }

-static int
-clk_rcg2_shared_force_enable_clear(struct clk_hw *hw, const struct freq_tbl *f)
-{
-   struct clk_rcg2 *rcg = to_clk_rcg2(hw);
-   int ret;
-
-   ret = clk_rcg2_set_force_enable(hw);
-   if (ret)
-   return ret;
-
-   ret = clk_rcg2_configure(rcg, f);
-   if (ret)
-   return ret;
-
-   return clk_rcg2_clear_force_enable(hw);
-}
-
-static int clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate,
+static int __clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
 {
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
const struct freq_tbl *f;
+   int ret;

f = qcom_find_freq(rcg->freq_tbl, rate);
if (!f)
@@ -857,7 +841,23 @@ static int clk_rcg2_shared_set_rate(struct clk_hw *hw, 
unsigned long rate,
if (!__clk_is_enabled(hw->clk))
return __clk_rcg2_configure(rcg, f);

-   return clk_rcg2_shared_force_enable_clear(hw, f);
+   ret = clk_rcg2_set_force_enable(hw);
+   if (ret)
+   return ret;
+
+   return clk_rcg2_configure(rcg, f);
+}
+
+static int clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate,
+   unsigned long parent_rate)
+{
+   int ret;
+
+   ret = __clk_rcg2_shared_set_rate(hw, rate, parent_rate);
+   if (ret)
+   return ret;
+
+   return clk_rcg2_clear_force_enable(hw);
 }

 static int clk_rcg2_shared_set_rate_and_parent(struct clk_hw *hw,
@@ -866,7 +866,7 @@ static int clk_rcg2_shared_set_rate_and_parent(struct 
clk_hw *hw,
return clk_rcg2_shared_set_rate(hw, rate, parent_rate);
 }

-static int clk_rcg2_shared_enable(struct clk_hw *hw)
+static int __clk_rcg2_shared_enable(struct clk_hw *hw)
 {
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
int ret;
@@ -879,7 +879,14 @@ static int clk_rcg2_shared_enable(struct clk_hw *hw)
if (ret)
return ret;

-   ret = update_config(rcg);
+   return update_config(rcg);
+}
+
+static int clk_rcg2_shared_enable(struct clk_hw *hw)
+{
+   int ret;
+
+   ret = __clk_rcg2_shared_enable(hw);
if (ret)
return ret;

@@ -929,3 +936,32 @@ 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);
+
+static int clk_rcg2_gfx3d_enable(struct clk_hw *hw)
+{
+   return __clk_rcg2_shared_enable(hw);
+}
+
+static int clk_rcg2_gfx3d_set_rate(struct clk_hw *hw, unsigned long rate,
+   unsigned long parent_rate)
+{
+   return __clk_rcg2_shared_set_rate(hw, rate, parent_rate);
+}
+
+static int clk_rcg2_gfx3d_set_rate_and_parent(struct clk_hw *hw,
+   unsigned long rate, unsigned long parent_rate, u8 index)
+{
+   return clk_rcg2_gfx3d_set_rate(hw, rate, parent_rate);
+}
+
+const struct clk_ops clk_rcg2_gfx3d_ops = {
+   .enable = clk_rcg2_gfx3d_enable,
+   .disable = clk_rcg2_shared_disable,
+   .get_parent = clk_rcg2_get_parent,
+   .set_parent = clk_rcg2_set_parent,
+   .recalc_rate = clk_rcg2_recalc_rate,
+   .determine_rate = clk_rcg2_determine_rate,
+   .set_rate = clk_rcg2_gfx3d_set_rate,
+   .set_rate_and_parent = clk_rcg2_gfx3d_set

[PATCH 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845

2018-06-06 Thread Amit Nischal
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() and set_rate() 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.

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.

Signed-off-by: Amit Nischal 
---
 drivers/clk/qcom/clk-rcg.h  |  1 +
 drivers/clk/qcom/clk-rcg2.c | 78 +
 2 files changed, 58 insertions(+), 21 deletions(-)

diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h
index b209a2f..c8c9558 100644
--- a/drivers/clk/qcom/clk-rcg.h
+++ b/drivers/clk/qcom/clk-rcg.h
@@ -160,5 +160,6 @@ struct clk_rcg2 {
 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;
+extern const struct clk_ops clk_rcg2_gfx3d_ops;

 #endif
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index 52208d4..491e710 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -823,28 +823,12 @@ static int clk_rcg2_clear_force_enable(struct clk_hw *hw)
CMD_ROOT_EN, 0);
 }

-static int
-clk_rcg2_shared_force_enable_clear(struct clk_hw *hw, const struct freq_tbl *f)
-{
-   struct clk_rcg2 *rcg = to_clk_rcg2(hw);
-   int ret;
-
-   ret = clk_rcg2_set_force_enable(hw);
-   if (ret)
-   return ret;
-
-   ret = clk_rcg2_configure(rcg, f);
-   if (ret)
-   return ret;
-
-   return clk_rcg2_clear_force_enable(hw);
-}
-
-static int clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate,
+static int __clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
 {
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
const struct freq_tbl *f;
+   int ret;

f = qcom_find_freq(rcg->freq_tbl, rate);
if (!f)
@@ -857,7 +841,23 @@ static int clk_rcg2_shared_set_rate(struct clk_hw *hw, 
unsigned long rate,
if (!__clk_is_enabled(hw->clk))
return __clk_rcg2_configure(rcg, f);

-   return clk_rcg2_shared_force_enable_clear(hw, f);
+   ret = clk_rcg2_set_force_enable(hw);
+   if (ret)
+   return ret;
+
+   return clk_rcg2_configure(rcg, f);
+}
+
+static int clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate,
+   unsigned long parent_rate)
+{
+   int ret;
+
+   ret = __clk_rcg2_shared_set_rate(hw, rate, parent_rate);
+   if (ret)
+   return ret;
+
+   return clk_rcg2_clear_force_enable(hw);
 }

 static int clk_rcg2_shared_set_rate_and_parent(struct clk_hw *hw,
@@ -866,7 +866,7 @@ static int clk_rcg2_shared_set_rate_and_parent(struct 
clk_hw *hw,
return clk_rcg2_shared_set_rate(hw, rate, parent_rate);
 }

-static int clk_rcg2_shared_enable(struct clk_hw *hw)
+static int __clk_rcg2_shared_enable(struct clk_hw *hw)
 {
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
int ret;
@@ -879,7 +879,14 @@ static int clk_rcg2_shared_enable(struct clk_hw *hw)
if (ret)
return ret;

-   ret = update_config(rcg);
+   return update_config(rcg);
+}
+
+static int clk_rcg2_shared_enable(struct clk_hw *hw)
+{
+   int ret;
+
+   ret = __clk_rcg2_shared_enable(hw);
if (ret)
return ret;

@@ -929,3 +936,32 @@ 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);
+
+static int clk_rcg2_gfx3d_enable(struct clk_hw *hw)
+{
+   return __clk_rcg2_shared_enable(hw);
+}
+
+static int clk_rcg2_gfx3d_set_rate(struct clk_hw *hw, unsigned long rate,
+   unsigned long parent_rate)
+{
+   return __clk_rcg2_shared_set_rate(hw, rate, parent_rate);
+}
+
+static int clk_rcg2_gfx3d_set_rate_and_parent(struct clk_hw *hw,
+   unsigned long rate, unsigned long parent_rate, u8 index)
+{
+   return clk_rcg2_gfx3d_set_rate(hw, rate, parent_rate);
+}
+
+const struct clk_ops clk_rcg2_gfx3d_ops = {
+   .enable = clk_rcg2_gfx3d_enable,
+   .disable = clk_rcg2_shared_disable,
+   .get_parent = clk_rcg2_get_parent,
+   .set_parent = clk_rcg2_set_parent,
+   .recalc_rate = clk_rcg2_recalc_rate,
+   .determine_rate = clk_rcg2_determine_rate,
+   .set_rate = clk_rcg2_gfx3d_set_rate,
+   .set_rate_and_parent = clk_rcg2_gfx3d_set

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

2018-06-06 Thread Amit Nischal
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 
---
 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 
 #include 
 #include 
 #include 
@@ -208,11 +210,41 @@ static inline void gdsc_assert_reset_aon(struct gdsc *sc)
regmap_update_bits(sc->regmap, sc->clamp_io_ctrl,
   GMEM_RESET_MASK, 0);
 }
+
+static int gdsc_clk_prepare_enable(struct gdsc *sc)
+{
+   int i, ret;
+
+   for (i = 0; i < sc->clk_count; i++) {
+   ret = clk_prepare_enable(sc->clk_hws[i]->clk);
+   if (ret) {
+   for (i--; i >= 0; i--)
+   clk_disable_unprepare(sc->clk_hws[i]->clk);
+   return ret;
+   }
+   }
+   return 0;
+}
+
+static void gdsc_clk_disable_unprepare(struct gdsc *sc)
+{
+   int i;
+
+   for (i = 0; i < sc->clk_count; i++)
+   clk_disable_unprepare(sc->clk_hws[i]->clk);
+}
+
 static int gdsc_enable(struct generic_pm_domain *domain)
 {
struct gdsc *sc = domain_to_gdsc(domain);
int ret;

+   if (sc->clk_count) {
+   ret = gdsc_clk_prepare_enable(sc);
+   if (ret)
+   return ret;
+   }
+
if (sc->pwrsts == PWRSTS_ON)
return gdsc_deassert_reset(sc);

@@ -260,6 +292,9 @@ static int gdsc_enable(struct generic_pm_domain *domain)
udelay(1);
}

+   if (sc->clk_count)
+   gdsc_clk_disable_unprepare(sc);
+
return 0;
 }

@@ -268,6 +303,12 @@ static int gdsc_disable(struct generic_pm_domain *domain)
struct gdsc *sc = domain_to_gdsc(domain);
int ret;

+   if (sc->clk_count) {
+   ret = gdsc_clk_prepare_enable(sc);
+   if (ret)
+   return ret;
+   }
+
if (sc->pwrsts == PWRSTS_ON)
return gdsc_assert_reset(sc);

@@ -299,6 +340,9 @@ static int gdsc_disable(struct generic_pm_domain *domain)
if (sc->flags & CLAMP_IO)
gdsc_assert_clamp_io(sc);

+   if (sc->clk_count)
+   gdsc_clk_disable_unprepare(sc);
+
return 0;
 }

diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
index bd1f2c7..59957d7 100644
--- a/drivers/clk/qcom/gdsc.h
+++ b/drivers/clk/qcom/gdsc.h
@@ -17,6 +17,7 @@
 #include 
 #include 

+struct clk_hw;
 struct regmap;
 struct reset_controller_dev;

@@ -32,6 +33,8 @@
  * @resets: ids of resets associated with this gdsc
  * @reset_count: number of @resets
  * @rcdev: reset controller
+ * @clk_count: number of associated clocks
+ * @clk_hws: clk_hw pointers for associated clocks with gdsc
  */
 struct gdsc {
struct generic_pm_domainpd;
@@ -60,6 +63,8 @@ struct gdsc {
struct reset_controller_dev *rcdev;
unsigned int*resets;
unsigned intreset_count;
+   unsigned intclk_count;
+   struct clk_hw   *clk_hws[];
 };

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



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

2018-06-06 Thread Amit Nischal
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 
---
 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 
 #include 
 #include 
 #include 
@@ -208,11 +210,41 @@ static inline void gdsc_assert_reset_aon(struct gdsc *sc)
regmap_update_bits(sc->regmap, sc->clamp_io_ctrl,
   GMEM_RESET_MASK, 0);
 }
+
+static int gdsc_clk_prepare_enable(struct gdsc *sc)
+{
+   int i, ret;
+
+   for (i = 0; i < sc->clk_count; i++) {
+   ret = clk_prepare_enable(sc->clk_hws[i]->clk);
+   if (ret) {
+   for (i--; i >= 0; i--)
+   clk_disable_unprepare(sc->clk_hws[i]->clk);
+   return ret;
+   }
+   }
+   return 0;
+}
+
+static void gdsc_clk_disable_unprepare(struct gdsc *sc)
+{
+   int i;
+
+   for (i = 0; i < sc->clk_count; i++)
+   clk_disable_unprepare(sc->clk_hws[i]->clk);
+}
+
 static int gdsc_enable(struct generic_pm_domain *domain)
 {
struct gdsc *sc = domain_to_gdsc(domain);
int ret;

+   if (sc->clk_count) {
+   ret = gdsc_clk_prepare_enable(sc);
+   if (ret)
+   return ret;
+   }
+
if (sc->pwrsts == PWRSTS_ON)
return gdsc_deassert_reset(sc);

@@ -260,6 +292,9 @@ static int gdsc_enable(struct generic_pm_domain *domain)
udelay(1);
}

+   if (sc->clk_count)
+   gdsc_clk_disable_unprepare(sc);
+
return 0;
 }

@@ -268,6 +303,12 @@ static int gdsc_disable(struct generic_pm_domain *domain)
struct gdsc *sc = domain_to_gdsc(domain);
int ret;

+   if (sc->clk_count) {
+   ret = gdsc_clk_prepare_enable(sc);
+   if (ret)
+   return ret;
+   }
+
if (sc->pwrsts == PWRSTS_ON)
return gdsc_assert_reset(sc);

@@ -299,6 +340,9 @@ static int gdsc_disable(struct generic_pm_domain *domain)
if (sc->flags & CLAMP_IO)
gdsc_assert_clamp_io(sc);

+   if (sc->clk_count)
+   gdsc_clk_disable_unprepare(sc);
+
return 0;
 }

diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
index bd1f2c7..59957d7 100644
--- a/drivers/clk/qcom/gdsc.h
+++ b/drivers/clk/qcom/gdsc.h
@@ -17,6 +17,7 @@
 #include 
 #include 

+struct clk_hw;
 struct regmap;
 struct reset_controller_dev;

@@ -32,6 +33,8 @@
  * @resets: ids of resets associated with this gdsc
  * @reset_count: number of @resets
  * @rcdev: reset controller
+ * @clk_count: number of associated clocks
+ * @clk_hws: clk_hw pointers for associated clocks with gdsc
  */
 struct gdsc {
struct generic_pm_domainpd;
@@ -60,6 +63,8 @@ struct gdsc {
struct reset_controller_dev *rcdev;
unsigned int*resets;
unsigned intreset_count;
+   unsigned intclk_count;
+   struct clk_hw   *clk_hws[];
 };

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



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

2018-06-06 Thread Amit Nischal
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() and set_rate() 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.

Amit Nischal (4):
  clk: qcom: gdsc: Add support to enable/disable the clocks with GDSC
  clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845
  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/clk-rcg.h |   1 +
 drivers/clk/qcom/clk-rcg2.c|  78 +++-
 drivers/clk/qcom/gdsc.c|  44 ++
 drivers/clk/qcom/gdsc.h|   5 +
 drivers/clk/qcom/gpucc-sdm845.c| 441 +
 include/dt-bindings/clock/qcom,gpucc-sdm845.h  |  38 ++
 9 files changed, 614 insertions(+), 21 deletions(-)
 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 Code Aurora Forum, hosted by The Linux Foundation



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

2018-06-06 Thread 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 
---
 drivers/clk/qcom/Kconfig|   9 +
 drivers/clk/qcom/Makefile   |   1 +
 drivers/clk/qcom/gpucc-sdm845.c | 441 
 3 files changed, 451 insertions(+)
 create mode 100644 drivers/clk/qcom/gpucc-sdm845.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 9c3480d..193c2f5 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -235,6 +235,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 32d17c2..8aa2bc9 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -40,5 +40,6 @@ 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_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
diff --git a/drivers/clk/qcom/gpucc-sdm845.c b/drivers/clk/qcom/gpucc-sdm845.c
new file mode 100644
index 000..81f8926
--- /dev/null
+++ b/drivers/clk/qcom/gpucc-sdm845.c
@@ -0,0 +1,441 @@
+// 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)
+
+#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
+
+enum {
+   P_BI_TCXO,
+   P_CORE_BI_PLL_TEST_SE,
+   P_GPLL0_OUT_MAIN,
+   P_GPLL0_OUT_MAIN_DIV,
+   P_GPU_CC_PLL0_OUT_EVEN,
+   P_GPU_CC_PLL0_OUT_MAIN,
+   P_GPU_CC_PLL0_OUT_ODD,
+   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_PLL0_OUT_MAIN, 1 },
+   { 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_pll0",
+   "gpu_cc_pll1",
+   "gcc_gpu_gpll0_clk_src",
+   "gcc_gpu_gpll0_div_clk_src",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map gpu_cc_parent_map_1[] = {
+   { P_BI_TCXO, 0 },
+   { P_GPU_CC_PLL0_OUT_EVEN, 1 },
+   { P_GPU_CC_PLL0_OUT_ODD, 2 },
+   { P_GPU_CC_PLL1_OUT_EVEN, 3 },
+   { P_GPU_CC_PLL1_OUT_ODD, 4 },
+   { P_GPLL0_OUT_MAIN, 5 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gpu_cc_parent_names_1[] = {
+   "bi_tcxo",
+   "gpu_cc_pll0_out_even",
+   "gpu_cc_pll0_out_odd",
+   "gpu_cc_pll1_out_even",
+   "gpu_cc_pll1_out_odd",
+   "gcc_gpu_gpll0_clk_src",
+   "core_bi_pll_test_se",
+};
+
+static const struct alpha_pll_config gpu_cc_pll0_config = {
+   .l = 0x1d,
+   .alpha = 0x2aaa,
+};
+
+static const struct alpha_pll_config gpu_cc_pll1_config = {
+   .l = 0x1a,
+   .alpha = 0xaab,
+};
+
+static struct clk_alpha_pll gpu_cc_pll0 = {
+   .offset = 0x0,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "gpu_cc_pll0",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static const struct clk_div_table post_div_table_fabia_

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

2018-06-06 Thread Amit Nischal
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() and set_rate() 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.

Amit Nischal (4):
  clk: qcom: gdsc: Add support to enable/disable the clocks with GDSC
  clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845
  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/clk-rcg.h |   1 +
 drivers/clk/qcom/clk-rcg2.c|  78 +++-
 drivers/clk/qcom/gdsc.c|  44 ++
 drivers/clk/qcom/gdsc.h|   5 +
 drivers/clk/qcom/gpucc-sdm845.c| 441 +
 include/dt-bindings/clock/qcom,gpucc-sdm845.h  |  38 ++
 9 files changed, 614 insertions(+), 21 deletions(-)
 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 Code Aurora Forum, hosted by The Linux Foundation



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

2018-06-06 Thread 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 
---
 drivers/clk/qcom/Kconfig|   9 +
 drivers/clk/qcom/Makefile   |   1 +
 drivers/clk/qcom/gpucc-sdm845.c | 441 
 3 files changed, 451 insertions(+)
 create mode 100644 drivers/clk/qcom/gpucc-sdm845.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 9c3480d..193c2f5 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -235,6 +235,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 32d17c2..8aa2bc9 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -40,5 +40,6 @@ 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_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
diff --git a/drivers/clk/qcom/gpucc-sdm845.c b/drivers/clk/qcom/gpucc-sdm845.c
new file mode 100644
index 000..81f8926
--- /dev/null
+++ b/drivers/clk/qcom/gpucc-sdm845.c
@@ -0,0 +1,441 @@
+// 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)
+
+#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
+
+enum {
+   P_BI_TCXO,
+   P_CORE_BI_PLL_TEST_SE,
+   P_GPLL0_OUT_MAIN,
+   P_GPLL0_OUT_MAIN_DIV,
+   P_GPU_CC_PLL0_OUT_EVEN,
+   P_GPU_CC_PLL0_OUT_MAIN,
+   P_GPU_CC_PLL0_OUT_ODD,
+   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_PLL0_OUT_MAIN, 1 },
+   { 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_pll0",
+   "gpu_cc_pll1",
+   "gcc_gpu_gpll0_clk_src",
+   "gcc_gpu_gpll0_div_clk_src",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map gpu_cc_parent_map_1[] = {
+   { P_BI_TCXO, 0 },
+   { P_GPU_CC_PLL0_OUT_EVEN, 1 },
+   { P_GPU_CC_PLL0_OUT_ODD, 2 },
+   { P_GPU_CC_PLL1_OUT_EVEN, 3 },
+   { P_GPU_CC_PLL1_OUT_ODD, 4 },
+   { P_GPLL0_OUT_MAIN, 5 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gpu_cc_parent_names_1[] = {
+   "bi_tcxo",
+   "gpu_cc_pll0_out_even",
+   "gpu_cc_pll0_out_odd",
+   "gpu_cc_pll1_out_even",
+   "gpu_cc_pll1_out_odd",
+   "gcc_gpu_gpll0_clk_src",
+   "core_bi_pll_test_se",
+};
+
+static const struct alpha_pll_config gpu_cc_pll0_config = {
+   .l = 0x1d,
+   .alpha = 0x2aaa,
+};
+
+static const struct alpha_pll_config gpu_cc_pll1_config = {
+   .l = 0x1a,
+   .alpha = 0xaab,
+};
+
+static struct clk_alpha_pll gpu_cc_pll0 = {
+   .offset = 0x0,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "gpu_cc_pll0",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static const struct clk_div_table post_div_table_fabia_

[PATCH 3/4] dt-bindings: clock: Introduce QCOM Graphics clock bindings

2018-06-06 Thread Amit Nischal
Add device tree bindings for graphics clock controller for
Qualcomm Technology Inc's SoCs.

Signed-off-by: Amit Nischal 
---
 .../devicetree/bindings/clock/qcom,gpucc.txt   | 18 ++
 include/dt-bindings/clock/qcom,gpucc-sdm845.h  | 38 ++
 2 files changed, 56 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..e311219
--- /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..b9cbce5
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,gpucc-sdm845.h
@@ -0,0 +1,38 @@
+/* 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_CRC_AHB_CLK 0
+#define GPU_CC_CX_APB_CLK  1
+#define GPU_CC_CX_GFX3D_CLK2
+#define GPU_CC_CX_GFX3D_SLV_CLK3
+#define GPU_CC_CX_GMU_CLK  4
+#define GPU_CC_CX_SNOC_DVM_CLK 5
+#define GPU_CC_CXO_CLK 6
+#define GPU_CC_GMU_CLK_SRC 7
+#define GPU_CC_GX_GMU_CLK  8
+#define GPU_CC_GX_GFX3D_CLK_SRC9
+#define GPU_CC_GX_GFX3D_CLK10
+#define GPU_CC_PLL011
+#define GPU_CC_PLL0_OUT_EVEN   12
+#define GPU_CC_PLL112
+
+/* GPU_CC Resets */
+#define GPUCC_GPU_CC_ACD_BCR   0
+#define GPUCC_GPU_CC_CX_BCR1
+#define GPUCC_GPU_CC_GFX3D_AON_BCR 2
+#define GPUCC_GPU_CC_GMU_BCR   3
+#define GPUCC_GPU_CC_GX_BCR4
+#define GPUCC_GPU_CC_SPDM_BCR  5
+#define GPUCC_GPU_CC_XO_BCR6
+
+/* 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 Code Aurora Forum, hosted by The Linux Foundation



[PATCH 3/4] dt-bindings: clock: Introduce QCOM Graphics clock bindings

2018-06-06 Thread Amit Nischal
Add device tree bindings for graphics clock controller for
Qualcomm Technology Inc's SoCs.

Signed-off-by: Amit Nischal 
---
 .../devicetree/bindings/clock/qcom,gpucc.txt   | 18 ++
 include/dt-bindings/clock/qcom,gpucc-sdm845.h  | 38 ++
 2 files changed, 56 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..e311219
--- /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..b9cbce5
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,gpucc-sdm845.h
@@ -0,0 +1,38 @@
+/* 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_CRC_AHB_CLK 0
+#define GPU_CC_CX_APB_CLK  1
+#define GPU_CC_CX_GFX3D_CLK2
+#define GPU_CC_CX_GFX3D_SLV_CLK3
+#define GPU_CC_CX_GMU_CLK  4
+#define GPU_CC_CX_SNOC_DVM_CLK 5
+#define GPU_CC_CXO_CLK 6
+#define GPU_CC_GMU_CLK_SRC 7
+#define GPU_CC_GX_GMU_CLK  8
+#define GPU_CC_GX_GFX3D_CLK_SRC9
+#define GPU_CC_GX_GFX3D_CLK10
+#define GPU_CC_PLL011
+#define GPU_CC_PLL0_OUT_EVEN   12
+#define GPU_CC_PLL112
+
+/* GPU_CC Resets */
+#define GPUCC_GPU_CC_ACD_BCR   0
+#define GPUCC_GPU_CC_CX_BCR1
+#define GPUCC_GPU_CC_GFX3D_AON_BCR 2
+#define GPUCC_GPU_CC_GMU_BCR   3
+#define GPUCC_GPU_CC_GX_BCR4
+#define GPUCC_GPU_CC_SPDM_BCR  5
+#define GPUCC_GPU_CC_XO_BCR6
+
+/* 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 Code Aurora Forum, hosted by The Linux Foundation



[PATCH v2] clk: qcom: Enable clocks which needs to be always on for SDM845

2018-05-29 Thread Amit Nischal
There are certain clocks which needs to be always enabled for system
operation. Remove support for such clocks from the clock driver and
enable them explicitly gcc driver probe. Also fix the target name in
kernel configuration description for SDM845 gcc driver.

Signed-off-by: Amit Nischal 
---

Changes in v2:
* Fix target name in kernel configuration help text for SDM845 GCC
  clock driver.

[v1]: https://lkml.org/lkml/2018/5/28/171

 drivers/clk/qcom/Kconfig|   2 +-
 drivers/clk/qcom/gcc-sdm845.c   | 119 +-
 include/dt-bindings/clock/qcom,gcc-sdm845.h | 351 ++--
 3 files changed, 183 insertions(+), 289 deletions(-)

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index fc3edd1..79e9144 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -231,7 +231,7 @@ config SDM_GCC_845
select QCOM_GDSC
depends on COMMON_CLK_QCOM
help
- Support for the global clock controller on msm8998 devices.
+ Support for the global clock controller on SDM845 devices.
  Say Y if you want to use peripheral devices such as UART, SPI,
  I2C, USB, UFS, SDDC, PCIe, etc.

diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index e78e6f5..b40aafc 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -1093,21 +1093,6 @@ enum {
},
 };

-static struct clk_branch gcc_camera_ahb_clk = {
-   .halt_reg = 0xb008,
-   .halt_check = BRANCH_HALT,
-   .hwcg_reg = 0xb008,
-   .hwcg_bit = 1,
-   .clkr = {
-   .enable_reg = 0xb008,
-   .enable_mask = BIT(0),
-   .hw.init = &(struct clk_init_data){
-   .name = "gcc_camera_ahb_clk",
-   .ops = _branch2_ops,
-   },
-   },
-};
-
 static struct clk_branch gcc_camera_axi_clk = {
.halt_reg = 0xb020,
.halt_check = BRANCH_VOTED,
@@ -1121,19 +1106,6 @@ enum {
},
 };

-static struct clk_branch gcc_camera_xo_clk = {
-   .halt_reg = 0xb02c,
-   .halt_check = BRANCH_HALT,
-   .clkr = {
-   .enable_reg = 0xb02c,
-   .enable_mask = BIT(0),
-   .hw.init = &(struct clk_init_data){
-   .name = "gcc_camera_xo_clk",
-   .ops = _branch2_ops,
-   },
-   },
-};
-
 static struct clk_branch gcc_ce1_ahb_clk = {
.halt_reg = 0x4100c,
.halt_check = BRANCH_HALT_VOTED,
@@ -1260,21 +1232,6 @@ enum {
},
 };

-static struct clk_branch gcc_disp_ahb_clk = {
-   .halt_reg = 0xb00c,
-   .halt_check = BRANCH_HALT,
-   .hwcg_reg = 0xb00c,
-   .hwcg_bit = 1,
-   .clkr = {
-   .enable_reg = 0xb00c,
-   .enable_mask = BIT(0),
-   .hw.init = &(struct clk_init_data){
-   .name = "gcc_disp_ahb_clk",
-   .ops = _branch2_ops,
-   },
-   },
-};
-
 static struct clk_branch gcc_disp_axi_clk = {
.halt_reg = 0xb024,
.halt_check = BRANCH_VOTED,
@@ -1320,19 +1277,6 @@ enum {
},
 };

-static struct clk_branch gcc_disp_xo_clk = {
-   .halt_reg = 0xb030,
-   .halt_check = BRANCH_HALT,
-   .clkr = {
-   .enable_reg = 0xb030,
-   .enable_mask = BIT(0),
-   .hw.init = &(struct clk_init_data){
-   .name = "gcc_disp_xo_clk",
-   .ops = _branch2_ops,
-   },
-   },
-};
-
 static struct clk_branch gcc_gp1_clk = {
.halt_reg = 0x64000,
.halt_check = BRANCH_HALT,
@@ -1387,21 +1331,6 @@ enum {
},
 };

-static struct clk_branch gcc_gpu_cfg_ahb_clk = {
-   .halt_reg = 0x71004,
-   .halt_check = BRANCH_HALT,
-   .hwcg_reg = 0x71004,
-   .hwcg_bit = 1,
-   .clkr = {
-   .enable_reg = 0x71004,
-   .enable_mask = BIT(0),
-   .hw.init = &(struct clk_init_data){
-   .name = "gcc_gpu_cfg_ahb_clk",
-   .ops = _branch2_ops,
-   },
-   },
-};
-
 static struct clk_branch gcc_gpu_gpll0_clk_src = {
.halt_check = BRANCH_HALT_DELAY,
.clkr = {
@@ -2975,21 +2904,6 @@ enum {
},
 };

-static struct clk_branch gcc_video_ahb_clk = {
-   .halt_reg = 0xb004,
-   .halt_check = BRANCH_HALT,
-   .hwcg_reg = 0xb004,
-   .hwcg_bit = 1,
-   .clkr = {
-   .enable_reg = 0xb004,
-   .enable_mask = BIT(0),
-   .hw.init = &(struct clk_init_data){
-   .name = "gcc_video_ahb_clk",
-   .ops = _branch2_ops,
-   },
-   },
-};
-
 static struct clk_branch gcc_video_axi_clk = {
.halt_reg = 0xb01c,
.halt_check = BRANCH_VOTED,
@@ -

[PATCH v2] clk: qcom: Enable clocks which needs to be always on for SDM845

2018-05-29 Thread Amit Nischal
There are certain clocks which needs to be always enabled for system
operation. Remove support for such clocks from the clock driver and
enable them explicitly gcc driver probe. Also fix the target name in
kernel configuration description for SDM845 gcc driver.

Signed-off-by: Amit Nischal 
---

Changes in v2:
* Fix target name in kernel configuration help text for SDM845 GCC
  clock driver.

[v1]: https://lkml.org/lkml/2018/5/28/171

 drivers/clk/qcom/Kconfig|   2 +-
 drivers/clk/qcom/gcc-sdm845.c   | 119 +-
 include/dt-bindings/clock/qcom,gcc-sdm845.h | 351 ++--
 3 files changed, 183 insertions(+), 289 deletions(-)

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index fc3edd1..79e9144 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -231,7 +231,7 @@ config SDM_GCC_845
select QCOM_GDSC
depends on COMMON_CLK_QCOM
help
- Support for the global clock controller on msm8998 devices.
+ Support for the global clock controller on SDM845 devices.
  Say Y if you want to use peripheral devices such as UART, SPI,
  I2C, USB, UFS, SDDC, PCIe, etc.

diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index e78e6f5..b40aafc 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -1093,21 +1093,6 @@ enum {
},
 };

-static struct clk_branch gcc_camera_ahb_clk = {
-   .halt_reg = 0xb008,
-   .halt_check = BRANCH_HALT,
-   .hwcg_reg = 0xb008,
-   .hwcg_bit = 1,
-   .clkr = {
-   .enable_reg = 0xb008,
-   .enable_mask = BIT(0),
-   .hw.init = &(struct clk_init_data){
-   .name = "gcc_camera_ahb_clk",
-   .ops = _branch2_ops,
-   },
-   },
-};
-
 static struct clk_branch gcc_camera_axi_clk = {
.halt_reg = 0xb020,
.halt_check = BRANCH_VOTED,
@@ -1121,19 +1106,6 @@ enum {
},
 };

-static struct clk_branch gcc_camera_xo_clk = {
-   .halt_reg = 0xb02c,
-   .halt_check = BRANCH_HALT,
-   .clkr = {
-   .enable_reg = 0xb02c,
-   .enable_mask = BIT(0),
-   .hw.init = &(struct clk_init_data){
-   .name = "gcc_camera_xo_clk",
-   .ops = _branch2_ops,
-   },
-   },
-};
-
 static struct clk_branch gcc_ce1_ahb_clk = {
.halt_reg = 0x4100c,
.halt_check = BRANCH_HALT_VOTED,
@@ -1260,21 +1232,6 @@ enum {
},
 };

-static struct clk_branch gcc_disp_ahb_clk = {
-   .halt_reg = 0xb00c,
-   .halt_check = BRANCH_HALT,
-   .hwcg_reg = 0xb00c,
-   .hwcg_bit = 1,
-   .clkr = {
-   .enable_reg = 0xb00c,
-   .enable_mask = BIT(0),
-   .hw.init = &(struct clk_init_data){
-   .name = "gcc_disp_ahb_clk",
-   .ops = _branch2_ops,
-   },
-   },
-};
-
 static struct clk_branch gcc_disp_axi_clk = {
.halt_reg = 0xb024,
.halt_check = BRANCH_VOTED,
@@ -1320,19 +1277,6 @@ enum {
},
 };

-static struct clk_branch gcc_disp_xo_clk = {
-   .halt_reg = 0xb030,
-   .halt_check = BRANCH_HALT,
-   .clkr = {
-   .enable_reg = 0xb030,
-   .enable_mask = BIT(0),
-   .hw.init = &(struct clk_init_data){
-   .name = "gcc_disp_xo_clk",
-   .ops = _branch2_ops,
-   },
-   },
-};
-
 static struct clk_branch gcc_gp1_clk = {
.halt_reg = 0x64000,
.halt_check = BRANCH_HALT,
@@ -1387,21 +1331,6 @@ enum {
},
 };

-static struct clk_branch gcc_gpu_cfg_ahb_clk = {
-   .halt_reg = 0x71004,
-   .halt_check = BRANCH_HALT,
-   .hwcg_reg = 0x71004,
-   .hwcg_bit = 1,
-   .clkr = {
-   .enable_reg = 0x71004,
-   .enable_mask = BIT(0),
-   .hw.init = &(struct clk_init_data){
-   .name = "gcc_gpu_cfg_ahb_clk",
-   .ops = _branch2_ops,
-   },
-   },
-};
-
 static struct clk_branch gcc_gpu_gpll0_clk_src = {
.halt_check = BRANCH_HALT_DELAY,
.clkr = {
@@ -2975,21 +2904,6 @@ enum {
},
 };

-static struct clk_branch gcc_video_ahb_clk = {
-   .halt_reg = 0xb004,
-   .halt_check = BRANCH_HALT,
-   .hwcg_reg = 0xb004,
-   .hwcg_bit = 1,
-   .clkr = {
-   .enable_reg = 0xb004,
-   .enable_mask = BIT(0),
-   .hw.init = &(struct clk_init_data){
-   .name = "gcc_video_ahb_clk",
-   .ops = _branch2_ops,
-   },
-   },
-};
-
 static struct clk_branch gcc_video_axi_clk = {
.halt_reg = 0xb01c,
.halt_check = BRANCH_VOTED,
@@ -

[PATCH] clk: qcom: Enable clocks which needs to be always on for SDM845

2018-05-28 Thread Amit Nischal
There are certain clocks which needs to be always enabled for
system operation. Remove support for such clocks from the clock
driver and enable them explicitly gcc driver probe.

Signed-off-by: Amit Nischal <anisc...@codeaurora.org>
---
 drivers/clk/qcom/gcc-sdm845.c   | 119 +-
 include/dt-bindings/clock/qcom,gcc-sdm845.h | 351 ++--
 2 files changed, 182 insertions(+), 288 deletions(-)

diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index e78e6f5..b40aafc 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -1093,21 +1093,6 @@ enum {
},
 };

-static struct clk_branch gcc_camera_ahb_clk = {
-   .halt_reg = 0xb008,
-   .halt_check = BRANCH_HALT,
-   .hwcg_reg = 0xb008,
-   .hwcg_bit = 1,
-   .clkr = {
-   .enable_reg = 0xb008,
-   .enable_mask = BIT(0),
-   .hw.init = &(struct clk_init_data){
-   .name = "gcc_camera_ahb_clk",
-   .ops = _branch2_ops,
-   },
-   },
-};
-
 static struct clk_branch gcc_camera_axi_clk = {
.halt_reg = 0xb020,
.halt_check = BRANCH_VOTED,
@@ -1121,19 +1106,6 @@ enum {
},
 };

-static struct clk_branch gcc_camera_xo_clk = {
-   .halt_reg = 0xb02c,
-   .halt_check = BRANCH_HALT,
-   .clkr = {
-   .enable_reg = 0xb02c,
-   .enable_mask = BIT(0),
-   .hw.init = &(struct clk_init_data){
-   .name = "gcc_camera_xo_clk",
-   .ops = _branch2_ops,
-   },
-   },
-};
-
 static struct clk_branch gcc_ce1_ahb_clk = {
.halt_reg = 0x4100c,
.halt_check = BRANCH_HALT_VOTED,
@@ -1260,21 +1232,6 @@ enum {
},
 };

-static struct clk_branch gcc_disp_ahb_clk = {
-   .halt_reg = 0xb00c,
-   .halt_check = BRANCH_HALT,
-   .hwcg_reg = 0xb00c,
-   .hwcg_bit = 1,
-   .clkr = {
-   .enable_reg = 0xb00c,
-   .enable_mask = BIT(0),
-   .hw.init = &(struct clk_init_data){
-   .name = "gcc_disp_ahb_clk",
-   .ops = _branch2_ops,
-   },
-   },
-};
-
 static struct clk_branch gcc_disp_axi_clk = {
.halt_reg = 0xb024,
.halt_check = BRANCH_VOTED,
@@ -1320,19 +1277,6 @@ enum {
},
 };

-static struct clk_branch gcc_disp_xo_clk = {
-   .halt_reg = 0xb030,
-   .halt_check = BRANCH_HALT,
-   .clkr = {
-   .enable_reg = 0xb030,
-   .enable_mask = BIT(0),
-   .hw.init = &(struct clk_init_data){
-   .name = "gcc_disp_xo_clk",
-   .ops = _branch2_ops,
-   },
-   },
-};
-
 static struct clk_branch gcc_gp1_clk = {
.halt_reg = 0x64000,
.halt_check = BRANCH_HALT,
@@ -1387,21 +1331,6 @@ enum {
},
 };

-static struct clk_branch gcc_gpu_cfg_ahb_clk = {
-   .halt_reg = 0x71004,
-   .halt_check = BRANCH_HALT,
-   .hwcg_reg = 0x71004,
-   .hwcg_bit = 1,
-   .clkr = {
-   .enable_reg = 0x71004,
-   .enable_mask = BIT(0),
-   .hw.init = &(struct clk_init_data){
-   .name = "gcc_gpu_cfg_ahb_clk",
-   .ops = _branch2_ops,
-   },
-   },
-};
-
 static struct clk_branch gcc_gpu_gpll0_clk_src = {
.halt_check = BRANCH_HALT_DELAY,
.clkr = {
@@ -2975,21 +2904,6 @@ enum {
},
 };

-static struct clk_branch gcc_video_ahb_clk = {
-   .halt_reg = 0xb004,
-   .halt_check = BRANCH_HALT,
-   .hwcg_reg = 0xb004,
-   .hwcg_bit = 1,
-   .clkr = {
-   .enable_reg = 0xb004,
-   .enable_mask = BIT(0),
-   .hw.init = &(struct clk_init_data){
-   .name = "gcc_video_ahb_clk",
-   .ops = _branch2_ops,
-   },
-   },
-};
-
 static struct clk_branch gcc_video_axi_clk = {
.halt_reg = 0xb01c,
.halt_check = BRANCH_VOTED,
@@ -3003,19 +2917,6 @@ enum {
},
 };

-static struct clk_branch gcc_video_xo_clk = {
-   .halt_reg = 0xb028,
-   .halt_check = BRANCH_HALT,
-   .clkr = {
-   .enable_reg = 0xb028,
-   .enable_mask = BIT(0),
-   .hw.init = &(struct clk_init_data){
-   .name = "gcc_video_xo_clk",
-   .ops = _branch2_ops,
-   },
-   },
-};
-
 static struct clk_branch gcc_vs_ctrl_ahb_clk = {
.halt_reg = 0x7a014,
.halt_check = BRANCH_HALT,
@@ -3167,9 +3068,7 @@ enum {
[GCC_AGGRE_USB3_SEC_AXI_CLK] = _aggre_usb3_sec_axi_clk.clkr,
[GCC_APC_VS_CLK] = _apc_vs_clk.clkr,
[GCC_BOOT_ROM_AHB_CLK] = _boot_rom_ahb_clk.clkr,
-   [GCC_CAMERA_AHB_CLK]

[PATCH] clk: qcom: Enable clocks which needs to be always on for SDM845

2018-05-28 Thread Amit Nischal
There are certain clocks which needs to be always enabled for
system operation. Remove support for such clocks from the clock
driver and enable them explicitly gcc driver probe.

Signed-off-by: Amit Nischal 
---
 drivers/clk/qcom/gcc-sdm845.c   | 119 +-
 include/dt-bindings/clock/qcom,gcc-sdm845.h | 351 ++--
 2 files changed, 182 insertions(+), 288 deletions(-)

diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index e78e6f5..b40aafc 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -1093,21 +1093,6 @@ enum {
},
 };

-static struct clk_branch gcc_camera_ahb_clk = {
-   .halt_reg = 0xb008,
-   .halt_check = BRANCH_HALT,
-   .hwcg_reg = 0xb008,
-   .hwcg_bit = 1,
-   .clkr = {
-   .enable_reg = 0xb008,
-   .enable_mask = BIT(0),
-   .hw.init = &(struct clk_init_data){
-   .name = "gcc_camera_ahb_clk",
-   .ops = _branch2_ops,
-   },
-   },
-};
-
 static struct clk_branch gcc_camera_axi_clk = {
.halt_reg = 0xb020,
.halt_check = BRANCH_VOTED,
@@ -1121,19 +1106,6 @@ enum {
},
 };

-static struct clk_branch gcc_camera_xo_clk = {
-   .halt_reg = 0xb02c,
-   .halt_check = BRANCH_HALT,
-   .clkr = {
-   .enable_reg = 0xb02c,
-   .enable_mask = BIT(0),
-   .hw.init = &(struct clk_init_data){
-   .name = "gcc_camera_xo_clk",
-   .ops = _branch2_ops,
-   },
-   },
-};
-
 static struct clk_branch gcc_ce1_ahb_clk = {
.halt_reg = 0x4100c,
.halt_check = BRANCH_HALT_VOTED,
@@ -1260,21 +1232,6 @@ enum {
},
 };

-static struct clk_branch gcc_disp_ahb_clk = {
-   .halt_reg = 0xb00c,
-   .halt_check = BRANCH_HALT,
-   .hwcg_reg = 0xb00c,
-   .hwcg_bit = 1,
-   .clkr = {
-   .enable_reg = 0xb00c,
-   .enable_mask = BIT(0),
-   .hw.init = &(struct clk_init_data){
-   .name = "gcc_disp_ahb_clk",
-   .ops = _branch2_ops,
-   },
-   },
-};
-
 static struct clk_branch gcc_disp_axi_clk = {
.halt_reg = 0xb024,
.halt_check = BRANCH_VOTED,
@@ -1320,19 +1277,6 @@ enum {
},
 };

-static struct clk_branch gcc_disp_xo_clk = {
-   .halt_reg = 0xb030,
-   .halt_check = BRANCH_HALT,
-   .clkr = {
-   .enable_reg = 0xb030,
-   .enable_mask = BIT(0),
-   .hw.init = &(struct clk_init_data){
-   .name = "gcc_disp_xo_clk",
-   .ops = _branch2_ops,
-   },
-   },
-};
-
 static struct clk_branch gcc_gp1_clk = {
.halt_reg = 0x64000,
.halt_check = BRANCH_HALT,
@@ -1387,21 +1331,6 @@ enum {
},
 };

-static struct clk_branch gcc_gpu_cfg_ahb_clk = {
-   .halt_reg = 0x71004,
-   .halt_check = BRANCH_HALT,
-   .hwcg_reg = 0x71004,
-   .hwcg_bit = 1,
-   .clkr = {
-   .enable_reg = 0x71004,
-   .enable_mask = BIT(0),
-   .hw.init = &(struct clk_init_data){
-   .name = "gcc_gpu_cfg_ahb_clk",
-   .ops = _branch2_ops,
-   },
-   },
-};
-
 static struct clk_branch gcc_gpu_gpll0_clk_src = {
.halt_check = BRANCH_HALT_DELAY,
.clkr = {
@@ -2975,21 +2904,6 @@ enum {
},
 };

-static struct clk_branch gcc_video_ahb_clk = {
-   .halt_reg = 0xb004,
-   .halt_check = BRANCH_HALT,
-   .hwcg_reg = 0xb004,
-   .hwcg_bit = 1,
-   .clkr = {
-   .enable_reg = 0xb004,
-   .enable_mask = BIT(0),
-   .hw.init = &(struct clk_init_data){
-   .name = "gcc_video_ahb_clk",
-   .ops = _branch2_ops,
-   },
-   },
-};
-
 static struct clk_branch gcc_video_axi_clk = {
.halt_reg = 0xb01c,
.halt_check = BRANCH_VOTED,
@@ -3003,19 +2917,6 @@ enum {
},
 };

-static struct clk_branch gcc_video_xo_clk = {
-   .halt_reg = 0xb028,
-   .halt_check = BRANCH_HALT,
-   .clkr = {
-   .enable_reg = 0xb028,
-   .enable_mask = BIT(0),
-   .hw.init = &(struct clk_init_data){
-   .name = "gcc_video_xo_clk",
-   .ops = _branch2_ops,
-   },
-   },
-};
-
 static struct clk_branch gcc_vs_ctrl_ahb_clk = {
.halt_reg = 0x7a014,
.halt_check = BRANCH_HALT,
@@ -3167,9 +3068,7 @@ enum {
[GCC_AGGRE_USB3_SEC_AXI_CLK] = _aggre_usb3_sec_axi_clk.clkr,
[GCC_APC_VS_CLK] = _apc_vs_clk.clkr,
[GCC_BOOT_ROM_AHB_CLK] = _boot_rom_ahb_clk.clkr,
-   [GCC_CAMERA_AHB_CLK] = _camera_ahb_clk.clkr,

Re: [PATCH v1 0/2] Add QCOM video clock controller driver

2018-05-09 Thread Amit Nischal

On 2018-05-09 01:45, Stephen Boyd wrote:

Quoting Rob Herring (2018-05-08 05:48:07)
On Mon, May 7, 2018 at 11:53 PM, Amit Nischal 
<anisc...@codeaurora.org> wrote:

> On 2018-05-07 22:41, Rob Herring wrote:
>>
>> On Mon, May 07, 2018 at 04:16:53PM +0530, Amit Nischal wrote:
>>>
>>> On 2018-05-04 22:01, Stephen Boyd wrote:
>>> > Quoting Amit Nischal (2018-05-03 05:35:23)
>>> > > Changes in v1:
>>> > >https://lkml.org/lkml/2018/4/24/545
>>> > > Addressed below review comments given by Rob
>>> > > - Change the compatible property as per ',-'
>>> > > format.
>>> > > - Add header definitions for resets and power-domain cells.
>>> >
>>> > You didn't add any reset definitions though?
>>>
>>> We haven't added the reset definitions for videocc as there is no
>>> video reset client.
>>
>>
>> So? You don't know what resets there are?
>>
>
> We know the resets, but video driver doesn't do any block resets
> prior to accessing the video subsystem so that's the reason we do
> not want to expose the resets in videocc driver.

Bindings don't have to match what drivers currently use but should be
complete as possible.


Right. Please add the #defines in the header file for the resets. You
can leave them out of the driver if you really want to, but typically 
we

still add them and then rely on not touching them if they shouldn't be
used.


Thanks for the suggestion.
I will add the videocc resets in the header file.


Re: [PATCH v1 0/2] Add QCOM video clock controller driver

2018-05-09 Thread Amit Nischal

On 2018-05-09 01:45, Stephen Boyd wrote:

Quoting Rob Herring (2018-05-08 05:48:07)
On Mon, May 7, 2018 at 11:53 PM, Amit Nischal 
 wrote:

> On 2018-05-07 22:41, Rob Herring wrote:
>>
>> On Mon, May 07, 2018 at 04:16:53PM +0530, Amit Nischal wrote:
>>>
>>> On 2018-05-04 22:01, Stephen Boyd wrote:
>>> > Quoting Amit Nischal (2018-05-03 05:35:23)
>>> > > Changes in v1:
>>> > >https://lkml.org/lkml/2018/4/24/545
>>> > > Addressed below review comments given by Rob
>>> > > - Change the compatible property as per ',-'
>>> > > format.
>>> > > - Add header definitions for resets and power-domain cells.
>>> >
>>> > You didn't add any reset definitions though?
>>>
>>> We haven't added the reset definitions for videocc as there is no
>>> video reset client.
>>
>>
>> So? You don't know what resets there are?
>>
>
> We know the resets, but video driver doesn't do any block resets
> prior to accessing the video subsystem so that's the reason we do
> not want to expose the resets in videocc driver.

Bindings don't have to match what drivers currently use but should be
complete as possible.


Right. Please add the #defines in the header file for the resets. You
can leave them out of the driver if you really want to, but typically 
we

still add them and then rely on not touching them if they shouldn't be
used.


Thanks for the suggestion.
I will add the videocc resets in the header file.


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

2018-05-09 Thread Amit Nischal
Add support for the video clock controller found on SDM845
based devices. This would allow video drivers to probe and
control their clocks.

Signed-off-by: Amit Nischal <anisc...@codeaurora.org>
---
 drivers/clk/qcom/Kconfig  |  11 ++
 drivers/clk/qcom/Makefile |   1 +
 drivers/clk/qcom/videocc-sdm845.c | 358 ++
 3 files changed, 370 insertions(+)
 create mode 100644 drivers/clk/qcom/videocc-sdm845.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index aec69d2..81388ee 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -235,6 +235,17 @@ 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_VIDEOCC_845
+   tristate "SDM845 Video Clock Controller"
+   depends on COMMON_CLK_QCOM
+   select SDM_GCC_845
+   select QCOM_GDSC
+   help
+ Support for the video clock controller on Qualcomm Technologies, Inc
+ SDM845 devices.
+ Say Y if you want to support video devices and functionality such as
+ video encode and decode.
+
 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 bf8fb25..762c011 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -39,4 +39,5 @@ 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_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/videocc-sdm845.c 
b/drivers/clk/qcom/videocc-sdm845.c
new file mode 100644
index 000..9073b7a
--- /dev/null
+++ b/drivers/clk/qcom/videocc-sdm845.c
@@ -0,0 +1,358 @@
+// 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-rcg.h"
+#include "clk-regmap.h"
+#include "clk-pll.h"
+#include "gdsc.h"
+
+#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
+
+enum {
+   P_BI_TCXO,
+   P_CORE_BI_PLL_TEST_SE,
+   P_VIDEO_PLL0_OUT_EVEN,
+   P_VIDEO_PLL0_OUT_MAIN,
+   P_VIDEO_PLL0_OUT_ODD,
+};
+
+static const struct parent_map video_cc_parent_map_0[] = {
+   { P_BI_TCXO, 0 },
+   { P_VIDEO_PLL0_OUT_MAIN, 1 },
+   { P_VIDEO_PLL0_OUT_EVEN, 2 },
+   { P_VIDEO_PLL0_OUT_ODD, 3 },
+   { P_CORE_BI_PLL_TEST_SE, 4 },
+};
+
+static const char * const video_cc_parent_names_0[] = {
+   "bi_tcxo",
+   "video_pll0",
+   "video_pll0_out_even",
+   "video_pll0_out_odd",
+   "core_bi_pll_test_se",
+};
+
+static const struct alpha_pll_config video_pll0_config = {
+   .l = 0x10,
+   .alpha = 0xaaab,
+};
+
+static struct clk_alpha_pll video_pll0 = {
+   .offset = 0x42c,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "video_pll0",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static const struct freq_tbl ftbl_video_cc_venus_clk_src[] = {
+   F(1, P_VIDEO_PLL0_OUT_MAIN, 4, 0, 0),
+   F(2, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0),
+   F(33000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
+   F(40400, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
+   F(44400, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
+   F(53300, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
+   { }
+};
+
+static struct clk_rcg2 video_cc_venus_clk_src = {
+   .cmd_rcgr = 0x7f0,
+   .mnd_width = 0,
+   .hid_width = 5,
+   .parent_map = video_cc_parent_map_0,
+   .freq_tbl = ftbl_video_cc_venus_clk_src,
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "video_cc_venus_clk_src",
+   .parent_names = video_cc_parent_names_0,
+   .num_parents = 5,
+   .flags = CLK_SET_RATE_PARENT,
+   .ops = _rcg2_shared_ops,
+   },
+};
+
+static struct clk_branch video_cc_apb_clk = {
+   .halt_reg = 0x990,
+   .halt_check = BRANCH_HALT,
+   .clkr = {
+   .enable_reg = 0x990,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "video_cc_apb_clk",
+   .ops = _bran

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

2018-05-09 Thread Amit Nischal
Add support for the video clock controller found on SDM845
based devices. This would allow video drivers to probe and
control their clocks.

Signed-off-by: Amit Nischal 
---
 drivers/clk/qcom/Kconfig  |  11 ++
 drivers/clk/qcom/Makefile |   1 +
 drivers/clk/qcom/videocc-sdm845.c | 358 ++
 3 files changed, 370 insertions(+)
 create mode 100644 drivers/clk/qcom/videocc-sdm845.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index aec69d2..81388ee 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -235,6 +235,17 @@ 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_VIDEOCC_845
+   tristate "SDM845 Video Clock Controller"
+   depends on COMMON_CLK_QCOM
+   select SDM_GCC_845
+   select QCOM_GDSC
+   help
+ Support for the video clock controller on Qualcomm Technologies, Inc
+ SDM845 devices.
+ Say Y if you want to support video devices and functionality such as
+ video encode and decode.
+
 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 bf8fb25..762c011 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -39,4 +39,5 @@ 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_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/videocc-sdm845.c 
b/drivers/clk/qcom/videocc-sdm845.c
new file mode 100644
index 000..9073b7a
--- /dev/null
+++ b/drivers/clk/qcom/videocc-sdm845.c
@@ -0,0 +1,358 @@
+// 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-rcg.h"
+#include "clk-regmap.h"
+#include "clk-pll.h"
+#include "gdsc.h"
+
+#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
+
+enum {
+   P_BI_TCXO,
+   P_CORE_BI_PLL_TEST_SE,
+   P_VIDEO_PLL0_OUT_EVEN,
+   P_VIDEO_PLL0_OUT_MAIN,
+   P_VIDEO_PLL0_OUT_ODD,
+};
+
+static const struct parent_map video_cc_parent_map_0[] = {
+   { P_BI_TCXO, 0 },
+   { P_VIDEO_PLL0_OUT_MAIN, 1 },
+   { P_VIDEO_PLL0_OUT_EVEN, 2 },
+   { P_VIDEO_PLL0_OUT_ODD, 3 },
+   { P_CORE_BI_PLL_TEST_SE, 4 },
+};
+
+static const char * const video_cc_parent_names_0[] = {
+   "bi_tcxo",
+   "video_pll0",
+   "video_pll0_out_even",
+   "video_pll0_out_odd",
+   "core_bi_pll_test_se",
+};
+
+static const struct alpha_pll_config video_pll0_config = {
+   .l = 0x10,
+   .alpha = 0xaaab,
+};
+
+static struct clk_alpha_pll video_pll0 = {
+   .offset = 0x42c,
+   .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+   .clkr = {
+   .hw.init = &(struct clk_init_data){
+   .name = "video_pll0",
+   .parent_names = (const char *[]){ "bi_tcxo" },
+   .num_parents = 1,
+   .ops = _alpha_pll_fabia_ops,
+   },
+   },
+};
+
+static const struct freq_tbl ftbl_video_cc_venus_clk_src[] = {
+   F(1, P_VIDEO_PLL0_OUT_MAIN, 4, 0, 0),
+   F(2, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0),
+   F(33000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
+   F(40400, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
+   F(44400, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
+   F(53300, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
+   { }
+};
+
+static struct clk_rcg2 video_cc_venus_clk_src = {
+   .cmd_rcgr = 0x7f0,
+   .mnd_width = 0,
+   .hid_width = 5,
+   .parent_map = video_cc_parent_map_0,
+   .freq_tbl = ftbl_video_cc_venus_clk_src,
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "video_cc_venus_clk_src",
+   .parent_names = video_cc_parent_names_0,
+   .num_parents = 5,
+   .flags = CLK_SET_RATE_PARENT,
+   .ops = _rcg2_shared_ops,
+   },
+};
+
+static struct clk_branch video_cc_apb_clk = {
+   .halt_reg = 0x990,
+   .halt_check = BRANCH_HALT,
+   .clkr = {
+   .enable_reg = 0x990,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "video_cc_apb_clk",
+   .ops = _branch2_ops,
+   },
+   

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

2018-05-09 Thread Amit Nischal
Add device tree bindings for video clock controller for
Qualcomm Technology Inc's SoCs.

Signed-off-by: Amit Nischal <anisc...@codeaurora.org>
---
 .../devicetree/bindings/clock/qcom,videocc.txt | 19 
 include/dt-bindings/clock/qcom,videocc-sdm845.h| 35 ++
 2 files changed, 54 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,videocc.txt
 create mode 100644 include/dt-bindings/clock/qcom,videocc-sdm845.h

diff --git a/Documentation/devicetree/bindings/clock/qcom,videocc.txt 
b/Documentation/devicetree/bindings/clock/qcom,videocc.txt
new file mode 100644
index 000..e7c035a
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,videocc.txt
@@ -0,0 +1,19 @@
+Qualcomm Video Clock & Reset Controller Binding
+---
+
+Required properties :
+- compatible : shall contain "qcom,sdm845-videocc"
+- reg : shall contain base register location and length
+- #clock-cells : from common clock binding, shall contain 1.
+- #power-domain-cells : from generic power domain binding, shall contain 1.
+
+Optional properties :
+- #reset-cells : from common reset binding, shall contain 1.
+
+Example:
+   videocc: clock-controller@ab0 {
+   compatible = "qcom,sdm845-videocc";
+   reg = <0xab0 0x1>;
+   #clock-cells = <1>;
+   #power-domain-cells = <1>;
+   };
diff --git a/include/dt-bindings/clock/qcom,videocc-sdm845.h 
b/include/dt-bindings/clock/qcom,videocc-sdm845.h
new file mode 100644
index 000..1b86816
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,videocc-sdm845.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_SDM_VIDEO_CC_SDM845_H
+#define _DT_BINDINGS_CLK_SDM_VIDEO_CC_SDM845_H
+
+/* VIDEO_CC clock registers */
+#define VIDEO_CC_APB_CLK   0
+#define VIDEO_CC_AT_CLK1
+#define VIDEO_CC_QDSS_TRIG_CLK 2
+#define VIDEO_CC_QDSS_TSCTR_DIV8_CLK   3
+#define VIDEO_CC_VCODEC0_AXI_CLK   4
+#define VIDEO_CC_VCODEC0_CORE_CLK  5
+#define VIDEO_CC_VCODEC1_AXI_CLK   6
+#define VIDEO_CC_VCODEC1_CORE_CLK  7
+#define VIDEO_CC_VENUS_AHB_CLK 8
+#define VIDEO_CC_VENUS_CLK_SRC 9
+#define VIDEO_CC_VENUS_CTL_AXI_CLK 10
+#define VIDEO_CC_VENUS_CTL_CORE_CLK11
+#define VIDEO_PLL0 12
+
+/* VIDEO_CC Resets */
+#define VIDEO_CC_VENUS_BCR 0
+#define VIDEO_CC_VCODEC0_BCR   1
+#define VIDEO_CC_VCODEC1_BCR   2
+#define VIDEO_CC_INTERFACE_BCR 3
+
+/* VIDEO_CC GDSCRs */
+#define VENUS_GDSC 0
+#define VCODEC0_GDSC   1
+#define VCODEC1_GDSC   2
+
+#endif
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



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

2018-05-09 Thread Amit Nischal
Add device tree bindings for video clock controller for
Qualcomm Technology Inc's SoCs.

Signed-off-by: Amit Nischal 
---
 .../devicetree/bindings/clock/qcom,videocc.txt | 19 
 include/dt-bindings/clock/qcom,videocc-sdm845.h| 35 ++
 2 files changed, 54 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,videocc.txt
 create mode 100644 include/dt-bindings/clock/qcom,videocc-sdm845.h

diff --git a/Documentation/devicetree/bindings/clock/qcom,videocc.txt 
b/Documentation/devicetree/bindings/clock/qcom,videocc.txt
new file mode 100644
index 000..e7c035a
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,videocc.txt
@@ -0,0 +1,19 @@
+Qualcomm Video Clock & Reset Controller Binding
+---
+
+Required properties :
+- compatible : shall contain "qcom,sdm845-videocc"
+- reg : shall contain base register location and length
+- #clock-cells : from common clock binding, shall contain 1.
+- #power-domain-cells : from generic power domain binding, shall contain 1.
+
+Optional properties :
+- #reset-cells : from common reset binding, shall contain 1.
+
+Example:
+   videocc: clock-controller@ab0 {
+   compatible = "qcom,sdm845-videocc";
+   reg = <0xab0 0x1>;
+   #clock-cells = <1>;
+   #power-domain-cells = <1>;
+   };
diff --git a/include/dt-bindings/clock/qcom,videocc-sdm845.h 
b/include/dt-bindings/clock/qcom,videocc-sdm845.h
new file mode 100644
index 000..1b86816
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,videocc-sdm845.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_SDM_VIDEO_CC_SDM845_H
+#define _DT_BINDINGS_CLK_SDM_VIDEO_CC_SDM845_H
+
+/* VIDEO_CC clock registers */
+#define VIDEO_CC_APB_CLK   0
+#define VIDEO_CC_AT_CLK1
+#define VIDEO_CC_QDSS_TRIG_CLK 2
+#define VIDEO_CC_QDSS_TSCTR_DIV8_CLK   3
+#define VIDEO_CC_VCODEC0_AXI_CLK   4
+#define VIDEO_CC_VCODEC0_CORE_CLK  5
+#define VIDEO_CC_VCODEC1_AXI_CLK   6
+#define VIDEO_CC_VCODEC1_CORE_CLK  7
+#define VIDEO_CC_VENUS_AHB_CLK 8
+#define VIDEO_CC_VENUS_CLK_SRC 9
+#define VIDEO_CC_VENUS_CTL_AXI_CLK 10
+#define VIDEO_CC_VENUS_CTL_CORE_CLK11
+#define VIDEO_PLL0 12
+
+/* VIDEO_CC Resets */
+#define VIDEO_CC_VENUS_BCR 0
+#define VIDEO_CC_VCODEC0_BCR   1
+#define VIDEO_CC_VCODEC1_BCR   2
+#define VIDEO_CC_INTERFACE_BCR 3
+
+/* VIDEO_CC GDSCRs */
+#define VENUS_GDSC 0
+#define VCODEC0_GDSC   1
+#define VCODEC1_GDSC   2
+
+#endif
--
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 video clock controller driver

2018-05-09 Thread Amit Nischal
Changes in v2:
https://lkml.org/lkml/2018/5/8/918
- Added #defines for resets in the header file.

Changes in v1:
   https://lkml.org/lkml/2018/4/24/545
Addressed below review comments given by Rob
- Change the compatible property as per ',-' format.
- Add header definitions for resets and power-domain cells.

This patch series adds a driver and device tree documentation binding
for the video clock controller on some Qualcomm Technologies, Inc, SoCs
such as SDM845. This would allow video drivers to probe and control their
clocks.

The video clock driver depends upon the RPMh driver[1], command DB driver[2],
RPMh clock driver[3], rcg2 shared ops[4] and GCC clock driver[5] changes
which are undergoing review.

[1]: https://lkml.org/lkml/2018/4/19/914
[2]: https://lkml.org/lkml/2018/4/5/451
[3]: https://lkml.org/lkml/2018/4/24/390
[4]: https://lkml.org/lkml/2018/4/18/367
[5]: https://lkml.org/lkml/2018/4/30/533

[v1]: https://lkml.org/lkml/2018/5/3/386

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

 .../devicetree/bindings/clock/qcom,videocc.txt |  19 ++
 drivers/clk/qcom/Kconfig   |  11 +
 drivers/clk/qcom/Makefile  |   1 +
 drivers/clk/qcom/videocc-sdm845.c  | 358 +
 include/dt-bindings/clock/qcom,videocc-sdm845.h|  35 ++
 5 files changed, 424 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,videocc.txt
 create mode 100644 drivers/clk/qcom/videocc-sdm845.c
 create mode 100644 include/dt-bindings/clock/qcom,videocc-sdm845.h

--
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 video clock controller driver

2018-05-09 Thread Amit Nischal
Changes in v2:
https://lkml.org/lkml/2018/5/8/918
- Added #defines for resets in the header file.

Changes in v1:
   https://lkml.org/lkml/2018/4/24/545
Addressed below review comments given by Rob
- Change the compatible property as per ',-' format.
- Add header definitions for resets and power-domain cells.

This patch series adds a driver and device tree documentation binding
for the video clock controller on some Qualcomm Technologies, Inc, SoCs
such as SDM845. This would allow video drivers to probe and control their
clocks.

The video clock driver depends upon the RPMh driver[1], command DB driver[2],
RPMh clock driver[3], rcg2 shared ops[4] and GCC clock driver[5] changes
which are undergoing review.

[1]: https://lkml.org/lkml/2018/4/19/914
[2]: https://lkml.org/lkml/2018/4/5/451
[3]: https://lkml.org/lkml/2018/4/24/390
[4]: https://lkml.org/lkml/2018/4/18/367
[5]: https://lkml.org/lkml/2018/4/30/533

[v1]: https://lkml.org/lkml/2018/5/3/386

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

 .../devicetree/bindings/clock/qcom,videocc.txt |  19 ++
 drivers/clk/qcom/Kconfig   |  11 +
 drivers/clk/qcom/Makefile  |   1 +
 drivers/clk/qcom/videocc-sdm845.c  | 358 +
 include/dt-bindings/clock/qcom,videocc-sdm845.h|  35 ++
 5 files changed, 424 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,videocc.txt
 create mode 100644 drivers/clk/qcom/videocc-sdm845.c
 create mode 100644 include/dt-bindings/clock/qcom,videocc-sdm845.h

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



Re: [PATCH v1 0/2] Add QCOM video clock controller driver

2018-05-07 Thread Amit Nischal

On 2018-05-07 22:41, Rob Herring wrote:

On Mon, May 07, 2018 at 04:16:53PM +0530, Amit Nischal wrote:

On 2018-05-04 22:01, Stephen Boyd wrote:
> Quoting Amit Nischal (2018-05-03 05:35:23)
> > Changes in v1:
> >https://lkml.org/lkml/2018/4/24/545
> > Addressed below review comments given by Rob
> > - Change the compatible property as per ',-'
> > format.
> > - Add header definitions for resets and power-domain cells.
>
> You didn't add any reset definitions though?

We haven't added the reset definitions for videocc as there is no
video reset client.


So? You don't know what resets there are?



We know the resets, but video driver doesn't do any block resets
prior to accessing the video subsystem so that's the reason we do
not want to expose the resets in videocc driver.


Rob
--
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


Re: [PATCH v1 0/2] Add QCOM video clock controller driver

2018-05-07 Thread Amit Nischal

On 2018-05-07 22:41, Rob Herring wrote:

On Mon, May 07, 2018 at 04:16:53PM +0530, Amit Nischal wrote:

On 2018-05-04 22:01, Stephen Boyd wrote:
> Quoting Amit Nischal (2018-05-03 05:35:23)
> > Changes in v1:
> >https://lkml.org/lkml/2018/4/24/545
> > Addressed below review comments given by Rob
> > - Change the compatible property as per ',-'
> > format.
> > - Add header definitions for resets and power-domain cells.
>
> You didn't add any reset definitions though?

We haven't added the reset definitions for videocc as there is no
video reset client.


So? You don't know what resets there are?



We know the resets, but video driver doesn't do any block resets
prior to accessing the video subsystem so that's the reason we do
not want to expose the resets in videocc driver.


Rob
--
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


[PATCH v7 2/3] clk: qcom: Add DT bindings for SDM845 gcc clock controller

2018-05-07 Thread Amit Nischal
Add compatible string and the include file for gcc clock
controller for SDM845.

Signed-off-by: Amit Nischal <anisc...@codeaurora.org>
Reviewed-by: Rob Herring <r...@kernel.org>
---
 .../devicetree/bindings/clock/qcom,gcc.txt |   1 +
 include/dt-bindings/clock/qcom,gcc-sdm845.h| 239 +
 2 files changed, 240 insertions(+)
 create mode 100644 include/dt-bindings/clock/qcom,gcc-sdm845.h

diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.txt 
b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
index d1fb8b2..664ea1f 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-sdm845"

 - reg : shall contain base register location and length
 - #clock-cells : shall contain 1
diff --git a/include/dt-bindings/clock/qcom,gcc-sdm845.h 
b/include/dt-bindings/clock/qcom,gcc-sdm845.h
new file mode 100644
index 000..aca6126
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,gcc-sdm845.h
@@ -0,0 +1,239 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_SDM_GCC_SDM845_H
+#define _DT_BINDINGS_CLK_SDM_GCC_SDM845_H
+
+/* 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 GCC_AGGRE_USB3_SEC_AXI_CLK 4
+#define GCC_BOOT_ROM_AHB_CLK   5
+#define GCC_CAMERA_AHB_CLK 6
+#define GCC_CAMERA_AXI_CLK 7
+#define GCC_CAMERA_XO_CLK  8
+#define GCC_CE1_AHB_CLK9
+#define GCC_CE1_AXI_CLK10
+#define GCC_CE1_CLK11
+#define GCC_CFG_NOC_USB3_PRIM_AXI_CLK  12
+#define GCC_CFG_NOC_USB3_SEC_AXI_CLK   13
+#define GCC_CPUSS_AHB_CLK  14
+#define GCC_CPUSS_AHB_CLK_SRC  15
+#define GCC_CPUSS_RBCPR_CLK16
+#define GCC_CPUSS_RBCPR_CLK_SRC17
+#define GCC_DDRSS_GPU_AXI_CLK  18
+#define GCC_DISP_AHB_CLK   19
+#define GCC_DISP_AXI_CLK   20
+#define GCC_DISP_GPLL0_CLK_SRC 21
+#define GCC_DISP_GPLL0_DIV_CLK_SRC 22
+#define GCC_DISP_XO_CLK23
+#define GCC_GP1_CLK24
+#define GCC_GP1_CLK_SRC25
+#define GCC_GP2_CLK26
+#define GCC_GP2_CLK_SRC27
+#define GCC_GP3_CLK28
+#define GCC_GP3_CLK_SRC29
+#define GCC_GPU_CFG_AHB_CLK30
+#define GCC_GPU_GPLL0_CLK_SRC  31
+#define GCC_GPU_GPLL0_DIV_CLK_SRC  32
+#define GCC_GPU_MEMNOC_GFX_CLK 33
+#define GCC_GPU_SNOC_DVM_GFX_CLK   34
+#define GCC_MSS_AXIS2_CLK  35
+#define GCC_MSS_CFG_AHB_CLK36
+#define GCC_MSS_GPLL0_DIV_CLK_SRC  37
+#define GCC_MSS_MFAB_AXIS_CLK  38
+#define GCC_MSS_Q6_MEMNOC_AXI_CLK  39
+#define GCC_MSS_SNOC_AXI_CLK   40
+#define GCC_PCIE_0_AUX_CLK 41
+#define GCC_PCIE_0_AUX_CLK_SRC 42
+#define GCC_PCIE_0_CFG_AHB_CLK 43
+#define GCC_PCIE_0_CLKREF_CLK  44
+#define GCC_PCIE_0_MSTR_AXI_CLK45
+#define GCC_PCIE_0_PIPE_CLK46
+#define GCC_PCIE_0_SLV_AXI_CLK 47
+#define GCC_PCIE_0_SLV_Q2A_AXI_CLK 48
+#define GCC_PCIE_1_AUX_CLK 49
+#define GCC_PCIE_1_AUX_CLK_SRC 50
+#define GCC_P

[PATCH v7 2/3] clk: qcom: Add DT bindings for SDM845 gcc clock controller

2018-05-07 Thread Amit Nischal
Add compatible string and the include file for gcc clock
controller for SDM845.

Signed-off-by: Amit Nischal 
Reviewed-by: Rob Herring 
---
 .../devicetree/bindings/clock/qcom,gcc.txt |   1 +
 include/dt-bindings/clock/qcom,gcc-sdm845.h| 239 +
 2 files changed, 240 insertions(+)
 create mode 100644 include/dt-bindings/clock/qcom,gcc-sdm845.h

diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.txt 
b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
index d1fb8b2..664ea1f 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-sdm845"

 - reg : shall contain base register location and length
 - #clock-cells : shall contain 1
diff --git a/include/dt-bindings/clock/qcom,gcc-sdm845.h 
b/include/dt-bindings/clock/qcom,gcc-sdm845.h
new file mode 100644
index 000..aca6126
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,gcc-sdm845.h
@@ -0,0 +1,239 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_SDM_GCC_SDM845_H
+#define _DT_BINDINGS_CLK_SDM_GCC_SDM845_H
+
+/* 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 GCC_AGGRE_USB3_SEC_AXI_CLK 4
+#define GCC_BOOT_ROM_AHB_CLK   5
+#define GCC_CAMERA_AHB_CLK 6
+#define GCC_CAMERA_AXI_CLK 7
+#define GCC_CAMERA_XO_CLK  8
+#define GCC_CE1_AHB_CLK9
+#define GCC_CE1_AXI_CLK10
+#define GCC_CE1_CLK11
+#define GCC_CFG_NOC_USB3_PRIM_AXI_CLK  12
+#define GCC_CFG_NOC_USB3_SEC_AXI_CLK   13
+#define GCC_CPUSS_AHB_CLK  14
+#define GCC_CPUSS_AHB_CLK_SRC  15
+#define GCC_CPUSS_RBCPR_CLK16
+#define GCC_CPUSS_RBCPR_CLK_SRC17
+#define GCC_DDRSS_GPU_AXI_CLK  18
+#define GCC_DISP_AHB_CLK   19
+#define GCC_DISP_AXI_CLK   20
+#define GCC_DISP_GPLL0_CLK_SRC 21
+#define GCC_DISP_GPLL0_DIV_CLK_SRC 22
+#define GCC_DISP_XO_CLK23
+#define GCC_GP1_CLK24
+#define GCC_GP1_CLK_SRC25
+#define GCC_GP2_CLK26
+#define GCC_GP2_CLK_SRC27
+#define GCC_GP3_CLK28
+#define GCC_GP3_CLK_SRC29
+#define GCC_GPU_CFG_AHB_CLK30
+#define GCC_GPU_GPLL0_CLK_SRC  31
+#define GCC_GPU_GPLL0_DIV_CLK_SRC  32
+#define GCC_GPU_MEMNOC_GFX_CLK 33
+#define GCC_GPU_SNOC_DVM_GFX_CLK   34
+#define GCC_MSS_AXIS2_CLK  35
+#define GCC_MSS_CFG_AHB_CLK36
+#define GCC_MSS_GPLL0_DIV_CLK_SRC  37
+#define GCC_MSS_MFAB_AXIS_CLK  38
+#define GCC_MSS_Q6_MEMNOC_AXI_CLK  39
+#define GCC_MSS_SNOC_AXI_CLK   40
+#define GCC_PCIE_0_AUX_CLK 41
+#define GCC_PCIE_0_AUX_CLK_SRC 42
+#define GCC_PCIE_0_CFG_AHB_CLK 43
+#define GCC_PCIE_0_CLKREF_CLK  44
+#define GCC_PCIE_0_MSTR_AXI_CLK45
+#define GCC_PCIE_0_PIPE_CLK46
+#define GCC_PCIE_0_SLV_AXI_CLK 47
+#define GCC_PCIE_0_SLV_Q2A_AXI_CLK 48
+#define GCC_PCIE_1_AUX_CLK 49
+#define GCC_PCIE_1_AUX_CLK_SRC 50
+#define GCC_PCIE_1_CFG_AHB_CLK  

[PATCH v7 3/3] clk: qcom: Add Global Clock controller (GCC) driver for SDM845

2018-05-07 Thread Amit Nischal
From: Taniya Das <t...@codeaurora.org>

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

Signed-off-by: Taniya Das <t...@codeaurora.org>
Signed-off-by: Amit Nischal <anisc...@codeaurora.org>
---
 drivers/clk/qcom/Kconfig  |9 +
 drivers/clk/qcom/Makefile |1 +
 drivers/clk/qcom/gcc-sdm845.c | 3465 +
 3 files changed, 3475 insertions(+)
 create mode 100644 drivers/clk/qcom/gcc-sdm845.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index e42e1af..aec69d2 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_845
+   tristate "SDM845 Global Clock Controller"
+   select QCOM_GDSC
+   depends on COMMON_CLK_QCOM
+   help
+ Support for the global clock controller on msm8998 devices.
+ Say Y if you want to use peripheral devices such as UART, SPI,
+ I2C, USB, UFS, SDDC, PCIe, etc.
+
 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 7c09ab1..bf8fb25 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -38,4 +38,5 @@ 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_845) += gcc-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
new file mode 100644
index 000..e78e6f5
--- /dev/null
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -0,0 +1,3465 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "common.h"
+#include "clk-regmap.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-branch.h"
+#include "clk-alpha-pll.h"
+#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,
+   P_CORE_BI_PLL_TEST_SE,
+   P_GPLL0_OUT_EVEN,
+   P_GPLL0_OUT_MAIN,
+   P_GPLL4_OUT_MAIN,
+   P_SLEEP_CLK,
+};
+
+static const struct parent_map gcc_parent_map_0[] = {
+   { P_BI_TCXO, 0 },
+   { P_GPLL0_OUT_MAIN, 1 },
+   { P_GPLL0_OUT_EVEN, 6 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_0[] = {
+   "bi_tcxo",
+   "gpll0",
+   "gpll0_out_even",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map gcc_parent_map_1[] = {
+   { P_BI_TCXO, 0 },
+   { P_GPLL0_OUT_MAIN, 1 },
+   { P_SLEEP_CLK, 5 },
+   { P_GPLL0_OUT_EVEN, 6 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_1[] = {
+   "bi_tcxo",
+   "gpll0",
+   "core_pi_sleep_clk",
+   "gpll0_out_even",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map gcc_parent_map_2[] = {
+   { P_BI_TCXO, 0 },
+   { P_SLEEP_CLK, 5 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_2[] = {
+   "bi_tcxo",
+   "core_pi_sleep_clk",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map gcc_parent_map_3[] = {
+   { P_BI_TCXO, 0 },
+   { P_GPLL0_OUT_MAIN, 1 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_3[] = {
+   "bi_tcxo",
+   "gpll0",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map gcc_parent_map_4[] = {
+   { P_BI_TCXO, 0 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_4[] = {
+   "bi_tcxo",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map gcc_parent_map_5[] = {
+   { P_BI_TCXO, 0 },
+   { P_GPLL0_OUT_MAIN, 1 },
+   { P_GPLL4_OUT_MAIN, 5 },
+   { P_GPLL0_OUT_EVEN, 6 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_5[] = {
+   "bi_tcxo",
+   "gpll0",
+   "gpll4",
+   "gpll0_out_even",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map gcc_pare

[PATCH v7 3/3] clk: qcom: Add Global Clock controller (GCC) driver for SDM845

2018-05-07 Thread Amit Nischal
From: Taniya Das 

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

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

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index e42e1af..aec69d2 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_845
+   tristate "SDM845 Global Clock Controller"
+   select QCOM_GDSC
+   depends on COMMON_CLK_QCOM
+   help
+ Support for the global clock controller on msm8998 devices.
+ Say Y if you want to use peripheral devices such as UART, SPI,
+ I2C, USB, UFS, SDDC, PCIe, etc.
+
 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 7c09ab1..bf8fb25 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -38,4 +38,5 @@ 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_845) += gcc-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
new file mode 100644
index 000..e78e6f5
--- /dev/null
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -0,0 +1,3465 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "common.h"
+#include "clk-regmap.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-branch.h"
+#include "clk-alpha-pll.h"
+#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,
+   P_CORE_BI_PLL_TEST_SE,
+   P_GPLL0_OUT_EVEN,
+   P_GPLL0_OUT_MAIN,
+   P_GPLL4_OUT_MAIN,
+   P_SLEEP_CLK,
+};
+
+static const struct parent_map gcc_parent_map_0[] = {
+   { P_BI_TCXO, 0 },
+   { P_GPLL0_OUT_MAIN, 1 },
+   { P_GPLL0_OUT_EVEN, 6 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_0[] = {
+   "bi_tcxo",
+   "gpll0",
+   "gpll0_out_even",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map gcc_parent_map_1[] = {
+   { P_BI_TCXO, 0 },
+   { P_GPLL0_OUT_MAIN, 1 },
+   { P_SLEEP_CLK, 5 },
+   { P_GPLL0_OUT_EVEN, 6 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_1[] = {
+   "bi_tcxo",
+   "gpll0",
+   "core_pi_sleep_clk",
+   "gpll0_out_even",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map gcc_parent_map_2[] = {
+   { P_BI_TCXO, 0 },
+   { P_SLEEP_CLK, 5 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_2[] = {
+   "bi_tcxo",
+   "core_pi_sleep_clk",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map gcc_parent_map_3[] = {
+   { P_BI_TCXO, 0 },
+   { P_GPLL0_OUT_MAIN, 1 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_3[] = {
+   "bi_tcxo",
+   "gpll0",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map gcc_parent_map_4[] = {
+   { P_BI_TCXO, 0 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_4[] = {
+   "bi_tcxo",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map gcc_parent_map_5[] = {
+   { P_BI_TCXO, 0 },
+   { P_GPLL0_OUT_MAIN, 1 },
+   { P_GPLL4_OUT_MAIN, 5 },
+   { P_GPLL0_OUT_EVEN, 6 },
+   { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_5[] = {
+   "bi_tcxo",
+   "gpll0",
+   "gpll4",
+   "gpll0_out_even",
+   "core_bi_pll_test_se",
+};
+
+static const struct parent_map gcc_parent_map_6[] = {
+   { P_BI_TCXO, 0 },
+   { P_GPLL0_OUT_MAIN, 1 },
+   { P_AUD_REF_C

[PATCH v7 1/3] clk: qcom: Configure the RCGs to a safe source as needed

2018-05-07 Thread Amit Nischal
For some root clock generators, there could be child branches which are
controlled by an entity other than application processor subsystem. For
such RCGs, as per application processor subsystem clock driver, all of
its downstream clocks are disabled and RCG is in disabled state but in
reality downstream clocks can be left enabled before.

So in this scenario, when RCG is disabled as per clock driver's point of
view and when rate scaling request comes before downstream clock enable
request, then RCG fails to update its configuration because in reality
RCG is on and it expects its new source to already be in enable state but
in reality new source is off. In order to avoid having the RCG to go into
an invalid state, add support to update the CFG, M, N and D registers
during set_rate() without configuration update and defer the actual RCG
configuration update to be done during clk_enable() as at this point of
time, both its new parent and safe source will be already enabled and RCG
can safely switch to new parent.

During clk_disable() request, configure it to safe source as both its
parents, safe source and current parent will be enabled and RCG can
safely execute a switch.

Signed-off-by: Taniya Das <t...@codeaurora.org>
Signed-off-by: Amit Nischal <anisc...@codeaurora.org>
---
 drivers/clk/qcom/clk-rcg.h  |  17 ++---
 drivers/clk/qcom/clk-rcg2.c | 170 
 2 files changed, 163 insertions(+), 24 deletions(-)

diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h
index 2a7489a..b209a2f 100644
--- a/drivers/clk/qcom/clk-rcg.h
+++ b/drivers/clk/qcom/clk-rcg.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, 2018, The Linux Foundation. All rights reserved. */

 #ifndef __QCOM_CLK_RCG_H__
 #define __QCOM_CLK_RCG_H__
@@ -144,6 +134,7 @@ struct clk_dyn_rcg {
  * @cmd_rcgr: corresponds to *_CMD_RCGR
  * @mnd_width: number of bits in m/n/d values
  * @hid_width: number of bits in half integer divider
+ * @safe_src_index: safe src index value
  * @parent_map: map from software's parent index to hardware's src_sel field
  * @freq_tbl: frequency table
  * @clkr: regmap clock handle
@@ -153,6 +144,7 @@ struct clk_rcg2 {
u32 cmd_rcgr;
u8  mnd_width;
u8  hid_width;
+   u8  safe_src_index;
const struct parent_map *parent_map;
const struct freq_tbl   *freq_tbl;
struct clk_regmap   clkr;
@@ -167,5 +159,6 @@ struct clk_rcg2 {
 extern const struct clk_ops clk_byte2_ops;
 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;

 #endif
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index e63db10..6827ab3 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -1,14 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2013, 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 
@@ -249,7 +241,7 @@ static int clk_rcg2_determine_floor_rate(struct clk_hw *hw,
return _freq_tbl_determine_rate(hw, rcg->freq_tbl, req, FLOOR);
 }

-static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
+static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
 {
u32 cfg, mask;
struct clk_hw *hw = >clkr.hw;
@@ -282,8 +274,16 @@ static int clk_rcg2_configure(struct clk_rcg2 *rcg, const 
struct freq_tbl *f)
cfg |= rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT;
if (rcg->mnd_width && f->n && (f->m != f->n))
cfg |= CFG_MODE_DUAL_EDGE;
-   ret = regmap_update_bits(rcg->clkr.regmap,
-   rcg->cmd_rcgr + CFG_REG, mask, cfg);
+
+   return regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG,
+

[PATCH v7 1/3] clk: qcom: Configure the RCGs to a safe source as needed

2018-05-07 Thread Amit Nischal
For some root clock generators, there could be child branches which are
controlled by an entity other than application processor subsystem. For
such RCGs, as per application processor subsystem clock driver, all of
its downstream clocks are disabled and RCG is in disabled state but in
reality downstream clocks can be left enabled before.

So in this scenario, when RCG is disabled as per clock driver's point of
view and when rate scaling request comes before downstream clock enable
request, then RCG fails to update its configuration because in reality
RCG is on and it expects its new source to already be in enable state but
in reality new source is off. In order to avoid having the RCG to go into
an invalid state, add support to update the CFG, M, N and D registers
during set_rate() without configuration update and defer the actual RCG
configuration update to be done during clk_enable() as at this point of
time, both its new parent and safe source will be already enabled and RCG
can safely switch to new parent.

During clk_disable() request, configure it to safe source as both its
parents, safe source and current parent will be enabled and RCG can
safely execute a switch.

Signed-off-by: Taniya Das 
Signed-off-by: Amit Nischal 
---
 drivers/clk/qcom/clk-rcg.h  |  17 ++---
 drivers/clk/qcom/clk-rcg2.c | 170 
 2 files changed, 163 insertions(+), 24 deletions(-)

diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h
index 2a7489a..b209a2f 100644
--- a/drivers/clk/qcom/clk-rcg.h
+++ b/drivers/clk/qcom/clk-rcg.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, 2018, The Linux Foundation. All rights reserved. */

 #ifndef __QCOM_CLK_RCG_H__
 #define __QCOM_CLK_RCG_H__
@@ -144,6 +134,7 @@ struct clk_dyn_rcg {
  * @cmd_rcgr: corresponds to *_CMD_RCGR
  * @mnd_width: number of bits in m/n/d values
  * @hid_width: number of bits in half integer divider
+ * @safe_src_index: safe src index value
  * @parent_map: map from software's parent index to hardware's src_sel field
  * @freq_tbl: frequency table
  * @clkr: regmap clock handle
@@ -153,6 +144,7 @@ struct clk_rcg2 {
u32 cmd_rcgr;
u8  mnd_width;
u8  hid_width;
+   u8  safe_src_index;
const struct parent_map *parent_map;
const struct freq_tbl   *freq_tbl;
struct clk_regmap   clkr;
@@ -167,5 +159,6 @@ struct clk_rcg2 {
 extern const struct clk_ops clk_byte2_ops;
 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;

 #endif
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index e63db10..6827ab3 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -1,14 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2013, 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 
@@ -249,7 +241,7 @@ static int clk_rcg2_determine_floor_rate(struct clk_hw *hw,
return _freq_tbl_determine_rate(hw, rcg->freq_tbl, req, FLOOR);
 }

-static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
+static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
 {
u32 cfg, mask;
struct clk_hw *hw = >clkr.hw;
@@ -282,8 +274,16 @@ static int clk_rcg2_configure(struct clk_rcg2 *rcg, const 
struct freq_tbl *f)
cfg |= rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT;
if (rcg->mnd_width && f->n && (f->m != f->n))
cfg |= CFG_MODE_DUAL_EDGE;
-   ret = regmap_update_bits(rcg->clkr.regmap,
-   rcg->cmd_rcgr + CFG_REG, mask, cfg);
+
+   return regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG,
+   mask, cfg);
+}
+
+static in

[PATCH v7 0/3] Misc patches to support clocks for SDM845

2018-05-07 Thread Amit Nischal
Changes in v7:
1. Addressed review comments from Stephen and Rob for GCC driver.
   - Split dt-bindings to a separate patch from the driver patch.
   - Change the 'halt_check' type to BRANCH_HALT_SKIP for pipe
 and ufs_card tx/rx symbol clocks.
   - Remove 'halt_reg' for the clocks where 'halt_check' type is
 BRANCH_HALT_DELAY. For such clocks, there is no status bit
 to poll. For e.g. gcc_disp_gpll0_clk_src clock.
2. Implemented rcg2_shared_ops as suggested by Stephen in
   https://lkml.org/lkml/2018/5/2/91.
3. The GCC clock driver(patch 3) depends upon the below patches related to
   GDSC operation and RPMh clock driver, which are under review.
   https://lkml.org/lkml/2018/4/27/110
   https://lkml.org/lkml/2018/4/24/390

Changes in v6:
1. Addressed review comments for v3 and v4 version of GCC driver for SDM845.
   https://lkml.org/lkml/2018/4/16/1129.
2. Add support for new flag 'BRANCH_NO_DELAY' for branch clocks.
3. Addressed review comments for v5 version of rcg2_shared_ops patch.
   https://lkml.org/lkml/2018/4/19/86
4. The GCC clock driver(patch 3) depends upon the below patches related to
   GDSC operation and RPMh clock driver, which are under review.
   https://lkml.org/lkml/2018/4/27/110
   https://lkml.org/lkml/2018/4/24/390

Changes in v5:
1. Addressed review comments for v3 and v4 version of GCC driver for SDM845
   https://lkml.org/lkml/2018/4/16/1129
2. Removed bi_tcxo clock being modelled from the GCC driver, as RPMH clock
   driver would provide the same. https://lkml.org/lkml/2018/4/13/685
3. The GCC clock driver(patch 2) depends upon the below patches related to
   GDSC operation and RPMh clock driver, which are under review.
   https://lkml.org/lkml/2018/4/2/143
   https://lkml.org/lkml/2018/4/13/685

Changes in v4:
1. Addressed review comments for v2 version of GCC driver for SDM845
   https://lkml.org/lkml/2018/4/9/55.
2. The GCC clock driver(patch 3) depends upon the below patches
   related to GDSC operation and are under review.

   https://lkml.org/lkml/2018/4/2/142

Changes in v3:
1. Addressed review comments given for v2 series.
2. The GCC clock driver(patch 3) depends upon the below patches related
   to GDSC operation and are under review.

   https://lkml.org/lkml/2018/4/2/142

Changes in v2:
Fixup for recalc_rate ops for clk_rcg2_shared_ops:
There could be few scenarios where shared clocks are configured
at rate other than CXO by boot. In those cases there would be a
mismatch between the rate calculated by the recalc shared ops
and the actual HW register configuration. Fix the same by adding
an additional check to read current src from CFG register and
make a decision based on that.

Changes in v1:
https://lkml.org/lkml/2018/1/31/209

This patch series does the miscellaneous changes to support
clock nodes for SDM845. Below are the major changes for
which the existing code does not have support.

1. Clear hardware clock control bit of RCGs where HW clock
   control bit is set by default so that software can control
   those root clocks.
2. Introduces clk_rcg2_shared_ops to support clock controller
   drivers for SDM845. With new shared ops, RCGs with shared
   branches will be configured to a safe source in disable
   path and actual RCG update configuration will be done in
   enable path instead of doing config update in set_rate.
   In set_rate(), just cache the rate instead of doing actual
   configuration update. Also each RCG in clock controller
   driver will have their own safe configuration frequency
   table to switch to safe frequency.
3. Add support for controlling Fabia PLL for which the support
   is not available in existing alpha PLL code.
4. Add Global Clock controller (GCC) driver for SDM845. This
   should allow most non-multimedia device drivers to probe
   and control their clocks.

[v1] : https://lkml.org/lkml/2018/1/31/209
[v2] : https://lkml.org/lkml/2018/3/8/495
[v3] : https://lkml.org/lkml/2018/4/3/356
[v4] : https://lkml.org/lkml/2018/4/9/79
[v5] : https://lkml.org/lkml/2018/4/18/367
[v6] : https://lkml.org/lkml/2018/4/30/533

Amit Nischal (2):
  clk: qcom: Configure the RCGs to a safe source as needed
  clk: qcom: Add DT bindings for SDM845 gcc clock controller

Taniya Das (1):
  clk: qcom: Add Global Clock controller (GCC) driver for SDM845

 .../devicetree/bindings/clock/qcom,gcc.txt |1 +
 drivers/clk/qcom/Kconfig   |9 +
 drivers/clk/qcom/Makefile  |1 +
 drivers/clk/qcom/clk-rcg.h |   17 +-
 drivers/clk/qcom/clk-rcg2.c|  170 +-
 drivers/clk/qcom/gcc-sdm845.c  | 3465 
 include/dt-bindings/clock/qcom,gcc-sdm845.h|  239 ++
 7 files changed, 3878 insertions(+), 24 deletions(-)
 create mode 100644 drivers/clk/qcom/gcc-sdm845.c
 create mode 100644 include/dt-bindings/clock/qcom,gcc-sdm845.h

--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code

[PATCH v7 0/3] Misc patches to support clocks for SDM845

2018-05-07 Thread Amit Nischal
Changes in v7:
1. Addressed review comments from Stephen and Rob for GCC driver.
   - Split dt-bindings to a separate patch from the driver patch.
   - Change the 'halt_check' type to BRANCH_HALT_SKIP for pipe
 and ufs_card tx/rx symbol clocks.
   - Remove 'halt_reg' for the clocks where 'halt_check' type is
 BRANCH_HALT_DELAY. For such clocks, there is no status bit
 to poll. For e.g. gcc_disp_gpll0_clk_src clock.
2. Implemented rcg2_shared_ops as suggested by Stephen in
   https://lkml.org/lkml/2018/5/2/91.
3. The GCC clock driver(patch 3) depends upon the below patches related to
   GDSC operation and RPMh clock driver, which are under review.
   https://lkml.org/lkml/2018/4/27/110
   https://lkml.org/lkml/2018/4/24/390

Changes in v6:
1. Addressed review comments for v3 and v4 version of GCC driver for SDM845.
   https://lkml.org/lkml/2018/4/16/1129.
2. Add support for new flag 'BRANCH_NO_DELAY' for branch clocks.
3. Addressed review comments for v5 version of rcg2_shared_ops patch.
   https://lkml.org/lkml/2018/4/19/86
4. The GCC clock driver(patch 3) depends upon the below patches related to
   GDSC operation and RPMh clock driver, which are under review.
   https://lkml.org/lkml/2018/4/27/110
   https://lkml.org/lkml/2018/4/24/390

Changes in v5:
1. Addressed review comments for v3 and v4 version of GCC driver for SDM845
   https://lkml.org/lkml/2018/4/16/1129
2. Removed bi_tcxo clock being modelled from the GCC driver, as RPMH clock
   driver would provide the same. https://lkml.org/lkml/2018/4/13/685
3. The GCC clock driver(patch 2) depends upon the below patches related to
   GDSC operation and RPMh clock driver, which are under review.
   https://lkml.org/lkml/2018/4/2/143
   https://lkml.org/lkml/2018/4/13/685

Changes in v4:
1. Addressed review comments for v2 version of GCC driver for SDM845
   https://lkml.org/lkml/2018/4/9/55.
2. The GCC clock driver(patch 3) depends upon the below patches
   related to GDSC operation and are under review.

   https://lkml.org/lkml/2018/4/2/142

Changes in v3:
1. Addressed review comments given for v2 series.
2. The GCC clock driver(patch 3) depends upon the below patches related
   to GDSC operation and are under review.

   https://lkml.org/lkml/2018/4/2/142

Changes in v2:
Fixup for recalc_rate ops for clk_rcg2_shared_ops:
There could be few scenarios where shared clocks are configured
at rate other than CXO by boot. In those cases there would be a
mismatch between the rate calculated by the recalc shared ops
and the actual HW register configuration. Fix the same by adding
an additional check to read current src from CFG register and
make a decision based on that.

Changes in v1:
https://lkml.org/lkml/2018/1/31/209

This patch series does the miscellaneous changes to support
clock nodes for SDM845. Below are the major changes for
which the existing code does not have support.

1. Clear hardware clock control bit of RCGs where HW clock
   control bit is set by default so that software can control
   those root clocks.
2. Introduces clk_rcg2_shared_ops to support clock controller
   drivers for SDM845. With new shared ops, RCGs with shared
   branches will be configured to a safe source in disable
   path and actual RCG update configuration will be done in
   enable path instead of doing config update in set_rate.
   In set_rate(), just cache the rate instead of doing actual
   configuration update. Also each RCG in clock controller
   driver will have their own safe configuration frequency
   table to switch to safe frequency.
3. Add support for controlling Fabia PLL for which the support
   is not available in existing alpha PLL code.
4. Add Global Clock controller (GCC) driver for SDM845. This
   should allow most non-multimedia device drivers to probe
   and control their clocks.

[v1] : https://lkml.org/lkml/2018/1/31/209
[v2] : https://lkml.org/lkml/2018/3/8/495
[v3] : https://lkml.org/lkml/2018/4/3/356
[v4] : https://lkml.org/lkml/2018/4/9/79
[v5] : https://lkml.org/lkml/2018/4/18/367
[v6] : https://lkml.org/lkml/2018/4/30/533

Amit Nischal (2):
  clk: qcom: Configure the RCGs to a safe source as needed
  clk: qcom: Add DT bindings for SDM845 gcc clock controller

Taniya Das (1):
  clk: qcom: Add Global Clock controller (GCC) driver for SDM845

 .../devicetree/bindings/clock/qcom,gcc.txt |1 +
 drivers/clk/qcom/Kconfig   |9 +
 drivers/clk/qcom/Makefile  |1 +
 drivers/clk/qcom/clk-rcg.h |   17 +-
 drivers/clk/qcom/clk-rcg2.c|  170 +-
 drivers/clk/qcom/gcc-sdm845.c  | 3465 
 include/dt-bindings/clock/qcom,gcc-sdm845.h|  239 ++
 7 files changed, 3878 insertions(+), 24 deletions(-)
 create mode 100644 drivers/clk/qcom/gcc-sdm845.c
 create mode 100644 include/dt-bindings/clock/qcom,gcc-sdm845.h

--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code

Re: [PATCH v1 0/2] Add QCOM video clock controller driver

2018-05-07 Thread Amit Nischal

On 2018-05-04 22:01, Stephen Boyd wrote:

Quoting Amit Nischal (2018-05-03 05:35:23)

Changes in v1:
   https://lkml.org/lkml/2018/4/24/545
Addressed below review comments given by Rob
- Change the compatible property as per ',-' 
format.

- Add header definitions for resets and power-domain cells.


You didn't add any reset definitions though?


We haven't added the reset definitions for videocc as there is no
video reset client.



--
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


Re: [PATCH v1 0/2] Add QCOM video clock controller driver

2018-05-07 Thread Amit Nischal

On 2018-05-04 22:01, Stephen Boyd wrote:

Quoting Amit Nischal (2018-05-03 05:35:23)

Changes in v1:
   https://lkml.org/lkml/2018/4/24/545
Addressed below review comments given by Rob
- Change the compatible property as per ',-' 
format.

- Add header definitions for resets and power-domain cells.


You didn't add any reset definitions though?


We haven't added the reset definitions for videocc as there is no
video reset client.



--
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


Re: [PATCH v6 3/3] clk: qcom: Add Global Clock controller (GCC) driver for SDM845

2018-05-07 Thread Amit Nischal

On 2018-05-05 08:44, Stephen Boyd wrote:

Quoting Amit Nischal (2018-05-04 03:45:12)

On 2018-05-02 12:53, Stephen Boyd wrote:
> Quoting Amit Nischal (2018-04-30 09:20:10)
>> +
>> +static struct clk_branch gcc_disp_gpll0_clk_src = {
>> +   .halt_reg = 0x52004,
>> +   .halt_check = BRANCH_HALT_DELAY,
>
> What about this one? It's not a phy so I'm confused again why we're
> unable to check the halt bit. To be clear(er), I don't see why we ever
> want to have HALT_DELAY used. Hopefully we can remove that flag.
>
> From what I recall, the flag is there for clks that don't toggle their
> status bit at all, but that we know take a few cycles to ungate the
> upstream clk. So we threw a delay into the code to make sure that when
> clk_enable() returned, a driver wouldn't try to use hardware before the
> clk was actually on. But these cases should pretty much never happen,
> hence all the pushback against this flag.
>

For these "*gpll0_clk_src" and "*gpll0_div_clk" clocks, there is no 
halt
bit to check the status and it is required to have delay for few 
cycles
so that clock gets turned on before a client driver to use the 
hardware.


Ok.. but then why is there a 'halt_reg' configured for the clk?


Thanks for the review.
I will remove the halt_reg for the clocks where we are using the 
'HALT_DELAY'
flag and there is no need to poll the status bit as we are returning 
early

from the 'clk_branch_wait()' function.




>> +
>> +static struct clk_branch gcc_ufs_card_rx_symbol_0_clk = {
>> +   .halt_reg = 0x75018,
>> +   .halt_check = BRANCH_HALT_DELAY,
>
> There are still HALT_DELAY flags for UFS though? Why?

For ufs_card tx/rx symbol clocks, we don't poll the status bit as
per the recommendation from the HW team. We can change the halt_check
type to newly implemented flag "BRANCH_HALT_SKIP". Please update us 
with

your thoughts to change the flag to "BRANCH_HALT_SKIP".


Yes use HALT_SKIP please.


Thanks for confirming. I will do the changes in the next patch series.





>
> Also, are you going to send DFS support for the QUP clks? I would like
> to see that code merged soon.

Taniya has sent the patches for DFS support for QUP clocks.
https://patchwork.kernel.org/patch/10376951/



I'll take a look.
--
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


Re: [PATCH v6 3/3] clk: qcom: Add Global Clock controller (GCC) driver for SDM845

2018-05-07 Thread Amit Nischal

On 2018-05-05 08:44, Stephen Boyd wrote:

Quoting Amit Nischal (2018-05-04 03:45:12)

On 2018-05-02 12:53, Stephen Boyd wrote:
> Quoting Amit Nischal (2018-04-30 09:20:10)
>> +
>> +static struct clk_branch gcc_disp_gpll0_clk_src = {
>> +   .halt_reg = 0x52004,
>> +   .halt_check = BRANCH_HALT_DELAY,
>
> What about this one? It's not a phy so I'm confused again why we're
> unable to check the halt bit. To be clear(er), I don't see why we ever
> want to have HALT_DELAY used. Hopefully we can remove that flag.
>
> From what I recall, the flag is there for clks that don't toggle their
> status bit at all, but that we know take a few cycles to ungate the
> upstream clk. So we threw a delay into the code to make sure that when
> clk_enable() returned, a driver wouldn't try to use hardware before the
> clk was actually on. But these cases should pretty much never happen,
> hence all the pushback against this flag.
>

For these "*gpll0_clk_src" and "*gpll0_div_clk" clocks, there is no 
halt
bit to check the status and it is required to have delay for few 
cycles
so that clock gets turned on before a client driver to use the 
hardware.


Ok.. but then why is there a 'halt_reg' configured for the clk?


Thanks for the review.
I will remove the halt_reg for the clocks where we are using the 
'HALT_DELAY'
flag and there is no need to poll the status bit as we are returning 
early

from the 'clk_branch_wait()' function.




>> +
>> +static struct clk_branch gcc_ufs_card_rx_symbol_0_clk = {
>> +   .halt_reg = 0x75018,
>> +   .halt_check = BRANCH_HALT_DELAY,
>
> There are still HALT_DELAY flags for UFS though? Why?

For ufs_card tx/rx symbol clocks, we don't poll the status bit as
per the recommendation from the HW team. We can change the halt_check
type to newly implemented flag "BRANCH_HALT_SKIP". Please update us 
with

your thoughts to change the flag to "BRANCH_HALT_SKIP".


Yes use HALT_SKIP please.


Thanks for confirming. I will do the changes in the next patch series.





>
> Also, are you going to send DFS support for the QUP clks? I would like
> to see that code merged soon.

Taniya has sent the patches for DFS support for QUP clocks.
https://patchwork.kernel.org/patch/10376951/



I'll take a look.
--
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


Re: [PATCH v6 1/3] clk: qcom: Configure the RCGs to a safe source as needed

2018-05-07 Thread Amit Nischal

On 2018-05-05 08:54, Stephen Boyd wrote:

Quoting Amit Nischal (2018-05-03 04:57:37)

On 2018-05-02 13:15, Stephen Boyd wrote:
> Quoting Amit Nischal (2018-04-30 09:20:08)
>
>> +}
>> +
>> +static void clk_rcg2_shared_disable(struct clk_hw *hw)
>> +{
>> +   struct clk_rcg2 *rcg = to_clk_rcg2(hw);
>> +   struct freq_tbl safe_src_tbl = { 0 };
>> +
>> +   /*
>> +* Park the RCG at a safe configuration - sourced off from
>> safe source.
>> +* Force enable and disable the RCG while configuring it to
>> safeguard
>> +* against any update signal coming from the downstream clock.
>> +* The current parent is still prepared and enabled at this
>> point, and
>> +* the safe source is always on while application processor
>> subsystem
>> +* is online. Therefore, the RCG can safely switch its parent.
>> +*/
>> +   safe_src_tbl.src = rcg->safe_src_index;
>> +   clk_rcg2_shared_force_enable_clear(hw, _src_tbl);
>
> This should then re-dirty the config register to have the software
> frequency settings that existed in the hardware when disable was
> called.
> Given that MND shouldn't be changed here, this should be as simple as
> saving away the CFG register, forcing it to XO speed by changing the
> src
> and disabling dual edge in the CFG register (please don't call
> force_enable_clear with some frequency pointer, just do this inline
> here), and then rewriting the cfg register with the "real" settings for
> whatever frequency it's supposed to run at and then returning from this
> function.
>
> I guess we have to do a read cfg from hardware, write cfg, hit update
> config, and then write cfg again each time we disable. For enable, we
> just do an update config (if it's dirty?) inside of a force
> enable/disable pair. And set_rate doesn't really change except it
> either
> does or doesn't hit the update config bit if the clk is enabled or
> disabled respectively.
>

We have done the below changes suggested by you and that logic seems 
to

be
working fine. But we have one concern about leaving the RCG registers 
in

dirty state and would like to have a little bit modification as
explained
below:

Suggested Logic:
1. set_rate()--> Update CFG, M, N and D registers and don't hit the
update
  bit if clock is disabled - call new
__clk_rcg2_configure().
  Above will make the CFG register as dirty.

2. _disable()--> 2.1 - Store the CFG register configuration in a
variable.
  2.2 - Move to the safe source (XO) and hit the 
update

bit.
It will only touch the CFG register and M, N, 
D

register values will remain as it was.
  2.3 - Write back the stored CFG value done in step 
#2.1

This will again redirty the CFG register.

3. _enable()--> Just hit the update bit as the configuration write 
will

 be taken care in the steps #1 and #2.

It would be great if we don't redirty the CFG register and leave the 
RCG

CFG register to at safe source(XO) in disable() path.

This would help us to debug the issues where device crashes and we 
want

to dump the RCG registers to know whether from software, we have
actually
moved to safe source or not. Otherwise, we would get the dirty 
register

values in crash dumps.

So instead of writing back the stored CFG(corresponding to real rate
settings) in disable path, we want to restore the stored CFG in enable
path and then hit the update bit.
CFG configuration store can happen at two places - set_rate() and
disable()
path and above logic will be modified as below:

1. set_rate()--> 1.1 - Update CFG, M, N and D registers and don't hit
the
update bit if clock is disabled.
  1.2 - Store CFG register value in 'current_cfg' 
member

of 'rcg2' structure.

2. _disable()--> 2.1 - Store the CFG register value in 'current_cfg'
before
switching to the safe source (XO).
  2.2 - Move to the safe source (XO) and hit the 
update

bit.
Now RCG configuration wil not be dirty.

3. _enable()--> 3.1 - Check for 'current_cfg' value and if 0 then
return.
   This would catch the below one time condition:
   - when clk_enable() gets call without 
set_rate().


We want clk_enable() to work without set_rate() though. So returning 0
if the value is 0 is wrong.


 3.2 - Write the CFG value from 'current_cfg' to CFG
register.
 3.2 - Hit the update bit as we have already written 
the

latest
   configuration in step #3.2.
 3.3 - Clear the 'cu

Re: [PATCH v6 1/3] clk: qcom: Configure the RCGs to a safe source as needed

2018-05-07 Thread Amit Nischal

On 2018-05-05 08:54, Stephen Boyd wrote:

Quoting Amit Nischal (2018-05-03 04:57:37)

On 2018-05-02 13:15, Stephen Boyd wrote:
> Quoting Amit Nischal (2018-04-30 09:20:08)
>
>> +}
>> +
>> +static void clk_rcg2_shared_disable(struct clk_hw *hw)
>> +{
>> +   struct clk_rcg2 *rcg = to_clk_rcg2(hw);
>> +   struct freq_tbl safe_src_tbl = { 0 };
>> +
>> +   /*
>> +* Park the RCG at a safe configuration - sourced off from
>> safe source.
>> +* Force enable and disable the RCG while configuring it to
>> safeguard
>> +* against any update signal coming from the downstream clock.
>> +* The current parent is still prepared and enabled at this
>> point, and
>> +* the safe source is always on while application processor
>> subsystem
>> +* is online. Therefore, the RCG can safely switch its parent.
>> +*/
>> +   safe_src_tbl.src = rcg->safe_src_index;
>> +   clk_rcg2_shared_force_enable_clear(hw, _src_tbl);
>
> This should then re-dirty the config register to have the software
> frequency settings that existed in the hardware when disable was
> called.
> Given that MND shouldn't be changed here, this should be as simple as
> saving away the CFG register, forcing it to XO speed by changing the
> src
> and disabling dual edge in the CFG register (please don't call
> force_enable_clear with some frequency pointer, just do this inline
> here), and then rewriting the cfg register with the "real" settings for
> whatever frequency it's supposed to run at and then returning from this
> function.
>
> I guess we have to do a read cfg from hardware, write cfg, hit update
> config, and then write cfg again each time we disable. For enable, we
> just do an update config (if it's dirty?) inside of a force
> enable/disable pair. And set_rate doesn't really change except it
> either
> does or doesn't hit the update config bit if the clk is enabled or
> disabled respectively.
>

We have done the below changes suggested by you and that logic seems 
to

be
working fine. But we have one concern about leaving the RCG registers 
in

dirty state and would like to have a little bit modification as
explained
below:

Suggested Logic:
1. set_rate()--> Update CFG, M, N and D registers and don't hit the
update
  bit if clock is disabled - call new
__clk_rcg2_configure().
  Above will make the CFG register as dirty.

2. _disable()--> 2.1 - Store the CFG register configuration in a
variable.
  2.2 - Move to the safe source (XO) and hit the 
update

bit.
It will only touch the CFG register and M, N, 
D

register values will remain as it was.
  2.3 - Write back the stored CFG value done in step 
#2.1

This will again redirty the CFG register.

3. _enable()--> Just hit the update bit as the configuration write 
will

 be taken care in the steps #1 and #2.

It would be great if we don't redirty the CFG register and leave the 
RCG

CFG register to at safe source(XO) in disable() path.

This would help us to debug the issues where device crashes and we 
want

to dump the RCG registers to know whether from software, we have
actually
moved to safe source or not. Otherwise, we would get the dirty 
register

values in crash dumps.

So instead of writing back the stored CFG(corresponding to real rate
settings) in disable path, we want to restore the stored CFG in enable
path and then hit the update bit.
CFG configuration store can happen at two places - set_rate() and
disable()
path and above logic will be modified as below:

1. set_rate()--> 1.1 - Update CFG, M, N and D registers and don't hit
the
update bit if clock is disabled.
  1.2 - Store CFG register value in 'current_cfg' 
member

of 'rcg2' structure.

2. _disable()--> 2.1 - Store the CFG register value in 'current_cfg'
before
switching to the safe source (XO).
  2.2 - Move to the safe source (XO) and hit the 
update

bit.
Now RCG configuration wil not be dirty.

3. _enable()--> 3.1 - Check for 'current_cfg' value and if 0 then
return.
   This would catch the below one time condition:
   - when clk_enable() gets call without 
set_rate().


We want clk_enable() to work without set_rate() though. So returning 0
if the value is 0 is wrong.


 3.2 - Write the CFG value from 'current_cfg' to CFG
register.
 3.2 - Hit the update bit as we have already written 
the

latest
   configuration in step #3.2.
 3.3 - Clear the 'cu

Re: [PATCH v6 3/3] clk: qcom: Add Global Clock controller (GCC) driver for SDM845

2018-05-04 Thread Amit Nischal

On 2018-05-02 12:53, Stephen Boyd wrote:

Quoting Amit Nischal (2018-04-30 09:20:10)

---
 .../devicetree/bindings/clock/qcom,gcc.txt |1 +
 drivers/clk/qcom/Kconfig   |   10 +-
 drivers/clk/qcom/Makefile  |1 +
 drivers/clk/qcom/gcc-sdm845.c  | 3480 


 include/dt-bindings/clock/qcom,gcc-sdm845.h|  239 ++


Do the split that Rob suggests please, given that you're resending. And
also include his reviewed-by tag.


Thanks for the review. Sure I will split the dt-binding into
separate patch in next series.




 5 files changed, 3727 insertions(+), 4 deletions(-)
 create mode 100644 drivers/clk/qcom/gcc-sdm845.c
 create mode 100644 include/dt-bindings/clock/qcom,gcc-sdm845.h

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index e42e1af..3298beb 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -218,13 +218,15 @@ config MSM_MMCC_8996
  Say Y if you want to support multimedia devices such as 
display,

  graphics, video encode/decode, camera, etc.

-config MSM_GCC_8998
-   tristate "MSM8998 Global Clock Controller"
+config SDM_GCC_845
+   tristate "SDM845 Global Clock Controller"
+   select QCOM_GDSC
depends on COMMON_CLK_QCOM
help
- Support for the global clock controller on msm8998 devices.
+ Support for the global clock controller on Qualcomm 
Technologies, Inc

+ sdm845 devices.
  Say Y if you want to use peripheral devices such as UART, 
SPI,

- i2c, USB, UFS, SD/eMMC, PCIe, etc.
+ I2C, USB, UFS, SDDC, PCIe, etc.


This is all wrong.



My bad. I did by mistake. Will fix this in next series.



 config SPMI_PMIC_CLKDIV
tristate "SPMI PMIC clkdiv Support"
diff --git a/drivers/clk/qcom/gcc-sdm845.c 
b/drivers/clk/qcom/gcc-sdm845.c

new file mode 100644
index 000..6484cba
--- /dev/null
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -0,0 +1,3480 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+

[...]

+   .name = "gcc_disp_axi_clk",
+   .ops = _branch2_ops,
+   },
+   },
+};
+
+static struct clk_branch gcc_disp_gpll0_clk_src = {
+   .halt_reg = 0x52004,
+   .halt_check = BRANCH_HALT_DELAY,


What about this one? It's not a phy so I'm confused again why we're
unable to check the halt bit. To be clear(er), I don't see why we ever
want to have HALT_DELAY used. Hopefully we can remove that flag.

From what I recall, the flag is there for clks that don't toggle their
status bit at all, but that we know take a few cycles to ungate the
upstream clk. So we threw a delay into the code to make sure that when
clk_enable() returned, a driver wouldn't try to use hardware before the
clk was actually on. But these cases should pretty much never happen,
hence all the pushback against this flag.



For these "*gpll0_clk_src" and "*gpll0_div_clk" clocks, there is no halt
bit to check the status and it is required to have delay for few cycles
so that clock gets turned on before a client driver to use the hardware.


+   .clkr = {
+   .enable_reg = 0x52004,
+   .enable_mask = BIT(18),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_disp_gpll0_clk_src",
+   .parent_names = (const char *[]){
+   "gpll0",
+   },
+   .num_parents = 1,

[...]

+   .enable_reg = 0x7508c,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_ufs_card_phy_aux_clk",
+   .parent_names = (const char *[]){
+   "gcc_ufs_card_phy_aux_clk_src",
+   },
+   .num_parents = 1,
+   .flags = CLK_SET_RATE_PARENT,
+   .ops = _branch2_ops,
+   },
+   },
+};
+
+static struct clk_branch gcc_ufs_card_rx_symbol_0_clk = {
+   .halt_reg = 0x75018,
+   .halt_check = BRANCH_HALT_DELAY,


There are still HALT_DELAY flags for UFS though? Why?


For ufs_card tx/rx symbol clocks, we don't poll the status bit as
per the recommendation from the HW team. We can change the halt_check
type to newly implemented flag "BRANCH_HALT_SKIP". Please update us with
your thoughts to change the flag to "BRANCH_HALT_SKIP".



Also, are you going to send DFS support for the QUP clks? I would like
to see that code merged soon.


Taniya has sent the patches for DFS support for QUP clocks.
https://patchwork.kernel.org/patch/10376951/



Re: [PATCH v6 3/3] clk: qcom: Add Global Clock controller (GCC) driver for SDM845

2018-05-04 Thread Amit Nischal

On 2018-05-02 12:53, Stephen Boyd wrote:

Quoting Amit Nischal (2018-04-30 09:20:10)

---
 .../devicetree/bindings/clock/qcom,gcc.txt |1 +
 drivers/clk/qcom/Kconfig   |   10 +-
 drivers/clk/qcom/Makefile  |1 +
 drivers/clk/qcom/gcc-sdm845.c  | 3480 


 include/dt-bindings/clock/qcom,gcc-sdm845.h|  239 ++


Do the split that Rob suggests please, given that you're resending. And
also include his reviewed-by tag.


Thanks for the review. Sure I will split the dt-binding into
separate patch in next series.




 5 files changed, 3727 insertions(+), 4 deletions(-)
 create mode 100644 drivers/clk/qcom/gcc-sdm845.c
 create mode 100644 include/dt-bindings/clock/qcom,gcc-sdm845.h

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index e42e1af..3298beb 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -218,13 +218,15 @@ config MSM_MMCC_8996
  Say Y if you want to support multimedia devices such as 
display,

  graphics, video encode/decode, camera, etc.

-config MSM_GCC_8998
-   tristate "MSM8998 Global Clock Controller"
+config SDM_GCC_845
+   tristate "SDM845 Global Clock Controller"
+   select QCOM_GDSC
depends on COMMON_CLK_QCOM
help
- Support for the global clock controller on msm8998 devices.
+ Support for the global clock controller on Qualcomm 
Technologies, Inc

+ sdm845 devices.
  Say Y if you want to use peripheral devices such as UART, 
SPI,

- i2c, USB, UFS, SD/eMMC, PCIe, etc.
+ I2C, USB, UFS, SDDC, PCIe, etc.


This is all wrong.



My bad. I did by mistake. Will fix this in next series.



 config SPMI_PMIC_CLKDIV
tristate "SPMI PMIC clkdiv Support"
diff --git a/drivers/clk/qcom/gcc-sdm845.c 
b/drivers/clk/qcom/gcc-sdm845.c

new file mode 100644
index 000..6484cba
--- /dev/null
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -0,0 +1,3480 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+

[...]

+   .name = "gcc_disp_axi_clk",
+   .ops = _branch2_ops,
+   },
+   },
+};
+
+static struct clk_branch gcc_disp_gpll0_clk_src = {
+   .halt_reg = 0x52004,
+   .halt_check = BRANCH_HALT_DELAY,


What about this one? It's not a phy so I'm confused again why we're
unable to check the halt bit. To be clear(er), I don't see why we ever
want to have HALT_DELAY used. Hopefully we can remove that flag.

From what I recall, the flag is there for clks that don't toggle their
status bit at all, but that we know take a few cycles to ungate the
upstream clk. So we threw a delay into the code to make sure that when
clk_enable() returned, a driver wouldn't try to use hardware before the
clk was actually on. But these cases should pretty much never happen,
hence all the pushback against this flag.



For these "*gpll0_clk_src" and "*gpll0_div_clk" clocks, there is no halt
bit to check the status and it is required to have delay for few cycles
so that clock gets turned on before a client driver to use the hardware.


+   .clkr = {
+   .enable_reg = 0x52004,
+   .enable_mask = BIT(18),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_disp_gpll0_clk_src",
+   .parent_names = (const char *[]){
+   "gpll0",
+   },
+   .num_parents = 1,

[...]

+   .enable_reg = 0x7508c,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "gcc_ufs_card_phy_aux_clk",
+   .parent_names = (const char *[]){
+   "gcc_ufs_card_phy_aux_clk_src",
+   },
+   .num_parents = 1,
+   .flags = CLK_SET_RATE_PARENT,
+   .ops = _branch2_ops,
+   },
+   },
+};
+
+static struct clk_branch gcc_ufs_card_rx_symbol_0_clk = {
+   .halt_reg = 0x75018,
+   .halt_check = BRANCH_HALT_DELAY,


There are still HALT_DELAY flags for UFS though? Why?


For ufs_card tx/rx symbol clocks, we don't poll the status bit as
per the recommendation from the HW team. We can change the halt_check
type to newly implemented flag "BRANCH_HALT_SKIP". Please update us with
your thoughts to change the flag to "BRANCH_HALT_SKIP".



Also, are you going to send DFS support for the QUP clks? I would like
to see that code merged soon.


Taniya has sent the patches for DFS support for QUP clocks.
https://patchwork.kernel.org/patch/10376951/



[PATCH v1 1/2] dt-bindings: clock: Introduce QCOM Video clock controller bindings

2018-05-03 Thread Amit Nischal
Add device tree bindings for video clock controller for Qualcomm
Technology Inc's SoCs.

Signed-off-by: Amit Nischal <anisc...@codeaurora.org>
---
 .../devicetree/bindings/clock/qcom,videocc.txt | 18 
 include/dt-bindings/clock/qcom,videocc-sdm845.h| 25 ++
 2 files changed, 43 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,videocc.txt
 create mode 100644 include/dt-bindings/clock/qcom,videocc-sdm845.h

diff --git a/Documentation/devicetree/bindings/clock/qcom,videocc.txt 
b/Documentation/devicetree/bindings/clock/qcom,videocc.txt
new file mode 100644
index 000..600eda2
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,videocc.txt
@@ -0,0 +1,18 @@
+Qualcomm Video Clock & Reset Controller Binding
+---
+
+Required properties :
+- compatible : shall contain "qcom,sdm845-videocc"
+- 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:
+   videocc: clock-controller@ab0 {
+   compatible = "qcom,sdm845-videocc";
+   reg = <0xab0 0x1>;
+   #clock-cells = <1>;
+   #reset-cells = <1>;
+   #power-domain-cells = <1>;
+   };
diff --git a/include/dt-bindings/clock/qcom,videocc-sdm845.h 
b/include/dt-bindings/clock/qcom,videocc-sdm845.h
new file mode 100644
index 000..48f6a9e
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,videocc-sdm845.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved. */
+
+#ifndef _DT_BINDINGS_CLK_MSM_VIDEO_CC_SDM845_H
+#define _DT_BINDINGS_CLK_MSM_VIDEO_CC_SDM845_H
+
+#define VIDEO_CC_APB_CLK   0
+#define VIDEO_CC_AT_CLK1
+#define VIDEO_CC_QDSS_TRIG_CLK 2
+#define VIDEO_CC_QDSS_TSCTR_DIV8_CLK   3
+#define VIDEO_CC_VCODEC0_AXI_CLK   4
+#define VIDEO_CC_VCODEC0_CORE_CLK  5
+#define VIDEO_CC_VCODEC1_AXI_CLK   6
+#define VIDEO_CC_VCODEC1_CORE_CLK  7
+#define VIDEO_CC_VENUS_AHB_CLK 8
+#define VIDEO_CC_VENUS_CLK_SRC 9
+#define VIDEO_CC_VENUS_CTL_AXI_CLK 10
+#define VIDEO_CC_VENUS_CTL_CORE_CLK11
+#define VIDEO_PLL0 12
+
+#define VENUS_GDSC 0
+#define VCODEC0_GDSC   1
+#define VCODEC1_GDSC   2
+
+#endif
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



[PATCH v1 1/2] dt-bindings: clock: Introduce QCOM Video clock controller bindings

2018-05-03 Thread Amit Nischal
Add device tree bindings for video clock controller for Qualcomm
Technology Inc's SoCs.

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

diff --git a/Documentation/devicetree/bindings/clock/qcom,videocc.txt 
b/Documentation/devicetree/bindings/clock/qcom,videocc.txt
new file mode 100644
index 000..600eda2
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,videocc.txt
@@ -0,0 +1,18 @@
+Qualcomm Video Clock & Reset Controller Binding
+---
+
+Required properties :
+- compatible : shall contain "qcom,sdm845-videocc"
+- 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:
+   videocc: clock-controller@ab0 {
+   compatible = "qcom,sdm845-videocc";
+   reg = <0xab0 0x1>;
+   #clock-cells = <1>;
+   #reset-cells = <1>;
+   #power-domain-cells = <1>;
+   };
diff --git a/include/dt-bindings/clock/qcom,videocc-sdm845.h 
b/include/dt-bindings/clock/qcom,videocc-sdm845.h
new file mode 100644
index 000..48f6a9e
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,videocc-sdm845.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved. */
+
+#ifndef _DT_BINDINGS_CLK_MSM_VIDEO_CC_SDM845_H
+#define _DT_BINDINGS_CLK_MSM_VIDEO_CC_SDM845_H
+
+#define VIDEO_CC_APB_CLK   0
+#define VIDEO_CC_AT_CLK1
+#define VIDEO_CC_QDSS_TRIG_CLK 2
+#define VIDEO_CC_QDSS_TSCTR_DIV8_CLK   3
+#define VIDEO_CC_VCODEC0_AXI_CLK   4
+#define VIDEO_CC_VCODEC0_CORE_CLK  5
+#define VIDEO_CC_VCODEC1_AXI_CLK   6
+#define VIDEO_CC_VCODEC1_CORE_CLK  7
+#define VIDEO_CC_VENUS_AHB_CLK 8
+#define VIDEO_CC_VENUS_CLK_SRC 9
+#define VIDEO_CC_VENUS_CTL_AXI_CLK 10
+#define VIDEO_CC_VENUS_CTL_CORE_CLK11
+#define VIDEO_PLL0 12
+
+#define VENUS_GDSC 0
+#define VCODEC0_GDSC   1
+#define VCODEC1_GDSC   2
+
+#endif
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



  1   2   3   >