omap_clk.c 31 KB

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