diff options
author | Olof Johansson <olof@lixom.net> | 2018-01-05 01:31:02 -0500 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2018-01-05 01:31:02 -0500 |
commit | 7e32c6054e6bb18126f2cc4835a891649bd1b723 (patch) | |
tree | 6f72e6736068834e6e2525a3adb1c235a1142470 /drivers/soc | |
parent | f681e08f671a8e68b085ba66190b8661deab4d85 (diff) | |
parent | f780429adfbc222a4d8a227a2a550ba627c7338b (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.c | 176 | ||||
-rw-r--r-- | drivers/soc/bcm/brcmstb/common.c | 27 |
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 | ||
27 | static void __iomem *cpubiuctrl_base; | 38 | static void __iomem *cpubiuctrl_base; |
28 | static bool mcp_wr_pairing_en; | 39 | static bool mcp_wr_pairing_en; |
40 | static const int *cpubiuctrl_regs; | ||
41 | |||
42 | static 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 | |||
52 | static 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 | |||
62 | enum cpubiuctrl_regs { | ||
63 | CPU_CREDIT_REG = 0, | ||
64 | CPU_MCP_FLOW_REG, | ||
65 | CPU_WRITEBACK_CTRL_REG | ||
66 | }; | ||
67 | |||
68 | static 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 */ | ||
75 | static 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 | |||
81 | static 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 | ||
30 | static int __init mcp_write_pairing_set(void) | 89 | static 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 | ||
112 | static const u32 b53_mach_compat[] = { | ||
113 | 0x7268, | ||
114 | 0x7271, | ||
115 | 0x7278, | ||
116 | }; | ||
117 | |||
118 | static 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 | |||
53 | static int __init setup_hifcpubiuctrl_regs(void) | 165 | static 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; | ||
72 | out: | 204 | out: |
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 |
78 | static u32 cpu_credit_reg_dump; /* for save/restore */ | 210 | static u32 cpubiuctrl_reg_save[NUM_CPU_BIUCTRL_REGS]; |
79 | 211 | ||
80 | static int brcmstb_cpu_credit_reg_suspend(void) | 212 | static 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 | ||
88 | static void brcmstb_cpu_credit_reg_resume(void) | 225 | static 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 | ||
95 | static struct syscore_ops brcmstb_cpu_credit_syscore_ops = { | 236 | static 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 | ||
102 | void __init brcmstb_biuctrl_init(void) | 243 | static 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 | } |
261 | early_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 | ||
69 | static int __init brcmstb_soc_device_init(void) | 69 | static 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 | } | ||
87 | early_initcall(brcmstb_soc_device_early_init); | ||
88 | |||
89 | static 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 | |||
116 | out: | ||
117 | iounmap(sun_top_ctrl_base); | ||
118 | return ret; | ||
119 | } | 118 | } |
120 | arch_initcall(brcmstb_soc_device_init); | 119 | arch_initcall(brcmstb_soc_device_init); |