dispcc-milos.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
  4. * Copyright (c) 2025, Luca Weiss <luca.weiss@fairphone.com>
  5. */
  6. #include <linux/clk.h>
  7. #include <linux/clk-provider.h>
  8. #include <linux/err.h>
  9. #include <linux/kernel.h>
  10. #include <linux/module.h>
  11. #include <linux/of.h>
  12. #include <linux/platform_device.h>
  13. #include <linux/regmap.h>
  14. #include <dt-bindings/clock/qcom,milos-dispcc.h>
  15. #include "common.h"
  16. #include "clk-alpha-pll.h"
  17. #include "clk-branch.h"
  18. #include "clk-pll.h"
  19. #include "clk-rcg.h"
  20. #include "clk-regmap.h"
  21. #include "clk-regmap-divider.h"
  22. #include "clk-regmap-mux.h"
  23. #include "reset.h"
  24. #include "gdsc.h"
  25. /* Need to match the order of clocks in DT binding */
  26. enum {
  27. DT_BI_TCXO,
  28. DT_SLEEP_CLK,
  29. DT_AHB_CLK,
  30. DT_GCC_DISP_GPLL0_CLK,
  31. DT_DSI0_PHY_PLL_OUT_BYTECLK,
  32. DT_DSI0_PHY_PLL_OUT_DSICLK,
  33. DT_DP0_PHY_PLL_LINK_CLK,
  34. DT_DP0_PHY_PLL_VCO_DIV_CLK,
  35. };
  36. #define DISP_CC_MISC_CMD 0xF000
  37. enum {
  38. P_BI_TCXO,
  39. P_DISP_CC_PLL0_OUT_EVEN,
  40. P_DISP_CC_PLL0_OUT_MAIN,
  41. P_DP0_PHY_PLL_LINK_CLK,
  42. P_DP0_PHY_PLL_VCO_DIV_CLK,
  43. P_DSI0_PHY_PLL_OUT_BYTECLK,
  44. P_DSI0_PHY_PLL_OUT_DSICLK,
  45. P_GCC_DISP_GPLL0_CLK,
  46. P_SLEEP_CLK,
  47. };
  48. static const struct pll_vco lucid_ole_vco[] = {
  49. { 249600000, 2300000000, 0 },
  50. };
  51. /* 257.142858 MHz Configuration */
  52. static const struct alpha_pll_config disp_cc_pll0_config = {
  53. .l = 0xd,
  54. .alpha = 0x6492,
  55. .config_ctl_val = 0x20485699,
  56. .config_ctl_hi_val = 0x00182261,
  57. .config_ctl_hi1_val = 0x82aa299c,
  58. .test_ctl_val = 0x00000000,
  59. .test_ctl_hi_val = 0x00000003,
  60. .test_ctl_hi1_val = 0x00009000,
  61. .test_ctl_hi2_val = 0x00000034,
  62. .user_ctl_val = 0x00000000,
  63. .user_ctl_hi_val = 0x00000005,
  64. };
  65. static struct clk_alpha_pll disp_cc_pll0 = {
  66. .offset = 0x0,
  67. .config = &disp_cc_pll0_config,
  68. .vco_table = lucid_ole_vco,
  69. .num_vco = ARRAY_SIZE(lucid_ole_vco),
  70. .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
  71. .clkr = {
  72. .hw.init = &(const struct clk_init_data) {
  73. .name = "disp_cc_pll0",
  74. .parent_data = &(const struct clk_parent_data) {
  75. .index = DT_BI_TCXO,
  76. },
  77. .num_parents = 1,
  78. .ops = &clk_alpha_pll_lucid_evo_ops,
  79. },
  80. },
  81. };
  82. static const struct parent_map disp_cc_parent_map_0[] = {
  83. { P_BI_TCXO, 0 },
  84. };
  85. static const struct clk_parent_data disp_cc_parent_data_0[] = {
  86. { .index = DT_BI_TCXO },
  87. };
  88. static const struct parent_map disp_cc_parent_map_1[] = {
  89. { P_BI_TCXO, 0 },
  90. { P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
  91. { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 },
  92. };
  93. static const struct clk_parent_data disp_cc_parent_data_1[] = {
  94. { .index = DT_BI_TCXO },
  95. { .index = DT_DSI0_PHY_PLL_OUT_DSICLK },
  96. { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
  97. };
  98. static const struct parent_map disp_cc_parent_map_2[] = {
  99. { P_BI_TCXO, 0 },
  100. { P_DP0_PHY_PLL_LINK_CLK, 1 },
  101. { P_DP0_PHY_PLL_VCO_DIV_CLK, 2 },
  102. };
  103. static const struct clk_parent_data disp_cc_parent_data_2[] = {
  104. { .index = DT_BI_TCXO },
  105. { .index = DT_DP0_PHY_PLL_LINK_CLK },
  106. { .index = DT_DP0_PHY_PLL_VCO_DIV_CLK },
  107. };
  108. static const struct parent_map disp_cc_parent_map_3[] = {
  109. { P_BI_TCXO, 0 },
  110. { P_GCC_DISP_GPLL0_CLK, 4 },
  111. };
  112. static const struct clk_parent_data disp_cc_parent_data_3[] = {
  113. { .index = DT_BI_TCXO },
  114. { .index = DT_GCC_DISP_GPLL0_CLK },
  115. };
  116. static const struct parent_map disp_cc_parent_map_4[] = {
  117. { P_BI_TCXO, 0 },
  118. { P_DP0_PHY_PLL_LINK_CLK, 1 },
  119. };
  120. static const struct clk_parent_data disp_cc_parent_data_4[] = {
  121. { .index = DT_BI_TCXO },
  122. { .index = DT_DP0_PHY_PLL_LINK_CLK },
  123. };
  124. static const struct parent_map disp_cc_parent_map_5[] = {
  125. { P_BI_TCXO, 0 },
  126. { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 },
  127. };
  128. static const struct clk_parent_data disp_cc_parent_data_5[] = {
  129. { .index = DT_BI_TCXO },
  130. { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
  131. };
  132. static const struct parent_map disp_cc_parent_map_6[] = {
  133. { P_BI_TCXO, 0 },
  134. { P_DISP_CC_PLL0_OUT_MAIN, 1 },
  135. { P_GCC_DISP_GPLL0_CLK, 4 },
  136. { P_DISP_CC_PLL0_OUT_EVEN, 6 },
  137. };
  138. static const struct clk_parent_data disp_cc_parent_data_6[] = {
  139. { .index = DT_BI_TCXO },
  140. { .hw = &disp_cc_pll0.clkr.hw },
  141. { .index = DT_GCC_DISP_GPLL0_CLK },
  142. { .hw = &disp_cc_pll0.clkr.hw },
  143. };
  144. static const struct parent_map disp_cc_parent_map_7[] = {
  145. { P_SLEEP_CLK, 0 },
  146. };
  147. static const struct clk_parent_data disp_cc_parent_data_7_ao[] = {
  148. { .index = DT_SLEEP_CLK },
  149. };
  150. static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = {
  151. F(19200000, P_BI_TCXO, 1, 0, 0),
  152. F(37500000, P_GCC_DISP_GPLL0_CLK, 8, 0, 0),
  153. F(75000000, P_GCC_DISP_GPLL0_CLK, 4, 0, 0),
  154. { }
  155. };
  156. static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = {
  157. .cmd_rcgr = 0x8130,
  158. .mnd_width = 0,
  159. .hid_width = 5,
  160. .parent_map = disp_cc_parent_map_3,
  161. .freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src,
  162. .clkr.hw.init = &(const struct clk_init_data) {
  163. .name = "disp_cc_mdss_ahb_clk_src",
  164. .parent_data = disp_cc_parent_data_3,
  165. .num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
  166. .flags = CLK_SET_RATE_PARENT,
  167. .ops = &clk_rcg2_shared_ops,
  168. },
  169. };
  170. static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
  171. .cmd_rcgr = 0x8098,
  172. .mnd_width = 0,
  173. .hid_width = 5,
  174. .parent_map = disp_cc_parent_map_1,
  175. .clkr.hw.init = &(const struct clk_init_data) {
  176. .name = "disp_cc_mdss_byte0_clk_src",
  177. .parent_data = disp_cc_parent_data_1,
  178. .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
  179. .flags = CLK_SET_RATE_PARENT,
  180. .ops = &clk_byte2_ops,
  181. },
  182. };
  183. static const struct freq_tbl ftbl_disp_cc_mdss_dptx0_aux_clk_src[] = {
  184. F(19200000, P_BI_TCXO, 1, 0, 0),
  185. { }
  186. };
  187. static struct clk_rcg2 disp_cc_mdss_dptx0_aux_clk_src = {
  188. .cmd_rcgr = 0x8118,
  189. .mnd_width = 0,
  190. .hid_width = 5,
  191. .parent_map = disp_cc_parent_map_0,
  192. .freq_tbl = ftbl_disp_cc_mdss_dptx0_aux_clk_src,
  193. .clkr.hw.init = &(const struct clk_init_data) {
  194. .name = "disp_cc_mdss_dptx0_aux_clk_src",
  195. .parent_data = disp_cc_parent_data_0,
  196. .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
  197. .flags = CLK_SET_RATE_PARENT,
  198. .ops = &clk_rcg2_ops,
  199. },
  200. };
  201. static struct clk_rcg2 disp_cc_mdss_dptx0_link_clk_src = {
  202. .cmd_rcgr = 0x80cc,
  203. .mnd_width = 0,
  204. .hid_width = 5,
  205. .parent_map = disp_cc_parent_map_4,
  206. .clkr.hw.init = &(const struct clk_init_data) {
  207. .name = "disp_cc_mdss_dptx0_link_clk_src",
  208. .parent_data = disp_cc_parent_data_4,
  209. .num_parents = ARRAY_SIZE(disp_cc_parent_data_4),
  210. .flags = CLK_SET_RATE_PARENT,
  211. .ops = &clk_byte2_ops,
  212. },
  213. };
  214. static struct clk_rcg2 disp_cc_mdss_dptx0_pixel0_clk_src = {
  215. .cmd_rcgr = 0x80e8,
  216. .mnd_width = 16,
  217. .hid_width = 5,
  218. .parent_map = disp_cc_parent_map_2,
  219. .clkr.hw.init = &(const struct clk_init_data) {
  220. .name = "disp_cc_mdss_dptx0_pixel0_clk_src",
  221. .parent_data = disp_cc_parent_data_2,
  222. .num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
  223. .flags = CLK_SET_RATE_PARENT,
  224. .ops = &clk_dp_ops,
  225. },
  226. };
  227. static struct clk_rcg2 disp_cc_mdss_dptx0_pixel1_clk_src = {
  228. .cmd_rcgr = 0x8100,
  229. .mnd_width = 16,
  230. .hid_width = 5,
  231. .parent_map = disp_cc_parent_map_2,
  232. .clkr.hw.init = &(const struct clk_init_data) {
  233. .name = "disp_cc_mdss_dptx0_pixel1_clk_src",
  234. .parent_data = disp_cc_parent_data_2,
  235. .num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
  236. .flags = CLK_SET_RATE_PARENT,
  237. .ops = &clk_dp_ops,
  238. },
  239. };
  240. static const struct freq_tbl ftbl_disp_cc_mdss_esc0_clk_src[] = {
  241. F(9600000, P_BI_TCXO, 2, 0, 0),
  242. F(12800000, P_BI_TCXO, 1.5, 0, 0),
  243. F(19200000, P_BI_TCXO, 1, 0, 0),
  244. { }
  245. };
  246. static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
  247. .cmd_rcgr = 0x80b4,
  248. .mnd_width = 0,
  249. .hid_width = 5,
  250. .parent_map = disp_cc_parent_map_5,
  251. .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,
  252. .clkr.hw.init = &(const struct clk_init_data) {
  253. .name = "disp_cc_mdss_esc0_clk_src",
  254. .parent_data = disp_cc_parent_data_5,
  255. .num_parents = ARRAY_SIZE(disp_cc_parent_data_5),
  256. .flags = CLK_SET_RATE_PARENT,
  257. .ops = &clk_rcg2_ops,
  258. },
  259. };
  260. static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
  261. F(19200000, P_BI_TCXO, 1, 0, 0),
  262. F(85714286, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
  263. F(100000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
  264. F(200000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
  265. F(342000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
  266. F(402000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
  267. F(535000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
  268. F(600000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
  269. F(630000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
  270. { }
  271. };
  272. static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
  273. .cmd_rcgr = 0x8068,
  274. .mnd_width = 0,
  275. .hid_width = 5,
  276. .parent_map = disp_cc_parent_map_6,
  277. .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
  278. .clkr.hw.init = &(const struct clk_init_data) {
  279. .name = "disp_cc_mdss_mdp_clk_src",
  280. .parent_data = disp_cc_parent_data_6,
  281. .num_parents = ARRAY_SIZE(disp_cc_parent_data_6),
  282. .flags = CLK_SET_RATE_PARENT,
  283. .ops = &clk_rcg2_shared_ops,
  284. },
  285. };
  286. static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
  287. .cmd_rcgr = 0x8050,
  288. .mnd_width = 8,
  289. .hid_width = 5,
  290. .parent_map = disp_cc_parent_map_1,
  291. .clkr.hw.init = &(const struct clk_init_data) {
  292. .name = "disp_cc_mdss_pclk0_clk_src",
  293. .parent_data = disp_cc_parent_data_1,
  294. .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
  295. .flags = CLK_SET_RATE_PARENT,
  296. .ops = &clk_pixel_ops,
  297. },
  298. };
  299. static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
  300. .cmd_rcgr = 0x8080,
  301. .mnd_width = 0,
  302. .hid_width = 5,
  303. .parent_map = disp_cc_parent_map_0,
  304. .freq_tbl = ftbl_disp_cc_mdss_dptx0_aux_clk_src,
  305. .clkr.hw.init = &(const struct clk_init_data) {
  306. .name = "disp_cc_mdss_vsync_clk_src",
  307. .parent_data = disp_cc_parent_data_0,
  308. .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
  309. .flags = CLK_SET_RATE_PARENT,
  310. .ops = &clk_rcg2_ops,
  311. },
  312. };
  313. static const struct freq_tbl ftbl_disp_cc_sleep_clk_src[] = {
  314. F(32000, P_SLEEP_CLK, 1, 0, 0),
  315. { }
  316. };
  317. static struct clk_rcg2 disp_cc_sleep_clk_src = {
  318. .cmd_rcgr = 0xe054,
  319. .mnd_width = 0,
  320. .hid_width = 5,
  321. .parent_map = disp_cc_parent_map_7,
  322. .freq_tbl = ftbl_disp_cc_sleep_clk_src,
  323. .clkr.hw.init = &(const struct clk_init_data) {
  324. .name = "disp_cc_sleep_clk_src",
  325. .parent_data = disp_cc_parent_data_7_ao,
  326. .num_parents = ARRAY_SIZE(disp_cc_parent_data_7_ao),
  327. .flags = CLK_SET_RATE_PARENT,
  328. .ops = &clk_rcg2_ops,
  329. },
  330. };
  331. static struct clk_rcg2 disp_cc_xo_clk_src = {
  332. .cmd_rcgr = 0xe034,
  333. .mnd_width = 0,
  334. .hid_width = 5,
  335. .parent_map = disp_cc_parent_map_0,
  336. .freq_tbl = ftbl_disp_cc_mdss_dptx0_aux_clk_src,
  337. .clkr.hw.init = &(const struct clk_init_data) {
  338. .name = "disp_cc_xo_clk_src",
  339. .parent_data = disp_cc_parent_data_0,
  340. .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
  341. .flags = CLK_SET_RATE_PARENT,
  342. .ops = &clk_rcg2_ops,
  343. },
  344. };
  345. static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
  346. .reg = 0x80b0,
  347. .shift = 0,
  348. .width = 4,
  349. .clkr.hw.init = &(const struct clk_init_data) {
  350. .name = "disp_cc_mdss_byte0_div_clk_src",
  351. .parent_hws = (const struct clk_hw*[]) {
  352. &disp_cc_mdss_byte0_clk_src.clkr.hw,
  353. },
  354. .num_parents = 1,
  355. .flags = CLK_SET_RATE_PARENT,
  356. .ops = &clk_regmap_div_ops,
  357. },
  358. };
  359. static struct clk_regmap_div disp_cc_mdss_dptx0_link_div_clk_src = {
  360. .reg = 0x80e4,
  361. .shift = 0,
  362. .width = 4,
  363. .clkr.hw.init = &(const struct clk_init_data) {
  364. .name = "disp_cc_mdss_dptx0_link_div_clk_src",
  365. .parent_hws = (const struct clk_hw*[]) {
  366. &disp_cc_mdss_dptx0_link_clk_src.clkr.hw,
  367. },
  368. .num_parents = 1,
  369. .flags = CLK_SET_RATE_PARENT,
  370. .ops = &clk_regmap_div_ro_ops,
  371. },
  372. };
  373. static struct clk_branch disp_cc_mdss_accu_clk = {
  374. .halt_reg = 0xe050,
  375. .halt_check = BRANCH_HALT_VOTED,
  376. .clkr = {
  377. .enable_reg = 0xe050,
  378. .enable_mask = BIT(0),
  379. .hw.init = &(const struct clk_init_data) {
  380. .name = "disp_cc_mdss_accu_clk",
  381. .parent_hws = (const struct clk_hw*[]) {
  382. &disp_cc_xo_clk_src.clkr.hw,
  383. },
  384. .num_parents = 1,
  385. .flags = CLK_SET_RATE_PARENT,
  386. .ops = &clk_branch2_ops,
  387. },
  388. },
  389. };
  390. static struct clk_branch disp_cc_mdss_ahb1_clk = {
  391. .halt_reg = 0xa020,
  392. .halt_check = BRANCH_HALT,
  393. .clkr = {
  394. .enable_reg = 0xa020,
  395. .enable_mask = BIT(0),
  396. .hw.init = &(const struct clk_init_data) {
  397. .name = "disp_cc_mdss_ahb1_clk",
  398. .parent_hws = (const struct clk_hw*[]) {
  399. &disp_cc_mdss_ahb_clk_src.clkr.hw,
  400. },
  401. .num_parents = 1,
  402. .flags = CLK_SET_RATE_PARENT,
  403. .ops = &clk_branch2_ops,
  404. },
  405. },
  406. };
  407. static struct clk_branch disp_cc_mdss_ahb_clk = {
  408. .halt_reg = 0x804c,
  409. .halt_check = BRANCH_HALT,
  410. .clkr = {
  411. .enable_reg = 0x804c,
  412. .enable_mask = BIT(0),
  413. .hw.init = &(const struct clk_init_data) {
  414. .name = "disp_cc_mdss_ahb_clk",
  415. .parent_hws = (const struct clk_hw*[]) {
  416. &disp_cc_mdss_ahb_clk_src.clkr.hw,
  417. },
  418. .num_parents = 1,
  419. .flags = CLK_SET_RATE_PARENT,
  420. .ops = &clk_branch2_ops,
  421. },
  422. },
  423. };
  424. static struct clk_branch disp_cc_mdss_byte0_clk = {
  425. .halt_reg = 0x8024,
  426. .halt_check = BRANCH_HALT,
  427. .clkr = {
  428. .enable_reg = 0x8024,
  429. .enable_mask = BIT(0),
  430. .hw.init = &(const struct clk_init_data) {
  431. .name = "disp_cc_mdss_byte0_clk",
  432. .parent_hws = (const struct clk_hw*[]) {
  433. &disp_cc_mdss_byte0_clk_src.clkr.hw,
  434. },
  435. .num_parents = 1,
  436. .flags = CLK_SET_RATE_PARENT,
  437. .ops = &clk_branch2_ops,
  438. },
  439. },
  440. };
  441. static struct clk_branch disp_cc_mdss_byte0_intf_clk = {
  442. .halt_reg = 0x8028,
  443. .halt_check = BRANCH_HALT,
  444. .clkr = {
  445. .enable_reg = 0x8028,
  446. .enable_mask = BIT(0),
  447. .hw.init = &(const struct clk_init_data) {
  448. .name = "disp_cc_mdss_byte0_intf_clk",
  449. .parent_hws = (const struct clk_hw*[]) {
  450. &disp_cc_mdss_byte0_div_clk_src.clkr.hw,
  451. },
  452. .num_parents = 1,
  453. .flags = CLK_SET_RATE_PARENT,
  454. .ops = &clk_branch2_ops,
  455. },
  456. },
  457. };
  458. static struct clk_branch disp_cc_mdss_dptx0_aux_clk = {
  459. .halt_reg = 0x8048,
  460. .halt_check = BRANCH_HALT,
  461. .clkr = {
  462. .enable_reg = 0x8048,
  463. .enable_mask = BIT(0),
  464. .hw.init = &(const struct clk_init_data) {
  465. .name = "disp_cc_mdss_dptx0_aux_clk",
  466. .parent_hws = (const struct clk_hw*[]) {
  467. &disp_cc_mdss_dptx0_aux_clk_src.clkr.hw,
  468. },
  469. .num_parents = 1,
  470. .flags = CLK_SET_RATE_PARENT,
  471. .ops = &clk_branch2_ops,
  472. },
  473. },
  474. };
  475. static struct clk_branch disp_cc_mdss_dptx0_crypto_clk = {
  476. .halt_reg = 0x803c,
  477. .halt_check = BRANCH_HALT,
  478. .clkr = {
  479. .enable_reg = 0x803c,
  480. .enable_mask = BIT(0),
  481. .hw.init = &(const struct clk_init_data) {
  482. .name = "disp_cc_mdss_dptx0_crypto_clk",
  483. .parent_hws = (const struct clk_hw*[]) {
  484. &disp_cc_mdss_dptx0_link_clk_src.clkr.hw,
  485. },
  486. .num_parents = 1,
  487. .flags = CLK_SET_RATE_PARENT,
  488. .ops = &clk_branch2_ops,
  489. },
  490. },
  491. };
  492. static struct clk_branch disp_cc_mdss_dptx0_link_clk = {
  493. .halt_reg = 0x8030,
  494. .halt_check = BRANCH_HALT,
  495. .clkr = {
  496. .enable_reg = 0x8030,
  497. .enable_mask = BIT(0),
  498. .hw.init = &(const struct clk_init_data) {
  499. .name = "disp_cc_mdss_dptx0_link_clk",
  500. .parent_hws = (const struct clk_hw*[]) {
  501. &disp_cc_mdss_dptx0_link_clk_src.clkr.hw,
  502. },
  503. .num_parents = 1,
  504. .flags = CLK_SET_RATE_PARENT,
  505. .ops = &clk_branch2_ops,
  506. },
  507. },
  508. };
  509. static struct clk_branch disp_cc_mdss_dptx0_link_intf_clk = {
  510. .halt_reg = 0x8038,
  511. .halt_check = BRANCH_HALT,
  512. .clkr = {
  513. .enable_reg = 0x8038,
  514. .enable_mask = BIT(0),
  515. .hw.init = &(const struct clk_init_data) {
  516. .name = "disp_cc_mdss_dptx0_link_intf_clk",
  517. .parent_hws = (const struct clk_hw*[]) {
  518. &disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw,
  519. },
  520. .num_parents = 1,
  521. .flags = CLK_SET_RATE_PARENT,
  522. .ops = &clk_branch2_ops,
  523. },
  524. },
  525. };
  526. static struct clk_branch disp_cc_mdss_dptx0_pixel0_clk = {
  527. .halt_reg = 0x8040,
  528. .halt_check = BRANCH_HALT,
  529. .clkr = {
  530. .enable_reg = 0x8040,
  531. .enable_mask = BIT(0),
  532. .hw.init = &(const struct clk_init_data) {
  533. .name = "disp_cc_mdss_dptx0_pixel0_clk",
  534. .parent_hws = (const struct clk_hw*[]) {
  535. &disp_cc_mdss_dptx0_pixel0_clk_src.clkr.hw,
  536. },
  537. .num_parents = 1,
  538. .flags = CLK_SET_RATE_PARENT,
  539. .ops = &clk_branch2_ops,
  540. },
  541. },
  542. };
  543. static struct clk_branch disp_cc_mdss_dptx0_pixel1_clk = {
  544. .halt_reg = 0x8044,
  545. .halt_check = BRANCH_HALT,
  546. .clkr = {
  547. .enable_reg = 0x8044,
  548. .enable_mask = BIT(0),
  549. .hw.init = &(const struct clk_init_data) {
  550. .name = "disp_cc_mdss_dptx0_pixel1_clk",
  551. .parent_hws = (const struct clk_hw*[]) {
  552. &disp_cc_mdss_dptx0_pixel1_clk_src.clkr.hw,
  553. },
  554. .num_parents = 1,
  555. .flags = CLK_SET_RATE_PARENT,
  556. .ops = &clk_branch2_ops,
  557. },
  558. },
  559. };
  560. static struct clk_branch disp_cc_mdss_dptx0_usb_router_link_intf_clk = {
  561. .halt_reg = 0x8034,
  562. .halt_check = BRANCH_HALT,
  563. .clkr = {
  564. .enable_reg = 0x8034,
  565. .enable_mask = BIT(0),
  566. .hw.init = &(const struct clk_init_data) {
  567. .name = "disp_cc_mdss_dptx0_usb_router_link_intf_clk",
  568. .parent_hws = (const struct clk_hw*[]) {
  569. &disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw,
  570. },
  571. .num_parents = 1,
  572. .flags = CLK_SET_RATE_PARENT,
  573. .ops = &clk_branch2_ops,
  574. },
  575. },
  576. };
  577. static struct clk_branch disp_cc_mdss_esc0_clk = {
  578. .halt_reg = 0x802c,
  579. .halt_check = BRANCH_HALT,
  580. .clkr = {
  581. .enable_reg = 0x802c,
  582. .enable_mask = BIT(0),
  583. .hw.init = &(const struct clk_init_data) {
  584. .name = "disp_cc_mdss_esc0_clk",
  585. .parent_hws = (const struct clk_hw*[]) {
  586. &disp_cc_mdss_esc0_clk_src.clkr.hw,
  587. },
  588. .num_parents = 1,
  589. .flags = CLK_SET_RATE_PARENT,
  590. .ops = &clk_branch2_ops,
  591. },
  592. },
  593. };
  594. static struct clk_branch disp_cc_mdss_mdp1_clk = {
  595. .halt_reg = 0xa004,
  596. .halt_check = BRANCH_HALT,
  597. .clkr = {
  598. .enable_reg = 0xa004,
  599. .enable_mask = BIT(0),
  600. .hw.init = &(const struct clk_init_data) {
  601. .name = "disp_cc_mdss_mdp1_clk",
  602. .parent_hws = (const struct clk_hw*[]) {
  603. &disp_cc_mdss_mdp_clk_src.clkr.hw,
  604. },
  605. .num_parents = 1,
  606. .flags = CLK_SET_RATE_PARENT,
  607. .ops = &clk_branch2_ops,
  608. },
  609. },
  610. };
  611. static struct clk_branch disp_cc_mdss_mdp_clk = {
  612. .halt_reg = 0x8008,
  613. .halt_check = BRANCH_HALT,
  614. .clkr = {
  615. .enable_reg = 0x8008,
  616. .enable_mask = BIT(0),
  617. .hw.init = &(const struct clk_init_data) {
  618. .name = "disp_cc_mdss_mdp_clk",
  619. .parent_hws = (const struct clk_hw*[]) {
  620. &disp_cc_mdss_mdp_clk_src.clkr.hw,
  621. },
  622. .num_parents = 1,
  623. .flags = CLK_SET_RATE_PARENT,
  624. .ops = &clk_branch2_ops,
  625. },
  626. },
  627. };
  628. static struct clk_branch disp_cc_mdss_mdp_lut1_clk = {
  629. .halt_reg = 0xa010,
  630. .halt_check = BRANCH_HALT,
  631. .clkr = {
  632. .enable_reg = 0xa010,
  633. .enable_mask = BIT(0),
  634. .hw.init = &(const struct clk_init_data) {
  635. .name = "disp_cc_mdss_mdp_lut1_clk",
  636. .parent_hws = (const struct clk_hw*[]) {
  637. &disp_cc_mdss_mdp_clk_src.clkr.hw,
  638. },
  639. .num_parents = 1,
  640. .flags = CLK_SET_RATE_PARENT,
  641. .ops = &clk_branch2_ops,
  642. },
  643. },
  644. };
  645. static struct clk_branch disp_cc_mdss_mdp_lut_clk = {
  646. .halt_reg = 0x8014,
  647. .halt_check = BRANCH_HALT_VOTED,
  648. .clkr = {
  649. .enable_reg = 0x8014,
  650. .enable_mask = BIT(0),
  651. .hw.init = &(const struct clk_init_data) {
  652. .name = "disp_cc_mdss_mdp_lut_clk",
  653. .parent_hws = (const struct clk_hw*[]) {
  654. &disp_cc_mdss_mdp_clk_src.clkr.hw,
  655. },
  656. .num_parents = 1,
  657. .flags = CLK_SET_RATE_PARENT,
  658. .ops = &clk_branch2_ops,
  659. },
  660. },
  661. };
  662. static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = {
  663. .halt_reg = 0xc004,
  664. .halt_check = BRANCH_HALT_VOTED,
  665. .clkr = {
  666. .enable_reg = 0xc004,
  667. .enable_mask = BIT(0),
  668. .hw.init = &(const struct clk_init_data) {
  669. .name = "disp_cc_mdss_non_gdsc_ahb_clk",
  670. .parent_hws = (const struct clk_hw*[]) {
  671. &disp_cc_mdss_ahb_clk_src.clkr.hw,
  672. },
  673. .num_parents = 1,
  674. .flags = CLK_SET_RATE_PARENT,
  675. .ops = &clk_branch2_ops,
  676. },
  677. },
  678. };
  679. static struct clk_branch disp_cc_mdss_pclk0_clk = {
  680. .halt_reg = 0x8004,
  681. .halt_check = BRANCH_HALT,
  682. .clkr = {
  683. .enable_reg = 0x8004,
  684. .enable_mask = BIT(0),
  685. .hw.init = &(const struct clk_init_data) {
  686. .name = "disp_cc_mdss_pclk0_clk",
  687. .parent_hws = (const struct clk_hw*[]) {
  688. &disp_cc_mdss_pclk0_clk_src.clkr.hw,
  689. },
  690. .num_parents = 1,
  691. .flags = CLK_SET_RATE_PARENT,
  692. .ops = &clk_branch2_ops,
  693. },
  694. },
  695. };
  696. static struct clk_branch disp_cc_mdss_rscc_ahb_clk = {
  697. .halt_reg = 0xc00c,
  698. .halt_check = BRANCH_HALT,
  699. .clkr = {
  700. .enable_reg = 0xc00c,
  701. .enable_mask = BIT(0),
  702. .hw.init = &(const struct clk_init_data) {
  703. .name = "disp_cc_mdss_rscc_ahb_clk",
  704. .parent_hws = (const struct clk_hw*[]) {
  705. &disp_cc_mdss_ahb_clk_src.clkr.hw,
  706. },
  707. .num_parents = 1,
  708. .flags = CLK_SET_RATE_PARENT,
  709. .ops = &clk_branch2_ops,
  710. },
  711. },
  712. };
  713. static struct clk_branch disp_cc_mdss_rscc_vsync_clk = {
  714. .halt_reg = 0xc008,
  715. .halt_check = BRANCH_HALT,
  716. .clkr = {
  717. .enable_reg = 0xc008,
  718. .enable_mask = BIT(0),
  719. .hw.init = &(const struct clk_init_data) {
  720. .name = "disp_cc_mdss_rscc_vsync_clk",
  721. .parent_hws = (const struct clk_hw*[]) {
  722. &disp_cc_mdss_vsync_clk_src.clkr.hw,
  723. },
  724. .num_parents = 1,
  725. .flags = CLK_SET_RATE_PARENT,
  726. .ops = &clk_branch2_ops,
  727. },
  728. },
  729. };
  730. static struct clk_branch disp_cc_mdss_vsync1_clk = {
  731. .halt_reg = 0xa01c,
  732. .halt_check = BRANCH_HALT,
  733. .clkr = {
  734. .enable_reg = 0xa01c,
  735. .enable_mask = BIT(0),
  736. .hw.init = &(const struct clk_init_data) {
  737. .name = "disp_cc_mdss_vsync1_clk",
  738. .parent_hws = (const struct clk_hw*[]) {
  739. &disp_cc_mdss_vsync_clk_src.clkr.hw,
  740. },
  741. .num_parents = 1,
  742. .flags = CLK_SET_RATE_PARENT,
  743. .ops = &clk_branch2_ops,
  744. },
  745. },
  746. };
  747. static struct clk_branch disp_cc_mdss_vsync_clk = {
  748. .halt_reg = 0x8020,
  749. .halt_check = BRANCH_HALT,
  750. .clkr = {
  751. .enable_reg = 0x8020,
  752. .enable_mask = BIT(0),
  753. .hw.init = &(const struct clk_init_data) {
  754. .name = "disp_cc_mdss_vsync_clk",
  755. .parent_hws = (const struct clk_hw*[]) {
  756. &disp_cc_mdss_vsync_clk_src.clkr.hw,
  757. },
  758. .num_parents = 1,
  759. .flags = CLK_SET_RATE_PARENT,
  760. .ops = &clk_branch2_ops,
  761. },
  762. },
  763. };
  764. static struct gdsc disp_cc_mdss_core_gdsc = {
  765. .gdscr = 0x9000,
  766. .en_rest_wait_val = 0x2,
  767. .en_few_wait_val = 0x2,
  768. .clk_dis_wait_val = 0xf,
  769. .pd = {
  770. .name = "disp_cc_mdss_core_gdsc",
  771. },
  772. .pwrsts = PWRSTS_OFF_ON,
  773. .flags = POLL_CFG_GDSCR | HW_CTRL | RETAIN_FF_ENABLE,
  774. };
  775. static struct gdsc disp_cc_mdss_core_int2_gdsc = {
  776. .gdscr = 0xb000,
  777. .en_rest_wait_val = 0x2,
  778. .en_few_wait_val = 0x2,
  779. .clk_dis_wait_val = 0xf,
  780. .pd = {
  781. .name = "disp_cc_mdss_core_int2_gdsc",
  782. },
  783. .pwrsts = PWRSTS_OFF_ON,
  784. .flags = POLL_CFG_GDSCR | HW_CTRL | RETAIN_FF_ENABLE,
  785. };
  786. static struct clk_regmap *disp_cc_milos_clocks[] = {
  787. [DISP_CC_MDSS_ACCU_CLK] = &disp_cc_mdss_accu_clk.clkr,
  788. [DISP_CC_MDSS_AHB1_CLK] = &disp_cc_mdss_ahb1_clk.clkr,
  789. [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,
  790. [DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr,
  791. [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr,
  792. [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr,
  793. [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr,
  794. [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr,
  795. [DISP_CC_MDSS_DPTX0_AUX_CLK] = &disp_cc_mdss_dptx0_aux_clk.clkr,
  796. [DISP_CC_MDSS_DPTX0_AUX_CLK_SRC] = &disp_cc_mdss_dptx0_aux_clk_src.clkr,
  797. [DISP_CC_MDSS_DPTX0_CRYPTO_CLK] = &disp_cc_mdss_dptx0_crypto_clk.clkr,
  798. [DISP_CC_MDSS_DPTX0_LINK_CLK] = &disp_cc_mdss_dptx0_link_clk.clkr,
  799. [DISP_CC_MDSS_DPTX0_LINK_CLK_SRC] = &disp_cc_mdss_dptx0_link_clk_src.clkr,
  800. [DISP_CC_MDSS_DPTX0_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx0_link_div_clk_src.clkr,
  801. [DISP_CC_MDSS_DPTX0_LINK_INTF_CLK] = &disp_cc_mdss_dptx0_link_intf_clk.clkr,
  802. [DISP_CC_MDSS_DPTX0_PIXEL0_CLK] = &disp_cc_mdss_dptx0_pixel0_clk.clkr,
  803. [DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx0_pixel0_clk_src.clkr,
  804. [DISP_CC_MDSS_DPTX0_PIXEL1_CLK] = &disp_cc_mdss_dptx0_pixel1_clk.clkr,
  805. [DISP_CC_MDSS_DPTX0_PIXEL1_CLK_SRC] = &disp_cc_mdss_dptx0_pixel1_clk_src.clkr,
  806. [DISP_CC_MDSS_DPTX0_USB_ROUTER_LINK_INTF_CLK] =
  807. &disp_cc_mdss_dptx0_usb_router_link_intf_clk.clkr,
  808. [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,
  809. [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,
  810. [DISP_CC_MDSS_MDP1_CLK] = &disp_cc_mdss_mdp1_clk.clkr,
  811. [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,
  812. [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,
  813. [DISP_CC_MDSS_MDP_LUT1_CLK] = &disp_cc_mdss_mdp_lut1_clk.clkr,
  814. [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,
  815. [DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr,
  816. [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr,
  817. [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,
  818. [DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr,
  819. [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr,
  820. [DISP_CC_MDSS_VSYNC1_CLK] = &disp_cc_mdss_vsync1_clk.clkr,
  821. [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,
  822. [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,
  823. [DISP_CC_PLL0] = &disp_cc_pll0.clkr,
  824. [DISP_CC_SLEEP_CLK_SRC] = &disp_cc_sleep_clk_src.clkr,
  825. [DISP_CC_XO_CLK_SRC] = &disp_cc_xo_clk_src.clkr,
  826. };
  827. static const struct qcom_reset_map disp_cc_milos_resets[] = {
  828. [DISP_CC_MDSS_CORE_BCR] = { 0x8000 },
  829. [DISP_CC_MDSS_CORE_INT2_BCR] = { 0xa000 },
  830. [DISP_CC_MDSS_RSCC_BCR] = { 0xc000 },
  831. };
  832. static struct gdsc *disp_cc_milos_gdscs[] = {
  833. [DISP_CC_MDSS_CORE_GDSC] = &disp_cc_mdss_core_gdsc,
  834. [DISP_CC_MDSS_CORE_INT2_GDSC] = &disp_cc_mdss_core_int2_gdsc,
  835. };
  836. static struct clk_alpha_pll *disp_cc_milos_plls[] = {
  837. &disp_cc_pll0,
  838. };
  839. static u32 disp_cc_milos_critical_cbcrs[] = {
  840. 0xe06c, /* DISP_CC_SLEEP_CLK */
  841. 0xe04c, /* DISP_CC_XO_CLK */
  842. };
  843. static const struct regmap_config disp_cc_milos_regmap_config = {
  844. .reg_bits = 32,
  845. .reg_stride = 4,
  846. .val_bits = 32,
  847. .max_register = 0x11008,
  848. .fast_io = true,
  849. };
  850. static void disp_cc_milos_clk_regs_configure(struct device *dev, struct regmap *regmap)
  851. {
  852. /* Enable clock gating for MDP clocks */
  853. regmap_update_bits(regmap, DISP_CC_MISC_CMD, 0x10, 0x10);
  854. }
  855. static struct qcom_cc_driver_data disp_cc_milos_driver_data = {
  856. .alpha_plls = disp_cc_milos_plls,
  857. .num_alpha_plls = ARRAY_SIZE(disp_cc_milos_plls),
  858. .clk_cbcrs = disp_cc_milos_critical_cbcrs,
  859. .num_clk_cbcrs = ARRAY_SIZE(disp_cc_milos_critical_cbcrs),
  860. .clk_regs_configure = disp_cc_milos_clk_regs_configure,
  861. };
  862. static const struct qcom_cc_desc disp_cc_milos_desc = {
  863. .config = &disp_cc_milos_regmap_config,
  864. .clks = disp_cc_milos_clocks,
  865. .num_clks = ARRAY_SIZE(disp_cc_milos_clocks),
  866. .resets = disp_cc_milos_resets,
  867. .num_resets = ARRAY_SIZE(disp_cc_milos_resets),
  868. .gdscs = disp_cc_milos_gdscs,
  869. .num_gdscs = ARRAY_SIZE(disp_cc_milos_gdscs),
  870. .use_rpm = true,
  871. .driver_data = &disp_cc_milos_driver_data,
  872. };
  873. static const struct of_device_id disp_cc_milos_match_table[] = {
  874. { .compatible = "qcom,milos-dispcc" },
  875. { }
  876. };
  877. MODULE_DEVICE_TABLE(of, disp_cc_milos_match_table);
  878. static int disp_cc_milos_probe(struct platform_device *pdev)
  879. {
  880. return qcom_cc_probe(pdev, &disp_cc_milos_desc);
  881. }
  882. static struct platform_driver disp_cc_milos_driver = {
  883. .probe = disp_cc_milos_probe,
  884. .driver = {
  885. .name = "disp_cc-milos",
  886. .of_match_table = disp_cc_milos_match_table,
  887. },
  888. };
  889. module_platform_driver(disp_cc_milos_driver);
  890. MODULE_DESCRIPTION("QTI DISP_CC Milos Driver");
  891. MODULE_LICENSE("GPL");