l2_cache.c 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /*
  2. * Copyright Altera Corporation (C) 2016. All rights reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms and conditions of the GNU General Public License,
  6. * version 2, as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope it will be useful, but WITHOUT
  9. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  11. * more details.
  12. *
  13. * You should have received a copy of the GNU General Public License along with
  14. * this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include <linux/io.h>
  17. #include <linux/of_platform.h>
  18. #include <linux/of_address.h>
  19. #include "core.h"
  20. /* A10 System Manager L2 ECC Control register */
  21. #define A10_MPU_CTRL_L2_ECC_OFST 0x0
  22. #define A10_MPU_CTRL_L2_ECC_EN BIT(0)
  23. /* A10 System Manager Global IRQ Mask register */
  24. #define A10_SYSMGR_ECC_INTMASK_CLR_OFST 0x98
  25. #define A10_SYSMGR_ECC_INTMASK_CLR_L2 BIT(0)
  26. /* A10 System Manager L2 ECC IRQ Clear register */
  27. #define A10_SYSMGR_MPU_CLEAR_L2_ECC_OFST 0xA8
  28. #define A10_SYSMGR_MPU_CLEAR_L2_ECC (BIT(31) | BIT(15))
  29. void socfpga_init_l2_ecc(void)
  30. {
  31. struct device_node *np;
  32. void __iomem *mapped_l2_edac_addr;
  33. np = of_find_compatible_node(NULL, NULL, "altr,socfpga-l2-ecc");
  34. if (!np) {
  35. pr_err("Unable to find socfpga-l2-ecc in dtb\n");
  36. return;
  37. }
  38. mapped_l2_edac_addr = of_iomap(np, 0);
  39. of_node_put(np);
  40. if (!mapped_l2_edac_addr) {
  41. pr_err("Unable to find L2 ECC mapping in dtb\n");
  42. return;
  43. }
  44. /* Enable ECC */
  45. writel(0x01, mapped_l2_edac_addr);
  46. iounmap(mapped_l2_edac_addr);
  47. }
  48. void socfpga_init_arria10_l2_ecc(void)
  49. {
  50. struct device_node *np;
  51. void __iomem *mapped_l2_edac_addr;
  52. /* Find the L2 EDAC device tree node */
  53. np = of_find_compatible_node(NULL, NULL, "altr,socfpga-a10-l2-ecc");
  54. if (!np) {
  55. pr_err("Unable to find socfpga-a10-l2-ecc in dtb\n");
  56. return;
  57. }
  58. mapped_l2_edac_addr = of_iomap(np, 0);
  59. of_node_put(np);
  60. if (!mapped_l2_edac_addr) {
  61. pr_err("Unable to find L2 ECC mapping in dtb\n");
  62. return;
  63. }
  64. if (!sys_manager_base_addr) {
  65. pr_err("System Manager not mapped for L2 ECC\n");
  66. goto exit;
  67. }
  68. /* Clear any pending IRQs */
  69. writel(A10_SYSMGR_MPU_CLEAR_L2_ECC, (sys_manager_base_addr +
  70. A10_SYSMGR_MPU_CLEAR_L2_ECC_OFST));
  71. /* Enable ECC */
  72. writel(A10_SYSMGR_ECC_INTMASK_CLR_L2, sys_manager_base_addr +
  73. A10_SYSMGR_ECC_INTMASK_CLR_OFST);
  74. writel(A10_MPU_CTRL_L2_ECC_EN, mapped_l2_edac_addr +
  75. A10_MPU_CTRL_L2_ECC_OFST);
  76. exit:
  77. iounmap(mapped_l2_edac_addr);
  78. }