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>
@@ -139,6 +140,20 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = {
139
140
[PLL_OFF_OPMODE ] = 0x28 ,
140
141
[PLL_OFF_STATUS ] = 0x38 ,
141
142
},
143
+ [CLK_ALPHA_PLL_TYPE_LUCID_EVO ] = {
144
+ [PLL_OFF_OPMODE ] = 0x04 ,
145
+ [PLL_OFF_STATUS ] = 0x0c ,
146
+ [PLL_OFF_L_VAL ] = 0x10 ,
147
+ [PLL_OFF_ALPHA_VAL ] = 0x14 ,
148
+ [PLL_OFF_USER_CTL ] = 0x18 ,
149
+ [PLL_OFF_USER_CTL_U ] = 0x1c ,
150
+ [PLL_OFF_CONFIG_CTL ] = 0x20 ,
151
+ [PLL_OFF_CONFIG_CTL_U ] = 0x24 ,
152
+ [PLL_OFF_CONFIG_CTL_U1 ] = 0x28 ,
153
+ [PLL_OFF_TEST_CTL ] = 0x2c ,
154
+ [PLL_OFF_TEST_CTL_U ] = 0x30 ,
155
+ [PLL_OFF_TEST_CTL_U1 ] = 0x34 ,
156
+ },
142
157
};
143
158
EXPORT_SYMBOL_GPL (clk_alpha_pll_regs );
144
159
@@ -175,6 +190,10 @@ EXPORT_SYMBOL_GPL(clk_alpha_pll_regs);
175
190
#define LUCID_5LPE_PLL_LATCH_INPUT BIT(14)
176
191
#define LUCID_5LPE_ENABLE_VOTE_RUN BIT(21)
177
192
193
+ /* LUCID EVO PLL specific settings and offsets */
194
+ #define LUCID_EVO_ENABLE_VOTE_RUN BIT(25)
195
+ #define LUCID_EVO_PLL_L_VAL_MASK GENMASK(15, 0)
196
+
178
197
/* ZONDA PLL specific */
179
198
#define ZONDA_PLL_OUT_MASK 0xf
180
199
#define ZONDA_STAY_IN_CFA BIT(16)
@@ -1741,24 +1760,32 @@ static int alpha_pll_lucid_5lpe_set_rate(struct clk_hw *hw, unsigned long rate,
1741
1760
LUCID_5LPE_ALPHA_PLL_ACK_LATCH );
1742
1761
}
1743
1762
1744
- static int clk_lucid_5lpe_pll_postdiv_set_rate (struct clk_hw * hw , unsigned long rate ,
1745
- unsigned long parent_rate )
1763
+ static int __clk_lucid_pll_postdiv_set_rate (struct clk_hw * hw , unsigned long rate ,
1764
+ unsigned long parent_rate ,
1765
+ unsigned long enable_vote_run )
1746
1766
{
1747
1767
struct clk_alpha_pll_postdiv * pll = to_clk_alpha_pll_postdiv (hw );
1748
- int i , val = 0 , div , ret ;
1768
+ struct regmap * regmap = pll -> clkr .regmap ;
1769
+ int i , val , div , ret ;
1749
1770
u32 mask ;
1750
1771
1751
1772
/*
1752
1773
* If the PLL is in FSM mode, then treat set_rate callback as a
1753
1774
* no-operation.
1754
1775
*/
1755
- ret = regmap_read (pll -> clkr . regmap , PLL_USER_CTL (pll ), & val );
1776
+ ret = regmap_read (regmap , PLL_USER_CTL (pll ), & val );
1756
1777
if (ret )
1757
1778
return ret ;
1758
1779
1759
- if (val & LUCID_5LPE_ENABLE_VOTE_RUN )
1780
+ if (val & enable_vote_run )
1760
1781
return 0 ;
1761
1782
1783
+ if (!pll -> post_div_table ) {
1784
+ pr_err ("Missing the post_div_table for the %s PLL\n" ,
1785
+ clk_hw_get_name (& pll -> clkr .hw ));
1786
+ return - EINVAL ;
1787
+ }
1788
+
1762
1789
div = DIV_ROUND_UP_ULL ((u64 )parent_rate , rate );
1763
1790
for (i = 0 ; i < pll -> num_post_div ; i ++ ) {
1764
1791
if (pll -> post_div_table [i ].div == div ) {
@@ -1772,6 +1799,12 @@ static int clk_lucid_5lpe_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long
1772
1799
mask , val << pll -> post_div_shift );
1773
1800
}
1774
1801
1802
+ static int clk_lucid_5lpe_pll_postdiv_set_rate (struct clk_hw * hw , unsigned long rate ,
1803
+ unsigned long parent_rate )
1804
+ {
1805
+ return __clk_lucid_pll_postdiv_set_rate (hw , rate , parent_rate , LUCID_5LPE_ENABLE_VOTE_RUN );
1806
+ }
1807
+
1775
1808
const struct clk_ops clk_alpha_pll_lucid_5lpe_ops = {
1776
1809
.prepare = alpha_pll_lucid_5lpe_prepare ,
1777
1810
.enable = alpha_pll_lucid_5lpe_enable ,
@@ -1951,3 +1984,124 @@ const struct clk_ops clk_alpha_pll_zonda_ops = {
1951
1984
.set_rate = clk_zonda_pll_set_rate ,
1952
1985
};
1953
1986
EXPORT_SYMBOL (clk_alpha_pll_zonda_ops );
1987
+
1988
+ static int alpha_pll_lucid_evo_enable (struct clk_hw * hw )
1989
+ {
1990
+ struct clk_alpha_pll * pll = to_clk_alpha_pll (hw );
1991
+ struct regmap * regmap = pll -> clkr .regmap ;
1992
+ u32 val ;
1993
+ int ret ;
1994
+
1995
+ ret = regmap_read (regmap , PLL_USER_CTL (pll ), & val );
1996
+ if (ret )
1997
+ return ret ;
1998
+
1999
+ /* If in FSM mode, just vote for it */
2000
+ if (val & LUCID_EVO_ENABLE_VOTE_RUN ) {
2001
+ ret = clk_enable_regmap (hw );
2002
+ if (ret )
2003
+ return ret ;
2004
+ return wait_for_pll_enable_lock (pll );
2005
+ }
2006
+
2007
+ /* Check if PLL is already enabled */
2008
+ ret = trion_pll_is_enabled (pll , regmap );
2009
+ if (ret < 0 ) {
2010
+ return ret ;
2011
+ } else if (ret ) {
2012
+ pr_warn ("%s PLL is already enabled\n" , clk_hw_get_name (& pll -> clkr .hw ));
2013
+ return 0 ;
2014
+ }
2015
+
2016
+ ret = regmap_update_bits (regmap , PLL_MODE (pll ), PLL_RESET_N , PLL_RESET_N );
2017
+ if (ret )
2018
+ return ret ;
2019
+
2020
+ /* Set operation mode to RUN */
2021
+ regmap_write (regmap , PLL_OPMODE (pll ), PLL_RUN );
2022
+
2023
+ ret = wait_for_pll_enable_lock (pll );
2024
+ if (ret )
2025
+ return ret ;
2026
+
2027
+ /* Enable the PLL outputs */
2028
+ ret = regmap_update_bits (regmap , PLL_USER_CTL (pll ), PLL_OUT_MASK , PLL_OUT_MASK );
2029
+ if (ret )
2030
+ return ret ;
2031
+
2032
+ /* Enable the global PLL outputs */
2033
+ ret = regmap_update_bits (regmap , PLL_MODE (pll ), PLL_OUTCTRL , PLL_OUTCTRL );
2034
+ if (ret )
2035
+ return ret ;
2036
+
2037
+ /* Ensure that the write above goes through before returning. */
2038
+ mb ();
2039
+ return ret ;
2040
+ }
2041
+
2042
+ static void alpha_pll_lucid_evo_disable (struct clk_hw * hw )
2043
+ {
2044
+ struct clk_alpha_pll * pll = to_clk_alpha_pll (hw );
2045
+ struct regmap * regmap = pll -> clkr .regmap ;
2046
+ u32 val ;
2047
+ int ret ;
2048
+
2049
+ ret = regmap_read (regmap , PLL_USER_CTL (pll ), & val );
2050
+ if (ret )
2051
+ return ;
2052
+
2053
+ /* If in FSM mode, just unvote it */
2054
+ if (val & LUCID_EVO_ENABLE_VOTE_RUN ) {
2055
+ clk_disable_regmap (hw );
2056
+ return ;
2057
+ }
2058
+
2059
+ /* Disable the global PLL output */
2060
+ ret = regmap_update_bits (regmap , PLL_MODE (pll ), PLL_OUTCTRL , 0 );
2061
+ if (ret )
2062
+ return ;
2063
+
2064
+ /* Disable the PLL outputs */
2065
+ ret = regmap_update_bits (regmap , PLL_USER_CTL (pll ), PLL_OUT_MASK , 0 );
2066
+ if (ret )
2067
+ return ;
2068
+
2069
+ /* Place the PLL mode in STANDBY */
2070
+ regmap_write (regmap , PLL_OPMODE (pll ), PLL_STANDBY );
2071
+ }
2072
+
2073
+ static unsigned long alpha_pll_lucid_evo_recalc_rate (struct clk_hw * hw ,
2074
+ unsigned long parent_rate )
2075
+ {
2076
+ struct clk_alpha_pll * pll = to_clk_alpha_pll (hw );
2077
+ struct regmap * regmap = pll -> clkr .regmap ;
2078
+ u32 l , frac ;
2079
+
2080
+ regmap_read (regmap , PLL_L_VAL (pll ), & l );
2081
+ l &= LUCID_EVO_PLL_L_VAL_MASK ;
2082
+ regmap_read (regmap , PLL_ALPHA_VAL (pll ), & frac );
2083
+
2084
+ return alpha_pll_calc_rate (parent_rate , l , frac , pll_alpha_width (pll ));
2085
+ }
2086
+
2087
+ static int clk_lucid_evo_pll_postdiv_set_rate (struct clk_hw * hw , unsigned long rate ,
2088
+ unsigned long parent_rate )
2089
+ {
2090
+ return __clk_lucid_pll_postdiv_set_rate (hw , rate , parent_rate , LUCID_EVO_ENABLE_VOTE_RUN );
2091
+ }
2092
+
2093
+ const struct clk_ops clk_alpha_pll_fixed_lucid_evo_ops = {
2094
+ .enable = alpha_pll_lucid_evo_enable ,
2095
+ .disable = alpha_pll_lucid_evo_disable ,
2096
+ .is_enabled = clk_trion_pll_is_enabled ,
2097
+ .recalc_rate = alpha_pll_lucid_evo_recalc_rate ,
2098
+ .round_rate = clk_alpha_pll_round_rate ,
2099
+ };
2100
+ EXPORT_SYMBOL_GPL (clk_alpha_pll_fixed_lucid_evo_ops );
2101
+
2102
+ const struct clk_ops clk_alpha_pll_postdiv_lucid_evo_ops = {
2103
+ .recalc_rate = clk_alpha_pll_postdiv_fabia_recalc_rate ,
2104
+ .round_rate = clk_alpha_pll_postdiv_fabia_round_rate ,
2105
+ .set_rate = clk_lucid_evo_pll_postdiv_set_rate ,
2106
+ };
2107
+ EXPORT_SYMBOL_GPL (clk_alpha_pll_postdiv_lucid_evo_ops );
0 commit comments