clk-bpmp.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. /*
  2. * Copyright (C) 2016 NVIDIA Corporation
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 as
  6. * published by the Free Software Foundation.
  7. */
  8. #include <linux/clk-provider.h>
  9. #include <linux/device.h>
  10. #include <linux/seq_buf.h>
  11. #include <linux/slab.h>
  12. #include <soc/tegra/bpmp.h>
  13. #include <soc/tegra/bpmp-abi.h>
  14. #define TEGRA_BPMP_DUMP_CLOCK_INFO 0
  15. #define TEGRA_BPMP_CLK_HAS_MUX BIT(0)
  16. #define TEGRA_BPMP_CLK_HAS_SET_RATE BIT(1)
  17. #define TEGRA_BPMP_CLK_IS_ROOT BIT(2)
  18. struct tegra_bpmp_clk_info {
  19. unsigned int id;
  20. char name[MRQ_CLK_NAME_MAXLEN];
  21. unsigned int parents[MRQ_CLK_MAX_PARENTS];
  22. unsigned int num_parents;
  23. unsigned long flags;
  24. };
  25. struct tegra_bpmp_clk {
  26. struct clk_hw hw;
  27. struct tegra_bpmp *bpmp;
  28. unsigned int id;
  29. unsigned int num_parents;
  30. unsigned int *parents;
  31. };
  32. static inline struct tegra_bpmp_clk *to_tegra_bpmp_clk(struct clk_hw *hw)
  33. {
  34. return container_of(hw, struct tegra_bpmp_clk, hw);
  35. }
  36. struct tegra_bpmp_clk_message {
  37. unsigned int cmd;
  38. unsigned int id;
  39. struct {
  40. const void *data;
  41. size_t size;
  42. } tx;
  43. struct {
  44. void *data;
  45. size_t size;
  46. int ret;
  47. } rx;
  48. };
  49. static int tegra_bpmp_clk_transfer(struct tegra_bpmp *bpmp,
  50. const struct tegra_bpmp_clk_message *clk)
  51. {
  52. struct mrq_clk_request request;
  53. struct tegra_bpmp_message msg;
  54. void *req = &request;
  55. int err;
  56. memset(&request, 0, sizeof(request));
  57. request.cmd_and_id = (clk->cmd << 24) | clk->id;
  58. /*
  59. * The mrq_clk_request structure has an anonymous union at offset 4
  60. * that contains all possible sub-command structures. Copy the data
  61. * to that union. Ideally we'd be able to refer to it by name, but
  62. * doing so would require changing the ABI header and increase the
  63. * maintenance burden.
  64. */
  65. memcpy(req + 4, clk->tx.data, clk->tx.size);
  66. memset(&msg, 0, sizeof(msg));
  67. msg.mrq = MRQ_CLK;
  68. msg.tx.data = &request;
  69. msg.tx.size = sizeof(request);
  70. msg.rx.data = clk->rx.data;
  71. msg.rx.size = clk->rx.size;
  72. err = tegra_bpmp_transfer(bpmp, &msg);
  73. if (err < 0)
  74. return err;
  75. else if (msg.rx.ret < 0)
  76. return -EINVAL;
  77. return 0;
  78. }
  79. static int tegra_bpmp_clk_prepare(struct clk_hw *hw)
  80. {
  81. struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
  82. struct tegra_bpmp_clk_message msg;
  83. memset(&msg, 0, sizeof(msg));
  84. msg.cmd = CMD_CLK_ENABLE;
  85. msg.id = clk->id;
  86. return tegra_bpmp_clk_transfer(clk->bpmp, &msg);
  87. }
  88. static void tegra_bpmp_clk_unprepare(struct clk_hw *hw)
  89. {
  90. struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
  91. struct tegra_bpmp_clk_message msg;
  92. int err;
  93. memset(&msg, 0, sizeof(msg));
  94. msg.cmd = CMD_CLK_DISABLE;
  95. msg.id = clk->id;
  96. err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
  97. if (err < 0)
  98. dev_err(clk->bpmp->dev, "failed to disable clock %s: %d\n",
  99. clk_hw_get_name(hw), err);
  100. }
  101. static int tegra_bpmp_clk_is_prepared(struct clk_hw *hw)
  102. {
  103. struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
  104. struct cmd_clk_is_enabled_response response;
  105. struct tegra_bpmp_clk_message msg;
  106. int err;
  107. memset(&msg, 0, sizeof(msg));
  108. msg.cmd = CMD_CLK_IS_ENABLED;
  109. msg.id = clk->id;
  110. msg.rx.data = &response;
  111. msg.rx.size = sizeof(response);
  112. err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
  113. if (err < 0)
  114. return err;
  115. return response.state;
  116. }
  117. static unsigned long tegra_bpmp_clk_recalc_rate(struct clk_hw *hw,
  118. unsigned long parent_rate)
  119. {
  120. struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
  121. struct cmd_clk_get_rate_response response;
  122. struct cmd_clk_get_rate_request request;
  123. struct tegra_bpmp_clk_message msg;
  124. int err;
  125. memset(&msg, 0, sizeof(msg));
  126. msg.cmd = CMD_CLK_GET_RATE;
  127. msg.id = clk->id;
  128. msg.tx.data = &request;
  129. msg.tx.size = sizeof(request);
  130. msg.rx.data = &response;
  131. msg.rx.size = sizeof(response);
  132. err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
  133. if (err < 0)
  134. return err;
  135. return response.rate;
  136. }
  137. static long tegra_bpmp_clk_round_rate(struct clk_hw *hw, unsigned long rate,
  138. unsigned long *parent_rate)
  139. {
  140. struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
  141. struct cmd_clk_round_rate_response response;
  142. struct cmd_clk_round_rate_request request;
  143. struct tegra_bpmp_clk_message msg;
  144. int err;
  145. memset(&request, 0, sizeof(request));
  146. request.rate = rate;
  147. memset(&msg, 0, sizeof(msg));
  148. msg.cmd = CMD_CLK_ROUND_RATE;
  149. msg.id = clk->id;
  150. msg.tx.data = &request;
  151. msg.tx.size = sizeof(request);
  152. msg.rx.data = &response;
  153. msg.rx.size = sizeof(response);
  154. err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
  155. if (err < 0)
  156. return err;
  157. return response.rate;
  158. }
  159. static int tegra_bpmp_clk_set_parent(struct clk_hw *hw, u8 index)
  160. {
  161. struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
  162. struct cmd_clk_set_parent_response response;
  163. struct cmd_clk_set_parent_request request;
  164. struct tegra_bpmp_clk_message msg;
  165. int err;
  166. memset(&request, 0, sizeof(request));
  167. request.parent_id = clk->parents[index];
  168. memset(&msg, 0, sizeof(msg));
  169. msg.cmd = CMD_CLK_SET_PARENT;
  170. msg.id = clk->id;
  171. msg.tx.data = &request;
  172. msg.tx.size = sizeof(request);
  173. msg.rx.data = &response;
  174. msg.rx.size = sizeof(response);
  175. err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
  176. if (err < 0)
  177. return err;
  178. /* XXX check parent ID in response */
  179. return 0;
  180. }
  181. static u8 tegra_bpmp_clk_get_parent(struct clk_hw *hw)
  182. {
  183. struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
  184. struct cmd_clk_get_parent_response response;
  185. struct tegra_bpmp_clk_message msg;
  186. unsigned int i;
  187. int err;
  188. memset(&msg, 0, sizeof(msg));
  189. msg.cmd = CMD_CLK_GET_PARENT;
  190. msg.id = clk->id;
  191. msg.rx.data = &response;
  192. msg.rx.size = sizeof(response);
  193. err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
  194. if (err < 0) {
  195. dev_err(clk->bpmp->dev, "failed to get parent for %s: %d\n",
  196. clk_hw_get_name(hw), err);
  197. return U8_MAX;
  198. }
  199. for (i = 0; i < clk->num_parents; i++)
  200. if (clk->parents[i] == response.parent_id)
  201. return i;
  202. return U8_MAX;
  203. }
  204. static int tegra_bpmp_clk_set_rate(struct clk_hw *hw, unsigned long rate,
  205. unsigned long parent_rate)
  206. {
  207. struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
  208. struct cmd_clk_set_rate_response response;
  209. struct cmd_clk_set_rate_request request;
  210. struct tegra_bpmp_clk_message msg;
  211. memset(&request, 0, sizeof(request));
  212. request.rate = rate;
  213. memset(&msg, 0, sizeof(msg));
  214. msg.cmd = CMD_CLK_SET_RATE;
  215. msg.id = clk->id;
  216. msg.tx.data = &request;
  217. msg.tx.size = sizeof(request);
  218. msg.rx.data = &response;
  219. msg.rx.size = sizeof(response);
  220. return tegra_bpmp_clk_transfer(clk->bpmp, &msg);
  221. }
  222. static const struct clk_ops tegra_bpmp_clk_gate_ops = {
  223. .prepare = tegra_bpmp_clk_prepare,
  224. .unprepare = tegra_bpmp_clk_unprepare,
  225. .is_prepared = tegra_bpmp_clk_is_prepared,
  226. .recalc_rate = tegra_bpmp_clk_recalc_rate,
  227. };
  228. static const struct clk_ops tegra_bpmp_clk_mux_ops = {
  229. .prepare = tegra_bpmp_clk_prepare,
  230. .unprepare = tegra_bpmp_clk_unprepare,
  231. .is_prepared = tegra_bpmp_clk_is_prepared,
  232. .recalc_rate = tegra_bpmp_clk_recalc_rate,
  233. .set_parent = tegra_bpmp_clk_set_parent,
  234. .get_parent = tegra_bpmp_clk_get_parent,
  235. };
  236. static const struct clk_ops tegra_bpmp_clk_rate_ops = {
  237. .prepare = tegra_bpmp_clk_prepare,
  238. .unprepare = tegra_bpmp_clk_unprepare,
  239. .is_prepared = tegra_bpmp_clk_is_prepared,
  240. .recalc_rate = tegra_bpmp_clk_recalc_rate,
  241. .round_rate = tegra_bpmp_clk_round_rate,
  242. .set_rate = tegra_bpmp_clk_set_rate,
  243. };
  244. static const struct clk_ops tegra_bpmp_clk_mux_rate_ops = {
  245. .prepare = tegra_bpmp_clk_prepare,
  246. .unprepare = tegra_bpmp_clk_unprepare,
  247. .is_prepared = tegra_bpmp_clk_is_prepared,
  248. .recalc_rate = tegra_bpmp_clk_recalc_rate,
  249. .round_rate = tegra_bpmp_clk_round_rate,
  250. .set_parent = tegra_bpmp_clk_set_parent,
  251. .get_parent = tegra_bpmp_clk_get_parent,
  252. .set_rate = tegra_bpmp_clk_set_rate,
  253. };
  254. static int tegra_bpmp_clk_get_max_id(struct tegra_bpmp *bpmp)
  255. {
  256. struct cmd_clk_get_max_clk_id_response response;
  257. struct tegra_bpmp_clk_message msg;
  258. int err;
  259. memset(&msg, 0, sizeof(msg));
  260. msg.cmd = CMD_CLK_GET_MAX_CLK_ID;
  261. msg.rx.data = &response;
  262. msg.rx.size = sizeof(response);
  263. err = tegra_bpmp_clk_transfer(bpmp, &msg);
  264. if (err < 0)
  265. return err;
  266. if (response.max_id > INT_MAX)
  267. return -E2BIG;
  268. return response.max_id;
  269. }
  270. static int tegra_bpmp_clk_get_info(struct tegra_bpmp *bpmp, unsigned int id,
  271. struct tegra_bpmp_clk_info *info)
  272. {
  273. struct cmd_clk_get_all_info_response response;
  274. struct tegra_bpmp_clk_message msg;
  275. unsigned int i;
  276. int err;
  277. memset(&msg, 0, sizeof(msg));
  278. msg.cmd = CMD_CLK_GET_ALL_INFO;
  279. msg.id = id;
  280. msg.rx.data = &response;
  281. msg.rx.size = sizeof(response);
  282. err = tegra_bpmp_clk_transfer(bpmp, &msg);
  283. if (err < 0)
  284. return err;
  285. strlcpy(info->name, response.name, MRQ_CLK_NAME_MAXLEN);
  286. info->num_parents = response.num_parents;
  287. for (i = 0; i < info->num_parents; i++)
  288. info->parents[i] = response.parents[i];
  289. info->flags = response.flags;
  290. return 0;
  291. }
  292. static void tegra_bpmp_clk_info_dump(struct tegra_bpmp *bpmp,
  293. const char *level,
  294. const struct tegra_bpmp_clk_info *info)
  295. {
  296. const char *prefix = "";
  297. struct seq_buf buf;
  298. unsigned int i;
  299. char flags[64];
  300. seq_buf_init(&buf, flags, sizeof(flags));
  301. if (info->flags)
  302. seq_buf_printf(&buf, "(");
  303. if (info->flags & TEGRA_BPMP_CLK_HAS_MUX) {
  304. seq_buf_printf(&buf, "%smux", prefix);
  305. prefix = ", ";
  306. }
  307. if ((info->flags & TEGRA_BPMP_CLK_HAS_SET_RATE) == 0) {
  308. seq_buf_printf(&buf, "%sfixed", prefix);
  309. prefix = ", ";
  310. }
  311. if (info->flags & TEGRA_BPMP_CLK_IS_ROOT) {
  312. seq_buf_printf(&buf, "%sroot", prefix);
  313. prefix = ", ";
  314. }
  315. if (info->flags)
  316. seq_buf_printf(&buf, ")");
  317. dev_printk(level, bpmp->dev, "%03u: %s\n", info->id, info->name);
  318. dev_printk(level, bpmp->dev, " flags: %lx %s\n", info->flags, flags);
  319. dev_printk(level, bpmp->dev, " parents: %u\n", info->num_parents);
  320. for (i = 0; i < info->num_parents; i++)
  321. dev_printk(level, bpmp->dev, " %03u\n", info->parents[i]);
  322. }
  323. static int tegra_bpmp_probe_clocks(struct tegra_bpmp *bpmp,
  324. struct tegra_bpmp_clk_info **clocksp)
  325. {
  326. struct tegra_bpmp_clk_info *clocks;
  327. unsigned int max_id, id, count = 0;
  328. unsigned int holes = 0;
  329. int err;
  330. err = tegra_bpmp_clk_get_max_id(bpmp);
  331. if (err < 0)
  332. return err;
  333. max_id = err;
  334. dev_dbg(bpmp->dev, "maximum clock ID: %u\n", max_id);
  335. clocks = kcalloc(max_id + 1, sizeof(*clocks), GFP_KERNEL);
  336. if (!clocks)
  337. return -ENOMEM;
  338. for (id = 0; id <= max_id; id++) {
  339. struct tegra_bpmp_clk_info *info = &clocks[count];
  340. err = tegra_bpmp_clk_get_info(bpmp, id, info);
  341. if (err < 0)
  342. continue;
  343. if (info->num_parents >= U8_MAX) {
  344. dev_err(bpmp->dev,
  345. "clock %u has too many parents (%u, max: %u)\n",
  346. id, info->num_parents, U8_MAX);
  347. continue;
  348. }
  349. /* clock not exposed by BPMP */
  350. if (info->name[0] == '\0') {
  351. holes++;
  352. continue;
  353. }
  354. info->id = id;
  355. count++;
  356. if (TEGRA_BPMP_DUMP_CLOCK_INFO)
  357. tegra_bpmp_clk_info_dump(bpmp, KERN_DEBUG, info);
  358. }
  359. dev_dbg(bpmp->dev, "holes: %u\n", holes);
  360. *clocksp = clocks;
  361. return count;
  362. }
  363. static const struct tegra_bpmp_clk_info *
  364. tegra_bpmp_clk_find(const struct tegra_bpmp_clk_info *clocks,
  365. unsigned int num_clocks, unsigned int id)
  366. {
  367. unsigned int i;
  368. for (i = 0; i < num_clocks; i++)
  369. if (clocks[i].id == id)
  370. return &clocks[i];
  371. return NULL;
  372. }
  373. static struct tegra_bpmp_clk *
  374. tegra_bpmp_clk_register(struct tegra_bpmp *bpmp,
  375. const struct tegra_bpmp_clk_info *info,
  376. const struct tegra_bpmp_clk_info *clocks,
  377. unsigned int num_clocks)
  378. {
  379. struct tegra_bpmp_clk *clk;
  380. struct clk_init_data init;
  381. const char **parents;
  382. unsigned int i;
  383. int err;
  384. clk = devm_kzalloc(bpmp->dev, sizeof(*clk), GFP_KERNEL);
  385. if (!clk)
  386. return ERR_PTR(-ENOMEM);
  387. clk->id = info->id;
  388. clk->bpmp = bpmp;
  389. clk->parents = devm_kcalloc(bpmp->dev, info->num_parents,
  390. sizeof(*clk->parents), GFP_KERNEL);
  391. if (!clk->parents)
  392. return ERR_PTR(-ENOMEM);
  393. clk->num_parents = info->num_parents;
  394. /* hardware clock initialization */
  395. memset(&init, 0, sizeof(init));
  396. init.name = info->name;
  397. clk->hw.init = &init;
  398. if (info->flags & TEGRA_BPMP_CLK_HAS_MUX) {
  399. if (info->flags & TEGRA_BPMP_CLK_HAS_SET_RATE)
  400. init.ops = &tegra_bpmp_clk_mux_rate_ops;
  401. else
  402. init.ops = &tegra_bpmp_clk_mux_ops;
  403. } else {
  404. if (info->flags & TEGRA_BPMP_CLK_HAS_SET_RATE)
  405. init.ops = &tegra_bpmp_clk_rate_ops;
  406. else
  407. init.ops = &tegra_bpmp_clk_gate_ops;
  408. }
  409. init.num_parents = info->num_parents;
  410. parents = kcalloc(info->num_parents, sizeof(*parents), GFP_KERNEL);
  411. if (!parents)
  412. return ERR_PTR(-ENOMEM);
  413. for (i = 0; i < info->num_parents; i++) {
  414. const struct tegra_bpmp_clk_info *parent;
  415. /* keep a private copy of the ID to parent index map */
  416. clk->parents[i] = info->parents[i];
  417. parent = tegra_bpmp_clk_find(clocks, num_clocks,
  418. info->parents[i]);
  419. if (!parent) {
  420. dev_err(bpmp->dev, "no parent %u found for %u\n",
  421. info->parents[i], info->id);
  422. continue;
  423. }
  424. parents[i] = parent->name;
  425. }
  426. init.parent_names = parents;
  427. err = devm_clk_hw_register(bpmp->dev, &clk->hw);
  428. kfree(parents);
  429. if (err < 0)
  430. return ERR_PTR(err);
  431. return clk;
  432. }
  433. static int tegra_bpmp_register_clocks(struct tegra_bpmp *bpmp,
  434. struct tegra_bpmp_clk_info *infos,
  435. unsigned int count)
  436. {
  437. struct tegra_bpmp_clk *clk;
  438. unsigned int i;
  439. bpmp->num_clocks = count;
  440. bpmp->clocks = devm_kcalloc(bpmp->dev, count, sizeof(clk), GFP_KERNEL);
  441. if (!bpmp->clocks)
  442. return -ENOMEM;
  443. for (i = 0; i < count; i++) {
  444. struct tegra_bpmp_clk_info *info = &infos[i];
  445. clk = tegra_bpmp_clk_register(bpmp, info, infos, count);
  446. if (IS_ERR(clk)) {
  447. dev_err(bpmp->dev,
  448. "failed to register clock %u (%s): %ld\n",
  449. info->id, info->name, PTR_ERR(clk));
  450. continue;
  451. }
  452. bpmp->clocks[i] = clk;
  453. }
  454. return 0;
  455. }
  456. static void tegra_bpmp_unregister_clocks(struct tegra_bpmp *bpmp)
  457. {
  458. unsigned int i;
  459. for (i = 0; i < bpmp->num_clocks; i++)
  460. clk_hw_unregister(&bpmp->clocks[i]->hw);
  461. }
  462. static struct clk_hw *tegra_bpmp_clk_of_xlate(struct of_phandle_args *clkspec,
  463. void *data)
  464. {
  465. unsigned int id = clkspec->args[0], i;
  466. struct tegra_bpmp *bpmp = data;
  467. for (i = 0; i < bpmp->num_clocks; i++) {
  468. struct tegra_bpmp_clk *clk = bpmp->clocks[i];
  469. if (!clk)
  470. continue;
  471. if (clk->id == id)
  472. return &clk->hw;
  473. }
  474. return NULL;
  475. }
  476. int tegra_bpmp_init_clocks(struct tegra_bpmp *bpmp)
  477. {
  478. struct tegra_bpmp_clk_info *clocks;
  479. unsigned int count;
  480. int err;
  481. err = tegra_bpmp_probe_clocks(bpmp, &clocks);
  482. if (err < 0)
  483. return err;
  484. count = err;
  485. dev_dbg(bpmp->dev, "%u clocks probed\n", count);
  486. err = tegra_bpmp_register_clocks(bpmp, clocks, count);
  487. if (err < 0)
  488. goto free;
  489. err = of_clk_add_hw_provider(bpmp->dev->of_node,
  490. tegra_bpmp_clk_of_xlate,
  491. bpmp);
  492. if (err < 0) {
  493. tegra_bpmp_unregister_clocks(bpmp);
  494. goto free;
  495. }
  496. free:
  497. kfree(clocks);
  498. return err;
  499. }