omap_clk.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744
  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. uint32_t flags;
  37. int id;
  38. int running; /* Is currently ticking */
  39. int enabled; /* Is enabled, regardless of its input clk */
  40. unsigned long rate; /* Current rate (if .running) */
  41. unsigned int divisor; /* Rate relative to input (if .enabled) */
  42. unsigned int multiplier; /* Rate relative to input (if .enabled) */
  43. qemu_irq users[16]; /* Who to notify on change */
  44. int usecount; /* Automatically idle when unused */
  45. };
  46. static struct clk xtal_osc12m = {
  47. .name = "xtal_osc_12m",
  48. .rate = 12000000,
  49. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
  50. };
  51. static struct clk xtal_osc32k = {
  52. .name = "xtal_osc_32k",
  53. .rate = 32768,
  54. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
  55. };
  56. static struct clk ck_ref = {
  57. .name = "ck_ref",
  58. .alias = "clkin",
  59. .parent = &xtal_osc12m,
  60. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
  61. ALWAYS_ENABLED,
  62. };
  63. /* If a dpll is disabled it becomes a bypass, child clocks don't stop */
  64. static struct clk dpll1 = {
  65. .name = "dpll1",
  66. .parent = &ck_ref,
  67. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
  68. ALWAYS_ENABLED,
  69. };
  70. static struct clk dpll2 = {
  71. .name = "dpll2",
  72. .parent = &ck_ref,
  73. .flags = CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
  74. };
  75. static struct clk dpll3 = {
  76. .name = "dpll3",
  77. .parent = &ck_ref,
  78. .flags = CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
  79. };
  80. static struct clk dpll4 = {
  81. .name = "dpll4",
  82. .parent = &ck_ref,
  83. .multiplier = 4,
  84. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
  85. };
  86. static struct clk apll = {
  87. .name = "apll",
  88. .parent = &ck_ref,
  89. .multiplier = 48,
  90. .divisor = 12,
  91. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
  92. };
  93. static struct clk ck_48m = {
  94. .name = "ck_48m",
  95. .parent = &dpll4, /* either dpll4 or apll */
  96. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
  97. };
  98. static struct clk ck_dpll1out = {
  99. .name = "ck_dpll1out",
  100. .parent = &dpll1,
  101. .flags = CLOCK_IN_OMAP16XX,
  102. };
  103. static struct clk sossi_ck = {
  104. .name = "ck_sossi",
  105. .parent = &ck_dpll1out,
  106. .flags = CLOCK_IN_OMAP16XX,
  107. };
  108. static struct clk clkm1 = {
  109. .name = "clkm1",
  110. .alias = "ck_gen1",
  111. .parent = &dpll1,
  112. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
  113. ALWAYS_ENABLED,
  114. };
  115. static struct clk clkm2 = {
  116. .name = "clkm2",
  117. .alias = "ck_gen2",
  118. .parent = &dpll1,
  119. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
  120. ALWAYS_ENABLED,
  121. };
  122. static struct clk clkm3 = {
  123. .name = "clkm3",
  124. .alias = "ck_gen3",
  125. .parent = &dpll1, /* either dpll1 or ck_ref */
  126. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
  127. ALWAYS_ENABLED,
  128. };
  129. static struct clk arm_ck = {
  130. .name = "arm_ck",
  131. .alias = "mpu_ck",
  132. .parent = &clkm1,
  133. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
  134. ALWAYS_ENABLED,
  135. };
  136. static struct clk armper_ck = {
  137. .name = "armper_ck",
  138. .alias = "mpuper_ck",
  139. .parent = &clkm1,
  140. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
  141. };
  142. static struct clk arm_gpio_ck = {
  143. .name = "arm_gpio_ck",
  144. .alias = "mpu_gpio_ck",
  145. .parent = &clkm1,
  146. .divisor = 1,
  147. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
  148. };
  149. static struct clk armxor_ck = {
  150. .name = "armxor_ck",
  151. .alias = "mpuxor_ck",
  152. .parent = &ck_ref,
  153. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
  154. };
  155. static struct clk armtim_ck = {
  156. .name = "armtim_ck",
  157. .alias = "mputim_ck",
  158. .parent = &ck_ref, /* either CLKIN or DPLL1 */
  159. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
  160. };
  161. static struct clk armwdt_ck = {
  162. .name = "armwdt_ck",
  163. .alias = "mpuwd_ck",
  164. .parent = &clkm1,
  165. .divisor = 14,
  166. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
  167. ALWAYS_ENABLED,
  168. };
  169. static struct clk arminth_ck16xx = {
  170. .name = "arminth_ck",
  171. .parent = &arm_ck,
  172. .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
  173. /* Note: On 16xx the frequency can be divided by 2 by programming
  174. * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1
  175. *
  176. * 1510 version is in TC clocks.
  177. */
  178. };
  179. static struct clk dsp_ck = {
  180. .name = "dsp_ck",
  181. .parent = &clkm2,
  182. .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
  183. };
  184. static struct clk dspmmu_ck = {
  185. .name = "dspmmu_ck",
  186. .parent = &clkm2,
  187. .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
  188. ALWAYS_ENABLED,
  189. };
  190. static struct clk dspper_ck = {
  191. .name = "dspper_ck",
  192. .parent = &clkm2,
  193. .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
  194. };
  195. static struct clk dspxor_ck = {
  196. .name = "dspxor_ck",
  197. .parent = &ck_ref,
  198. .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
  199. };
  200. static struct clk dsptim_ck = {
  201. .name = "dsptim_ck",
  202. .parent = &ck_ref,
  203. .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
  204. };
  205. static struct clk tc_ck = {
  206. .name = "tc_ck",
  207. .parent = &clkm3,
  208. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
  209. CLOCK_IN_OMAP730 | CLOCK_IN_OMAP310 |
  210. ALWAYS_ENABLED,
  211. };
  212. static struct clk arminth_ck15xx = {
  213. .name = "arminth_ck",
  214. .parent = &tc_ck,
  215. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
  216. /* Note: On 1510 the frequency follows TC_CK
  217. *
  218. * 16xx version is in MPU clocks.
  219. */
  220. };
  221. static struct clk tipb_ck = {
  222. /* No-idle controlled by "tc_ck" */
  223. .name = "tipb_ck",
  224. .parent = &tc_ck,
  225. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
  226. };
  227. static struct clk l3_ocpi_ck = {
  228. /* No-idle controlled by "tc_ck" */
  229. .name = "l3_ocpi_ck",
  230. .parent = &tc_ck,
  231. .flags = CLOCK_IN_OMAP16XX,
  232. };
  233. static struct clk tc1_ck = {
  234. .name = "tc1_ck",
  235. .parent = &tc_ck,
  236. .flags = CLOCK_IN_OMAP16XX,
  237. };
  238. static struct clk tc2_ck = {
  239. .name = "tc2_ck",
  240. .parent = &tc_ck,
  241. .flags = CLOCK_IN_OMAP16XX,
  242. };
  243. static struct clk dma_ck = {
  244. /* No-idle controlled by "tc_ck" */
  245. .name = "dma_ck",
  246. .parent = &tc_ck,
  247. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
  248. ALWAYS_ENABLED,
  249. };
  250. static struct clk dma_lcdfree_ck = {
  251. .name = "dma_lcdfree_ck",
  252. .parent = &tc_ck,
  253. .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
  254. };
  255. static struct clk api_ck = {
  256. .name = "api_ck",
  257. .alias = "mpui_ck",
  258. .parent = &tc_ck,
  259. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
  260. };
  261. static struct clk lb_ck = {
  262. .name = "lb_ck",
  263. .parent = &tc_ck,
  264. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
  265. };
  266. static struct clk lbfree_ck = {
  267. .name = "lbfree_ck",
  268. .parent = &tc_ck,
  269. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
  270. };
  271. static struct clk hsab_ck = {
  272. .name = "hsab_ck",
  273. .parent = &tc_ck,
  274. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
  275. };
  276. static struct clk rhea1_ck = {
  277. .name = "rhea1_ck",
  278. .parent = &tc_ck,
  279. .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
  280. };
  281. static struct clk rhea2_ck = {
  282. .name = "rhea2_ck",
  283. .parent = &tc_ck,
  284. .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
  285. };
  286. static struct clk lcd_ck_16xx = {
  287. .name = "lcd_ck",
  288. .parent = &clkm3,
  289. .flags = CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730,
  290. };
  291. static struct clk lcd_ck_1510 = {
  292. .name = "lcd_ck",
  293. .parent = &clkm3,
  294. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
  295. };
  296. static struct clk uart1_1510 = {
  297. .name = "uart1_ck",
  298. /* Direct from ULPD, no real parent */
  299. .parent = &armper_ck, /* either armper_ck or dpll4 */
  300. .rate = 12000000,
  301. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
  302. };
  303. static struct clk uart1_16xx = {
  304. .name = "uart1_ck",
  305. /* Direct from ULPD, no real parent */
  306. .parent = &armper_ck,
  307. .rate = 48000000,
  308. .flags = CLOCK_IN_OMAP16XX,
  309. };
  310. static struct clk uart2_ck = {
  311. .name = "uart2_ck",
  312. /* Direct from ULPD, no real parent */
  313. .parent = &armper_ck, /* either armper_ck or dpll4 */
  314. .rate = 12000000,
  315. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
  316. ALWAYS_ENABLED,
  317. };
  318. static struct clk uart3_1510 = {
  319. .name = "uart3_ck",
  320. /* Direct from ULPD, no real parent */
  321. .parent = &armper_ck, /* either armper_ck or dpll4 */
  322. .rate = 12000000,
  323. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
  324. };
  325. static struct clk uart3_16xx = {
  326. .name = "uart3_ck",
  327. /* Direct from ULPD, no real parent */
  328. .parent = &armper_ck,
  329. .rate = 48000000,
  330. .flags = CLOCK_IN_OMAP16XX,
  331. };
  332. static struct clk usb_clk0 = { /* 6 MHz output on W4_USB_CLK0 */
  333. .name = "usb_clk0",
  334. .alias = "usb.clko",
  335. /* Direct from ULPD, no parent */
  336. .rate = 6000000,
  337. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
  338. };
  339. static struct clk usb_hhc_ck1510 = {
  340. .name = "usb_hhc_ck",
  341. /* Direct from ULPD, no parent */
  342. .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
  343. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
  344. };
  345. static struct clk usb_hhc_ck16xx = {
  346. .name = "usb_hhc_ck",
  347. /* Direct from ULPD, no parent */
  348. .rate = 48000000,
  349. /* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
  350. .flags = CLOCK_IN_OMAP16XX,
  351. };
  352. static struct clk usb_w2fc_mclk = {
  353. .name = "usb_w2fc_mclk",
  354. .alias = "usb_w2fc_ck",
  355. .parent = &ck_48m,
  356. .rate = 48000000,
  357. .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
  358. };
  359. static struct clk mclk_1510 = {
  360. .name = "mclk",
  361. /* Direct from ULPD, no parent. May be enabled by ext hardware. */
  362. .rate = 12000000,
  363. .flags = CLOCK_IN_OMAP1510,
  364. };
  365. static struct clk bclk_310 = {
  366. .name = "bt_mclk_out", /* Alias midi_mclk_out? */
  367. .parent = &armper_ck,
  368. .flags = CLOCK_IN_OMAP310,
  369. };
  370. static struct clk mclk_310 = {
  371. .name = "com_mclk_out",
  372. .parent = &armper_ck,
  373. .flags = CLOCK_IN_OMAP310,
  374. };
  375. static struct clk mclk_16xx = {
  376. .name = "mclk",
  377. /* Direct from ULPD, no parent. May be enabled by ext hardware. */
  378. .flags = CLOCK_IN_OMAP16XX,
  379. };
  380. static struct clk bclk_1510 = {
  381. .name = "bclk",
  382. /* Direct from ULPD, no parent. May be enabled by ext hardware. */
  383. .rate = 12000000,
  384. .flags = CLOCK_IN_OMAP1510,
  385. };
  386. static struct clk bclk_16xx = {
  387. .name = "bclk",
  388. /* Direct from ULPD, no parent. May be enabled by ext hardware. */
  389. .flags = CLOCK_IN_OMAP16XX,
  390. };
  391. static struct clk mmc1_ck = {
  392. .name = "mmc_ck",
  393. .id = 1,
  394. /* Functional clock is direct from ULPD, interface clock is ARMPER */
  395. .parent = &armper_ck, /* either armper_ck or dpll4 */
  396. .rate = 48000000,
  397. .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
  398. };
  399. static struct clk mmc2_ck = {
  400. .name = "mmc_ck",
  401. .id = 2,
  402. /* Functional clock is direct from ULPD, interface clock is ARMPER */
  403. .parent = &armper_ck,
  404. .rate = 48000000,
  405. .flags = CLOCK_IN_OMAP16XX,
  406. };
  407. static struct clk cam_mclk = {
  408. .name = "cam.mclk",
  409. .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
  410. .rate = 12000000,
  411. };
  412. static struct clk cam_exclk = {
  413. .name = "cam.exclk",
  414. .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
  415. /* Either 12M from cam.mclk or 48M from dpll4 */
  416. .parent = &cam_mclk,
  417. };
  418. static struct clk cam_lclk = {
  419. .name = "cam.lclk",
  420. .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
  421. };
  422. static struct clk i2c_fck = {
  423. .name = "i2c_fck",
  424. .id = 1,
  425. .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
  426. ALWAYS_ENABLED,
  427. .parent = &armxor_ck,
  428. };
  429. static struct clk i2c_ick = {
  430. .name = "i2c_ick",
  431. .id = 1,
  432. .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
  433. .parent = &armper_ck,
  434. };
  435. static struct clk clk32k = {
  436. .name = "clk32-kHz",
  437. .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
  438. ALWAYS_ENABLED,
  439. .parent = &xtal_osc32k,
  440. };
  441. static struct clk *onchip_clks[] = {
  442. /* OMAP 1 */
  443. /* non-ULPD clocks */
  444. &xtal_osc12m,
  445. &xtal_osc32k,
  446. &ck_ref,
  447. &dpll1,
  448. &dpll2,
  449. &dpll3,
  450. &dpll4,
  451. &apll,
  452. &ck_48m,
  453. /* CK_GEN1 clocks */
  454. &clkm1,
  455. &ck_dpll1out,
  456. &sossi_ck,
  457. &arm_ck,
  458. &armper_ck,
  459. &arm_gpio_ck,
  460. &armxor_ck,
  461. &armtim_ck,
  462. &armwdt_ck,
  463. &arminth_ck15xx, &arminth_ck16xx,
  464. /* CK_GEN2 clocks */
  465. &clkm2,
  466. &dsp_ck,
  467. &dspmmu_ck,
  468. &dspper_ck,
  469. &dspxor_ck,
  470. &dsptim_ck,
  471. /* CK_GEN3 clocks */
  472. &clkm3,
  473. &tc_ck,
  474. &tipb_ck,
  475. &l3_ocpi_ck,
  476. &tc1_ck,
  477. &tc2_ck,
  478. &dma_ck,
  479. &dma_lcdfree_ck,
  480. &api_ck,
  481. &lb_ck,
  482. &lbfree_ck,
  483. &hsab_ck,
  484. &rhea1_ck,
  485. &rhea2_ck,
  486. &lcd_ck_16xx,
  487. &lcd_ck_1510,
  488. /* ULPD clocks */
  489. &uart1_1510,
  490. &uart1_16xx,
  491. &uart2_ck,
  492. &uart3_1510,
  493. &uart3_16xx,
  494. &usb_clk0,
  495. &usb_hhc_ck1510, &usb_hhc_ck16xx,
  496. &mclk_1510, &mclk_16xx, &mclk_310,
  497. &bclk_1510, &bclk_16xx, &bclk_310,
  498. &mmc1_ck,
  499. &mmc2_ck,
  500. &cam_mclk,
  501. &cam_exclk,
  502. &cam_lclk,
  503. &clk32k,
  504. &usb_w2fc_mclk,
  505. /* Virtual clocks */
  506. &i2c_fck,
  507. &i2c_ick,
  508. NULL
  509. };
  510. void omap_clk_adduser(struct clk *clk, qemu_irq user)
  511. {
  512. qemu_irq *i;
  513. for (i = clk->users; *i; i ++);
  514. *i = user;
  515. }
  516. struct clk *omap_findclk(struct omap_mpu_state_s *mpu, const char *name)
  517. {
  518. struct clk *i;
  519. for (i = mpu->clks; i->name; i ++)
  520. if (!strcmp(i->name, name) || (i->alias && !strcmp(i->alias, name)))
  521. return i;
  522. hw_error("%s: %s not found\n", __func__, name);
  523. }
  524. void omap_clk_get(struct clk *clk)
  525. {
  526. clk->usecount ++;
  527. }
  528. void omap_clk_put(struct clk *clk)
  529. {
  530. if (!(clk->usecount --))
  531. hw_error("%s: %s is not in use\n", __func__, clk->name);
  532. }
  533. static void omap_clk_update(struct clk *clk)
  534. {
  535. int parent, running;
  536. qemu_irq *user;
  537. struct clk *i;
  538. if (clk->parent)
  539. parent = clk->parent->running;
  540. else
  541. parent = 1;
  542. running = parent && (clk->enabled ||
  543. ((clk->flags & ALWAYS_ENABLED) && clk->usecount));
  544. if (clk->running != running) {
  545. clk->running = running;
  546. for (user = clk->users; *user; user ++)
  547. qemu_set_irq(*user, running);
  548. for (i = clk->child1; i; i = i->sibling)
  549. omap_clk_update(i);
  550. }
  551. }
  552. static void omap_clk_rate_update_full(struct clk *clk, unsigned long int rate,
  553. unsigned long int div, unsigned long int mult)
  554. {
  555. struct clk *i;
  556. qemu_irq *user;
  557. clk->rate = muldiv64(rate, mult, div);
  558. if (clk->running)
  559. for (user = clk->users; *user; user ++)
  560. qemu_irq_raise(*user);
  561. for (i = clk->child1; i; i = i->sibling)
  562. omap_clk_rate_update_full(i, rate,
  563. div * i->divisor, mult * i->multiplier);
  564. }
  565. static void omap_clk_rate_update(struct clk *clk)
  566. {
  567. struct clk *i;
  568. unsigned long int div, mult = div = 1;
  569. for (i = clk; i->parent; i = i->parent) {
  570. div *= i->divisor;
  571. mult *= i->multiplier;
  572. }
  573. omap_clk_rate_update_full(clk, i->rate, div, mult);
  574. }
  575. void omap_clk_reparent(struct clk *clk, struct clk *parent)
  576. {
  577. struct clk **p;
  578. if (clk->parent) {
  579. for (p = &clk->parent->child1; *p != clk; p = &(*p)->sibling);
  580. *p = clk->sibling;
  581. }
  582. clk->parent = parent;
  583. if (parent) {
  584. clk->sibling = parent->child1;
  585. parent->child1 = clk;
  586. omap_clk_update(clk);
  587. omap_clk_rate_update(clk);
  588. } else
  589. clk->sibling = NULL;
  590. }
  591. void omap_clk_onoff(struct clk *clk, int on)
  592. {
  593. clk->enabled = on;
  594. omap_clk_update(clk);
  595. }
  596. void omap_clk_canidle(struct clk *clk, int can)
  597. {
  598. if (can)
  599. omap_clk_put(clk);
  600. else
  601. omap_clk_get(clk);
  602. }
  603. void omap_clk_setrate(struct clk *clk, int divide, int multiply)
  604. {
  605. clk->divisor = divide;
  606. clk->multiplier = multiply;
  607. omap_clk_rate_update(clk);
  608. }
  609. int64_t omap_clk_getrate(omap_clk clk)
  610. {
  611. return clk->rate;
  612. }
  613. void omap_clk_init(struct omap_mpu_state_s *mpu)
  614. {
  615. struct clk **i, *j, *k;
  616. int count;
  617. int flag;
  618. if (cpu_is_omap310(mpu))
  619. flag = CLOCK_IN_OMAP310;
  620. else if (cpu_is_omap1510(mpu))
  621. flag = CLOCK_IN_OMAP1510;
  622. else
  623. return;
  624. for (i = onchip_clks, count = 0; *i; i ++)
  625. if ((*i)->flags & flag)
  626. count ++;
  627. mpu->clks = g_new0(struct clk, count + 1);
  628. for (i = onchip_clks, j = mpu->clks; *i; i ++)
  629. if ((*i)->flags & flag) {
  630. memcpy(j, *i, sizeof(struct clk));
  631. for (k = mpu->clks; k < j; k ++)
  632. if (j->parent && !strcmp(j->parent->name, k->name)) {
  633. j->parent = k;
  634. j->sibling = k->child1;
  635. k->child1 = j;
  636. } else if (k->parent && !strcmp(k->parent->name, j->name)) {
  637. k->parent = j;
  638. k->sibling = j->child1;
  639. j->child1 = k;
  640. }
  641. j->divisor = j->divisor ?: 1;
  642. j->multiplier = j->multiplier ?: 1;
  643. j ++;
  644. }
  645. for (j = mpu->clks; count --; j ++) {
  646. omap_clk_update(j);
  647. omap_clk_rate_update(j);
  648. }
  649. }