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