abb.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. *
  3. * Adaptive Body Bias programming sequence for OMAP family
  4. *
  5. * (C) Copyright 2013
  6. * Texas Instruments, <www.ti.com>
  7. *
  8. * Andrii Tseglytskyi <andrii.tseglytskyi@ti.com>
  9. *
  10. * See file CREDITS for list of people who contributed to this
  11. * project.
  12. *
  13. * This program is free software; you can redistribute it and/or
  14. * modify it under the terms of the GNU General Public License as
  15. * published by the Free Software Foundation; either version 2 of
  16. * the License, or (at your option) any later version.
  17. *
  18. * This program is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with this program; if not, write to the Free Software
  25. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  26. * MA 02111-1307 USA
  27. */
  28. #include <common.h>
  29. #include <asm/omap_common.h>
  30. #include <asm/io.h>
  31. #include <asm/arch/sys_proto.h>
  32. __weak s8 abb_setup_ldovbb(u32 fuse, u32 ldovbb)
  33. {
  34. return -1;
  35. }
  36. static void abb_setup_timings(u32 setup)
  37. {
  38. u32 sys_rate, sr2_cnt, clk_cycles;
  39. /*
  40. * SR2_WTCNT_VALUE is the settling time for the ABB ldo after a
  41. * transition and must be programmed with the correct time at boot.
  42. * The value programmed into the register is the number of SYS_CLK
  43. * clock cycles that match a given wall time profiled for the ldo.
  44. * This value depends on:
  45. * settling time of ldo in micro-seconds (varies per OMAP family),
  46. * of clock cycles per SYS_CLK period (varies per OMAP family),
  47. * the SYS_CLK frequency in MHz (varies per board)
  48. * The formula is:
  49. *
  50. * ldo settling time (in micro-seconds)
  51. * SR2_WTCNT_VALUE = ------------------------------------------
  52. * (# system clock cycles) * (sys_clk period)
  53. *
  54. * Put another way:
  55. *
  56. * SR2_WTCNT_VALUE = settling time / (# SYS_CLK cycles / SYS_CLK rate))
  57. *
  58. * To avoid dividing by zero multiply both "# clock cycles" and
  59. * "settling time" by 10 such that the final result is the one we want.
  60. */
  61. /* calculate SR2_WTCNT_VALUE */
  62. sys_rate = DIV_ROUND(V_OSCK, 1000000);
  63. clk_cycles = DIV_ROUND(OMAP_ABB_CLOCK_CYCLES * 10, sys_rate);
  64. sr2_cnt = DIV_ROUND(OMAP_ABB_SETTLING_TIME * 10, clk_cycles);
  65. setbits_le32(setup,
  66. sr2_cnt << (ffs(OMAP_ABB_SETUP_SR2_WTCNT_VALUE_MASK) - 1));
  67. }
  68. void abb_setup(u32 fuse, u32 ldovbb, u32 setup, u32 control,
  69. u32 txdone, u32 txdone_mask, u32 opp)
  70. {
  71. u32 abb_type_mask, opp_sel_mask;
  72. /* sanity check */
  73. if (!setup || !control || !txdone)
  74. return;
  75. /* setup ABB only in case of Fast or Slow OPP */
  76. switch (opp) {
  77. case OMAP_ABB_FAST_OPP:
  78. abb_type_mask = OMAP_ABB_SETUP_ACTIVE_FBB_SEL_MASK;
  79. opp_sel_mask = OMAP_ABB_CONTROL_FAST_OPP_SEL_MASK;
  80. break;
  81. case OMAP_ABB_SLOW_OPP:
  82. abb_type_mask = OMAP_ABB_SETUP_ACTIVE_RBB_SEL_MASK;
  83. opp_sel_mask = OMAP_ABB_CONTROL_SLOW_OPP_SEL_MASK;
  84. break;
  85. default:
  86. return;
  87. }
  88. /*
  89. * For some OMAP silicons additional setup for LDOVBB register is
  90. * required. This is determined by data retrieved from corresponding
  91. * OPP EFUSE register. Data, which is retrieved from EFUSE - is
  92. * ABB enable/disable flag and VSET value, which must be copied
  93. * to LDOVBB register. If function call fails - return quietly,
  94. * it means no ABB is required for such silicon.
  95. *
  96. * For silicons, which don't require LDOVBB setup "fuse" and
  97. * "ldovbb" offsets are not defined. ABB will be initialized in
  98. * the common way for them.
  99. */
  100. if (fuse && ldovbb) {
  101. if (abb_setup_ldovbb(fuse, ldovbb))
  102. return;
  103. }
  104. /* clear ABB registers */
  105. writel(0, setup);
  106. writel(0, control);
  107. /* configure timings, based on oscillator value */
  108. abb_setup_timings(setup);
  109. /* clear pending interrupts before setup */
  110. setbits_le32(txdone, txdone_mask);
  111. /* select ABB type */
  112. setbits_le32(setup, abb_type_mask | OMAP_ABB_SETUP_SR2EN_MASK);
  113. /* initiate ABB ldo change */
  114. setbits_le32(control, opp_sel_mask | OMAP_ABB_CONTROL_OPP_CHANGE_MASK);
  115. /* wait until transition complete */
  116. if (!wait_on_value(txdone_mask, txdone_mask, (void *)txdone, LDELAY))
  117. puts("Error: ABB txdone is not set\n");
  118. /* clear ABB tranxdone */
  119. setbits_le32(txdone, txdone_mask);
  120. }