gpucc-milos.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
  4. * Copyright (c) 2025, Luca Weiss <luca.weiss@fairphone.com>
  5. */
  6. #include <linux/clk-provider.h>
  7. #include <linux/mod_devicetable.h>
  8. #include <linux/module.h>
  9. #include <linux/platform_device.h>
  10. #include <linux/regmap.h>
  11. #include <dt-bindings/clock/qcom,milos-gpucc.h>
  12. #include "clk-alpha-pll.h"
  13. #include "clk-branch.h"
  14. #include "clk-pll.h"
  15. #include "clk-rcg.h"
  16. #include "clk-regmap.h"
  17. #include "clk-regmap-divider.h"
  18. #include "clk-regmap-mux.h"
  19. #include "common.h"
  20. #include "gdsc.h"
  21. #include "reset.h"
  22. /* Need to match the order of clocks in DT binding */
  23. enum {
  24. DT_BI_TCXO,
  25. DT_GPLL0_OUT_MAIN,
  26. DT_GPLL0_OUT_MAIN_DIV,
  27. };
  28. enum {
  29. P_BI_TCXO,
  30. P_GPLL0_OUT_MAIN,
  31. P_GPLL0_OUT_MAIN_DIV,
  32. P_GPU_CC_PLL0_OUT_EVEN,
  33. P_GPU_CC_PLL0_OUT_MAIN,
  34. P_GPU_CC_PLL0_OUT_ODD,
  35. };
  36. static const struct pll_vco lucid_ole_vco[] = {
  37. { 249600000, 2300000000, 0 },
  38. };
  39. /* 700.0 MHz Configuration */
  40. static const struct alpha_pll_config gpu_cc_pll0_config = {
  41. .l = 0x24,
  42. .alpha = 0x7555,
  43. .config_ctl_val = 0x20485699,
  44. .config_ctl_hi_val = 0x00182261,
  45. .config_ctl_hi1_val = 0x82aa299c,
  46. .test_ctl_val = 0x00000000,
  47. .test_ctl_hi_val = 0x00000003,
  48. .test_ctl_hi1_val = 0x00009000,
  49. .test_ctl_hi2_val = 0x00000034,
  50. .user_ctl_val = 0x00000400,
  51. .user_ctl_hi_val = 0x00000005,
  52. };
  53. static struct clk_alpha_pll gpu_cc_pll0 = {
  54. .offset = 0x0,
  55. .config = &gpu_cc_pll0_config,
  56. .vco_table = lucid_ole_vco,
  57. .num_vco = ARRAY_SIZE(lucid_ole_vco),
  58. .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
  59. .clkr = {
  60. .hw.init = &(const struct clk_init_data) {
  61. .name = "gpu_cc_pll0",
  62. .parent_data = &(const struct clk_parent_data) {
  63. .index = DT_BI_TCXO,
  64. },
  65. .num_parents = 1,
  66. .ops = &clk_alpha_pll_lucid_evo_ops,
  67. },
  68. },
  69. };
  70. static const struct clk_div_table post_div_table_gpu_cc_pll0_out_even[] = {
  71. { 0x1, 2 },
  72. { }
  73. };
  74. static struct clk_alpha_pll_postdiv gpu_cc_pll0_out_even = {
  75. .offset = 0x0,
  76. .post_div_shift = 10,
  77. .post_div_table = post_div_table_gpu_cc_pll0_out_even,
  78. .num_post_div = ARRAY_SIZE(post_div_table_gpu_cc_pll0_out_even),
  79. .width = 4,
  80. .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
  81. .clkr.hw.init = &(const struct clk_init_data) {
  82. .name = "gpu_cc_pll0_out_even",
  83. .parent_hws = (const struct clk_hw*[]) {
  84. &gpu_cc_pll0.clkr.hw,
  85. },
  86. .num_parents = 1,
  87. .flags = CLK_SET_RATE_PARENT,
  88. .ops = &clk_alpha_pll_postdiv_lucid_ole_ops,
  89. },
  90. };
  91. static const struct parent_map gpu_cc_parent_map_0[] = {
  92. { P_BI_TCXO, 0 },
  93. { P_GPLL0_OUT_MAIN, 5 },
  94. { P_GPLL0_OUT_MAIN_DIV, 6 },
  95. };
  96. static const struct clk_parent_data gpu_cc_parent_data_0[] = {
  97. { .index = DT_BI_TCXO },
  98. { .index = DT_GPLL0_OUT_MAIN },
  99. { .index = DT_GPLL0_OUT_MAIN_DIV },
  100. };
  101. static const struct parent_map gpu_cc_parent_map_1[] = {
  102. { P_BI_TCXO, 0 },
  103. { P_GPU_CC_PLL0_OUT_MAIN, 1 },
  104. { P_GPU_CC_PLL0_OUT_EVEN, 2 },
  105. { P_GPU_CC_PLL0_OUT_ODD, 3 },
  106. { P_GPLL0_OUT_MAIN, 5 },
  107. { P_GPLL0_OUT_MAIN_DIV, 6 },
  108. };
  109. static const struct clk_parent_data gpu_cc_parent_data_1[] = {
  110. { .index = DT_BI_TCXO },
  111. { .hw = &gpu_cc_pll0.clkr.hw },
  112. { .hw = &gpu_cc_pll0_out_even.clkr.hw },
  113. { .hw = &gpu_cc_pll0.clkr.hw },
  114. { .index = DT_GPLL0_OUT_MAIN },
  115. { .index = DT_GPLL0_OUT_MAIN_DIV },
  116. };
  117. static const struct freq_tbl ftbl_gpu_cc_ff_clk_src[] = {
  118. F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
  119. { }
  120. };
  121. static struct clk_rcg2 gpu_cc_ff_clk_src = {
  122. .cmd_rcgr = 0x9474,
  123. .mnd_width = 0,
  124. .hid_width = 5,
  125. .parent_map = gpu_cc_parent_map_0,
  126. .freq_tbl = ftbl_gpu_cc_ff_clk_src,
  127. .clkr.hw.init = &(const struct clk_init_data) {
  128. .name = "gpu_cc_ff_clk_src",
  129. .parent_data = gpu_cc_parent_data_0,
  130. .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0),
  131. .flags = CLK_SET_RATE_PARENT,
  132. .ops = &clk_rcg2_shared_ops,
  133. },
  134. };
  135. static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
  136. F(19200000, P_BI_TCXO, 1, 0, 0),
  137. F(350000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0),
  138. F(650000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0),
  139. F(687500000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0),
  140. { }
  141. };
  142. static struct clk_rcg2 gpu_cc_gmu_clk_src = {
  143. .cmd_rcgr = 0x9318,
  144. .mnd_width = 0,
  145. .hid_width = 5,
  146. .parent_map = gpu_cc_parent_map_1,
  147. .freq_tbl = ftbl_gpu_cc_gmu_clk_src,
  148. .clkr.hw.init = &(const struct clk_init_data) {
  149. .name = "gpu_cc_gmu_clk_src",
  150. .parent_data = gpu_cc_parent_data_1,
  151. .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1),
  152. .flags = CLK_SET_RATE_PARENT,
  153. .ops = &clk_rcg2_shared_ops,
  154. },
  155. };
  156. static const struct freq_tbl ftbl_gpu_cc_hub_clk_src[] = {
  157. F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
  158. F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
  159. F(400000000, P_GPLL0_OUT_MAIN, 1.5, 0, 0),
  160. { }
  161. };
  162. static struct clk_rcg2 gpu_cc_hub_clk_src = {
  163. .cmd_rcgr = 0x93ec,
  164. .mnd_width = 0,
  165. .hid_width = 5,
  166. .parent_map = gpu_cc_parent_map_1,
  167. .freq_tbl = ftbl_gpu_cc_hub_clk_src,
  168. .clkr.hw.init = &(const struct clk_init_data) {
  169. .name = "gpu_cc_hub_clk_src",
  170. .parent_data = gpu_cc_parent_data_1,
  171. .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1),
  172. .flags = CLK_SET_RATE_PARENT,
  173. .ops = &clk_rcg2_shared_ops,
  174. },
  175. };
  176. static struct clk_regmap_div gpu_cc_hub_div_clk_src = {
  177. .reg = 0x942c,
  178. .shift = 0,
  179. .width = 4,
  180. .clkr.hw.init = &(const struct clk_init_data) {
  181. .name = "gpu_cc_hub_div_clk_src",
  182. .parent_hws = (const struct clk_hw*[]) {
  183. &gpu_cc_hub_clk_src.clkr.hw,
  184. },
  185. .num_parents = 1,
  186. .flags = CLK_SET_RATE_PARENT,
  187. .ops = &clk_regmap_div_ro_ops,
  188. },
  189. };
  190. static struct clk_branch gpu_cc_ahb_clk = {
  191. .halt_reg = 0x90bc,
  192. .halt_check = BRANCH_HALT_DELAY,
  193. .clkr = {
  194. .enable_reg = 0x90bc,
  195. .enable_mask = BIT(0),
  196. .hw.init = &(const struct clk_init_data) {
  197. .name = "gpu_cc_ahb_clk",
  198. .parent_hws = (const struct clk_hw*[]) {
  199. &gpu_cc_hub_div_clk_src.clkr.hw,
  200. },
  201. .num_parents = 1,
  202. .flags = CLK_SET_RATE_PARENT,
  203. .ops = &clk_branch2_ops,
  204. },
  205. },
  206. };
  207. static struct clk_branch gpu_cc_cx_accu_shift_clk = {
  208. .halt_reg = 0x910c,
  209. .halt_check = BRANCH_HALT_VOTED,
  210. .clkr = {
  211. .enable_reg = 0x910c,
  212. .enable_mask = BIT(0),
  213. .hw.init = &(const struct clk_init_data) {
  214. .name = "gpu_cc_cx_accu_shift_clk",
  215. .ops = &clk_branch2_ops,
  216. },
  217. },
  218. };
  219. static struct clk_branch gpu_cc_cx_ff_clk = {
  220. .halt_reg = 0x90ec,
  221. .halt_check = BRANCH_HALT,
  222. .clkr = {
  223. .enable_reg = 0x90ec,
  224. .enable_mask = BIT(0),
  225. .hw.init = &(const struct clk_init_data) {
  226. .name = "gpu_cc_cx_ff_clk",
  227. .parent_hws = (const struct clk_hw*[]) {
  228. &gpu_cc_ff_clk_src.clkr.hw,
  229. },
  230. .num_parents = 1,
  231. .flags = CLK_SET_RATE_PARENT,
  232. .ops = &clk_branch2_ops,
  233. },
  234. },
  235. };
  236. static struct clk_branch gpu_cc_cx_gmu_clk = {
  237. .halt_reg = 0x90d4,
  238. .halt_check = BRANCH_HALT_VOTED,
  239. .clkr = {
  240. .enable_reg = 0x90d4,
  241. .enable_mask = BIT(0),
  242. .hw.init = &(const struct clk_init_data) {
  243. .name = "gpu_cc_cx_gmu_clk",
  244. .parent_hws = (const struct clk_hw*[]) {
  245. &gpu_cc_gmu_clk_src.clkr.hw,
  246. },
  247. .num_parents = 1,
  248. .flags = CLK_SET_RATE_PARENT,
  249. .ops = &clk_branch2_aon_ops,
  250. },
  251. },
  252. };
  253. static struct clk_branch gpu_cc_cxo_clk = {
  254. .halt_reg = 0x90e4,
  255. .halt_check = BRANCH_HALT,
  256. .clkr = {
  257. .enable_reg = 0x90e4,
  258. .enable_mask = BIT(0),
  259. .hw.init = &(const struct clk_init_data) {
  260. .name = "gpu_cc_cxo_clk",
  261. .ops = &clk_branch2_ops,
  262. },
  263. },
  264. };
  265. static struct clk_branch gpu_cc_dpm_clk = {
  266. .halt_reg = 0x9110,
  267. .halt_check = BRANCH_HALT,
  268. .clkr = {
  269. .enable_reg = 0x9110,
  270. .enable_mask = BIT(0),
  271. .hw.init = &(const struct clk_init_data) {
  272. .name = "gpu_cc_dpm_clk",
  273. .ops = &clk_branch2_ops,
  274. },
  275. },
  276. };
  277. static struct clk_branch gpu_cc_freq_measure_clk = {
  278. .halt_reg = 0x900c,
  279. .halt_check = BRANCH_HALT,
  280. .clkr = {
  281. .enable_reg = 0x900c,
  282. .enable_mask = BIT(0),
  283. .hw.init = &(const struct clk_init_data) {
  284. .name = "gpu_cc_freq_measure_clk",
  285. .ops = &clk_branch2_ops,
  286. },
  287. },
  288. };
  289. static struct clk_branch gpu_cc_gx_accu_shift_clk = {
  290. .halt_reg = 0x9070,
  291. .halt_check = BRANCH_HALT_VOTED,
  292. .clkr = {
  293. .enable_reg = 0x9070,
  294. .enable_mask = BIT(0),
  295. .hw.init = &(const struct clk_init_data) {
  296. .name = "gpu_cc_gx_accu_shift_clk",
  297. .ops = &clk_branch2_ops,
  298. },
  299. },
  300. };
  301. static struct clk_branch gpu_cc_gx_acd_ahb_ff_clk = {
  302. .halt_reg = 0x9068,
  303. .halt_check = BRANCH_HALT,
  304. .clkr = {
  305. .enable_reg = 0x9068,
  306. .enable_mask = BIT(0),
  307. .hw.init = &(const struct clk_init_data) {
  308. .name = "gpu_cc_gx_acd_ahb_ff_clk",
  309. .parent_hws = (const struct clk_hw*[]) {
  310. &gpu_cc_ff_clk_src.clkr.hw,
  311. },
  312. .num_parents = 1,
  313. .flags = CLK_SET_RATE_PARENT,
  314. .ops = &clk_branch2_ops,
  315. },
  316. },
  317. };
  318. static struct clk_branch gpu_cc_gx_gmu_clk = {
  319. .halt_reg = 0x9060,
  320. .halt_check = BRANCH_HALT,
  321. .clkr = {
  322. .enable_reg = 0x9060,
  323. .enable_mask = BIT(0),
  324. .hw.init = &(const struct clk_init_data) {
  325. .name = "gpu_cc_gx_gmu_clk",
  326. .parent_hws = (const struct clk_hw*[]) {
  327. &gpu_cc_gmu_clk_src.clkr.hw,
  328. },
  329. .num_parents = 1,
  330. .flags = CLK_SET_RATE_PARENT,
  331. .ops = &clk_branch2_ops,
  332. },
  333. },
  334. };
  335. static struct clk_branch gpu_cc_gx_rcg_ahb_ff_clk = {
  336. .halt_reg = 0x906c,
  337. .halt_check = BRANCH_HALT_VOTED,
  338. .clkr = {
  339. .enable_reg = 0x906c,
  340. .enable_mask = BIT(0),
  341. .hw.init = &(const struct clk_init_data) {
  342. .name = "gpu_cc_gx_rcg_ahb_ff_clk",
  343. .parent_hws = (const struct clk_hw*[]) {
  344. &gpu_cc_ff_clk_src.clkr.hw,
  345. },
  346. .num_parents = 1,
  347. .flags = CLK_SET_RATE_PARENT,
  348. .ops = &clk_branch2_ops,
  349. },
  350. },
  351. };
  352. static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = {
  353. .halt_reg = 0x7000,
  354. .halt_check = BRANCH_HALT_VOTED,
  355. .clkr = {
  356. .enable_reg = 0x7000,
  357. .enable_mask = BIT(0),
  358. .hw.init = &(const struct clk_init_data) {
  359. .name = "gpu_cc_hlos1_vote_gpu_smmu_clk",
  360. .ops = &clk_branch2_ops,
  361. },
  362. },
  363. };
  364. static struct clk_branch gpu_cc_hub_aon_clk = {
  365. .halt_reg = 0x93e8,
  366. .halt_check = BRANCH_HALT_VOTED,
  367. .clkr = {
  368. .enable_reg = 0x93e8,
  369. .enable_mask = BIT(0),
  370. .hw.init = &(const struct clk_init_data) {
  371. .name = "gpu_cc_hub_aon_clk",
  372. .parent_hws = (const struct clk_hw*[]) {
  373. &gpu_cc_hub_clk_src.clkr.hw,
  374. },
  375. .num_parents = 1,
  376. .flags = CLK_SET_RATE_PARENT,
  377. .ops = &clk_branch2_aon_ops,
  378. },
  379. },
  380. };
  381. static struct clk_branch gpu_cc_hub_cx_int_clk = {
  382. .halt_reg = 0x90e8,
  383. .halt_check = BRANCH_HALT_VOTED,
  384. .clkr = {
  385. .enable_reg = 0x90e8,
  386. .enable_mask = BIT(0),
  387. .hw.init = &(const struct clk_init_data) {
  388. .name = "gpu_cc_hub_cx_int_clk",
  389. .parent_hws = (const struct clk_hw*[]) {
  390. &gpu_cc_hub_clk_src.clkr.hw,
  391. },
  392. .num_parents = 1,
  393. .flags = CLK_SET_RATE_PARENT,
  394. .ops = &clk_branch2_aon_ops,
  395. },
  396. },
  397. };
  398. static struct clk_branch gpu_cc_memnoc_gfx_clk = {
  399. .halt_reg = 0x90f4,
  400. .halt_check = BRANCH_HALT_VOTED,
  401. .clkr = {
  402. .enable_reg = 0x90f4,
  403. .enable_mask = BIT(0),
  404. .hw.init = &(const struct clk_init_data) {
  405. .name = "gpu_cc_memnoc_gfx_clk",
  406. .ops = &clk_branch2_ops,
  407. },
  408. },
  409. };
  410. static struct gdsc gpu_cc_cx_gdsc = {
  411. .gdscr = 0x9080,
  412. .gds_hw_ctrl = 0x9094,
  413. .en_rest_wait_val = 0x2,
  414. .en_few_wait_val = 0x2,
  415. .clk_dis_wait_val = 0x8,
  416. .pd = {
  417. .name = "gpu_cc_cx_gdsc",
  418. },
  419. .pwrsts = PWRSTS_OFF_ON,
  420. .flags = RETAIN_FF_ENABLE | VOTABLE,
  421. };
  422. static struct clk_regmap *gpu_cc_milos_clocks[] = {
  423. [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr,
  424. [GPU_CC_CX_ACCU_SHIFT_CLK] = &gpu_cc_cx_accu_shift_clk.clkr,
  425. [GPU_CC_CX_FF_CLK] = &gpu_cc_cx_ff_clk.clkr,
  426. [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
  427. [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
  428. [GPU_CC_DPM_CLK] = &gpu_cc_dpm_clk.clkr,
  429. [GPU_CC_FF_CLK_SRC] = &gpu_cc_ff_clk_src.clkr,
  430. [GPU_CC_FREQ_MEASURE_CLK] = &gpu_cc_freq_measure_clk.clkr,
  431. [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
  432. [GPU_CC_GX_ACCU_SHIFT_CLK] = &gpu_cc_gx_accu_shift_clk.clkr,
  433. [GPU_CC_GX_ACD_AHB_FF_CLK] = &gpu_cc_gx_acd_ahb_ff_clk.clkr,
  434. [GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr,
  435. [GPU_CC_GX_RCG_AHB_FF_CLK] = &gpu_cc_gx_rcg_ahb_ff_clk.clkr,
  436. [GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_clk.clkr,
  437. [GPU_CC_HUB_AON_CLK] = &gpu_cc_hub_aon_clk.clkr,
  438. [GPU_CC_HUB_CLK_SRC] = &gpu_cc_hub_clk_src.clkr,
  439. [GPU_CC_HUB_CX_INT_CLK] = &gpu_cc_hub_cx_int_clk.clkr,
  440. [GPU_CC_HUB_DIV_CLK_SRC] = &gpu_cc_hub_div_clk_src.clkr,
  441. [GPU_CC_MEMNOC_GFX_CLK] = &gpu_cc_memnoc_gfx_clk.clkr,
  442. [GPU_CC_PLL0] = &gpu_cc_pll0.clkr,
  443. [GPU_CC_PLL0_OUT_EVEN] = &gpu_cc_pll0_out_even.clkr,
  444. };
  445. static struct gdsc *gpu_cc_milos_gdscs[] = {
  446. [GPU_CC_CX_GDSC] = &gpu_cc_cx_gdsc,
  447. };
  448. static const struct qcom_reset_map gpu_cc_milos_resets[] = {
  449. [GPU_CC_CB_BCR] = { 0x93a0 },
  450. [GPU_CC_CX_BCR] = { 0x907c },
  451. [GPU_CC_FAST_HUB_BCR] = { 0x93e4 },
  452. [GPU_CC_FF_BCR] = { 0x9470 },
  453. [GPU_CC_GMU_BCR] = { 0x9314 },
  454. [GPU_CC_GX_BCR] = { 0x905c },
  455. [GPU_CC_RBCPR_BCR] = { 0x91e0 },
  456. [GPU_CC_XO_BCR] = { 0x9000 },
  457. };
  458. static struct clk_alpha_pll *gpu_cc_milos_plls[] = {
  459. &gpu_cc_pll0,
  460. };
  461. static u32 gpu_cc_milos_critical_cbcrs[] = {
  462. 0x93a4, /* GPU_CC_CB_CLK */
  463. 0x9008, /* GPU_CC_CXO_AON_CLK */
  464. 0x9010, /* GPU_CC_DEMET_CLK */
  465. 0x9064, /* GPU_CC_GX_AHB_FF_CLK */
  466. 0x93a8, /* GPU_CC_RSCC_HUB_AON_CLK */
  467. 0x9004, /* GPU_CC_RSCC_XO_AON_CLK */
  468. 0x90cc, /* GPU_CC_SLEEP_CLK */
  469. };
  470. static const struct regmap_config gpu_cc_milos_regmap_config = {
  471. .reg_bits = 32,
  472. .reg_stride = 4,
  473. .val_bits = 32,
  474. .max_register = 0x95e8,
  475. .fast_io = true,
  476. };
  477. static struct qcom_cc_driver_data gpu_cc_milos_driver_data = {
  478. .alpha_plls = gpu_cc_milos_plls,
  479. .num_alpha_plls = ARRAY_SIZE(gpu_cc_milos_plls),
  480. .clk_cbcrs = gpu_cc_milos_critical_cbcrs,
  481. .num_clk_cbcrs = ARRAY_SIZE(gpu_cc_milos_critical_cbcrs),
  482. };
  483. static const struct qcom_cc_desc gpu_cc_milos_desc = {
  484. .config = &gpu_cc_milos_regmap_config,
  485. .clks = gpu_cc_milos_clocks,
  486. .num_clks = ARRAY_SIZE(gpu_cc_milos_clocks),
  487. .resets = gpu_cc_milos_resets,
  488. .num_resets = ARRAY_SIZE(gpu_cc_milos_resets),
  489. .gdscs = gpu_cc_milos_gdscs,
  490. .num_gdscs = ARRAY_SIZE(gpu_cc_milos_gdscs),
  491. .use_rpm = true,
  492. .driver_data = &gpu_cc_milos_driver_data,
  493. };
  494. static const struct of_device_id gpu_cc_milos_match_table[] = {
  495. { .compatible = "qcom,milos-gpucc" },
  496. { }
  497. };
  498. MODULE_DEVICE_TABLE(of, gpu_cc_milos_match_table);
  499. static int gpu_cc_milos_probe(struct platform_device *pdev)
  500. {
  501. return qcom_cc_probe(pdev, &gpu_cc_milos_desc);
  502. }
  503. static struct platform_driver gpu_cc_milos_driver = {
  504. .probe = gpu_cc_milos_probe,
  505. .driver = {
  506. .name = "gpu_cc-milos",
  507. .of_match_table = gpu_cc_milos_match_table,
  508. },
  509. };
  510. module_platform_driver(gpu_cc_milos_driver);
  511. MODULE_DESCRIPTION("QTI GPU_CC Milos Driver");
  512. MODULE_LICENSE("GPL");