2
0

omap_clk.c 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267
  1. /*
  2. * OMAP clocks.
  3. *
  4. * Copyright (C) 2006-2008 Andrzej Zaborowski <balrog@zabor.org>
  5. *
  6. * Clocks data comes in part from arch/arm/mach-omap1/clock.h in Linux.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License along
  19. * with this program; if not, see <http://www.gnu.org/licenses/>.
  20. */
  21. #include "qemu/osdep.h"
  22. #include "hw/hw.h"
  23. #include "hw/irq.h"
  24. #include "hw/arm/omap.h"
  25. struct clk {
  26. const char *name;
  27. const char *alias;
  28. struct clk *parent;
  29. struct clk *child1;
  30. struct clk *sibling;
  31. #define ALWAYS_ENABLED (1 << 0)
  32. #define CLOCK_IN_OMAP310 (1 << 10)
  33. #define CLOCK_IN_OMAP730 (1 << 11)
  34. #define CLOCK_IN_OMAP1510 (1 << 12)
  35. #define CLOCK_IN_OMAP16XX (1 << 13)
  36. #define CLOCK_IN_OMAP242X (1 << 14)
  37. #define CLOCK_IN_OMAP243X (1 << 15)
  38. #define CLOCK_IN_OMAP343X (1 << 16)
  39. uint32_t flags;
  40. int id;
  41. int running; /* Is currently ticking */
  42. int enabled; /* Is enabled, regardless of its input clk */
  43. unsigned long rate; /* Current rate (if .running) */
  44. unsigned int divisor; /* Rate relative to input (if .enabled) */
  45. unsigned int multiplier; /* Rate relative to input (if .enabled) */
  46. qemu_irq users[16]; /* Who to notify on change */
  47. int usecount; /* Automatically idle when unused */
  48. };
  49. static struct clk xtal_osc12m = {
  50. .name = "xtal_osc_12m",
  51. .rate = 12000000,
  52. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
  53. };
  54. static struct clk xtal_osc32k = {
  55. .name = "xtal_osc_32k",
  56. .rate = 32768,
  57. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
  58. CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  59. };
  60. static struct clk ck_ref = {
  61. .name = "ck_ref",
  62. .alias = "clkin",
  63. .parent = &xtal_osc12m,
  64. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
  65. ALWAYS_ENABLED,
  66. };
  67. /* If a dpll is disabled it becomes a bypass, child clocks don't stop */
  68. static struct clk dpll1 = {
  69. .name = "dpll1",
  70. .parent = &ck_ref,
  71. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
  72. ALWAYS_ENABLED,
  73. };
  74. static struct clk dpll2 = {
  75. .name = "dpll2",
  76. .parent = &ck_ref,
  77. .flags = CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
  78. };
  79. static struct clk dpll3 = {
  80. .name = "dpll3",
  81. .parent = &ck_ref,
  82. .flags = CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
  83. };
  84. static struct clk dpll4 = {
  85. .name = "dpll4",
  86. .parent = &ck_ref,
  87. .multiplier = 4,
  88. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
  89. };
  90. static struct clk apll = {
  91. .name = "apll",
  92. .parent = &ck_ref,
  93. .multiplier = 48,
  94. .divisor = 12,
  95. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
  96. };
  97. static struct clk ck_48m = {
  98. .name = "ck_48m",
  99. .parent = &dpll4, /* either dpll4 or apll */
  100. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
  101. };
  102. static struct clk ck_dpll1out = {
  103. .name = "ck_dpll1out",
  104. .parent = &dpll1,
  105. .flags = CLOCK_IN_OMAP16XX,
  106. };
  107. static struct clk sossi_ck = {
  108. .name = "ck_sossi",
  109. .parent = &ck_dpll1out,
  110. .flags = CLOCK_IN_OMAP16XX,
  111. };
  112. static struct clk clkm1 = {
  113. .name = "clkm1",
  114. .alias = "ck_gen1",
  115. .parent = &dpll1,
  116. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
  117. ALWAYS_ENABLED,
  118. };
  119. static struct clk clkm2 = {
  120. .name = "clkm2",
  121. .alias = "ck_gen2",
  122. .parent = &dpll1,
  123. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
  124. ALWAYS_ENABLED,
  125. };
  126. static struct clk clkm3 = {
  127. .name = "clkm3",
  128. .alias = "ck_gen3",
  129. .parent = &dpll1, /* either dpll1 or ck_ref */
  130. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
  131. ALWAYS_ENABLED,
  132. };
  133. static struct clk arm_ck = {
  134. .name = "arm_ck",
  135. .alias = "mpu_ck",
  136. .parent = &clkm1,
  137. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
  138. ALWAYS_ENABLED,
  139. };
  140. static struct clk armper_ck = {
  141. .name = "armper_ck",
  142. .alias = "mpuper_ck",
  143. .parent = &clkm1,
  144. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
  145. };
  146. static struct clk arm_gpio_ck = {
  147. .name = "arm_gpio_ck",
  148. .alias = "mpu_gpio_ck",
  149. .parent = &clkm1,
  150. .divisor = 1,
  151. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
  152. };
  153. static struct clk armxor_ck = {
  154. .name = "armxor_ck",
  155. .alias = "mpuxor_ck",
  156. .parent = &ck_ref,
  157. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
  158. };
  159. static struct clk armtim_ck = {
  160. .name = "armtim_ck",
  161. .alias = "mputim_ck",
  162. .parent = &ck_ref, /* either CLKIN or DPLL1 */
  163. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
  164. };
  165. static struct clk armwdt_ck = {
  166. .name = "armwdt_ck",
  167. .alias = "mpuwd_ck",
  168. .parent = &clkm1,
  169. .divisor = 14,
  170. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
  171. ALWAYS_ENABLED,
  172. };
  173. static struct clk arminth_ck16xx = {
  174. .name = "arminth_ck",
  175. .parent = &arm_ck,
  176. .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
  177. /* Note: On 16xx the frequency can be divided by 2 by programming
  178. * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1
  179. *
  180. * 1510 version is in TC clocks.
  181. */
  182. };
  183. static struct clk dsp_ck = {
  184. .name = "dsp_ck",
  185. .parent = &clkm2,
  186. .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
  187. };
  188. static struct clk dspmmu_ck = {
  189. .name = "dspmmu_ck",
  190. .parent = &clkm2,
  191. .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
  192. ALWAYS_ENABLED,
  193. };
  194. static struct clk dspper_ck = {
  195. .name = "dspper_ck",
  196. .parent = &clkm2,
  197. .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
  198. };
  199. static struct clk dspxor_ck = {
  200. .name = "dspxor_ck",
  201. .parent = &ck_ref,
  202. .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
  203. };
  204. static struct clk dsptim_ck = {
  205. .name = "dsptim_ck",
  206. .parent = &ck_ref,
  207. .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
  208. };
  209. static struct clk tc_ck = {
  210. .name = "tc_ck",
  211. .parent = &clkm3,
  212. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
  213. CLOCK_IN_OMAP730 | CLOCK_IN_OMAP310 |
  214. ALWAYS_ENABLED,
  215. };
  216. static struct clk arminth_ck15xx = {
  217. .name = "arminth_ck",
  218. .parent = &tc_ck,
  219. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
  220. /* Note: On 1510 the frequency follows TC_CK
  221. *
  222. * 16xx version is in MPU clocks.
  223. */
  224. };
  225. static struct clk tipb_ck = {
  226. /* No-idle controlled by "tc_ck" */
  227. .name = "tipb_ck",
  228. .parent = &tc_ck,
  229. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
  230. };
  231. static struct clk l3_ocpi_ck = {
  232. /* No-idle controlled by "tc_ck" */
  233. .name = "l3_ocpi_ck",
  234. .parent = &tc_ck,
  235. .flags = CLOCK_IN_OMAP16XX,
  236. };
  237. static struct clk tc1_ck = {
  238. .name = "tc1_ck",
  239. .parent = &tc_ck,
  240. .flags = CLOCK_IN_OMAP16XX,
  241. };
  242. static struct clk tc2_ck = {
  243. .name = "tc2_ck",
  244. .parent = &tc_ck,
  245. .flags = CLOCK_IN_OMAP16XX,
  246. };
  247. static struct clk dma_ck = {
  248. /* No-idle controlled by "tc_ck" */
  249. .name = "dma_ck",
  250. .parent = &tc_ck,
  251. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
  252. ALWAYS_ENABLED,
  253. };
  254. static struct clk dma_lcdfree_ck = {
  255. .name = "dma_lcdfree_ck",
  256. .parent = &tc_ck,
  257. .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
  258. };
  259. static struct clk api_ck = {
  260. .name = "api_ck",
  261. .alias = "mpui_ck",
  262. .parent = &tc_ck,
  263. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
  264. };
  265. static struct clk lb_ck = {
  266. .name = "lb_ck",
  267. .parent = &tc_ck,
  268. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
  269. };
  270. static struct clk lbfree_ck = {
  271. .name = "lbfree_ck",
  272. .parent = &tc_ck,
  273. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
  274. };
  275. static struct clk hsab_ck = {
  276. .name = "hsab_ck",
  277. .parent = &tc_ck,
  278. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
  279. };
  280. static struct clk rhea1_ck = {
  281. .name = "rhea1_ck",
  282. .parent = &tc_ck,
  283. .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
  284. };
  285. static struct clk rhea2_ck = {
  286. .name = "rhea2_ck",
  287. .parent = &tc_ck,
  288. .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
  289. };
  290. static struct clk lcd_ck_16xx = {
  291. .name = "lcd_ck",
  292. .parent = &clkm3,
  293. .flags = CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730,
  294. };
  295. static struct clk lcd_ck_1510 = {
  296. .name = "lcd_ck",
  297. .parent = &clkm3,
  298. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
  299. };
  300. static struct clk uart1_1510 = {
  301. .name = "uart1_ck",
  302. /* Direct from ULPD, no real parent */
  303. .parent = &armper_ck, /* either armper_ck or dpll4 */
  304. .rate = 12000000,
  305. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
  306. };
  307. static struct clk uart1_16xx = {
  308. .name = "uart1_ck",
  309. /* Direct from ULPD, no real parent */
  310. .parent = &armper_ck,
  311. .rate = 48000000,
  312. .flags = CLOCK_IN_OMAP16XX,
  313. };
  314. static struct clk uart2_ck = {
  315. .name = "uart2_ck",
  316. /* Direct from ULPD, no real parent */
  317. .parent = &armper_ck, /* either armper_ck or dpll4 */
  318. .rate = 12000000,
  319. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
  320. ALWAYS_ENABLED,
  321. };
  322. static struct clk uart3_1510 = {
  323. .name = "uart3_ck",
  324. /* Direct from ULPD, no real parent */
  325. .parent = &armper_ck, /* either armper_ck or dpll4 */
  326. .rate = 12000000,
  327. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
  328. };
  329. static struct clk uart3_16xx = {
  330. .name = "uart3_ck",
  331. /* Direct from ULPD, no real parent */
  332. .parent = &armper_ck,
  333. .rate = 48000000,
  334. .flags = CLOCK_IN_OMAP16XX,
  335. };
  336. static struct clk usb_clk0 = { /* 6 MHz output on W4_USB_CLK0 */
  337. .name = "usb_clk0",
  338. .alias = "usb.clko",
  339. /* Direct from ULPD, no parent */
  340. .rate = 6000000,
  341. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
  342. };
  343. static struct clk usb_hhc_ck1510 = {
  344. .name = "usb_hhc_ck",
  345. /* Direct from ULPD, no parent */
  346. .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
  347. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
  348. };
  349. static struct clk usb_hhc_ck16xx = {
  350. .name = "usb_hhc_ck",
  351. /* Direct from ULPD, no parent */
  352. .rate = 48000000,
  353. /* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
  354. .flags = CLOCK_IN_OMAP16XX,
  355. };
  356. static struct clk usb_w2fc_mclk = {
  357. .name = "usb_w2fc_mclk",
  358. .alias = "usb_w2fc_ck",
  359. .parent = &ck_48m,
  360. .rate = 48000000,
  361. .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
  362. };
  363. static struct clk mclk_1510 = {
  364. .name = "mclk",
  365. /* Direct from ULPD, no parent. May be enabled by ext hardware. */
  366. .rate = 12000000,
  367. .flags = CLOCK_IN_OMAP1510,
  368. };
  369. static struct clk bclk_310 = {
  370. .name = "bt_mclk_out", /* Alias midi_mclk_out? */
  371. .parent = &armper_ck,
  372. .flags = CLOCK_IN_OMAP310,
  373. };
  374. static struct clk mclk_310 = {
  375. .name = "com_mclk_out",
  376. .parent = &armper_ck,
  377. .flags = CLOCK_IN_OMAP310,
  378. };
  379. static struct clk mclk_16xx = {
  380. .name = "mclk",
  381. /* Direct from ULPD, no parent. May be enabled by ext hardware. */
  382. .flags = CLOCK_IN_OMAP16XX,
  383. };
  384. static struct clk bclk_1510 = {
  385. .name = "bclk",
  386. /* Direct from ULPD, no parent. May be enabled by ext hardware. */
  387. .rate = 12000000,
  388. .flags = CLOCK_IN_OMAP1510,
  389. };
  390. static struct clk bclk_16xx = {
  391. .name = "bclk",
  392. /* Direct from ULPD, no parent. May be enabled by ext hardware. */
  393. .flags = CLOCK_IN_OMAP16XX,
  394. };
  395. static struct clk mmc1_ck = {
  396. .name = "mmc_ck",
  397. .id = 1,
  398. /* Functional clock is direct from ULPD, interface clock is ARMPER */
  399. .parent = &armper_ck, /* either armper_ck or dpll4 */
  400. .rate = 48000000,
  401. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
  402. };
  403. static struct clk mmc2_ck = {
  404. .name = "mmc_ck",
  405. .id = 2,
  406. /* Functional clock is direct from ULPD, interface clock is ARMPER */
  407. .parent = &armper_ck,
  408. .rate = 48000000,
  409. .flags = CLOCK_IN_OMAP16XX,
  410. };
  411. static struct clk cam_mclk = {
  412. .name = "cam.mclk",
  413. .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
  414. .rate = 12000000,
  415. };
  416. static struct clk cam_exclk = {
  417. .name = "cam.exclk",
  418. .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
  419. /* Either 12M from cam.mclk or 48M from dpll4 */
  420. .parent = &cam_mclk,
  421. };
  422. static struct clk cam_lclk = {
  423. .name = "cam.lclk",
  424. .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
  425. };
  426. static struct clk i2c_fck = {
  427. .name = "i2c_fck",
  428. .id = 1,
  429. .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
  430. ALWAYS_ENABLED,
  431. .parent = &armxor_ck,
  432. };
  433. static struct clk i2c_ick = {
  434. .name = "i2c_ick",
  435. .id = 1,
  436. .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
  437. .parent = &armper_ck,
  438. };
  439. static struct clk clk32k = {
  440. .name = "clk32-kHz",
  441. .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
  442. CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
  443. .parent = &xtal_osc32k,
  444. };
  445. static struct clk ref_clk = {
  446. .name = "ref_clk",
  447. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
  448. .rate = 12000000, /* 12 MHz or 13 MHz or 19.2 MHz */
  449. /*.parent = sys.xtalin */
  450. };
  451. static struct clk apll_96m = {
  452. .name = "apll_96m",
  453. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
  454. .rate = 96000000,
  455. /*.parent = ref_clk */
  456. };
  457. static struct clk apll_54m = {
  458. .name = "apll_54m",
  459. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
  460. .rate = 54000000,
  461. /*.parent = ref_clk */
  462. };
  463. static struct clk sys_clk = {
  464. .name = "sys_clk",
  465. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
  466. .rate = 32768,
  467. /*.parent = sys.xtalin */
  468. };
  469. static struct clk sleep_clk = {
  470. .name = "sleep_clk",
  471. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
  472. .rate = 32768,
  473. /*.parent = sys.xtalin */
  474. };
  475. static struct clk dpll_ck = {
  476. .name = "dpll",
  477. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
  478. .parent = &ref_clk,
  479. };
  480. static struct clk dpll_x2_ck = {
  481. .name = "dpll_x2",
  482. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
  483. .parent = &ref_clk,
  484. };
  485. static struct clk wdt1_sys_clk = {
  486. .name = "wdt1_sys_clk",
  487. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
  488. .rate = 32768,
  489. /*.parent = sys.xtalin */
  490. };
  491. static struct clk func_96m_clk = {
  492. .name = "func_96m_clk",
  493. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  494. .divisor = 1,
  495. .parent = &apll_96m,
  496. };
  497. static struct clk func_48m_clk = {
  498. .name = "func_48m_clk",
  499. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  500. .divisor = 2,
  501. .parent = &apll_96m,
  502. };
  503. static struct clk func_12m_clk = {
  504. .name = "func_12m_clk",
  505. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  506. .divisor = 8,
  507. .parent = &apll_96m,
  508. };
  509. static struct clk func_54m_clk = {
  510. .name = "func_54m_clk",
  511. .flags = CLOCK_IN_OMAP242X,
  512. .divisor = 1,
  513. .parent = &apll_54m,
  514. };
  515. static struct clk sys_clkout = {
  516. .name = "clkout",
  517. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  518. .parent = &sys_clk,
  519. };
  520. static struct clk sys_clkout2 = {
  521. .name = "clkout2",
  522. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  523. .parent = &sys_clk,
  524. };
  525. static struct clk core_clk = {
  526. .name = "core_clk",
  527. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  528. .parent = &dpll_x2_ck, /* Switchable between dpll_ck and clk32k */
  529. };
  530. static struct clk l3_clk = {
  531. .name = "l3_clk",
  532. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  533. .parent = &core_clk,
  534. };
  535. static struct clk core_l4_iclk = {
  536. .name = "core_l4_iclk",
  537. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  538. .parent = &l3_clk,
  539. };
  540. static struct clk wu_l4_iclk = {
  541. .name = "wu_l4_iclk",
  542. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  543. .parent = &l3_clk,
  544. };
  545. static struct clk core_l3_iclk = {
  546. .name = "core_l3_iclk",
  547. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  548. .parent = &core_clk,
  549. };
  550. static struct clk core_l4_usb_clk = {
  551. .name = "core_l4_usb_clk",
  552. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  553. .parent = &l3_clk,
  554. };
  555. static struct clk wu_gpt1_clk = {
  556. .name = "wu_gpt1_clk",
  557. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  558. .parent = &sys_clk,
  559. };
  560. static struct clk wu_32k_clk = {
  561. .name = "wu_32k_clk",
  562. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  563. .parent = &sys_clk,
  564. };
  565. static struct clk uart1_fclk = {
  566. .name = "uart1_fclk",
  567. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  568. .parent = &func_48m_clk,
  569. };
  570. static struct clk uart1_iclk = {
  571. .name = "uart1_iclk",
  572. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  573. .parent = &core_l4_iclk,
  574. };
  575. static struct clk uart2_fclk = {
  576. .name = "uart2_fclk",
  577. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  578. .parent = &func_48m_clk,
  579. };
  580. static struct clk uart2_iclk = {
  581. .name = "uart2_iclk",
  582. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  583. .parent = &core_l4_iclk,
  584. };
  585. static struct clk uart3_fclk = {
  586. .name = "uart3_fclk",
  587. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  588. .parent = &func_48m_clk,
  589. };
  590. static struct clk uart3_iclk = {
  591. .name = "uart3_iclk",
  592. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  593. .parent = &core_l4_iclk,
  594. };
  595. static struct clk mpu_fclk = {
  596. .name = "mpu_fclk",
  597. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  598. .parent = &core_clk,
  599. };
  600. static struct clk mpu_iclk = {
  601. .name = "mpu_iclk",
  602. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  603. .parent = &core_clk,
  604. };
  605. static struct clk int_m_fclk = {
  606. .name = "int_m_fclk",
  607. .alias = "mpu_intc_fclk",
  608. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  609. .parent = &core_clk,
  610. };
  611. static struct clk int_m_iclk = {
  612. .name = "int_m_iclk",
  613. .alias = "mpu_intc_iclk",
  614. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  615. .parent = &core_clk,
  616. };
  617. static struct clk core_gpt2_clk = {
  618. .name = "core_gpt2_clk",
  619. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  620. .parent = &sys_clk,
  621. };
  622. static struct clk core_gpt3_clk = {
  623. .name = "core_gpt3_clk",
  624. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  625. .parent = &sys_clk,
  626. };
  627. static struct clk core_gpt4_clk = {
  628. .name = "core_gpt4_clk",
  629. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  630. .parent = &sys_clk,
  631. };
  632. static struct clk core_gpt5_clk = {
  633. .name = "core_gpt5_clk",
  634. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  635. .parent = &sys_clk,
  636. };
  637. static struct clk core_gpt6_clk = {
  638. .name = "core_gpt6_clk",
  639. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  640. .parent = &sys_clk,
  641. };
  642. static struct clk core_gpt7_clk = {
  643. .name = "core_gpt7_clk",
  644. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  645. .parent = &sys_clk,
  646. };
  647. static struct clk core_gpt8_clk = {
  648. .name = "core_gpt8_clk",
  649. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  650. .parent = &sys_clk,
  651. };
  652. static struct clk core_gpt9_clk = {
  653. .name = "core_gpt9_clk",
  654. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  655. .parent = &sys_clk,
  656. };
  657. static struct clk core_gpt10_clk = {
  658. .name = "core_gpt10_clk",
  659. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  660. .parent = &sys_clk,
  661. };
  662. static struct clk core_gpt11_clk = {
  663. .name = "core_gpt11_clk",
  664. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  665. .parent = &sys_clk,
  666. };
  667. static struct clk core_gpt12_clk = {
  668. .name = "core_gpt12_clk",
  669. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  670. .parent = &sys_clk,
  671. };
  672. static struct clk mcbsp1_clk = {
  673. .name = "mcbsp1_cg",
  674. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  675. .divisor = 2,
  676. .parent = &func_96m_clk,
  677. };
  678. static struct clk mcbsp2_clk = {
  679. .name = "mcbsp2_cg",
  680. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  681. .divisor = 2,
  682. .parent = &func_96m_clk,
  683. };
  684. static struct clk emul_clk = {
  685. .name = "emul_ck",
  686. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  687. .parent = &func_54m_clk,
  688. };
  689. static struct clk sdma_fclk = {
  690. .name = "sdma_fclk",
  691. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  692. .parent = &l3_clk,
  693. };
  694. static struct clk sdma_iclk = {
  695. .name = "sdma_iclk",
  696. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  697. .parent = &core_l3_iclk, /* core_l4_iclk for the configuration port */
  698. };
  699. static struct clk i2c1_fclk = {
  700. .name = "i2c1.fclk",
  701. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  702. .parent = &func_12m_clk,
  703. .divisor = 1,
  704. };
  705. static struct clk i2c1_iclk = {
  706. .name = "i2c1.iclk",
  707. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  708. .parent = &core_l4_iclk,
  709. };
  710. static struct clk i2c2_fclk = {
  711. .name = "i2c2.fclk",
  712. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  713. .parent = &func_12m_clk,
  714. .divisor = 1,
  715. };
  716. static struct clk i2c2_iclk = {
  717. .name = "i2c2.iclk",
  718. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  719. .parent = &core_l4_iclk,
  720. };
  721. static struct clk gpio_dbclk[5] = {
  722. {
  723. .name = "gpio1_dbclk",
  724. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  725. .parent = &wu_32k_clk,
  726. }, {
  727. .name = "gpio2_dbclk",
  728. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  729. .parent = &wu_32k_clk,
  730. }, {
  731. .name = "gpio3_dbclk",
  732. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  733. .parent = &wu_32k_clk,
  734. }, {
  735. .name = "gpio4_dbclk",
  736. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  737. .parent = &wu_32k_clk,
  738. }, {
  739. .name = "gpio5_dbclk",
  740. .flags = CLOCK_IN_OMAP243X,
  741. .parent = &wu_32k_clk,
  742. },
  743. };
  744. static struct clk gpio_iclk = {
  745. .name = "gpio_iclk",
  746. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  747. .parent = &wu_l4_iclk,
  748. };
  749. static struct clk mmc_fck = {
  750. .name = "mmc_fclk",
  751. .flags = CLOCK_IN_OMAP242X,
  752. .parent = &func_96m_clk,
  753. };
  754. static struct clk mmc_ick = {
  755. .name = "mmc_iclk",
  756. .flags = CLOCK_IN_OMAP242X,
  757. .parent = &core_l4_iclk,
  758. };
  759. static struct clk spi_fclk[3] = {
  760. {
  761. .name = "spi1_fclk",
  762. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  763. .parent = &func_48m_clk,
  764. }, {
  765. .name = "spi2_fclk",
  766. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  767. .parent = &func_48m_clk,
  768. }, {
  769. .name = "spi3_fclk",
  770. .flags = CLOCK_IN_OMAP243X,
  771. .parent = &func_48m_clk,
  772. },
  773. };
  774. static struct clk dss_clk[2] = {
  775. {
  776. .name = "dss_clk1",
  777. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  778. .parent = &core_clk,
  779. }, {
  780. .name = "dss_clk2",
  781. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  782. .parent = &sys_clk,
  783. },
  784. };
  785. static struct clk dss_54m_clk = {
  786. .name = "dss_54m_clk",
  787. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  788. .parent = &func_54m_clk,
  789. };
  790. static struct clk dss_l3_iclk = {
  791. .name = "dss_l3_iclk",
  792. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  793. .parent = &core_l3_iclk,
  794. };
  795. static struct clk dss_l4_iclk = {
  796. .name = "dss_l4_iclk",
  797. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  798. .parent = &core_l4_iclk,
  799. };
  800. static struct clk spi_iclk[3] = {
  801. {
  802. .name = "spi1_iclk",
  803. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  804. .parent = &core_l4_iclk,
  805. }, {
  806. .name = "spi2_iclk",
  807. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  808. .parent = &core_l4_iclk,
  809. }, {
  810. .name = "spi3_iclk",
  811. .flags = CLOCK_IN_OMAP243X,
  812. .parent = &core_l4_iclk,
  813. },
  814. };
  815. static struct clk omapctrl_clk = {
  816. .name = "omapctrl_iclk",
  817. .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  818. /* XXX Should be in WKUP domain */
  819. .parent = &core_l4_iclk,
  820. };
  821. static struct clk *onchip_clks[] = {
  822. /* OMAP 1 */
  823. /* non-ULPD clocks */
  824. &xtal_osc12m,
  825. &xtal_osc32k,
  826. &ck_ref,
  827. &dpll1,
  828. &dpll2,
  829. &dpll3,
  830. &dpll4,
  831. &apll,
  832. &ck_48m,
  833. /* CK_GEN1 clocks */
  834. &clkm1,
  835. &ck_dpll1out,
  836. &sossi_ck,
  837. &arm_ck,
  838. &armper_ck,
  839. &arm_gpio_ck,
  840. &armxor_ck,
  841. &armtim_ck,
  842. &armwdt_ck,
  843. &arminth_ck15xx, &arminth_ck16xx,
  844. /* CK_GEN2 clocks */
  845. &clkm2,
  846. &dsp_ck,
  847. &dspmmu_ck,
  848. &dspper_ck,
  849. &dspxor_ck,
  850. &dsptim_ck,
  851. /* CK_GEN3 clocks */
  852. &clkm3,
  853. &tc_ck,
  854. &tipb_ck,
  855. &l3_ocpi_ck,
  856. &tc1_ck,
  857. &tc2_ck,
  858. &dma_ck,
  859. &dma_lcdfree_ck,
  860. &api_ck,
  861. &lb_ck,
  862. &lbfree_ck,
  863. &hsab_ck,
  864. &rhea1_ck,
  865. &rhea2_ck,
  866. &lcd_ck_16xx,
  867. &lcd_ck_1510,
  868. /* ULPD clocks */
  869. &uart1_1510,
  870. &uart1_16xx,
  871. &uart2_ck,
  872. &uart3_1510,
  873. &uart3_16xx,
  874. &usb_clk0,
  875. &usb_hhc_ck1510, &usb_hhc_ck16xx,
  876. &mclk_1510, &mclk_16xx, &mclk_310,
  877. &bclk_1510, &bclk_16xx, &bclk_310,
  878. &mmc1_ck,
  879. &mmc2_ck,
  880. &cam_mclk,
  881. &cam_exclk,
  882. &cam_lclk,
  883. &clk32k,
  884. &usb_w2fc_mclk,
  885. /* Virtual clocks */
  886. &i2c_fck,
  887. &i2c_ick,
  888. /* OMAP 2 */
  889. &ref_clk,
  890. &apll_96m,
  891. &apll_54m,
  892. &sys_clk,
  893. &sleep_clk,
  894. &dpll_ck,
  895. &dpll_x2_ck,
  896. &wdt1_sys_clk,
  897. &func_96m_clk,
  898. &func_48m_clk,
  899. &func_12m_clk,
  900. &func_54m_clk,
  901. &sys_clkout,
  902. &sys_clkout2,
  903. &core_clk,
  904. &l3_clk,
  905. &core_l4_iclk,
  906. &wu_l4_iclk,
  907. &core_l3_iclk,
  908. &core_l4_usb_clk,
  909. &wu_gpt1_clk,
  910. &wu_32k_clk,
  911. &uart1_fclk,
  912. &uart1_iclk,
  913. &uart2_fclk,
  914. &uart2_iclk,
  915. &uart3_fclk,
  916. &uart3_iclk,
  917. &mpu_fclk,
  918. &mpu_iclk,
  919. &int_m_fclk,
  920. &int_m_iclk,
  921. &core_gpt2_clk,
  922. &core_gpt3_clk,
  923. &core_gpt4_clk,
  924. &core_gpt5_clk,
  925. &core_gpt6_clk,
  926. &core_gpt7_clk,
  927. &core_gpt8_clk,
  928. &core_gpt9_clk,
  929. &core_gpt10_clk,
  930. &core_gpt11_clk,
  931. &core_gpt12_clk,
  932. &mcbsp1_clk,
  933. &mcbsp2_clk,
  934. &emul_clk,
  935. &sdma_fclk,
  936. &sdma_iclk,
  937. &i2c1_fclk,
  938. &i2c1_iclk,
  939. &i2c2_fclk,
  940. &i2c2_iclk,
  941. &gpio_dbclk[0],
  942. &gpio_dbclk[1],
  943. &gpio_dbclk[2],
  944. &gpio_dbclk[3],
  945. &gpio_iclk,
  946. &mmc_fck,
  947. &mmc_ick,
  948. &spi_fclk[0],
  949. &spi_iclk[0],
  950. &spi_fclk[1],
  951. &spi_iclk[1],
  952. &spi_fclk[2],
  953. &spi_iclk[2],
  954. &dss_clk[0],
  955. &dss_clk[1],
  956. &dss_54m_clk,
  957. &dss_l3_iclk,
  958. &dss_l4_iclk,
  959. &omapctrl_clk,
  960. NULL
  961. };
  962. void omap_clk_adduser(struct clk *clk, qemu_irq user)
  963. {
  964. qemu_irq *i;
  965. for (i = clk->users; *i; i ++);
  966. *i = user;
  967. }
  968. struct clk *omap_findclk(struct omap_mpu_state_s *mpu, const char *name)
  969. {
  970. struct clk *i;
  971. for (i = mpu->clks; i->name; i ++)
  972. if (!strcmp(i->name, name) || (i->alias && !strcmp(i->alias, name)))
  973. return i;
  974. hw_error("%s: %s not found\n", __func__, name);
  975. }
  976. void omap_clk_get(struct clk *clk)
  977. {
  978. clk->usecount ++;
  979. }
  980. void omap_clk_put(struct clk *clk)
  981. {
  982. if (!(clk->usecount --))
  983. hw_error("%s: %s is not in use\n", __func__, clk->name);
  984. }
  985. static void omap_clk_update(struct clk *clk)
  986. {
  987. int parent, running;
  988. qemu_irq *user;
  989. struct clk *i;
  990. if (clk->parent)
  991. parent = clk->parent->running;
  992. else
  993. parent = 1;
  994. running = parent && (clk->enabled ||
  995. ((clk->flags & ALWAYS_ENABLED) && clk->usecount));
  996. if (clk->running != running) {
  997. clk->running = running;
  998. for (user = clk->users; *user; user ++)
  999. qemu_set_irq(*user, running);
  1000. for (i = clk->child1; i; i = i->sibling)
  1001. omap_clk_update(i);
  1002. }
  1003. }
  1004. static void omap_clk_rate_update_full(struct clk *clk, unsigned long int rate,
  1005. unsigned long int div, unsigned long int mult)
  1006. {
  1007. struct clk *i;
  1008. qemu_irq *user;
  1009. clk->rate = muldiv64(rate, mult, div);
  1010. if (clk->running)
  1011. for (user = clk->users; *user; user ++)
  1012. qemu_irq_raise(*user);
  1013. for (i = clk->child1; i; i = i->sibling)
  1014. omap_clk_rate_update_full(i, rate,
  1015. div * i->divisor, mult * i->multiplier);
  1016. }
  1017. static void omap_clk_rate_update(struct clk *clk)
  1018. {
  1019. struct clk *i;
  1020. unsigned long int div, mult = div = 1;
  1021. for (i = clk; i->parent; i = i->parent) {
  1022. div *= i->divisor;
  1023. mult *= i->multiplier;
  1024. }
  1025. omap_clk_rate_update_full(clk, i->rate, div, mult);
  1026. }
  1027. void omap_clk_reparent(struct clk *clk, struct clk *parent)
  1028. {
  1029. struct clk **p;
  1030. if (clk->parent) {
  1031. for (p = &clk->parent->child1; *p != clk; p = &(*p)->sibling);
  1032. *p = clk->sibling;
  1033. }
  1034. clk->parent = parent;
  1035. if (parent) {
  1036. clk->sibling = parent->child1;
  1037. parent->child1 = clk;
  1038. omap_clk_update(clk);
  1039. omap_clk_rate_update(clk);
  1040. } else
  1041. clk->sibling = NULL;
  1042. }
  1043. void omap_clk_onoff(struct clk *clk, int on)
  1044. {
  1045. clk->enabled = on;
  1046. omap_clk_update(clk);
  1047. }
  1048. void omap_clk_canidle(struct clk *clk, int can)
  1049. {
  1050. if (can)
  1051. omap_clk_put(clk);
  1052. else
  1053. omap_clk_get(clk);
  1054. }
  1055. void omap_clk_setrate(struct clk *clk, int divide, int multiply)
  1056. {
  1057. clk->divisor = divide;
  1058. clk->multiplier = multiply;
  1059. omap_clk_rate_update(clk);
  1060. }
  1061. int64_t omap_clk_getrate(omap_clk clk)
  1062. {
  1063. return clk->rate;
  1064. }
  1065. void omap_clk_init(struct omap_mpu_state_s *mpu)
  1066. {
  1067. struct clk **i, *j, *k;
  1068. int count;
  1069. int flag;
  1070. if (cpu_is_omap310(mpu))
  1071. flag = CLOCK_IN_OMAP310;
  1072. else if (cpu_is_omap1510(mpu))
  1073. flag = CLOCK_IN_OMAP1510;
  1074. else if (cpu_is_omap2410(mpu) || cpu_is_omap2420(mpu))
  1075. flag = CLOCK_IN_OMAP242X;
  1076. else if (cpu_is_omap2430(mpu))
  1077. flag = CLOCK_IN_OMAP243X;
  1078. else if (cpu_is_omap3430(mpu))
  1079. flag = CLOCK_IN_OMAP243X;
  1080. else
  1081. return;
  1082. for (i = onchip_clks, count = 0; *i; i ++)
  1083. if ((*i)->flags & flag)
  1084. count ++;
  1085. mpu->clks = g_new0(struct clk, count + 1);
  1086. for (i = onchip_clks, j = mpu->clks; *i; i ++)
  1087. if ((*i)->flags & flag) {
  1088. memcpy(j, *i, sizeof(struct clk));
  1089. for (k = mpu->clks; k < j; k ++)
  1090. if (j->parent && !strcmp(j->parent->name, k->name)) {
  1091. j->parent = k;
  1092. j->sibling = k->child1;
  1093. k->child1 = j;
  1094. } else if (k->parent && !strcmp(k->parent->name, j->name)) {
  1095. k->parent = j;
  1096. k->sibling = j->child1;
  1097. j->child1 = k;
  1098. }
  1099. j->divisor = j->divisor ?: 1;
  1100. j->multiplier = j->multiplier ?: 1;
  1101. j ++;
  1102. }
  1103. for (j = mpu->clks; count --; j ++) {
  1104. omap_clk_update(j);
  1105. omap_clk_rate_update(j);
  1106. }
  1107. }