diff options
| author | Stephen Boyd <sboyd@codeaurora.org> | 2014-01-15 13:47:32 -0500 |
|---|---|---|
| committer | Mike Turquette <mturquette@linaro.org> | 2014-01-16 15:01:05 -0500 |
| commit | 0eeff27b49b78979bb4d37d1ff8dda6751fa0ad8 (patch) | |
| tree | 9a8c07ca3144228c9efb74b9d20413b18f8b6e6b /drivers/clk | |
| parent | d8b212014e69d6b6323773ce6898f224ef4ed0d6 (diff) | |
clk: qcom: Add support for MSM8660's global clock controller (GCC)
Add a driver for the global clock controller found on MSM8660
based platforms. This should allow most non-multimedia device
drivers to probe and control their clocks.
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Mike Turquette <mturquette@linaro.org>
Diffstat (limited to 'drivers/clk')
| -rw-r--r-- | drivers/clk/qcom/Kconfig | 8 | ||||
| -rw-r--r-- | drivers/clk/qcom/Makefile | 1 | ||||
| -rw-r--r-- | drivers/clk/qcom/gcc-msm8660.c | 2819 |
3 files changed, 2828 insertions, 0 deletions
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 7b582dd5cd08..995bcfa021a4 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig | |||
| @@ -4,6 +4,14 @@ config COMMON_CLK_QCOM | |||
| 4 | select REGMAP_MMIO | 4 | select REGMAP_MMIO |
| 5 | select RESET_CONTROLLER | 5 | select RESET_CONTROLLER |
| 6 | 6 | ||
| 7 | config MSM_GCC_8660 | ||
| 8 | tristate "MSM8660 Global Clock Controller" | ||
| 9 | depends on COMMON_CLK_QCOM | ||
| 10 | help | ||
| 11 | Support for the global clock controller on msm8660 devices. | ||
| 12 | Say Y if you want to use peripheral devices such as UART, SPI, | ||
| 13 | i2c, USB, SD/eMMC, etc. | ||
| 14 | |||
| 7 | config MSM_GCC_8960 | 15 | config MSM_GCC_8960 |
| 8 | tristate "MSM8960 Global Clock Controller" | 16 | tristate "MSM8960 Global Clock Controller" |
| 9 | depends on COMMON_CLK_QCOM | 17 | depends on COMMON_CLK_QCOM |
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index e00cb848a1ae..190d38433202 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile | |||
| @@ -7,6 +7,7 @@ clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-rcg2.o | |||
| 7 | clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-branch.o | 7 | clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-branch.o |
| 8 | clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += reset.o | 8 | clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += reset.o |
| 9 | 9 | ||
| 10 | obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o | ||
| 10 | obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o | 11 | obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o |
| 11 | obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o | 12 | obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o |
| 12 | obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o | 13 | obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o |
diff --git a/drivers/clk/qcom/gcc-msm8660.c b/drivers/clk/qcom/gcc-msm8660.c new file mode 100644 index 000000000000..bc0b7f1fcfbe --- /dev/null +++ b/drivers/clk/qcom/gcc-msm8660.c | |||
| @@ -0,0 +1,2819 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2013, The Linux Foundation. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is licensed under the terms of the GNU General Public | ||
| 5 | * License version 2, as published by the Free Software Foundation, and | ||
| 6 | * may be copied, distributed, and modified under those terms. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/bitops.h> | ||
| 16 | #include <linux/err.h> | ||
| 17 | #include <linux/platform_device.h> | ||
| 18 | #include <linux/module.h> | ||
| 19 | #include <linux/of.h> | ||
| 20 | #include <linux/of_device.h> | ||
| 21 | #include <linux/clk-provider.h> | ||
| 22 | #include <linux/regmap.h> | ||
| 23 | #include <linux/reset-controller.h> | ||
| 24 | |||
| 25 | #include <dt-bindings/clock/qcom,gcc-msm8660.h> | ||
| 26 | #include <dt-bindings/reset/qcom,gcc-msm8660.h> | ||
| 27 | |||
| 28 | #include "clk-regmap.h" | ||
| 29 | #include "clk-pll.h" | ||
| 30 | #include "clk-rcg.h" | ||
| 31 | #include "clk-branch.h" | ||
| 32 | #include "reset.h" | ||
| 33 | |||
| 34 | static struct clk_pll pll8 = { | ||
| 35 | .l_reg = 0x3144, | ||
| 36 | .m_reg = 0x3148, | ||
| 37 | .n_reg = 0x314c, | ||
| 38 | .config_reg = 0x3154, | ||
| 39 | .mode_reg = 0x3140, | ||
| 40 | .status_reg = 0x3158, | ||
| 41 | .status_bit = 16, | ||
| 42 | .clkr.hw.init = &(struct clk_init_data){ | ||
| 43 | .name = "pll8", | ||
| 44 | .parent_names = (const char *[]){ "pxo" }, | ||
| 45 | .num_parents = 1, | ||
| 46 | .ops = &clk_pll_ops, | ||
| 47 | }, | ||
| 48 | }; | ||
| 49 | |||
| 50 | static struct clk_regmap pll8_vote = { | ||
| 51 | .enable_reg = 0x34c0, | ||
| 52 | .enable_mask = BIT(8), | ||
| 53 | .hw.init = &(struct clk_init_data){ | ||
| 54 | .name = "pll8_vote", | ||
| 55 | .parent_names = (const char *[]){ "pll8" }, | ||
| 56 | .num_parents = 1, | ||
| 57 | .ops = &clk_pll_vote_ops, | ||
| 58 | }, | ||
| 59 | }; | ||
| 60 | |||
| 61 | #define P_PXO 0 | ||
| 62 | #define P_PLL8 1 | ||
| 63 | #define P_CXO 2 | ||
| 64 | |||
| 65 | static const u8 gcc_pxo_pll8_map[] = { | ||
| 66 | [P_PXO] = 0, | ||
| 67 | [P_PLL8] = 3, | ||
| 68 | }; | ||
| 69 | |||
| 70 | static const char *gcc_pxo_pll8[] = { | ||
| 71 | "pxo", | ||
| 72 | "pll8_vote", | ||
| 73 | }; | ||
| 74 | |||
| 75 | static const u8 gcc_pxo_pll8_cxo_map[] = { | ||
| 76 | [P_PXO] = 0, | ||
| 77 | [P_PLL8] = 3, | ||
| 78 | [P_CXO] = 5, | ||
| 79 | }; | ||
| 80 | |||
| 81 | static const char *gcc_pxo_pll8_cxo[] = { | ||
| 82 | "pxo", | ||
| 83 | "pll8_vote", | ||
| 84 | "cxo", | ||
| 85 | }; | ||
| 86 | |||
| 87 | static struct freq_tbl clk_tbl_gsbi_uart[] = { | ||
| 88 | { 1843200, P_PLL8, 2, 6, 625 }, | ||
| 89 | { 3686400, P_PLL8, 2, 12, 625 }, | ||
| 90 | { 7372800, P_PLL8, 2, 24, 625 }, | ||
| 91 | { 14745600, P_PLL8, 2, 48, 625 }, | ||
| 92 | { 16000000, P_PLL8, 4, 1, 6 }, | ||
| 93 | { 24000000, P_PLL8, 4, 1, 4 }, | ||
| 94 | { 32000000, P_PLL8, 4, 1, 3 }, | ||
| 95 | { 40000000, P_PLL8, 1, 5, 48 }, | ||
| 96 | { 46400000, P_PLL8, 1, 29, 240 }, | ||
| 97 | { 48000000, P_PLL8, 4, 1, 2 }, | ||
| 98 | { 51200000, P_PLL8, 1, 2, 15 }, | ||
| 99 | { 56000000, P_PLL8, 1, 7, 48 }, | ||
| 100 | { 58982400, P_PLL8, 1, 96, 625 }, | ||
| 101 | { 64000000, P_PLL8, 2, 1, 3 }, | ||
| 102 | { } | ||
| 103 | }; | ||
| 104 | |||
| 105 | static struct clk_rcg gsbi1_uart_src = { | ||
| 106 | .ns_reg = 0x29d4, | ||
| 107 | .md_reg = 0x29d0, | ||
| 108 | .mn = { | ||
| 109 | .mnctr_en_bit = 8, | ||
| 110 | .mnctr_reset_bit = 7, | ||
| 111 | .mnctr_mode_shift = 5, | ||
| 112 | .n_val_shift = 16, | ||
| 113 | .m_val_shift = 16, | ||
| 114 | .width = 16, | ||
| 115 | }, | ||
| 116 | .p = { | ||
| 117 | .pre_div_shift = 3, | ||
| 118 | .pre_div_width = 2, | ||
| 119 | }, | ||
| 120 | .s = { | ||
| 121 | .src_sel_shift = 0, | ||
| 122 | .parent_map = gcc_pxo_pll8_map, | ||
| 123 | }, | ||
| 124 | .freq_tbl = clk_tbl_gsbi_uart, | ||
| 125 | .clkr = { | ||
| 126 | .enable_reg = 0x29d4, | ||
| 127 | .enable_mask = BIT(11), | ||
| 128 | .hw.init = &(struct clk_init_data){ | ||
| 129 | .name = "gsbi1_uart_src", | ||
| 130 | .parent_names = gcc_pxo_pll8, | ||
| 131 | .num_parents = 2, | ||
| 132 | .ops = &clk_rcg_ops, | ||
| 133 | .flags = CLK_SET_PARENT_GATE, | ||
| 134 | }, | ||
| 135 | }, | ||
| 136 | }; | ||
| 137 | |||
| 138 | static struct clk_branch gsbi1_uart_clk = { | ||
| 139 | .halt_reg = 0x2fcc, | ||
| 140 | .halt_bit = 10, | ||
| 141 | .clkr = { | ||
| 142 | .enable_reg = 0x29d4, | ||
| 143 | .enable_mask = BIT(9), | ||
| 144 | .hw.init = &(struct clk_init_data){ | ||
| 145 | .name = "gsbi1_uart_clk", | ||
| 146 | .parent_names = (const char *[]){ | ||
| 147 | "gsbi1_uart_src", | ||
| 148 | }, | ||
| 149 | .num_parents = 1, | ||
| 150 | .ops = &clk_branch_ops, | ||
| 151 | .flags = CLK_SET_RATE_PARENT, | ||
| 152 | }, | ||
| 153 | }, | ||
| 154 | }; | ||
| 155 | |||
| 156 | static struct clk_rcg gsbi2_uart_src = { | ||
| 157 | .ns_reg = 0x29f4, | ||
| 158 | .md_reg = 0x29f0, | ||
| 159 | .mn = { | ||
| 160 | .mnctr_en_bit = 8, | ||
| < | |||
