0431-clk-bcm2835-Mark-the-CM-SDRAM-clock-s-parent-as-crit.patch 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. From 3dbdbeedb865d12700dae53b59e259ea083e6186 Mon Sep 17 00:00:00 2001
  2. From: Eric Anholt <eric@anholt.net>
  3. Date: Wed, 1 Jun 2016 12:05:35 -0700
  4. Subject: [PATCH] clk: bcm2835: Mark the CM SDRAM clock's parent as critical
  5. While the SDRAM is being driven by its dedicated PLL most of the time,
  6. there is a little loop running in the firmware that periodically turns
  7. on the CM SDRAM clock (using its pre-initialized parent) and switches
  8. SDRAM to using the CM clock to do PVT recalibration.
  9. This avoids system hangs if we choose SDRAM's parent for some other
  10. clock, then disable that clock.
  11. Signed-off-by: Eric Anholt <eric@anholt.net>
  12. ---
  13. drivers/clk/bcm/clk-bcm2835.c | 25 +++++++++++++++++++++++++
  14. 1 file changed, 25 insertions(+)
  15. --- a/drivers/clk/bcm/clk-bcm2835.c
  16. +++ b/drivers/clk/bcm/clk-bcm2835.c
  17. @@ -36,6 +36,7 @@
  18. #include <linux/clk-provider.h>
  19. #include <linux/clkdev.h>
  20. +#include <linux/clk.h>
  21. #include <linux/clk/bcm2835.h>
  22. #include <linux/debugfs.h>
  23. #include <linux/module.h>
  24. @@ -1847,6 +1848,25 @@ static const struct bcm2835_clk_desc clk
  25. .ctl_reg = CM_PERIICTL),
  26. };
  27. +/*
  28. + * Permanently take a reference on the parent of the SDRAM clock.
  29. + *
  30. + * While the SDRAM is being driven by its dedicated PLL most of the
  31. + * time, there is a little loop running in the firmware that
  32. + * periodically switches the SDRAM to using our CM clock to do PVT
  33. + * recalibration, with the assumption that the previously configured
  34. + * SDRAM parent is still enabled and running.
  35. + */
  36. +static int bcm2835_mark_sdc_parent_critical(struct clk *sdc)
  37. +{
  38. + struct clk *parent = clk_get_parent(sdc);
  39. +
  40. + if (IS_ERR(parent))
  41. + return PTR_ERR(parent);
  42. +
  43. + return clk_prepare_enable(parent);
  44. +}
  45. +
  46. static int bcm2835_clk_probe(struct platform_device *pdev)
  47. {
  48. struct device *dev = &pdev->dev;
  49. @@ -1856,6 +1876,7 @@ static int bcm2835_clk_probe(struct plat
  50. const struct bcm2835_clk_desc *desc;
  51. const size_t asize = ARRAY_SIZE(clk_desc_array);
  52. size_t i;
  53. + int ret;
  54. cprman = devm_kzalloc(dev,
  55. sizeof(*cprman) + asize * sizeof(*clks),
  56. @@ -1886,6 +1907,10 @@ static int bcm2835_clk_probe(struct plat
  57. clks[i] = desc->clk_register(cprman, desc->data);
  58. }
  59. + ret = bcm2835_mark_sdc_parent_critical(clks[BCM2835_CLOCK_SDRAM]);
  60. + if (ret)
  61. + return ret;
  62. +
  63. return of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
  64. &cprman->onecell);
  65. }