Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

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