clk-rpmh.c 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #include <linux/clk-provider.h>
  7. #include <linux/err.h>
  8. #include <linux/kernel.h>
  9. #include <linux/module.h>
  10. #include <linux/of.h>
  11. #include <linux/of_device.h>
  12. #include <linux/platform_device.h>
  13. #include <soc/qcom/cmd-db.h>
  14. #include <soc/qcom/rpmh.h>
  15. #include <soc/qcom/tcs.h>
  16. #include <dt-bindings/clock/qcom,rpmh.h>
  17. #define CLK_RPMH_ARC_EN_OFFSET 0
  18. #define CLK_RPMH_VRM_EN_OFFSET 4
  19. /**
  20. * struct bcm_db - Auxiliary data pertaining to each Bus Clock Manager(BCM)
  21. * @unit: divisor used to convert Hz value to an RPMh msg
  22. * @width: multiplier used to convert Hz value to an RPMh msg
  23. * @vcd: virtual clock domain that this bcm belongs to
  24. * @reserved: reserved to pad the struct
  25. */
  26. struct bcm_db {
  27. __le32 unit;
  28. __le16 width;
  29. u8 vcd;
  30. u8 reserved;
  31. };
  32. /**
  33. * struct clk_rpmh - individual rpmh clock data structure
  34. * @hw: handle between common and hardware-specific interfaces
  35. * @res_name: resource name for the rpmh clock
  36. * @div: clock divider to compute the clock rate
  37. * @res_addr: base address of the rpmh resource within the RPMh
  38. * @res_on_val: rpmh clock enable value
  39. * @state: rpmh clock requested state
  40. * @aggr_state: rpmh clock aggregated state
  41. * @last_sent_aggr_state: rpmh clock last aggr state sent to RPMh
  42. * @valid_state_mask: mask to determine the state of the rpmh clock
  43. * @unit: divisor to convert rate to rpmh msg in magnitudes of Khz
  44. * @dev: device to which it is attached
  45. * @peer: pointer to the clock rpmh sibling
  46. */
  47. struct clk_rpmh {
  48. struct clk_hw hw;
  49. const char *res_name;
  50. u8 div;
  51. bool optional;
  52. u32 res_addr;
  53. u32 res_on_val;
  54. u32 state;
  55. u32 aggr_state;
  56. u32 last_sent_aggr_state;
  57. u32 valid_state_mask;
  58. u32 unit;
  59. struct device *dev;
  60. struct clk_rpmh *peer;
  61. };
  62. struct clk_rpmh_desc {
  63. struct clk_hw **clks;
  64. size_t num_clks;
  65. };
  66. static DEFINE_MUTEX(rpmh_clk_lock);
  67. #define __DEFINE_CLK_RPMH(_platform, _name, _name_active, _res_name, \
  68. _res_en_offset, _res_on, _div, _optional) \
  69. static struct clk_rpmh _platform##_##_name_active; \
  70. static struct clk_rpmh _platform##_##_name = { \
  71. .res_name = _res_name, \
  72. .res_addr = _res_en_offset, \
  73. .res_on_val = _res_on, \
  74. .div = _div, \
  75. .optional = _optional, \
  76. .peer = &_platform##_##_name_active, \
  77. .valid_state_mask = (BIT(RPMH_WAKE_ONLY_STATE) | \
  78. BIT(RPMH_ACTIVE_ONLY_STATE) | \
  79. BIT(RPMH_SLEEP_STATE)), \
  80. .hw.init = &(struct clk_init_data){ \
  81. .ops = &clk_rpmh_ops, \
  82. .name = #_name, \
  83. .parent_data = &(const struct clk_parent_data){ \
  84. .fw_name = "xo", \
  85. .name = "xo_board", \
  86. }, \
  87. .num_parents = 1, \
  88. }, \
  89. }; \
  90. static struct clk_rpmh _platform##_##_name_active = { \
  91. .res_name = _res_name, \
  92. .res_addr = _res_en_offset, \
  93. .res_on_val = _res_on, \
  94. .div = _div, \
  95. .optional = _optional, \
  96. .peer = &_platform##_##_name, \
  97. .valid_state_mask = (BIT(RPMH_WAKE_ONLY_STATE) | \
  98. BIT(RPMH_ACTIVE_ONLY_STATE)), \
  99. .hw.init = &(struct clk_init_data){ \
  100. .ops = &clk_rpmh_ops, \
  101. .name = #_name_active, \
  102. .parent_data = &(const struct clk_parent_data){ \
  103. .fw_name = "xo", \
  104. .name = "xo_board", \
  105. }, \
  106. .num_parents = 1, \
  107. }, \
  108. }
  109. #define DEFINE_CLK_RPMH_FIXED(_platform, _name, _name_active, \
  110. _parent_name, _name_active_parent, \
  111. _div) \
  112. static struct clk_fixed_factor _platform##_##_name = { \
  113. .mult = 1, \
  114. .div = _div, \
  115. .hw.init = &(struct clk_init_data){ \
  116. .ops = &clk_fixed_factor_ops, \
  117. .name = #_name, \
  118. .parent_data = &(const struct clk_parent_data){ \
  119. .fw_name = #_parent_name, \
  120. .name = #_parent_name, \
  121. }, \
  122. .num_parents = 1, \
  123. }, \
  124. }; \
  125. static struct clk_fixed_factor _platform##_##_name_active = { \
  126. .mult = 1, \
  127. .div = _div, \
  128. .hw.init = &(struct clk_init_data){ \
  129. .ops = &clk_fixed_factor_ops, \
  130. .name = #_name_active, \
  131. .parent_data = &(const struct clk_parent_data){ \
  132. .fw_name = #_name_active_parent,\
  133. .name = #_name_active_parent, \
  134. }, \
  135. .num_parents = 1, \
  136. }, \
  137. }
  138. #define DEFINE_CLK_RPMH_ARC(_platform, _name, _name_active, _res_name, \
  139. _res_on, _div) \
  140. __DEFINE_CLK_RPMH(_platform, _name, _name_active, _res_name, \
  141. CLK_RPMH_ARC_EN_OFFSET, _res_on, _div, false)
  142. #define DEFINE_CLK_RPMH_VRM(_platform, _name, _name_active, _res_name, \
  143. _div) \
  144. __DEFINE_CLK_RPMH(_platform, _name, _name_active, _res_name, \
  145. CLK_RPMH_VRM_EN_OFFSET, 1, _div, false)
  146. #define DEFINE_CLK_RPMH_VRM_OPT(_platform, _name, _name_active, \
  147. _res_name, _div) \
  148. __DEFINE_CLK_RPMH(_platform, _name, _name_active, _res_name, \
  149. CLK_RPMH_VRM_EN_OFFSET, 1, _div, true)
  150. #define DEFINE_CLK_RPMH_BCM(_platform, _name, _res_name) \
  151. static struct clk_rpmh _platform##_##_name = { \
  152. .res_name = _res_name, \
  153. .valid_state_mask = BIT(RPMH_ACTIVE_ONLY_STATE), \
  154. .div = 1, \
  155. .hw.init = &(struct clk_init_data){ \
  156. .ops = &clk_rpmh_bcm_ops, \
  157. .name = #_name, \
  158. }, \
  159. }
  160. static inline struct clk_rpmh *to_clk_rpmh(struct clk_hw *_hw)
  161. {
  162. return container_of(_hw, struct clk_rpmh, hw);
  163. }
  164. static inline bool has_state_changed(struct clk_rpmh *c, u32 state)
  165. {
  166. return (c->last_sent_aggr_state & BIT(state))
  167. != (c->aggr_state & BIT(state));
  168. }
  169. static int clk_rpmh_send(struct clk_rpmh *c, enum rpmh_state state,
  170. struct tcs_cmd *cmd, bool wait)
  171. {
  172. if (wait)
  173. return rpmh_write(c->dev, state, cmd, 1);
  174. return rpmh_write_async(c->dev, state, cmd, 1);
  175. }
  176. static int clk_rpmh_send_aggregate_command(struct clk_rpmh *c)
  177. {
  178. struct tcs_cmd cmd = { 0 };
  179. u32 cmd_state, on_val;
  180. enum rpmh_state state = RPMH_SLEEP_STATE;
  181. int ret;
  182. bool wait;
  183. cmd.addr = c->res_addr;
  184. cmd_state = c->aggr_state;
  185. on_val = c->res_on_val;
  186. for (; state <= RPMH_ACTIVE_ONLY_STATE; state++) {
  187. if (has_state_changed(c, state)) {
  188. if (cmd_state & BIT(state))
  189. cmd.data = on_val;
  190. wait = cmd_state && state == RPMH_ACTIVE_ONLY_STATE;
  191. ret = clk_rpmh_send(c, state, &cmd, wait);
  192. if (ret) {
  193. dev_err(c->dev, "set %s state of %s failed: (%d)\n",
  194. !state ? "sleep" :
  195. state == RPMH_WAKE_ONLY_STATE ?
  196. "wake" : "active", c->res_name, ret);
  197. return ret;
  198. }
  199. }
  200. }
  201. c->last_sent_aggr_state = c->aggr_state;
  202. c->peer->last_sent_aggr_state = c->last_sent_aggr_state;
  203. return 0;
  204. }
  205. /*
  206. * Update state and aggregate state values based on enable value.
  207. */
  208. static int clk_rpmh_aggregate_state_send_command(struct clk_rpmh *c,
  209. bool enable)
  210. {
  211. int ret;
  212. c->state = enable ? c->valid_state_mask : 0;
  213. c->aggr_state = c->state | c->peer->state;
  214. c->peer->aggr_state = c->aggr_state;
  215. ret = clk_rpmh_send_aggregate_command(c);
  216. if (!ret)
  217. return 0;
  218. if (ret && enable)
  219. c->state = 0;
  220. else if (ret)
  221. c->state = c->valid_state_mask;
  222. WARN(1, "clk: %s failed to %s\n", c->res_name,
  223. enable ? "enable" : "disable");
  224. return ret;
  225. }
  226. static int clk_rpmh_prepare(struct clk_hw *hw)
  227. {
  228. struct clk_rpmh *c = to_clk_rpmh(hw);
  229. int ret = 0;
  230. mutex_lock(&rpmh_clk_lock);
  231. ret = clk_rpmh_aggregate_state_send_command(c, true);
  232. mutex_unlock(&rpmh_clk_lock);
  233. return ret;
  234. }
  235. static void clk_rpmh_unprepare(struct clk_hw *hw)
  236. {
  237. struct clk_rpmh *c = to_clk_rpmh(hw);
  238. mutex_lock(&rpmh_clk_lock);
  239. clk_rpmh_aggregate_state_send_command(c, false);
  240. mutex_unlock(&rpmh_clk_lock);
  241. };
  242. static unsigned long clk_rpmh_recalc_rate(struct clk_hw *hw,
  243. unsigned long prate)
  244. {
  245. struct clk_rpmh *r = to_clk_rpmh(hw);
  246. /*
  247. * RPMh clocks have a fixed rate. Return static rate.
  248. */
  249. return prate / r->div;
  250. }
  251. static const struct clk_ops clk_rpmh_ops = {
  252. .prepare = clk_rpmh_prepare,
  253. .unprepare = clk_rpmh_unprepare,
  254. .recalc_rate = clk_rpmh_recalc_rate,
  255. };
  256. static int clk_rpmh_bcm_send_cmd(struct clk_rpmh *c, bool enable)
  257. {
  258. struct tcs_cmd cmd = { 0 };
  259. u32 cmd_state;
  260. int ret = 0;
  261. mutex_lock(&rpmh_clk_lock);
  262. if (enable) {
  263. cmd_state = 1;
  264. if (c->aggr_state)
  265. cmd_state = c->aggr_state;
  266. } else {
  267. cmd_state = 0;
  268. }
  269. if (cmd_state > BCM_TCS_CMD_VOTE_MASK)
  270. cmd_state = BCM_TCS_CMD_VOTE_MASK;
  271. if (c->last_sent_aggr_state != cmd_state) {
  272. cmd.addr = c->res_addr;
  273. cmd.data = BCM_TCS_CMD(1, enable, 0, cmd_state);
  274. /*
  275. * Send only an active only state request. RPMh continues to
  276. * use the active state when we're in sleep/wake state as long
  277. * as the sleep/wake state has never been set.
  278. */
  279. ret = clk_rpmh_send(c, RPMH_ACTIVE_ONLY_STATE, &cmd, enable);
  280. if (ret) {
  281. dev_err(c->dev, "set active state of %s failed: (%d)\n",
  282. c->res_name, ret);
  283. } else {
  284. c->last_sent_aggr_state = cmd_state;
  285. }
  286. }
  287. mutex_unlock(&rpmh_clk_lock);
  288. return ret;
  289. }
  290. static int clk_rpmh_bcm_prepare(struct clk_hw *hw)
  291. {
  292. struct clk_rpmh *c = to_clk_rpmh(hw);
  293. return clk_rpmh_bcm_send_cmd(c, true);
  294. }
  295. static void clk_rpmh_bcm_unprepare(struct clk_hw *hw)
  296. {
  297. struct clk_rpmh *c = to_clk_rpmh(hw);
  298. clk_rpmh_bcm_send_cmd(c, false);
  299. }
  300. static int clk_rpmh_bcm_set_rate(struct clk_hw *hw, unsigned long rate,
  301. unsigned long parent_rate)
  302. {
  303. struct clk_rpmh *c = to_clk_rpmh(hw);
  304. c->aggr_state = rate / c->unit;
  305. /*
  306. * Since any non-zero value sent to hw would result in enabling the
  307. * clock, only send the value if the clock has already been prepared.
  308. */
  309. if (clk_hw_is_prepared(hw))
  310. clk_rpmh_bcm_send_cmd(c, true);
  311. return 0;
  312. }
  313. static long clk_rpmh_round_rate(struct clk_hw *hw, unsigned long rate,
  314. unsigned long *parent_rate)
  315. {
  316. return rate;
  317. }
  318. static unsigned long clk_rpmh_bcm_recalc_rate(struct clk_hw *hw,
  319. unsigned long prate)
  320. {
  321. struct clk_rpmh *c = to_clk_rpmh(hw);
  322. return c->aggr_state * c->unit;
  323. }
  324. static const struct clk_ops clk_rpmh_bcm_ops = {
  325. .prepare = clk_rpmh_bcm_prepare,
  326. .unprepare = clk_rpmh_bcm_unprepare,
  327. .set_rate = clk_rpmh_bcm_set_rate,
  328. .round_rate = clk_rpmh_round_rate,
  329. .recalc_rate = clk_rpmh_bcm_recalc_rate,
  330. };
  331. /* Resource name must match resource id present in cmd-db */
  332. DEFINE_CLK_RPMH_ARC(sdm845, bi_tcxo, bi_tcxo_ao, "xo.lvl", 0x3, 2);
  333. DEFINE_CLK_RPMH_VRM(sdm845, ln_bb_clk2, ln_bb_clk2_ao, "lnbclka2", 2);
  334. DEFINE_CLK_RPMH_VRM(sdm845, ln_bb_clk3, ln_bb_clk3_ao, "lnbclka3", 2);
  335. DEFINE_CLK_RPMH_VRM(sdm845, rf_clk1, rf_clk1_ao, "rfclka1", 1);
  336. DEFINE_CLK_RPMH_VRM(sdm845, rf_clk2, rf_clk2_ao, "rfclka2", 1);
  337. DEFINE_CLK_RPMH_VRM(sdm845, rf_clk3, rf_clk3_ao, "rfclka3", 1);
  338. DEFINE_CLK_RPMH_VRM(sm8150, rf_clk3, rf_clk3_ao, "rfclka3", 1);
  339. DEFINE_CLK_RPMH_VRM(sc8180x, rf_clk1, rf_clk1_ao, "rfclkd1", 1);
  340. DEFINE_CLK_RPMH_VRM(sc8180x, rf_clk2, rf_clk2_ao, "rfclkd2", 1);
  341. DEFINE_CLK_RPMH_VRM(sc8180x, rf_clk3, rf_clk3_ao, "rfclkd3", 1);
  342. DEFINE_CLK_RPMH_VRM(sc8180x, rf_clk4, rf_clk4_ao, "rfclkd4", 1);
  343. DEFINE_CLK_RPMH_BCM(sdm845, ipa, "IP0");
  344. DEFINE_CLK_RPMH_BCM(sdm845, ce, "CE0");
  345. static struct clk_hw *sdm845_rpmh_clocks[] = {
  346. [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw,
  347. [RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw,
  348. [RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw,
  349. [RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw,
  350. [RPMH_LN_BB_CLK3] = &sdm845_ln_bb_clk3.hw,
  351. [RPMH_LN_BB_CLK3_A] = &sdm845_ln_bb_clk3_ao.hw,
  352. [RPMH_RF_CLK1] = &sdm845_rf_clk1.hw,
  353. [RPMH_RF_CLK1_A] = &sdm845_rf_clk1_ao.hw,
  354. [RPMH_RF_CLK2] = &sdm845_rf_clk2.hw,
  355. [RPMH_RF_CLK2_A] = &sdm845_rf_clk2_ao.hw,
  356. [RPMH_RF_CLK3] = &sdm845_rf_clk3.hw,
  357. [RPMH_RF_CLK3_A] = &sdm845_rf_clk3_ao.hw,
  358. [RPMH_IPA_CLK] = &sdm845_ipa.hw,
  359. [RPMH_CE_CLK] = &sdm845_ce.hw,
  360. };
  361. static const struct clk_rpmh_desc clk_rpmh_sdm845 = {
  362. .clks = sdm845_rpmh_clocks,
  363. .num_clks = ARRAY_SIZE(sdm845_rpmh_clocks),
  364. };
  365. static struct clk_hw *sdm670_rpmh_clocks[] = {
  366. [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw,
  367. [RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw,
  368. [RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw,
  369. [RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw,
  370. [RPMH_LN_BB_CLK3] = &sdm845_ln_bb_clk3.hw,
  371. [RPMH_LN_BB_CLK3_A] = &sdm845_ln_bb_clk3_ao.hw,
  372. [RPMH_RF_CLK1] = &sdm845_rf_clk1.hw,
  373. [RPMH_RF_CLK1_A] = &sdm845_rf_clk1_ao.hw,
  374. [RPMH_RF_CLK2] = &sdm845_rf_clk2.hw,
  375. [RPMH_RF_CLK2_A] = &sdm845_rf_clk2_ao.hw,
  376. [RPMH_IPA_CLK] = &sdm845_ipa.hw,
  377. [RPMH_CE_CLK] = &sdm845_ce.hw,
  378. };
  379. static const struct clk_rpmh_desc clk_rpmh_sdm670 = {
  380. .clks = sdm670_rpmh_clocks,
  381. .num_clks = ARRAY_SIZE(sdm670_rpmh_clocks),
  382. };
  383. DEFINE_CLK_RPMH_VRM(sdx55, rf_clk1, rf_clk1_ao, "rfclkd1", 1);
  384. DEFINE_CLK_RPMH_VRM(sdx55, rf_clk2, rf_clk2_ao, "rfclkd2", 1);
  385. DEFINE_CLK_RPMH_BCM(sdx55, qpic_clk, "QP0");
  386. DEFINE_CLK_RPMH_BCM(sdx55, ipa, "IP0");
  387. static struct clk_hw *sdx55_rpmh_clocks[] = {
  388. [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw,
  389. [RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw,
  390. [RPMH_RF_CLK1] = &sdx55_rf_clk1.hw,
  391. [RPMH_RF_CLK1_A] = &sdx55_rf_clk1_ao.hw,
  392. [RPMH_RF_CLK2] = &sdx55_rf_clk2.hw,
  393. [RPMH_RF_CLK2_A] = &sdx55_rf_clk2_ao.hw,
  394. [RPMH_QPIC_CLK] = &sdx55_qpic_clk.hw,
  395. [RPMH_IPA_CLK] = &sdx55_ipa.hw,
  396. };
  397. static const struct clk_rpmh_desc clk_rpmh_sdx55 = {
  398. .clks = sdx55_rpmh_clocks,
  399. .num_clks = ARRAY_SIZE(sdx55_rpmh_clocks),
  400. };
  401. static struct clk_hw *sm8150_rpmh_clocks[] = {
  402. [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw,
  403. [RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw,
  404. [RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw,
  405. [RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw,
  406. [RPMH_LN_BB_CLK3] = &sdm845_ln_bb_clk3.hw,
  407. [RPMH_LN_BB_CLK3_A] = &sdm845_ln_bb_clk3_ao.hw,
  408. [RPMH_RF_CLK1] = &sdm845_rf_clk1.hw,
  409. [RPMH_RF_CLK1_A] = &sdm845_rf_clk1_ao.hw,
  410. [RPMH_RF_CLK2] = &sdm845_rf_clk2.hw,
  411. [RPMH_RF_CLK2_A] = &sdm845_rf_clk2_ao.hw,
  412. [RPMH_RF_CLK3] = &sdm845_rf_clk3.hw,
  413. [RPMH_RF_CLK3_A] = &sdm845_rf_clk3_ao.hw,
  414. [RPMH_IPA_CLK] = &sdm845_ipa.hw,
  415. };
  416. static const struct clk_rpmh_desc clk_rpmh_sm8150 = {
  417. .clks = sm8150_rpmh_clocks,
  418. .num_clks = ARRAY_SIZE(sm8150_rpmh_clocks),
  419. };
  420. static struct clk_hw *sc7180_rpmh_clocks[] = {
  421. [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw,
  422. [RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw,
  423. [RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw,
  424. [RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw,
  425. [RPMH_LN_BB_CLK3] = &sdm845_ln_bb_clk3.hw,
  426. [RPMH_LN_BB_CLK3_A] = &sdm845_ln_bb_clk3_ao.hw,
  427. [RPMH_RF_CLK1] = &sdm845_rf_clk1.hw,
  428. [RPMH_RF_CLK1_A] = &sdm845_rf_clk1_ao.hw,
  429. [RPMH_RF_CLK2] = &sdm845_rf_clk2.hw,
  430. [RPMH_RF_CLK2_A] = &sdm845_rf_clk2_ao.hw,
  431. [RPMH_IPA_CLK] = &sdm845_ipa.hw,
  432. };
  433. static const struct clk_rpmh_desc clk_rpmh_sc7180 = {
  434. .clks = sc7180_rpmh_clocks,
  435. .num_clks = ARRAY_SIZE(sc7180_rpmh_clocks),
  436. };
  437. static struct clk_hw *sc8180x_rpmh_clocks[] = {
  438. [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw,
  439. [RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw,
  440. [RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw,
  441. [RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw,
  442. [RPMH_LN_BB_CLK3] = &sdm845_ln_bb_clk3.hw,
  443. [RPMH_LN_BB_CLK3_A] = &sdm845_ln_bb_clk3_ao.hw,
  444. [RPMH_RF_CLK1] = &sc8180x_rf_clk1.hw,
  445. [RPMH_RF_CLK1_A] = &sc8180x_rf_clk1_ao.hw,
  446. [RPMH_RF_CLK2] = &sc8180x_rf_clk2.hw,
  447. [RPMH_RF_CLK2_A] = &sc8180x_rf_clk2_ao.hw,
  448. [RPMH_RF_CLK3] = &sc8180x_rf_clk3.hw,
  449. [RPMH_RF_CLK3_A] = &sc8180x_rf_clk3_ao.hw,
  450. [RPMH_IPA_CLK] = &sdm845_ipa.hw,
  451. };
  452. static const struct clk_rpmh_desc clk_rpmh_sc8180x = {
  453. .clks = sc8180x_rpmh_clocks,
  454. .num_clks = ARRAY_SIZE(sc8180x_rpmh_clocks),
  455. };
  456. DEFINE_CLK_RPMH_VRM(sm8250, ln_bb_clk1, ln_bb_clk1_ao, "lnbclka1", 2);
  457. static struct clk_hw *sm8250_rpmh_clocks[] = {
  458. [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw,
  459. [RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw,
  460. [RPMH_LN_BB_CLK1] = &sm8250_ln_bb_clk1.hw,
  461. [RPMH_LN_BB_CLK1_A] = &sm8250_ln_bb_clk1_ao.hw,
  462. [RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw,
  463. [RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw,
  464. [RPMH_LN_BB_CLK3] = &sdm845_ln_bb_clk3.hw,
  465. [RPMH_LN_BB_CLK3_A] = &sdm845_ln_bb_clk3_ao.hw,
  466. [RPMH_RF_CLK1] = &sdm845_rf_clk1.hw,
  467. [RPMH_RF_CLK1_A] = &sdm845_rf_clk1_ao.hw,
  468. [RPMH_RF_CLK3] = &sdm845_rf_clk3.hw,
  469. [RPMH_RF_CLK3_A] = &sdm845_rf_clk3_ao.hw,
  470. [RPMH_IPA_CLK] = &sdm845_ipa.hw,
  471. };
  472. static const struct clk_rpmh_desc clk_rpmh_sm8250 = {
  473. .clks = sm8250_rpmh_clocks,
  474. .num_clks = ARRAY_SIZE(sm8250_rpmh_clocks),
  475. };
  476. DEFINE_CLK_RPMH_VRM(sm8350, div_clk1, div_clk1_ao, "divclka1", 2);
  477. DEFINE_CLK_RPMH_VRM(sm8350, rf_clk4, rf_clk4_ao, "rfclka4", 1);
  478. DEFINE_CLK_RPMH_VRM(sm8350, rf_clk5, rf_clk5_ao, "rfclka5", 1);
  479. DEFINE_CLK_RPMH_BCM(sm8350, pka, "PKA0");
  480. DEFINE_CLK_RPMH_BCM(sm8350, hwkm, "HK0");
  481. static struct clk_hw *sm8350_rpmh_clocks[] = {
  482. [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw,
  483. [RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw,
  484. [RPMH_DIV_CLK1] = &sm8350_div_clk1.hw,
  485. [RPMH_DIV_CLK1_A] = &sm8350_div_clk1_ao.hw,
  486. [RPMH_LN_BB_CLK1] = &sm8250_ln_bb_clk1.hw,
  487. [RPMH_LN_BB_CLK1_A] = &sm8250_ln_bb_clk1_ao.hw,
  488. [RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw,
  489. [RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw,
  490. [RPMH_RF_CLK1] = &sdm845_rf_clk1.hw,
  491. [RPMH_RF_CLK1_A] = &sdm845_rf_clk1_ao.hw,
  492. [RPMH_RF_CLK3] = &sdm845_rf_clk3.hw,
  493. [RPMH_RF_CLK3_A] = &sdm845_rf_clk3_ao.hw,
  494. [RPMH_RF_CLK4] = &sm8350_rf_clk4.hw,
  495. [RPMH_RF_CLK4_A] = &sm8350_rf_clk4_ao.hw,
  496. [RPMH_RF_CLK5] = &sm8350_rf_clk5.hw,
  497. [RPMH_RF_CLK5_A] = &sm8350_rf_clk5_ao.hw,
  498. [RPMH_IPA_CLK] = &sdm845_ipa.hw,
  499. [RPMH_PKA_CLK] = &sm8350_pka.hw,
  500. [RPMH_HWKM_CLK] = &sm8350_hwkm.hw,
  501. };
  502. static const struct clk_rpmh_desc clk_rpmh_sm8350 = {
  503. .clks = sm8350_rpmh_clocks,
  504. .num_clks = ARRAY_SIZE(sm8350_rpmh_clocks),
  505. };
  506. DEFINE_CLK_RPMH_VRM(sc8280xp, ln_bb_clk3, ln_bb_clk3_ao, "lnbclka3", 2);
  507. static struct clk_hw *sc8280xp_rpmh_clocks[] = {
  508. [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw,
  509. [RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw,
  510. [RPMH_LN_BB_CLK3] = &sc8280xp_ln_bb_clk3.hw,
  511. [RPMH_LN_BB_CLK3_A] = &sc8280xp_ln_bb_clk3_ao.hw,
  512. [RPMH_IPA_CLK] = &sdm845_ipa.hw,
  513. [RPMH_PKA_CLK] = &sm8350_pka.hw,
  514. [RPMH_HWKM_CLK] = &sm8350_hwkm.hw,
  515. };
  516. static const struct clk_rpmh_desc clk_rpmh_sc8280xp = {
  517. .clks = sc8280xp_rpmh_clocks,
  518. .num_clks = ARRAY_SIZE(sc8280xp_rpmh_clocks),
  519. };
  520. /* Resource name must match resource id present in cmd-db */
  521. DEFINE_CLK_RPMH_ARC(sc7280, bi_tcxo, bi_tcxo_ao, "xo.lvl", 0x3, 4);
  522. DEFINE_CLK_RPMH_VRM(sm8450, ln_bb_clk1, ln_bb_clk1_ao, "lnbclka1", 4);
  523. DEFINE_CLK_RPMH_VRM(sm8450, ln_bb_clk2, ln_bb_clk2_ao, "lnbclka2", 4);
  524. static struct clk_hw *sm8450_rpmh_clocks[] = {
  525. [RPMH_CXO_CLK] = &sc7280_bi_tcxo.hw,
  526. [RPMH_CXO_CLK_A] = &sc7280_bi_tcxo_ao.hw,
  527. [RPMH_LN_BB_CLK1] = &sm8450_ln_bb_clk1.hw,
  528. [RPMH_LN_BB_CLK1_A] = &sm8450_ln_bb_clk1_ao.hw,
  529. [RPMH_LN_BB_CLK2] = &sm8450_ln_bb_clk2.hw,
  530. [RPMH_LN_BB_CLK2_A] = &sm8450_ln_bb_clk2_ao.hw,
  531. [RPMH_RF_CLK1] = &sdm845_rf_clk1.hw,
  532. [RPMH_RF_CLK1_A] = &sdm845_rf_clk1_ao.hw,
  533. [RPMH_RF_CLK2] = &sdm845_rf_clk2.hw,
  534. [RPMH_RF_CLK2_A] = &sdm845_rf_clk2_ao.hw,
  535. [RPMH_RF_CLK3] = &sdm845_rf_clk3.hw,
  536. [RPMH_RF_CLK3_A] = &sdm845_rf_clk3_ao.hw,
  537. [RPMH_RF_CLK4] = &sm8350_rf_clk4.hw,
  538. [RPMH_RF_CLK4_A] = &sm8350_rf_clk4_ao.hw,
  539. [RPMH_IPA_CLK] = &sdm845_ipa.hw,
  540. };
  541. static const struct clk_rpmh_desc clk_rpmh_sm8450 = {
  542. .clks = sm8450_rpmh_clocks,
  543. .num_clks = ARRAY_SIZE(sm8450_rpmh_clocks),
  544. };
  545. static struct clk_hw *sc7280_rpmh_clocks[] = {
  546. [RPMH_CXO_CLK] = &sc7280_bi_tcxo.hw,
  547. [RPMH_CXO_CLK_A] = &sc7280_bi_tcxo_ao.hw,
  548. [RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw,
  549. [RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw,
  550. [RPMH_RF_CLK1] = &sdm845_rf_clk1.hw,
  551. [RPMH_RF_CLK1_A] = &sdm845_rf_clk1_ao.hw,
  552. [RPMH_RF_CLK3] = &sdm845_rf_clk3.hw,
  553. [RPMH_RF_CLK3_A] = &sdm845_rf_clk3_ao.hw,
  554. [RPMH_RF_CLK4] = &sm8350_rf_clk4.hw,
  555. [RPMH_RF_CLK4_A] = &sm8350_rf_clk4_ao.hw,
  556. [RPMH_IPA_CLK] = &sdm845_ipa.hw,
  557. [RPMH_PKA_CLK] = &sm8350_pka.hw,
  558. [RPMH_HWKM_CLK] = &sm8350_hwkm.hw,
  559. };
  560. static const struct clk_rpmh_desc clk_rpmh_sc7280 = {
  561. .clks = sc7280_rpmh_clocks,
  562. .num_clks = ARRAY_SIZE(sc7280_rpmh_clocks),
  563. };
  564. DEFINE_CLK_RPMH_VRM(sm6350, ln_bb_clk2, ln_bb_clk2_ao, "lnbclkg2", 4);
  565. DEFINE_CLK_RPMH_VRM(sm6350, ln_bb_clk3, ln_bb_clk3_ao, "lnbclkg3", 4);
  566. DEFINE_CLK_RPMH_ARC(sm6350, qlink, qlink_ao, "qphy.lvl", 0x1, 4);
  567. static struct clk_hw *sm6350_rpmh_clocks[] = {
  568. [RPMH_CXO_CLK] = &sc7280_bi_tcxo.hw,
  569. [RPMH_CXO_CLK_A] = &sc7280_bi_tcxo_ao.hw,
  570. [RPMH_LN_BB_CLK2] = &sm6350_ln_bb_clk2.hw,
  571. [RPMH_LN_BB_CLK2_A] = &sm6350_ln_bb_clk2_ao.hw,
  572. [RPMH_LN_BB_CLK3] = &sm6350_ln_bb_clk3.hw,
  573. [RPMH_LN_BB_CLK3_A] = &sm6350_ln_bb_clk3_ao.hw,
  574. [RPMH_QLINK_CLK] = &sm6350_qlink.hw,
  575. [RPMH_QLINK_CLK_A] = &sm6350_qlink_ao.hw,
  576. };
  577. static const struct clk_rpmh_desc clk_rpmh_sm6350 = {
  578. .clks = sm6350_rpmh_clocks,
  579. .num_clks = ARRAY_SIZE(sm6350_rpmh_clocks),
  580. };
  581. DEFINE_CLK_RPMH_VRM(sdx65, ln_bb_clk1, ln_bb_clk1_ao, "lnbclka1", 4);
  582. static struct clk_hw *sdx65_rpmh_clocks[] = {
  583. [RPMH_CXO_CLK] = &sc7280_bi_tcxo.hw,
  584. [RPMH_CXO_CLK_A] = &sc7280_bi_tcxo_ao.hw,
  585. [RPMH_LN_BB_CLK1] = &sdx65_ln_bb_clk1.hw,
  586. [RPMH_LN_BB_CLK1_A] = &sdx65_ln_bb_clk1_ao.hw,
  587. [RPMH_RF_CLK1] = &sdm845_rf_clk1.hw,
  588. [RPMH_RF_CLK1_A] = &sdm845_rf_clk1_ao.hw,
  589. [RPMH_RF_CLK2] = &sdm845_rf_clk2.hw,
  590. [RPMH_RF_CLK2_A] = &sdm845_rf_clk2_ao.hw,
  591. [RPMH_RF_CLK3] = &sdm845_rf_clk3.hw,
  592. [RPMH_RF_CLK3_A] = &sdm845_rf_clk3_ao.hw,
  593. [RPMH_RF_CLK4] = &sm8350_rf_clk4.hw,
  594. [RPMH_RF_CLK4_A] = &sm8350_rf_clk4_ao.hw,
  595. [RPMH_IPA_CLK] = &sdm845_ipa.hw,
  596. [RPMH_QPIC_CLK] = &sdx55_qpic_clk.hw,
  597. };
  598. static const struct clk_rpmh_desc clk_rpmh_sdx65 = {
  599. .clks = sdx65_rpmh_clocks,
  600. .num_clks = ARRAY_SIZE(sdx65_rpmh_clocks),
  601. };
  602. static struct clk_hw *lemans_rpmh_clocks[] = {
  603. [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw,
  604. [RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw,
  605. [RPMH_LN_BB_CLK1] = &sm8250_ln_bb_clk1.hw,
  606. [RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw,
  607. [RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw,
  608. [RPMH_IPA_CLK] = &sdm845_ipa.hw,
  609. [RPMH_PKA_CLK] = &sm8350_pka.hw,
  610. [RPMH_HWKM_CLK] = &sm8350_hwkm.hw,
  611. };
  612. static const struct clk_rpmh_desc clk_rpmh_lemans = {
  613. .clks = lemans_rpmh_clocks,
  614. .num_clks = ARRAY_SIZE(lemans_rpmh_clocks),
  615. };
  616. DEFINE_CLK_RPMH_VRM(anorak, rf_clk1, rf_clk1_ao, "clka1", 1);
  617. DEFINE_CLK_RPMH_VRM(anorak, ln_bb_clk7, ln_bb_clk7_ao, "clka7", 2);
  618. DEFINE_CLK_RPMH_VRM(anorak, ln_bb_clk8, ln_bb_clk8_ao, "clka8", 4);
  619. DEFINE_CLK_RPMH_VRM(anorak, ln_bb_clk9, ln_bb_clk9_ao, "clka9", 2);
  620. static struct clk_hw *anorak_rpmh_clocks[] = {
  621. [RPMH_CXO_CLK] = &sc7280_bi_tcxo.hw,
  622. [RPMH_CXO_CLK_A] = &sc7280_bi_tcxo_ao.hw,
  623. [RPMH_LN_BB_CLK7] = &anorak_ln_bb_clk7.hw,
  624. [RPMH_LN_BB_CLK7_A] = &anorak_ln_bb_clk7_ao.hw,
  625. [RPMH_LN_BB_CLK8] = &anorak_ln_bb_clk8.hw,
  626. [RPMH_LN_BB_CLK8_A] = &anorak_ln_bb_clk8_ao.hw,
  627. [RPMH_LN_BB_CLK9] = &anorak_ln_bb_clk9.hw,
  628. [RPMH_LN_BB_CLK9_A] = &anorak_ln_bb_clk9_ao.hw,
  629. [RPMH_RF_CLK1] = &anorak_rf_clk1.hw,
  630. [RPMH_RF_CLK1_A] = &anorak_rf_clk1_ao.hw,
  631. [RPMH_IPA_CLK] = &sdm845_ipa.hw,
  632. };
  633. static const struct clk_rpmh_desc clk_rpmh_anorak = {
  634. .clks = anorak_rpmh_clocks,
  635. .num_clks = ARRAY_SIZE(anorak_rpmh_clocks),
  636. };
  637. static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec,
  638. void *data)
  639. {
  640. struct clk_rpmh_desc *rpmh = data;
  641. unsigned int idx = clkspec->args[0];
  642. if (idx >= rpmh->num_clks) {
  643. pr_err("%s: invalid index %u\n", __func__, idx);
  644. return ERR_PTR(-EINVAL);
  645. }
  646. if (!rpmh->clks[idx])
  647. return ERR_PTR(-ENOENT);
  648. return rpmh->clks[idx];
  649. }
  650. DEFINE_CLK_RPMH_ARC(kalama, xo_pad, xo_pad_ao, "xo.lvl", 0x03, 2);
  651. DEFINE_CLK_RPMH_FIXED(kalama, bi_tcxo, bi_tcxo_ao, xo_pad, xo_pad_ao, 2);
  652. DEFINE_CLK_RPMH_VRM_OPT(kalama, rf_clk1, rf_clk1_ao, "clka1", 1);
  653. DEFINE_CLK_RPMH_VRM_OPT(kalama, rf_clk2, rf_clk2_ao, "clka2", 1);
  654. DEFINE_CLK_RPMH_VRM_OPT(kalama, rf_clk3, rf_clk3_ao, "clka3", 1);
  655. DEFINE_CLK_RPMH_VRM_OPT(kalama, rf_clk4, rf_clk4_ao, "clka4", 1);
  656. DEFINE_CLK_RPMH_VRM_OPT(kalama, rf_clk5, rf_clk5_ao, "clka5", 2);
  657. DEFINE_CLK_RPMH_VRM_OPT(kalama, ln_bb_clk1, ln_bb_clk1_ao, "clka6", 2);
  658. DEFINE_CLK_RPMH_VRM_OPT(kalama, ln_bb_clk2, ln_bb_clk2_ao, "clka7", 2);
  659. DEFINE_CLK_RPMH_VRM_OPT(kalama, ln_bb_clk3, ln_bb_clk3_ao, "clka8", 2);
  660. static struct clk_hw *kalama_rpmh_clocks[] = {
  661. [RPMH_CXO_PAD_CLK] = &kalama_xo_pad.hw,
  662. [RPMH_CXO_PAD_CLK_A] = &kalama_xo_pad_ao.hw,
  663. [RPMH_CXO_CLK] = &kalama_bi_tcxo.hw,
  664. [RPMH_CXO_CLK_A] = &kalama_bi_tcxo_ao.hw,
  665. [RPMH_LN_BB_CLK1] = &kalama_ln_bb_clk1.hw,
  666. [RPMH_LN_BB_CLK1_A] = &kalama_ln_bb_clk1_ao.hw,
  667. [RPMH_LN_BB_CLK2] = &kalama_ln_bb_clk2.hw,
  668. [RPMH_LN_BB_CLK2_A] = &kalama_ln_bb_clk2_ao.hw,
  669. [RPMH_LN_BB_CLK3] = &kalama_ln_bb_clk3.hw,
  670. [RPMH_LN_BB_CLK3_A] = &kalama_ln_bb_clk3_ao.hw,
  671. [RPMH_RF_CLK1] = &kalama_rf_clk1.hw,
  672. [RPMH_RF_CLK1_A] = &kalama_rf_clk1_ao.hw,
  673. [RPMH_RF_CLK2] = &kalama_rf_clk2.hw,
  674. [RPMH_RF_CLK2_A] = &kalama_rf_clk2_ao.hw,
  675. [RPMH_RF_CLK3] = &kalama_rf_clk3.hw,
  676. [RPMH_RF_CLK3_A] = &kalama_rf_clk3_ao.hw,
  677. [RPMH_RF_CLK4] = &kalama_rf_clk4.hw,
  678. [RPMH_RF_CLK4_A] = &kalama_rf_clk4_ao.hw,
  679. [RPMH_RF_CLK5] = &kalama_rf_clk5.hw,
  680. [RPMH_RF_CLK5_A] = &kalama_rf_clk5_ao.hw,
  681. [RPMH_IPA_CLK] = &sdm845_ipa.hw,
  682. };
  683. static const struct clk_rpmh_desc clk_rpmh_kalama = {
  684. .clks = kalama_rpmh_clocks,
  685. .num_clks = ARRAY_SIZE(kalama_rpmh_clocks),
  686. };
  687. DEFINE_CLK_RPMH_ARC(pineapple, xo_pad, xo_pad_ao, "xo.lvl", 0x03, 2);
  688. DEFINE_CLK_RPMH_FIXED(pineapple, bi_tcxo, bi_tcxo_ao, xo_pad, xo_pad_ao, 2);
  689. DEFINE_CLK_RPMH_VRM_OPT(pineapple, rf_clk1, rf_clk1_ao, "clka1", 1);
  690. DEFINE_CLK_RPMH_VRM_OPT(pineapple, rf_clk2, rf_clk2_ao, "clka2", 1);
  691. DEFINE_CLK_RPMH_VRM_OPT(pineapple, rf_clk3, rf_clk3_ao, "clka3", 2);
  692. DEFINE_CLK_RPMH_VRM_OPT(pineapple, rf_clk4, rf_clk4_ao, "clka4", 2);
  693. DEFINE_CLK_RPMH_VRM_OPT(pineapple, rf_clk5, rf_clk5_ao, "clka5", 2);
  694. DEFINE_CLK_RPMH_VRM_OPT(pineapple, ln_bb_clk1, ln_bb_clk1_ao, "clka6", 2);
  695. DEFINE_CLK_RPMH_VRM_OPT(pineapple, ln_bb_clk2, ln_bb_clk2_ao, "clka7", 2);
  696. DEFINE_CLK_RPMH_VRM_OPT(pineapple, ln_bb_clk3, ln_bb_clk3_ao, "clka8", 2);
  697. static struct clk_hw *pineapple_rpmh_clocks[] = {
  698. [RPMH_CXO_PAD_CLK] = &pineapple_xo_pad.hw,
  699. [RPMH_CXO_PAD_CLK_A] = &pineapple_xo_pad_ao.hw,
  700. [RPMH_CXO_CLK] = &pineapple_bi_tcxo.hw,
  701. [RPMH_CXO_CLK_A] = &pineapple_bi_tcxo_ao.hw,
  702. [RPMH_LN_BB_CLK1] = &pineapple_ln_bb_clk1.hw,
  703. [RPMH_LN_BB_CLK1_A] = &pineapple_ln_bb_clk1_ao.hw,
  704. [RPMH_LN_BB_CLK2] = &pineapple_ln_bb_clk2.hw,
  705. [RPMH_LN_BB_CLK2_A] = &pineapple_ln_bb_clk2_ao.hw,
  706. [RPMH_LN_BB_CLK3] = &pineapple_ln_bb_clk3.hw,
  707. [RPMH_LN_BB_CLK3_A] = &pineapple_ln_bb_clk3_ao.hw,
  708. [RPMH_RF_CLK1] = &pineapple_rf_clk1.hw,
  709. [RPMH_RF_CLK1_A] = &pineapple_rf_clk1_ao.hw,
  710. [RPMH_RF_CLK2] = &pineapple_rf_clk2.hw,
  711. [RPMH_RF_CLK2_A] = &pineapple_rf_clk2_ao.hw,
  712. [RPMH_RF_CLK3] = &pineapple_rf_clk3.hw,
  713. [RPMH_RF_CLK3_A] = &pineapple_rf_clk3_ao.hw,
  714. [RPMH_RF_CLK4] = &pineapple_rf_clk4.hw,
  715. [RPMH_RF_CLK4_A] = &pineapple_rf_clk4_ao.hw,
  716. [RPMH_RF_CLK5] = &pineapple_rf_clk5.hw,
  717. [RPMH_RF_CLK5_A] = &pineapple_rf_clk5_ao.hw,
  718. [RPMH_IPA_CLK] = &sdm845_ipa.hw,
  719. };
  720. static const struct clk_rpmh_desc clk_rpmh_pineapple = {
  721. .clks = pineapple_rpmh_clocks,
  722. .num_clks = ARRAY_SIZE(pineapple_rpmh_clocks),
  723. };
  724. static struct clk_hw *sm6150_rpmh_clocks[] = {
  725. [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw,
  726. [RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw,
  727. [RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw,
  728. [RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw,
  729. [RPMH_LN_BB_CLK3] = &sdm845_ln_bb_clk3.hw,
  730. [RPMH_LN_BB_CLK3_A] = &sdm845_ln_bb_clk3_ao.hw,
  731. [RPMH_RF_CLK1] = &sdm845_rf_clk1.hw,
  732. [RPMH_RF_CLK1_A] = &sdm845_rf_clk1_ao.hw,
  733. [RPMH_RF_CLK2] = &sdm845_rf_clk2.hw,
  734. [RPMH_RF_CLK2_A] = &sdm845_rf_clk2_ao.hw,
  735. };
  736. static const struct clk_rpmh_desc clk_rpmh_sm6150 = {
  737. .clks = sm6150_rpmh_clocks,
  738. .num_clks = ARRAY_SIZE(sm6150_rpmh_clocks),
  739. };
  740. static struct clk_hw *cliffs_rpmh_clocks[] = {
  741. [RPMH_CXO_PAD_CLK] = &pineapple_xo_pad.hw,
  742. [RPMH_CXO_PAD_CLK_A] = &pineapple_xo_pad_ao.hw,
  743. [RPMH_CXO_CLK] = &pineapple_bi_tcxo.hw,
  744. [RPMH_CXO_CLK_A] = &pineapple_bi_tcxo_ao.hw,
  745. [RPMH_LN_BB_CLK2] = &pineapple_ln_bb_clk2.hw,
  746. [RPMH_LN_BB_CLK2_A] = &pineapple_ln_bb_clk2_ao.hw,
  747. [RPMH_LN_BB_CLK3] = &pineapple_ln_bb_clk3.hw,
  748. [RPMH_LN_BB_CLK3_A] = &pineapple_ln_bb_clk3_ao.hw,
  749. [RPMH_RF_CLK1] = &pineapple_rf_clk1.hw,
  750. [RPMH_RF_CLK1_A] = &pineapple_rf_clk1_ao.hw,
  751. [RPMH_RF_CLK2] = &pineapple_rf_clk2.hw,
  752. [RPMH_RF_CLK2_A] = &pineapple_rf_clk2_ao.hw,
  753. [RPMH_IPA_CLK] = &sdm845_ipa.hw,
  754. };
  755. static const struct clk_rpmh_desc clk_rpmh_cliffs = {
  756. .clks = cliffs_rpmh_clocks,
  757. .num_clks = ARRAY_SIZE(cliffs_rpmh_clocks),
  758. };
  759. static struct clk_hw *niobe_rpmh_clocks[] = {
  760. [RPMH_CXO_PAD_CLK] = &pineapple_xo_pad.hw,
  761. [RPMH_CXO_PAD_CLK_A] = &pineapple_xo_pad_ao.hw,
  762. [RPMH_CXO_CLK] = &pineapple_bi_tcxo.hw,
  763. [RPMH_CXO_CLK_A] = &pineapple_bi_tcxo_ao.hw,
  764. [RPMH_LN_BB_CLK3] = &pineapple_ln_bb_clk3.hw,
  765. [RPMH_LN_BB_CLK3_A] = &pineapple_ln_bb_clk3_ao.hw,
  766. [RPMH_RF_CLK1] = &pineapple_rf_clk1.hw,
  767. [RPMH_RF_CLK1_A] = &pineapple_rf_clk1_ao.hw,
  768. [RPMH_IPA_CLK] = &sdm845_ipa.hw,
  769. };
  770. static const struct clk_rpmh_desc clk_rpmh_niobe = {
  771. .clks = niobe_rpmh_clocks,
  772. .num_clks = ARRAY_SIZE(niobe_rpmh_clocks),
  773. };
  774. DEFINE_CLK_RPMH_VRM_OPT(volcano, ln_bb_clk2, ln_bb_clk2_ao, "clka7", 4);
  775. DEFINE_CLK_RPMH_VRM_OPT(volcano, ln_bb_clk3, ln_bb_clk3_ao, "clka8", 4);
  776. DEFINE_CLK_RPMH_VRM_OPT(volcano, ln_bb_clk4, ln_bb_clk4_ao, "clka9", 2);
  777. static struct clk_hw *volcano_rpmh_clocks[] = {
  778. [RPMH_CXO_PAD_CLK] = &pineapple_xo_pad.hw,
  779. [RPMH_CXO_PAD_CLK_A] = &pineapple_xo_pad_ao.hw,
  780. [RPMH_CXO_CLK] = &pineapple_bi_tcxo.hw,
  781. [RPMH_CXO_CLK_A] = &pineapple_bi_tcxo_ao.hw,
  782. [RPMH_LN_BB_CLK2] = &volcano_ln_bb_clk2.hw,
  783. [RPMH_LN_BB_CLK2_A] = &volcano_ln_bb_clk2_ao.hw,
  784. [RPMH_LN_BB_CLK3] = &volcano_ln_bb_clk3.hw,
  785. [RPMH_LN_BB_CLK3_A] = &volcano_ln_bb_clk3_ao.hw,
  786. [RPMH_LN_BB_CLK4] = &volcano_ln_bb_clk4.hw,
  787. [RPMH_LN_BB_CLK4_A] = &volcano_ln_bb_clk4_ao.hw,
  788. [RPMH_RF_CLK1] = &pineapple_rf_clk1.hw,
  789. [RPMH_RF_CLK1_A] = &pineapple_rf_clk1_ao.hw,
  790. [RPMH_RF_CLK2] = &pineapple_rf_clk2.hw,
  791. [RPMH_RF_CLK2_A] = &pineapple_rf_clk2_ao.hw,
  792. [RPMH_RF_CLK3] = &kalama_rf_clk3.hw,
  793. [RPMH_RF_CLK3_A] = &kalama_rf_clk3_ao.hw,
  794. [RPMH_IPA_CLK] = &sdm845_ipa.hw,
  795. };
  796. static const struct clk_rpmh_desc clk_rpmh_volcano = {
  797. .clks = volcano_rpmh_clocks,
  798. .num_clks = ARRAY_SIZE(volcano_rpmh_clocks),
  799. };
  800. static int clk_rpmh_probe(struct platform_device *pdev)
  801. {
  802. struct clk_hw **hw_clks;
  803. struct clk_rpmh *rpmh_clk;
  804. const struct clk_rpmh_desc *desc;
  805. int ret, i;
  806. desc = of_device_get_match_data(&pdev->dev);
  807. if (!desc)
  808. return -ENODEV;
  809. hw_clks = desc->clks;
  810. for (i = 0; i < desc->num_clks; i++) {
  811. const char *name;
  812. u32 res_addr;
  813. size_t aux_data_len;
  814. const struct bcm_db *data;
  815. if (!hw_clks[i])
  816. continue;
  817. name = hw_clks[i]->init->name;
  818. if (hw_clks[i]->init->ops != &clk_fixed_factor_ops) {
  819. rpmh_clk = to_clk_rpmh(hw_clks[i]);
  820. res_addr = cmd_db_read_addr(rpmh_clk->res_name);
  821. if (!res_addr) {
  822. hw_clks[i] = NULL;
  823. if (rpmh_clk->optional)
  824. continue;
  825. WARN(1, "clk-rpmh: Missing RPMh resource address for %s\n",
  826. rpmh_clk->res_name);
  827. return -ENODEV;
  828. }
  829. data = cmd_db_read_aux_data(rpmh_clk->res_name, &aux_data_len);
  830. if (IS_ERR(data)) {
  831. ret = PTR_ERR(data);
  832. WARN(1, "clk-rpmh: error reading RPMh aux data for %s (%d)\n",
  833. rpmh_clk->res_name, ret);
  834. return ret;
  835. }
  836. /* Convert unit from Khz to Hz */
  837. if (aux_data_len == sizeof(*data))
  838. rpmh_clk->unit = le32_to_cpu(data->unit) * 1000ULL;
  839. rpmh_clk->res_addr += res_addr;
  840. rpmh_clk->dev = &pdev->dev;
  841. }
  842. ret = devm_clk_hw_register(&pdev->dev, hw_clks[i]);
  843. if (ret) {
  844. dev_err(&pdev->dev, "failed to register %s\n", name);
  845. return ret;
  846. }
  847. }
  848. /* typecast to silence compiler warning */
  849. ret = devm_of_clk_add_hw_provider(&pdev->dev, of_clk_rpmh_hw_get,
  850. (void *)desc);
  851. if (ret) {
  852. dev_err(&pdev->dev, "Failed to add clock provider\n");
  853. return ret;
  854. }
  855. dev_dbg(&pdev->dev, "Registered RPMh clocks\n");
  856. return 0;
  857. }
  858. static const struct of_device_id clk_rpmh_match_table[] = {
  859. { .compatible = "qcom,sc7180-rpmh-clk", .data = &clk_rpmh_sc7180},
  860. { .compatible = "qcom,sc8180x-rpmh-clk", .data = &clk_rpmh_sc8180x},
  861. { .compatible = "qcom,sc8280xp-rpmh-clk", .data = &clk_rpmh_sc8280xp},
  862. { .compatible = "qcom,sdm845-rpmh-clk", .data = &clk_rpmh_sdm845},
  863. { .compatible = "qcom,sdm670-rpmh-clk", .data = &clk_rpmh_sdm670},
  864. { .compatible = "qcom,sdx55-rpmh-clk", .data = &clk_rpmh_sdx55},
  865. { .compatible = "qcom,sdx65-rpmh-clk", .data = &clk_rpmh_sdx65},
  866. { .compatible = "qcom,sm6350-rpmh-clk", .data = &clk_rpmh_sm6350},
  867. { .compatible = "qcom,sm8150-rpmh-clk", .data = &clk_rpmh_sm8150},
  868. { .compatible = "qcom,sm8250-rpmh-clk", .data = &clk_rpmh_sm8250},
  869. { .compatible = "qcom,sm8350-rpmh-clk", .data = &clk_rpmh_sm8350},
  870. { .compatible = "qcom,sm8450-rpmh-clk", .data = &clk_rpmh_sm8450},
  871. { .compatible = "qcom,sc7280-rpmh-clk", .data = &clk_rpmh_sc7280},
  872. { .compatible = "qcom,kalama-rpmh-clk", .data = &clk_rpmh_kalama},
  873. { .compatible = "qcom,pineapple-rpmh-clk", .data = &clk_rpmh_pineapple},
  874. { .compatible = "qcom,sm6150-rpmh-clk", .data = &clk_rpmh_sm6150},
  875. { .compatible = "qcom,lemans-rpmh-clk", .data = &clk_rpmh_lemans},
  876. { .compatible = "qcom,cliffs-rpmh-clk", .data = &clk_rpmh_cliffs},
  877. { .compatible = "qcom,niobe-rpmh-clk", .data = &clk_rpmh_niobe},
  878. { .compatible = "qcom,volcano-rpmh-clk", .data = &clk_rpmh_volcano},
  879. { .compatible = "qcom,anorak-rpmh-clk", .data = &clk_rpmh_anorak},
  880. { }
  881. };
  882. MODULE_DEVICE_TABLE(of, clk_rpmh_match_table);
  883. static struct platform_driver clk_rpmh_driver = {
  884. .probe = clk_rpmh_probe,
  885. .driver = {
  886. .name = "clk-rpmh",
  887. .of_match_table = clk_rpmh_match_table,
  888. },
  889. };
  890. static int __init clk_rpmh_init(void)
  891. {
  892. return platform_driver_register(&clk_rpmh_driver);
  893. }
  894. core_initcall(clk_rpmh_init);
  895. static void __exit clk_rpmh_exit(void)
  896. {
  897. platform_driver_unregister(&clk_rpmh_driver);
  898. }
  899. module_exit(clk_rpmh_exit);
  900. MODULE_DESCRIPTION("QCOM RPMh Clock Driver");
  901. MODULE_LICENSE("GPL v2");