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

clk: qcom: clk-alpha-pll: add support for zonda pll

Ported over from the downstream driver. Will be used by SM8250 CAMCC.

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Link: https://lore.kernel.org/r/20210609022051.2171-2-jonathan@marek.ca
Signed-off-by: Stephen Boyd <sboyd@kernel.org>

authored by

Jonathan Marek and committed by
Stephen Boyd
f21b6bfe 652c96bb

+180
+174
drivers/clk/qcom/clk-alpha-pll.c
··· 126 126 [PLL_OFF_TEST_CTL_U] = 0x1c, 127 127 [PLL_OFF_STATUS] = 0x2c, 128 128 }, 129 + [CLK_ALPHA_PLL_TYPE_ZONDA] = { 130 + [PLL_OFF_L_VAL] = 0x04, 131 + [PLL_OFF_ALPHA_VAL] = 0x08, 132 + [PLL_OFF_USER_CTL] = 0x0c, 133 + [PLL_OFF_CONFIG_CTL] = 0x10, 134 + [PLL_OFF_CONFIG_CTL_U] = 0x14, 135 + [PLL_OFF_CONFIG_CTL_U1] = 0x18, 136 + [PLL_OFF_TEST_CTL] = 0x1c, 137 + [PLL_OFF_TEST_CTL_U] = 0x20, 138 + [PLL_OFF_TEST_CTL_U1] = 0x24, 139 + [PLL_OFF_OPMODE] = 0x28, 140 + [PLL_OFF_STATUS] = 0x38, 141 + }, 129 142 }; 130 143 EXPORT_SYMBOL_GPL(clk_alpha_pll_regs); 131 144 ··· 174 161 #define LUCID_5LPE_ALPHA_PLL_ACK_LATCH BIT(13) 175 162 #define LUCID_5LPE_PLL_LATCH_INPUT BIT(14) 176 163 #define LUCID_5LPE_ENABLE_VOTE_RUN BIT(21) 164 + 165 + /* ZONDA PLL specific */ 166 + #define ZONDA_PLL_OUT_MASK 0xf 167 + #define ZONDA_STAY_IN_CFA BIT(16) 168 + #define ZONDA_PLL_FREQ_LOCK_DET BIT(29) 177 169 178 170 #define pll_alpha_width(p) \ 179 171 ((PLL_ALPHA_VAL_U(p) - PLL_ALPHA_VAL(p) == 4) ? \ ··· 225 207 226 208 #define wait_for_pll_enable_lock(pll) \ 227 209 wait_for_pll(pll, PLL_LOCK_DET, 0, "enable") 210 + 211 + #define wait_for_zonda_pll_freq_lock(pll) \ 212 + wait_for_pll(pll, ZONDA_PLL_FREQ_LOCK_DET, 0, "freq enable") 228 213 229 214 #define wait_for_pll_disable(pll) \ 230 215 wait_for_pll(pll, PLL_ACTIVE_FLAG, 1, "disable") ··· 1798 1777 .set_rate = clk_lucid_5lpe_pll_postdiv_set_rate, 1799 1778 }; 1800 1779 EXPORT_SYMBOL(clk_alpha_pll_postdiv_lucid_5lpe_ops); 1780 + 1781 + void clk_zonda_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, 1782 + const struct alpha_pll_config *config) 1783 + { 1784 + clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l); 1785 + clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha); 1786 + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val); 1787 + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll), config->config_ctl_hi_val); 1788 + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll), config->config_ctl_hi1_val); 1789 + clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll), config->user_ctl_val); 1790 + clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll), config->user_ctl_hi_val); 1791 + clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U1(pll), config->user_ctl_hi1_val); 1792 + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll), config->test_ctl_val); 1793 + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll), config->test_ctl_hi_val); 1794 + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U1(pll), config->test_ctl_hi1_val); 1795 + 1796 + regmap_update_bits(regmap, PLL_MODE(pll), PLL_BYPASSNL, 0); 1797 + 1798 + /* Disable PLL output */ 1799 + regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0); 1800 + 1801 + /* Set operation mode to OFF */ 1802 + regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY); 1803 + 1804 + /* Place the PLL in STANDBY mode */ 1805 + regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N); 1806 + } 1807 + EXPORT_SYMBOL_GPL(clk_zonda_pll_configure); 1808 + 1809 + static int clk_zonda_pll_enable(struct clk_hw *hw) 1810 + { 1811 + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); 1812 + struct regmap *regmap = pll->clkr.regmap; 1813 + u32 val; 1814 + int ret; 1815 + 1816 + regmap_read(regmap, PLL_MODE(pll), &val); 1817 + 1818 + /* If in FSM mode, just vote for it */ 1819 + if (val & PLL_VOTE_FSM_ENA) { 1820 + ret = clk_enable_regmap(hw); 1821 + if (ret) 1822 + return ret; 1823 + return wait_for_pll_enable_active(pll); 1824 + } 1825 + 1826 + /* Get the PLL out of bypass mode */ 1827 + regmap_update_bits(regmap, PLL_MODE(pll), PLL_BYPASSNL, PLL_BYPASSNL); 1828 + 1829 + /* 1830 + * H/W requires a 1us delay between disabling the bypass and 1831 + * de-asserting the reset. 1832 + */ 1833 + udelay(1); 1834 + 1835 + regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N); 1836 + 1837 + /* Set operation mode to RUN */ 1838 + regmap_write(regmap, PLL_OPMODE(pll), PLL_RUN); 1839 + 1840 + regmap_read(regmap, PLL_TEST_CTL(pll), &val); 1841 + 1842 + /* If cfa mode then poll for freq lock */ 1843 + if (val & ZONDA_STAY_IN_CFA) 1844 + ret = wait_for_zonda_pll_freq_lock(pll); 1845 + else 1846 + ret = wait_for_pll_enable_lock(pll); 1847 + if (ret) 1848 + return ret; 1849 + 1850 + /* Enable the PLL outputs */ 1851 + regmap_update_bits(regmap, PLL_USER_CTL(pll), ZONDA_PLL_OUT_MASK, ZONDA_PLL_OUT_MASK); 1852 + 1853 + /* Enable the global PLL outputs */ 1854 + regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, PLL_OUTCTRL); 1855 + 1856 + return 0; 1857 + } 1858 + 1859 + static void clk_zonda_pll_disable(struct clk_hw *hw) 1860 + { 1861 + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); 1862 + struct regmap *regmap = pll->clkr.regmap; 1863 + u32 val; 1864 + 1865 + regmap_read(regmap, PLL_MODE(pll), &val); 1866 + 1867 + /* If in FSM mode, just unvote it */ 1868 + if (val & PLL_VOTE_FSM_ENA) { 1869 + clk_disable_regmap(hw); 1870 + return; 1871 + } 1872 + 1873 + /* Disable the global PLL output */ 1874 + regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0); 1875 + 1876 + /* Disable the PLL outputs */ 1877 + regmap_update_bits(regmap, PLL_USER_CTL(pll), ZONDA_PLL_OUT_MASK, 0); 1878 + 1879 + /* Put the PLL in bypass and reset */ 1880 + regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N | PLL_BYPASSNL, 0); 1881 + 1882 + /* Place the PLL mode in OFF state */ 1883 + regmap_write(regmap, PLL_OPMODE(pll), 0x0); 1884 + } 1885 + 1886 + static int clk_zonda_pll_set_rate(struct clk_hw *hw, unsigned long rate, 1887 + unsigned long prate) 1888 + { 1889 + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); 1890 + unsigned long rrate; 1891 + u32 test_ctl_val; 1892 + u32 l, alpha_width = pll_alpha_width(pll); 1893 + u64 a; 1894 + int ret; 1895 + 1896 + rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width); 1897 + 1898 + ret = alpha_pll_check_rate_margin(hw, rrate, rate); 1899 + if (ret < 0) 1900 + return ret; 1901 + 1902 + regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a); 1903 + regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l); 1904 + 1905 + /* Wait before polling for the frequency latch */ 1906 + udelay(5); 1907 + 1908 + /* Read stay in cfa mode */ 1909 + regmap_read(pll->clkr.regmap, PLL_TEST_CTL(pll), &test_ctl_val); 1910 + 1911 + /* If cfa mode then poll for freq lock */ 1912 + if (test_ctl_val & ZONDA_STAY_IN_CFA) 1913 + ret = wait_for_zonda_pll_freq_lock(pll); 1914 + else 1915 + ret = wait_for_pll_enable_lock(pll); 1916 + if (ret) 1917 + return ret; 1918 + 1919 + /* Wait for PLL output to stabilize */ 1920 + udelay(100); 1921 + return 0; 1922 + } 1923 + 1924 + const struct clk_ops clk_alpha_pll_zonda_ops = { 1925 + .enable = clk_zonda_pll_enable, 1926 + .disable = clk_zonda_pll_disable, 1927 + .is_enabled = clk_trion_pll_is_enabled, 1928 + .recalc_rate = clk_trion_pll_recalc_rate, 1929 + .round_rate = clk_alpha_pll_round_rate, 1930 + .set_rate = clk_zonda_pll_set_rate, 1931 + }; 1932 + EXPORT_SYMBOL(clk_alpha_pll_zonda_ops);
+6
drivers/clk/qcom/clk-alpha-pll.h
··· 16 16 CLK_ALPHA_PLL_TYPE_TRION, 17 17 CLK_ALPHA_PLL_TYPE_LUCID = CLK_ALPHA_PLL_TYPE_TRION, 18 18 CLK_ALPHA_PLL_TYPE_AGERA, 19 + CLK_ALPHA_PLL_TYPE_ZONDA, 19 20 CLK_ALPHA_PLL_TYPE_MAX, 20 21 }; 21 22 ··· 149 148 extern const struct clk_ops clk_alpha_pll_fixed_lucid_5lpe_ops; 150 149 extern const struct clk_ops clk_alpha_pll_postdiv_lucid_5lpe_ops; 151 150 151 + extern const struct clk_ops clk_alpha_pll_zonda_ops; 152 + #define clk_alpha_pll_postdiv_zonda_ops clk_alpha_pll_postdiv_fabia_ops 153 + 152 154 void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, 153 155 const struct alpha_pll_config *config); 154 156 void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, ··· 163 159 #define clk_lucid_pll_configure(pll, regmap, config) \ 164 160 clk_trion_pll_configure(pll, regmap, config) 165 161 162 + void clk_zonda_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, 163 + const struct alpha_pll_config *config); 166 164 167 165 168 166 #endif