dsi_clk_manager.c 36 KB

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