biuctrl.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*
  2. * Broadcom STB SoCs Bus Unit Interface controls
  3. *
  4. * Copyright (C) 2015, Broadcom Corporation
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. */
  15. #define pr_fmt(fmt) "brcmstb: " KBUILD_MODNAME ": " fmt
  16. #include <linux/kernel.h>
  17. #include <linux/io.h>
  18. #include <linux/of_address.h>
  19. #include <linux/syscore_ops.h>
  20. #include <linux/soc/brcmstb/brcmstb.h>
  21. #define CPU_CREDIT_REG_OFFSET 0x184
  22. #define CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK 0x70000000
  23. static void __iomem *cpubiuctrl_base;
  24. static bool mcp_wr_pairing_en;
  25. static int __init mcp_write_pairing_set(void)
  26. {
  27. u32 creds = 0;
  28. if (!cpubiuctrl_base)
  29. return -1;
  30. creds = readl_relaxed(cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
  31. if (mcp_wr_pairing_en) {
  32. pr_info("MCP: Enabling write pairing\n");
  33. writel_relaxed(creds | CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK,
  34. cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
  35. } else if (creds & CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK) {
  36. pr_info("MCP: Disabling write pairing\n");
  37. writel_relaxed(creds & ~CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK,
  38. cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
  39. } else {
  40. pr_info("MCP: Write pairing already disabled\n");
  41. }
  42. return 0;
  43. }
  44. static int __init setup_hifcpubiuctrl_regs(void)
  45. {
  46. struct device_node *np;
  47. int ret = 0;
  48. np = of_find_compatible_node(NULL, NULL, "brcm,brcmstb-cpu-biu-ctrl");
  49. if (!np) {
  50. pr_err("missing BIU control node\n");
  51. return -ENODEV;
  52. }
  53. cpubiuctrl_base = of_iomap(np, 0);
  54. if (!cpubiuctrl_base) {
  55. pr_err("failed to remap BIU control base\n");
  56. ret = -ENOMEM;
  57. goto out;
  58. }
  59. mcp_wr_pairing_en = of_property_read_bool(np, "brcm,write-pairing");
  60. out:
  61. of_node_put(np);
  62. return ret;
  63. }
  64. #ifdef CONFIG_PM_SLEEP
  65. static u32 cpu_credit_reg_dump; /* for save/restore */
  66. static int brcmstb_cpu_credit_reg_suspend(void)
  67. {
  68. if (cpubiuctrl_base)
  69. cpu_credit_reg_dump =
  70. readl_relaxed(cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
  71. return 0;
  72. }
  73. static void brcmstb_cpu_credit_reg_resume(void)
  74. {
  75. if (cpubiuctrl_base)
  76. writel_relaxed(cpu_credit_reg_dump,
  77. cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
  78. }
  79. static struct syscore_ops brcmstb_cpu_credit_syscore_ops = {
  80. .suspend = brcmstb_cpu_credit_reg_suspend,
  81. .resume = brcmstb_cpu_credit_reg_resume,
  82. };
  83. #endif
  84. void __init brcmstb_biuctrl_init(void)
  85. {
  86. int ret;
  87. setup_hifcpubiuctrl_regs();
  88. ret = mcp_write_pairing_set();
  89. if (ret) {
  90. pr_err("MCP: Unable to disable write pairing!\n");
  91. return;
  92. }
  93. #ifdef CONFIG_PM_SLEEP
  94. register_syscore_ops(&brcmstb_cpu_credit_syscore_ops);
  95. #endif
  96. }