clkt_iclk.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /*
  2. * OMAP2/3 interface clock control
  3. *
  4. * Copyright (C) 2011 Nokia Corporation
  5. * Paul Walmsley
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 as
  9. * published by the Free Software Foundation.
  10. */
  11. #undef DEBUG
  12. #include <linux/kernel.h>
  13. #include <linux/clk-provider.h>
  14. #include <linux/io.h>
  15. #include <linux/clk/ti.h>
  16. #include "clock.h"
  17. /* Register offsets */
  18. #define OMAP24XX_CM_FCLKEN2 0x04
  19. #define CM_AUTOIDLE 0x30
  20. #define CM_ICLKEN 0x10
  21. #define CM_IDLEST 0x20
  22. #define OMAP24XX_CM_IDLEST_VAL 0
  23. /* Private functions */
  24. /* XXX */
  25. void omap2_clkt_iclk_allow_idle(struct clk_hw_omap *clk)
  26. {
  27. u32 v;
  28. void __iomem *r;
  29. r = (__force void __iomem *)
  30. ((__force u32)clk->enable_reg ^ (CM_AUTOIDLE ^ CM_ICLKEN));
  31. v = ti_clk_ll_ops->clk_readl(r);
  32. v |= (1 << clk->enable_bit);
  33. ti_clk_ll_ops->clk_writel(v, r);
  34. }
  35. /* XXX */
  36. void omap2_clkt_iclk_deny_idle(struct clk_hw_omap *clk)
  37. {
  38. u32 v;
  39. void __iomem *r;
  40. r = (__force void __iomem *)
  41. ((__force u32)clk->enable_reg ^ (CM_AUTOIDLE ^ CM_ICLKEN));
  42. v = ti_clk_ll_ops->clk_readl(r);
  43. v &= ~(1 << clk->enable_bit);
  44. ti_clk_ll_ops->clk_writel(v, r);
  45. }
  46. /**
  47. * omap2430_clk_i2chs_find_idlest - return CM_IDLEST info for 2430 I2CHS
  48. * @clk: struct clk * being enabled
  49. * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
  50. * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
  51. * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
  52. *
  53. * OMAP2430 I2CHS CM_IDLEST bits are in CM_IDLEST1_CORE, but the
  54. * CM_*CLKEN bits are in CM_{I,F}CLKEN2_CORE. This custom function
  55. * passes back the correct CM_IDLEST register address for I2CHS
  56. * modules. No return value.
  57. */
  58. static void omap2430_clk_i2chs_find_idlest(struct clk_hw_omap *clk,
  59. void __iomem **idlest_reg,
  60. u8 *idlest_bit,
  61. u8 *idlest_val)
  62. {
  63. u32 r;
  64. r = ((__force u32)clk->enable_reg ^ (OMAP24XX_CM_FCLKEN2 ^ CM_IDLEST));
  65. *idlest_reg = (__force void __iomem *)r;
  66. *idlest_bit = clk->enable_bit;
  67. *idlest_val = OMAP24XX_CM_IDLEST_VAL;
  68. }
  69. /* Public data */
  70. const struct clk_hw_omap_ops clkhwops_iclk = {
  71. .allow_idle = omap2_clkt_iclk_allow_idle,
  72. .deny_idle = omap2_clkt_iclk_deny_idle,
  73. };
  74. const struct clk_hw_omap_ops clkhwops_iclk_wait = {
  75. .allow_idle = omap2_clkt_iclk_allow_idle,
  76. .deny_idle = omap2_clkt_iclk_deny_idle,
  77. .find_idlest = omap2_clk_dflt_find_idlest,
  78. .find_companion = omap2_clk_dflt_find_companion,
  79. };
  80. /* 2430 I2CHS has non-standard IDLEST register */
  81. const struct clk_hw_omap_ops clkhwops_omap2430_i2chs_wait = {
  82. .find_idlest = omap2430_clk_i2chs_find_idlest,
  83. .find_companion = omap2_clk_dflt_find_companion,
  84. };