hc
2024-01-05 071106ecf68c401173c58808b1cf5f68cc50d390
kernel/drivers/clk/qcom/clk-alpha-pll.c
....@@ -32,6 +32,7 @@
3232 # define PLL_LOCK_DET BIT(31)
3333
3434 #define PLL_L_VAL(p) ((p)->offset + (p)->regs[PLL_OFF_L_VAL])
35
+#define PLL_CAL_L_VAL(p) ((p)->offset + (p)->regs[PLL_OFF_CAL_L_VAL])
3536 #define PLL_ALPHA_VAL(p) ((p)->offset + (p)->regs[PLL_OFF_ALPHA_VAL])
3637 #define PLL_ALPHA_VAL_U(p) ((p)->offset + (p)->regs[PLL_OFF_ALPHA_VAL_U])
3738
....@@ -44,11 +45,14 @@
4445 # define PLL_VCO_MASK 0x3
4546
4647 #define PLL_USER_CTL_U(p) ((p)->offset + (p)->regs[PLL_OFF_USER_CTL_U])
48
+#define PLL_USER_CTL_U1(p) ((p)->offset + (p)->regs[PLL_OFF_USER_CTL_U1])
4749
4850 #define PLL_CONFIG_CTL(p) ((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL])
4951 #define PLL_CONFIG_CTL_U(p) ((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL_U])
52
+#define PLL_CONFIG_CTL_U1(p) ((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL_U1])
5053 #define PLL_TEST_CTL(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL])
5154 #define PLL_TEST_CTL_U(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U])
55
+#define PLL_TEST_CTL_U1(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U1])
5256 #define PLL_STATUS(p) ((p)->offset + (p)->regs[PLL_OFF_STATUS])
5357 #define PLL_OPMODE(p) ((p)->offset + (p)->regs[PLL_OFF_OPMODE])
5458 #define PLL_FRAC(p) ((p)->offset + (p)->regs[PLL_OFF_FRAC])
....@@ -96,6 +100,22 @@
96100 [PLL_OFF_OPMODE] = 0x2c,
97101 [PLL_OFF_FRAC] = 0x38,
98102 },
103
+ [CLK_ALPHA_PLL_TYPE_TRION] = {
104
+ [PLL_OFF_L_VAL] = 0x04,
105
+ [PLL_OFF_CAL_L_VAL] = 0x08,
106
+ [PLL_OFF_USER_CTL] = 0x0c,
107
+ [PLL_OFF_USER_CTL_U] = 0x10,
108
+ [PLL_OFF_USER_CTL_U1] = 0x14,
109
+ [PLL_OFF_CONFIG_CTL] = 0x18,
110
+ [PLL_OFF_CONFIG_CTL_U] = 0x1c,
111
+ [PLL_OFF_CONFIG_CTL_U1] = 0x20,
112
+ [PLL_OFF_TEST_CTL] = 0x24,
113
+ [PLL_OFF_TEST_CTL_U] = 0x28,
114
+ [PLL_OFF_TEST_CTL_U1] = 0x2c,
115
+ [PLL_OFF_STATUS] = 0x30,
116
+ [PLL_OFF_OPMODE] = 0x38,
117
+ [PLL_OFF_ALPHA_VAL] = 0x40,
118
+ },
99119 };
100120 EXPORT_SYMBOL_GPL(clk_alpha_pll_regs);
101121
....@@ -114,11 +134,17 @@
114134 #define PLL_HUAYRA_N_MASK 0xff
115135 #define PLL_HUAYRA_ALPHA_WIDTH 16
116136
117
-#define FABIA_OPMODE_STANDBY 0x0
118
-#define FABIA_OPMODE_RUN 0x1
137
+#define PLL_STANDBY 0x0
138
+#define PLL_RUN 0x1
139
+#define PLL_OUT_MASK 0x7
140
+#define PLL_RATE_MARGIN 500
119141
120
-#define FABIA_PLL_OUT_MASK 0x7
121
-#define FABIA_PLL_RATE_MARGIN 500
142
+/* TRION PLL specific settings and offsets */
143
+#define TRION_PLL_CAL_VAL 0x44
144
+#define TRION_PCAL_DONE BIT(26)
145
+
146
+/* LUCID PLL specific settings and offsets */
147
+#define LUCID_PCAL_DONE BIT(27)
122148
123149 #define pll_alpha_width(p) \
124150 ((PLL_ALPHA_VAL_U(p) - PLL_ALPHA_VAL(p) == 4) ? \
....@@ -220,6 +246,7 @@
220246 if (pll->flags & SUPPORTS_FSM_MODE)
221247 qcom_pll_set_fsm_mode(regmap, PLL_MODE(pll), 6, 0);
222248 }
249
+EXPORT_SYMBOL_GPL(clk_alpha_pll_configure);
223250
224251 static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)
225252 {
....@@ -519,7 +546,8 @@
519546 rate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);
520547 vco = alpha_pll_find_vco(pll, rate);
521548 if (pll->vco_table && !vco) {
522
- pr_err("alpha pll not in a valid vco range\n");
549
+ pr_err("%s: alpha pll not in a valid vco range\n",
550
+ clk_hw_get_name(hw));
523551 return -EINVAL;
524552 }
525553
....@@ -581,7 +609,7 @@
581609 alpha_huayra_pll_calc_rate(u64 prate, u32 l, u32 a)
582610 {
583611 /*
584
- * a contains 16 bit alpha_val in two’s compliment number in the range
612
+ * a contains 16 bit alpha_val in two’s complement number in the range
585613 * of [-0.5, 0.5).
586614 */
587615 if (a >= BIT(PLL_HUAYRA_ALPHA_WIDTH - 1))
....@@ -613,7 +641,7 @@
613641 quotient++;
614642
615643 /*
616
- * alpha_val should be in two’s compliment number in the range
644
+ * alpha_val should be in two’s complement number in the range
617645 * of [-0.5, 0.5) so if quotient >= 0.5 then increment the l value
618646 * since alpha value will be subtracted in this case.
619647 */
....@@ -638,7 +666,7 @@
638666 regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &alpha);
639667 /*
640668 * Depending upon alpha_mode, it can be treated as M/N value or
641
- * as a two’s compliment number. When alpha_mode=1,
669
+ * as a two’s complement number. When alpha_mode=1,
642670 * pll_alpha_val<15:8>=M and pll_apla_val<7:0>=N
643671 *
644672 * Fout=FIN*(L+(M/N))
....@@ -646,12 +674,12 @@
646674 * M is a signed number (-128 to 127) and N is unsigned
647675 * (0 to 255). M/N has to be within +/-0.5.
648676 *
649
- * When alpha_mode=0, it is a two’s compliment number in the
677
+ * When alpha_mode=0, it is a two’s complement number in the
650678 * range [-0.5, 0.5).
651679 *
652680 * Fout=FIN*(L+(alpha_val)/2^16)
653681 *
654
- * where alpha_val is two’s compliment number.
682
+ * where alpha_val is two’s complement number.
655683 */
656684 if (!(ctl & PLL_ALPHA_MODE))
657685 return alpha_huayra_pll_calc_rate(rate, l, alpha);
....@@ -697,7 +725,7 @@
697725 */
698726 if (clk_alpha_pll_is_enabled(hw)) {
699727 if (cur_alpha != a) {
700
- pr_err("clock needs to be gated %s\n",
728
+ pr_err("%s: clock needs to be gated\n",
701729 clk_hw_get_name(hw));
702730 return -EBUSY;
703731 }
....@@ -729,6 +757,117 @@
729757 return alpha_huayra_pll_round_rate(rate, *prate, &l, &a);
730758 }
731759
760
+static int trion_pll_is_enabled(struct clk_alpha_pll *pll,
761
+ struct regmap *regmap)
762
+{
763
+ u32 mode_regval, opmode_regval;
764
+ int ret;
765
+
766
+ ret = regmap_read(regmap, PLL_MODE(pll), &mode_regval);
767
+ ret |= regmap_read(regmap, PLL_OPMODE(pll), &opmode_regval);
768
+ if (ret)
769
+ return 0;
770
+
771
+ return ((opmode_regval & PLL_RUN) && (mode_regval & PLL_OUTCTRL));
772
+}
773
+
774
+static int clk_trion_pll_is_enabled(struct clk_hw *hw)
775
+{
776
+ struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
777
+
778
+ return trion_pll_is_enabled(pll, pll->clkr.regmap);
779
+}
780
+
781
+static int clk_trion_pll_enable(struct clk_hw *hw)
782
+{
783
+ struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
784
+ struct regmap *regmap = pll->clkr.regmap;
785
+ u32 val;
786
+ int ret;
787
+
788
+ ret = regmap_read(regmap, PLL_MODE(pll), &val);
789
+ if (ret)
790
+ return ret;
791
+
792
+ /* If in FSM mode, just vote for it */
793
+ if (val & PLL_VOTE_FSM_ENA) {
794
+ ret = clk_enable_regmap(hw);
795
+ if (ret)
796
+ return ret;
797
+ return wait_for_pll_enable_active(pll);
798
+ }
799
+
800
+ /* Set operation mode to RUN */
801
+ regmap_write(regmap, PLL_OPMODE(pll), PLL_RUN);
802
+
803
+ ret = wait_for_pll_enable_lock(pll);
804
+ if (ret)
805
+ return ret;
806
+
807
+ /* Enable the PLL outputs */
808
+ ret = regmap_update_bits(regmap, PLL_USER_CTL(pll),
809
+ PLL_OUT_MASK, PLL_OUT_MASK);
810
+ if (ret)
811
+ return ret;
812
+
813
+ /* Enable the global PLL outputs */
814
+ return regmap_update_bits(regmap, PLL_MODE(pll),
815
+ PLL_OUTCTRL, PLL_OUTCTRL);
816
+}
817
+
818
+static void clk_trion_pll_disable(struct clk_hw *hw)
819
+{
820
+ struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
821
+ struct regmap *regmap = pll->clkr.regmap;
822
+ u32 val;
823
+ int ret;
824
+
825
+ ret = regmap_read(regmap, PLL_MODE(pll), &val);
826
+ if (ret)
827
+ return;
828
+
829
+ /* If in FSM mode, just unvote it */
830
+ if (val & PLL_VOTE_FSM_ENA) {
831
+ clk_disable_regmap(hw);
832
+ return;
833
+ }
834
+
835
+ /* Disable the global PLL output */
836
+ ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0);
837
+ if (ret)
838
+ return;
839
+
840
+ /* Disable the PLL outputs */
841
+ ret = regmap_update_bits(regmap, PLL_USER_CTL(pll),
842
+ PLL_OUT_MASK, 0);
843
+ if (ret)
844
+ return;
845
+
846
+ /* Place the PLL mode in STANDBY */
847
+ regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);
848
+ regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);
849
+}
850
+
851
+static unsigned long
852
+clk_trion_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
853
+{
854
+ struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
855
+ u32 l, frac, alpha_width = pll_alpha_width(pll);
856
+
857
+ regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l);
858
+ regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &frac);
859
+
860
+ return alpha_pll_calc_rate(parent_rate, l, frac, alpha_width);
861
+}
862
+
863
+const struct clk_ops clk_alpha_pll_fixed_ops = {
864
+ .enable = clk_alpha_pll_enable,
865
+ .disable = clk_alpha_pll_disable,
866
+ .is_enabled = clk_alpha_pll_is_enabled,
867
+ .recalc_rate = clk_alpha_pll_recalc_rate,
868
+};
869
+EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_ops);
870
+
732871 const struct clk_ops clk_alpha_pll_ops = {
733872 .enable = clk_alpha_pll_enable,
734873 .disable = clk_alpha_pll_disable,
....@@ -758,6 +897,15 @@
758897 .set_rate = clk_alpha_pll_hwfsm_set_rate,
759898 };
760899 EXPORT_SYMBOL_GPL(clk_alpha_pll_hwfsm_ops);
900
+
901
+const struct clk_ops clk_alpha_pll_fixed_trion_ops = {
902
+ .enable = clk_trion_pll_enable,
903
+ .disable = clk_trion_pll_disable,
904
+ .is_enabled = clk_trion_pll_is_enabled,
905
+ .recalc_rate = clk_trion_pll_recalc_rate,
906
+ .round_rate = clk_alpha_pll_round_rate,
907
+};
908
+EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_trion_ops);
761909
762910 static unsigned long
763911 clk_alpha_pll_postdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
....@@ -831,7 +979,7 @@
831979 int div;
832980
833981 /* 16 -> 0xf, 8 -> 0x7, 4 -> 0x3, 2 -> 0x1, 1 -> 0x0 */
834
- div = DIV_ROUND_UP_ULL((u64)parent_rate, rate) - 1;
982
+ div = DIV_ROUND_UP_ULL(parent_rate, rate) - 1;
835983
836984 return regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll),
837985 PLL_POST_DIV_MASK(pll) << PLL_POST_DIV_SHIFT,
....@@ -865,6 +1013,25 @@
8651013 if (config->config_ctl_val)
8661014 regmap_write(regmap, PLL_CONFIG_CTL(pll),
8671015 config->config_ctl_val);
1016
+
1017
+ if (config->config_ctl_hi_val)
1018
+ regmap_write(regmap, PLL_CONFIG_CTL_U(pll),
1019
+ config->config_ctl_hi_val);
1020
+
1021
+ if (config->user_ctl_val)
1022
+ regmap_write(regmap, PLL_USER_CTL(pll), config->user_ctl_val);
1023
+
1024
+ if (config->user_ctl_hi_val)
1025
+ regmap_write(regmap, PLL_USER_CTL_U(pll),
1026
+ config->user_ctl_hi_val);
1027
+
1028
+ if (config->test_ctl_val)
1029
+ regmap_write(regmap, PLL_TEST_CTL(pll),
1030
+ config->test_ctl_val);
1031
+
1032
+ if (config->test_ctl_hi_val)
1033
+ regmap_write(regmap, PLL_TEST_CTL_U(pll),
1034
+ config->test_ctl_hi_val);
8681035
8691036 if (config->post_div_mask) {
8701037 mask = config->post_div_mask;
....@@ -903,14 +1070,14 @@
9031070 return ret;
9041071
9051072 /* Skip If PLL is already running */
906
- if ((opmode_val & FABIA_OPMODE_RUN) && (val & PLL_OUTCTRL))
1073
+ if ((opmode_val & PLL_RUN) && (val & PLL_OUTCTRL))
9071074 return 0;
9081075
9091076 ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0);
9101077 if (ret)
9111078 return ret;
9121079
913
- ret = regmap_write(regmap, PLL_OPMODE(pll), FABIA_OPMODE_STANDBY);
1080
+ ret = regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);
9141081 if (ret)
9151082 return ret;
9161083
....@@ -919,7 +1086,7 @@
9191086 if (ret)
9201087 return ret;
9211088
922
- ret = regmap_write(regmap, PLL_OPMODE(pll), FABIA_OPMODE_RUN);
1089
+ ret = regmap_write(regmap, PLL_OPMODE(pll), PLL_RUN);
9231090 if (ret)
9241091 return ret;
9251092
....@@ -928,7 +1095,7 @@
9281095 return ret;
9291096
9301097 ret = regmap_update_bits(regmap, PLL_USER_CTL(pll),
931
- FABIA_PLL_OUT_MASK, FABIA_PLL_OUT_MASK);
1098
+ PLL_OUT_MASK, PLL_OUT_MASK);
9321099 if (ret)
9331100 return ret;
9341101
....@@ -958,13 +1125,12 @@
9581125 return;
9591126
9601127 /* Disable main outputs */
961
- ret = regmap_update_bits(regmap, PLL_USER_CTL(pll), FABIA_PLL_OUT_MASK,
962
- 0);
1128
+ ret = regmap_update_bits(regmap, PLL_USER_CTL(pll), PLL_OUT_MASK, 0);
9631129 if (ret)
9641130 return;
9651131
9661132 /* Place the PLL in STANDBY */
967
- regmap_write(regmap, PLL_OPMODE(pll), FABIA_OPMODE_STANDBY);
1133
+ regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);
9681134 }
9691135
9701136 static unsigned long alpha_pll_fabia_recalc_rate(struct clk_hw *hw,
....@@ -983,14 +1149,9 @@
9831149 unsigned long prate)
9841150 {
9851151 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
986
- u32 val, l, alpha_width = pll_alpha_width(pll);
1152
+ u32 l, alpha_width = pll_alpha_width(pll);
9871153 u64 a;
988
- unsigned long rrate;
989
- int ret = 0;
990
-
991
- ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
992
- if (ret)
993
- return ret;
1154
+ unsigned long rrate, max = rate + PLL_RATE_MARGIN;
9941155
9951156 rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);
9961157
....@@ -998,8 +1159,9 @@
9981159 * Due to limited number of bits for fractional rate programming, the
9991160 * rounded up rate could be marginally higher than the requested rate.
10001161 */
1001
- if (rrate > (rate + FABIA_PLL_RATE_MARGIN) || rrate < rate) {
1002
- pr_err("Call set rate on the PLL with rounded rates!\n");
1162
+ if (rrate > (rate + PLL_RATE_MARGIN) || rrate < rate) {
1163
+ pr_err("%s: Rounded rate %lu not within range [%lu, %lu)\n",
1164
+ clk_hw_get_name(hw), rrate, rate, max);
10031165 return -EINVAL;
10041166 }
10051167
....@@ -1009,7 +1171,65 @@
10091171 return __clk_alpha_pll_update_latch(pll);
10101172 }
10111173
1174
+static int alpha_pll_fabia_prepare(struct clk_hw *hw)
1175
+{
1176
+ struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
1177
+ const struct pll_vco *vco;
1178
+ struct clk_hw *parent_hw;
1179
+ unsigned long cal_freq, rrate;
1180
+ u32 cal_l, val, alpha_width = pll_alpha_width(pll);
1181
+ const char *name = clk_hw_get_name(hw);
1182
+ u64 a;
1183
+ int ret;
1184
+
1185
+ /* Check if calibration needs to be done i.e. PLL is in reset */
1186
+ ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
1187
+ if (ret)
1188
+ return ret;
1189
+
1190
+ /* Return early if calibration is not needed. */
1191
+ if (val & PLL_RESET_N)
1192
+ return 0;
1193
+
1194
+ vco = alpha_pll_find_vco(pll, clk_hw_get_rate(hw));
1195
+ if (!vco) {
1196
+ pr_err("%s: alpha pll not in a valid vco range\n", name);
1197
+ return -EINVAL;
1198
+ }
1199
+
1200
+ cal_freq = DIV_ROUND_CLOSEST((pll->vco_table[0].min_freq +
1201
+ pll->vco_table[0].max_freq) * 54, 100);
1202
+
1203
+ parent_hw = clk_hw_get_parent(hw);
1204
+ if (!parent_hw)
1205
+ return -EINVAL;
1206
+
1207
+ rrate = alpha_pll_round_rate(cal_freq, clk_hw_get_rate(parent_hw),
1208
+ &cal_l, &a, alpha_width);
1209
+ /*
1210
+ * Due to a limited number of bits for fractional rate programming, the
1211
+ * rounded up rate could be marginally higher than the requested rate.
1212
+ */
1213
+ if (rrate > (cal_freq + PLL_RATE_MARGIN) || rrate < cal_freq)
1214
+ return -EINVAL;
1215
+
1216
+ /* Setup PLL for calibration frequency */
1217
+ regmap_write(pll->clkr.regmap, PLL_CAL_L_VAL(pll), cal_l);
1218
+
1219
+ /* Bringup the PLL at calibration frequency */
1220
+ ret = clk_alpha_pll_enable(hw);
1221
+ if (ret) {
1222
+ pr_err("%s: alpha pll calibration failed\n", name);
1223
+ return ret;
1224
+ }
1225
+
1226
+ clk_alpha_pll_disable(hw);
1227
+
1228
+ return 0;
1229
+}
1230
+
10121231 const struct clk_ops clk_alpha_pll_fabia_ops = {
1232
+ .prepare = alpha_pll_fabia_prepare,
10131233 .enable = alpha_pll_fabia_enable,
10141234 .disable = alpha_pll_fabia_disable,
10151235 .is_enabled = clk_alpha_pll_is_enabled,
....@@ -1035,11 +1255,6 @@
10351255 u32 i, div = 1, val;
10361256 int ret;
10371257
1038
- if (!pll->post_div_table) {
1039
- pr_err("Missing the post_div_table for the PLL\n");
1040
- return -EINVAL;
1041
- }
1042
-
10431258 ret = regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &val);
10441259 if (ret)
10451260 return ret;
....@@ -1057,15 +1272,70 @@
10571272 return (parent_rate / div);
10581273 }
10591274
1275
+static unsigned long
1276
+clk_trion_pll_postdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
1277
+{
1278
+ struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
1279
+ struct regmap *regmap = pll->clkr.regmap;
1280
+ u32 i, div = 1, val;
1281
+
1282
+ regmap_read(regmap, PLL_USER_CTL(pll), &val);
1283
+
1284
+ val >>= pll->post_div_shift;
1285
+ val &= PLL_POST_DIV_MASK(pll);
1286
+
1287
+ for (i = 0; i < pll->num_post_div; i++) {
1288
+ if (pll->post_div_table[i].val == val) {
1289
+ div = pll->post_div_table[i].div;
1290
+ break;
1291
+ }
1292
+ }
1293
+
1294
+ return (parent_rate / div);
1295
+}
1296
+
1297
+static long
1298
+clk_trion_pll_postdiv_round_rate(struct clk_hw *hw, unsigned long rate,
1299
+ unsigned long *prate)
1300
+{
1301
+ struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
1302
+
1303
+ return divider_round_rate(hw, rate, prate, pll->post_div_table,
1304
+ pll->width, CLK_DIVIDER_ROUND_CLOSEST);
1305
+};
1306
+
1307
+static int
1308
+clk_trion_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,
1309
+ unsigned long parent_rate)
1310
+{
1311
+ struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
1312
+ struct regmap *regmap = pll->clkr.regmap;
1313
+ int i, val = 0, div;
1314
+
1315
+ div = DIV_ROUND_UP_ULL(parent_rate, rate);
1316
+ for (i = 0; i < pll->num_post_div; i++) {
1317
+ if (pll->post_div_table[i].div == div) {
1318
+ val = pll->post_div_table[i].val;
1319
+ break;
1320
+ }
1321
+ }
1322
+
1323
+ return regmap_update_bits(regmap, PLL_USER_CTL(pll),
1324
+ PLL_POST_DIV_MASK(pll) << PLL_POST_DIV_SHIFT,
1325
+ val << PLL_POST_DIV_SHIFT);
1326
+}
1327
+
1328
+const struct clk_ops clk_alpha_pll_postdiv_trion_ops = {
1329
+ .recalc_rate = clk_trion_pll_postdiv_recalc_rate,
1330
+ .round_rate = clk_trion_pll_postdiv_round_rate,
1331
+ .set_rate = clk_trion_pll_postdiv_set_rate,
1332
+};
1333
+EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_trion_ops);
1334
+
10601335 static long clk_alpha_pll_postdiv_fabia_round_rate(struct clk_hw *hw,
10611336 unsigned long rate, unsigned long *prate)
10621337 {
10631338 struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
1064
-
1065
- if (!pll->post_div_table) {
1066
- pr_err("Missing the post_div_table for the PLL\n");
1067
- return -EINVAL;
1068
- }
10691339
10701340 return divider_round_rate(hw, rate, prate, pll->post_div_table,
10711341 pll->width, CLK_DIVIDER_ROUND_CLOSEST);
....@@ -1088,12 +1358,7 @@
10881358 if (val & PLL_VOTE_FSM_ENA)
10891359 return 0;
10901360
1091
- if (!pll->post_div_table) {
1092
- pr_err("Missing the post_div_table for the PLL\n");
1093
- return -EINVAL;
1094
- }
1095
-
1096
- div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
1361
+ div = DIV_ROUND_UP_ULL(parent_rate, rate);
10971362 for (i = 0; i < pll->num_post_div; i++) {
10981363 if (pll->post_div_table[i].div == div) {
10991364 val = pll->post_div_table[i].val;
....@@ -1112,3 +1377,187 @@
11121377 .set_rate = clk_alpha_pll_postdiv_fabia_set_rate,
11131378 };
11141379 EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_fabia_ops);
1380
+
1381
+/**
1382
+ * clk_trion_pll_configure - configure the trion pll
1383
+ *
1384
+ * @pll: clk alpha pll
1385
+ * @regmap: register map
1386
+ * @config: configuration to apply for pll
1387
+ */
1388
+void clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
1389
+ const struct alpha_pll_config *config)
1390
+{
1391
+ if (config->l)
1392
+ regmap_write(regmap, PLL_L_VAL(pll), config->l);
1393
+
1394
+ regmap_write(regmap, PLL_CAL_L_VAL(pll), TRION_PLL_CAL_VAL);
1395
+
1396
+ if (config->alpha)
1397
+ regmap_write(regmap, PLL_ALPHA_VAL(pll), config->alpha);
1398
+
1399
+ if (config->config_ctl_val)
1400
+ regmap_write(regmap, PLL_CONFIG_CTL(pll),
1401
+ config->config_ctl_val);
1402
+
1403
+ if (config->config_ctl_hi_val)
1404
+ regmap_write(regmap, PLL_CONFIG_CTL_U(pll),
1405
+ config->config_ctl_hi_val);
1406
+
1407
+ if (config->config_ctl_hi1_val)
1408
+ regmap_write(regmap, PLL_CONFIG_CTL_U1(pll),
1409
+ config->config_ctl_hi1_val);
1410
+
1411
+ if (config->user_ctl_val)
1412
+ regmap_write(regmap, PLL_USER_CTL(pll),
1413
+ config->user_ctl_val);
1414
+
1415
+ if (config->user_ctl_hi_val)
1416
+ regmap_write(regmap, PLL_USER_CTL_U(pll),
1417
+ config->user_ctl_hi_val);
1418
+
1419
+ if (config->user_ctl_hi1_val)
1420
+ regmap_write(regmap, PLL_USER_CTL_U1(pll),
1421
+ config->user_ctl_hi1_val);
1422
+
1423
+ if (config->test_ctl_val)
1424
+ regmap_write(regmap, PLL_TEST_CTL(pll),
1425
+ config->test_ctl_val);
1426
+
1427
+ if (config->test_ctl_hi_val)
1428
+ regmap_write(regmap, PLL_TEST_CTL_U(pll),
1429
+ config->test_ctl_hi_val);
1430
+
1431
+ if (config->test_ctl_hi1_val)
1432
+ regmap_write(regmap, PLL_TEST_CTL_U1(pll),
1433
+ config->test_ctl_hi1_val);
1434
+
1435
+ regmap_update_bits(regmap, PLL_MODE(pll), PLL_UPDATE_BYPASS,
1436
+ PLL_UPDATE_BYPASS);
1437
+
1438
+ /* Disable PLL output */
1439
+ regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0);
1440
+
1441
+ /* Set operation mode to OFF */
1442
+ regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);
1443
+
1444
+ /* Place the PLL in STANDBY mode */
1445
+ regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);
1446
+}
1447
+EXPORT_SYMBOL_GPL(clk_trion_pll_configure);
1448
+
1449
+/*
1450
+ * The TRION PLL requires a power-on self-calibration which happens when the
1451
+ * PLL comes out of reset. Calibrate in case it is not completed.
1452
+ */
1453
+static int __alpha_pll_trion_prepare(struct clk_hw *hw, u32 pcal_done)
1454
+{
1455
+ struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
1456
+ u32 regval;
1457
+ int ret;
1458
+
1459
+ /* Return early if calibration is not needed. */
1460
+ regmap_read(pll->clkr.regmap, PLL_STATUS(pll), &regval);
1461
+ if (regval & pcal_done)
1462
+ return 0;
1463
+
1464
+ /* On/off to calibrate */
1465
+ ret = clk_trion_pll_enable(hw);
1466
+ if (!ret)
1467
+ clk_trion_pll_disable(hw);
1468
+
1469
+ return ret;
1470
+}
1471
+
1472
+static int alpha_pll_trion_prepare(struct clk_hw *hw)
1473
+{
1474
+ return __alpha_pll_trion_prepare(hw, TRION_PCAL_DONE);
1475
+}
1476
+
1477
+static int alpha_pll_lucid_prepare(struct clk_hw *hw)
1478
+{
1479
+ return __alpha_pll_trion_prepare(hw, LUCID_PCAL_DONE);
1480
+}
1481
+
1482
+static int alpha_pll_trion_set_rate(struct clk_hw *hw, unsigned long rate,
1483
+ unsigned long prate)
1484
+{
1485
+ struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
1486
+ unsigned long rrate;
1487
+ u32 regval, l, alpha_width = pll_alpha_width(pll);
1488
+ u64 a;
1489
+ int ret;
1490
+
1491
+ rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);
1492
+
1493
+ /*
1494
+ * Due to a limited number of bits for fractional rate programming, the
1495
+ * rounded up rate could be marginally higher than the requested rate.
1496
+ */
1497
+ if (rrate > (rate + PLL_RATE_MARGIN) || rrate < rate) {
1498
+ pr_err("Call set rate on the PLL with rounded rates!\n");
1499
+ return -EINVAL;
1500
+ }
1501
+
1502
+ regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);
1503
+ regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);
1504
+
1505
+ /* Latch the PLL input */
1506
+ ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll),
1507
+ PLL_UPDATE, PLL_UPDATE);
1508
+ if (ret)
1509
+ return ret;
1510
+
1511
+ /* Wait for 2 reference cycles before checking the ACK bit. */
1512
+ udelay(1);
1513
+ regmap_read(pll->clkr.regmap, PLL_MODE(pll), &regval);
1514
+ if (!(regval & ALPHA_PLL_ACK_LATCH)) {
1515
+ pr_err("Lucid PLL latch failed. Output may be unstable!\n");
1516
+ return -EINVAL;
1517
+ }
1518
+
1519
+ /* Return the latch input to 0 */
1520
+ ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll),
1521
+ PLL_UPDATE, 0);
1522
+ if (ret)
1523
+ return ret;
1524
+
1525
+ if (clk_hw_is_enabled(hw)) {
1526
+ ret = wait_for_pll_enable_lock(pll);
1527
+ if (ret)
1528
+ return ret;
1529
+ }
1530
+
1531
+ /* Wait for PLL output to stabilize */
1532
+ udelay(100);
1533
+ return 0;
1534
+}
1535
+
1536
+const struct clk_ops clk_alpha_pll_trion_ops = {
1537
+ .prepare = alpha_pll_trion_prepare,
1538
+ .enable = clk_trion_pll_enable,
1539
+ .disable = clk_trion_pll_disable,
1540
+ .is_enabled = clk_trion_pll_is_enabled,
1541
+ .recalc_rate = clk_trion_pll_recalc_rate,
1542
+ .round_rate = clk_alpha_pll_round_rate,
1543
+ .set_rate = alpha_pll_trion_set_rate,
1544
+};
1545
+EXPORT_SYMBOL_GPL(clk_alpha_pll_trion_ops);
1546
+
1547
+const struct clk_ops clk_alpha_pll_lucid_ops = {
1548
+ .prepare = alpha_pll_lucid_prepare,
1549
+ .enable = clk_trion_pll_enable,
1550
+ .disable = clk_trion_pll_disable,
1551
+ .is_enabled = clk_trion_pll_is_enabled,
1552
+ .recalc_rate = clk_trion_pll_recalc_rate,
1553
+ .round_rate = clk_alpha_pll_round_rate,
1554
+ .set_rate = alpha_pll_trion_set_rate,
1555
+};
1556
+EXPORT_SYMBOL_GPL(clk_alpha_pll_lucid_ops);
1557
+
1558
+const struct clk_ops clk_alpha_pll_postdiv_lucid_ops = {
1559
+ .recalc_rate = clk_alpha_pll_postdiv_fabia_recalc_rate,
1560
+ .round_rate = clk_alpha_pll_postdiv_fabia_round_rate,
1561
+ .set_rate = clk_alpha_pll_postdiv_fabia_set_rate,
1562
+};
1563
+EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_lucid_ops);