diff options
author | Olof Johansson <olof@lixom.net> | 2014-05-26 16:29:22 -0400 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2014-05-26 16:29:22 -0400 |
commit | 75d6bc5f7ab41a166deb6e9ebc8434706799fb00 (patch) | |
tree | a9fddb9739c2e478d61d47eb5bf22866fe27a7f7 /drivers/bus | |
parent | 1b7f0c7b931864642e825a6fd01cde5881b064cc (diff) | |
parent | 27b7d5f3cc49f2e5cd6c005d73696058b7140c5c (diff) |
Merge tag 'omap-for-v3.16/l3-noc-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into next/drivers
Merge "ARM: omap l3-noc bus driver changes for v3.16 merge window, resend" from
Tony Lindgren:
Improvments to omap l3-noc bus driver for v3.16 merge window
to add support for am347x and dra7.
* tag 'omap-for-v3.16/l3-noc-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap: (25 commits)
bus: omap_l3_noc: Add AM4372 interconnect error data
bus: omap_l3_noc: Add DRA7 interconnect error data
bus: omap_l3_noc: introduce concept of submodule
bus: omap_l3_noc: Add information about the context of operation
bus: omap_l3_noc: add information about the type of operation
bus: omap_l3_noc: ignore masked out unclearable targets
bus: omap_l3_noc: improve readability by using helper for slave event parsing
bus: omap_l3_noc: make error reporting and handling common
bus: omap_l3_noc: fix masterid detection
bus: omap_l3_noc: convert flagmux information into a structure
bus: omap_l3_noc: use of_match_data to pick up SoC information
bus: omap_l3_noc: Add support for discountinous flag mux input numbers
bus: omap_l3_noc: convert target information into a structure
bus: omap_l3_noc: move L3 master data structure out
bus: omap_l3_noc: un-obfuscate l3_targ address computation
bus: omap_l3_noc: switch over to relaxed variants of readl/writel
bus: omap_l3_noc: populate l3->dev and use it
bus: omap_l3_noc: remove iclk from omap_l3 struct
bus: omap_l3_noc: rename functions and data to omap_l3
bus: omap_l3_noc: Fix copyright information
...
Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'drivers/bus')
-rw-r--r-- | drivers/bus/omap_l3_noc.c | 406 | ||||
-rw-r--r-- | drivers/bus/omap_l3_noc.h | 545 |
2 files changed, 651 insertions, 300 deletions
diff --git a/drivers/bus/omap_l3_noc.c b/drivers/bus/omap_l3_noc.c index feeecae623f6..531ae591783b 100644 --- a/drivers/bus/omap_l3_noc.c +++ b/drivers/bus/omap_l3_noc.c | |||
@@ -1,43 +1,45 @@ | |||
1 | /* | 1 | /* |
2 | * OMAP4XXX L3 Interconnect error handling driver | 2 | * OMAP L3 Interconnect error handling driver |
3 | * | 3 | * |
4 | * Copyright (C) 2011 Texas Corporation | 4 | * Copyright (C) 2011-2014 Texas Instruments Incorporated - http://www.ti.com/ |
5 | * Santosh Shilimkar <santosh.shilimkar@ti.com> | 5 | * Santosh Shilimkar <santosh.shilimkar@ti.com> |
6 | * Sricharan <r.sricharan@ti.com> | 6 | * Sricharan <r.sricharan@ti.com> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License version 2 as |
10 | * the Free Software Foundation; either version 2 of the License, or | 10 | * published by the Free Software Foundation. |
11 | * (at your option) any later version. | ||
12 | * | 11 | * |
13 | * This program is distributed in the hope that it will be useful, | 12 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 | * kind, whether express or implied; without even the implied warranty |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 14 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU General Public License for more details. | 15 | * GNU General Public License for more details. |
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
21 | * USA | ||
22 | */ | 16 | */ |
23 | #include <linux/module.h> | ||
24 | #include <linux/init.h> | 17 | #include <linux/init.h> |
25 | #include <linux/io.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/io.h> | ||
28 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/module.h> | ||
22 | #include <linux/of_device.h> | ||
23 | #include <linux/of.h> | ||
24 | #include <linux/platform_device.h> | ||
29 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
30 | 26 | ||
31 | #include "omap_l3_noc.h" | 27 | #include "omap_l3_noc.h" |
32 | 28 | ||
33 | /* | 29 | /** |
34 | * Interrupt Handler for L3 error detection. | 30 | * l3_handle_target() - Handle Target specific parse and reporting |
35 | * 1) Identify the L3 clockdomain partition to which the error belongs to. | 31 | * @l3: pointer to l3 struct |
36 | * 2) Identify the slave where the error information is logged | 32 | * @base: base address of clkdm |
37 | * 3) Print the logged information. | 33 | * @flag_mux: flagmux corresponding to the event |
38 | * 4) Add dump stack to provide kernel trace. | 34 | * @err_src: error source index of the slave (target) |
39 | * | 35 | * |
40 | * Two Types of errors : | 36 | * This does the second part of the error interrupt handling: |
37 | * 3) Parse in the slave information | ||
38 | * 4) Print the logged information. | ||
39 | * 5) Add dump stack to provide kernel trace. | ||
40 | * 6) Clear the source if known. | ||
41 | * | ||
42 | * This handles two types of errors: | ||
41 | * 1) Custom errors in L3 : | 43 | * 1) Custom errors in L3 : |
42 | * Target like DMM/FW/EMIF generates SRESP=ERR error | 44 | * Target like DMM/FW/EMIF generates SRESP=ERR error |
43 | * 2) Standard L3 error: | 45 | * 2) Standard L3 error: |
@@ -53,214 +55,264 @@ | |||
53 | * can be trapped as well. But the trapping is implemented as part | 55 | * can be trapped as well. But the trapping is implemented as part |
54 | * secure software and hence need not be implemented here. | 56 | * secure software and hence need not be implemented here. |
55 | */ | 57 | */ |
56 | static irqreturn_t l3_interrupt_handler(int irq, void *_l3) | 58 | static int l3_handle_target(struct omap_l3 *l3, void __iomem *base, |
59 | struct l3_flagmux_data *flag_mux, int err_src) | ||
57 | { | 60 | { |
61 | int k; | ||
62 | u32 std_err_main, clear, masterid; | ||
63 | u8 op_code, m_req_info; | ||
64 | void __iomem *l3_targ_base; | ||
65 | void __iomem *l3_targ_stderr, *l3_targ_slvofslsb, *l3_targ_mstaddr; | ||
66 | void __iomem *l3_targ_hdr, *l3_targ_info; | ||
67 | struct l3_target_data *l3_targ_inst; | ||
68 | struct l3_masters_data *master; | ||
69 | char *target_name, *master_name = "UN IDENTIFIED"; | ||
70 | char *err_description; | ||
71 | char err_string[30] = { 0 }; | ||
72 | char info_string[60] = { 0 }; | ||
73 | |||
74 | /* We DONOT expect err_src to go out of bounds */ | ||
75 | BUG_ON(err_src > MAX_CLKDM_TARGETS); | ||
76 | |||
77 | if (err_src < flag_mux->num_targ_data) { | ||
78 | l3_targ_inst = &flag_mux->l3_targ[err_src]; | ||
79 | target_name = l3_targ_inst->name; | ||
80 | l3_targ_base = base + l3_targ_inst->offset; | ||
81 | } else { | ||
82 | target_name = L3_TARGET_NOT_SUPPORTED; | ||
83 | } | ||
58 | 84 | ||
59 | struct omap4_l3 *l3 = _l3; | 85 | if (target_name == L3_TARGET_NOT_SUPPORTED) |
60 | int inttype, i, k; | 86 | return -ENODEV; |
87 | |||
88 | /* Read the stderrlog_main_source from clk domain */ | ||
89 | l3_targ_stderr = l3_targ_base + L3_TARG_STDERRLOG_MAIN; | ||
90 | l3_targ_slvofslsb = l3_targ_base + L3_TARG_STDERRLOG_SLVOFSLSB; | ||
91 | |||
92 | std_err_main = readl_relaxed(l3_targ_stderr); | ||
93 | |||
94 | switch (std_err_main & CUSTOM_ERROR) { | ||
95 | case STANDARD_ERROR: | ||
96 | err_description = "Standard"; | ||
97 | snprintf(err_string, sizeof(err_string), | ||
98 | ": At Address: 0x%08X ", | ||
99 | readl_relaxed(l3_targ_slvofslsb)); | ||
100 | |||
101 | l3_targ_mstaddr = l3_targ_base + L3_TARG_STDERRLOG_MSTADDR; | ||
102 | l3_targ_hdr = l3_targ_base + L3_TARG_STDERRLOG_HDR; | ||
103 | l3_targ_info = l3_targ_base + L3_TARG_STDERRLOG_INFO; | ||
104 | break; | ||
105 | |||
106 | case CUSTOM_ERROR: | ||
107 | err_description = "Custom"; | ||
108 | |||
109 | l3_targ_mstaddr = l3_targ_base + | ||
110 | L3_TARG_STDERRLOG_CINFO_MSTADDR; | ||
111 | l3_targ_hdr = l3_targ_base + L3_TARG_STDERRLOG_CINFO_OPCODE; | ||
112 | l3_targ_info = l3_targ_base + L3_TARG_STDERRLOG_CINFO_INFO; | ||
113 | break; | ||
114 | |||
115 | default: | ||
116 | /* Nothing to be handled here as of now */ | ||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | /* STDERRLOG_MSTADDR Stores the NTTP master address. */ | ||
121 | masterid = (readl_relaxed(l3_targ_mstaddr) & | ||
122 | l3->mst_addr_mask) >> __ffs(l3->mst_addr_mask); | ||
123 | |||
124 | for (k = 0, master = l3->l3_masters; k < l3->num_masters; | ||
125 | k++, master++) { | ||
126 | if (masterid == master->id) { | ||
127 | master_name = master->name; | ||
128 | break; | ||
129 | } | ||
130 | } | ||
131 | |||
132 | op_code = readl_relaxed(l3_targ_hdr) & 0x7; | ||
133 | |||
134 | m_req_info = readl_relaxed(l3_targ_info) & 0xF; | ||
135 | snprintf(info_string, sizeof(info_string), | ||
136 | ": %s in %s mode during %s access", | ||
137 | (m_req_info & BIT(0)) ? "Opcode Fetch" : "Data Access", | ||
138 | (m_req_info & BIT(1)) ? "Supervisor" : "User", | ||
139 | (m_req_info & BIT(3)) ? "Debug" : "Functional"); | ||
140 | |||
141 | WARN(true, | ||
142 | "%s:L3 %s Error: MASTER %s TARGET %s (%s)%s%s\n", | ||
143 | dev_name(l3->dev), | ||
144 | err_description, | ||
145 | master_name, target_name, | ||
146 | l3_transaction_type[op_code], | ||
147 | err_string, info_string); | ||
148 | |||
149 | /* clear the std error log*/ | ||
150 | clear = std_err_main | CLEAR_STDERR_LOG; | ||
151 | writel_relaxed(clear, l3_targ_stderr); | ||
152 | |||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | /** | ||
157 | * l3_interrupt_handler() - interrupt handler for l3 events | ||
158 | * @irq: irq number | ||
159 | * @_l3: pointer to l3 structure | ||
160 | * | ||
161 | * Interrupt Handler for L3 error detection. | ||
162 | * 1) Identify the L3 clockdomain partition to which the error belongs to. | ||
163 | * 2) Identify the slave where the error information is logged | ||
164 | * ... handle the slave event.. | ||
165 | * 7) if the slave is unknown, mask out the slave. | ||
166 | */ | ||
167 | static irqreturn_t l3_interrupt_handler(int irq, void *_l3) | ||
168 | { | ||
169 | struct omap_l3 *l3 = _l3; | ||
170 | int inttype, i, ret; | ||
61 | int err_src = 0; | 171 | int err_src = 0; |
62 | u32 std_err_main, err_reg, clear, masterid; | 172 | u32 err_reg, mask_val; |
63 | void __iomem *base, *l3_targ_base; | 173 | void __iomem *base, *mask_reg; |
64 | char *target_name, *master_name = "UN IDENTIFIED"; | 174 | struct l3_flagmux_data *flag_mux; |
65 | 175 | ||
66 | /* Get the Type of interrupt */ | 176 | /* Get the Type of interrupt */ |
67 | inttype = irq == l3->app_irq ? L3_APPLICATION_ERROR : L3_DEBUG_ERROR; | 177 | inttype = irq == l3->app_irq ? L3_APPLICATION_ERROR : L3_DEBUG_ERROR; |
68 | 178 | ||
69 | for (i = 0; i < L3_MODULES; i++) { | 179 | for (i = 0; i < l3->num_modules; i++) { |
70 | /* | 180 | /* |
71 | * Read the regerr register of the clock domain | 181 | * Read the regerr register of the clock domain |
72 | * to determine the source | 182 | * to determine the source |
73 | */ | 183 | */ |
74 | base = l3->l3_base[i]; | 184 | base = l3->l3_base[i]; |
75 | err_reg = __raw_readl(base + l3_flagmux[i] + | 185 | flag_mux = l3->l3_flagmux[i]; |
76 | + L3_FLAGMUX_REGERR0 + (inttype << 3)); | 186 | err_reg = readl_relaxed(base + flag_mux->offset + |
187 | L3_FLAGMUX_REGERR0 + (inttype << 3)); | ||
188 | |||
189 | err_reg &= ~(inttype ? flag_mux->mask_app_bits : | ||
190 | flag_mux->mask_dbg_bits); | ||
77 | 191 | ||
78 | /* Get the corresponding error and analyse */ | 192 | /* Get the corresponding error and analyse */ |
79 | if (err_reg) { | 193 | if (err_reg) { |
80 | /* Identify the source from control status register */ | 194 | /* Identify the source from control status register */ |
81 | err_src = __ffs(err_reg); | 195 | err_src = __ffs(err_reg); |
82 | 196 | ||
83 | /* Read the stderrlog_main_source from clk domain */ | 197 | ret = l3_handle_target(l3, base, flag_mux, err_src); |
84 | l3_targ_base = base + *(l3_targ[i] + err_src); | 198 | |
85 | std_err_main = __raw_readl(l3_targ_base + | 199 | /* |
86 | L3_TARG_STDERRLOG_MAIN); | 200 | * Certain plaforms may have "undocumented" status |
87 | masterid = __raw_readl(l3_targ_base + | 201 | * pending on boot. So dont generate a severe warning |
88 | L3_TARG_STDERRLOG_MSTADDR); | 202 | * here. Just mask it off to prevent the error from |
89 | 203 | * reoccuring and locking up the system. | |
90 | switch (std_err_main & CUSTOM_ERROR) { | 204 | */ |
91 | case STANDARD_ERROR: | 205 | if (ret) { |
92 | target_name = | 206 | dev_err(l3->dev, |
93 | l3_targ_inst_name[i][err_src]; | 207 | "L3 %s error: target %d mod:%d %s\n", |
94 | WARN(true, "L3 standard error: TARGET:%s at address 0x%x\n", | 208 | inttype ? "debug" : "application", |
95 | target_name, | 209 | err_src, i, "(unclearable)"); |
96 | __raw_readl(l3_targ_base + | 210 | |
97 | L3_TARG_STDERRLOG_SLVOFSLSB)); | 211 | mask_reg = base + flag_mux->offset + |
98 | /* clear the std error log*/ | 212 | L3_FLAGMUX_MASK0 + (inttype << 3); |
99 | clear = std_err_main | CLEAR_STDERR_LOG; | 213 | mask_val = readl_relaxed(mask_reg); |
100 | writel(clear, l3_targ_base + | 214 | mask_val &= ~(1 << err_src); |
101 | L3_TARG_STDERRLOG_MAIN); | 215 | writel_relaxed(mask_val, mask_reg); |
102 | break; | 216 | |
103 | 217 | /* Mark these bits as to be ignored */ | |
104 | case CUSTOM_ERROR: | 218 | if (inttype) |
105 | target_name = | 219 | flag_mux->mask_app_bits |= 1 << err_src; |
106 | l3_targ_inst_name[i][err_src]; | 220 | else |
107 | for (k = 0; k < NUM_OF_L3_MASTERS; k++) { | 221 | flag_mux->mask_dbg_bits |= 1 << err_src; |
108 | if (masterid == l3_masters[k].id) | ||
109 | master_name = | ||
110 | l3_masters[k].name; | ||
111 | } | ||
112 | WARN(true, "L3 custom error: MASTER:%s TARGET:%s\n", | ||
113 | master_name, target_name); | ||
114 | /* clear the std error log*/ | ||
115 | clear = std_err_main | CLEAR_STDERR_LOG; | ||
116 | writel(clear, l3_targ_base + | ||
117 | L3_TARG_STDERRLOG_MAIN); | ||
118 | break; | ||
119 | |||
120 | default: | ||
121 | /* Nothing to be handled here as of now */ | ||
122 | break; | ||
123 | } | 222 | } |
124 | /* Error found so break the for loop */ | 223 | |
125 | break; | 224 | /* Error found so break the for loop */ |
225 | break; | ||
126 | } | 226 | } |
127 | } | 227 | } |
128 | return IRQ_HANDLED; | 228 | return IRQ_HANDLED; |
129 | } | 229 | } |
130 | 230 | ||
131 | static int omap4_l3_probe(struct platform_device *pdev) | 231 | static const struct of_device_id l3_noc_match[] = { |
232 | {.compatible = "ti,omap4-l3-noc", .data = &omap_l3_data}, | ||
233 | {.compatible = "ti,dra7-l3-noc", .data = &dra_l3_data}, | ||
234 | {.compatible = "ti,am4372-l3-noc", .data = &am4372_l3_data}, | ||
235 | {}, | ||
236 | }; | ||
237 | MODULE_DEVICE_TABLE(of, l3_noc_match); | ||
238 | |||
239 | static int omap_l3_probe(struct platform_device *pdev) | ||
132 | { | 240 | { |
133 | static struct omap4_l3 *l3; | 241 | const struct of_device_id *of_id; |
134 | struct resource *res; | 242 | static struct omap_l3 *l3; |
135 | int ret; | 243 | int ret, i, res_idx; |
244 | |||
245 | of_id = of_match_device(l3_noc_match, &pdev->dev); | ||
246 | if (!of_id) { | ||
247 | dev_err(&pdev->dev, "OF data missing\n"); | ||
248 | return -EINVAL; | ||
249 | } | ||
136 | 250 | ||
137 | l3 = kzalloc(sizeof(*l3), GFP_KERNEL); | 251 | l3 = devm_kzalloc(&pdev->dev, sizeof(*l3), GFP_KERNEL); |
138 | if (!l3) | 252 | if (!l3) |
139 | return -ENOMEM; | 253 | return -ENOMEM; |
140 | 254 | ||
255 | memcpy(l3, of_id->data, sizeof(*l3)); | ||
256 | l3->dev = &pdev->dev; | ||
141 | platform_set_drvdata(pdev, l3); | 257 | platform_set_drvdata(pdev, l3); |
142 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
143 | if (!res) { | ||
144 | dev_err(&pdev->dev, "couldn't find resource 0\n"); | ||
145 | ret = -ENODEV; | ||
146 | goto err0; | ||
147 | } | ||
148 | |||
149 | l3->l3_base[0] = ioremap(res->start, resource_size(res)); | ||
150 | if (!l3->l3_base[0]) { | ||
151 | dev_err(&pdev->dev, "ioremap failed\n"); | ||
152 | ret = -ENOMEM; | ||
153 | goto err0; | ||
154 | } | ||
155 | |||
156 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
157 | if (!res) { | ||
158 | dev_err(&pdev->dev, "couldn't find resource 1\n"); | ||
159 | ret = -ENODEV; | ||
160 | goto err1; | ||
161 | } | ||
162 | |||
163 | l3->l3_base[1] = ioremap(res->start, resource_size(res)); | ||
164 | if (!l3->l3_base[1]) { | ||
165 | dev_err(&pdev->dev, "ioremap failed\n"); | ||
166 | ret = -ENOMEM; | ||
167 | goto err1; | ||
168 | } | ||
169 | 258 | ||
170 | res = platform_get_resource(pdev, IORESOURCE_MEM, 2); | 259 | /* Get mem resources */ |
171 | if (!res) { | 260 | for (i = 0, res_idx = 0; i < l3->num_modules; i++) { |
172 | dev_err(&pdev->dev, "couldn't find resource 2\n"); | 261 | struct resource *res; |
173 | ret = -ENODEV; | ||
174 | goto err2; | ||
175 | } | ||
176 | 262 | ||
177 | l3->l3_base[2] = ioremap(res->start, resource_size(res)); | 263 | if (l3->l3_base[i] == L3_BASE_IS_SUBMODULE) { |
178 | if (!l3->l3_base[2]) { | 264 | /* First entry cannot be submodule */ |
179 | dev_err(&pdev->dev, "ioremap failed\n"); | 265 | BUG_ON(i == 0); |
180 | ret = -ENOMEM; | 266 | l3->l3_base[i] = l3->l3_base[i - 1]; |
181 | goto err2; | 267 | continue; |
268 | } | ||
269 | res = platform_get_resource(pdev, IORESOURCE_MEM, res_idx); | ||
270 | l3->l3_base[i] = devm_ioremap_resource(&pdev->dev, res); | ||
271 | if (IS_ERR(l3->l3_base[i])) { | ||
272 | dev_err(l3->dev, "ioremap %d failed\n", i); | ||
273 | return PTR_ERR(l3->l3_base[i]); | ||
274 | } | ||
275 | res_idx++; | ||
182 | } | 276 | } |
183 | 277 | ||
184 | /* | 278 | /* |
185 | * Setup interrupt Handlers | 279 | * Setup interrupt Handlers |
186 | */ | 280 | */ |
187 | l3->debug_irq = platform_get_irq(pdev, 0); | 281 | l3->debug_irq = platform_get_irq(pdev, 0); |
188 | ret = request_irq(l3->debug_irq, | 282 | ret = devm_request_irq(l3->dev, l3->debug_irq, l3_interrupt_handler, |
189 | l3_interrupt_handler, | 283 | IRQF_DISABLED, "l3-dbg-irq", l3); |
190 | IRQF_DISABLED, "l3-dbg-irq", l3); | ||
191 | if (ret) { | 284 | if (ret) { |
192 | pr_crit("L3: request_irq failed to register for 0x%x\n", | 285 | dev_err(l3->dev, "request_irq failed for %d\n", |
193 | l3->debug_irq); | 286 | l3->debug_irq); |
194 | goto err3; | 287 | return ret; |
195 | } | 288 | } |
196 | 289 | ||
197 | l3->app_irq = platform_get_irq(pdev, 1); | 290 | l3->app_irq = platform_get_irq(pdev, 1); |
198 | ret = request_irq(l3->app_irq, | 291 | ret = devm_request_irq(l3->dev, l3->app_irq, l3_interrupt_handler, |
199 | l3_interrupt_handler, | 292 | IRQF_DISABLED, "l3-app-irq", l3); |
200 | IRQF_DISABLED, "l3-app-irq", l3); | 293 | if (ret) |
201 | if (ret) { | 294 | dev_err(l3->dev, "request_irq failed for %d\n", l3->app_irq); |
202 | pr_crit("L3: request_irq failed to register for 0x%x\n", | ||
203 | l3->app_irq); | ||
204 | goto err4; | ||
205 | } | ||
206 | 295 | ||
207 | return 0; | ||
208 | |||
209 | err4: | ||
210 | free_irq(l3->debug_irq, l3); | ||
211 | err3: | ||
212 | iounmap(l3->l3_base[2]); | ||
213 | err2: | ||
214 | iounmap(l3->l3_base[1]); | ||
215 | err1: | ||
216 | iounmap(l3->l3_base[0]); | ||
217 | err0: | ||
218 | kfree(l3); | ||
219 | return ret; | 296 | return ret; |
220 | } | 297 | } |
221 | 298 | ||
222 | static int omap4_l3_remove(struct platform_device *pdev) | 299 | static struct platform_driver omap_l3_driver = { |
223 | { | 300 | .probe = omap_l3_probe, |
224 | struct omap4_l3 *l3 = platform_get_drvdata(pdev); | ||
225 | |||
226 | free_irq(l3->app_irq, l3); | ||
227 | free_irq(l3->debug_irq, l3); | ||
228 | iounmap(l3->l3_base[0]); | ||
229 | iounmap(l3->l3_base[1]); | ||
230 | iounmap(l3->l3_base[2]); | ||
231 | kfree(l3); | ||
232 | |||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | #if defined(CONFIG_OF) | ||
237 | static const struct of_device_id l3_noc_match[] = { | ||
238 | {.compatible = "ti,omap4-l3-noc", }, | ||
239 | {}, | ||
240 | }; | ||
241 | MODULE_DEVICE_TABLE(of, l3_noc_match); | ||
242 | #else | ||
243 | #define l3_noc_match NULL | ||
244 | #endif | ||
245 | |||
246 | static struct platform_driver omap4_l3_driver = { | ||
247 | .probe = omap4_l3_probe, | ||
248 | .remove = omap4_l3_remove, | ||
249 | .driver = { | 301 | .driver = { |
250 | .name = "omap_l3_noc", | 302 | .name = "omap_l3_noc", |
251 | .owner = THIS_MODULE, | 303 | .owner = THIS_MODULE, |
252 | .of_match_table = l3_noc_match, | 304 | .of_match_table = of_match_ptr(l3_noc_match), |
253 | }, | 305 | }, |
254 | }; | 306 | }; |
255 | 307 | ||
256 | static int __init omap4_l3_init(void) | 308 | static int __init omap_l3_init(void) |
257 | { | 309 | { |
258 | return platform_driver_register(&omap4_l3_driver); | 310 | return platform_driver_register(&omap_l3_driver); |
259 | } | 311 | } |
260 | postcore_initcall_sync(omap4_l3_init); | 312 | postcore_initcall_sync(omap_l3_init); |
261 | 313 | ||
262 | static void __exit omap4_l3_exit(void) | 314 | static void __exit omap_l3_exit(void) |
263 | { | 315 | { |
264 | platform_driver_unregister(&omap4_l3_driver); | 316 | platform_driver_unregister(&omap_l3_driver); |
265 | } | 317 | } |
266 | module_exit(omap4_l3_exit); | 318 | module_exit(omap_l3_exit); |
diff --git a/drivers/bus/omap_l3_noc.h b/drivers/bus/omap_l3_noc.h index a6ce34dc4814..551e01061434 100644 --- a/drivers/bus/omap_l3_noc.h +++ b/drivers/bus/omap_l3_noc.h | |||
@@ -1,29 +1,25 @@ | |||
1 | /* | 1 | /* |
2 | * OMAP4XXX L3 Interconnect error handling driver header | 2 | * OMAP L3 Interconnect error handling driver header |
3 | * | 3 | * |
4 | * Copyright (C) 2011 Texas Corporation | 4 | * Copyright (C) 2011-2014 Texas Instruments Incorporated - http://www.ti.com/ |
5 | * Santosh Shilimkar <santosh.shilimkar@ti.com> | 5 | * Santosh Shilimkar <santosh.shilimkar@ti.com> |
6 | * sricharan <r.sricharan@ti.com> | 6 | * sricharan <r.sricharan@ti.com> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License version 2 as |
10 | * the Free Software Foundation; either version 2 of the License, or | 10 | * published by the Free Software Foundation. |
11 | * (at your option) any later version. | ||
12 | * | 11 | * |
13 | * This program is distributed in the hope that it will be useful, | 12 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 | * kind, whether express or implied; without even the implied warranty |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 14 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU General Public License for more details. | 15 | * GNU General Public License for more details. |
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
21 | * USA | ||
22 | */ | 16 | */ |
23 | #ifndef __ARCH_ARM_MACH_OMAP2_L3_INTERCONNECT_3XXX_H | 17 | #ifndef __OMAP_L3_NOC_H |
24 | #define __ARCH_ARM_MACH_OMAP2_L3_INTERCONNECT_3XXX_H | 18 | #define __OMAP_L3_NOC_H |
19 | |||
20 | #define MAX_L3_MODULES 3 | ||
21 | #define MAX_CLKDM_TARGETS 31 | ||
25 | 22 | ||
26 | #define L3_MODULES 3 | ||
27 | #define CLEAR_STDERR_LOG (1 << 31) | 23 | #define CLEAR_STDERR_LOG (1 << 31) |
28 | #define CUSTOM_ERROR 0x2 | 24 | #define CUSTOM_ERROR 0x2 |
29 | #define STANDARD_ERROR 0x0 | 25 | #define STANDARD_ERROR 0x0 |
@@ -33,63 +29,165 @@ | |||
33 | 29 | ||
34 | /* L3 TARG register offsets */ | 30 | /* L3 TARG register offsets */ |
35 | #define L3_TARG_STDERRLOG_MAIN 0x48 | 31 | #define L3_TARG_STDERRLOG_MAIN 0x48 |
32 | #define L3_TARG_STDERRLOG_HDR 0x4c | ||
33 | #define L3_TARG_STDERRLOG_MSTADDR 0x50 | ||
34 | #define L3_TARG_STDERRLOG_INFO 0x58 | ||
36 | #define L3_TARG_STDERRLOG_SLVOFSLSB 0x5c | 35 | #define L3_TARG_STDERRLOG_SLVOFSLSB 0x5c |
37 | #define L3_TARG_STDERRLOG_MSTADDR 0x68 | 36 | #define L3_TARG_STDERRLOG_CINFO_INFO 0x64 |
37 | #define L3_TARG_STDERRLOG_CINFO_MSTADDR 0x68 | ||
38 | #define L3_TARG_STDERRLOG_CINFO_OPCODE 0x6c | ||
38 | #define L3_FLAGMUX_REGERR0 0xc | 39 | #define L3_FLAGMUX_REGERR0 0xc |
40 | #define L3_FLAGMUX_MASK0 0x8 | ||
41 | |||
42 | #define L3_TARGET_NOT_SUPPORTED NULL | ||
43 | |||
44 | #define L3_BASE_IS_SUBMODULE ((void __iomem *)(1 << 0)) | ||
45 | |||
46 | static const char * const l3_transaction_type[] = { | ||
47 | /* 0 0 0 */ "Idle", | ||
48 | /* 0 0 1 */ "Write", | ||
49 | /* 0 1 0 */ "Read", | ||
50 | /* 0 1 1 */ "ReadEx", | ||
51 | /* 1 0 0 */ "Read Link", | ||
52 | /* 1 0 1 */ "Write Non-Posted", | ||
53 | /* 1 1 0 */ "Write Conditional", | ||
54 | /* 1 1 1 */ "Write Broadcast", | ||
55 | }; | ||
39 | 56 | ||
40 | #define NUM_OF_L3_MASTERS (sizeof(l3_masters)/sizeof(l3_masters[0])) | 57 | /** |
41 | 58 | * struct l3_masters_data - L3 Master information | |
42 | static u32 l3_flagmux[L3_MODULES] = { | 59 | * @id: ID of the L3 Master |
43 | 0x500, | 60 | * @name: master name |
44 | 0x1000, | 61 | */ |
45 | 0X0200 | 62 | struct l3_masters_data { |
46 | }; | ||
47 | |||
48 | /* L3 Target standard Error register offsets */ | ||
49 | static u32 l3_targ_inst_clk1[] = { | ||
50 | 0x100, /* DMM1 */ | ||
51 | 0x200, /* DMM2 */ | ||
52 | 0x300, /* ABE */ | ||
53 | 0x400, /* L4CFG */ | ||
54 | 0x600, /* CLK2 PWR DISC */ | ||
55 | 0x0, /* Host CLK1 */ | ||
56 | 0x900 /* L4 Wakeup */ | ||
57 | }; | ||
58 | |||
59 | static u32 l3_targ_inst_clk2[] = { | ||
60 | 0x500, /* CORTEX M3 */ | ||
61 | 0x300, /* DSS */ | ||
62 | 0x100, /* GPMC */ | ||
63 | 0x400, /* ISS */ | ||
64 | 0x700, /* IVAHD */ | ||
65 | 0xD00, /* missing in TRM corresponds to AES1*/ | ||
66 | 0x900, /* L4 PER0*/ | ||
67 | 0x200, /* OCMRAM */ | ||
68 | 0x100, /* missing in TRM corresponds to GPMC sERROR*/ | ||
69 | 0x600, /* SGX */ | ||
70 | 0x800, /* SL2 */ | ||
71 | 0x1600, /* C2C */ | ||
72 | 0x1100, /* missing in TRM corresponds PWR DISC CLK1*/ | ||
73 | 0xF00, /* missing in TRM corrsponds to SHA1*/ | ||
74 | 0xE00, /* missing in TRM corresponds to AES2*/ | ||
75 | 0xC00, /* L4 PER3 */ | ||
76 | 0xA00, /* L4 PER1*/ | ||
77 | 0xB00, /* L4 PER2*/ | ||
78 | 0x0, /* HOST CLK2 */ | ||
79 | 0x1800, /* CAL */ | ||
80 | 0x1700 /* LLI */ | ||
81 | }; | ||
82 | |||
83 | static u32 l3_targ_inst_clk3[] = { | ||
84 | 0x0100 /* EMUSS */, | ||
85 | 0x0300, /* DEBUGSS_CT_TBR */ | ||
86 | 0x0 /* HOST CLK3 */ | ||
87 | }; | ||
88 | |||
89 | static struct l3_masters_data { | ||
90 | u32 id; | 63 | u32 id; |
91 | char name[10]; | 64 | char *name; |
92 | } l3_masters[] = { | 65 | }; |
66 | |||
67 | /** | ||
68 | * struct l3_target_data - L3 Target information | ||
69 | * @offset: Offset from base for L3 Target | ||
70 | * @name: Target name | ||
71 | * | ||
72 | * Target information is organized indexed by bit field definitions. | ||
73 | */ | ||
74 | struct l3_target_data { | ||
75 | u32 offset; | ||
76 | char *name; | ||
77 | }; | ||
78 | |||
79 | /** | ||
80 | * struct l3_flagmux_data - Flag Mux information | ||
81 | * @offset: offset from base for flagmux register | ||
82 | * @l3_targ: array indexed by flagmux index (bit offset) pointing to the | ||
83 | * target data. unsupported ones are marked with | ||
84 | * L3_TARGET_NOT_SUPPORTED | ||
85 | * @num_targ_data: number of entries in target data | ||
86 | * @mask_app_bits: ignore these from raw application irq status | ||
87 | * @mask_dbg_bits: ignore these from raw debug irq status | ||
88 | */ | ||
89 | struct l3_flagmux_data { | ||
90 | u32 offset; | ||
91 | struct l3_target_data *l3_targ; | ||
92 | u8 num_targ_data; | ||
93 | u32 mask_app_bits; | ||
94 | u32 mask_dbg_bits; | ||
95 | }; | ||
96 | |||
97 | |||
98 | /** | ||
99 | * struct omap_l3 - Description of data relevant for L3 bus. | ||
100 | * @dev: device representing the bus (populated runtime) | ||
101 | * @l3_base: base addresses of modules (populated runtime if 0) | ||
102 | * if set to L3_BASE_IS_SUBMODULE, then uses previous | ||
103 | * module index as the base address | ||
104 | * @l3_flag_mux: array containing flag mux data per module | ||
105 | * offset from corresponding module base indexed per | ||
106 | * module. | ||
107 | * @num_modules: number of clock domains / modules. | ||
108 | * @l3_masters: array pointing to master data containing name and register | ||
109 | * offset for the master. | ||
110 | * @num_master: number of masters | ||
111 | * @mst_addr_mask: Mask representing MSTADDR information of NTTP packet | ||
112 | * @debug_irq: irq number of the debug interrupt (populated runtime) | ||
113 | * @app_irq: irq number of the application interrupt (populated runtime) | ||
114 | */ | ||
115 | struct omap_l3 { | ||
116 | struct device *dev; | ||
117 | |||
118 | void __iomem *l3_base[MAX_L3_MODULES]; | ||
119 | struct l3_flagmux_data **l3_flagmux; | ||
120 | int num_modules; | ||
121 | |||
122 | struct l3_masters_data *l3_masters; | ||
123 | int num_masters; | ||
124 | u32 mst_addr_mask; | ||
125 | |||
126 | int debug_irq; | ||
127 | int app_irq; | ||
128 | }; | ||
129 | |||
130 | static struct l3_target_data omap_l3_target_data_clk1[] = { | ||
131 | {0x100, "DMM1",}, | ||
132 | {0x200, "DMM2",}, | ||
133 | {0x300, "ABE",}, | ||
134 | {0x400, "L4CFG",}, | ||
135 | {0x600, "CLK2PWRDISC",}, | ||
136 | {0x0, "HOSTCLK1",}, | ||
137 | {0x900, "L4WAKEUP",}, | ||
138 | }; | ||
139 | |||
140 | static struct l3_flagmux_data omap_l3_flagmux_clk1 = { | ||
141 | .offset = 0x500, | ||
142 | .l3_targ = omap_l3_target_data_clk1, | ||
143 | .num_targ_data = ARRAY_SIZE(omap_l3_target_data_clk1), | ||
144 | }; | ||
145 | |||
146 | |||
147 | static struct l3_target_data omap_l3_target_data_clk2[] = { | ||
148 | {0x500, "CORTEXM3",}, | ||
149 | {0x300, "DSS",}, | ||
150 | {0x100, "GPMC",}, | ||
151 | {0x400, "ISS",}, | ||
152 | {0x700, "IVAHD",}, | ||
153 | {0xD00, "AES1",}, | ||
154 | {0x900, "L4PER0",}, | ||
155 | {0x200, "OCMRAM",}, | ||
156 | {0x100, "GPMCsERROR",}, | ||
157 | {0x600, "SGX",}, | ||
158 | {0x800, "SL2",}, | ||
159 | {0x1600, "C2C",}, | ||
160 | {0x1100, "PWRDISCCLK1",}, | ||
161 | {0xF00, "SHA1",}, | ||
162 | {0xE00, "AES2",}, | ||
163 | {0xC00, "L4PER3",}, | ||
164 | {0xA00, "L4PER1",}, | ||
165 | {0xB00, "L4PER2",}, | ||
166 | {0x0, "HOSTCLK2",}, | ||
167 | {0x1800, "CAL",}, | ||
168 | {0x1700, "LLI",}, | ||
169 | }; | ||
170 | |||
171 | static struct l3_flagmux_data omap_l3_flagmux_clk2 = { | ||
172 | .offset = 0x1000, | ||
173 | .l3_targ = omap_l3_target_data_clk2, | ||
174 | .num_targ_data = ARRAY_SIZE(omap_l3_target_data_clk2), | ||
175 | }; | ||
176 | |||
177 | |||
178 | static struct l3_target_data omap_l3_target_data_clk3[] = { | ||
179 | {0x0100, "EMUSS",}, | ||
180 | {0x0300, "DEBUG SOURCE",}, | ||
181 | {0x0, "HOST CLK3",}, | ||
182 | }; | ||
183 | |||
184 | static struct l3_flagmux_data omap_l3_flagmux_clk3 = { | ||
185 | .offset = 0x0200, | ||
186 | .l3_targ = omap_l3_target_data_clk3, | ||
187 | .num_targ_data = ARRAY_SIZE(omap_l3_target_data_clk3), | ||
188 | }; | ||
189 | |||
190 | static struct l3_masters_data omap_l3_masters[] = { | ||
93 | { 0x0 , "MPU"}, | 191 | { 0x0 , "MPU"}, |
94 | { 0x10, "CS_ADP"}, | 192 | { 0x10, "CS_ADP"}, |
95 | { 0x14, "xxx"}, | 193 | { 0x14, "xxx"}, |
@@ -117,60 +215,261 @@ static struct l3_masters_data { | |||
117 | { 0xC8, "USBHOSTFS"} | 215 | { 0xC8, "USBHOSTFS"} |
118 | }; | 216 | }; |
119 | 217 | ||
120 | static char *l3_targ_inst_name[L3_MODULES][21] = { | 218 | static struct l3_flagmux_data *omap_l3_flagmux[] = { |
121 | { | 219 | &omap_l3_flagmux_clk1, |
122 | "DMM1", | 220 | &omap_l3_flagmux_clk2, |
123 | "DMM2", | 221 | &omap_l3_flagmux_clk3, |
124 | "ABE", | 222 | }; |
125 | "L4CFG", | 223 | |
126 | "CLK2 PWR DISC", | 224 | static const struct omap_l3 omap_l3_data = { |
127 | "HOST CLK1", | 225 | .l3_flagmux = omap_l3_flagmux, |
128 | "L4 WAKEUP" | 226 | .num_modules = ARRAY_SIZE(omap_l3_flagmux), |
129 | }, | 227 | .l3_masters = omap_l3_masters, |
130 | { | 228 | .num_masters = ARRAY_SIZE(omap_l3_masters), |
131 | "CORTEX M3" , | 229 | /* The 6 MSBs of register field used to distinguish initiator */ |
132 | "DSS ", | 230 | .mst_addr_mask = 0xFC, |
133 | "GPMC ", | 231 | }; |
134 | "ISS ", | ||
135 | "IVAHD ", | ||
136 | "AES1", | ||
137 | "L4 PER0", | ||
138 | "OCMRAM ", | ||
139 | "GPMC sERROR", | ||
140 | "SGX ", | ||
141 | "SL2 ", | ||
142 | "C2C ", | ||
143 | "PWR DISC CLK1", | ||
144 | "SHA1", | ||
145 | "AES2", | ||
146 | "L4 PER3", | ||
147 | "L4 PER1", | ||
148 | "L4 PER2", | ||
149 | "HOST CLK2", | ||
150 | "CAL", | ||
151 | "LLI" | ||
152 | }, | ||
153 | { | ||
154 | "EMUSS", | ||
155 | "DEBUG SOURCE", | ||
156 | "HOST CLK3" | ||
157 | }, | ||
158 | }; | ||
159 | |||
160 | static u32 *l3_targ[L3_MODULES] = { | ||
161 | l3_targ_inst_clk1, | ||
162 | l3_targ_inst_clk2, | ||
163 | l3_targ_inst_clk3, | ||
164 | }; | ||
165 | |||
166 | struct omap4_l3 { | ||
167 | struct device *dev; | ||
168 | struct clk *ick; | ||
169 | 232 | ||
170 | /* memory base */ | 233 | /* DRA7 data */ |
171 | void __iomem *l3_base[L3_MODULES]; | 234 | static struct l3_target_data dra_l3_target_data_clk1[] = { |
235 | {0x2a00, "AES1",}, | ||
236 | {0x0200, "DMM_P1",}, | ||
237 | {0x0600, "DSP2_SDMA",}, | ||
238 | {0x0b00, "EVE2",}, | ||
239 | {0x1300, "DMM_P2",}, | ||
240 | {0x2c00, "AES2",}, | ||
241 | {0x0300, "DSP1_SDMA",}, | ||
242 | {0x0a00, "EVE1",}, | ||
243 | {0x0c00, "EVE3",}, | ||
244 | {0x0d00, "EVE4",}, | ||
245 | {0x2900, "DSS",}, | ||
246 | {0x0100, "GPMC",}, | ||
247 | {0x3700, "PCIE1",}, | ||
248 | {0x1600, "IVA_CONFIG",}, | ||
249 | {0x1800, "IVA_SL2IF",}, | ||
250 | {0x0500, "L4_CFG",}, | ||
251 | {0x1d00, "L4_WKUP",}, | ||
252 | {0x3800, "PCIE2",}, | ||
253 | {0x3300, "SHA2_1",}, | ||
254 | {0x1200, "GPU",}, | ||
255 | {0x1000, "IPU1",}, | ||
256 | {0x1100, "IPU2",}, | ||
257 | {0x2000, "TPCC_EDMA",}, | ||
258 | {0x2e00, "TPTC1_EDMA",}, | ||
259 | {0x2b00, "TPTC2_EDMA",}, | ||
260 | {0x0700, "VCP1",}, | ||
261 | {0x2500, "L4_PER2_P3",}, | ||
262 | {0x0e00, "L4_PER3_P3",}, | ||
263 | {0x2200, "MMU1",}, | ||
264 | {0x1400, "PRUSS1",}, | ||
265 | {0x1500, "PRUSS2"}, | ||
266 | {0x0800, "VCP1",}, | ||
267 | }; | ||
172 | 268 | ||
173 | int debug_irq; | 269 | static struct l3_flagmux_data dra_l3_flagmux_clk1 = { |
174 | int app_irq; | 270 | .offset = 0x803500, |
271 | .l3_targ = dra_l3_target_data_clk1, | ||
272 | .num_targ_data = ARRAY_SIZE(dra_l3_target_data_clk1), | ||
273 | }; | ||
274 | |||
275 | static struct l3_target_data dra_l3_target_data_clk2[] = { | ||
276 | {0x0, "HOST CLK1",}, | ||
277 | {0x0, "HOST CLK2",}, | ||
278 | {0xdead, L3_TARGET_NOT_SUPPORTED,}, | ||
279 | {0x3400, "SHA2_2",}, | ||
280 | {0x0900, "BB2D",}, | ||
281 | {0xdead, L3_TARGET_NOT_SUPPORTED,}, | ||
282 | {0x2100, "L4_PER1_P3",}, | ||
283 | {0x1c00, "L4_PER1_P1",}, | ||
284 | {0x1f00, "L4_PER1_P2",}, | ||
285 | {0x2300, "L4_PER2_P1",}, | ||
286 | {0x2400, "L4_PER2_P2",}, | ||
287 | {0x2600, "L4_PER3_P1",}, | ||
288 | {0x2700, "L4_PER3_P2",}, | ||
289 | {0x2f00, "MCASP1",}, | ||
290 | {0x3000, "MCASP2",}, | ||
291 | {0x3100, "MCASP3",}, | ||
292 | {0x2800, "MMU2",}, | ||
293 | {0x0f00, "OCMC_RAM1",}, | ||
294 | {0x1700, "OCMC_RAM2",}, | ||
295 | {0x1900, "OCMC_RAM3",}, | ||
296 | {0x1e00, "OCMC_ROM",}, | ||
297 | {0x3900, "QSPI",}, | ||
298 | }; | ||
299 | |||
300 | static struct l3_flagmux_data dra_l3_flagmux_clk2 = { | ||
301 | .offset = 0x803600, | ||
302 | .l3_targ = dra_l3_target_data_clk2, | ||
303 | .num_targ_data = ARRAY_SIZE(dra_l3_target_data_clk2), | ||
304 | }; | ||
305 | |||
306 | static struct l3_target_data dra_l3_target_data_clk3[] = { | ||
307 | {0x0100, "L3_INSTR"}, | ||
308 | {0x0300, "DEBUGSS_CT_TBR"}, | ||
309 | {0x0, "HOST CLK3"}, | ||
310 | }; | ||
311 | |||
312 | static struct l3_flagmux_data dra_l3_flagmux_clk3 = { | ||
313 | .offset = 0x200, | ||
314 | .l3_targ = dra_l3_target_data_clk3, | ||
315 | .num_targ_data = ARRAY_SIZE(dra_l3_target_data_clk3), | ||
316 | }; | ||
317 | |||
318 | static struct l3_masters_data dra_l3_masters[] = { | ||
319 | { 0x0, "MPU" }, | ||
320 | { 0x4, "CS_DAP" }, | ||
321 | { 0x5, "IEEE1500_2_OCP" }, | ||
322 | { 0x8, "DSP1_MDMA" }, | ||
323 | { 0x9, "DSP1_CFG" }, | ||
324 | { 0xA, "DSP1_DMA" }, | ||
325 | { 0xB, "DSP2_MDMA" }, | ||
326 | { 0xC, "DSP2_CFG" }, | ||
327 | { 0xD, "DSP2_DMA" }, | ||
328 | { 0xE, "IVA" }, | ||
329 | { 0x10, "EVE1_P1" }, | ||
330 | { 0x11, "EVE2_P1" }, | ||
331 | { 0x12, "EVE3_P1" }, | ||
332 | { 0x13, "EVE4_P1" }, | ||
333 | { 0x14, "PRUSS1 PRU1" }, | ||
334 | { 0x15, "PRUSS1 PRU2" }, | ||
335 | { 0x16, "PRUSS2 PRU1" }, | ||
336 | { 0x17, "PRUSS2 PRU2" }, | ||
337 | { 0x18, "IPU1" }, | ||
338 | { 0x19, "IPU2" }, | ||
339 | { 0x1A, "SDMA" }, | ||
340 | { 0x1B, "CDMA" }, | ||
341 | { 0x1C, "TC1_EDMA" }, | ||
342 | { 0x1D, "TC2_EDMA" }, | ||
343 | { 0x20, "DSS" }, | ||
344 | { 0x21, "MMU1" }, | ||
345 | { 0x22, "PCIE1" }, | ||
346 | { 0x23, "MMU2" }, | ||
347 | { 0x24, "VIP1" }, | ||
348 | { 0x25, "VIP2" }, | ||
349 | { 0x26, "VIP3" }, | ||
350 | { 0x27, "VPE" }, | ||
351 | { 0x28, "GPU_P1" }, | ||
352 | { 0x29, "BB2D" }, | ||
353 | { 0x29, "GPU_P2" }, | ||
354 | { 0x2B, "GMAC_SW" }, | ||
355 | { 0x2C, "USB3" }, | ||
356 | { 0x2D, "USB2_SS" }, | ||
357 | { 0x2E, "USB2_ULPI_SS1" }, | ||
358 | { 0x2F, "USB2_ULPI_SS2" }, | ||
359 | { 0x30, "CSI2_1" }, | ||
360 | { 0x31, "CSI2_2" }, | ||
361 | { 0x33, "SATA" }, | ||
362 | { 0x34, "EVE1_P2" }, | ||
363 | { 0x35, "EVE2_P2" }, | ||
364 | { 0x36, "EVE3_P2" }, | ||
365 | { 0x37, "EVE4_P2" } | ||
175 | }; | 366 | }; |
176 | #endif | 367 | |
368 | static struct l3_flagmux_data *dra_l3_flagmux[] = { | ||
369 | &dra_l3_flagmux_clk1, | ||
370 | &dra_l3_flagmux_clk2, | ||
371 | &dra_l3_flagmux_clk3, | ||
372 | }; | ||
373 | |||
374 | static const struct omap_l3 dra_l3_data = { | ||
375 | .l3_base = { [1] = L3_BASE_IS_SUBMODULE }, | ||
376 | .l3_flagmux = dra_l3_flagmux, | ||
377 | .num_modules = ARRAY_SIZE(dra_l3_flagmux), | ||
378 | .l3_masters = dra_l3_masters, | ||
379 | .num_masters = ARRAY_SIZE(dra_l3_masters), | ||
380 | /* The 6 MSBs of register field used to distinguish initiator */ | ||
381 | .mst_addr_mask = 0xFC, | ||
382 | }; | ||
383 | |||
384 | /* AM4372 data */ | ||
385 | static struct l3_target_data am4372_l3_target_data_200f[] = { | ||
386 | {0xf00, "EMIF",}, | ||
387 | {0x1200, "DES",}, | ||
388 | {0x400, "OCMCRAM",}, | ||
389 | {0x700, "TPTC0",}, | ||
390 | {0x800, "TPTC1",}, | ||
391 | {0x900, "TPTC2"}, | ||
392 | {0xb00, "TPCC",}, | ||
393 | {0xd00, "DEBUGSS",}, | ||
394 | {0xdead, L3_TARGET_NOT_SUPPORTED,}, | ||
395 | {0x200, "SHA",}, | ||
396 | {0xc00, "SGX530",}, | ||
397 | {0x500, "AES0",}, | ||
398 | {0xa00, "L4_FAST",}, | ||
399 | {0x300, "MPUSS_L2_RAM",}, | ||
400 | {0x100, "ICSS",}, | ||
401 | }; | ||
402 | |||
403 | static struct l3_flagmux_data am4372_l3_flagmux_200f = { | ||
404 | .offset = 0x1000, | ||
405 | .l3_targ = am4372_l3_target_data_200f, | ||
406 | .num_targ_data = ARRAY_SIZE(am4372_l3_target_data_200f), | ||
407 | }; | ||
408 | |||
409 | static struct l3_target_data am4372_l3_target_data_100s[] = { | ||
410 | {0x100, "L4_PER_0",}, | ||
411 | {0x200, "L4_PER_1",}, | ||
412 | {0x300, "L4_PER_2",}, | ||
413 | {0x400, "L4_PER_3",}, | ||
414 | {0x800, "McASP0",}, | ||
415 | {0x900, "McASP1",}, | ||
416 | {0xC00, "MMCHS2",}, | ||
417 | {0x700, "GPMC",}, | ||
418 | {0xD00, "L4_FW",}, | ||
419 | {0xdead, L3_TARGET_NOT_SUPPORTED,}, | ||
420 | {0x500, "ADCTSC",}, | ||
421 | {0xE00, "L4_WKUP",}, | ||
422 | {0xA00, "MAG_CARD",}, | ||
423 | }; | ||
424 | |||
425 | static struct l3_flagmux_data am4372_l3_flagmux_100s = { | ||
426 | .offset = 0x600, | ||
427 | .l3_targ = am4372_l3_target_data_100s, | ||
428 | .num_targ_data = ARRAY_SIZE(am4372_l3_target_data_100s), | ||
429 | }; | ||
430 | |||
431 | static struct l3_masters_data am4372_l3_masters[] = { | ||
432 | { 0x0, "M1 (128-bit)"}, | ||
433 | { 0x1, "M2 (64-bit)"}, | ||
434 | { 0x4, "DAP"}, | ||
435 | { 0x5, "P1500"}, | ||
436 | { 0xC, "ICSS0"}, | ||
437 | { 0xD, "ICSS1"}, | ||
438 | { 0x14, "Wakeup Processor"}, | ||
439 | { 0x18, "TPTC0 Read"}, | ||
440 | { 0x19, "TPTC0 Write"}, | ||
441 | { 0x1A, "TPTC1 Read"}, | ||
442 | { 0x1B, "TPTC1 Write"}, | ||
443 | { 0x1C, "TPTC2 Read"}, | ||
444 | { 0x1D, "TPTC2 Write"}, | ||
445 | { 0x20, "SGX530"}, | ||
446 | { 0x21, "OCP WP Traffic Probe"}, | ||
447 | { 0x22, "OCP WP DMA Profiling"}, | ||
448 | { 0x23, "OCP WP Event Trace"}, | ||
449 | { 0x25, "DSS"}, | ||
450 | { 0x28, "Crypto DMA RD"}, | ||
451 | { 0x29, "Crypto DMA WR"}, | ||
452 | { 0x2C, "VPFE0"}, | ||
453 | { 0x2D, "VPFE1"}, | ||
454 | { 0x30, "GEMAC"}, | ||
455 | { 0x34, "USB0 RD"}, | ||
456 | { 0x35, "USB0 WR"}, | ||
457 | { 0x36, "USB1 RD"}, | ||
458 | { 0x37, "USB1 WR"}, | ||
459 | }; | ||
460 | |||
461 | static struct l3_flagmux_data *am4372_l3_flagmux[] = { | ||
462 | &am4372_l3_flagmux_200f, | ||
463 | &am4372_l3_flagmux_100s, | ||
464 | }; | ||
465 | |||
466 | static const struct omap_l3 am4372_l3_data = { | ||
467 | .l3_flagmux = am4372_l3_flagmux, | ||
468 | .num_modules = ARRAY_SIZE(am4372_l3_flagmux), | ||
469 | .l3_masters = am4372_l3_masters, | ||
470 | .num_masters = ARRAY_SIZE(am4372_l3_masters), | ||
471 | /* All 6 bits of register field used to distinguish initiator */ | ||
472 | .mst_addr_mask = 0x3F, | ||
473 | }; | ||
474 | |||
475 | #endif /* __OMAP_L3_NOC_H */ | ||