045-clk-iproc-Add-PWRCTRL-support.patch 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. From 7c70cb333deb6e2f88da9c94ddd6b3b00c97b93a Mon Sep 17 00:00:00 2001
  2. From: Jon Mason <jonmason@broadcom.com>
  3. Date: Thu, 15 Oct 2015 15:48:26 -0400
  4. Subject: [PATCH 45/50] clk: iproc: Add PWRCTRL support
  5. Some iProc SoC clocks use a different way to control clock power, via
  6. the PWRDWN bit in the PLL control register. Since the PLL control
  7. register is used to access the PWRDWN bit, there is no need for the
  8. pwr_base when this is being used. A new flag, IPROC_CLK_EMBED_PWRCTRL,
  9. has been added to identify this usage. We can use the AON interface to
  10. write the values to enable/disable PWRDOWN.
  11. Signed-off-by: Jon Mason <jonmason@broadcom.com>
  12. ---
  13. drivers/clk/bcm/clk-iproc-pll.c | 55 ++++++++++++++++++++++++++++-------------
  14. drivers/clk/bcm/clk-iproc.h | 6 +++++
  15. 2 files changed, 44 insertions(+), 17 deletions(-)
  16. --- a/drivers/clk/bcm/clk-iproc-pll.c
  17. +++ b/drivers/clk/bcm/clk-iproc-pll.c
  18. @@ -148,14 +148,25 @@ static void __pll_disable(struct iproc_p
  19. writel(val, pll->asiu_base + ctrl->asiu.offset);
  20. }
  21. - /* latch input value so core power can be shut down */
  22. - val = readl(pll->pwr_base + ctrl->aon.offset);
  23. - val |= (1 << ctrl->aon.iso_shift);
  24. - writel(val, pll->pwr_base + ctrl->aon.offset);
  25. -
  26. - /* power down the core */
  27. - val &= ~(bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift);
  28. - writel(val, pll->pwr_base + ctrl->aon.offset);
  29. + if (ctrl->flags & IPROC_CLK_EMBED_PWRCTRL) {
  30. + val = readl(pll->pll_base + ctrl->aon.offset);
  31. + val |= (bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift);
  32. + writel(val, pll->pll_base + ctrl->aon.offset);
  33. +
  34. + if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK))
  35. + readl(pll->pll_base + ctrl->aon.offset);
  36. + }
  37. +
  38. + if (pll->pwr_base) {
  39. + /* latch input value so core power can be shut down */
  40. + val = readl(pll->pwr_base + ctrl->aon.offset);
  41. + val |= (1 << ctrl->aon.iso_shift);
  42. + writel(val, pll->pwr_base + ctrl->aon.offset);
  43. +
  44. + /* power down the core */
  45. + val &= ~(bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift);
  46. + writel(val, pll->pwr_base + ctrl->aon.offset);
  47. + }
  48. }
  49. static int __pll_enable(struct iproc_pll *pll)
  50. @@ -163,11 +174,22 @@ static int __pll_enable(struct iproc_pll
  51. const struct iproc_pll_ctrl *ctrl = pll->ctrl;
  52. u32 val;
  53. - /* power up the PLL and make sure it's not latched */
  54. - val = readl(pll->pwr_base + ctrl->aon.offset);
  55. - val |= bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift;
  56. - val &= ~(1 << ctrl->aon.iso_shift);
  57. - writel(val, pll->pwr_base + ctrl->aon.offset);
  58. + if (ctrl->flags & IPROC_CLK_EMBED_PWRCTRL) {
  59. + val = readl(pll->pll_base + ctrl->aon.offset);
  60. + val &= ~(bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift);
  61. + writel(val, pll->pll_base + ctrl->aon.offset);
  62. +
  63. + if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK))
  64. + readl(pll->pll_base + ctrl->aon.offset);
  65. + }
  66. +
  67. + if (pll->pwr_base) {
  68. + /* power up the PLL and make sure it's not latched */
  69. + val = readl(pll->pwr_base + ctrl->aon.offset);
  70. + val |= bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift;
  71. + val &= ~(1 << ctrl->aon.iso_shift);
  72. + writel(val, pll->pwr_base + ctrl->aon.offset);
  73. + }
  74. /* certain PLLs also need to be ungated from the ASIU top level */
  75. if (ctrl->flags & IPROC_CLK_PLL_ASIU) {
  76. @@ -607,9 +629,8 @@ void __init iproc_pll_clk_setup(struct d
  77. if (WARN_ON(!pll->pll_base))
  78. goto err_pll_iomap;
  79. + /* Some SoCs do not require the pwr_base, thus failing is not fatal */
  80. pll->pwr_base = of_iomap(node, 1);
  81. - if (WARN_ON(!pll->pwr_base))
  82. - goto err_pwr_iomap;
  83. /* some PLLs require gating control at the top ASIU level */
  84. if (pll_ctrl->flags & IPROC_CLK_PLL_ASIU) {
  85. @@ -692,9 +713,9 @@ err_pll_register:
  86. iounmap(pll->asiu_base);
  87. err_asiu_iomap:
  88. - iounmap(pll->pwr_base);
  89. + if (pll->pwr_base)
  90. + iounmap(pll->pwr_base);
  91. -err_pwr_iomap:
  92. iounmap(pll->pll_base);
  93. err_pll_iomap:
  94. --- a/drivers/clk/bcm/clk-iproc.h
  95. +++ b/drivers/clk/bcm/clk-iproc.h
  96. @@ -49,6 +49,12 @@
  97. #define IPROC_CLK_PLL_NEEDS_SW_CFG BIT(4)
  98. /*
  99. + * Some PLLs use a different way to control clock power, via the PWRDWN bit in
  100. + * the PLL control register
  101. + */
  102. +#define IPROC_CLK_EMBED_PWRCTRL BIT(5)
  103. +
  104. +/*
  105. * Parameters for VCO frequency configuration
  106. *
  107. * VCO frequency =