coherency.c 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /*
  2. * Coherency fabric (Aurora) support for Armada 370 and XP platforms.
  3. *
  4. * Copyright (C) 2012 Marvell
  5. *
  6. * Yehuda Yitschak <yehuday@marvell.com>
  7. * Gregory Clement <gregory.clement@free-electrons.com>
  8. * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
  9. *
  10. * This file is licensed under the terms of the GNU General Public
  11. * License version 2. This program is licensed "as is" without any
  12. * warranty of any kind, whether express or implied.
  13. *
  14. * The Armada 370 and Armada XP SOCs have a coherency fabric which is
  15. * responsible for ensuring hardware coherency between all CPUs and between
  16. * CPUs and I/O masters. This file initializes the coherency fabric and
  17. * supplies basic routines for configuring and controlling hardware coherency
  18. */
  19. #include <linux/kernel.h>
  20. #include <linux/init.h>
  21. #include <linux/of_address.h>
  22. #include <linux/io.h>
  23. #include <linux/smp.h>
  24. #include <asm/smp_plat.h>
  25. #include "armada-370-xp.h"
  26. /*
  27. * Some functions in this file are called very early during SMP
  28. * initialization. At that time the device tree framework is not yet
  29. * ready, and it is not possible to get the register address to
  30. * ioremap it. That's why the pointer below is given with an initial
  31. * value matching its virtual mapping
  32. */
  33. static void __iomem *coherency_base = ARMADA_370_XP_REGS_VIRT_BASE + 0x20200;
  34. /* Coherency fabric registers */
  35. #define COHERENCY_FABRIC_CFG_OFFSET 0x4
  36. static struct of_device_id of_coherency_table[] = {
  37. {.compatible = "marvell,coherency-fabric"},
  38. { /* end of list */ },
  39. };
  40. #ifdef CONFIG_SMP
  41. int coherency_get_cpu_count(void)
  42. {
  43. int reg, cnt;
  44. reg = readl(coherency_base + COHERENCY_FABRIC_CFG_OFFSET);
  45. cnt = (reg & 0xF) + 1;
  46. return cnt;
  47. }
  48. #endif
  49. /* Function defined in coherency_ll.S */
  50. int ll_set_cpu_coherent(void __iomem *base_addr, unsigned int hw_cpu_id);
  51. int set_cpu_coherent(unsigned int hw_cpu_id, int smp_group_id)
  52. {
  53. if (!coherency_base) {
  54. pr_warn("Can't make CPU %d cache coherent.\n", hw_cpu_id);
  55. pr_warn("Coherency fabric is not initialized\n");
  56. return 1;
  57. }
  58. return ll_set_cpu_coherent(coherency_base, hw_cpu_id);
  59. }
  60. int __init coherency_init(void)
  61. {
  62. struct device_node *np;
  63. np = of_find_matching_node(NULL, of_coherency_table);
  64. if (np) {
  65. pr_info("Initializing Coherency fabric\n");
  66. coherency_base = of_iomap(np, 0);
  67. }
  68. return 0;
  69. }