summaryrefslogtreecommitdiffstats
path: root/drivers/soc
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2018-01-05 01:31:02 -0500
committerOlof Johansson <olof@lixom.net>2018-01-05 01:31:02 -0500
commit7e32c6054e6bb18126f2cc4835a891649bd1b723 (patch)
tree6f72e6736068834e6e2525a3adb1c235a1142470 /drivers/soc
parentf681e08f671a8e68b085ba66190b8661deab4d85 (diff)
parentf780429adfbc222a4d8a227a2a550ba627c7338b (diff)
Merge tag 'arm-soc/for-4.16/drivers' of http://github.com/Broadcom/stblinux into next/drivers
This pull request contains Broadcom ARM/ARM64 based SoCs drivers changes for 4.16, please pull the following: - Arnd provides an update to the Raspberry Pi firmware interface and uses time64_t to print the time to make it more future proof - Florian provides a set of updates to make the Broadcom STB Bus Interface Unit code work on newer ARM64-based chips, as well as perform the correct interface tuning for these chips to reach the expected performance * tag 'arm-soc/for-4.16/drivers' of http://github.com/Broadcom/stblinux: soc: brcmstb: biuctrl: Move to early_initcall soc: brcmstb: Split initialization soc: brcmstb: biuctrl: Fine tune B53 MCP interface settings soc: brcmstb: biuctrl: Wire-up new registers soc: brcmstb: biuctrl: Prepare for saving/restoring other registers soc: brcmstb: Correct CPU_CREDIT_REG offset for Brahma-B53 CPUs soc: brcmstb: Make CPU credit offset more parameterized dt-bindings: arm: brcmstb: Correct BIUCTRL node documentation dt-bindings: arm: Add entry for Broadcom Brahma-B53 firmware: raspberrypi: print time using time64_t Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'drivers/soc')
-rw-r--r--drivers/soc/bcm/brcmstb/biuctrl.c176
-rw-r--r--drivers/soc/bcm/brcmstb/common.c27
2 files changed, 173 insertions, 30 deletions
diff --git a/drivers/soc/bcm/brcmstb/biuctrl.c b/drivers/soc/bcm/brcmstb/biuctrl.c
index 3c39415d484f..2b23ae7b5e9b 100644
--- a/drivers/soc/bcm/brcmstb/biuctrl.c
+++ b/drivers/soc/bcm/brcmstb/biuctrl.c
@@ -21,11 +21,70 @@
21#include <linux/syscore_ops.h> 21#include <linux/syscore_ops.h>
22#include <linux/soc/brcmstb/brcmstb.h> 22#include <linux/soc/brcmstb/brcmstb.h>
23 23
24#define CPU_CREDIT_REG_OFFSET 0x184
25#define CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK 0x70000000 24#define CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK 0x70000000
25#define CPU_CREDIT_REG_MCPx_READ_CRED_MASK 0xf
26#define CPU_CREDIT_REG_MCPx_WRITE_CRED_MASK 0xf
27#define CPU_CREDIT_REG_MCPx_READ_CRED_SHIFT(x) ((x) * 8)
28#define CPU_CREDIT_REG_MCPx_WRITE_CRED_SHIFT(x) (((x) * 8) + 4)
29
30#define CPU_MCP_FLOW_REG_MCPx_RDBUFF_CRED_SHIFT(x) ((x) * 8)
31#define CPU_MCP_FLOW_REG_MCPx_RDBUFF_CRED_MASK 0xff
32
33#define CPU_WRITEBACK_CTRL_REG_WB_THROTTLE_THRESHOLD_MASK 0xf
34#define CPU_WRITEBACK_CTRL_REG_WB_THROTTLE_TIMEOUT_MASK 0xf
35#define CPU_WRITEBACK_CTRL_REG_WB_THROTTLE_TIMEOUT_SHIFT 4
36#define CPU_WRITEBACK_CTRL_REG_WB_THROTTLE_ENABLE BIT(8)
26 37
27static void __iomem *cpubiuctrl_base; 38static void __iomem *cpubiuctrl_base;
28static bool mcp_wr_pairing_en; 39static bool mcp_wr_pairing_en;
40static const int *cpubiuctrl_regs;
41
42static inline u32 cbc_readl(int reg)
43{
44 int offset = cpubiuctrl_regs[reg];
45
46 if (offset == -1)
47 return (u32)-1;
48
49 return readl_relaxed(cpubiuctrl_base + offset);
50}
51
52static inline void cbc_writel(u32 val, int reg)
53{
54 int offset = cpubiuctrl_regs[reg];
55
56 if (offset == -1)
57 return;
58
59 writel_relaxed(val, cpubiuctrl_base + offset);
60}
61
62enum cpubiuctrl_regs {
63 CPU_CREDIT_REG = 0,
64 CPU_MCP_FLOW_REG,
65 CPU_WRITEBACK_CTRL_REG
66};
67
68static const int b15_cpubiuctrl_regs[] = {
69 [CPU_CREDIT_REG] = 0x184,
70 [CPU_MCP_FLOW_REG] = -1,
71 [CPU_WRITEBACK_CTRL_REG] = -1,
72};
73
74/* Odd cases, e.g: 7260 */
75static const int b53_cpubiuctrl_no_wb_regs[] = {
76 [CPU_CREDIT_REG] = 0x0b0,
77 [CPU_MCP_FLOW_REG] = 0x0b4,
78 [CPU_WRITEBACK_CTRL_REG] = -1,
79};
80
81static const int b53_cpubiuctrl_regs[] = {
82 [CPU_CREDIT_REG] = 0x0b0,
83 [CPU_MCP_FLOW_REG] = 0x0b4,
84 [CPU_WRITEBACK_CTRL_REG] = 0x22c,
85};
86
87#define NUM_CPU_BIUCTRL_REGS 3
29 88
30static int __init mcp_write_pairing_set(void) 89static int __init mcp_write_pairing_set(void)
31{ 90{
@@ -34,15 +93,15 @@ static int __init mcp_write_pairing_set(void)
34 if (!cpubiuctrl_base) 93 if (!cpubiuctrl_base)
35 return -1; 94 return -1;
36 95
37 creds = readl_relaxed(cpubiuctrl_base + CPU_CREDIT_REG_OFFSET); 96 creds = cbc_readl(CPU_CREDIT_REG);
38 if (mcp_wr_pairing_en) { 97 if (mcp_wr_pairing_en) {
39 pr_info("MCP: Enabling write pairing\n"); 98 pr_info("MCP: Enabling write pairing\n");
40 writel_relaxed(creds | CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK, 99 cbc_writel(creds | CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK,
41 cpubiuctrl_base + CPU_CREDIT_REG_OFFSET); 100 CPU_CREDIT_REG);
42 } else if (creds & CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK) { 101 } else if (creds & CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK) {
43 pr_info("MCP: Disabling write pairing\n"); 102 pr_info("MCP: Disabling write pairing\n");
44 writel_relaxed(creds & ~CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK, 103 cbc_writel(creds & ~CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK,
45 cpubiuctrl_base + CPU_CREDIT_REG_OFFSET); 104 CPU_CREDIT_REG);
46 } else { 105 } else {
47 pr_info("MCP: Write pairing already disabled\n"); 106 pr_info("MCP: Write pairing already disabled\n");
48 } 107 }
@@ -50,9 +109,62 @@ static int __init mcp_write_pairing_set(void)
50 return 0; 109 return 0;
51} 110}
52 111
112static const u32 b53_mach_compat[] = {
113 0x7268,
114 0x7271,
115 0x7278,
116};
117
118static void __init mcp_b53_set(void)
119{
120 unsigned int i;
121 u32 reg;
122
123 reg = brcmstb_get_family_id();
124
125 for (i = 0; i < ARRAY_SIZE(b53_mach_compat); i++) {
126 if (BRCM_ID(reg) == b53_mach_compat[i])
127 break;
128 }
129
130 if (i == ARRAY_SIZE(b53_mach_compat))
131 return;
132
133 /* Set all 3 MCP interfaces to 8 credits */
134 reg = cbc_readl(CPU_CREDIT_REG);
135 for (i = 0; i < 3; i++) {
136 reg &= ~(CPU_CREDIT_REG_MCPx_WRITE_CRED_MASK <<
137 CPU_CREDIT_REG_MCPx_WRITE_CRED_SHIFT(i));
138 reg &= ~(CPU_CREDIT_REG_MCPx_READ_CRED_MASK <<
139 CPU_CREDIT_REG_MCPx_READ_CRED_SHIFT(i));
140 reg |= 8 << CPU_CREDIT_REG_MCPx_WRITE_CRED_SHIFT(i);
141 reg |= 8 << CPU_CREDIT_REG_MCPx_READ_CRED_SHIFT(i);
142 }
143 cbc_writel(reg, CPU_CREDIT_REG);
144
145 /* Max out the number of in-flight Jwords reads on the MCP interface */
146 reg = cbc_readl(CPU_MCP_FLOW_REG);
147 for (i = 0; i < 3; i++)
148 reg |= CPU_MCP_FLOW_REG_MCPx_RDBUFF_CRED_MASK <<
149 CPU_MCP_FLOW_REG_MCPx_RDBUFF_CRED_SHIFT(i);
150 cbc_writel(reg, CPU_MCP_FLOW_REG);
151
152 /* Enable writeback throttling, set timeout to 128 cycles, 256 cycles
153 * threshold
154 */
155 reg = cbc_readl(CPU_WRITEBACK_CTRL_REG);
156 reg |= CPU_WRITEBACK_CTRL_REG_WB_THROTTLE_ENABLE;
157 reg &= ~CPU_WRITEBACK_CTRL_REG_WB_THROTTLE_THRESHOLD_MASK;
158 reg &= ~(CPU_WRITEBACK_CTRL_REG_WB_THROTTLE_TIMEOUT_MASK <<
159 CPU_WRITEBACK_CTRL_REG_WB_THROTTLE_TIMEOUT_SHIFT);
160 reg |= 8;
161 reg |= 7 << CPU_WRITEBACK_CTRL_REG_WB_THROTTLE_TIMEOUT_SHIFT;
162 cbc_writel(reg, CPU_WRITEBACK_CTRL_REG);
163}
164
53static int __init setup_hifcpubiuctrl_regs(void) 165static int __init setup_hifcpubiuctrl_regs(void)
54{ 166{
55 struct device_node *np; 167 struct device_node *np, *cpu_dn;
56 int ret = 0; 168 int ret = 0;
57 169
58 np = of_find_compatible_node(NULL, NULL, "brcm,brcmstb-cpu-biu-ctrl"); 170 np = of_find_compatible_node(NULL, NULL, "brcm,brcmstb-cpu-biu-ctrl");
@@ -69,27 +181,56 @@ static int __init setup_hifcpubiuctrl_regs(void)
69 } 181 }
70 182
71 mcp_wr_pairing_en = of_property_read_bool(np, "brcm,write-pairing"); 183 mcp_wr_pairing_en = of_property_read_bool(np, "brcm,write-pairing");
184
185 cpu_dn = of_get_cpu_node(0, NULL);
186 if (!cpu_dn) {
187 pr_err("failed to obtain CPU device node\n");
188 ret = -ENODEV;
189 goto out;
190 }
191
192 if (of_device_is_compatible(cpu_dn, "brcm,brahma-b15"))
193 cpubiuctrl_regs = b15_cpubiuctrl_regs;
194 else if (of_device_is_compatible(cpu_dn, "brcm,brahma-b53"))
195 cpubiuctrl_regs = b53_cpubiuctrl_regs;
196 else {
197 pr_err("unsupported CPU\n");
198 ret = -EINVAL;
199 }
200 of_node_put(cpu_dn);
201
202 if (BRCM_ID(brcmstb_get_family_id()) == 0x7260)
203 cpubiuctrl_regs = b53_cpubiuctrl_no_wb_regs;
72out: 204out:
73 of_node_put(np); 205 of_node_put(np);
74 return ret; 206 return ret;
75} 207}
76 208
77#ifdef CONFIG_PM_SLEEP 209#ifdef CONFIG_PM_SLEEP
78static u32 cpu_credit_reg_dump; /* for save/restore */ 210static u32 cpubiuctrl_reg_save[NUM_CPU_BIUCTRL_REGS];
79 211
80static int brcmstb_cpu_credit_reg_suspend(void) 212static int brcmstb_cpu_credit_reg_suspend(void)
81{ 213{
82 if (cpubiuctrl_base) 214 unsigned int i;
83 cpu_credit_reg_dump = 215
84 readl_relaxed(cpubiuctrl_base + CPU_CREDIT_REG_OFFSET); 216 if (!cpubiuctrl_base)
217 return 0;
218
219 for (i = 0; i < NUM_CPU_BIUCTRL_REGS; i++)
220 cpubiuctrl_reg_save[i] = cbc_readl(i);
221
85 return 0; 222 return 0;
86} 223}
87 224
88static void brcmstb_cpu_credit_reg_resume(void) 225static void brcmstb_cpu_credit_reg_resume(void)
89{ 226{
90 if (cpubiuctrl_base) 227 unsigned int i;
91 writel_relaxed(cpu_credit_reg_dump, 228
92 cpubiuctrl_base + CPU_CREDIT_REG_OFFSET); 229 if (!cpubiuctrl_base)
230 return;
231
232 for (i = 0; i < NUM_CPU_BIUCTRL_REGS; i++)
233 cbc_writel(cpubiuctrl_reg_save[i], i);
93} 234}
94 235
95static struct syscore_ops brcmstb_cpu_credit_syscore_ops = { 236static struct syscore_ops brcmstb_cpu_credit_syscore_ops = {
@@ -99,7 +240,7 @@ static struct syscore_ops brcmstb_cpu_credit_syscore_ops = {
99#endif 240#endif
100 241
101 242
102void __init brcmstb_biuctrl_init(void) 243static int __init brcmstb_biuctrl_init(void)
103{ 244{
104 int ret; 245 int ret;
105 246
@@ -108,10 +249,13 @@ void __init brcmstb_biuctrl_init(void)
108 ret = mcp_write_pairing_set(); 249 ret = mcp_write_pairing_set();
109 if (ret) { 250 if (ret) {
110 pr_err("MCP: Unable to disable write pairing!\n"); 251 pr_err("MCP: Unable to disable write pairing!\n");
111 return; 252 return ret;
112 } 253 }
113 254
255 mcp_b53_set();
114#ifdef CONFIG_PM_SLEEP 256#ifdef CONFIG_PM_SLEEP
115 register_syscore_ops(&brcmstb_cpu_credit_syscore_ops); 257 register_syscore_ops(&brcmstb_cpu_credit_syscore_ops);
116#endif 258#endif
259 return 0;
117} 260}
261early_initcall(brcmstb_biuctrl_init);
diff --git a/drivers/soc/bcm/brcmstb/common.c b/drivers/soc/bcm/brcmstb/common.c
index a71730da6385..781ada62d0a3 100644
--- a/drivers/soc/bcm/brcmstb/common.c
+++ b/drivers/soc/bcm/brcmstb/common.c
@@ -66,13 +66,10 @@ static const struct of_device_id sun_top_ctrl_match[] = {
66 { } 66 { }
67}; 67};
68 68
69static int __init brcmstb_soc_device_init(void) 69static int __init brcmstb_soc_device_early_init(void)
70{ 70{
71 struct soc_device_attribute *soc_dev_attr;
72 struct soc_device *soc_dev;
73 struct device_node *sun_top_ctrl; 71 struct device_node *sun_top_ctrl;
74 void __iomem *sun_top_ctrl_base; 72 void __iomem *sun_top_ctrl_base;
75 int ret = 0;
76 73
77 sun_top_ctrl = of_find_matching_node(NULL, sun_top_ctrl_match); 74 sun_top_ctrl = of_find_matching_node(NULL, sun_top_ctrl_match);
78 if (!sun_top_ctrl) 75 if (!sun_top_ctrl)
@@ -84,12 +81,19 @@ static int __init brcmstb_soc_device_init(void)
84 81
85 family_id = readl(sun_top_ctrl_base); 82 family_id = readl(sun_top_ctrl_base);
86 product_id = readl(sun_top_ctrl_base + 0x4); 83 product_id = readl(sun_top_ctrl_base + 0x4);
84 iounmap(sun_top_ctrl_base);
85 return 0;
86}
87early_initcall(brcmstb_soc_device_early_init);
88
89static int __init brcmstb_soc_device_init(void)
90{
91 struct soc_device_attribute *soc_dev_attr;
92 struct soc_device *soc_dev;
87 93
88 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); 94 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
89 if (!soc_dev_attr) { 95 if (!soc_dev_attr)
90 ret = -ENOMEM; 96 return -ENOMEM;
91 goto out;
92 }
93 97
94 soc_dev_attr->family = kasprintf(GFP_KERNEL, "%x", 98 soc_dev_attr->family = kasprintf(GFP_KERNEL, "%x",
95 family_id >> 28 ? 99 family_id >> 28 ?
@@ -107,14 +111,9 @@ static int __init brcmstb_soc_device_init(void)
107 kfree(soc_dev_attr->soc_id); 111 kfree(soc_dev_attr->soc_id);
108 kfree(soc_dev_attr->revision); 112 kfree(soc_dev_attr->revision);
109 kfree(soc_dev_attr); 113 kfree(soc_dev_attr);
110 ret = -ENODEV; 114 return -ENOMEM;
111 goto out;
112 } 115 }
113 116
114 return 0; 117 return 0;
115
116out:
117 iounmap(sun_top_ctrl_base);
118 return ret;
119} 118}
120arch_initcall(brcmstb_soc_device_init); 119arch_initcall(brcmstb_soc_device_init);