openwrtv4/target/linux/ipq806x/patches/0107-clk-qcom-Support-msm8974pro-global-clock-control-har.patch
John Crispin 3c1f6e358d ipq806x: Add support for IPQ806x chip family
Patches are generated using the "format-patch" command from the
following location:
*https://www.codeaurora.org/cgit/quic/kernel/galak-msm/log/?h=apq_ipq_base
*rev=0771849495b4128cac2faf7d49c85c729fc48b20
Patches numbered 76/77/102/103 have already been integrated in 3.14.12,
so they're not in this list.

All these patches are either integrated are pending integration into
kernel.org, therefore these patches should go away once the kernel
gets upgraded to 3.16.

Support is currently limited to AP148 board but can be extended to other
platforms in the future.

These changes do not cover ethernet connectivity.

Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>

SVN-Revision: 42334
2014-08-30 09:32:58 +00:00

245 lines
6.9 KiB
Diff

From a740d2b024c5b71c6f9989976049f03b634bb13d Mon Sep 17 00:00:00 2001
From: Stephen Boyd <sboyd@codeaurora.org>
Date: Fri, 16 May 2014 16:07:13 -0700
Subject: [PATCH 107/182] clk: qcom: Support msm8974pro global clock control
hardware
A new PLL (gpll4) is added on msm8974 PRO devices to support a
faster sdc1 clock rate. Add support for this and the two new sdcc
cal clocks.
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Mike Turquette <mturquette@linaro.org>
---
.../devicetree/bindings/clock/qcom,gcc.txt | 2 +
drivers/clk/qcom/gcc-msm8974.c | 130 +++++++++++++++++++-
include/dt-bindings/clock/qcom,gcc-msm8974.h | 4 +
3 files changed, 130 insertions(+), 6 deletions(-)
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.txt b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
index 7b7104e..9cfcb4f 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt
+++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
@@ -8,6 +8,8 @@ Required properties :
"qcom,gcc-msm8660"
"qcom,gcc-msm8960"
"qcom,gcc-msm8974"
+ "qcom,gcc-msm8974pro"
+ "qcom,gcc-msm8974pro-ac"
- reg : shall contain base register location and length
- #clock-cells : shall contain 1
diff --git a/drivers/clk/qcom/gcc-msm8974.c b/drivers/clk/qcom/gcc-msm8974.c
index 7a420fc..7af7c18 100644
--- a/drivers/clk/qcom/gcc-msm8974.c
+++ b/drivers/clk/qcom/gcc-msm8974.c
@@ -35,6 +35,7 @@
#define P_XO 0
#define P_GPLL0 1
#define P_GPLL1 1
+#define P_GPLL4 2
static const u8 gcc_xo_gpll0_map[] = {
[P_XO] = 0,
@@ -46,6 +47,18 @@ static const char *gcc_xo_gpll0[] = {
"gpll0_vote",
};
+static const u8 gcc_xo_gpll0_gpll4_map[] = {
+ [P_XO] = 0,
+ [P_GPLL0] = 1,
+ [P_GPLL4] = 5,
+};
+
+static const char *gcc_xo_gpll0_gpll4[] = {
+ "xo",
+ "gpll0_vote",
+ "gpll4_vote",
+};
+
#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
static struct clk_pll gpll0 = {
@@ -138,6 +151,33 @@ static struct clk_regmap gpll1_vote = {
},
};
+static struct clk_pll gpll4 = {
+ .l_reg = 0x1dc4,
+ .m_reg = 0x1dc8,
+ .n_reg = 0x1dcc,
+ .config_reg = 0x1dd4,
+ .mode_reg = 0x1dc0,
+ .status_reg = 0x1ddc,
+ .status_bit = 17,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gpll4",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .ops = &clk_pll_ops,
+ },
+};
+
+static struct clk_regmap gpll4_vote = {
+ .enable_reg = 0x1480,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpll4_vote",
+ .parent_names = (const char *[]){ "gpll4" },
+ .num_parents = 1,
+ .ops = &clk_pll_vote_ops,
+ },
+};
+
static const struct freq_tbl ftbl_gcc_usb30_master_clk[] = {
F(125000000, P_GPLL0, 1, 5, 24),
{ }
@@ -812,18 +852,33 @@ static const struct freq_tbl ftbl_gcc_sdcc1_4_apps_clk[] = {
{ }
};
+static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk_pro[] = {
+ F(144000, P_XO, 16, 3, 25),
+ F(400000, P_XO, 12, 1, 4),
+ F(20000000, P_GPLL0, 15, 1, 2),
+ F(25000000, P_GPLL0, 12, 1, 2),
+ F(50000000, P_GPLL0, 12, 0, 0),
+ F(100000000, P_GPLL0, 6, 0, 0),
+ F(192000000, P_GPLL4, 4, 0, 0),
+ F(200000000, P_GPLL0, 3, 0, 0),
+ F(384000000, P_GPLL4, 2, 0, 0),
+ { }
+};
+
+static struct clk_init_data sdcc1_apps_clk_src_init = {
+ .name = "sdcc1_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+};
+
static struct clk_rcg2 sdcc1_apps_clk_src = {
.cmd_rcgr = 0x04d0,
.mnd_width = 8,
.hid_width = 5,
.parent_map = gcc_xo_gpll0_map,
.freq_tbl = ftbl_gcc_sdcc1_4_apps_clk,
- .clkr.hw.init = &(struct clk_init_data){
- .name = "sdcc1_apps_clk_src",
- .parent_names = gcc_xo_gpll0,
- .num_parents = 2,
- .ops = &clk_rcg2_ops,
- },
+ .clkr.hw.init = &sdcc1_apps_clk_src_init,
};
static struct clk_rcg2 sdcc2_apps_clk_src = {
@@ -1995,6 +2050,38 @@ static struct clk_branch gcc_sdcc1_apps_clk = {
},
};
+static struct clk_branch gcc_sdcc1_cdccal_ff_clk = {
+ .halt_reg = 0x04e8,
+ .clkr = {
+ .enable_reg = 0x04e8,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_sdcc1_cdccal_ff_clk",
+ .parent_names = (const char *[]){
+ "xo"
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sdcc1_cdccal_sleep_clk = {
+ .halt_reg = 0x04e4,
+ .clkr = {
+ .enable_reg = 0x04e4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_sdcc1_cdccal_sleep_clk",
+ .parent_names = (const char *[]){
+ "sleep_clk_src"
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
static struct clk_branch gcc_sdcc2_ahb_clk = {
.halt_reg = 0x0508,
.clkr = {
@@ -2484,6 +2571,10 @@ static struct clk_regmap *gcc_msm8974_clocks[] = {
[GCC_USB_HSIC_IO_CAL_SLEEP_CLK] = &gcc_usb_hsic_io_cal_sleep_clk.clkr,
[GCC_USB_HSIC_SYSTEM_CLK] = &gcc_usb_hsic_system_clk.clkr,
[GCC_MMSS_GPLL0_CLK_SRC] = &gcc_mmss_gpll0_clk_src,
+ [GPLL4] = NULL,
+ [GPLL4_VOTE] = NULL,
+ [GCC_SDCC1_CDCCAL_SLEEP_CLK] = NULL,
+ [GCC_SDCC1_CDCCAL_FF_CLK] = NULL,
};
static const struct qcom_reset_map gcc_msm8974_resets[] = {
@@ -2585,14 +2676,41 @@ static const struct qcom_cc_desc gcc_msm8974_desc = {
static const struct of_device_id gcc_msm8974_match_table[] = {
{ .compatible = "qcom,gcc-msm8974" },
+ { .compatible = "qcom,gcc-msm8974pro" , .data = (void *)1UL },
+ { .compatible = "qcom,gcc-msm8974pro-ac", .data = (void *)1UL },
{ }
};
MODULE_DEVICE_TABLE(of, gcc_msm8974_match_table);
+static void msm8974_pro_clock_override(void)
+{
+ sdcc1_apps_clk_src_init.parent_names = gcc_xo_gpll0_gpll4;
+ sdcc1_apps_clk_src_init.num_parents = 3;
+ sdcc1_apps_clk_src.freq_tbl = ftbl_gcc_sdcc1_apps_clk_pro;
+ sdcc1_apps_clk_src.parent_map = gcc_xo_gpll0_gpll4_map;
+
+ gcc_msm8974_clocks[GPLL4] = &gpll4.clkr;
+ gcc_msm8974_clocks[GPLL4_VOTE] = &gpll4_vote;
+ gcc_msm8974_clocks[GCC_SDCC1_CDCCAL_SLEEP_CLK] =
+ &gcc_sdcc1_cdccal_sleep_clk.clkr;
+ gcc_msm8974_clocks[GCC_SDCC1_CDCCAL_FF_CLK] =
+ &gcc_sdcc1_cdccal_ff_clk.clkr;
+}
+
static int gcc_msm8974_probe(struct platform_device *pdev)
{
struct clk *clk;
struct device *dev = &pdev->dev;
+ bool pro;
+ const struct of_device_id *id;
+
+ id = of_match_device(gcc_msm8974_match_table, dev);
+ if (!id)
+ return -ENODEV;
+ pro = !!(id->data);
+
+ if (pro)
+ msm8974_pro_clock_override();
/* Temporary until RPM clocks supported */
clk = clk_register_fixed_rate(dev, "xo", NULL, CLK_IS_ROOT, 19200000);
diff --git a/include/dt-bindings/clock/qcom,gcc-msm8974.h b/include/dt-bindings/clock/qcom,gcc-msm8974.h
index 223ca17..51e51c8 100644
--- a/include/dt-bindings/clock/qcom,gcc-msm8974.h
+++ b/include/dt-bindings/clock/qcom,gcc-msm8974.h
@@ -316,5 +316,9 @@
#define GCC_CE2_CLK_SLEEP_ENA 299
#define GCC_CE2_AXI_CLK_SLEEP_ENA 300
#define GCC_CE2_AHB_CLK_SLEEP_ENA 301
+#define GPLL4 302
+#define GPLL4_VOTE 303
+#define GCC_SDCC1_CDCCAL_SLEEP_CLK 304
+#define GCC_SDCC1_CDCCAL_FF_CLK 305
#endif
--
1.7.10.4