biuctrl.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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. #define CPU_CREDIT_REG_OFFSET 0x184
  21. #define CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK 0x70000000
  22. static void __iomem *cpubiuctrl_base;
  23. static bool mcp_wr_pairing_en;
  24. static int __init mcp_write_pairing_set(void)
  25. {
  26. u32 creds = 0;
  27. if (!cpubiuctrl_base)
  28. return -1;
  29. creds = readl_relaxed(cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
  30. if (mcp_wr_pairing_en) {
  31. pr_info("MCP: Enabling write pairing\n");
  32. writel_relaxed(creds | CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK,
  33. cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
  34. } else if (creds & CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK) {
  35. pr_info("MCP: Disabling write pairing\n");
  36. writel_relaxed(creds & ~CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK,
  37. cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
  38. } else {
  39. pr_info("MCP: Write pairing already disabled\n");
  40. }
  41. return 0;
  42. }
  43. static int __init setup_hifcpubiuctrl_regs(void)
  44. {
  45. struct device_node *np;
  46. int ret = 0;
  47. np = of_find_compatible_node(NULL, NULL, "brcm,brcmstb-cpu-biu-ctrl");
  48. if (!np) {
  49. pr_err("missing BIU control node\n");
  50. return -ENODEV;
  51. }
  52. cpubiuctrl_base = of_iomap(np, 0);
  53. if (!cpubiuctrl_base) {
  54. pr_err("failed to remap BIU control base\n");
  55. ret = -ENOMEM;
  56. goto out;
  57. }
  58. mcp_wr_pairing_en = of_property_read_bool(np, "brcm,write-pairing");
  59. out:
  60. of_node_put(np);
  61. return ret;
  62. }
  63. #ifdef CONFIG_PM_SLEEP
  64. static u32 cpu_credit_reg_dump; /* for save/restore */
  65. static int brcmstb_cpu_credit_reg_suspend(void)
  66. {
  67. if (cpubiuctrl_base)
  68. cpu_credit_reg_dump =
  69. readl_relaxed(cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
  70. return 0;
  71. }
  72. static void brcmstb_cpu_credit_reg_resume(void)
  73. {
  74. if (cpubiuctrl_base)
  75. writel_relaxed(cpu_credit_reg_dump,
  76. cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
  77. }
  78. static struct syscore_ops brcmstb_cpu_credit_syscore_ops = {
  79. .suspend = brcmstb_cpu_credit_reg_suspend,
  80. .resume = brcmstb_cpu_credit_reg_resume,
  81. };
  82. #endif
  83. void __init brcmstb_biuctrl_init(void)
  84. {
  85. int ret;
  86. setup_hifcpubiuctrl_regs();
  87. ret = mcp_write_pairing_set();
  88. if (ret) {
  89. pr_err("MCP: Unable to disable write pairing!\n");
  90. return;
  91. }
  92. #ifdef CONFIG_PM_SLEEP
  93. register_syscore_ops(&brcmstb_cpu_credit_syscore_ops);
  94. #endif
  95. }