clk-mmc-phase.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*
  2. * Copyright 2014 Google, Inc
  3. * Author: Alexandru M Stan <amstan@chromium.org>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. */
  15. #include <linux/slab.h>
  16. #include <linux/clk-provider.h>
  17. #include "clk.h"
  18. struct rockchip_mmc_clock {
  19. struct clk_hw hw;
  20. void __iomem *reg;
  21. int id;
  22. int shift;
  23. };
  24. #define to_mmc_clock(_hw) container_of(_hw, struct rockchip_mmc_clock, hw)
  25. #define RK3288_MMC_CLKGEN_DIV 2
  26. static unsigned long rockchip_mmc_recalc(struct clk_hw *hw,
  27. unsigned long parent_rate)
  28. {
  29. return parent_rate / RK3288_MMC_CLKGEN_DIV;
  30. }
  31. #define ROCKCHIP_MMC_DELAY_SEL BIT(10)
  32. #define ROCKCHIP_MMC_DEGREE_MASK 0x3
  33. #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2
  34. #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
  35. #define PSECS_PER_SEC 1000000000000LL
  36. /*
  37. * Each fine delay is between 40ps-80ps. Assume each fine delay is 60ps to
  38. * simplify calculations. So 45degs could be anywhere between 33deg and 66deg.
  39. */
  40. #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
  41. static int rockchip_mmc_get_phase(struct clk_hw *hw)
  42. {
  43. struct rockchip_mmc_clock *mmc_clock = to_mmc_clock(hw);
  44. unsigned long rate = clk_get_rate(hw->clk);
  45. u32 raw_value;
  46. u16 degrees;
  47. u32 delay_num = 0;
  48. raw_value = readl(mmc_clock->reg) >> (mmc_clock->shift);
  49. degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
  50. if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
  51. /* degrees/delaynum * 10000 */
  52. unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
  53. 36 * (rate / 1000000);
  54. delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
  55. delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
  56. degrees += delay_num * factor / 10000;
  57. }
  58. return degrees % 360;
  59. }
  60. static int rockchip_mmc_set_phase(struct clk_hw *hw, int degrees)
  61. {
  62. struct rockchip_mmc_clock *mmc_clock = to_mmc_clock(hw);
  63. unsigned long rate = clk_get_rate(hw->clk);
  64. u8 nineties, remainder;
  65. u8 delay_num;
  66. u32 raw_value;
  67. u64 delay;
  68. /* allow 22 to be 22.5 */
  69. degrees++;
  70. /* floor to 22.5 increment */
  71. degrees -= ((degrees) * 10 % 225) / 10;
  72. nineties = degrees / 90;
  73. /* 22.5 multiples */
  74. remainder = (degrees % 90) / 22;
  75. delay = PSECS_PER_SEC;
  76. do_div(delay, rate);
  77. /* / 360 / 22.5 */
  78. do_div(delay, 16);
  79. do_div(delay, ROCKCHIP_MMC_DELAY_ELEMENT_PSEC);
  80. delay *= remainder;
  81. delay_num = (u8) min(delay, 255ULL);
  82. raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
  83. raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
  84. raw_value |= nineties;
  85. writel(HIWORD_UPDATE(raw_value, 0x07ff, mmc_clock->shift), mmc_clock->reg);
  86. pr_debug("%s->set_phase(%d) delay_nums=%u reg[0x%p]=0x%03x actual_degrees=%d\n",
  87. __clk_get_name(hw->clk), degrees, delay_num,
  88. mmc_clock->reg, raw_value>>(mmc_clock->shift),
  89. rockchip_mmc_get_phase(hw)
  90. );
  91. return 0;
  92. }
  93. static const struct clk_ops rockchip_mmc_clk_ops = {
  94. .recalc_rate = rockchip_mmc_recalc,
  95. .get_phase = rockchip_mmc_get_phase,
  96. .set_phase = rockchip_mmc_set_phase,
  97. };
  98. struct clk *rockchip_clk_register_mmc(const char *name,
  99. const char **parent_names, u8 num_parents,
  100. void __iomem *reg, int shift)
  101. {
  102. struct clk_init_data init;
  103. struct rockchip_mmc_clock *mmc_clock;
  104. struct clk *clk;
  105. mmc_clock = kmalloc(sizeof(*mmc_clock), GFP_KERNEL);
  106. if (!mmc_clock)
  107. return NULL;
  108. init.num_parents = num_parents;
  109. init.parent_names = parent_names;
  110. init.ops = &rockchip_mmc_clk_ops;
  111. mmc_clock->hw.init = &init;
  112. mmc_clock->reg = reg;
  113. mmc_clock->shift = shift;
  114. if (name)
  115. init.name = name;
  116. clk = clk_register(NULL, &mmc_clock->hw);
  117. if (IS_ERR(clk))
  118. goto err_free;
  119. return clk;
  120. err_free:
  121. kfree(mmc_clock);
  122. return NULL;
  123. }