Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

clk: qcom: Add LUCID_EVO PLL type for SDX65

Add a LUCID_EVO PLL type for SDX65 SoC from Qualcomm.

Signed-off-by: Vamsi Krishna Lanka <quic_vamslank@quicinc.com>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Reviewed-by: Vinod Koul <vkoul@kernel.org>
[bjorn: Fixed indentation issues reported by checkpatch]
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Link: https://lore.kernel.org/r/d582c3e291ae82aa488785eff36157653741f841.1638861860.git.quic_vamslank@quicinc.com

authored by

Vamsi Krishna Lanka and committed by
Bjorn Andersson
d1b121d6 4ad3ce00

+162 -5
+159 -5
drivers/clk/qcom/clk-alpha-pll.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* 3 3 * Copyright (c) 2015, 2018, The Linux Foundation. All rights reserved. 4 + * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved. 4 5 */ 5 6 6 7 #include <linux/kernel.h> ··· 140 139 [PLL_OFF_OPMODE] = 0x28, 141 140 [PLL_OFF_STATUS] = 0x38, 142 141 }, 142 + [CLK_ALPHA_PLL_TYPE_LUCID_EVO] = { 143 + [PLL_OFF_OPMODE] = 0x04, 144 + [PLL_OFF_STATUS] = 0x0c, 145 + [PLL_OFF_L_VAL] = 0x10, 146 + [PLL_OFF_ALPHA_VAL] = 0x14, 147 + [PLL_OFF_USER_CTL] = 0x18, 148 + [PLL_OFF_USER_CTL_U] = 0x1c, 149 + [PLL_OFF_CONFIG_CTL] = 0x20, 150 + [PLL_OFF_CONFIG_CTL_U] = 0x24, 151 + [PLL_OFF_CONFIG_CTL_U1] = 0x28, 152 + [PLL_OFF_TEST_CTL] = 0x2c, 153 + [PLL_OFF_TEST_CTL_U] = 0x30, 154 + [PLL_OFF_TEST_CTL_U1] = 0x34, 155 + }, 143 156 }; 144 157 EXPORT_SYMBOL_GPL(clk_alpha_pll_regs); 145 158 ··· 189 174 #define LUCID_5LPE_ALPHA_PLL_ACK_LATCH BIT(13) 190 175 #define LUCID_5LPE_PLL_LATCH_INPUT BIT(14) 191 176 #define LUCID_5LPE_ENABLE_VOTE_RUN BIT(21) 177 + 178 + /* LUCID EVO PLL specific settings and offsets */ 179 + #define LUCID_EVO_ENABLE_VOTE_RUN BIT(25) 180 + #define LUCID_EVO_PLL_L_VAL_MASK GENMASK(15, 0) 192 181 193 182 /* ZONDA PLL specific */ 194 183 #define ZONDA_PLL_OUT_MASK 0xf ··· 1760 1741 LUCID_5LPE_ALPHA_PLL_ACK_LATCH); 1761 1742 } 1762 1743 1763 - static int clk_lucid_5lpe_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate, 1764 - unsigned long parent_rate) 1744 + static int __clk_lucid_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate, 1745 + unsigned long parent_rate, 1746 + unsigned long enable_vote_run) 1765 1747 { 1766 1748 struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw); 1767 - int i, val = 0, div, ret; 1749 + struct regmap *regmap = pll->clkr.regmap; 1750 + int i, val, div, ret; 1768 1751 u32 mask; 1769 1752 1770 1753 /* 1771 1754 * If the PLL is in FSM mode, then treat set_rate callback as a 1772 1755 * no-operation. 1773 1756 */ 1774 - ret = regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &val); 1757 + ret = regmap_read(regmap, PLL_USER_CTL(pll), &val); 1775 1758 if (ret) 1776 1759 return ret; 1777 1760 1778 - if (val & LUCID_5LPE_ENABLE_VOTE_RUN) 1761 + if (val & enable_vote_run) 1779 1762 return 0; 1763 + 1764 + if (!pll->post_div_table) { 1765 + pr_err("Missing the post_div_table for the %s PLL\n", 1766 + clk_hw_get_name(&pll->clkr.hw)); 1767 + return -EINVAL; 1768 + } 1780 1769 1781 1770 div = DIV_ROUND_UP_ULL((u64)parent_rate, rate); 1782 1771 for (i = 0; i < pll->num_post_div; i++) { ··· 1797 1770 mask = GENMASK(pll->width + pll->post_div_shift - 1, pll->post_div_shift); 1798 1771 return regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll), 1799 1772 mask, val << pll->post_div_shift); 1773 + } 1774 + 1775 + static int clk_lucid_5lpe_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate, 1776 + unsigned long parent_rate) 1777 + { 1778 + return __clk_lucid_pll_postdiv_set_rate(hw, rate, parent_rate, LUCID_5LPE_ENABLE_VOTE_RUN); 1800 1779 } 1801 1780 1802 1781 const struct clk_ops clk_alpha_pll_lucid_5lpe_ops = { ··· 1984 1951 .set_rate = clk_zonda_pll_set_rate, 1985 1952 }; 1986 1953 EXPORT_SYMBOL(clk_alpha_pll_zonda_ops); 1954 + 1955 + static int alpha_pll_lucid_evo_enable(struct clk_hw *hw) 1956 + { 1957 + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); 1958 + struct regmap *regmap = pll->clkr.regmap; 1959 + u32 val; 1960 + int ret; 1961 + 1962 + ret = regmap_read(regmap, PLL_USER_CTL(pll), &val); 1963 + if (ret) 1964 + return ret; 1965 + 1966 + /* If in FSM mode, just vote for it */ 1967 + if (val & LUCID_EVO_ENABLE_VOTE_RUN) { 1968 + ret = clk_enable_regmap(hw); 1969 + if (ret) 1970 + return ret; 1971 + return wait_for_pll_enable_lock(pll); 1972 + } 1973 + 1974 + /* Check if PLL is already enabled */ 1975 + ret = trion_pll_is_enabled(pll, regmap); 1976 + if (ret < 0) { 1977 + return ret; 1978 + } else if (ret) { 1979 + pr_warn("%s PLL is already enabled\n", clk_hw_get_name(&pll->clkr.hw)); 1980 + return 0; 1981 + } 1982 + 1983 + ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N); 1984 + if (ret) 1985 + return ret; 1986 + 1987 + /* Set operation mode to RUN */ 1988 + regmap_write(regmap, PLL_OPMODE(pll), PLL_RUN); 1989 + 1990 + ret = wait_for_pll_enable_lock(pll); 1991 + if (ret) 1992 + return ret; 1993 + 1994 + /* Enable the PLL outputs */ 1995 + ret = regmap_update_bits(regmap, PLL_USER_CTL(pll), PLL_OUT_MASK, PLL_OUT_MASK); 1996 + if (ret) 1997 + return ret; 1998 + 1999 + /* Enable the global PLL outputs */ 2000 + ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, PLL_OUTCTRL); 2001 + if (ret) 2002 + return ret; 2003 + 2004 + /* Ensure that the write above goes through before returning. */ 2005 + mb(); 2006 + return ret; 2007 + } 2008 + 2009 + static void alpha_pll_lucid_evo_disable(struct clk_hw *hw) 2010 + { 2011 + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); 2012 + struct regmap *regmap = pll->clkr.regmap; 2013 + u32 val; 2014 + int ret; 2015 + 2016 + ret = regmap_read(regmap, PLL_USER_CTL(pll), &val); 2017 + if (ret) 2018 + return; 2019 + 2020 + /* If in FSM mode, just unvote it */ 2021 + if (val & LUCID_EVO_ENABLE_VOTE_RUN) { 2022 + clk_disable_regmap(hw); 2023 + return; 2024 + } 2025 + 2026 + /* Disable the global PLL output */ 2027 + ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0); 2028 + if (ret) 2029 + return; 2030 + 2031 + /* Disable the PLL outputs */ 2032 + ret = regmap_update_bits(regmap, PLL_USER_CTL(pll), PLL_OUT_MASK, 0); 2033 + if (ret) 2034 + return; 2035 + 2036 + /* Place the PLL mode in STANDBY */ 2037 + regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY); 2038 + } 2039 + 2040 + static unsigned long alpha_pll_lucid_evo_recalc_rate(struct clk_hw *hw, 2041 + unsigned long parent_rate) 2042 + { 2043 + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); 2044 + struct regmap *regmap = pll->clkr.regmap; 2045 + u32 l, frac; 2046 + 2047 + regmap_read(regmap, PLL_L_VAL(pll), &l); 2048 + l &= LUCID_EVO_PLL_L_VAL_MASK; 2049 + regmap_read(regmap, PLL_ALPHA_VAL(pll), &frac); 2050 + 2051 + return alpha_pll_calc_rate(parent_rate, l, frac, pll_alpha_width(pll)); 2052 + } 2053 + 2054 + static int clk_lucid_evo_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate, 2055 + unsigned long parent_rate) 2056 + { 2057 + return __clk_lucid_pll_postdiv_set_rate(hw, rate, parent_rate, LUCID_EVO_ENABLE_VOTE_RUN); 2058 + } 2059 + 2060 + const struct clk_ops clk_alpha_pll_fixed_lucid_evo_ops = { 2061 + .enable = alpha_pll_lucid_evo_enable, 2062 + .disable = alpha_pll_lucid_evo_disable, 2063 + .is_enabled = clk_trion_pll_is_enabled, 2064 + .recalc_rate = alpha_pll_lucid_evo_recalc_rate, 2065 + .round_rate = clk_alpha_pll_round_rate, 2066 + }; 2067 + EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_lucid_evo_ops); 2068 + 2069 + const struct clk_ops clk_alpha_pll_postdiv_lucid_evo_ops = { 2070 + .recalc_rate = clk_alpha_pll_postdiv_fabia_recalc_rate, 2071 + .round_rate = clk_alpha_pll_postdiv_fabia_round_rate, 2072 + .set_rate = clk_lucid_evo_pll_postdiv_set_rate, 2073 + }; 2074 + EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_lucid_evo_ops);
+3
drivers/clk/qcom/clk-alpha-pll.h
··· 17 17 CLK_ALPHA_PLL_TYPE_LUCID = CLK_ALPHA_PLL_TYPE_TRION, 18 18 CLK_ALPHA_PLL_TYPE_AGERA, 19 19 CLK_ALPHA_PLL_TYPE_ZONDA, 20 + CLK_ALPHA_PLL_TYPE_LUCID_EVO, 20 21 CLK_ALPHA_PLL_TYPE_MAX, 21 22 }; 22 23 ··· 152 151 153 152 extern const struct clk_ops clk_alpha_pll_zonda_ops; 154 153 #define clk_alpha_pll_postdiv_zonda_ops clk_alpha_pll_postdiv_fabia_ops 154 + extern const struct clk_ops clk_alpha_pll_fixed_lucid_evo_ops; 155 + extern const struct clk_ops clk_alpha_pll_postdiv_lucid_evo_ops; 155 156 156 157 void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, 157 158 const struct alpha_pll_config *config);