dsi_clk_manager.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
  4. */
  5. #include <linux/of.h>
  6. #include <linux/delay.h>
  7. #include <linux/slab.h>
  8. #include <linux/pm_runtime.h>
  9. #include "dsi_clk.h"
  10. #include "dsi_defs.h"
  11. struct dsi_core_clks {
  12. struct dsi_core_clk_info clks;
  13. };
  14. struct dsi_link_clks {
  15. struct dsi_link_hs_clk_info hs_clks;
  16. struct dsi_link_lp_clk_info lp_clks;
  17. struct link_clk_freq freq;
  18. };
  19. struct dsi_clk_mngr {
  20. char name[MAX_STRING_LEN];
  21. struct mutex clk_mutex;
  22. struct list_head client_list;
  23. u32 dsi_ctrl_count;
  24. u32 master_ndx;
  25. struct dsi_core_clks core_clks[MAX_DSI_CTRL];
  26. struct dsi_link_clks link_clks[MAX_DSI_CTRL];
  27. u32 ctrl_index[MAX_DSI_CTRL];
  28. u32 core_clk_state;
  29. u32 link_clk_state;
  30. pre_clockoff_cb pre_clkoff_cb;
  31. post_clockoff_cb post_clkoff_cb;
  32. post_clockon_cb post_clkon_cb;
  33. pre_clockon_cb pre_clkon_cb;
  34. bool is_cont_splash_enabled;
  35. void *priv_data;
  36. };
  37. struct dsi_clk_client_info {
  38. char name[MAX_STRING_LEN];
  39. u32 core_refcount;
  40. u32 link_refcount;
  41. u32 core_clk_state;
  42. u32 link_clk_state;
  43. struct list_head list;
  44. struct dsi_clk_mngr *mngr;
  45. };
  46. static int _get_clk_mngr_index(struct dsi_clk_mngr *mngr,
  47. u32 dsi_ctrl_index,
  48. u32 *clk_mngr_index)
  49. {
  50. int i;
  51. for (i = 0; i < mngr->dsi_ctrl_count; i++) {
  52. if (mngr->ctrl_index[i] == dsi_ctrl_index) {
  53. *clk_mngr_index = i;
  54. return 0;
  55. }
  56. }
  57. return -EINVAL;
  58. }
  59. /**
  60. * dsi_clk_set_link_frequencies() - set frequencies for link clks
  61. * @clks: Link clock information
  62. * @pixel_clk: pixel clock frequency in KHz.
  63. * @byte_clk: Byte clock frequency in KHz.
  64. * @esc_clk: Escape clock frequency in KHz.
  65. *
  66. * return: error code in case of failure or 0 for success.
  67. */
  68. int dsi_clk_set_link_frequencies(void *client, struct link_clk_freq freq,
  69. u32 index)
  70. {
  71. int rc = 0, clk_mngr_index = 0;
  72. struct dsi_clk_client_info *c = client;
  73. struct dsi_clk_mngr *mngr;
  74. if (!client) {
  75. DSI_ERR("invalid params\n");
  76. return -EINVAL;
  77. }
  78. mngr = c->mngr;
  79. rc = _get_clk_mngr_index(mngr, index, &clk_mngr_index);
  80. if (rc) {
  81. DSI_ERR("failed to map control index %d\n", index);
  82. return -EINVAL;
  83. }
  84. memcpy(&mngr->link_clks[clk_mngr_index].freq, &freq,
  85. sizeof(struct link_clk_freq));
  86. return rc;
  87. }
  88. /**
  89. * dsi_clk_set_pixel_clk_rate() - set frequency for pixel clock
  90. * @clks: DSI link clock information.
  91. * @pixel_clk: Pixel clock rate in KHz.
  92. * @index: Index of the DSI controller.
  93. *
  94. * return: error code in case of failure or 0 for success.
  95. */
  96. int dsi_clk_set_pixel_clk_rate(void *client, u64 pixel_clk, u32 index)
  97. {
  98. int rc = 0;
  99. struct dsi_clk_client_info *c = client;
  100. struct dsi_clk_mngr *mngr;
  101. mngr = c->mngr;
  102. rc = clk_set_rate(mngr->link_clks[index].hs_clks.pixel_clk, pixel_clk);
  103. if (rc)
  104. DSI_ERR("failed to set clk rate for pixel clk, rc=%d\n", rc);
  105. else
  106. mngr->link_clks[index].freq.pix_clk_rate = pixel_clk;
  107. return rc;
  108. }
  109. /**
  110. * dsi_clk_set_byte_clk_rate() - set frequency for byte clock
  111. * @client: DSI clock client pointer.
  112. * @byte_clk: Byte clock rate in Hz.
  113. * @byte_intf_clk: Byte interface clock rate in Hz.
  114. * @index: Index of the DSI controller.
  115. * return: error code in case of failure or 0 for success.
  116. */
  117. int dsi_clk_set_byte_clk_rate(void *client, u64 byte_clk,
  118. u64 byte_intf_clk, u32 index)
  119. {
  120. int rc = 0;
  121. struct dsi_clk_client_info *c = client;
  122. struct dsi_clk_mngr *mngr;
  123. mngr = c->mngr;
  124. rc = clk_set_rate(mngr->link_clks[index].hs_clks.byte_clk, byte_clk);
  125. if (rc)
  126. DSI_ERR("failed to set clk rate for byte clk, rc=%d\n", rc);
  127. else
  128. mngr->link_clks[index].freq.byte_clk_rate = byte_clk;
  129. if (mngr->link_clks[index].hs_clks.byte_intf_clk) {
  130. rc = clk_set_rate(mngr->link_clks[index].hs_clks.byte_intf_clk,
  131. byte_intf_clk);
  132. if (rc)
  133. DSI_ERR("failed to set clk rate for byte intf clk=%d\n",
  134. rc);
  135. else
  136. mngr->link_clks[index].freq.byte_intf_clk_rate =
  137. byte_intf_clk;
  138. }
  139. return rc;
  140. }
  141. /**
  142. * dsi_clk_update_parent() - update parent clocks for specified clock
  143. * @parent: link clock pair which are set as parent.
  144. * @child: link clock pair whose parent has to be set.
  145. */
  146. int dsi_clk_update_parent(struct dsi_clk_link_set *parent,
  147. struct dsi_clk_link_set *child)
  148. {
  149. int rc = 0;
  150. rc = clk_set_parent(child->byte_clk, parent->byte_clk);
  151. if (rc) {
  152. DSI_ERR("failed to set byte clk parent\n");
  153. goto error;
  154. }
  155. rc = clk_set_parent(child->pixel_clk, parent->pixel_clk);
  156. if (rc) {
  157. DSI_ERR("failed to set pixel clk parent\n");
  158. goto error;
  159. }
  160. error:
  161. return rc;
  162. }
  163. /**
  164. * dsi_clk_prepare_enable() - prepare and enable dsi src clocks
  165. * @clk: list of src clocks.
  166. *
  167. * @return: Zero on success and err no on failure.
  168. */
  169. int dsi_clk_prepare_enable(struct dsi_clk_link_set *clk)
  170. {
  171. int rc;
  172. rc = clk_prepare_enable(clk->byte_clk);
  173. if (rc) {
  174. DSI_ERR("failed to enable byte src clk %d\n", rc);
  175. return rc;
  176. }
  177. rc = clk_prepare_enable(clk->pixel_clk);
  178. if (rc) {
  179. DSI_ERR("failed to enable pixel src clk %d\n", rc);
  180. return rc;
  181. }
  182. return 0;
  183. }
  184. /**
  185. * dsi_clk_disable_unprepare() - disable and unprepare dsi src clocks
  186. * @clk: list of src clocks.
  187. */
  188. void dsi_clk_disable_unprepare(struct dsi_clk_link_set *clk)
  189. {
  190. clk_disable_unprepare(clk->pixel_clk);
  191. clk_disable_unprepare(clk->byte_clk);
  192. }
  193. int dsi_core_clk_start(struct dsi_core_clks *c_clks)
  194. {
  195. int rc = 0;
  196. if (c_clks->clks.mdp_core_clk) {
  197. rc = clk_prepare_enable(c_clks->clks.mdp_core_clk);
  198. if (rc) {
  199. DSI_ERR("failed to enable mdp_core_clk, rc=%d\n", rc);
  200. goto error;
  201. }
  202. }
  203. if (c_clks->clks.mnoc_clk) {
  204. rc = clk_prepare_enable(c_clks->clks.mnoc_clk);
  205. if (rc) {
  206. DSI_ERR("failed to enable mnoc_clk, rc=%d\n", rc);
  207. goto error_disable_core_clk;
  208. }
  209. }
  210. if (c_clks->clks.iface_clk) {
  211. rc = clk_prepare_enable(c_clks->clks.iface_clk);
  212. if (rc) {
  213. DSI_ERR("failed to enable iface_clk, rc=%d\n", rc);
  214. goto error_disable_mnoc_clk;
  215. }
  216. }
  217. if (c_clks->clks.bus_clk) {
  218. rc = clk_prepare_enable(c_clks->clks.bus_clk);
  219. if (rc) {
  220. DSI_ERR("failed to enable bus_clk, rc=%d\n", rc);
  221. goto error_disable_iface_clk;
  222. }
  223. }
  224. if (c_clks->clks.core_mmss_clk) {
  225. rc = clk_prepare_enable(c_clks->clks.core_mmss_clk);
  226. if (rc) {
  227. DSI_ERR("failed to enable core_mmss_clk, rc=%d\n", rc);
  228. goto error_disable_bus_clk;
  229. }
  230. }
  231. return rc;
  232. error_disable_bus_clk:
  233. if (c_clks->clks.bus_clk)
  234. clk_disable_unprepare(c_clks->clks.bus_clk);
  235. error_disable_iface_clk:
  236. if (c_clks->clks.iface_clk)
  237. clk_disable_unprepare(c_clks->clks.iface_clk);
  238. error_disable_mnoc_clk:
  239. if (c_clks->clks.mnoc_clk)
  240. clk_disable_unprepare(c_clks->clks.mnoc_clk);
  241. error_disable_core_clk:
  242. if (c_clks->clks.mdp_core_clk)
  243. clk_disable_unprepare(c_clks->clks.mdp_core_clk);
  244. error:
  245. return rc;
  246. }
  247. int dsi_core_clk_stop(struct dsi_core_clks *c_clks)
  248. {
  249. int rc = 0;
  250. if (c_clks->clks.core_mmss_clk)
  251. clk_disable_unprepare(c_clks->clks.core_mmss_clk);
  252. if (c_clks->clks.bus_clk)
  253. clk_disable_unprepare(c_clks->clks.bus_clk);
  254. if (c_clks->clks.iface_clk)
  255. clk_disable_unprepare(c_clks->clks.iface_clk);
  256. if (c_clks->clks.mnoc_clk)
  257. clk_disable_unprepare(c_clks->clks.mnoc_clk);
  258. if (c_clks->clks.mdp_core_clk)
  259. clk_disable_unprepare(c_clks->clks.mdp_core_clk);
  260. return rc;
  261. }
  262. static int dsi_link_hs_clk_set_rate(struct dsi_link_hs_clk_info *link_hs_clks,
  263. int index)
  264. {
  265. int rc = 0;
  266. struct dsi_clk_mngr *mngr;
  267. struct dsi_link_clks *l_clks;
  268. if (index >= MAX_DSI_CTRL) {
  269. DSI_ERR("Invalid DSI ctrl index\n");
  270. return -EINVAL;
  271. }
  272. l_clks = container_of(link_hs_clks, struct dsi_link_clks, hs_clks);
  273. mngr = container_of(l_clks, struct dsi_clk_mngr, link_clks[index]);
  274. /*
  275. * In an ideal world, cont_splash_enabled should not be required inside
  276. * the clock manager. But, in the current driver cont_splash_enabled
  277. * flag is set inside mdp driver and there is no interface event
  278. * associated with this flag setting.
  279. */
  280. if (mngr->is_cont_splash_enabled)
  281. return 0;
  282. rc = clk_set_rate(link_hs_clks->byte_clk,
  283. l_clks->freq.byte_clk_rate);
  284. if (rc) {
  285. DSI_ERR("clk_set_rate failed for byte_clk rc = %d\n", rc);
  286. goto error;
  287. }
  288. rc = clk_set_rate(link_hs_clks->pixel_clk,
  289. l_clks->freq.pix_clk_rate);
  290. if (rc) {
  291. DSI_ERR("clk_set_rate failed for pixel_clk rc = %d\n", rc);
  292. goto error;
  293. }
  294. /*
  295. * If byte_intf_clk is present, set rate for that too.
  296. */
  297. if (link_hs_clks->byte_intf_clk) {
  298. rc = clk_set_rate(link_hs_clks->byte_intf_clk,
  299. l_clks->freq.byte_intf_clk_rate);
  300. if (rc) {
  301. DSI_ERR("set_rate failed for byte_intf_clk rc = %d\n",
  302. rc);
  303. goto error;
  304. }
  305. }
  306. error:
  307. return rc;
  308. }
  309. static int dsi_link_hs_clk_prepare(struct dsi_link_hs_clk_info *link_hs_clks)
  310. {
  311. int rc = 0;
  312. rc = clk_prepare(link_hs_clks->byte_clk);
  313. if (rc) {
  314. DSI_ERR("Failed to prepare dsi byte clk, rc=%d\n", rc);
  315. goto byte_clk_err;
  316. }
  317. rc = clk_prepare(link_hs_clks->pixel_clk);
  318. if (rc) {
  319. DSI_ERR("Failed to prepare dsi pixel clk, rc=%d\n", rc);
  320. goto pixel_clk_err;
  321. }
  322. if (link_hs_clks->byte_intf_clk) {
  323. rc = clk_prepare(link_hs_clks->byte_intf_clk);
  324. if (rc) {
  325. DSI_ERR("Failed to prepare dsi byte intf clk, rc=%d\n",
  326. rc);
  327. goto byte_intf_clk_err;
  328. }
  329. }
  330. return rc;
  331. byte_intf_clk_err:
  332. clk_unprepare(link_hs_clks->pixel_clk);
  333. pixel_clk_err:
  334. clk_unprepare(link_hs_clks->byte_clk);
  335. byte_clk_err:
  336. return rc;
  337. }
  338. static void dsi_link_hs_clk_unprepare(struct dsi_link_hs_clk_info *link_hs_clks)
  339. {
  340. if (link_hs_clks->byte_intf_clk)
  341. clk_unprepare(link_hs_clks->byte_intf_clk);
  342. clk_unprepare(link_hs_clks->pixel_clk);
  343. clk_unprepare(link_hs_clks->byte_clk);
  344. }
  345. static int dsi_link_hs_clk_enable(struct dsi_link_hs_clk_info *link_hs_clks)
  346. {
  347. int rc = 0;
  348. rc = clk_enable(link_hs_clks->byte_clk);
  349. if (rc) {
  350. DSI_ERR("Failed to enable dsi byte clk, rc=%d\n", rc);
  351. goto byte_clk_err;
  352. }
  353. rc = clk_enable(link_hs_clks->pixel_clk);
  354. if (rc) {
  355. DSI_ERR("Failed to enable dsi pixel clk, rc=%d\n", rc);
  356. goto pixel_clk_err;
  357. }
  358. if (link_hs_clks->byte_intf_clk) {
  359. rc = clk_enable(link_hs_clks->byte_intf_clk);
  360. if (rc) {
  361. DSI_ERR("Failed to enable dsi byte intf clk, rc=%d\n",
  362. rc);
  363. goto byte_intf_clk_err;
  364. }
  365. }
  366. return rc;
  367. byte_intf_clk_err:
  368. clk_disable(link_hs_clks->pixel_clk);
  369. pixel_clk_err:
  370. clk_disable(link_hs_clks->byte_clk);
  371. byte_clk_err:
  372. return rc;
  373. }
  374. static void dsi_link_hs_clk_disable(struct dsi_link_hs_clk_info *link_hs_clks)
  375. {
  376. if (link_hs_clks->byte_intf_clk)
  377. clk_disable(link_hs_clks->byte_intf_clk);
  378. clk_disable(link_hs_clks->pixel_clk);
  379. clk_disable(link_hs_clks->byte_clk);
  380. }
  381. /**
  382. * dsi_link_clk_start() - enable dsi link clocks
  383. */
  384. static int dsi_link_hs_clk_start(struct dsi_link_hs_clk_info *link_hs_clks,
  385. enum dsi_link_clk_op_type op_type, int index)
  386. {
  387. int rc = 0;
  388. if (index >= MAX_DSI_CTRL) {
  389. DSI_ERR("Invalid DSI ctrl index\n");
  390. return -EINVAL;
  391. }
  392. if (op_type & DSI_LINK_CLK_SET_RATE) {
  393. rc = dsi_link_hs_clk_set_rate(link_hs_clks, index);
  394. if (rc) {
  395. DSI_ERR("failed to set HS clk rates, rc = %d\n", rc);
  396. goto error;
  397. }
  398. }
  399. if (op_type & DSI_LINK_CLK_PREPARE) {
  400. rc = dsi_link_hs_clk_prepare(link_hs_clks);
  401. if (rc) {
  402. DSI_ERR("failed to prepare link HS clks, rc = %d\n",
  403. rc);
  404. goto error;
  405. }
  406. }
  407. if (op_type & DSI_LINK_CLK_ENABLE) {
  408. rc = dsi_link_hs_clk_enable(link_hs_clks);
  409. if (rc) {
  410. DSI_ERR("failed to enable link HS clks, rc = %d\n", rc);
  411. goto error_unprepare;
  412. }
  413. }
  414. DSI_DEBUG("HS Link clocks are enabled\n");
  415. return rc;
  416. error_unprepare:
  417. dsi_link_hs_clk_unprepare(link_hs_clks);
  418. error:
  419. return rc;
  420. }
  421. /**
  422. * dsi_link_clk_stop() - Stop DSI link clocks.
  423. */
  424. static int dsi_link_hs_clk_stop(struct dsi_link_hs_clk_info *link_hs_clks)
  425. {
  426. struct dsi_link_clks *l_clks;
  427. l_clks = container_of(link_hs_clks, struct dsi_link_clks, hs_clks);
  428. dsi_link_hs_clk_disable(link_hs_clks);
  429. dsi_link_hs_clk_unprepare(link_hs_clks);
  430. DSI_DEBUG("HS Link clocks disabled\n");
  431. return 0;
  432. }
  433. static int dsi_link_lp_clk_start(struct dsi_link_lp_clk_info *link_lp_clks,
  434. int index)
  435. {
  436. int rc = 0;
  437. struct dsi_clk_mngr *mngr;
  438. struct dsi_link_clks *l_clks;
  439. if (index >= MAX_DSI_CTRL) {
  440. DSI_ERR("Invalid DSI ctrl index\n");
  441. return -EINVAL;
  442. }
  443. l_clks = container_of(link_lp_clks, struct dsi_link_clks, lp_clks);
  444. mngr = container_of(l_clks, struct dsi_clk_mngr, link_clks[index]);
  445. if (!mngr)
  446. return -EINVAL;
  447. /*
  448. * In an ideal world, cont_splash_enabled should not be required inside
  449. * the clock manager. But, in the current driver cont_splash_enabled
  450. * flag is set inside mdp driver and there is no interface event
  451. * associated with this flag setting. Also, set rate for clock need not
  452. * be called for every enable call. It should be done only once when
  453. * coming out of suspend.
  454. */
  455. if (mngr->is_cont_splash_enabled)
  456. goto prepare;
  457. rc = clk_set_rate(link_lp_clks->esc_clk, l_clks->freq.esc_clk_rate);
  458. if (rc) {
  459. DSI_ERR("clk_set_rate failed for esc_clk rc = %d\n", rc);
  460. goto error;
  461. }
  462. prepare:
  463. rc = clk_prepare_enable(link_lp_clks->esc_clk);
  464. if (rc) {
  465. DSI_ERR("Failed to enable dsi esc clk\n");
  466. clk_unprepare(l_clks->lp_clks.esc_clk);
  467. }
  468. error:
  469. DSI_DEBUG("LP Link clocks are enabled\n");
  470. return rc;
  471. }
  472. static int dsi_link_lp_clk_stop(
  473. struct dsi_link_lp_clk_info *link_lp_clks)
  474. {
  475. struct dsi_link_clks *l_clks;
  476. l_clks = container_of(link_lp_clks, struct dsi_link_clks, lp_clks);
  477. clk_disable_unprepare(l_clks->lp_clks.esc_clk);
  478. DSI_DEBUG("LP Link clocks are disabled\n");
  479. return 0;
  480. }
  481. static int dsi_display_core_clk_enable(struct dsi_core_clks *clks,
  482. u32 ctrl_count, u32 master_ndx)
  483. {
  484. int rc = 0;
  485. int i;
  486. struct dsi_core_clks *clk, *m_clks;
  487. /*
  488. * In case of split DSI usecases, the clock for master controller should
  489. * be enabled before the other controller. Master controller in the
  490. * clock context refers to the controller that sources the clock.
  491. */
  492. m_clks = &clks[master_ndx];
  493. rc = pm_runtime_get_sync(m_clks->clks.drm->dev);
  494. if (rc < 0) {
  495. DSI_ERR("Power resource enable failed, rc=%d\n", rc);
  496. goto error;
  497. }
  498. rc = dsi_core_clk_start(m_clks);
  499. if (rc) {
  500. DSI_ERR("failed to turn on master clocks, rc=%d\n", rc);
  501. goto error_disable_master_resource;
  502. }
  503. /* Turn on rest of the core clocks */
  504. for (i = 0; i < ctrl_count; i++) {
  505. clk = &clks[i];
  506. if (!clk || (clk == m_clks))
  507. continue;
  508. rc = pm_runtime_get_sync(m_clks->clks.drm->dev);
  509. if (rc < 0) {
  510. DSI_ERR("Power resource enable failed, rc=%d\n", rc);
  511. goto error_disable_master;
  512. }
  513. rc = dsi_core_clk_start(clk);
  514. if (rc) {
  515. DSI_ERR("failed to turn on clocks, rc=%d\n", rc);
  516. pm_runtime_put_sync(m_clks->clks.drm->dev);
  517. goto error_disable_master;
  518. }
  519. }
  520. return rc;
  521. error_disable_master:
  522. (void)dsi_core_clk_stop(m_clks);
  523. error_disable_master_resource:
  524. pm_runtime_put_sync(m_clks->clks.drm->dev);
  525. error:
  526. return rc;
  527. }
  528. static int dsi_display_link_clk_enable(struct dsi_link_clks *clks,
  529. enum dsi_lclk_type l_type, u32 ctrl_count, u32 master_ndx)
  530. {
  531. int rc = 0;
  532. int i;
  533. struct dsi_link_clks *clk, *m_clks;
  534. /*
  535. * In case of split DSI usecases, the clock for master controller should
  536. * be enabled before the other controller. Master controller in the
  537. * clock context refers to the controller that sources the clock.
  538. */
  539. m_clks = &clks[master_ndx];
  540. if (l_type & DSI_LINK_LP_CLK) {
  541. rc = dsi_link_lp_clk_start(&m_clks->lp_clks, master_ndx);
  542. if (rc) {
  543. DSI_ERR("failed to turn on master lp link clocks, rc=%d\n",
  544. rc);
  545. goto error;
  546. }
  547. }
  548. if (l_type & DSI_LINK_HS_CLK) {
  549. rc = dsi_link_hs_clk_start(&m_clks->hs_clks,
  550. DSI_LINK_CLK_START, master_ndx);
  551. if (rc) {
  552. DSI_ERR("failed to turn on master hs link clocks, rc=%d\n",
  553. rc);
  554. goto error;
  555. }
  556. }
  557. for (i = 0; i < ctrl_count; i++) {
  558. clk = &clks[i];
  559. if (!clk || (clk == m_clks))
  560. continue;
  561. if (l_type & DSI_LINK_LP_CLK) {
  562. rc = dsi_link_lp_clk_start(&clk->lp_clks, i);
  563. if (rc) {
  564. DSI_ERR("failed to turn on lp link clocks, rc=%d\n",
  565. rc);
  566. goto error_disable_master;
  567. }
  568. }
  569. if (l_type & DSI_LINK_HS_CLK) {
  570. rc = dsi_link_hs_clk_start(&clk->hs_clks,
  571. DSI_LINK_CLK_START, i);
  572. if (rc) {
  573. DSI_ERR("failed to turn on hs link clocks, rc=%d\n",
  574. rc);
  575. goto error_disable_master;
  576. }
  577. }
  578. }
  579. return rc;
  580. error_disable_master:
  581. if (l_type == DSI_LINK_LP_CLK)
  582. (void)dsi_link_lp_clk_stop(&m_clks->lp_clks);
  583. else if (l_type == DSI_LINK_HS_CLK)
  584. (void)dsi_link_hs_clk_stop(&m_clks->hs_clks);
  585. error:
  586. return rc;
  587. }
  588. static int dsi_display_core_clk_disable(struct dsi_core_clks *clks,
  589. u32 ctrl_count, u32 master_ndx)
  590. {
  591. int rc = 0;
  592. int i;
  593. struct dsi_core_clks *clk, *m_clks;
  594. /*
  595. * In case of split DSI usecases, clock for slave DSI controllers should
  596. * be disabled first before disabling clock for master controller. Slave
  597. * controllers in the clock context refer to controller which source
  598. * clock from another controller.
  599. */
  600. m_clks = &clks[master_ndx];
  601. /* Turn off non-master core clocks */
  602. for (i = 0; i < ctrl_count; i++) {
  603. clk = &clks[i];
  604. if (!clk || (clk == m_clks))
  605. continue;
  606. rc = dsi_core_clk_stop(clk);
  607. if (rc) {
  608. DSI_DEBUG("failed to turn off clocks, rc=%d\n", rc);
  609. goto error;
  610. }
  611. pm_runtime_put_sync(m_clks->clks.drm->dev);
  612. }
  613. rc = dsi_core_clk_stop(m_clks);
  614. if (rc) {
  615. DSI_ERR("failed to turn off master clocks, rc=%d\n", rc);
  616. goto error;
  617. }
  618. pm_runtime_put_sync(m_clks->clks.drm->dev);
  619. error:
  620. return rc;
  621. }
  622. static int dsi_display_link_clk_disable(struct dsi_link_clks *clks,
  623. enum dsi_lclk_type l_type, u32 ctrl_count, u32 master_ndx)
  624. {
  625. int rc = 0;
  626. int i;
  627. struct dsi_link_clks *clk, *m_clks;
  628. /*
  629. * In case of split DSI usecases, clock for slave DSI controllers should
  630. * be disabled first before disabling clock for master controller. Slave
  631. * controllers in the clock context refer to controller which source
  632. * clock from another controller.
  633. */
  634. m_clks = &clks[master_ndx];
  635. /* Turn off non-master link clocks */
  636. for (i = 0; i < ctrl_count; i++) {
  637. clk = &clks[i];
  638. if (!clk || (clk == m_clks))
  639. continue;
  640. if (l_type & DSI_LINK_LP_CLK) {
  641. rc = dsi_link_lp_clk_stop(&clk->lp_clks);
  642. if (rc)
  643. DSI_ERR("failed to turn off lp link clocks, rc=%d\n",
  644. rc);
  645. }
  646. if (l_type & DSI_LINK_HS_CLK) {
  647. rc = dsi_link_hs_clk_stop(&clk->hs_clks);
  648. if (rc)
  649. DSI_ERR("failed to turn off hs link clocks, rc=%d\n",
  650. rc);
  651. }
  652. }
  653. if (l_type & DSI_LINK_LP_CLK) {
  654. rc = dsi_link_lp_clk_stop(&m_clks->lp_clks);
  655. if (rc)
  656. DSI_ERR("failed to turn off master lp link clocks, rc=%d\n",
  657. rc);
  658. }
  659. if (l_type & DSI_LINK_HS_CLK) {
  660. rc = dsi_link_hs_clk_stop(&m_clks->hs_clks);
  661. if (rc)
  662. DSI_ERR("failed to turn off master hs link clocks, rc=%d\n",
  663. rc);
  664. }
  665. return rc;
  666. }
  667. static int dsi_clk_update_link_clk_state(struct dsi_clk_mngr *mngr,
  668. struct dsi_link_clks *l_clks, enum dsi_lclk_type l_type, u32 l_state,
  669. bool enable)
  670. {
  671. int rc = 0;
  672. if (!mngr)
  673. return -EINVAL;
  674. if (enable) {
  675. if (mngr->pre_clkon_cb) {
  676. rc = mngr->pre_clkon_cb(mngr->priv_data, DSI_LINK_CLK,
  677. l_type, l_state);
  678. if (rc) {
  679. DSI_ERR("pre link clk on cb failed for type %d\n",
  680. l_type);
  681. goto error;
  682. }
  683. }
  684. rc = dsi_display_link_clk_enable(l_clks, l_type,
  685. mngr->dsi_ctrl_count, mngr->master_ndx);
  686. if (rc) {
  687. DSI_ERR("failed to start link clk type %d rc=%d\n",
  688. l_type, rc);
  689. goto error;
  690. }
  691. if (mngr->post_clkon_cb) {
  692. rc = mngr->post_clkon_cb(mngr->priv_data, DSI_LINK_CLK,
  693. l_type, l_state);
  694. if (rc) {
  695. DSI_ERR("post link clk on cb failed for type %d\n",
  696. l_type);
  697. goto error;
  698. }
  699. }
  700. } else {
  701. if (mngr->pre_clkoff_cb) {
  702. rc = mngr->pre_clkoff_cb(mngr->priv_data,
  703. DSI_LINK_CLK, l_type, l_state);
  704. if (rc)
  705. DSI_ERR("pre link clk off cb failed\n");
  706. }
  707. rc = dsi_display_link_clk_disable(l_clks, l_type,
  708. mngr->dsi_ctrl_count, mngr->master_ndx);
  709. if (rc) {
  710. DSI_ERR("failed to stop link clk type %d, rc = %d\n",
  711. l_type, rc);
  712. goto error;
  713. }
  714. if (mngr->post_clkoff_cb) {
  715. rc = mngr->post_clkoff_cb(mngr->priv_data,
  716. DSI_LINK_CLK, l_type, l_state);
  717. if (rc)
  718. DSI_ERR("post link clk off cb failed\n");
  719. }
  720. }
  721. error:
  722. return rc;
  723. }
  724. static int dsi_update_core_clks(struct dsi_clk_mngr *mngr,
  725. struct dsi_core_clks *c_clks)
  726. {
  727. int rc = 0;
  728. if (mngr->core_clk_state == DSI_CLK_OFF) {
  729. rc = mngr->pre_clkon_cb(mngr->priv_data,
  730. DSI_CORE_CLK,
  731. DSI_LINK_NONE,
  732. DSI_CLK_ON);
  733. if (rc) {
  734. DSI_ERR("failed to turn on MDP FS rc= %d\n", rc);
  735. goto error;
  736. }
  737. }
  738. rc = dsi_display_core_clk_enable(c_clks, mngr->dsi_ctrl_count,
  739. mngr->master_ndx);
  740. if (rc) {
  741. DSI_ERR("failed to turn on core clks rc = %d\n", rc);
  742. goto error;
  743. }
  744. if (mngr->post_clkon_cb) {
  745. rc = mngr->post_clkon_cb(mngr->priv_data,
  746. DSI_CORE_CLK,
  747. DSI_LINK_NONE,
  748. DSI_CLK_ON);
  749. if (rc)
  750. DSI_ERR("post clk on cb failed, rc = %d\n", rc);
  751. }
  752. mngr->core_clk_state = DSI_CLK_ON;
  753. error:
  754. return rc;
  755. }
  756. static int dsi_update_clk_state(struct dsi_clk_mngr *mngr,
  757. struct dsi_core_clks *c_clks, u32 c_state,
  758. struct dsi_link_clks *l_clks, u32 l_state)
  759. {
  760. int rc = 0;
  761. bool l_c_on = false;
  762. if (!mngr)
  763. return -EINVAL;
  764. DSI_DEBUG("c_state = %d, l_state = %d\n",
  765. c_clks ? c_state : -1, l_clks ? l_state : -1);
  766. /*
  767. * Below is the sequence to toggle DSI clocks:
  768. * 1. For ON sequence, Core clocks before link clocks
  769. * 2. For OFF sequence, Link clocks before core clocks.
  770. */
  771. if (c_clks && (c_state == DSI_CLK_ON))
  772. rc = dsi_update_core_clks(mngr, c_clks);
  773. if (rc)
  774. goto error;
  775. if (l_clks) {
  776. if (l_state == DSI_CLK_ON) {
  777. rc = dsi_clk_update_link_clk_state(mngr, l_clks,
  778. DSI_LINK_LP_CLK, l_state, true);
  779. if (rc)
  780. goto error;
  781. rc = dsi_clk_update_link_clk_state(mngr, l_clks,
  782. DSI_LINK_HS_CLK, l_state, true);
  783. if (rc)
  784. goto error;
  785. } else {
  786. /*
  787. * Two conditions that need to be checked for Link
  788. * clocks:
  789. * 1. Link clocks need core clocks to be on when
  790. * transitioning from EARLY_GATE to OFF state.
  791. * 2. ULPS mode might have to be enabled in case of OFF
  792. * state. For ULPS, Link clocks should be turned ON
  793. * first before they are turned off again.
  794. *
  795. * If Link is going from EARLY_GATE to OFF state AND
  796. * Core clock is already in EARLY_GATE or OFF state,
  797. * turn on Core clocks and link clocks.
  798. *
  799. * ULPS state is managed as part of the pre_clkoff_cb.
  800. */
  801. if ((l_state == DSI_CLK_OFF) &&
  802. (mngr->link_clk_state ==
  803. DSI_CLK_EARLY_GATE) &&
  804. (mngr->core_clk_state !=
  805. DSI_CLK_ON)) {
  806. rc = dsi_display_core_clk_enable(
  807. mngr->core_clks, mngr->dsi_ctrl_count,
  808. mngr->master_ndx);
  809. if (rc) {
  810. DSI_ERR("core clks did not start\n");
  811. goto error;
  812. }
  813. rc = dsi_display_link_clk_enable(l_clks,
  814. (DSI_LINK_LP_CLK & DSI_LINK_HS_CLK),
  815. mngr->dsi_ctrl_count, mngr->master_ndx);
  816. if (rc) {
  817. DSI_ERR("LP Link clks did not start\n");
  818. goto error;
  819. }
  820. l_c_on = true;
  821. DSI_DEBUG("ECG: core and Link_on\n");
  822. }
  823. rc = dsi_clk_update_link_clk_state(mngr, l_clks,
  824. DSI_LINK_HS_CLK, l_state, false);
  825. if (rc)
  826. goto error;
  827. rc = dsi_clk_update_link_clk_state(mngr, l_clks,
  828. DSI_LINK_LP_CLK, l_state, false);
  829. if (rc)
  830. goto error;
  831. /*
  832. * This check is to save unnecessary clock state
  833. * change when going from EARLY_GATE to OFF. In the
  834. * case where the request happens for both Core and Link
  835. * clocks in the same call, core clocks need to be
  836. * turned on first before OFF state can be entered.
  837. *
  838. * Core clocks are turned on here for Link clocks to go
  839. * to OFF state. If core clock request is also present,
  840. * then core clocks can be turned off Core clocks are
  841. * transitioned to OFF state.
  842. */
  843. if (l_c_on && (!(c_clks && (c_state == DSI_CLK_OFF)
  844. && (mngr->core_clk_state ==
  845. DSI_CLK_EARLY_GATE)))) {
  846. rc = dsi_display_core_clk_disable(
  847. mngr->core_clks, mngr->dsi_ctrl_count,
  848. mngr->master_ndx);
  849. if (rc) {
  850. DSI_ERR("core clks did not stop\n");
  851. goto error;
  852. }
  853. l_c_on = false;
  854. DSI_DEBUG("ECG: core off\n");
  855. } else
  856. DSI_DEBUG("ECG: core off skip\n");
  857. }
  858. mngr->link_clk_state = l_state;
  859. }
  860. if (c_clks && (c_state != DSI_CLK_ON)) {
  861. /*
  862. * When going to OFF state from EARLY GATE state, Core clocks
  863. * should be turned on first so that the IOs can be clamped.
  864. * l_c_on flag is set, then the core clocks were turned before
  865. * to the Link clocks go to OFF state. So Core clocks are
  866. * already ON and this step can be skipped.
  867. *
  868. * IOs are clamped in pre_clkoff_cb callback.
  869. */
  870. if ((c_state == DSI_CLK_OFF) &&
  871. (mngr->core_clk_state ==
  872. DSI_CLK_EARLY_GATE) && !l_c_on) {
  873. rc = dsi_display_core_clk_enable(mngr->core_clks,
  874. mngr->dsi_ctrl_count, mngr->master_ndx);
  875. if (rc) {
  876. DSI_ERR("core clks did not start\n");
  877. goto error;
  878. }
  879. DSI_DEBUG("ECG: core on\n");
  880. } else
  881. DSI_DEBUG("ECG: core on skip\n");
  882. if (mngr->pre_clkoff_cb) {
  883. rc = mngr->pre_clkoff_cb(mngr->priv_data,
  884. DSI_CORE_CLK,
  885. DSI_LINK_NONE,
  886. c_state);
  887. if (rc)
  888. DSI_ERR("pre core clk off cb failed\n");
  889. }
  890. rc = dsi_display_core_clk_disable(c_clks, mngr->dsi_ctrl_count,
  891. mngr->master_ndx);
  892. if (rc) {
  893. DSI_ERR("failed to turn off core clks rc = %d\n", rc);
  894. goto error;
  895. }
  896. if (c_state == DSI_CLK_OFF) {
  897. if (mngr->post_clkoff_cb) {
  898. rc = mngr->post_clkoff_cb(mngr->priv_data,
  899. DSI_CORE_CLK,
  900. DSI_LINK_NONE,
  901. DSI_CLK_OFF);
  902. if (rc)
  903. DSI_ERR("post clkoff cb fail, rc = %d\n",
  904. rc);
  905. }
  906. }
  907. mngr->core_clk_state = c_state;
  908. }
  909. error:
  910. return rc;
  911. }
  912. static int dsi_recheck_clk_state(struct dsi_clk_mngr *mngr)
  913. {
  914. int rc = 0;
  915. struct list_head *pos = NULL;
  916. struct dsi_clk_client_info *c;
  917. u32 new_core_clk_state = DSI_CLK_OFF;
  918. u32 new_link_clk_state = DSI_CLK_OFF;
  919. u32 old_c_clk_state = DSI_CLK_OFF;
  920. u32 old_l_clk_state = DSI_CLK_OFF;
  921. struct dsi_core_clks *c_clks = NULL;
  922. struct dsi_link_clks *l_clks = NULL;
  923. /*
  924. * Conditions to maintain DSI manager clock state based on
  925. * clock states of various clients:
  926. * 1. If any client has clock in ON state, DSI manager clock state
  927. * should be ON.
  928. * 2. If any client is in ECG state with rest of them turned OFF,
  929. * go to Early gate state.
  930. * 3. If all clients have clocks as OFF, then go to OFF state.
  931. */
  932. list_for_each(pos, &mngr->client_list) {
  933. c = list_entry(pos, struct dsi_clk_client_info, list);
  934. if (c->core_clk_state == DSI_CLK_ON) {
  935. new_core_clk_state = DSI_CLK_ON;
  936. break;
  937. } else if (c->core_clk_state == DSI_CLK_EARLY_GATE) {
  938. new_core_clk_state = DSI_CLK_EARLY_GATE;
  939. }
  940. }
  941. list_for_each(pos, &mngr->client_list) {
  942. c = list_entry(pos, struct dsi_clk_client_info, list);
  943. if (c->link_clk_state == DSI_CLK_ON) {
  944. new_link_clk_state = DSI_CLK_ON;
  945. break;
  946. } else if (c->link_clk_state == DSI_CLK_EARLY_GATE) {
  947. new_link_clk_state = DSI_CLK_EARLY_GATE;
  948. }
  949. }
  950. if (new_core_clk_state != mngr->core_clk_state)
  951. c_clks = mngr->core_clks;
  952. if (new_link_clk_state != mngr->link_clk_state)
  953. l_clks = mngr->link_clks;
  954. old_c_clk_state = mngr->core_clk_state;
  955. old_l_clk_state = mngr->link_clk_state;
  956. DSI_DEBUG("c_clk_state (%d -> %d)\n", old_c_clk_state,
  957. new_core_clk_state);
  958. DSI_DEBUG("l_clk_state (%d -> %d)\n", old_l_clk_state,
  959. new_link_clk_state);
  960. if (c_clks || l_clks) {
  961. rc = dsi_update_clk_state(mngr, c_clks, new_core_clk_state,
  962. l_clks, new_link_clk_state);
  963. if (rc) {
  964. DSI_ERR("failed to update clock state, rc = %d\n", rc);
  965. goto error;
  966. }
  967. }
  968. error:
  969. return rc;
  970. }
  971. int dsi_clk_req_state(void *client, enum dsi_clk_type clk,
  972. enum dsi_clk_state state)
  973. {
  974. int rc = 0;
  975. struct dsi_clk_client_info *c = client;
  976. struct dsi_clk_mngr *mngr;
  977. bool changed = false;
  978. if (!client || !clk || clk > (DSI_CORE_CLK | DSI_LINK_CLK) ||
  979. state > DSI_CLK_EARLY_GATE) {
  980. DSI_ERR("Invalid params, client = %pK, clk = 0x%x, state = %d\n",
  981. client, clk, state);
  982. return -EINVAL;
  983. }
  984. mngr = c->mngr;
  985. mutex_lock(&mngr->clk_mutex);
  986. DSI_DEBUG("[%s]%s: CLK=%d, new_state=%d, core=%d, linkl=%d\n",
  987. mngr->name, c->name, clk, state, c->core_clk_state,
  988. c->link_clk_state);
  989. /*
  990. * Clock refcount handling as below:
  991. * i. Increment refcount whenever ON is called.
  992. * ii. Decrement refcount when transitioning from ON state to
  993. * either OFF or EARLY_GATE.
  994. * iii. Do not decrement refcount when changing from
  995. * EARLY_GATE to OFF.
  996. */
  997. if (state == DSI_CLK_ON) {
  998. if (clk & DSI_CORE_CLK) {
  999. c->core_refcount++;
  1000. if (c->core_clk_state != DSI_CLK_ON) {
  1001. c->core_clk_state = DSI_CLK_ON;
  1002. changed = true;
  1003. }
  1004. }
  1005. if (clk & DSI_LINK_CLK) {
  1006. c->link_refcount++;
  1007. if (c->link_clk_state != DSI_CLK_ON) {
  1008. c->link_clk_state = DSI_CLK_ON;
  1009. changed = true;
  1010. }
  1011. }
  1012. } else if ((state == DSI_CLK_EARLY_GATE) ||
  1013. (state == DSI_CLK_OFF)) {
  1014. if (clk & DSI_CORE_CLK) {
  1015. if (c->core_refcount == 0) {
  1016. if ((c->core_clk_state ==
  1017. DSI_CLK_EARLY_GATE) &&
  1018. (state == DSI_CLK_OFF)) {
  1019. changed = true;
  1020. c->core_clk_state = DSI_CLK_OFF;
  1021. } else {
  1022. DSI_WARN("Core refcount is zero for %s\n",
  1023. c->name);
  1024. }
  1025. } else {
  1026. c->core_refcount--;
  1027. if (c->core_refcount == 0) {
  1028. c->core_clk_state = state;
  1029. changed = true;
  1030. }
  1031. }
  1032. }
  1033. if (clk & DSI_LINK_CLK) {
  1034. if (c->link_refcount == 0) {
  1035. if ((c->link_clk_state ==
  1036. DSI_CLK_EARLY_GATE) &&
  1037. (state == DSI_CLK_OFF)) {
  1038. changed = true;
  1039. c->link_clk_state = DSI_CLK_OFF;
  1040. } else {
  1041. DSI_WARN("Link refcount is zero for %s\n",
  1042. c->name);
  1043. }
  1044. } else {
  1045. c->link_refcount--;
  1046. if (c->link_refcount == 0) {
  1047. c->link_clk_state = state;
  1048. changed = true;
  1049. }
  1050. }
  1051. }
  1052. }
  1053. DSI_DEBUG("[%s]%s: change=%d, Core (ref=%d, state=%d), Link (ref=%d, state=%d)\n",
  1054. mngr->name, c->name, changed, c->core_refcount,
  1055. c->core_clk_state, c->link_refcount, c->link_clk_state);
  1056. if (changed) {
  1057. rc = dsi_recheck_clk_state(mngr);
  1058. if (rc)
  1059. DSI_ERR("Failed to adjust clock state rc = %d\n", rc);
  1060. }
  1061. mutex_unlock(&mngr->clk_mutex);
  1062. return rc;
  1063. }
  1064. DEFINE_MUTEX(dsi_mngr_clk_mutex);
  1065. static int dsi_display_link_clk_force_update(void *client)
  1066. {
  1067. int rc = 0;
  1068. struct dsi_clk_client_info *c = client;
  1069. struct dsi_clk_mngr *mngr;
  1070. struct dsi_link_clks *l_clks;
  1071. mngr = c->mngr;
  1072. mutex_lock(&mngr->clk_mutex);
  1073. l_clks = mngr->link_clks;
  1074. /*
  1075. * When link_clk_state is DSI_CLK_OFF, don't change DSI clock rate
  1076. * since it is possible to be overwritten, and return -EAGAIN to
  1077. * dynamic DSI writing interface to defer the reenabling to the next
  1078. * drm commit.
  1079. */
  1080. if (mngr->link_clk_state == DSI_CLK_OFF) {
  1081. rc = -EAGAIN;
  1082. goto error;
  1083. }
  1084. rc = dsi_clk_update_link_clk_state(mngr, l_clks, (DSI_LINK_LP_CLK |
  1085. DSI_LINK_HS_CLK), DSI_CLK_OFF, false);
  1086. if (rc)
  1087. goto error;
  1088. rc = dsi_clk_update_link_clk_state(mngr, l_clks, (DSI_LINK_LP_CLK |
  1089. DSI_LINK_HS_CLK), DSI_CLK_ON, true);
  1090. if (rc)
  1091. goto error;
  1092. error:
  1093. mutex_unlock(&mngr->clk_mutex);
  1094. return rc;
  1095. }
  1096. int dsi_display_link_clk_force_update_ctrl(void *handle)
  1097. {
  1098. int rc = 0;
  1099. if (!handle) {
  1100. DSI_ERR("Invalid arg\n");
  1101. return -EINVAL;
  1102. }
  1103. mutex_lock(&dsi_mngr_clk_mutex);
  1104. rc = dsi_display_link_clk_force_update(handle);
  1105. mutex_unlock(&dsi_mngr_clk_mutex);
  1106. return rc;
  1107. }
  1108. int dsi_display_clk_ctrl(void *handle,
  1109. u32 clk_type, u32 clk_state)
  1110. {
  1111. int rc = 0;
  1112. if ((!handle) || (clk_type > DSI_ALL_CLKS) ||
  1113. (clk_state > DSI_CLK_EARLY_GATE)) {
  1114. DSI_ERR("Invalid arg\n");
  1115. return -EINVAL;
  1116. }
  1117. mutex_lock(&dsi_mngr_clk_mutex);
  1118. rc = dsi_clk_req_state(handle, clk_type, clk_state);
  1119. if (rc)
  1120. DSI_ERR("failed set clk state, rc = %d\n", rc);
  1121. mutex_unlock(&dsi_mngr_clk_mutex);
  1122. return rc;
  1123. }
  1124. void *dsi_register_clk_handle(void *clk_mngr, char *client)
  1125. {
  1126. void *handle = NULL;
  1127. struct dsi_clk_mngr *mngr = clk_mngr;
  1128. struct dsi_clk_client_info *c;
  1129. if (!mngr) {
  1130. DSI_ERR("bad params\n");
  1131. return ERR_PTR(-EINVAL);
  1132. }
  1133. mutex_lock(&mngr->clk_mutex);
  1134. c = kzalloc(sizeof(*c), GFP_KERNEL);
  1135. if (!c) {
  1136. handle = ERR_PTR(-ENOMEM);
  1137. goto error;
  1138. }
  1139. strlcpy(c->name, client, MAX_STRING_LEN);
  1140. c->mngr = mngr;
  1141. list_add(&c->list, &mngr->client_list);
  1142. DSI_DEBUG("[%s]: Added new client (%s)\n", mngr->name, c->name);
  1143. handle = c;
  1144. error:
  1145. mutex_unlock(&mngr->clk_mutex);
  1146. return handle;
  1147. }
  1148. int dsi_deregister_clk_handle(void *client)
  1149. {
  1150. int rc = 0;
  1151. struct dsi_clk_client_info *c = client;
  1152. struct dsi_clk_mngr *mngr;
  1153. struct list_head *pos = NULL;
  1154. struct list_head *tmp = NULL;
  1155. struct dsi_clk_client_info *node = NULL;
  1156. if (!client) {
  1157. DSI_ERR("Invalid params\n");
  1158. return -EINVAL;
  1159. }
  1160. mngr = c->mngr;
  1161. DSI_DEBUG("%s: ENTER\n", mngr->name);
  1162. mutex_lock(&mngr->clk_mutex);
  1163. c->core_clk_state = DSI_CLK_OFF;
  1164. c->link_clk_state = DSI_CLK_OFF;
  1165. rc = dsi_recheck_clk_state(mngr);
  1166. if (rc) {
  1167. DSI_ERR("clock state recheck failed rc = %d\n", rc);
  1168. goto error;
  1169. }
  1170. list_for_each_safe(pos, tmp, &mngr->client_list) {
  1171. node = list_entry(pos, struct dsi_clk_client_info,
  1172. list);
  1173. if (node == c) {
  1174. list_del(&node->list);
  1175. DSI_DEBUG("Removed device (%s)\n", node->name);
  1176. kfree(node);
  1177. break;
  1178. }
  1179. }
  1180. error:
  1181. mutex_unlock(&mngr->clk_mutex);
  1182. DSI_DEBUG("%s: EXIT, rc = %d\n", mngr->name, rc);
  1183. return rc;
  1184. }
  1185. void dsi_display_clk_mngr_update_splash_status(void *clk_mgr, bool status)
  1186. {
  1187. struct dsi_clk_mngr *mngr;
  1188. if (!clk_mgr) {
  1189. DSI_ERR("Invalid params\n");
  1190. return;
  1191. }
  1192. mngr = (struct dsi_clk_mngr *)clk_mgr;
  1193. mngr->is_cont_splash_enabled = status;
  1194. }
  1195. void *dsi_display_clk_mngr_register(struct dsi_clk_info *info)
  1196. {
  1197. struct dsi_clk_mngr *mngr;
  1198. int i = 0;
  1199. if (!info) {
  1200. DSI_ERR("Invalid params\n");
  1201. return ERR_PTR(-EINVAL);
  1202. }
  1203. mngr = kzalloc(sizeof(*mngr), GFP_KERNEL);
  1204. if (!mngr) {
  1205. mngr = ERR_PTR(-ENOMEM);
  1206. goto error;
  1207. }
  1208. mutex_init(&mngr->clk_mutex);
  1209. mngr->dsi_ctrl_count = info->dsi_ctrl_count;
  1210. mngr->master_ndx = info->master_ndx;
  1211. if (mngr->dsi_ctrl_count > MAX_DSI_CTRL) {
  1212. kfree(mngr);
  1213. return ERR_PTR(-EINVAL);
  1214. }
  1215. for (i = 0; i < mngr->dsi_ctrl_count; i++) {
  1216. memcpy(&mngr->core_clks[i].clks, &info->c_clks[i],
  1217. sizeof(struct dsi_core_clk_info));
  1218. memcpy(&mngr->link_clks[i].hs_clks, &info->l_hs_clks[i],
  1219. sizeof(struct dsi_link_hs_clk_info));
  1220. memcpy(&mngr->link_clks[i].lp_clks, &info->l_lp_clks[i],
  1221. sizeof(struct dsi_link_lp_clk_info));
  1222. mngr->ctrl_index[i] = info->ctrl_index[i];
  1223. }
  1224. INIT_LIST_HEAD(&mngr->client_list);
  1225. mngr->pre_clkon_cb = info->pre_clkon_cb;
  1226. mngr->post_clkon_cb = info->post_clkon_cb;
  1227. mngr->pre_clkoff_cb = info->pre_clkoff_cb;
  1228. mngr->post_clkoff_cb = info->post_clkoff_cb;
  1229. mngr->priv_data = info->priv_data;
  1230. memcpy(mngr->name, info->name, MAX_STRING_LEN);
  1231. error:
  1232. DSI_DEBUG("EXIT, rc = %ld\n", PTR_ERR(mngr));
  1233. return mngr;
  1234. }
  1235. int dsi_display_clk_mngr_deregister(void *clk_mngr)
  1236. {
  1237. int rc = 0;
  1238. struct dsi_clk_mngr *mngr = clk_mngr;
  1239. struct list_head *position = NULL;
  1240. struct list_head *tmp = NULL;
  1241. struct dsi_clk_client_info *node = NULL;
  1242. if (!mngr) {
  1243. DSI_ERR("Invalid params\n");
  1244. return -EINVAL;
  1245. }
  1246. DSI_DEBUG("%s: ENTER\n", mngr->name);
  1247. mutex_lock(&mngr->clk_mutex);
  1248. list_for_each_safe(position, tmp, &mngr->client_list) {
  1249. node = list_entry(position, struct dsi_clk_client_info,
  1250. list);
  1251. list_del(&node->list);
  1252. DSI_DEBUG("Removed device (%s)\n", node->name);
  1253. kfree(node);
  1254. }
  1255. rc = dsi_recheck_clk_state(mngr);
  1256. if (rc)
  1257. DSI_ERR("failed to disable all clocks\n");
  1258. mutex_unlock(&mngr->clk_mutex);
  1259. DSI_DEBUG("%s: EXIT, rc = %d\n", mngr->name, rc);
  1260. kfree(mngr);
  1261. return rc;
  1262. }