meson8b.c 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136
  1. /*
  2. * AmLogic S802 (Meson8) / S805 (Meson8b) / S812 (Meson8m2) Clock Controller
  3. * Driver
  4. *
  5. * Copyright (c) 2015 Endless Mobile, Inc.
  6. * Author: Carlo Caione <carlo@endlessm.com>
  7. *
  8. * Copyright (c) 2016 BayLibre, Inc.
  9. * Michael Turquette <mturquette@baylibre.com>
  10. *
  11. * This program is free software; you can redistribute it and/or modify it
  12. * under the terms and conditions of the GNU General Public License,
  13. * version 2, as published by the Free Software Foundation.
  14. *
  15. * This program is distributed in the hope it will be useful, but WITHOUT
  16. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  17. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  18. * more details.
  19. *
  20. * You should have received a copy of the GNU General Public License along with
  21. * this program. If not, see <http://www.gnu.org/licenses/>.
  22. */
  23. #include <linux/clk.h>
  24. #include <linux/clk-provider.h>
  25. #include <linux/init.h>
  26. #include <linux/of_address.h>
  27. #include <linux/platform_device.h>
  28. #include <linux/reset-controller.h>
  29. #include <linux/slab.h>
  30. #include <linux/regmap.h>
  31. #include "clkc.h"
  32. #include "meson8b.h"
  33. #include "clk-regmap.h"
  34. static DEFINE_SPINLOCK(meson_clk_lock);
  35. static void __iomem *clk_base;
  36. struct meson8b_clk_reset {
  37. struct reset_controller_dev reset;
  38. void __iomem *base;
  39. };
  40. static const struct pll_rate_table sys_pll_rate_table[] = {
  41. PLL_RATE(312000000, 52, 1, 2),
  42. PLL_RATE(336000000, 56, 1, 2),
  43. PLL_RATE(360000000, 60, 1, 2),
  44. PLL_RATE(384000000, 64, 1, 2),
  45. PLL_RATE(408000000, 68, 1, 2),
  46. PLL_RATE(432000000, 72, 1, 2),
  47. PLL_RATE(456000000, 76, 1, 2),
  48. PLL_RATE(480000000, 80, 1, 2),
  49. PLL_RATE(504000000, 84, 1, 2),
  50. PLL_RATE(528000000, 88, 1, 2),
  51. PLL_RATE(552000000, 92, 1, 2),
  52. PLL_RATE(576000000, 96, 1, 2),
  53. PLL_RATE(600000000, 50, 1, 1),
  54. PLL_RATE(624000000, 52, 1, 1),
  55. PLL_RATE(648000000, 54, 1, 1),
  56. PLL_RATE(672000000, 56, 1, 1),
  57. PLL_RATE(696000000, 58, 1, 1),
  58. PLL_RATE(720000000, 60, 1, 1),
  59. PLL_RATE(744000000, 62, 1, 1),
  60. PLL_RATE(768000000, 64, 1, 1),
  61. PLL_RATE(792000000, 66, 1, 1),
  62. PLL_RATE(816000000, 68, 1, 1),
  63. PLL_RATE(840000000, 70, 1, 1),
  64. PLL_RATE(864000000, 72, 1, 1),
  65. PLL_RATE(888000000, 74, 1, 1),
  66. PLL_RATE(912000000, 76, 1, 1),
  67. PLL_RATE(936000000, 78, 1, 1),
  68. PLL_RATE(960000000, 80, 1, 1),
  69. PLL_RATE(984000000, 82, 1, 1),
  70. PLL_RATE(1008000000, 84, 1, 1),
  71. PLL_RATE(1032000000, 86, 1, 1),
  72. PLL_RATE(1056000000, 88, 1, 1),
  73. PLL_RATE(1080000000, 90, 1, 1),
  74. PLL_RATE(1104000000, 92, 1, 1),
  75. PLL_RATE(1128000000, 94, 1, 1),
  76. PLL_RATE(1152000000, 96, 1, 1),
  77. PLL_RATE(1176000000, 98, 1, 1),
  78. PLL_RATE(1200000000, 50, 1, 0),
  79. PLL_RATE(1224000000, 51, 1, 0),
  80. PLL_RATE(1248000000, 52, 1, 0),
  81. PLL_RATE(1272000000, 53, 1, 0),
  82. PLL_RATE(1296000000, 54, 1, 0),
  83. PLL_RATE(1320000000, 55, 1, 0),
  84. PLL_RATE(1344000000, 56, 1, 0),
  85. PLL_RATE(1368000000, 57, 1, 0),
  86. PLL_RATE(1392000000, 58, 1, 0),
  87. PLL_RATE(1416000000, 59, 1, 0),
  88. PLL_RATE(1440000000, 60, 1, 0),
  89. PLL_RATE(1464000000, 61, 1, 0),
  90. PLL_RATE(1488000000, 62, 1, 0),
  91. PLL_RATE(1512000000, 63, 1, 0),
  92. PLL_RATE(1536000000, 64, 1, 0),
  93. { /* sentinel */ },
  94. };
  95. static struct clk_fixed_rate meson8b_xtal = {
  96. .fixed_rate = 24000000,
  97. .hw.init = &(struct clk_init_data){
  98. .name = "xtal",
  99. .num_parents = 0,
  100. .ops = &clk_fixed_rate_ops,
  101. },
  102. };
  103. static struct clk_regmap meson8b_fixed_pll = {
  104. .data = &(struct meson_clk_pll_data){
  105. .m = {
  106. .reg_off = HHI_MPLL_CNTL,
  107. .shift = 0,
  108. .width = 9,
  109. },
  110. .n = {
  111. .reg_off = HHI_MPLL_CNTL,
  112. .shift = 9,
  113. .width = 5,
  114. },
  115. .od = {
  116. .reg_off = HHI_MPLL_CNTL,
  117. .shift = 16,
  118. .width = 2,
  119. },
  120. .frac = {
  121. .reg_off = HHI_MPLL_CNTL2,
  122. .shift = 0,
  123. .width = 12,
  124. },
  125. .l = {
  126. .reg_off = HHI_MPLL_CNTL,
  127. .shift = 31,
  128. .width = 1,
  129. },
  130. .rst = {
  131. .reg_off = HHI_MPLL_CNTL,
  132. .shift = 29,
  133. .width = 1,
  134. },
  135. },
  136. .hw.init = &(struct clk_init_data){
  137. .name = "fixed_pll",
  138. .ops = &meson_clk_pll_ro_ops,
  139. .parent_names = (const char *[]){ "xtal" },
  140. .num_parents = 1,
  141. .flags = CLK_GET_RATE_NOCACHE,
  142. },
  143. };
  144. static struct clk_regmap meson8b_vid_pll = {
  145. .data = &(struct meson_clk_pll_data){
  146. .m = {
  147. .reg_off = HHI_VID_PLL_CNTL,
  148. .shift = 0,
  149. .width = 9,
  150. },
  151. .n = {
  152. .reg_off = HHI_VID_PLL_CNTL,
  153. .shift = 9,
  154. .width = 5,
  155. },
  156. .od = {
  157. .reg_off = HHI_VID_PLL_CNTL,
  158. .shift = 16,
  159. .width = 2,
  160. },
  161. .l = {
  162. .reg_off = HHI_VID_PLL_CNTL,
  163. .shift = 31,
  164. .width = 1,
  165. },
  166. .rst = {
  167. .reg_off = HHI_VID_PLL_CNTL,
  168. .shift = 29,
  169. .width = 1,
  170. },
  171. },
  172. .hw.init = &(struct clk_init_data){
  173. .name = "vid_pll",
  174. .ops = &meson_clk_pll_ro_ops,
  175. .parent_names = (const char *[]){ "xtal" },
  176. .num_parents = 1,
  177. .flags = CLK_GET_RATE_NOCACHE,
  178. },
  179. };
  180. static struct clk_regmap meson8b_sys_pll = {
  181. .data = &(struct meson_clk_pll_data){
  182. .m = {
  183. .reg_off = HHI_SYS_PLL_CNTL,
  184. .shift = 0,
  185. .width = 9,
  186. },
  187. .n = {
  188. .reg_off = HHI_SYS_PLL_CNTL,
  189. .shift = 9,
  190. .width = 5,
  191. },
  192. .od = {
  193. .reg_off = HHI_SYS_PLL_CNTL,
  194. .shift = 16,
  195. .width = 2,
  196. },
  197. .l = {
  198. .reg_off = HHI_SYS_PLL_CNTL,
  199. .shift = 31,
  200. .width = 1,
  201. },
  202. .rst = {
  203. .reg_off = HHI_SYS_PLL_CNTL,
  204. .shift = 29,
  205. .width = 1,
  206. },
  207. .table = sys_pll_rate_table,
  208. },
  209. .hw.init = &(struct clk_init_data){
  210. .name = "sys_pll",
  211. .ops = &meson_clk_pll_ro_ops,
  212. .parent_names = (const char *[]){ "xtal" },
  213. .num_parents = 1,
  214. .flags = CLK_GET_RATE_NOCACHE,
  215. },
  216. };
  217. static struct clk_fixed_factor meson8b_fclk_div2_div = {
  218. .mult = 1,
  219. .div = 2,
  220. .hw.init = &(struct clk_init_data){
  221. .name = "fclk_div2_div",
  222. .ops = &clk_fixed_factor_ops,
  223. .parent_names = (const char *[]){ "fixed_pll" },
  224. .num_parents = 1,
  225. },
  226. };
  227. static struct clk_regmap meson8b_fclk_div2 = {
  228. .data = &(struct clk_regmap_gate_data){
  229. .offset = HHI_MPLL_CNTL6,
  230. .bit_idx = 27,
  231. },
  232. .hw.init = &(struct clk_init_data){
  233. .name = "fclk_div2",
  234. .ops = &clk_regmap_gate_ops,
  235. .parent_names = (const char *[]){ "fclk_div2_div" },
  236. .num_parents = 1,
  237. },
  238. };
  239. static struct clk_fixed_factor meson8b_fclk_div3_div = {
  240. .mult = 1,
  241. .div = 3,
  242. .hw.init = &(struct clk_init_data){
  243. .name = "fclk_div3_div",
  244. .ops = &clk_fixed_factor_ops,
  245. .parent_names = (const char *[]){ "fixed_pll" },
  246. .num_parents = 1,
  247. },
  248. };
  249. static struct clk_regmap meson8b_fclk_div3 = {
  250. .data = &(struct clk_regmap_gate_data){
  251. .offset = HHI_MPLL_CNTL6,
  252. .bit_idx = 28,
  253. },
  254. .hw.init = &(struct clk_init_data){
  255. .name = "fclk_div3",
  256. .ops = &clk_regmap_gate_ops,
  257. .parent_names = (const char *[]){ "fclk_div3_div" },
  258. .num_parents = 1,
  259. },
  260. };
  261. static struct clk_fixed_factor meson8b_fclk_div4_div = {
  262. .mult = 1,
  263. .div = 4,
  264. .hw.init = &(struct clk_init_data){
  265. .name = "fclk_div4_div",
  266. .ops = &clk_fixed_factor_ops,
  267. .parent_names = (const char *[]){ "fixed_pll" },
  268. .num_parents = 1,
  269. },
  270. };
  271. static struct clk_regmap meson8b_fclk_div4 = {
  272. .data = &(struct clk_regmap_gate_data){
  273. .offset = HHI_MPLL_CNTL6,
  274. .bit_idx = 29,
  275. },
  276. .hw.init = &(struct clk_init_data){
  277. .name = "fclk_div4",
  278. .ops = &clk_regmap_gate_ops,
  279. .parent_names = (const char *[]){ "fclk_div4_div" },
  280. .num_parents = 1,
  281. },
  282. };
  283. static struct clk_fixed_factor meson8b_fclk_div5_div = {
  284. .mult = 1,
  285. .div = 5,
  286. .hw.init = &(struct clk_init_data){
  287. .name = "fclk_div5_div",
  288. .ops = &clk_fixed_factor_ops,
  289. .parent_names = (const char *[]){ "fixed_pll" },
  290. .num_parents = 1,
  291. },
  292. };
  293. static struct clk_regmap meson8b_fclk_div5 = {
  294. .data = &(struct clk_regmap_gate_data){
  295. .offset = HHI_MPLL_CNTL6,
  296. .bit_idx = 30,
  297. },
  298. .hw.init = &(struct clk_init_data){
  299. .name = "fclk_div5",
  300. .ops = &clk_regmap_gate_ops,
  301. .parent_names = (const char *[]){ "fclk_div5_div" },
  302. .num_parents = 1,
  303. },
  304. };
  305. static struct clk_fixed_factor meson8b_fclk_div7_div = {
  306. .mult = 1,
  307. .div = 7,
  308. .hw.init = &(struct clk_init_data){
  309. .name = "fclk_div7_div",
  310. .ops = &clk_fixed_factor_ops,
  311. .parent_names = (const char *[]){ "fixed_pll" },
  312. .num_parents = 1,
  313. },
  314. };
  315. static struct clk_regmap meson8b_fclk_div7 = {
  316. .data = &(struct clk_regmap_gate_data){
  317. .offset = HHI_MPLL_CNTL6,
  318. .bit_idx = 31,
  319. },
  320. .hw.init = &(struct clk_init_data){
  321. .name = "fclk_div7",
  322. .ops = &clk_regmap_gate_ops,
  323. .parent_names = (const char *[]){ "fclk_div7_div" },
  324. .num_parents = 1,
  325. },
  326. };
  327. static struct clk_regmap meson8b_mpll_prediv = {
  328. .data = &(struct clk_regmap_div_data){
  329. .offset = HHI_MPLL_CNTL5,
  330. .shift = 12,
  331. .width = 1,
  332. },
  333. .hw.init = &(struct clk_init_data){
  334. .name = "mpll_prediv",
  335. .ops = &clk_regmap_divider_ro_ops,
  336. .parent_names = (const char *[]){ "fixed_pll" },
  337. .num_parents = 1,
  338. },
  339. };
  340. static struct clk_regmap meson8b_mpll0_div = {
  341. .data = &(struct meson_clk_mpll_data){
  342. .sdm = {
  343. .reg_off = HHI_MPLL_CNTL7,
  344. .shift = 0,
  345. .width = 14,
  346. },
  347. .sdm_en = {
  348. .reg_off = HHI_MPLL_CNTL7,
  349. .shift = 15,
  350. .width = 1,
  351. },
  352. .n2 = {
  353. .reg_off = HHI_MPLL_CNTL7,
  354. .shift = 16,
  355. .width = 9,
  356. },
  357. .ssen = {
  358. .reg_off = HHI_MPLL_CNTL,
  359. .shift = 25,
  360. .width = 1,
  361. },
  362. .lock = &meson_clk_lock,
  363. },
  364. .hw.init = &(struct clk_init_data){
  365. .name = "mpll0_div",
  366. .ops = &meson_clk_mpll_ops,
  367. .parent_names = (const char *[]){ "mpll_prediv" },
  368. .num_parents = 1,
  369. },
  370. };
  371. static struct clk_regmap meson8b_mpll0 = {
  372. .data = &(struct clk_regmap_gate_data){
  373. .offset = HHI_MPLL_CNTL7,
  374. .bit_idx = 14,
  375. },
  376. .hw.init = &(struct clk_init_data){
  377. .name = "mpll0",
  378. .ops = &clk_regmap_gate_ops,
  379. .parent_names = (const char *[]){ "mpll0_div" },
  380. .num_parents = 1,
  381. .flags = CLK_SET_RATE_PARENT,
  382. },
  383. };
  384. static struct clk_regmap meson8b_mpll1_div = {
  385. .data = &(struct meson_clk_mpll_data){
  386. .sdm = {
  387. .reg_off = HHI_MPLL_CNTL8,
  388. .shift = 0,
  389. .width = 14,
  390. },
  391. .sdm_en = {
  392. .reg_off = HHI_MPLL_CNTL8,
  393. .shift = 15,
  394. .width = 1,
  395. },
  396. .n2 = {
  397. .reg_off = HHI_MPLL_CNTL8,
  398. .shift = 16,
  399. .width = 9,
  400. },
  401. .lock = &meson_clk_lock,
  402. },
  403. .hw.init = &(struct clk_init_data){
  404. .name = "mpll1_div",
  405. .ops = &meson_clk_mpll_ops,
  406. .parent_names = (const char *[]){ "mpll_prediv" },
  407. .num_parents = 1,
  408. },
  409. };
  410. static struct clk_regmap meson8b_mpll1 = {
  411. .data = &(struct clk_regmap_gate_data){
  412. .offset = HHI_MPLL_CNTL8,
  413. .bit_idx = 14,
  414. },
  415. .hw.init = &(struct clk_init_data){
  416. .name = "mpll1",
  417. .ops = &clk_regmap_gate_ops,
  418. .parent_names = (const char *[]){ "mpll1_div" },
  419. .num_parents = 1,
  420. .flags = CLK_SET_RATE_PARENT,
  421. },
  422. };
  423. static struct clk_regmap meson8b_mpll2_div = {
  424. .data = &(struct meson_clk_mpll_data){
  425. .sdm = {
  426. .reg_off = HHI_MPLL_CNTL9,
  427. .shift = 0,
  428. .width = 14,
  429. },
  430. .sdm_en = {
  431. .reg_off = HHI_MPLL_CNTL9,
  432. .shift = 15,
  433. .width = 1,
  434. },
  435. .n2 = {
  436. .reg_off = HHI_MPLL_CNTL9,
  437. .shift = 16,
  438. .width = 9,
  439. },
  440. .lock = &meson_clk_lock,
  441. },
  442. .hw.init = &(struct clk_init_data){
  443. .name = "mpll2_div",
  444. .ops = &meson_clk_mpll_ops,
  445. .parent_names = (const char *[]){ "mpll_prediv" },
  446. .num_parents = 1,
  447. },
  448. };
  449. static struct clk_regmap meson8b_mpll2 = {
  450. .data = &(struct clk_regmap_gate_data){
  451. .offset = HHI_MPLL_CNTL9,
  452. .bit_idx = 14,
  453. },
  454. .hw.init = &(struct clk_init_data){
  455. .name = "mpll2",
  456. .ops = &clk_regmap_gate_ops,
  457. .parent_names = (const char *[]){ "mpll2_div" },
  458. .num_parents = 1,
  459. .flags = CLK_SET_RATE_PARENT,
  460. },
  461. };
  462. static u32 mux_table_clk81[] = { 6, 5, 7 };
  463. static struct clk_regmap meson8b_mpeg_clk_sel = {
  464. .data = &(struct clk_regmap_mux_data){
  465. .offset = HHI_MPEG_CLK_CNTL,
  466. .mask = 0x7,
  467. .shift = 12,
  468. .table = mux_table_clk81,
  469. },
  470. .hw.init = &(struct clk_init_data){
  471. .name = "mpeg_clk_sel",
  472. .ops = &clk_regmap_mux_ro_ops,
  473. /*
  474. * FIXME bits 14:12 selects from 8 possible parents:
  475. * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2,
  476. * fclk_div4, fclk_div3, fclk_div5
  477. */
  478. .parent_names = (const char *[]){ "fclk_div3", "fclk_div4",
  479. "fclk_div5" },
  480. .num_parents = 3,
  481. },
  482. };
  483. static struct clk_regmap meson8b_mpeg_clk_div = {
  484. .data = &(struct clk_regmap_div_data){
  485. .offset = HHI_MPEG_CLK_CNTL,
  486. .shift = 0,
  487. .width = 7,
  488. },
  489. .hw.init = &(struct clk_init_data){
  490. .name = "mpeg_clk_div",
  491. .ops = &clk_regmap_divider_ro_ops,
  492. .parent_names = (const char *[]){ "mpeg_clk_sel" },
  493. .num_parents = 1,
  494. },
  495. };
  496. static struct clk_regmap meson8b_clk81 = {
  497. .data = &(struct clk_regmap_gate_data){
  498. .offset = HHI_MPEG_CLK_CNTL,
  499. .bit_idx = 7,
  500. },
  501. .hw.init = &(struct clk_init_data){
  502. .name = "clk81",
  503. .ops = &clk_regmap_gate_ops,
  504. .parent_names = (const char *[]){ "mpeg_clk_div" },
  505. .num_parents = 1,
  506. .flags = CLK_IS_CRITICAL,
  507. },
  508. };
  509. static struct clk_regmap meson8b_cpu_in_sel = {
  510. .data = &(struct clk_regmap_mux_data){
  511. .offset = HHI_SYS_CPU_CLK_CNTL0,
  512. .mask = 0x1,
  513. .shift = 0,
  514. },
  515. .hw.init = &(struct clk_init_data){
  516. .name = "cpu_in_sel",
  517. .ops = &clk_regmap_mux_ro_ops,
  518. .parent_names = (const char *[]){ "xtal", "sys_pll" },
  519. .num_parents = 2,
  520. .flags = (CLK_SET_RATE_PARENT |
  521. CLK_SET_RATE_NO_REPARENT),
  522. },
  523. };
  524. static struct clk_fixed_factor meson8b_cpu_div2 = {
  525. .mult = 1,
  526. .div = 2,
  527. .hw.init = &(struct clk_init_data){
  528. .name = "cpu_div2",
  529. .ops = &clk_fixed_factor_ops,
  530. .parent_names = (const char *[]){ "cpu_in_sel" },
  531. .num_parents = 1,
  532. .flags = CLK_SET_RATE_PARENT,
  533. },
  534. };
  535. static struct clk_fixed_factor meson8b_cpu_div3 = {
  536. .mult = 1,
  537. .div = 3,
  538. .hw.init = &(struct clk_init_data){
  539. .name = "cpu_div3",
  540. .ops = &clk_fixed_factor_ops,
  541. .parent_names = (const char *[]){ "cpu_in_sel" },
  542. .num_parents = 1,
  543. .flags = CLK_SET_RATE_PARENT,
  544. },
  545. };
  546. static const struct clk_div_table cpu_scale_table[] = {
  547. { .val = 2, .div = 4 },
  548. { .val = 3, .div = 6 },
  549. { .val = 4, .div = 8 },
  550. { .val = 5, .div = 10 },
  551. { .val = 6, .div = 12 },
  552. { .val = 7, .div = 14 },
  553. { .val = 8, .div = 16 },
  554. { /* sentinel */ },
  555. };
  556. static struct clk_regmap meson8b_cpu_scale_div = {
  557. .data = &(struct clk_regmap_div_data){
  558. .offset = HHI_SYS_CPU_CLK_CNTL1,
  559. .shift = 20,
  560. .width = 9,
  561. .table = cpu_scale_table,
  562. .flags = CLK_DIVIDER_ALLOW_ZERO,
  563. },
  564. .hw.init = &(struct clk_init_data){
  565. .name = "cpu_scale_div",
  566. .ops = &clk_regmap_divider_ro_ops,
  567. .parent_names = (const char *[]){ "cpu_in_sel" },
  568. .num_parents = 1,
  569. .flags = CLK_SET_RATE_PARENT,
  570. },
  571. };
  572. static struct clk_regmap meson8b_cpu_scale_out_sel = {
  573. .data = &(struct clk_regmap_mux_data){
  574. .offset = HHI_SYS_CPU_CLK_CNTL0,
  575. .mask = 0x3,
  576. .shift = 2,
  577. },
  578. .hw.init = &(struct clk_init_data){
  579. .name = "cpu_scale_out_sel",
  580. .ops = &clk_regmap_mux_ro_ops,
  581. .parent_names = (const char *[]) { "cpu_in_sel",
  582. "cpu_div2",
  583. "cpu_div3",
  584. "cpu_scale_div" },
  585. .num_parents = 4,
  586. .flags = CLK_SET_RATE_PARENT,
  587. },
  588. };
  589. static struct clk_regmap meson8b_cpu_clk = {
  590. .data = &(struct clk_regmap_mux_data){
  591. .offset = HHI_SYS_CPU_CLK_CNTL0,
  592. .mask = 0x1,
  593. .shift = 7,
  594. },
  595. .hw.init = &(struct clk_init_data){
  596. .name = "cpu_clk",
  597. .ops = &clk_regmap_mux_ro_ops,
  598. .parent_names = (const char *[]){ "xtal",
  599. "cpu_scale_out_sel" },
  600. .num_parents = 2,
  601. .flags = (CLK_SET_RATE_PARENT |
  602. CLK_SET_RATE_NO_REPARENT),
  603. },
  604. };
  605. /* Everything Else (EE) domain gates */
  606. static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0);
  607. static MESON_GATE(meson8b_dos, HHI_GCLK_MPEG0, 1);
  608. static MESON_GATE(meson8b_isa, HHI_GCLK_MPEG0, 5);
  609. static MESON_GATE(meson8b_pl301, HHI_GCLK_MPEG0, 6);
  610. static MESON_GATE(meson8b_periphs, HHI_GCLK_MPEG0, 7);
  611. static MESON_GATE(meson8b_spicc, HHI_GCLK_MPEG0, 8);
  612. static MESON_GATE(meson8b_i2c, HHI_GCLK_MPEG0, 9);
  613. static MESON_GATE(meson8b_sar_adc, HHI_GCLK_MPEG0, 10);
  614. static MESON_GATE(meson8b_smart_card, HHI_GCLK_MPEG0, 11);
  615. static MESON_GATE(meson8b_rng0, HHI_GCLK_MPEG0, 12);
  616. static MESON_GATE(meson8b_uart0, HHI_GCLK_MPEG0, 13);
  617. static MESON_GATE(meson8b_sdhc, HHI_GCLK_MPEG0, 14);
  618. static MESON_GATE(meson8b_stream, HHI_GCLK_MPEG0, 15);
  619. static MESON_GATE(meson8b_async_fifo, HHI_GCLK_MPEG0, 16);
  620. static MESON_GATE(meson8b_sdio, HHI_GCLK_MPEG0, 17);
  621. static MESON_GATE(meson8b_abuf, HHI_GCLK_MPEG0, 18);
  622. static MESON_GATE(meson8b_hiu_iface, HHI_GCLK_MPEG0, 19);
  623. static MESON_GATE(meson8b_assist_misc, HHI_GCLK_MPEG0, 23);
  624. static MESON_GATE(meson8b_spi, HHI_GCLK_MPEG0, 30);
  625. static MESON_GATE(meson8b_i2s_spdif, HHI_GCLK_MPEG1, 2);
  626. static MESON_GATE(meson8b_eth, HHI_GCLK_MPEG1, 3);
  627. static MESON_GATE(meson8b_demux, HHI_GCLK_MPEG1, 4);
  628. static MESON_GATE(meson8b_aiu_glue, HHI_GCLK_MPEG1, 6);
  629. static MESON_GATE(meson8b_iec958, HHI_GCLK_MPEG1, 7);
  630. static MESON_GATE(meson8b_i2s_out, HHI_GCLK_MPEG1, 8);
  631. static MESON_GATE(meson8b_amclk, HHI_GCLK_MPEG1, 9);
  632. static MESON_GATE(meson8b_aififo2, HHI_GCLK_MPEG1, 10);
  633. static MESON_GATE(meson8b_mixer, HHI_GCLK_MPEG1, 11);
  634. static MESON_GATE(meson8b_mixer_iface, HHI_GCLK_MPEG1, 12);
  635. static MESON_GATE(meson8b_adc, HHI_GCLK_MPEG1, 13);
  636. static MESON_GATE(meson8b_blkmv, HHI_GCLK_MPEG1, 14);
  637. static MESON_GATE(meson8b_aiu, HHI_GCLK_MPEG1, 15);
  638. static MESON_GATE(meson8b_uart1, HHI_GCLK_MPEG1, 16);
  639. static MESON_GATE(meson8b_g2d, HHI_GCLK_MPEG1, 20);
  640. static MESON_GATE(meson8b_usb0, HHI_GCLK_MPEG1, 21);
  641. static MESON_GATE(meson8b_usb1, HHI_GCLK_MPEG1, 22);
  642. static MESON_GATE(meson8b_reset, HHI_GCLK_MPEG1, 23);
  643. static MESON_GATE(meson8b_nand, HHI_GCLK_MPEG1, 24);
  644. static MESON_GATE(meson8b_dos_parser, HHI_GCLK_MPEG1, 25);
  645. static MESON_GATE(meson8b_usb, HHI_GCLK_MPEG1, 26);
  646. static MESON_GATE(meson8b_vdin1, HHI_GCLK_MPEG1, 28);
  647. static MESON_GATE(meson8b_ahb_arb0, HHI_GCLK_MPEG1, 29);
  648. static MESON_GATE(meson8b_efuse, HHI_GCLK_MPEG1, 30);
  649. static MESON_GATE(meson8b_boot_rom, HHI_GCLK_MPEG1, 31);
  650. static MESON_GATE(meson8b_ahb_data_bus, HHI_GCLK_MPEG2, 1);
  651. static MESON_GATE(meson8b_ahb_ctrl_bus, HHI_GCLK_MPEG2, 2);
  652. static MESON_GATE(meson8b_hdmi_intr_sync, HHI_GCLK_MPEG2, 3);
  653. static MESON_GATE(meson8b_hdmi_pclk, HHI_GCLK_MPEG2, 4);
  654. static MESON_GATE(meson8b_usb1_ddr_bridge, HHI_GCLK_MPEG2, 8);
  655. static MESON_GATE(meson8b_usb0_ddr_bridge, HHI_GCLK_MPEG2, 9);
  656. static MESON_GATE(meson8b_mmc_pclk, HHI_GCLK_MPEG2, 11);
  657. static MESON_GATE(meson8b_dvin, HHI_GCLK_MPEG2, 12);
  658. static MESON_GATE(meson8b_uart2, HHI_GCLK_MPEG2, 15);
  659. static MESON_GATE(meson8b_sana, HHI_GCLK_MPEG2, 22);
  660. static MESON_GATE(meson8b_vpu_intr, HHI_GCLK_MPEG2, 25);
  661. static MESON_GATE(meson8b_sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26);
  662. static MESON_GATE(meson8b_clk81_a9, HHI_GCLK_MPEG2, 29);
  663. static MESON_GATE(meson8b_vclk2_venci0, HHI_GCLK_OTHER, 1);
  664. static MESON_GATE(meson8b_vclk2_venci1, HHI_GCLK_OTHER, 2);
  665. static MESON_GATE(meson8b_vclk2_vencp0, HHI_GCLK_OTHER, 3);
  666. static MESON_GATE(meson8b_vclk2_vencp1, HHI_GCLK_OTHER, 4);
  667. static MESON_GATE(meson8b_gclk_venci_int, HHI_GCLK_OTHER, 8);
  668. static MESON_GATE(meson8b_gclk_vencp_int, HHI_GCLK_OTHER, 9);
  669. static MESON_GATE(meson8b_dac_clk, HHI_GCLK_OTHER, 10);
  670. static MESON_GATE(meson8b_aoclk_gate, HHI_GCLK_OTHER, 14);
  671. static MESON_GATE(meson8b_iec958_gate, HHI_GCLK_OTHER, 16);
  672. static MESON_GATE(meson8b_enc480p, HHI_GCLK_OTHER, 20);
  673. static MESON_GATE(meson8b_rng1, HHI_GCLK_OTHER, 21);
  674. static MESON_GATE(meson8b_gclk_vencl_int, HHI_GCLK_OTHER, 22);
  675. static MESON_GATE(meson8b_vclk2_venclmcc, HHI_GCLK_OTHER, 24);
  676. static MESON_GATE(meson8b_vclk2_vencl, HHI_GCLK_OTHER, 25);
  677. static MESON_GATE(meson8b_vclk2_other, HHI_GCLK_OTHER, 26);
  678. static MESON_GATE(meson8b_edp, HHI_GCLK_OTHER, 31);
  679. /* Always On (AO) domain gates */
  680. static MESON_GATE(meson8b_ao_media_cpu, HHI_GCLK_AO, 0);
  681. static MESON_GATE(meson8b_ao_ahb_sram, HHI_GCLK_AO, 1);
  682. static MESON_GATE(meson8b_ao_ahb_bus, HHI_GCLK_AO, 2);
  683. static MESON_GATE(meson8b_ao_iface, HHI_GCLK_AO, 3);
  684. static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
  685. .hws = {
  686. [CLKID_XTAL] = &meson8b_xtal.hw,
  687. [CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw,
  688. [CLKID_PLL_VID] = &meson8b_vid_pll.hw,
  689. [CLKID_PLL_SYS] = &meson8b_sys_pll.hw,
  690. [CLKID_FCLK_DIV2] = &meson8b_fclk_div2.hw,
  691. [CLKID_FCLK_DIV3] = &meson8b_fclk_div3.hw,
  692. [CLKID_FCLK_DIV4] = &meson8b_fclk_div4.hw,
  693. [CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw,
  694. [CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw,
  695. [CLKID_CPUCLK] = &meson8b_cpu_clk.hw,
  696. [CLKID_MPEG_SEL] = &meson8b_mpeg_clk_sel.hw,
  697. [CLKID_MPEG_DIV] = &meson8b_mpeg_clk_div.hw,
  698. [CLKID_CLK81] = &meson8b_clk81.hw,
  699. [CLKID_DDR] = &meson8b_ddr.hw,
  700. [CLKID_DOS] = &meson8b_dos.hw,
  701. [CLKID_ISA] = &meson8b_isa.hw,
  702. [CLKID_PL301] = &meson8b_pl301.hw,
  703. [CLKID_PERIPHS] = &meson8b_periphs.hw,
  704. [CLKID_SPICC] = &meson8b_spicc.hw,
  705. [CLKID_I2C] = &meson8b_i2c.hw,
  706. [CLKID_SAR_ADC] = &meson8b_sar_adc.hw,
  707. [CLKID_SMART_CARD] = &meson8b_smart_card.hw,
  708. [CLKID_RNG0] = &meson8b_rng0.hw,
  709. [CLKID_UART0] = &meson8b_uart0.hw,
  710. [CLKID_SDHC] = &meson8b_sdhc.hw,
  711. [CLKID_STREAM] = &meson8b_stream.hw,
  712. [CLKID_ASYNC_FIFO] = &meson8b_async_fifo.hw,
  713. [CLKID_SDIO] = &meson8b_sdio.hw,
  714. [CLKID_ABUF] = &meson8b_abuf.hw,
  715. [CLKID_HIU_IFACE] = &meson8b_hiu_iface.hw,
  716. [CLKID_ASSIST_MISC] = &meson8b_assist_misc.hw,
  717. [CLKID_SPI] = &meson8b_spi.hw,
  718. [CLKID_I2S_SPDIF] = &meson8b_i2s_spdif.hw,
  719. [CLKID_ETH] = &meson8b_eth.hw,
  720. [CLKID_DEMUX] = &meson8b_demux.hw,
  721. [CLKID_AIU_GLUE] = &meson8b_aiu_glue.hw,
  722. [CLKID_IEC958] = &meson8b_iec958.hw,
  723. [CLKID_I2S_OUT] = &meson8b_i2s_out.hw,
  724. [CLKID_AMCLK] = &meson8b_amclk.hw,
  725. [CLKID_AIFIFO2] = &meson8b_aififo2.hw,
  726. [CLKID_MIXER] = &meson8b_mixer.hw,
  727. [CLKID_MIXER_IFACE] = &meson8b_mixer_iface.hw,
  728. [CLKID_ADC] = &meson8b_adc.hw,
  729. [CLKID_BLKMV] = &meson8b_blkmv.hw,
  730. [CLKID_AIU] = &meson8b_aiu.hw,
  731. [CLKID_UART1] = &meson8b_uart1.hw,
  732. [CLKID_G2D] = &meson8b_g2d.hw,
  733. [CLKID_USB0] = &meson8b_usb0.hw,
  734. [CLKID_USB1] = &meson8b_usb1.hw,
  735. [CLKID_RESET] = &meson8b_reset.hw,
  736. [CLKID_NAND] = &meson8b_nand.hw,
  737. [CLKID_DOS_PARSER] = &meson8b_dos_parser.hw,
  738. [CLKID_USB] = &meson8b_usb.hw,
  739. [CLKID_VDIN1] = &meson8b_vdin1.hw,
  740. [CLKID_AHB_ARB0] = &meson8b_ahb_arb0.hw,
  741. [CLKID_EFUSE] = &meson8b_efuse.hw,
  742. [CLKID_BOOT_ROM] = &meson8b_boot_rom.hw,
  743. [CLKID_AHB_DATA_BUS] = &meson8b_ahb_data_bus.hw,
  744. [CLKID_AHB_CTRL_BUS] = &meson8b_ahb_ctrl_bus.hw,
  745. [CLKID_HDMI_INTR_SYNC] = &meson8b_hdmi_intr_sync.hw,
  746. [CLKID_HDMI_PCLK] = &meson8b_hdmi_pclk.hw,
  747. [CLKID_USB1_DDR_BRIDGE] = &meson8b_usb1_ddr_bridge.hw,
  748. [CLKID_USB0_DDR_BRIDGE] = &meson8b_usb0_ddr_bridge.hw,
  749. [CLKID_MMC_PCLK] = &meson8b_mmc_pclk.hw,
  750. [CLKID_DVIN] = &meson8b_dvin.hw,
  751. [CLKID_UART2] = &meson8b_uart2.hw,
  752. [CLKID_SANA] = &meson8b_sana.hw,
  753. [CLKID_VPU_INTR] = &meson8b_vpu_intr.hw,
  754. [CLKID_SEC_AHB_AHB3_BRIDGE] = &meson8b_sec_ahb_ahb3_bridge.hw,
  755. [CLKID_CLK81_A9] = &meson8b_clk81_a9.hw,
  756. [CLKID_VCLK2_VENCI0] = &meson8b_vclk2_venci0.hw,
  757. [CLKID_VCLK2_VENCI1] = &meson8b_vclk2_venci1.hw,
  758. [CLKID_VCLK2_VENCP0] = &meson8b_vclk2_vencp0.hw,
  759. [CLKID_VCLK2_VENCP1] = &meson8b_vclk2_vencp1.hw,
  760. [CLKID_GCLK_VENCI_INT] = &meson8b_gclk_venci_int.hw,
  761. [CLKID_GCLK_VENCP_INT] = &meson8b_gclk_vencp_int.hw,
  762. [CLKID_DAC_CLK] = &meson8b_dac_clk.hw,
  763. [CLKID_AOCLK_GATE] = &meson8b_aoclk_gate.hw,
  764. [CLKID_IEC958_GATE] = &meson8b_iec958_gate.hw,
  765. [CLKID_ENC480P] = &meson8b_enc480p.hw,
  766. [CLKID_RNG1] = &meson8b_rng1.hw,
  767. [CLKID_GCLK_VENCL_INT] = &meson8b_gclk_vencl_int.hw,
  768. [CLKID_VCLK2_VENCLMCC] = &meson8b_vclk2_venclmcc.hw,
  769. [CLKID_VCLK2_VENCL] = &meson8b_vclk2_vencl.hw,
  770. [CLKID_VCLK2_OTHER] = &meson8b_vclk2_other.hw,
  771. [CLKID_EDP] = &meson8b_edp.hw,
  772. [CLKID_AO_MEDIA_CPU] = &meson8b_ao_media_cpu.hw,
  773. [CLKID_AO_AHB_SRAM] = &meson8b_ao_ahb_sram.hw,
  774. [CLKID_AO_AHB_BUS] = &meson8b_ao_ahb_bus.hw,
  775. [CLKID_AO_IFACE] = &meson8b_ao_iface.hw,
  776. [CLKID_MPLL0] = &meson8b_mpll0.hw,
  777. [CLKID_MPLL1] = &meson8b_mpll1.hw,
  778. [CLKID_MPLL2] = &meson8b_mpll2.hw,
  779. [CLKID_MPLL0_DIV] = &meson8b_mpll0_div.hw,
  780. [CLKID_MPLL1_DIV] = &meson8b_mpll1_div.hw,
  781. [CLKID_MPLL2_DIV] = &meson8b_mpll2_div.hw,
  782. [CLKID_CPU_IN_SEL] = &meson8b_cpu_in_sel.hw,
  783. [CLKID_CPU_DIV2] = &meson8b_cpu_div2.hw,
  784. [CLKID_CPU_DIV3] = &meson8b_cpu_div3.hw,
  785. [CLKID_CPU_SCALE_DIV] = &meson8b_cpu_scale_div.hw,
  786. [CLKID_CPU_SCALE_OUT_SEL] = &meson8b_cpu_scale_out_sel.hw,
  787. [CLKID_MPLL_PREDIV] = &meson8b_mpll_prediv.hw,
  788. [CLKID_FCLK_DIV2_DIV] = &meson8b_fclk_div2_div.hw,
  789. [CLKID_FCLK_DIV3_DIV] = &meson8b_fclk_div3_div.hw,
  790. [CLKID_FCLK_DIV4_DIV] = &meson8b_fclk_div4_div.hw,
  791. [CLKID_FCLK_DIV5_DIV] = &meson8b_fclk_div5_div.hw,
  792. [CLKID_FCLK_DIV7_DIV] = &meson8b_fclk_div7_div.hw,
  793. [CLK_NR_CLKS] = NULL,
  794. },
  795. .num = CLK_NR_CLKS,
  796. };
  797. static struct clk_regmap *const meson8b_clk_regmaps[] = {
  798. &meson8b_clk81,
  799. &meson8b_ddr,
  800. &meson8b_dos,
  801. &meson8b_isa,
  802. &meson8b_pl301,
  803. &meson8b_periphs,
  804. &meson8b_spicc,
  805. &meson8b_i2c,
  806. &meson8b_sar_adc,
  807. &meson8b_smart_card,
  808. &meson8b_rng0,
  809. &meson8b_uart0,
  810. &meson8b_sdhc,
  811. &meson8b_stream,
  812. &meson8b_async_fifo,
  813. &meson8b_sdio,
  814. &meson8b_abuf,
  815. &meson8b_hiu_iface,
  816. &meson8b_assist_misc,
  817. &meson8b_spi,
  818. &meson8b_i2s_spdif,
  819. &meson8b_eth,
  820. &meson8b_demux,
  821. &meson8b_aiu_glue,
  822. &meson8b_iec958,
  823. &meson8b_i2s_out,
  824. &meson8b_amclk,
  825. &meson8b_aififo2,
  826. &meson8b_mixer,
  827. &meson8b_mixer_iface,
  828. &meson8b_adc,
  829. &meson8b_blkmv,
  830. &meson8b_aiu,
  831. &meson8b_uart1,
  832. &meson8b_g2d,
  833. &meson8b_usb0,
  834. &meson8b_usb1,
  835. &meson8b_reset,
  836. &meson8b_nand,
  837. &meson8b_dos_parser,
  838. &meson8b_usb,
  839. &meson8b_vdin1,
  840. &meson8b_ahb_arb0,
  841. &meson8b_efuse,
  842. &meson8b_boot_rom,
  843. &meson8b_ahb_data_bus,
  844. &meson8b_ahb_ctrl_bus,
  845. &meson8b_hdmi_intr_sync,
  846. &meson8b_hdmi_pclk,
  847. &meson8b_usb1_ddr_bridge,
  848. &meson8b_usb0_ddr_bridge,
  849. &meson8b_mmc_pclk,
  850. &meson8b_dvin,
  851. &meson8b_uart2,
  852. &meson8b_sana,
  853. &meson8b_vpu_intr,
  854. &meson8b_sec_ahb_ahb3_bridge,
  855. &meson8b_clk81_a9,
  856. &meson8b_vclk2_venci0,
  857. &meson8b_vclk2_venci1,
  858. &meson8b_vclk2_vencp0,
  859. &meson8b_vclk2_vencp1,
  860. &meson8b_gclk_venci_int,
  861. &meson8b_gclk_vencp_int,
  862. &meson8b_dac_clk,
  863. &meson8b_aoclk_gate,
  864. &meson8b_iec958_gate,
  865. &meson8b_enc480p,
  866. &meson8b_rng1,
  867. &meson8b_gclk_vencl_int,
  868. &meson8b_vclk2_venclmcc,
  869. &meson8b_vclk2_vencl,
  870. &meson8b_vclk2_other,
  871. &meson8b_edp,
  872. &meson8b_ao_media_cpu,
  873. &meson8b_ao_ahb_sram,
  874. &meson8b_ao_ahb_bus,
  875. &meson8b_ao_iface,
  876. &meson8b_mpeg_clk_div,
  877. &meson8b_mpeg_clk_sel,
  878. &meson8b_mpll0,
  879. &meson8b_mpll1,
  880. &meson8b_mpll2,
  881. &meson8b_mpll0_div,
  882. &meson8b_mpll1_div,
  883. &meson8b_mpll2_div,
  884. &meson8b_fixed_pll,
  885. &meson8b_vid_pll,
  886. &meson8b_sys_pll,
  887. &meson8b_cpu_in_sel,
  888. &meson8b_cpu_scale_div,
  889. &meson8b_cpu_scale_out_sel,
  890. &meson8b_cpu_clk,
  891. &meson8b_mpll_prediv,
  892. &meson8b_fclk_div2,
  893. &meson8b_fclk_div3,
  894. &meson8b_fclk_div4,
  895. &meson8b_fclk_div5,
  896. &meson8b_fclk_div7,
  897. };
  898. static const struct meson8b_clk_reset_line {
  899. u32 reg;
  900. u8 bit_idx;
  901. } meson8b_clk_reset_bits[] = {
  902. [CLKC_RESET_L2_CACHE_SOFT_RESET] = {
  903. .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 30
  904. },
  905. [CLKC_RESET_AXI_64_TO_128_BRIDGE_A5_SOFT_RESET] = {
  906. .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 29
  907. },
  908. [CLKC_RESET_SCU_SOFT_RESET] = {
  909. .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 28
  910. },
  911. [CLKC_RESET_CPU3_SOFT_RESET] = {
  912. .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 27
  913. },
  914. [CLKC_RESET_CPU2_SOFT_RESET] = {
  915. .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 26
  916. },
  917. [CLKC_RESET_CPU1_SOFT_RESET] = {
  918. .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 25
  919. },
  920. [CLKC_RESET_CPU0_SOFT_RESET] = {
  921. .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 24
  922. },
  923. [CLKC_RESET_A5_GLOBAL_RESET] = {
  924. .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 18
  925. },
  926. [CLKC_RESET_A5_AXI_SOFT_RESET] = {
  927. .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 17
  928. },
  929. [CLKC_RESET_A5_ABP_SOFT_RESET] = {
  930. .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 16
  931. },
  932. [CLKC_RESET_AXI_64_TO_128_BRIDGE_MMC_SOFT_RESET] = {
  933. .reg = HHI_SYS_CPU_CLK_CNTL1, .bit_idx = 30
  934. },
  935. [CLKC_RESET_VID_CLK_CNTL_SOFT_RESET] = {
  936. .reg = HHI_VID_CLK_CNTL, .bit_idx = 15
  937. },
  938. [CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_POST] = {
  939. .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 7
  940. },
  941. [CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_PRE] = {
  942. .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 3
  943. },
  944. [CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_POST] = {
  945. .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 1
  946. },
  947. [CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_PRE] = {
  948. .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 0
  949. },
  950. };
  951. static int meson8b_clk_reset_update(struct reset_controller_dev *rcdev,
  952. unsigned long id, bool assert)
  953. {
  954. struct meson8b_clk_reset *meson8b_clk_reset =
  955. container_of(rcdev, struct meson8b_clk_reset, reset);
  956. unsigned long flags;
  957. const struct meson8b_clk_reset_line *reset;
  958. u32 val;
  959. if (id >= ARRAY_SIZE(meson8b_clk_reset_bits))
  960. return -EINVAL;
  961. reset = &meson8b_clk_reset_bits[id];
  962. spin_lock_irqsave(&meson_clk_lock, flags);
  963. val = readl(meson8b_clk_reset->base + reset->reg);
  964. if (assert)
  965. val |= BIT(reset->bit_idx);
  966. else
  967. val &= ~BIT(reset->bit_idx);
  968. writel(val, meson8b_clk_reset->base + reset->reg);
  969. spin_unlock_irqrestore(&meson_clk_lock, flags);
  970. return 0;
  971. }
  972. static int meson8b_clk_reset_assert(struct reset_controller_dev *rcdev,
  973. unsigned long id)
  974. {
  975. return meson8b_clk_reset_update(rcdev, id, true);
  976. }
  977. static int meson8b_clk_reset_deassert(struct reset_controller_dev *rcdev,
  978. unsigned long id)
  979. {
  980. return meson8b_clk_reset_update(rcdev, id, false);
  981. }
  982. static const struct reset_control_ops meson8b_clk_reset_ops = {
  983. .assert = meson8b_clk_reset_assert,
  984. .deassert = meson8b_clk_reset_deassert,
  985. };
  986. static const struct regmap_config clkc_regmap_config = {
  987. .reg_bits = 32,
  988. .val_bits = 32,
  989. .reg_stride = 4,
  990. };
  991. static int meson8b_clkc_probe(struct platform_device *pdev)
  992. {
  993. int ret, i;
  994. struct device *dev = &pdev->dev;
  995. struct regmap *map;
  996. if (!clk_base)
  997. return -ENXIO;
  998. map = devm_regmap_init_mmio(dev, clk_base, &clkc_regmap_config);
  999. if (IS_ERR(map))
  1000. return PTR_ERR(map);
  1001. /* Populate regmap for the regmap backed clocks */
  1002. for (i = 0; i < ARRAY_SIZE(meson8b_clk_regmaps); i++)
  1003. meson8b_clk_regmaps[i]->map = map;
  1004. /*
  1005. * register all clks
  1006. * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
  1007. */
  1008. for (i = CLKID_XTAL; i < CLK_NR_CLKS; i++) {
  1009. /* array might be sparse */
  1010. if (!meson8b_hw_onecell_data.hws[i])
  1011. continue;
  1012. ret = devm_clk_hw_register(dev, meson8b_hw_onecell_data.hws[i]);
  1013. if (ret)
  1014. return ret;
  1015. }
  1016. return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
  1017. &meson8b_hw_onecell_data);
  1018. }
  1019. static const struct of_device_id meson8b_clkc_match_table[] = {
  1020. { .compatible = "amlogic,meson8-clkc" },
  1021. { .compatible = "amlogic,meson8b-clkc" },
  1022. { .compatible = "amlogic,meson8m2-clkc" },
  1023. { }
  1024. };
  1025. static struct platform_driver meson8b_driver = {
  1026. .probe = meson8b_clkc_probe,
  1027. .driver = {
  1028. .name = "meson8b-clkc",
  1029. .of_match_table = meson8b_clkc_match_table,
  1030. },
  1031. };
  1032. builtin_platform_driver(meson8b_driver);
  1033. static void __init meson8b_clkc_reset_init(struct device_node *np)
  1034. {
  1035. struct meson8b_clk_reset *rstc;
  1036. int ret;
  1037. /* Generic clocks, PLLs and some of the reset-bits */
  1038. clk_base = of_iomap(np, 1);
  1039. if (!clk_base) {
  1040. pr_err("%s: Unable to map clk base\n", __func__);
  1041. return;
  1042. }
  1043. rstc = kzalloc(sizeof(*rstc), GFP_KERNEL);
  1044. if (!rstc)
  1045. return;
  1046. /* Reset Controller */
  1047. rstc->base = clk_base;
  1048. rstc->reset.ops = &meson8b_clk_reset_ops;
  1049. rstc->reset.nr_resets = ARRAY_SIZE(meson8b_clk_reset_bits);
  1050. rstc->reset.of_node = np;
  1051. ret = reset_controller_register(&rstc->reset);
  1052. if (ret) {
  1053. pr_err("%s: Failed to register clkc reset controller: %d\n",
  1054. __func__, ret);
  1055. return;
  1056. }
  1057. }
  1058. CLK_OF_DECLARE_DRIVER(meson8_clkc, "amlogic,meson8-clkc",
  1059. meson8b_clkc_reset_init);
  1060. CLK_OF_DECLARE_DRIVER(meson8b_clkc, "amlogic,meson8b-clkc",
  1061. meson8b_clkc_reset_init);
  1062. CLK_OF_DECLARE_DRIVER(meson8m2_clkc, "amlogic,meson8m2-clkc",
  1063. meson8b_clkc_reset_init);