clock.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * linux/arch/arm/mach-omap1/clock.c
  4. *
  5. * Copyright (C) 2004 - 2005, 2009-2010 Nokia Corporation
  6. * Written by Tuukka Tikkanen <[email protected]>
  7. *
  8. * Modified to use omap shared clock framework by
  9. * Tony Lindgren <[email protected]>
  10. */
  11. #include <linux/kernel.h>
  12. #include <linux/export.h>
  13. #include <linux/list.h>
  14. #include <linux/errno.h>
  15. #include <linux/err.h>
  16. #include <linux/io.h>
  17. #include <linux/clk.h>
  18. #include <linux/clkdev.h>
  19. #include <linux/clk-provider.h>
  20. #include <linux/soc/ti/omap1-io.h>
  21. #include <linux/spinlock.h>
  22. #include <asm/mach-types.h>
  23. #include "hardware.h"
  24. #include "soc.h"
  25. #include "iomap.h"
  26. #include "clock.h"
  27. #include "opp.h"
  28. #include "sram.h"
  29. __u32 arm_idlect1_mask;
  30. /* provide direct internal access (not via clk API) to some clocks */
  31. struct omap1_clk *api_ck_p, *ck_dpll1_p, *ck_ref_p;
  32. /* protect registeres shared among clk_enable/disable() and clk_set_rate() operations */
  33. static DEFINE_SPINLOCK(arm_ckctl_lock);
  34. static DEFINE_SPINLOCK(arm_idlect2_lock);
  35. static DEFINE_SPINLOCK(mod_conf_ctrl_0_lock);
  36. static DEFINE_SPINLOCK(mod_conf_ctrl_1_lock);
  37. static DEFINE_SPINLOCK(swd_clk_div_ctrl_sel_lock);
  38. /*
  39. * Omap1 specific clock functions
  40. */
  41. unsigned long omap1_uart_recalc(struct omap1_clk *clk, unsigned long p_rate)
  42. {
  43. unsigned int val = __raw_readl(clk->enable_reg);
  44. return val & 1 << clk->enable_bit ? 48000000 : 12000000;
  45. }
  46. unsigned long omap1_sossi_recalc(struct omap1_clk *clk, unsigned long p_rate)
  47. {
  48. u32 div = omap_readl(MOD_CONF_CTRL_1);
  49. div = (div >> 17) & 0x7;
  50. div++;
  51. return p_rate / div;
  52. }
  53. static void omap1_clk_allow_idle(struct omap1_clk *clk)
  54. {
  55. struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk;
  56. if (!(clk->flags & CLOCK_IDLE_CONTROL))
  57. return;
  58. if (iclk->no_idle_count > 0 && !(--iclk->no_idle_count))
  59. arm_idlect1_mask |= 1 << iclk->idlect_shift;
  60. }
  61. static void omap1_clk_deny_idle(struct omap1_clk *clk)
  62. {
  63. struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk;
  64. if (!(clk->flags & CLOCK_IDLE_CONTROL))
  65. return;
  66. if (iclk->no_idle_count++ == 0)
  67. arm_idlect1_mask &= ~(1 << iclk->idlect_shift);
  68. }
  69. static __u16 verify_ckctl_value(__u16 newval)
  70. {
  71. /* This function checks for following limitations set
  72. * by the hardware (all conditions must be true):
  73. * DSPMMU_CK == DSP_CK or DSPMMU_CK == DSP_CK/2
  74. * ARM_CK >= TC_CK
  75. * DSP_CK >= TC_CK
  76. * DSPMMU_CK >= TC_CK
  77. *
  78. * In addition following rules are enforced:
  79. * LCD_CK <= TC_CK
  80. * ARMPER_CK <= TC_CK
  81. *
  82. * However, maximum frequencies are not checked for!
  83. */
  84. __u8 per_exp;
  85. __u8 lcd_exp;
  86. __u8 arm_exp;
  87. __u8 dsp_exp;
  88. __u8 tc_exp;
  89. __u8 dspmmu_exp;
  90. per_exp = (newval >> CKCTL_PERDIV_OFFSET) & 3;
  91. lcd_exp = (newval >> CKCTL_LCDDIV_OFFSET) & 3;
  92. arm_exp = (newval >> CKCTL_ARMDIV_OFFSET) & 3;
  93. dsp_exp = (newval >> CKCTL_DSPDIV_OFFSET) & 3;
  94. tc_exp = (newval >> CKCTL_TCDIV_OFFSET) & 3;
  95. dspmmu_exp = (newval >> CKCTL_DSPMMUDIV_OFFSET) & 3;
  96. if (dspmmu_exp < dsp_exp)
  97. dspmmu_exp = dsp_exp;
  98. if (dspmmu_exp > dsp_exp+1)
  99. dspmmu_exp = dsp_exp+1;
  100. if (tc_exp < arm_exp)
  101. tc_exp = arm_exp;
  102. if (tc_exp < dspmmu_exp)
  103. tc_exp = dspmmu_exp;
  104. if (tc_exp > lcd_exp)
  105. lcd_exp = tc_exp;
  106. if (tc_exp > per_exp)
  107. per_exp = tc_exp;
  108. newval &= 0xf000;
  109. newval |= per_exp << CKCTL_PERDIV_OFFSET;
  110. newval |= lcd_exp << CKCTL_LCDDIV_OFFSET;
  111. newval |= arm_exp << CKCTL_ARMDIV_OFFSET;
  112. newval |= dsp_exp << CKCTL_DSPDIV_OFFSET;
  113. newval |= tc_exp << CKCTL_TCDIV_OFFSET;
  114. newval |= dspmmu_exp << CKCTL_DSPMMUDIV_OFFSET;
  115. return newval;
  116. }
  117. static int calc_dsor_exp(unsigned long rate, unsigned long realrate)
  118. {
  119. /* Note: If target frequency is too low, this function will return 4,
  120. * which is invalid value. Caller must check for this value and act
  121. * accordingly.
  122. *
  123. * Note: This function does not check for following limitations set
  124. * by the hardware (all conditions must be true):
  125. * DSPMMU_CK == DSP_CK or DSPMMU_CK == DSP_CK/2
  126. * ARM_CK >= TC_CK
  127. * DSP_CK >= TC_CK
  128. * DSPMMU_CK >= TC_CK
  129. */
  130. unsigned dsor_exp;
  131. if (unlikely(realrate == 0))
  132. return -EIO;
  133. for (dsor_exp=0; dsor_exp<4; dsor_exp++) {
  134. if (realrate <= rate)
  135. break;
  136. realrate /= 2;
  137. }
  138. return dsor_exp;
  139. }
  140. unsigned long omap1_ckctl_recalc(struct omap1_clk *clk, unsigned long p_rate)
  141. {
  142. /* Calculate divisor encoded as 2-bit exponent */
  143. int dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
  144. /* update locally maintained rate, required by arm_ck for omap1_show_rates() */
  145. clk->rate = p_rate / dsor;
  146. return clk->rate;
  147. }
  148. static int omap1_clk_is_enabled(struct clk_hw *hw)
  149. {
  150. struct omap1_clk *clk = to_omap1_clk(hw);
  151. bool api_ck_was_enabled = true;
  152. __u32 regval32;
  153. int ret;
  154. if (!clk->ops) /* no gate -- always enabled */
  155. return 1;
  156. if (clk->ops == &clkops_dspck) {
  157. api_ck_was_enabled = omap1_clk_is_enabled(&api_ck_p->hw);
  158. if (!api_ck_was_enabled)
  159. if (api_ck_p->ops->enable(api_ck_p) < 0)
  160. return 0;
  161. }
  162. if (clk->flags & ENABLE_REG_32BIT)
  163. regval32 = __raw_readl(clk->enable_reg);
  164. else
  165. regval32 = __raw_readw(clk->enable_reg);
  166. ret = regval32 & (1 << clk->enable_bit);
  167. if (!api_ck_was_enabled)
  168. api_ck_p->ops->disable(api_ck_p);
  169. return ret;
  170. }
  171. unsigned long omap1_ckctl_recalc_dsp_domain(struct omap1_clk *clk, unsigned long p_rate)
  172. {
  173. bool api_ck_was_enabled;
  174. int dsor;
  175. /* Calculate divisor encoded as 2-bit exponent
  176. *
  177. * The clock control bits are in DSP domain,
  178. * so api_ck is needed for access.
  179. * Note that DSP_CKCTL virt addr = phys addr, so
  180. * we must use __raw_readw() instead of omap_readw().
  181. */
  182. api_ck_was_enabled = omap1_clk_is_enabled(&api_ck_p->hw);
  183. if (!api_ck_was_enabled)
  184. api_ck_p->ops->enable(api_ck_p);
  185. dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset));
  186. if (!api_ck_was_enabled)
  187. api_ck_p->ops->disable(api_ck_p);
  188. return p_rate / dsor;
  189. }
  190. /* MPU virtual clock functions */
  191. int omap1_select_table_rate(struct omap1_clk *clk, unsigned long rate, unsigned long p_rate)
  192. {
  193. /* Find the highest supported frequency <= rate and switch to it */
  194. struct mpu_rate * ptr;
  195. unsigned long ref_rate;
  196. ref_rate = ck_ref_p->rate;
  197. for (ptr = omap1_rate_table; ptr->rate; ptr++) {
  198. if (!(ptr->flags & cpu_mask))
  199. continue;
  200. if (ptr->xtal != ref_rate)
  201. continue;
  202. /* Can check only after xtal frequency check */
  203. if (ptr->rate <= rate)
  204. break;
  205. }
  206. if (!ptr->rate)
  207. return -EINVAL;
  208. /*
  209. * In most cases we should not need to reprogram DPLL.
  210. * Reprogramming the DPLL is tricky, it must be done from SRAM.
  211. */
  212. omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val);
  213. /* XXX Do we need to recalculate the tree below DPLL1 at this point? */
  214. ck_dpll1_p->rate = ptr->pll_rate;
  215. return 0;
  216. }
  217. int omap1_clk_set_rate_dsp_domain(struct omap1_clk *clk, unsigned long rate, unsigned long p_rate)
  218. {
  219. int dsor_exp;
  220. u16 regval;
  221. dsor_exp = calc_dsor_exp(rate, p_rate);
  222. if (dsor_exp > 3)
  223. dsor_exp = -EINVAL;
  224. if (dsor_exp < 0)
  225. return dsor_exp;
  226. regval = __raw_readw(DSP_CKCTL);
  227. regval &= ~(3 << clk->rate_offset);
  228. regval |= dsor_exp << clk->rate_offset;
  229. __raw_writew(regval, DSP_CKCTL);
  230. clk->rate = p_rate / (1 << dsor_exp);
  231. return 0;
  232. }
  233. long omap1_clk_round_rate_ckctl_arm(struct omap1_clk *clk, unsigned long rate,
  234. unsigned long *p_rate)
  235. {
  236. int dsor_exp = calc_dsor_exp(rate, *p_rate);
  237. if (dsor_exp < 0)
  238. return dsor_exp;
  239. if (dsor_exp > 3)
  240. dsor_exp = 3;
  241. return *p_rate / (1 << dsor_exp);
  242. }
  243. int omap1_clk_set_rate_ckctl_arm(struct omap1_clk *clk, unsigned long rate, unsigned long p_rate)
  244. {
  245. unsigned long flags;
  246. int dsor_exp;
  247. u16 regval;
  248. dsor_exp = calc_dsor_exp(rate, p_rate);
  249. if (dsor_exp > 3)
  250. dsor_exp = -EINVAL;
  251. if (dsor_exp < 0)
  252. return dsor_exp;
  253. /* protect ARM_CKCTL register from concurrent access via clk_enable/disable() */
  254. spin_lock_irqsave(&arm_ckctl_lock, flags);
  255. regval = omap_readw(ARM_CKCTL);
  256. regval &= ~(3 << clk->rate_offset);
  257. regval |= dsor_exp << clk->rate_offset;
  258. regval = verify_ckctl_value(regval);
  259. omap_writew(regval, ARM_CKCTL);
  260. clk->rate = p_rate / (1 << dsor_exp);
  261. spin_unlock_irqrestore(&arm_ckctl_lock, flags);
  262. return 0;
  263. }
  264. long omap1_round_to_table_rate(struct omap1_clk *clk, unsigned long rate, unsigned long *p_rate)
  265. {
  266. /* Find the highest supported frequency <= rate */
  267. struct mpu_rate * ptr;
  268. long highest_rate;
  269. unsigned long ref_rate;
  270. ref_rate = ck_ref_p->rate;
  271. highest_rate = -EINVAL;
  272. for (ptr = omap1_rate_table; ptr->rate; ptr++) {
  273. if (!(ptr->flags & cpu_mask))
  274. continue;
  275. if (ptr->xtal != ref_rate)
  276. continue;
  277. highest_rate = ptr->rate;
  278. /* Can check only after xtal frequency check */
  279. if (ptr->rate <= rate)
  280. break;
  281. }
  282. return highest_rate;
  283. }
  284. static unsigned calc_ext_dsor(unsigned long rate)
  285. {
  286. unsigned dsor;
  287. /* MCLK and BCLK divisor selection is not linear:
  288. * freq = 96MHz / dsor
  289. *
  290. * RATIO_SEL range: dsor <-> RATIO_SEL
  291. * 0..6: (RATIO_SEL+2) <-> (dsor-2)
  292. * 6..48: (8+(RATIO_SEL-6)*2) <-> ((dsor-8)/2+6)
  293. * Minimum dsor is 2 and maximum is 96. Odd divisors starting from 9
  294. * can not be used.
  295. */
  296. for (dsor = 2; dsor < 96; ++dsor) {
  297. if ((dsor & 1) && dsor > 8)
  298. continue;
  299. if (rate >= 96000000 / dsor)
  300. break;
  301. }
  302. return dsor;
  303. }
  304. /* XXX Only needed on 1510 */
  305. long omap1_round_uart_rate(struct omap1_clk *clk, unsigned long rate, unsigned long *p_rate)
  306. {
  307. return rate > 24000000 ? 48000000 : 12000000;
  308. }
  309. int omap1_set_uart_rate(struct omap1_clk *clk, unsigned long rate, unsigned long p_rate)
  310. {
  311. unsigned long flags;
  312. unsigned int val;
  313. if (rate == 12000000)
  314. val = 0;
  315. else if (rate == 48000000)
  316. val = 1 << clk->enable_bit;
  317. else
  318. return -EINVAL;
  319. /* protect MOD_CONF_CTRL_0 register from concurrent access via clk_enable/disable() */
  320. spin_lock_irqsave(&mod_conf_ctrl_0_lock, flags);
  321. val |= __raw_readl(clk->enable_reg) & ~(1 << clk->enable_bit);
  322. __raw_writel(val, clk->enable_reg);
  323. spin_unlock_irqrestore(&mod_conf_ctrl_0_lock, flags);
  324. clk->rate = rate;
  325. return 0;
  326. }
  327. /* External clock (MCLK & BCLK) functions */
  328. int omap1_set_ext_clk_rate(struct omap1_clk *clk, unsigned long rate, unsigned long p_rate)
  329. {
  330. unsigned long flags;
  331. unsigned dsor;
  332. __u16 ratio_bits;
  333. dsor = calc_ext_dsor(rate);
  334. clk->rate = 96000000 / dsor;
  335. if (dsor > 8)
  336. ratio_bits = ((dsor - 8) / 2 + 6) << 2;
  337. else
  338. ratio_bits = (dsor - 2) << 2;
  339. /* protect SWD_CLK_DIV_CTRL_SEL register from concurrent access via clk_enable/disable() */
  340. spin_lock_irqsave(&swd_clk_div_ctrl_sel_lock, flags);
  341. ratio_bits |= __raw_readw(clk->enable_reg) & ~0xfd;
  342. __raw_writew(ratio_bits, clk->enable_reg);
  343. spin_unlock_irqrestore(&swd_clk_div_ctrl_sel_lock, flags);
  344. return 0;
  345. }
  346. static int calc_div_sossi(unsigned long rate, unsigned long p_rate)
  347. {
  348. int div;
  349. /* Round towards slower frequency */
  350. div = (p_rate + rate - 1) / rate;
  351. return --div;
  352. }
  353. long omap1_round_sossi_rate(struct omap1_clk *clk, unsigned long rate, unsigned long *p_rate)
  354. {
  355. int div;
  356. div = calc_div_sossi(rate, *p_rate);
  357. if (div < 0)
  358. div = 0;
  359. else if (div > 7)
  360. div = 7;
  361. return *p_rate / (div + 1);
  362. }
  363. int omap1_set_sossi_rate(struct omap1_clk *clk, unsigned long rate, unsigned long p_rate)
  364. {
  365. unsigned long flags;
  366. u32 l;
  367. int div;
  368. div = calc_div_sossi(rate, p_rate);
  369. if (div < 0 || div > 7)
  370. return -EINVAL;
  371. /* protect MOD_CONF_CTRL_1 register from concurrent access via clk_enable/disable() */
  372. spin_lock_irqsave(&mod_conf_ctrl_1_lock, flags);
  373. l = omap_readl(MOD_CONF_CTRL_1);
  374. l &= ~(7 << 17);
  375. l |= div << 17;
  376. omap_writel(l, MOD_CONF_CTRL_1);
  377. clk->rate = p_rate / (div + 1);
  378. spin_unlock_irqrestore(&mod_conf_ctrl_1_lock, flags);
  379. return 0;
  380. }
  381. long omap1_round_ext_clk_rate(struct omap1_clk *clk, unsigned long rate, unsigned long *p_rate)
  382. {
  383. return 96000000 / calc_ext_dsor(rate);
  384. }
  385. int omap1_init_ext_clk(struct omap1_clk *clk)
  386. {
  387. unsigned dsor;
  388. __u16 ratio_bits;
  389. /* Determine current rate and ensure clock is based on 96MHz APLL */
  390. ratio_bits = __raw_readw(clk->enable_reg) & ~1;
  391. __raw_writew(ratio_bits, clk->enable_reg);
  392. ratio_bits = (ratio_bits & 0xfc) >> 2;
  393. if (ratio_bits > 6)
  394. dsor = (ratio_bits - 6) * 2 + 8;
  395. else
  396. dsor = ratio_bits + 2;
  397. clk-> rate = 96000000 / dsor;
  398. return 0;
  399. }
  400. static int omap1_clk_enable(struct clk_hw *hw)
  401. {
  402. struct omap1_clk *clk = to_omap1_clk(hw), *parent = to_omap1_clk(clk_hw_get_parent(hw));
  403. int ret = 0;
  404. if (parent && clk->flags & CLOCK_NO_IDLE_PARENT)
  405. omap1_clk_deny_idle(parent);
  406. if (clk->ops && !(WARN_ON(!clk->ops->enable)))
  407. ret = clk->ops->enable(clk);
  408. return ret;
  409. }
  410. static void omap1_clk_disable(struct clk_hw *hw)
  411. {
  412. struct omap1_clk *clk = to_omap1_clk(hw), *parent = to_omap1_clk(clk_hw_get_parent(hw));
  413. if (clk->ops && !(WARN_ON(!clk->ops->disable)))
  414. clk->ops->disable(clk);
  415. if (likely(parent) && clk->flags & CLOCK_NO_IDLE_PARENT)
  416. omap1_clk_allow_idle(parent);
  417. }
  418. static int omap1_clk_enable_generic(struct omap1_clk *clk)
  419. {
  420. unsigned long flags;
  421. __u16 regval16;
  422. __u32 regval32;
  423. if (unlikely(clk->enable_reg == NULL)) {
  424. printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
  425. clk_hw_get_name(&clk->hw));
  426. return -EINVAL;
  427. }
  428. /* protect clk->enable_reg from concurrent access via clk_set_rate() */
  429. if (clk->enable_reg == OMAP1_IO_ADDRESS(ARM_CKCTL))
  430. spin_lock_irqsave(&arm_ckctl_lock, flags);
  431. else if (clk->enable_reg == OMAP1_IO_ADDRESS(ARM_IDLECT2))
  432. spin_lock_irqsave(&arm_idlect2_lock, flags);
  433. else if (clk->enable_reg == OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0))
  434. spin_lock_irqsave(&mod_conf_ctrl_0_lock, flags);
  435. else if (clk->enable_reg == OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1))
  436. spin_lock_irqsave(&mod_conf_ctrl_1_lock, flags);
  437. else if (clk->enable_reg == OMAP1_IO_ADDRESS(SWD_CLK_DIV_CTRL_SEL))
  438. spin_lock_irqsave(&swd_clk_div_ctrl_sel_lock, flags);
  439. if (clk->flags & ENABLE_REG_32BIT) {
  440. regval32 = __raw_readl(clk->enable_reg);
  441. regval32 |= (1 << clk->enable_bit);
  442. __raw_writel(regval32, clk->enable_reg);
  443. } else {
  444. regval16 = __raw_readw(clk->enable_reg);
  445. regval16 |= (1 << clk->enable_bit);
  446. __raw_writew(regval16, clk->enable_reg);
  447. }
  448. if (clk->enable_reg == OMAP1_IO_ADDRESS(ARM_CKCTL))
  449. spin_unlock_irqrestore(&arm_ckctl_lock, flags);
  450. else if (clk->enable_reg == OMAP1_IO_ADDRESS(ARM_IDLECT2))
  451. spin_unlock_irqrestore(&arm_idlect2_lock, flags);
  452. else if (clk->enable_reg == OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0))
  453. spin_unlock_irqrestore(&mod_conf_ctrl_0_lock, flags);
  454. else if (clk->enable_reg == OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1))
  455. spin_unlock_irqrestore(&mod_conf_ctrl_1_lock, flags);
  456. else if (clk->enable_reg == OMAP1_IO_ADDRESS(SWD_CLK_DIV_CTRL_SEL))
  457. spin_unlock_irqrestore(&swd_clk_div_ctrl_sel_lock, flags);
  458. return 0;
  459. }
  460. static void omap1_clk_disable_generic(struct omap1_clk *clk)
  461. {
  462. unsigned long flags;
  463. __u16 regval16;
  464. __u32 regval32;
  465. if (clk->enable_reg == NULL)
  466. return;
  467. /* protect clk->enable_reg from concurrent access via clk_set_rate() */
  468. if (clk->enable_reg == OMAP1_IO_ADDRESS(ARM_CKCTL))
  469. spin_lock_irqsave(&arm_ckctl_lock, flags);
  470. else if (clk->enable_reg == OMAP1_IO_ADDRESS(ARM_IDLECT2))
  471. spin_lock_irqsave(&arm_idlect2_lock, flags);
  472. else if (clk->enable_reg == OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0))
  473. spin_lock_irqsave(&mod_conf_ctrl_0_lock, flags);
  474. else if (clk->enable_reg == OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1))
  475. spin_lock_irqsave(&mod_conf_ctrl_1_lock, flags);
  476. else if (clk->enable_reg == OMAP1_IO_ADDRESS(SWD_CLK_DIV_CTRL_SEL))
  477. spin_lock_irqsave(&swd_clk_div_ctrl_sel_lock, flags);
  478. if (clk->flags & ENABLE_REG_32BIT) {
  479. regval32 = __raw_readl(clk->enable_reg);
  480. regval32 &= ~(1 << clk->enable_bit);
  481. __raw_writel(regval32, clk->enable_reg);
  482. } else {
  483. regval16 = __raw_readw(clk->enable_reg);
  484. regval16 &= ~(1 << clk->enable_bit);
  485. __raw_writew(regval16, clk->enable_reg);
  486. }
  487. if (clk->enable_reg == OMAP1_IO_ADDRESS(ARM_CKCTL))
  488. spin_unlock_irqrestore(&arm_ckctl_lock, flags);
  489. else if (clk->enable_reg == OMAP1_IO_ADDRESS(ARM_IDLECT2))
  490. spin_unlock_irqrestore(&arm_idlect2_lock, flags);
  491. else if (clk->enable_reg == OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0))
  492. spin_unlock_irqrestore(&mod_conf_ctrl_0_lock, flags);
  493. else if (clk->enable_reg == OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1))
  494. spin_unlock_irqrestore(&mod_conf_ctrl_1_lock, flags);
  495. else if (clk->enable_reg == OMAP1_IO_ADDRESS(SWD_CLK_DIV_CTRL_SEL))
  496. spin_unlock_irqrestore(&swd_clk_div_ctrl_sel_lock, flags);
  497. }
  498. const struct clkops clkops_generic = {
  499. .enable = omap1_clk_enable_generic,
  500. .disable = omap1_clk_disable_generic,
  501. };
  502. static int omap1_clk_enable_dsp_domain(struct omap1_clk *clk)
  503. {
  504. bool api_ck_was_enabled;
  505. int retval = 0;
  506. api_ck_was_enabled = omap1_clk_is_enabled(&api_ck_p->hw);
  507. if (!api_ck_was_enabled)
  508. retval = api_ck_p->ops->enable(api_ck_p);
  509. if (!retval) {
  510. retval = omap1_clk_enable_generic(clk);
  511. if (!api_ck_was_enabled)
  512. api_ck_p->ops->disable(api_ck_p);
  513. }
  514. return retval;
  515. }
  516. static void omap1_clk_disable_dsp_domain(struct omap1_clk *clk)
  517. {
  518. bool api_ck_was_enabled;
  519. api_ck_was_enabled = omap1_clk_is_enabled(&api_ck_p->hw);
  520. if (!api_ck_was_enabled)
  521. if (api_ck_p->ops->enable(api_ck_p) < 0)
  522. return;
  523. omap1_clk_disable_generic(clk);
  524. if (!api_ck_was_enabled)
  525. api_ck_p->ops->disable(api_ck_p);
  526. }
  527. const struct clkops clkops_dspck = {
  528. .enable = omap1_clk_enable_dsp_domain,
  529. .disable = omap1_clk_disable_dsp_domain,
  530. };
  531. /* XXX SYSC register handling does not belong in the clock framework */
  532. static int omap1_clk_enable_uart_functional_16xx(struct omap1_clk *clk)
  533. {
  534. int ret;
  535. struct uart_clk *uclk;
  536. ret = omap1_clk_enable_generic(clk);
  537. if (ret == 0) {
  538. /* Set smart idle acknowledgement mode */
  539. uclk = (struct uart_clk *)clk;
  540. omap_writeb((omap_readb(uclk->sysc_addr) & ~0x10) | 8,
  541. uclk->sysc_addr);
  542. }
  543. return ret;
  544. }
  545. /* XXX SYSC register handling does not belong in the clock framework */
  546. static void omap1_clk_disable_uart_functional_16xx(struct omap1_clk *clk)
  547. {
  548. struct uart_clk *uclk;
  549. /* Set force idle acknowledgement mode */
  550. uclk = (struct uart_clk *)clk;
  551. omap_writeb((omap_readb(uclk->sysc_addr) & ~0x18), uclk->sysc_addr);
  552. omap1_clk_disable_generic(clk);
  553. }
  554. /* XXX SYSC register handling does not belong in the clock framework */
  555. const struct clkops clkops_uart_16xx = {
  556. .enable = omap1_clk_enable_uart_functional_16xx,
  557. .disable = omap1_clk_disable_uart_functional_16xx,
  558. };
  559. static unsigned long omap1_clk_recalc_rate(struct clk_hw *hw, unsigned long p_rate)
  560. {
  561. struct omap1_clk *clk = to_omap1_clk(hw);
  562. if (clk->recalc)
  563. return clk->recalc(clk, p_rate);
  564. return clk->rate;
  565. }
  566. static long omap1_clk_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *p_rate)
  567. {
  568. struct omap1_clk *clk = to_omap1_clk(hw);
  569. if (clk->round_rate != NULL)
  570. return clk->round_rate(clk, rate, p_rate);
  571. return omap1_clk_recalc_rate(hw, *p_rate);
  572. }
  573. static int omap1_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long p_rate)
  574. {
  575. struct omap1_clk *clk = to_omap1_clk(hw);
  576. int ret = -EINVAL;
  577. if (clk->set_rate)
  578. ret = clk->set_rate(clk, rate, p_rate);
  579. return ret;
  580. }
  581. /*
  582. * Omap1 clock reset and init functions
  583. */
  584. static int omap1_clk_init_op(struct clk_hw *hw)
  585. {
  586. struct omap1_clk *clk = to_omap1_clk(hw);
  587. if (clk->init)
  588. return clk->init(clk);
  589. return 0;
  590. }
  591. #ifdef CONFIG_OMAP_RESET_CLOCKS
  592. static void omap1_clk_disable_unused(struct clk_hw *hw)
  593. {
  594. struct omap1_clk *clk = to_omap1_clk(hw);
  595. const char *name = clk_hw_get_name(hw);
  596. /* Clocks in the DSP domain need api_ck. Just assume bootloader
  597. * has not enabled any DSP clocks */
  598. if (clk->enable_reg == DSP_IDLECT2) {
  599. pr_info("Skipping reset check for DSP domain clock \"%s\"\n", name);
  600. return;
  601. }
  602. pr_info("Disabling unused clock \"%s\"... ", name);
  603. omap1_clk_disable(hw);
  604. printk(" done\n");
  605. }
  606. #endif
  607. const struct clk_ops omap1_clk_gate_ops = {
  608. .enable = omap1_clk_enable,
  609. .disable = omap1_clk_disable,
  610. .is_enabled = omap1_clk_is_enabled,
  611. #ifdef CONFIG_OMAP_RESET_CLOCKS
  612. .disable_unused = omap1_clk_disable_unused,
  613. #endif
  614. };
  615. const struct clk_ops omap1_clk_rate_ops = {
  616. .recalc_rate = omap1_clk_recalc_rate,
  617. .round_rate = omap1_clk_round_rate,
  618. .set_rate = omap1_clk_set_rate,
  619. .init = omap1_clk_init_op,
  620. };
  621. const struct clk_ops omap1_clk_full_ops = {
  622. .enable = omap1_clk_enable,
  623. .disable = omap1_clk_disable,
  624. .is_enabled = omap1_clk_is_enabled,
  625. #ifdef CONFIG_OMAP_RESET_CLOCKS
  626. .disable_unused = omap1_clk_disable_unused,
  627. #endif
  628. .recalc_rate = omap1_clk_recalc_rate,
  629. .round_rate = omap1_clk_round_rate,
  630. .set_rate = omap1_clk_set_rate,
  631. .init = omap1_clk_init_op,
  632. };
  633. /*
  634. * OMAP specific clock functions shared between omap1 and omap2
  635. */
  636. /* Used for clocks that always have same value as the parent clock */
  637. unsigned long followparent_recalc(struct omap1_clk *clk, unsigned long p_rate)
  638. {
  639. return p_rate;
  640. }
  641. /*
  642. * Used for clocks that have the same value as the parent clock,
  643. * divided by some factor
  644. */
  645. unsigned long omap_fixed_divisor_recalc(struct omap1_clk *clk, unsigned long p_rate)
  646. {
  647. WARN_ON(!clk->fixed_div);
  648. return p_rate / clk->fixed_div;
  649. }
  650. /* Propagate rate to children */
  651. void propagate_rate(struct omap1_clk *tclk)
  652. {
  653. struct clk *clkp;
  654. /* depend on CCF ability to recalculate new rates across whole clock subtree */
  655. if (WARN_ON(!(clk_hw_get_flags(&tclk->hw) & CLK_GET_RATE_NOCACHE)))
  656. return;
  657. clkp = clk_get_sys(NULL, clk_hw_get_name(&tclk->hw));
  658. if (WARN_ON(!clkp))
  659. return;
  660. clk_get_rate(clkp);
  661. clk_put(clkp);
  662. }
  663. const struct clk_ops omap1_clk_null_ops = {
  664. };
  665. /*
  666. * Dummy clock
  667. *
  668. * Used for clock aliases that are needed on some OMAPs, but not others
  669. */
  670. struct omap1_clk dummy_ck __refdata = {
  671. .hw.init = CLK_HW_INIT_NO_PARENT("dummy", &omap1_clk_null_ops, 0),
  672. };