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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'memory-controller-drv-7.1' of https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl into soc/drivers

Memory controller drivers for v7.1

1. TegraMC:
- Few fixes for older issues - missing clock on Tegra264,
missing enabling of DLL for Tegra30 and Tegra124.
- Simplify the code in a few places.
- Rework handling interrupts on different variants and add support for
error logging on Tegra 264.

2. Drop Baikal SoC bt1-l2-ctl driver, because SoC support is being
removed tree-wide.

* tag 'memory-controller-drv-7.1' of https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl:
memory: tegra: Add MC error logging support for Tegra264
memory: tegra: Prepare for supporting multiple intmask registers
memory: tegra: Group SoC specific fields
memory: tegra: Add support for multiple IRQs
memory: tegra: Group register and fields
memory: tegra: Group error handling related registers
memory: tegra-mc: Use %pe format
memory: tegra-mc: Simplify printing PTR_ERR with dev_err_probe
memory: tegra-mc: Drop tegra_mc_setup_latency_allowance() return value
memory: renesas-rpc-if: Simplify printing PTR_ERR with dev_err_probe
memory: brcmstb_memc: Expand LPDDR4 check to cover for LPDDR5
dt-bindings: cache: bt1-l2-ctl: Remove unused bindings
memory: bt1-l2-ctl: Remove not-going-to-be-supported code for Baikal SoC
memory: tegra30-emc: Fix dll_change check
memory: tegra124-emc: Fix dll_change check
memory: tegra: Add support for DBB clock on Tegra264

Signed-off-by: Arnd Bergmann <arnd@arndb.de>

+809 -565
-63
Documentation/devicetree/bindings/cache/baikal,bt1-l2-ctl.yaml
··· 1 - # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 - # Copyright (C) 2020 BAIKAL ELECTRONICS, JSC 3 - %YAML 1.2 4 - --- 5 - $id: http://devicetree.org/schemas/cache/baikal,bt1-l2-ctl.yaml# 6 - $schema: http://devicetree.org/meta-schemas/core.yaml# 7 - 8 - title: Baikal-T1 L2-cache Control Block 9 - 10 - maintainers: 11 - - Serge Semin <fancer.lancer@gmail.com> 12 - 13 - description: | 14 - By means of the System Controller Baikal-T1 SoC exposes a few settings to 15 - tune the MIPS P5600 CM2 L2 cache performance up. In particular it's possible 16 - to change the Tag, Data and Way-select RAM access latencies. Baikal-T1 17 - L2-cache controller block is responsible for the tuning. Its DT node is 18 - supposed to be a child of the system controller. 19 - 20 - properties: 21 - compatible: 22 - const: baikal,bt1-l2-ctl 23 - 24 - reg: 25 - maxItems: 1 26 - 27 - baikal,l2-ws-latency: 28 - $ref: /schemas/types.yaml#/definitions/uint32 29 - description: Cycles of latency for Way-select RAM accesses 30 - default: 0 31 - minimum: 0 32 - maximum: 3 33 - 34 - baikal,l2-tag-latency: 35 - $ref: /schemas/types.yaml#/definitions/uint32 36 - description: Cycles of latency for Tag RAM accesses 37 - default: 0 38 - minimum: 0 39 - maximum: 3 40 - 41 - baikal,l2-data-latency: 42 - $ref: /schemas/types.yaml#/definitions/uint32 43 - description: Cycles of latency for Data RAM accesses 44 - default: 1 45 - minimum: 0 46 - maximum: 3 47 - 48 - additionalProperties: false 49 - 50 - required: 51 - - compatible 52 - 53 - examples: 54 - - | 55 - l2@1f04d028 { 56 - compatible = "baikal,bt1-l2-ctl"; 57 - reg = <0x1f04d028 0x004>; 58 - 59 - baikal,l2-ws-latency = <1>; 60 - baikal,l2-tag-latency = <1>; 61 - baikal,l2-data-latency = <2>; 62 - }; 63 - ...
-11
drivers/memory/Kconfig
··· 64 64 controller and specifically control the Self Refresh Power Down 65 65 (SRPD) inactivity timeout. 66 66 67 - config BT1_L2_CTL 68 - bool "Baikal-T1 CM2 L2-RAM Cache Control Block" 69 - depends on MIPS_BAIKAL_T1 || COMPILE_TEST 70 - select MFD_SYSCON 71 - help 72 - Baikal-T1 CPU is based on the MIPS P5600 Warrior IP-core. The CPU 73 - resides Coherency Manager v2 with embedded 1MB L2-cache. It's 74 - possible to tune the L2 cache performance up by setting the data, 75 - tags and way-select latencies of RAM access. This driver provides a 76 - dt properties-based and sysfs interface for it. 77 - 78 67 config TI_AEMIF 79 68 tristate "Texas Instruments AEMIF driver" 80 69 depends on ARCH_DAVINCI || ARCH_KEYSTONE || COMPILE_TEST
-1
drivers/memory/Makefile
··· 11 11 obj-$(CONFIG_ATMEL_EBI) += atmel-ebi.o 12 12 obj-$(CONFIG_BRCMSTB_DPFE) += brcmstb_dpfe.o 13 13 obj-$(CONFIG_BRCMSTB_MEMC) += brcmstb_memc.o 14 - obj-$(CONFIG_BT1_L2_CTL) += bt1-l2-ctl.o 15 14 obj-$(CONFIG_TI_AEMIF) += ti-aemif.o 16 15 obj-$(CONFIG_TI_EMIF) += emif.o 17 16 obj-$(CONFIG_OMAP_GPMC) += omap-gpmc.o
+5 -3
drivers/memory/brcmstb_memc.c
··· 14 14 15 15 #define REG_MEMC_CNTRLR_CONFIG 0x00 16 16 #define CNTRLR_CONFIG_LPDDR4_SHIFT 5 17 + #define CNTRLR_CONFIG_LPDDR5_SHIFT 6 17 18 #define CNTRLR_CONFIG_MASK 0xf 18 19 #define REG_MEMC_SRPD_CFG_21 0x20 19 20 #define REG_MEMC_SRPD_CFG_20 0x34 ··· 35 34 u32 srpd_offset; 36 35 }; 37 36 38 - static int brcmstb_memc_uses_lpddr4(struct brcmstb_memc *memc) 37 + static int brcmstb_memc_uses_lpddr45(struct brcmstb_memc *memc) 39 38 { 40 39 void __iomem *config = memc->ddr_ctrl + REG_MEMC_CNTRLR_CONFIG; 41 40 u32 reg; 42 41 43 42 reg = readl_relaxed(config) & CNTRLR_CONFIG_MASK; 44 43 45 - return reg == CNTRLR_CONFIG_LPDDR4_SHIFT; 44 + return reg == CNTRLR_CONFIG_LPDDR4_SHIFT || 45 + reg == CNTRLR_CONFIG_LPDDR5_SHIFT; 46 46 } 47 47 48 48 static int brcmstb_memc_srpd_config(struct brcmstb_memc *memc, ··· 97 95 * dynamic tuning process will also get affected by the inactivity 98 96 * timeout, thus making it non functional. 99 97 */ 100 - if (brcmstb_memc_uses_lpddr4(memc)) 98 + if (brcmstb_memc_uses_lpddr45(memc)) 101 99 return -EOPNOTSUPP; 102 100 103 101 ret = kstrtouint(buf, 10, &val);
-323
drivers/memory/bt1-l2-ctl.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC 4 - * 5 - * Authors: 6 - * Serge Semin <Sergey.Semin@baikalelectronics.ru> 7 - * 8 - * Baikal-T1 CM2 L2-cache Control Block driver. 9 - */ 10 - 11 - #include <linux/kernel.h> 12 - #include <linux/module.h> 13 - #include <linux/bitfield.h> 14 - #include <linux/types.h> 15 - #include <linux/device.h> 16 - #include <linux/platform_device.h> 17 - #include <linux/regmap.h> 18 - #include <linux/mfd/syscon.h> 19 - #include <linux/sysfs.h> 20 - #include <linux/of.h> 21 - 22 - #define L2_CTL_REG 0x028 23 - #define L2_CTL_DATA_STALL_FLD 0 24 - #define L2_CTL_DATA_STALL_MASK GENMASK(1, L2_CTL_DATA_STALL_FLD) 25 - #define L2_CTL_TAG_STALL_FLD 2 26 - #define L2_CTL_TAG_STALL_MASK GENMASK(3, L2_CTL_TAG_STALL_FLD) 27 - #define L2_CTL_WS_STALL_FLD 4 28 - #define L2_CTL_WS_STALL_MASK GENMASK(5, L2_CTL_WS_STALL_FLD) 29 - #define L2_CTL_SET_CLKRATIO BIT(13) 30 - #define L2_CTL_CLKRATIO_LOCK BIT(31) 31 - 32 - #define L2_CTL_STALL_MIN 0 33 - #define L2_CTL_STALL_MAX 3 34 - #define L2_CTL_STALL_SET_DELAY_US 1 35 - #define L2_CTL_STALL_SET_TOUT_US 1000 36 - 37 - /* 38 - * struct l2_ctl - Baikal-T1 L2 Control block private data. 39 - * @dev: Pointer to the device structure. 40 - * @sys_regs: Baikal-T1 System Controller registers map. 41 - */ 42 - struct l2_ctl { 43 - struct device *dev; 44 - 45 - struct regmap *sys_regs; 46 - }; 47 - 48 - /* 49 - * enum l2_ctl_stall - Baikal-T1 L2-cache-RAM stall identifier. 50 - * @L2_WSSTALL: Way-select latency. 51 - * @L2_TAGSTALL: Tag latency. 52 - * @L2_DATASTALL: Data latency. 53 - */ 54 - enum l2_ctl_stall { 55 - L2_WS_STALL, 56 - L2_TAG_STALL, 57 - L2_DATA_STALL 58 - }; 59 - 60 - /* 61 - * struct l2_ctl_device_attribute - Baikal-T1 L2-cache device attribute. 62 - * @dev_attr: Actual sysfs device attribute. 63 - * @id: L2-cache stall field identifier. 64 - */ 65 - struct l2_ctl_device_attribute { 66 - struct device_attribute dev_attr; 67 - enum l2_ctl_stall id; 68 - }; 69 - 70 - #define to_l2_ctl_dev_attr(_dev_attr) \ 71 - container_of(_dev_attr, struct l2_ctl_device_attribute, dev_attr) 72 - 73 - #define L2_CTL_ATTR_RW(_name, _prefix, _id) \ 74 - struct l2_ctl_device_attribute l2_ctl_attr_##_name = \ 75 - { __ATTR(_name, 0644, _prefix##_show, _prefix##_store), _id } 76 - 77 - static int l2_ctl_get_latency(struct l2_ctl *l2, enum l2_ctl_stall id, u32 *val) 78 - { 79 - u32 data = 0; 80 - int ret; 81 - 82 - ret = regmap_read(l2->sys_regs, L2_CTL_REG, &data); 83 - if (ret) 84 - return ret; 85 - 86 - switch (id) { 87 - case L2_WS_STALL: 88 - *val = FIELD_GET(L2_CTL_WS_STALL_MASK, data); 89 - break; 90 - case L2_TAG_STALL: 91 - *val = FIELD_GET(L2_CTL_TAG_STALL_MASK, data); 92 - break; 93 - case L2_DATA_STALL: 94 - *val = FIELD_GET(L2_CTL_DATA_STALL_MASK, data); 95 - break; 96 - default: 97 - return -EINVAL; 98 - } 99 - 100 - return 0; 101 - } 102 - 103 - static int l2_ctl_set_latency(struct l2_ctl *l2, enum l2_ctl_stall id, u32 val) 104 - { 105 - u32 mask = 0, data = 0; 106 - int ret; 107 - 108 - val = clamp_val(val, L2_CTL_STALL_MIN, L2_CTL_STALL_MAX); 109 - 110 - switch (id) { 111 - case L2_WS_STALL: 112 - data = FIELD_PREP(L2_CTL_WS_STALL_MASK, val); 113 - mask = L2_CTL_WS_STALL_MASK; 114 - break; 115 - case L2_TAG_STALL: 116 - data = FIELD_PREP(L2_CTL_TAG_STALL_MASK, val); 117 - mask = L2_CTL_TAG_STALL_MASK; 118 - break; 119 - case L2_DATA_STALL: 120 - data = FIELD_PREP(L2_CTL_DATA_STALL_MASK, val); 121 - mask = L2_CTL_DATA_STALL_MASK; 122 - break; 123 - default: 124 - return -EINVAL; 125 - } 126 - 127 - data |= L2_CTL_SET_CLKRATIO; 128 - mask |= L2_CTL_SET_CLKRATIO; 129 - 130 - ret = regmap_update_bits(l2->sys_regs, L2_CTL_REG, mask, data); 131 - if (ret) 132 - return ret; 133 - 134 - return regmap_read_poll_timeout(l2->sys_regs, L2_CTL_REG, data, 135 - data & L2_CTL_CLKRATIO_LOCK, 136 - L2_CTL_STALL_SET_DELAY_US, 137 - L2_CTL_STALL_SET_TOUT_US); 138 - } 139 - 140 - static void l2_ctl_clear_data(void *data) 141 - { 142 - struct l2_ctl *l2 = data; 143 - struct platform_device *pdev = to_platform_device(l2->dev); 144 - 145 - platform_set_drvdata(pdev, NULL); 146 - } 147 - 148 - static struct l2_ctl *l2_ctl_create_data(struct platform_device *pdev) 149 - { 150 - struct device *dev = &pdev->dev; 151 - struct l2_ctl *l2; 152 - int ret; 153 - 154 - l2 = devm_kzalloc(dev, sizeof(*l2), GFP_KERNEL); 155 - if (!l2) 156 - return ERR_PTR(-ENOMEM); 157 - 158 - ret = devm_add_action(dev, l2_ctl_clear_data, l2); 159 - if (ret) { 160 - dev_err(dev, "Can't add L2 CTL data clear action\n"); 161 - return ERR_PTR(ret); 162 - } 163 - 164 - l2->dev = dev; 165 - platform_set_drvdata(pdev, l2); 166 - 167 - return l2; 168 - } 169 - 170 - static int l2_ctl_find_sys_regs(struct l2_ctl *l2) 171 - { 172 - l2->sys_regs = syscon_node_to_regmap(l2->dev->of_node->parent); 173 - if (IS_ERR(l2->sys_regs)) { 174 - dev_err(l2->dev, "Couldn't get L2 CTL register map\n"); 175 - return PTR_ERR(l2->sys_regs); 176 - } 177 - 178 - return 0; 179 - } 180 - 181 - static int l2_ctl_of_parse_property(struct l2_ctl *l2, enum l2_ctl_stall id, 182 - const char *propname) 183 - { 184 - int ret = 0; 185 - u32 data; 186 - 187 - if (!of_property_read_u32(l2->dev->of_node, propname, &data)) { 188 - ret = l2_ctl_set_latency(l2, id, data); 189 - if (ret) 190 - dev_err(l2->dev, "Invalid value of '%s'\n", propname); 191 - } 192 - 193 - return ret; 194 - } 195 - 196 - static int l2_ctl_of_parse(struct l2_ctl *l2) 197 - { 198 - int ret; 199 - 200 - ret = l2_ctl_of_parse_property(l2, L2_WS_STALL, "baikal,l2-ws-latency"); 201 - if (ret) 202 - return ret; 203 - 204 - ret = l2_ctl_of_parse_property(l2, L2_TAG_STALL, "baikal,l2-tag-latency"); 205 - if (ret) 206 - return ret; 207 - 208 - return l2_ctl_of_parse_property(l2, L2_DATA_STALL, 209 - "baikal,l2-data-latency"); 210 - } 211 - 212 - static ssize_t l2_ctl_latency_show(struct device *dev, 213 - struct device_attribute *attr, 214 - char *buf) 215 - { 216 - struct l2_ctl_device_attribute *devattr = to_l2_ctl_dev_attr(attr); 217 - struct l2_ctl *l2 = dev_get_drvdata(dev); 218 - u32 data; 219 - int ret; 220 - 221 - ret = l2_ctl_get_latency(l2, devattr->id, &data); 222 - if (ret) 223 - return ret; 224 - 225 - return sysfs_emit(buf, "%u\n", data); 226 - } 227 - 228 - static ssize_t l2_ctl_latency_store(struct device *dev, 229 - struct device_attribute *attr, 230 - const char *buf, size_t count) 231 - { 232 - struct l2_ctl_device_attribute *devattr = to_l2_ctl_dev_attr(attr); 233 - struct l2_ctl *l2 = dev_get_drvdata(dev); 234 - u32 data; 235 - int ret; 236 - 237 - if (kstrtouint(buf, 0, &data) < 0) 238 - return -EINVAL; 239 - 240 - ret = l2_ctl_set_latency(l2, devattr->id, data); 241 - if (ret) 242 - return ret; 243 - 244 - return count; 245 - } 246 - 247 - static L2_CTL_ATTR_RW(l2_ws_latency, l2_ctl_latency, L2_WS_STALL); 248 - static L2_CTL_ATTR_RW(l2_tag_latency, l2_ctl_latency, L2_TAG_STALL); 249 - static L2_CTL_ATTR_RW(l2_data_latency, l2_ctl_latency, L2_DATA_STALL); 250 - 251 - static struct attribute *l2_ctl_sysfs_attrs[] = { 252 - &l2_ctl_attr_l2_ws_latency.dev_attr.attr, 253 - &l2_ctl_attr_l2_tag_latency.dev_attr.attr, 254 - &l2_ctl_attr_l2_data_latency.dev_attr.attr, 255 - NULL 256 - }; 257 - ATTRIBUTE_GROUPS(l2_ctl_sysfs); 258 - 259 - static void l2_ctl_remove_sysfs(void *data) 260 - { 261 - struct l2_ctl *l2 = data; 262 - 263 - device_remove_groups(l2->dev, l2_ctl_sysfs_groups); 264 - } 265 - 266 - static int l2_ctl_init_sysfs(struct l2_ctl *l2) 267 - { 268 - int ret; 269 - 270 - ret = device_add_groups(l2->dev, l2_ctl_sysfs_groups); 271 - if (ret) { 272 - dev_err(l2->dev, "Failed to create L2 CTL sysfs nodes\n"); 273 - return ret; 274 - } 275 - 276 - ret = devm_add_action_or_reset(l2->dev, l2_ctl_remove_sysfs, l2); 277 - if (ret) 278 - dev_err(l2->dev, "Can't add L2 CTL sysfs remove action\n"); 279 - 280 - return ret; 281 - } 282 - 283 - static int l2_ctl_probe(struct platform_device *pdev) 284 - { 285 - struct l2_ctl *l2; 286 - int ret; 287 - 288 - l2 = l2_ctl_create_data(pdev); 289 - if (IS_ERR(l2)) 290 - return PTR_ERR(l2); 291 - 292 - ret = l2_ctl_find_sys_regs(l2); 293 - if (ret) 294 - return ret; 295 - 296 - ret = l2_ctl_of_parse(l2); 297 - if (ret) 298 - return ret; 299 - 300 - ret = l2_ctl_init_sysfs(l2); 301 - if (ret) 302 - return ret; 303 - 304 - return 0; 305 - } 306 - 307 - static const struct of_device_id l2_ctl_of_match[] = { 308 - { .compatible = "baikal,bt1-l2-ctl" }, 309 - { } 310 - }; 311 - MODULE_DEVICE_TABLE(of, l2_ctl_of_match); 312 - 313 - static struct platform_driver l2_ctl_driver = { 314 - .probe = l2_ctl_probe, 315 - .driver = { 316 - .name = "bt1-l2-ctl", 317 - .of_match_table = l2_ctl_of_match 318 - } 319 - }; 320 - module_platform_driver(l2_ctl_driver); 321 - 322 - MODULE_AUTHOR("Serge Semin <Sergey.Semin@baikalelectronics.ru>"); 323 - MODULE_DESCRIPTION("Baikal-T1 L2-cache driver");
+3 -5
drivers/memory/renesas-rpc-if.c
··· 1005 1005 return PTR_ERR(rpc->base); 1006 1006 rpc->info = of_device_get_match_data(dev); 1007 1007 rpc->regmap = devm_regmap_init(dev, NULL, rpc, rpc->info->regmap_config); 1008 - if (IS_ERR(rpc->regmap)) { 1009 - dev_err(dev, "failed to init regmap for rpcif, error %ld\n", 1010 - PTR_ERR(rpc->regmap)); 1011 - return PTR_ERR(rpc->regmap); 1012 - } 1008 + if (IS_ERR(rpc->regmap)) 1009 + return dev_err_probe(dev, PTR_ERR(rpc->regmap), 1010 + "failed to init regmap for rpcif\n"); 1013 1011 1014 1012 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dirmap"); 1015 1013 rpc->dirmap = devm_ioremap_resource(dev, res);
+78 -57
drivers/memory/tegra/mc.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 - * Copyright (C) 2014-2025 NVIDIA CORPORATION. All rights reserved. 3 + * Copyright (C) 2014-2026 NVIDIA CORPORATION. All rights reserved. 4 4 */ 5 5 6 6 #include <linux/clk.h> ··· 55 55 { /* sentinel */ } 56 56 }; 57 57 MODULE_DEVICE_TABLE(of, tegra_mc_of_match); 58 + 59 + const struct tegra_mc_regs tegra20_mc_regs = { 60 + .cfg_channel_enable = 0xdf8, 61 + .err_status = 0x08, 62 + .err_add = 0x0c, 63 + .err_add_hi = 0x11fc, 64 + .err_vpr_status = 0x654, 65 + .err_vpr_add = 0x658, 66 + .err_sec_status = 0x67c, 67 + .err_sec_add = 0x680, 68 + .err_mts_status = 0x9b0, 69 + .err_mts_add = 0x9b4, 70 + .err_gen_co_status = 0xc00, 71 + .err_gen_co_add = 0xc04, 72 + .err_route_status = 0x9c0, 73 + .err_route_add = 0x9c4, 74 + }; 58 75 59 76 static void tegra_mc_devm_action_put_device(void *data) 60 77 { ··· 398 381 } 399 382 EXPORT_SYMBOL_GPL(tegra_mc_get_emem_device_count); 400 383 384 + const irq_handler_t tegra30_mc_irq_handlers[] = { 385 + tegra30_mc_handle_irq 386 + }; 387 + 401 388 #if defined(CONFIG_ARCH_TEGRA_3x_SOC) || \ 402 389 defined(CONFIG_ARCH_TEGRA_114_SOC) || \ 403 390 defined(CONFIG_ARCH_TEGRA_124_SOC) || \ 404 391 defined(CONFIG_ARCH_TEGRA_132_SOC) || \ 405 392 defined(CONFIG_ARCH_TEGRA_210_SOC) 406 - static int tegra_mc_setup_latency_allowance(struct tegra_mc *mc) 393 + static void tegra_mc_setup_latency_allowance(struct tegra_mc *mc) 407 394 { 408 395 unsigned long long tick; 409 396 unsigned int i; ··· 435 414 436 415 /* latch new values */ 437 416 mc_writel(mc, MC_TIMING_UPDATE, MC_TIMING_CONTROL); 438 - 439 - return 0; 440 417 } 441 418 442 419 static int load_one_timing(struct tegra_mc *mc, ··· 528 509 int err; 529 510 530 511 mc->clk = devm_clk_get_optional(mc->dev, "mc"); 531 - if (IS_ERR(mc->clk)) { 532 - dev_err(mc->dev, "failed to get MC clock: %ld\n", PTR_ERR(mc->clk)); 533 - return PTR_ERR(mc->clk); 534 - } 512 + if (IS_ERR(mc->clk)) 513 + return dev_err_probe(mc->dev, PTR_ERR(mc->clk), 514 + "failed to get MC clock\n"); 535 515 536 516 /* ensure that debug features are disabled */ 537 517 mc_writel(mc, 0x00000000, MC_TIMING_CONTROL_DBG); 538 518 539 - err = tegra_mc_setup_latency_allowance(mc); 540 - if (err < 0) { 541 - dev_err(mc->dev, "failed to setup latency allowance: %d\n", err); 542 - return err; 543 - } 519 + tegra_mc_setup_latency_allowance(mc); 544 520 545 521 err = tegra_mc_setup_timings(mc); 546 - if (err < 0) { 547 - dev_err(mc->dev, "failed to setup timings: %d\n", err); 548 - return err; 549 - } 522 + if (err < 0) 523 + return dev_err_probe(mc->dev, err, "failed to setup timings\n"); 550 524 551 525 return 0; 552 526 } 553 527 554 528 const struct tegra_mc_ops tegra30_mc_ops = { 555 529 .probe = tegra30_mc_probe, 556 - .handle_irq = tegra30_mc_handle_irq, 557 530 }; 558 531 #endif 559 532 ··· 586 575 } 587 576 588 577 /* mask all interrupts to avoid flooding */ 589 - status = mc_ch_readl(mc, channel, MC_INTSTATUS) & mc->soc->intmask; 578 + status = mc_ch_readl(mc, channel, MC_INTSTATUS) & mc->soc->intmasks[0].mask; 590 579 } else { 591 - status = mc_readl(mc, MC_INTSTATUS) & mc->soc->intmask; 580 + status = mc_readl(mc, MC_INTSTATUS) & mc->soc->intmasks[0].mask; 592 581 } 593 582 594 583 if (!status) ··· 611 600 612 601 switch (intmask) { 613 602 case MC_INT_DECERR_VPR: 614 - status_reg = MC_ERR_VPR_STATUS; 615 - addr_reg = MC_ERR_VPR_ADR; 603 + status_reg = mc->soc->regs->err_vpr_status; 604 + addr_reg = mc->soc->regs->err_vpr_add; 616 605 break; 617 606 618 607 case MC_INT_SECERR_SEC: 619 - status_reg = MC_ERR_SEC_STATUS; 620 - addr_reg = MC_ERR_SEC_ADR; 608 + status_reg = mc->soc->regs->err_sec_status; 609 + addr_reg = mc->soc->regs->err_sec_add; 621 610 break; 622 611 623 612 case MC_INT_DECERR_MTS: 624 - status_reg = MC_ERR_MTS_STATUS; 625 - addr_reg = MC_ERR_MTS_ADR; 613 + status_reg = mc->soc->regs->err_mts_status; 614 + addr_reg = mc->soc->regs->err_mts_add; 626 615 break; 627 616 628 617 case MC_INT_DECERR_GENERALIZED_CARVEOUT: 629 - status_reg = MC_ERR_GENERALIZED_CARVEOUT_STATUS; 630 - addr_reg = MC_ERR_GENERALIZED_CARVEOUT_ADR; 618 + status_reg = mc->soc->regs->err_gen_co_status; 619 + addr_reg = mc->soc->regs->err_gen_co_add; 631 620 break; 632 621 633 622 case MC_INT_DECERR_ROUTE_SANITY: 634 - status_reg = MC_ERR_ROUTE_SANITY_STATUS; 635 - addr_reg = MC_ERR_ROUTE_SANITY_ADR; 623 + status_reg = mc->soc->regs->err_route_status; 624 + addr_reg = mc->soc->regs->err_route_add; 636 625 break; 637 626 638 627 default: 639 - status_reg = MC_ERR_STATUS; 640 - addr_reg = MC_ERR_ADR; 628 + status_reg = mc->soc->regs->err_status; 629 + addr_reg = mc->soc->regs->err_add; 641 630 642 631 #ifdef CONFIG_PHYS_ADDR_T_64BIT 643 632 if (mc->soc->has_addr_hi_reg) 644 - addr_hi_reg = MC_ERR_ADR_HI; 633 + addr_hi_reg = mc->soc->regs->err_add_hi; 645 634 #endif 646 635 break; 647 636 } ··· 658 647 addr = mc_ch_readl(mc, channel, addr_hi_reg); 659 648 else 660 649 addr = mc_readl(mc, addr_hi_reg); 661 - } else { 650 + } else if (mc->soc->mc_addr_hi_mask) { 662 651 addr = ((value >> MC_ERR_STATUS_ADR_HI_SHIFT) & 663 - MC_ERR_STATUS_ADR_HI_MASK); 652 + mc->soc->mc_addr_hi_mask); 653 + } else { 654 + dev_err_ratelimited(mc->dev, "Unable to determine high address!"); 655 + return IRQ_NONE; 664 656 } 665 657 addr <<= 32; 666 658 } ··· 688 674 } 689 675 } 690 676 691 - type = (value & MC_ERR_STATUS_TYPE_MASK) >> 677 + type = (value & mc->soc->mc_err_status_type_mask) >> 692 678 MC_ERR_STATUS_TYPE_SHIFT; 693 - desc = tegra_mc_error_names[type]; 679 + desc = tegra20_mc_error_names[type]; 694 680 695 - switch (value & MC_ERR_STATUS_TYPE_MASK) { 681 + switch (value & mc->soc->mc_err_status_type_mask) { 696 682 case MC_ERR_STATUS_TYPE_INVALID_SMMU_PAGE: 697 683 perm[0] = ' '; 698 684 perm[1] = '['; ··· 758 744 [16] = "MTS carveout violation", 759 745 [17] = "Generalized carveout violation", 760 746 [20] = "Route Sanity error", 747 + [21] = "GIC_MSI error", 761 748 }; 762 749 763 - const char *const tegra_mc_error_names[8] = { 750 + const char *const tegra20_mc_error_names[8] = { 764 751 [2] = "EMEM decode error", 765 752 [3] = "TrustZone violation", 766 753 [4] = "Carveout violation", ··· 898 883 unsigned int i; 899 884 u32 value; 900 885 901 - value = mc_ch_readl(mc, 0, MC_EMEM_ADR_CFG_CHANNEL_ENABLE); 886 + value = mc_ch_readl(mc, 0, mc->soc->regs->cfg_channel_enable); 902 887 if (value <= 0) { 903 888 mc->num_channels = mc->soc->num_channels; 904 889 return; ··· 950 935 951 936 tegra_mc_num_channel_enabled(mc); 952 937 953 - if (mc->soc->ops && mc->soc->ops->handle_irq) { 954 - mc->irq = platform_get_irq(pdev, 0); 955 - if (mc->irq < 0) 956 - return mc->irq; 938 + if (mc->soc->handle_irq) { 939 + unsigned int i; 957 940 958 941 WARN(!mc->soc->client_id_mask, "missing client ID mask for this SoC\n"); 959 942 960 - if (mc->soc->num_channels) 961 - mc_ch_writel(mc, MC_BROADCAST_CHANNEL, mc->soc->intmask, 962 - MC_INTMASK); 963 - else 964 - mc_writel(mc, mc->soc->intmask, MC_INTMASK); 943 + for (i = 0; i < mc->soc->num_interrupts; i++) { 944 + int irq; 965 945 966 - err = devm_request_irq(&pdev->dev, mc->irq, mc->soc->ops->handle_irq, 0, 967 - dev_name(&pdev->dev), mc); 968 - if (err < 0) { 969 - dev_err(&pdev->dev, "failed to request IRQ#%u: %d\n", mc->irq, 970 - err); 971 - return err; 946 + irq = platform_get_irq(pdev, i); 947 + if (irq < 0) 948 + return irq; 949 + 950 + err = devm_request_irq(&pdev->dev, irq, mc->soc->handle_irq[i], 0, 951 + dev_name(&pdev->dev), mc); 952 + if (err < 0) { 953 + dev_err(&pdev->dev, "failed to request IRQ#%u: %d\n", irq, err); 954 + return err; 955 + } 956 + } 957 + 958 + for (i = 0; i < mc->soc->num_intmasks; i++) { 959 + if (mc->soc->num_channels) 960 + mc_ch_writel(mc, MC_BROADCAST_CHANNEL, mc->soc->intmasks[i].mask, 961 + mc->soc->intmasks[i].reg); 962 + else 963 + mc_writel(mc, mc->soc->intmasks[i].mask, mc->soc->intmasks[i].reg); 972 964 } 973 965 } 974 966 ··· 993 971 if (IS_ENABLED(CONFIG_TEGRA_IOMMU_SMMU) && mc->soc->smmu) { 994 972 mc->smmu = tegra_smmu_probe(&pdev->dev, mc->soc->smmu, mc); 995 973 if (IS_ERR(mc->smmu)) { 996 - dev_err(&pdev->dev, "failed to probe SMMU: %ld\n", 997 - PTR_ERR(mc->smmu)); 974 + dev_err(&pdev->dev, "failed to probe SMMU: %pe\n", mc->smmu); 998 975 mc->smmu = NULL; 999 976 } 1000 977 }
+107 -48
drivers/memory/tegra/mc.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 2 /* 3 - * Copyright (C) 2014-2025 NVIDIA CORPORATION. All rights reserved. 3 + * Copyright (C) 2014-2026 NVIDIA CORPORATION. All rights reserved. 4 4 */ 5 5 6 6 #ifndef MEMORY_TEGRA_MC_H ··· 13 13 #include <soc/tegra/mc.h> 14 14 15 15 #define MC_INTSTATUS 0x00 16 + /* Bit field of MC_INTSTATUS register */ 17 + #define MC_INT_DECERR_EMEM BIT(6) 18 + #define MC_INT_INVALID_GART_PAGE BIT(7) 19 + #define MC_INT_SECURITY_VIOLATION BIT(8) 20 + #define MC_INT_ARBITRATION_EMEM BIT(9) 21 + #define MC_INT_INVALID_SMMU_PAGE BIT(10) 22 + #define MC_INT_INVALID_APB_ASID_UPDATE BIT(11) 23 + #define MC_INT_DECERR_VPR BIT(12) 24 + #define MC_INT_SECERR_SEC BIT(13) 25 + #define MC_INT_DECERR_MTS BIT(16) 26 + #define MC_INT_DECERR_GENERALIZED_CARVEOUT BIT(17) 27 + #define MC_INT_DECERR_ROUTE_SANITY BIT(20) 28 + #define MC_INT_DECERR_ROUTE_SANITY_GIC_MSI BIT(21) 29 + 16 30 #define MC_INTMASK 0x04 17 - #define MC_ERR_STATUS 0x08 18 - #define MC_ERR_ADR 0x0c 19 31 #define MC_GART_ERROR_REQ 0x30 20 32 #define MC_EMEM_ADR_CFG 0x54 33 + #define MC_EMEM_ADR_CFG_EMEM_NUMDEV BIT(0) 34 + 21 35 #define MC_DECERR_EMEM_OTHERS_STATUS 0x58 22 36 #define MC_SECURITY_VIOLATION_STATUS 0x74 23 37 #define MC_EMEM_ARB_CFG 0x90 38 + #define MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE(x) ((x) & 0x1ff) 39 + #define MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE_MASK 0x1ff 40 + 24 41 #define MC_EMEM_ARB_OUTSTANDING_REQ 0x94 42 + #define MC_EMEM_ARB_OUTSTANDING_REQ_HOLDOFF_OVERRIDE BIT(30) 43 + #define MC_EMEM_ARB_OUTSTANDING_REQ_LIMIT_ENABLE BIT(31) 44 + #define MC_EMEM_ARB_OUTSTANDING_REQ_MAX_MASK 0x1ff 45 + 25 46 #define MC_EMEM_ARB_TIMING_RCD 0x98 26 47 #define MC_EMEM_ARB_TIMING_RP 0x9c 27 48 #define MC_EMEM_ARB_TIMING_RC 0xa0 ··· 62 41 #define MC_EMEM_ARB_MISC1 0xdc 63 42 #define MC_EMEM_ARB_RING1_THROTTLE 0xe0 64 43 #define MC_EMEM_ARB_OVERRIDE 0xe8 44 + #define MC_EMEM_ARB_OVERRIDE_EACK_MASK 0x3 45 + 65 46 #define MC_TIMING_CONTROL_DBG 0xf8 66 47 #define MC_TIMING_CONTROL 0xfc 67 - #define MC_ERR_VPR_STATUS 0x654 68 - #define MC_ERR_VPR_ADR 0x658 69 - #define MC_ERR_SEC_STATUS 0x67c 70 - #define MC_ERR_SEC_ADR 0x680 71 - #define MC_ERR_MTS_STATUS 0x9b0 72 - #define MC_ERR_MTS_ADR 0x9b4 73 - #define MC_ERR_ROUTE_SANITY_STATUS 0x9c0 74 - #define MC_ERR_ROUTE_SANITY_ADR 0x9c4 75 - #define MC_ERR_GENERALIZED_CARVEOUT_STATUS 0xc00 76 - #define MC_ERR_GENERALIZED_CARVEOUT_ADR 0xc04 77 - #define MC_EMEM_ADR_CFG_CHANNEL_ENABLE 0xdf8 78 - #define MC_GLOBAL_INTSTATUS 0xf24 79 - #define MC_ERR_ADR_HI 0x11fc 48 + #define MC_TIMING_UPDATE BIT(0) 80 49 81 - #define MC_INT_DECERR_ROUTE_SANITY BIT(20) 82 - #define MC_INT_DECERR_GENERALIZED_CARVEOUT BIT(17) 83 - #define MC_INT_DECERR_MTS BIT(16) 84 - #define MC_INT_SECERR_SEC BIT(13) 85 - #define MC_INT_DECERR_VPR BIT(12) 86 - #define MC_INT_INVALID_APB_ASID_UPDATE BIT(11) 87 - #define MC_INT_INVALID_SMMU_PAGE BIT(10) 88 - #define MC_INT_ARBITRATION_EMEM BIT(9) 89 - #define MC_INT_SECURITY_VIOLATION BIT(8) 90 - #define MC_INT_INVALID_GART_PAGE BIT(7) 91 - #define MC_INT_DECERR_EMEM BIT(6) 50 + #define MC_GLOBAL_INTSTATUS 0xf24 51 + 52 + /* Bit field of MC_ERR_STATUS_0 register */ 53 + #define MC_ERR_STATUS_RW BIT(16) 54 + #define MC_ERR_STATUS_SECURITY BIT(17) 55 + #define MC_ERR_STATUS_NONSECURE BIT(25) 56 + #define MC_ERR_STATUS_WRITABLE BIT(26) 57 + #define MC_ERR_STATUS_READABLE BIT(27) 58 + 59 + #define MC_ERR_STATUS_GSC_ADR_HI_MASK 0xffff 60 + #define MC_ERR_STATUS_GSC_ADR_HI_SHIFT 16 61 + #define MC_ERR_STATUS_RT_ADR_HI_SHIFT 15 92 62 93 63 #define MC_ERR_STATUS_TYPE_SHIFT 28 94 64 #define MC_ERR_STATUS_TYPE_INVALID_SMMU_PAGE (0x6 << 28) 95 - #define MC_ERR_STATUS_TYPE_MASK (0x7 << 28) 96 - #define MC_ERR_STATUS_READABLE BIT(27) 97 - #define MC_ERR_STATUS_WRITABLE BIT(26) 98 - #define MC_ERR_STATUS_NONSECURE BIT(25) 65 + #define MC_ERR_STATUS_RT_TYPE_MASK (0xf << 28) 66 + #define MC_ERR_STATUS_RT_TYPE_SHIFT 28 67 + 99 68 #define MC_ERR_STATUS_ADR_HI_SHIFT 20 100 - #define MC_ERR_STATUS_ADR_HI_MASK 0x3 101 - #define MC_ERR_STATUS_SECURITY BIT(17) 102 - #define MC_ERR_STATUS_RW BIT(16) 103 - 104 - #define MC_EMEM_ADR_CFG_EMEM_NUMDEV BIT(0) 105 - 106 - #define MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE(x) ((x) & 0x1ff) 107 - #define MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE_MASK 0x1ff 108 - 109 - #define MC_EMEM_ARB_OUTSTANDING_REQ_MAX_MASK 0x1ff 110 - #define MC_EMEM_ARB_OUTSTANDING_REQ_HOLDOFF_OVERRIDE BIT(30) 111 - #define MC_EMEM_ARB_OUTSTANDING_REQ_LIMIT_ENABLE BIT(31) 112 - 113 - #define MC_EMEM_ARB_OVERRIDE_EACK_MASK 0x3 114 - 115 - #define MC_TIMING_UPDATE BIT(0) 116 69 117 70 #define MC_BROADCAST_CHANNEL ~0 71 + 72 + /* Tegra264 specific registers */ 73 + 74 + /* Registers for MSS HUB */ 75 + #define MSS_HUB_GLOBAL_INTSTATUS_0 0x6000 76 + #define MSS_HUBC_INTR BIT(0) 77 + #define MSS_HUB_GLOBAL_MASK 0x7F00 78 + #define MSS_HUB_GLOBAL_SHIFT 8 79 + 80 + #define MSS_HUB_HUBC_INTSTATUS_0 0x6008 81 + #define MSS_HUB_INTRSTATUS_0 0x600c 82 + #define MSS_HUB_HUBC_INTMASK_0 0x6010 83 + #define MSS_HUB_HUBC_SCRUB_DONE_INTMASK BIT(0) 84 + 85 + #define MSS_HUB_HUBC_INTPRIORITY_0 0x6014 86 + #define MSS_HUB_INTRMASK_0 0x6018 87 + #define MSS_HUB_COALESCER_ERR_INTMASK BIT(0) 88 + #define MSS_HUB_SMMU_BYPASS_ALLOW_ERR_INTMASK BIT(1) 89 + #define MSS_HUB_ILLEGAL_TBUGRP_ID_INTMASK BIT(2) 90 + #define MSS_HUB_MSI_ERR_INTMASK BIT(3) 91 + #define MSS_HUB_POISON_RSP_INTMASK BIT(4) 92 + #define MSS_HUB_RESTRICTED_ACCESS_ERR_INTMASK BIT(5) 93 + #define MSS_HUB_RESERVED_PA_ERR_INTMASK BIT(6) 94 + 95 + #define MSS_HUB_INTRPRIORITY_0 0x601c 96 + #define MSS_HUB_SMMU_BYPASS_ALLOW_ERR_STATUS_0 0x6020 97 + #define MSS_HUB_MSI_ERR_STATUS_0 0x6024 98 + #define MSS_HUB_POISON_RSP_STATUS_0 0x6028 99 + #define MSS_HUB_COALESCE_ERR_STATUS_0 0x60e0 100 + #define MSS_HUB_COALESCE_ERR_ADR_HI_0 0x60e4 101 + #define MSS_HUB_COALESCE_ERR_ADR_0 0x60e8 102 + #define MSS_HUB_RESTRICTED_ACCESS_ERR_STATUS_0 0x638c 103 + #define MSS_HUB_RESERVED_PA_ERR_STATUS_0 0x6390 104 + #define MSS_HUB_ILLEGAL_TBUGRP_ID_ERR_STATUS_0 0x63b0 105 + 106 + /* Registers for channels */ 107 + #define MC_CH_INTSTATUS_0 0x82d4 108 + #define MC_CH_INTMASK_0 0x82d8 109 + #define WCAM_ERR_INTMASK BIT(19) 110 + 111 + #define MC_ERR_GENERALIZED_CARVEOUT_STATUS_1_0 0xbc74 112 + 113 + /* Registers for MCF */ 114 + #define MCF_COMMON_INTSTATUS0_0_0 0xce04 115 + #define MCF_INTSTATUS_0 0xce2c 116 + #define MCF_INTMASK_0 0xce30 117 + #define MCF_INTPRIORITY_0 0xce34 118 + 119 + /* Registers for SBS */ 120 + #define MSS_SBS_INTSTATUS_0 0xec08 121 + #define MSS_SBS_INTMASK_0 0xec0c 122 + #define MSS_SBS_FILL_FIFO_ISO_OVERFLOW_INTMASK BIT(0) 123 + #define MSS_SBS_FILL_FIFO_SISO_OVERFLOW_INTMASK BIT(1) 124 + #define MSS_SBS_FILL_FIFO_NISO_OVERFLOW_INTMASK BIT(2) 125 + 126 + /* Bit field of MC_ERR_ROUTE_SANITY_STATUS_0 register */ 127 + #define MC_ERR_ROUTE_SANITY_RW BIT(12) 128 + #define MC_ERR_ROUTE_SANITY_SEC BIT(13) 129 + 130 + #define ERR_GENERALIZED_APERTURE_ID_SHIFT 0 131 + #define ERR_GENERALIZED_APERTURE_ID_MASK 0x1F 132 + #define ERR_GENERALIZED_CARVEOUT_APERTURE_ID_SHIFT 5 133 + #define ERR_GENERALIZED_CARVEOUT_APERTURE_ID_MASK 0x1F 118 134 119 135 static inline u32 tegra_mc_scale_percents(u64 val, unsigned int percents) 120 136 { ··· 261 203 #endif 262 204 263 205 irqreturn_t tegra30_mc_handle_irq(int irq, void *data); 206 + extern const irq_handler_t tegra30_mc_irq_handlers[1]; 264 207 extern const char * const tegra_mc_status_names[32]; 265 - extern const char * const tegra_mc_error_names[8]; 208 + extern const char * const tegra20_mc_error_names[8]; 266 209 267 210 /* 268 211 * These IDs are for internal use of Tegra ICC drivers. The ID numbers are
+15 -3
drivers/memory/tegra/tegra114.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 - * Copyright (C) 2014 NVIDIA CORPORATION. All rights reserved. 3 + * Copyright (C) 2014-2026 NVIDIA CORPORATION. All rights reserved. 4 4 */ 5 5 6 6 #include <linux/of.h> ··· 1101 1101 TEGRA114_MC_RESET(VI, 0x200, 0x204, 17), 1102 1102 }; 1103 1103 1104 + static const struct tegra_mc_intmask tegra114_mc_intmasks[] = { 1105 + { 1106 + .reg = MC_INTMASK, 1107 + .mask = MC_INT_INVALID_SMMU_PAGE | MC_INT_SECURITY_VIOLATION | 1108 + MC_INT_DECERR_EMEM, 1109 + }, 1110 + }; 1111 + 1104 1112 const struct tegra_mc_soc tegra114_mc_soc = { 1105 1113 .clients = tegra114_mc_clients, 1106 1114 .num_clients = ARRAY_SIZE(tegra114_mc_clients), ··· 1116 1108 .atom_size = 32, 1117 1109 .client_id_mask = 0x7f, 1118 1110 .smmu = &tegra114_smmu_soc, 1119 - .intmask = MC_INT_INVALID_SMMU_PAGE | MC_INT_SECURITY_VIOLATION | 1120 - MC_INT_DECERR_EMEM, 1111 + .intmasks = tegra114_mc_intmasks, 1112 + .num_intmasks = ARRAY_SIZE(tegra114_mc_intmasks), 1121 1113 .reset_ops = &tegra_mc_reset_ops_common, 1122 1114 .resets = tegra114_mc_resets, 1123 1115 .num_resets = ARRAY_SIZE(tegra114_mc_resets), 1124 1116 .ops = &tegra30_mc_ops, 1117 + .regs = &tegra20_mc_regs, 1118 + .handle_irq = tegra30_mc_irq_handlers, 1119 + .num_interrupts = ARRAY_SIZE(tegra30_mc_irq_handlers), 1120 + .mc_err_status_type_mask = (0x7 << 28), 1125 1121 };
+1 -1
drivers/memory/tegra/tegra124-emc.c
··· 608 608 609 609 if ((last->emc_mode_1 & 0x1) == (timing->emc_mode_1 & 0x1)) 610 610 dll_change = DLL_CHANGE_NONE; 611 - else if (timing->emc_mode_1 & 0x1) 611 + else if (!(timing->emc_mode_1 & 0x1)) 612 612 dll_change = DLL_CHANGE_ON; 613 613 else 614 614 dll_change = DLL_CHANGE_OFF;
+33 -7
drivers/memory/tegra/tegra124.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 - * Copyright (C) 2014 NVIDIA CORPORATION. All rights reserved. 3 + * Copyright (C) 2014-2026 NVIDIA CORPORATION. All rights reserved. 4 4 */ 5 5 6 6 #include <linux/of.h> ··· 1258 1258 .num_asids = 128, 1259 1259 }; 1260 1260 1261 + static const struct tegra_mc_intmask tegra124_mc_intmasks[] = { 1262 + { 1263 + .reg = MC_INTMASK, 1264 + .mask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR | 1265 + MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE | 1266 + MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM, 1267 + }, 1268 + }; 1269 + 1261 1270 const struct tegra_mc_soc tegra124_mc_soc = { 1262 1271 .clients = tegra124_mc_clients, 1263 1272 .num_clients = ARRAY_SIZE(tegra124_mc_clients), ··· 1276 1267 .smmu = &tegra124_smmu_soc, 1277 1268 .emem_regs = tegra124_mc_emem_regs, 1278 1269 .num_emem_regs = ARRAY_SIZE(tegra124_mc_emem_regs), 1279 - .intmask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR | 1280 - MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE | 1281 - MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM, 1270 + .intmasks = tegra124_mc_intmasks, 1271 + .num_intmasks = ARRAY_SIZE(tegra124_mc_intmasks), 1282 1272 .reset_ops = &tegra_mc_reset_ops_common, 1283 1273 .resets = tegra124_mc_resets, 1284 1274 .num_resets = ARRAY_SIZE(tegra124_mc_resets), 1285 1275 .icc_ops = &tegra124_mc_icc_ops, 1286 1276 .ops = &tegra30_mc_ops, 1277 + .regs = &tegra20_mc_regs, 1278 + .handle_irq = tegra30_mc_irq_handlers, 1279 + .num_interrupts = ARRAY_SIZE(tegra30_mc_irq_handlers), 1280 + .mc_addr_hi_mask = 0x3, 1281 + .mc_err_status_type_mask = (0x7 << 28), 1287 1282 }; 1288 1283 #endif /* CONFIG_ARCH_TEGRA_124_SOC */ 1289 1284 ··· 1305 1292 .num_asids = 128, 1306 1293 }; 1307 1294 1295 + static const struct tegra_mc_intmask tegra132_mc_intmasks[] = { 1296 + { 1297 + .reg = MC_INTMASK, 1298 + .mask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR | 1299 + MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE | 1300 + MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM, 1301 + }, 1302 + }; 1303 + 1308 1304 const struct tegra_mc_soc tegra132_mc_soc = { 1309 1305 .clients = tegra124_mc_clients, 1310 1306 .num_clients = ARRAY_SIZE(tegra124_mc_clients), ··· 1321 1299 .atom_size = 32, 1322 1300 .client_id_mask = 0x7f, 1323 1301 .smmu = &tegra132_smmu_soc, 1324 - .intmask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR | 1325 - MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE | 1326 - MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM, 1302 + .intmasks = tegra132_mc_intmasks, 1303 + .num_intmasks = ARRAY_SIZE(tegra132_mc_intmasks), 1327 1304 .reset_ops = &tegra_mc_reset_ops_common, 1328 1305 .resets = tegra124_mc_resets, 1329 1306 .num_resets = ARRAY_SIZE(tegra124_mc_resets), 1330 1307 .icc_ops = &tegra124_mc_icc_ops, 1331 1308 .ops = &tegra30_mc_ops, 1309 + .regs = &tegra20_mc_regs, 1310 + .handle_irq = tegra30_mc_irq_handlers, 1311 + .num_interrupts = ARRAY_SIZE(tegra30_mc_irq_handlers), 1312 + .mc_addr_hi_mask = 0x3, 1313 + .mc_err_status_type_mask = (0x7 << 28), 1332 1314 }; 1333 1315 #endif /* CONFIG_ARCH_TEGRA_132_SOC */
+8
drivers/memory/tegra/tegra186-emc.c
··· 22 22 struct tegra_bpmp *bpmp; 23 23 struct device *dev; 24 24 struct clk *clk; 25 + struct clk *clk_dbb; 25 26 26 27 struct tegra186_emc_dvfs *dvfs; 27 28 unsigned int num_dvfs; ··· 326 325 if (IS_ERR(emc->clk)) { 327 326 err = dev_err_probe(&pdev->dev, PTR_ERR(emc->clk), 328 327 "failed to get EMC clock\n"); 328 + goto put_bpmp; 329 + } 330 + 331 + emc->clk_dbb = devm_clk_get_optional_enabled(&pdev->dev, "dbb"); 332 + if (IS_ERR(emc->clk_dbb)) { 333 + err = dev_err_probe(&pdev->dev, PTR_ERR(emc->clk_dbb), 334 + "failed to get DBB clock\n"); 329 335 goto put_bpmp; 330 336 } 331 337
+17 -5
drivers/memory/tegra/tegra186.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 - * Copyright (C) 2017-2025 NVIDIA CORPORATION. All rights reserved. 3 + * Copyright (C) 2017-2026 NVIDIA CORPORATION. All rights reserved. 4 4 */ 5 5 6 6 #include <linux/io.h> ··· 174 174 .remove = tegra186_mc_remove, 175 175 .resume = tegra186_mc_resume, 176 176 .probe_device = tegra186_mc_probe_device, 177 - .handle_irq = tegra30_mc_handle_irq, 178 177 }; 179 178 180 179 #if defined(CONFIG_ARCH_TEGRA_186_SOC) ··· 901 902 }, 902 903 }; 903 904 905 + static const struct tegra_mc_intmask tegra186_mc_intmasks[] = { 906 + { 907 + .reg = MC_INTMASK, 908 + .mask = MC_INT_DECERR_GENERALIZED_CARVEOUT | MC_INT_DECERR_MTS | 909 + MC_INT_SECERR_SEC | MC_INT_DECERR_VPR | 910 + MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM, 911 + }, 912 + }; 913 + 904 914 const struct tegra_mc_soc tegra186_mc_soc = { 905 915 .num_clients = ARRAY_SIZE(tegra186_mc_clients), 906 916 .clients = tegra186_mc_clients, 907 917 .num_address_bits = 40, 908 918 .num_channels = 4, 909 919 .client_id_mask = 0xff, 910 - .intmask = MC_INT_DECERR_GENERALIZED_CARVEOUT | MC_INT_DECERR_MTS | 911 - MC_INT_SECERR_SEC | MC_INT_DECERR_VPR | 912 - MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM, 920 + .intmasks = tegra186_mc_intmasks, 921 + .num_intmasks = ARRAY_SIZE(tegra186_mc_intmasks), 913 922 .ops = &tegra186_mc_ops, 914 923 .ch_intmask = 0x0000000f, 915 924 .global_intstatus_channel_shift = 0, 925 + .regs = &tegra20_mc_regs, 926 + .handle_irq = tegra30_mc_irq_handlers, 927 + .num_interrupts = ARRAY_SIZE(tegra30_mc_irq_handlers), 928 + .mc_addr_hi_mask = 0x3, 929 + .mc_err_status_type_mask = (0x7 << 28), 916 930 }; 917 931 #endif
+17 -5
drivers/memory/tegra/tegra194.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 - * Copyright (C) 2017-2021 NVIDIA CORPORATION. All rights reserved. 3 + * Copyright (C) 2017-2026 NVIDIA CORPORATION. All rights reserved. 4 4 */ 5 5 6 6 #include <soc/tegra/mc.h> ··· 1343 1343 }, 1344 1344 }; 1345 1345 1346 + static const struct tegra_mc_intmask tegra194_mc_intmasks[] = { 1347 + { 1348 + .reg = MC_INTMASK, 1349 + .mask = MC_INT_DECERR_ROUTE_SANITY | MC_INT_DECERR_GENERALIZED_CARVEOUT | 1350 + MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR | 1351 + MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM, 1352 + }, 1353 + }; 1354 + 1346 1355 const struct tegra_mc_soc tegra194_mc_soc = { 1347 1356 .num_clients = ARRAY_SIZE(tegra194_mc_clients), 1348 1357 .clients = tegra194_mc_clients, 1349 1358 .num_address_bits = 40, 1350 1359 .num_channels = 16, 1351 1360 .client_id_mask = 0xff, 1352 - .intmask = MC_INT_DECERR_ROUTE_SANITY | 1353 - MC_INT_DECERR_GENERALIZED_CARVEOUT | MC_INT_DECERR_MTS | 1354 - MC_INT_SECERR_SEC | MC_INT_DECERR_VPR | 1355 - MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM, 1361 + .intmasks = tegra194_mc_intmasks, 1362 + .num_intmasks = ARRAY_SIZE(tegra194_mc_intmasks), 1356 1363 .has_addr_hi_reg = true, 1357 1364 .ops = &tegra186_mc_ops, 1358 1365 .icc_ops = &tegra_mc_icc_ops, 1359 1366 .ch_intmask = 0x00000f00, 1360 1367 .global_intstatus_channel_shift = 8, 1368 + .regs = &tegra20_mc_regs, 1369 + .handle_irq = tegra30_mc_irq_handlers, 1370 + .num_interrupts = ARRAY_SIZE(tegra30_mc_irq_handlers), 1371 + .mc_addr_hi_mask = 0x3, 1372 + .mc_err_status_type_mask = (0x7 << 28), 1361 1373 };
+23 -8
drivers/memory/tegra/tegra20.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 - * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved. 3 + * Copyright (C) 2012-2026 NVIDIA CORPORATION. All rights reserved. 4 4 */ 5 5 6 6 #include <linux/bitfield.h> ··· 695 695 unsigned int bit; 696 696 697 697 /* mask all interrupts to avoid flooding */ 698 - status = mc_readl(mc, MC_INTSTATUS) & mc->soc->intmask; 698 + status = mc_readl(mc, MC_INTSTATUS) & mc->soc->intmasks[0].mask; 699 699 if (!status) 700 700 return IRQ_NONE; 701 701 ··· 713 713 value = mc_readl(mc, reg); 714 714 715 715 id = value & mc->soc->client_id_mask; 716 - desc = tegra_mc_error_names[2]; 716 + desc = tegra20_mc_error_names[2]; 717 717 718 718 if (value & BIT(31)) 719 719 direction = "write"; ··· 724 724 value = mc_readl(mc, reg); 725 725 726 726 id = (value >> 1) & mc->soc->client_id_mask; 727 - desc = tegra_mc_error_names[2]; 727 + desc = tegra20_mc_error_names[2]; 728 728 729 729 if (value & BIT(0)) 730 730 direction = "write"; ··· 736 736 737 737 id = value & mc->soc->client_id_mask; 738 738 type = (value & BIT(30)) ? 4 : 3; 739 - desc = tegra_mc_error_names[type]; 739 + desc = tegra20_mc_error_names[type]; 740 740 secure = "secure "; 741 741 742 742 if (value & BIT(31)) ··· 761 761 return IRQ_HANDLED; 762 762 } 763 763 764 + static const irq_handler_t tegra20_mc_irq_handlers[] = { 765 + tegra20_mc_handle_irq 766 + }; 767 + 764 768 static const struct tegra_mc_ops tegra20_mc_ops = { 765 769 .probe = tegra20_mc_probe, 766 - .handle_irq = tegra20_mc_handle_irq, 770 + }; 771 + 772 + static const struct tegra_mc_intmask tegra20_mc_intmasks[] = { 773 + { 774 + .reg = MC_INTMASK, 775 + .mask = MC_INT_SECURITY_VIOLATION | MC_INT_INVALID_GART_PAGE | 776 + MC_INT_DECERR_EMEM, 777 + }, 767 778 }; 768 779 769 780 const struct tegra_mc_soc tegra20_mc_soc = { ··· 782 771 .num_clients = ARRAY_SIZE(tegra20_mc_clients), 783 772 .num_address_bits = 32, 784 773 .client_id_mask = 0x3f, 785 - .intmask = MC_INT_SECURITY_VIOLATION | MC_INT_INVALID_GART_PAGE | 786 - MC_INT_DECERR_EMEM, 774 + .intmasks = tegra20_mc_intmasks, 775 + .num_intmasks = ARRAY_SIZE(tegra20_mc_intmasks), 787 776 .reset_ops = &tegra20_mc_reset_ops, 788 777 .resets = tegra20_mc_resets, 789 778 .num_resets = ARRAY_SIZE(tegra20_mc_resets), 790 779 .icc_ops = &tegra20_mc_icc_ops, 791 780 .ops = &tegra20_mc_ops, 781 + .regs = &tegra20_mc_regs, 782 + .handle_irq = tegra20_mc_irq_handlers, 783 + .num_interrupts = ARRAY_SIZE(tegra20_mc_irq_handlers), 784 + .mc_err_status_type_mask = (0x7 << 28), 792 785 };
+17 -4
drivers/memory/tegra/tegra210.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 - * Copyright (C) 2015 NVIDIA CORPORATION. All rights reserved. 3 + * Copyright (C) 2015-2026 NVIDIA CORPORATION. All rights reserved. 4 4 */ 5 5 6 6 #include <dt-bindings/memory/tegra210-mc.h> ··· 1273 1273 TEGRA210_MC_RESET(TSECB, 0x970, 0x974, 13), 1274 1274 }; 1275 1275 1276 + static const struct tegra_mc_intmask tegra210_mc_intmasks[] = { 1277 + { 1278 + .reg = MC_INTMASK, 1279 + .mask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR | 1280 + MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE | 1281 + MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM, 1282 + }, 1283 + }; 1284 + 1276 1285 const struct tegra_mc_soc tegra210_mc_soc = { 1277 1286 .clients = tegra210_mc_clients, 1278 1287 .num_clients = ARRAY_SIZE(tegra210_mc_clients), ··· 1289 1280 .atom_size = 64, 1290 1281 .client_id_mask = 0xff, 1291 1282 .smmu = &tegra210_smmu_soc, 1292 - .intmask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR | 1293 - MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE | 1294 - MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM, 1283 + .intmasks = tegra210_mc_intmasks, 1284 + .num_intmasks = ARRAY_SIZE(tegra210_mc_intmasks), 1295 1285 .reset_ops = &tegra_mc_reset_ops_common, 1296 1286 .resets = tegra210_mc_resets, 1297 1287 .num_resets = ARRAY_SIZE(tegra210_mc_resets), 1298 1288 .ops = &tegra30_mc_ops, 1289 + .regs = &tegra20_mc_regs, 1290 + .handle_irq = tegra30_mc_irq_handlers, 1291 + .num_interrupts = ARRAY_SIZE(tegra30_mc_irq_handlers), 1292 + .mc_addr_hi_mask = 0x3, 1293 + .mc_err_status_type_mask = (0x7 << 28), 1299 1294 };
+17 -5
drivers/memory/tegra/tegra234.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 - * Copyright (C) 2022-2023, NVIDIA CORPORATION. All rights reserved. 3 + * Copyright (C) 2022-2026, NVIDIA CORPORATION. All rights reserved. 4 4 */ 5 5 6 6 #include <soc/tegra/mc.h> ··· 1132 1132 .set = tegra234_mc_icc_set, 1133 1133 }; 1134 1134 1135 + static const struct tegra_mc_intmask tegra234_mc_intmasks[] = { 1136 + { 1137 + .reg = MC_INTMASK, 1138 + .mask = MC_INT_DECERR_ROUTE_SANITY | MC_INT_DECERR_GENERALIZED_CARVEOUT | 1139 + MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR | 1140 + MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM, 1141 + }, 1142 + }; 1143 + 1135 1144 const struct tegra_mc_soc tegra234_mc_soc = { 1136 1145 .num_clients = ARRAY_SIZE(tegra234_mc_clients), 1137 1146 .clients = tegra234_mc_clients, 1138 1147 .num_address_bits = 40, 1139 1148 .num_channels = 16, 1140 1149 .client_id_mask = 0x1ff, 1141 - .intmask = MC_INT_DECERR_ROUTE_SANITY | 1142 - MC_INT_DECERR_GENERALIZED_CARVEOUT | MC_INT_DECERR_MTS | 1143 - MC_INT_SECERR_SEC | MC_INT_DECERR_VPR | 1144 - MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM, 1150 + .intmasks = tegra234_mc_intmasks, 1151 + .num_intmasks = ARRAY_SIZE(tegra234_mc_intmasks), 1145 1152 .has_addr_hi_reg = true, 1146 1153 .ops = &tegra186_mc_ops, 1147 1154 .icc_ops = &tegra234_mc_icc_ops, ··· 1159 1152 * supported. 1160 1153 */ 1161 1154 .num_carveouts = 32, 1155 + .regs = &tegra20_mc_regs, 1156 + .handle_irq = tegra30_mc_irq_handlers, 1157 + .num_interrupts = ARRAY_SIZE(tegra30_mc_irq_handlers), 1158 + .mc_addr_hi_mask = 0x3, 1159 + .mc_err_status_type_mask = (0x7 << 28), 1162 1160 };
+415 -5
drivers/memory/tegra/tegra264.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 - * Copyright (C) 2025, NVIDIA CORPORATION. All rights reserved. 3 + * Copyright (C) 2025-2026, NVIDIA CORPORATION. All rights reserved. 4 4 */ 5 5 6 6 #include <dt-bindings/memory/nvidia,tegra264.h> ··· 188 188 }, 189 189 }; 190 190 191 + static const char *const tegra264_hub_error_names[32] = { 192 + [0] = "coalescer error", 193 + [1] = "SMMU BYPASS ALLOW error", 194 + [2] = "Illegal tbugrp_id error", 195 + [3] = "Malformed MSI request error", 196 + [4] = "Read response with poison bit error", 197 + [5] = "Restricted access violation error", 198 + [6] = "Reserved PA error", 199 + }; 200 + 201 + static const char *const tegra264_mc_error_names[4] = { 202 + [1] = "EMEM decode error", 203 + [2] = "TrustZone violation", 204 + [3] = "Carveout violation", 205 + }; 206 + 207 + static const char *const tegra264_rt_error_names[16] = { 208 + [1] = "DECERR_PARTIAL_POPULATED", 209 + [2] = "DECERR_SMMU_BYPASS", 210 + [3] = "DECERR_INVALID_MMIO", 211 + [4] = "DECERR_INVALID_GIC_MSI", 212 + [5] = "DECERR_ATOMIC_SYSRAM", 213 + [9] = "DECERR_REMOTE_REQ_PRE_BOOT", 214 + [10] = "DECERR_ISO_OVER_C2C", 215 + [11] = "DECERR_UNSUPPORTED_SBS_OPCODE", 216 + [12] = "DECERR_SBS_REQ_OVER_SISO_LL", 217 + }; 218 + 219 + /* 220 + * MC instance aperture mapping for hubc registers 221 + */ 222 + static const int mc_hubc_aperture_number[5] = { 223 + 7, 8, 9, 10, 11 224 + }; 225 + 191 226 /* 192 227 * tegra264_mc_icc_set() - Pass MC client info to the BPMP-FW 193 228 * @src: ICC node for Memory Controller's (MC) Client ··· 318 283 return 0; 319 284 } 320 285 286 + static void mcf_log_fault(struct tegra_mc *mc, u32 channel, unsigned long mcf_ch_intstatus) 287 + { 288 + unsigned int bit; 289 + 290 + for_each_set_bit(bit, &mcf_ch_intstatus, 32) { 291 + const char *client = "unknown", *desc = "NA"; 292 + u32 status_reg, status1_reg = 0, addr_reg, addr_hi_reg = 0, err_type_mask = 0; 293 + u32 value, client_id, i, addr_hi_shift = 0, addr_hi_mask = 0, status1; 294 + u32 mc_rw_bit = MC_ERR_STATUS_RW, mc_sec_bit = MC_ERR_STATUS_SECURITY; 295 + phys_addr_t addr = 0; 296 + u8 type; 297 + 298 + switch (BIT(bit)) { 299 + case MC_INT_DECERR_EMEM: 300 + case MC_INT_SECURITY_VIOLATION: 301 + status_reg = mc->soc->regs->err_status; 302 + addr_reg = mc->soc->regs->err_add; 303 + addr_hi_reg = mc->soc->regs->err_add_hi; 304 + err_type_mask = mc->soc->mc_err_status_type_mask; 305 + break; 306 + 307 + case MC_INT_DECERR_VPR: 308 + status_reg = mc->soc->regs->err_vpr_status; 309 + addr_reg = mc->soc->regs->err_vpr_add; 310 + addr_hi_shift = MC_ERR_STATUS_ADR_HI_SHIFT; 311 + addr_hi_mask = mc->soc->mc_addr_hi_mask; 312 + break; 313 + 314 + case MC_INT_SECERR_SEC: 315 + status_reg = mc->soc->regs->err_sec_status; 316 + addr_reg = mc->soc->regs->err_sec_add; 317 + addr_hi_shift = MC_ERR_STATUS_ADR_HI_SHIFT; 318 + addr_hi_mask = mc->soc->mc_addr_hi_mask; 319 + break; 320 + 321 + case MC_INT_DECERR_MTS: 322 + status_reg = mc->soc->regs->err_mts_status; 323 + addr_reg = mc->soc->regs->err_mts_add; 324 + addr_hi_shift = MC_ERR_STATUS_ADR_HI_SHIFT; 325 + addr_hi_mask = mc->soc->mc_addr_hi_mask; 326 + break; 327 + 328 + case MC_INT_DECERR_GENERALIZED_CARVEOUT: 329 + status_reg = mc->soc->regs->err_gen_co_status; 330 + status1_reg = MC_ERR_GENERALIZED_CARVEOUT_STATUS_1_0; 331 + addr_reg = mc->soc->regs->err_gen_co_add; 332 + addr_hi_shift = MC_ERR_STATUS_GSC_ADR_HI_SHIFT; 333 + addr_hi_mask = MC_ERR_STATUS_GSC_ADR_HI_MASK; 334 + break; 335 + 336 + case MC_INT_DECERR_ROUTE_SANITY: 337 + case MC_INT_DECERR_ROUTE_SANITY_GIC_MSI: 338 + status_reg = mc->soc->regs->err_route_status; 339 + addr_reg = mc->soc->regs->err_route_add; 340 + addr_hi_shift = MC_ERR_STATUS_RT_ADR_HI_SHIFT; 341 + addr_hi_mask = mc->soc->mc_addr_hi_mask; 342 + mc_sec_bit = MC_ERR_ROUTE_SANITY_SEC; 343 + mc_rw_bit = MC_ERR_ROUTE_SANITY_RW; 344 + err_type_mask = MC_ERR_STATUS_RT_TYPE_MASK; 345 + break; 346 + 347 + default: 348 + dev_err_ratelimited(mc->dev, "Incorrect MC interrupt mask\n"); 349 + return; 350 + } 351 + 352 + value = mc_ch_readl(mc, channel, status_reg); 353 + if (addr_hi_reg) { 354 + addr = mc_ch_readl(mc, channel, addr_hi_reg); 355 + } else { 356 + if (!status1_reg) { 357 + addr = ((value >> addr_hi_shift) & addr_hi_mask); 358 + } else { 359 + status1 = mc_ch_readl(mc, channel, status1_reg); 360 + addr = ((status1 >> addr_hi_shift) & addr_hi_mask); 361 + } 362 + } 363 + 364 + addr <<= 32; 365 + addr |= mc_ch_readl(mc, channel, addr_reg); 366 + 367 + client_id = value & mc->soc->client_id_mask; 368 + for (i = 0; i < mc->soc->num_clients; i++) { 369 + if (mc->soc->clients[i].id == client_id) { 370 + client = mc->soc->clients[i].name; 371 + break; 372 + } 373 + } 374 + 375 + if (err_type_mask == MC_ERR_STATUS_RT_TYPE_MASK) { 376 + type = (value & err_type_mask) >> 377 + MC_ERR_STATUS_RT_TYPE_SHIFT; 378 + desc = tegra264_rt_error_names[type]; 379 + } else if (err_type_mask) { 380 + type = (value & err_type_mask) >> 381 + MC_ERR_STATUS_TYPE_SHIFT; 382 + desc = tegra264_mc_error_names[type]; 383 + } 384 + 385 + dev_err_ratelimited(mc->dev, "%s: %s %s @%pa: %s (%s)\n", 386 + client, value & mc_sec_bit ? "secure" : "non-secure", 387 + value & mc_rw_bit ? "write" : "read", &addr, 388 + tegra_mc_status_names[bit] ?: "unknown", desc); 389 + if (status1_reg) 390 + dev_err_ratelimited(mc->dev, "gsc_apr_id=%u gsc_co_apr_id=%u\n", 391 + ((status1 >> ERR_GENERALIZED_APERTURE_ID_SHIFT) 392 + & ERR_GENERALIZED_APERTURE_ID_MASK), 393 + ((status1 >> ERR_GENERALIZED_CARVEOUT_APERTURE_ID_SHIFT) 394 + & ERR_GENERALIZED_CARVEOUT_APERTURE_ID_MASK)); 395 + } 396 + 397 + /* clear interrupts */ 398 + mc_ch_writel(mc, channel, mcf_ch_intstatus, MCF_INTSTATUS_0); 399 + } 400 + 401 + static irqreturn_t handle_mcf_irq(int irq, void *data) 402 + { 403 + struct tegra_mc *mc = data; 404 + unsigned long common_intstat, intstatus; 405 + u32 slice; 406 + 407 + /* Read MCF_COMMON_INTSTATUS0_0_0 from MCB block */ 408 + common_intstat = mc_ch_readl(mc, MC_BROADCAST_CHANNEL, MCF_COMMON_INTSTATUS0_0_0); 409 + if (common_intstat == 0) { 410 + dev_warn(mc->dev, "No interrupt in MCF\n"); 411 + return IRQ_NONE; 412 + } 413 + 414 + for_each_set_bit(slice, &common_intstat, 32) { 415 + /* Find out the slice number on which interrupt occurred */ 416 + if (slice > 4) { 417 + dev_err(mc->dev, "Slice index out of bounds: %u\n", slice); 418 + return IRQ_NONE; 419 + } 420 + 421 + intstatus = mc_ch_readl(mc, slice, MCF_INTSTATUS_0); 422 + if (intstatus != 0) 423 + mcf_log_fault(mc, slice, intstatus); 424 + } 425 + 426 + return IRQ_HANDLED; 427 + } 428 + 429 + static void hub_log_fault(struct tegra_mc *mc, u32 hub, unsigned long hub_intstat) 430 + { 431 + unsigned int bit; 432 + 433 + for_each_set_bit(bit, &hub_intstat, 32) { 434 + const char *client = "unknown"; 435 + u32 client_id, status_reg, value, i; 436 + phys_addr_t addr = 0; 437 + 438 + switch (BIT(bit)) { 439 + case MSS_HUB_COALESCER_ERR_INTMASK: 440 + status_reg = MSS_HUB_COALESCE_ERR_STATUS_0; 441 + addr = mc_ch_readl(mc, hub, MSS_HUB_COALESCE_ERR_ADR_HI_0); 442 + addr <<= 32; 443 + addr |= mc_ch_readl(mc, hub, MSS_HUB_COALESCE_ERR_ADR_0); 444 + break; 445 + 446 + case MSS_HUB_SMMU_BYPASS_ALLOW_ERR_INTMASK: 447 + status_reg = MSS_HUB_SMMU_BYPASS_ALLOW_ERR_STATUS_0; 448 + break; 449 + 450 + case MSS_HUB_ILLEGAL_TBUGRP_ID_INTMASK: 451 + status_reg = MSS_HUB_ILLEGAL_TBUGRP_ID_ERR_STATUS_0; 452 + break; 453 + 454 + case MSS_HUB_MSI_ERR_INTMASK: 455 + status_reg = MSS_HUB_MSI_ERR_STATUS_0; 456 + break; 457 + 458 + case MSS_HUB_POISON_RSP_INTMASK: 459 + status_reg = MSS_HUB_POISON_RSP_STATUS_0; 460 + break; 461 + 462 + case MSS_HUB_RESTRICTED_ACCESS_ERR_INTMASK: 463 + status_reg = MSS_HUB_RESTRICTED_ACCESS_ERR_STATUS_0; 464 + break; 465 + 466 + case MSS_HUB_RESERVED_PA_ERR_INTMASK: 467 + status_reg = MSS_HUB_RESERVED_PA_ERR_STATUS_0; 468 + break; 469 + 470 + default: 471 + dev_err_ratelimited(mc->dev, "Incorrect HUB interrupt mask\n"); 472 + return; 473 + } 474 + 475 + value = mc_ch_readl(mc, hub, status_reg); 476 + 477 + client_id = value & mc->soc->client_id_mask; 478 + for (i = 0; i < mc->soc->num_clients; i++) { 479 + if (mc->soc->clients[i].id == client_id) { 480 + client = mc->soc->clients[i].name; 481 + break; 482 + } 483 + } 484 + 485 + dev_err_ratelimited(mc->dev, "%s: @%pa: %s status: 0x%x\n", 486 + client, &addr, tegra264_hub_error_names[bit] ?: "unknown", 487 + value); 488 + } 489 + 490 + /* clear interrupts */ 491 + mc_ch_writel(mc, hub, hub_intstat, MSS_HUB_INTRSTATUS_0); 492 + } 493 + 494 + static irqreturn_t handle_hub_irq(int irq, void *data, int mc_hubc_aperture_number) 495 + { 496 + struct tegra_mc *mc = data; 497 + u32 global_intstat; 498 + unsigned long hub_interrupt, intstat, hub; 499 + 500 + /* Read MSS_HUB_GLOBAL_INTSTATUS_0 from mc_hubc_aperture_number block */ 501 + global_intstat = mc_ch_readl(mc, mc_hubc_aperture_number, MSS_HUB_GLOBAL_INTSTATUS_0); 502 + if (global_intstat == 0) { 503 + dev_warn(mc->dev, "No interrupt in HUB/HUBC\n"); 504 + return IRQ_NONE; 505 + } 506 + 507 + /* Handle interrupt from hubc */ 508 + if (global_intstat & MSS_HUBC_INTR) { 509 + /* Read MSS_HUB_HUBC_INTSTATUS_0 from block mc_hubc_aperture_number */ 510 + intstat = mc_ch_readl(mc, mc_hubc_aperture_number, MSS_HUB_HUBC_INTSTATUS_0); 511 + if (intstat != 0) { 512 + dev_err_ratelimited(mc->dev, "Scrubber operation status: 0x%lx\n", 513 + intstat); 514 + /* Clear hubc interrupt */ 515 + mc_ch_writel(mc, mc_hubc_aperture_number, intstat, 516 + MSS_HUB_HUBC_INTSTATUS_0); 517 + } 518 + } 519 + 520 + hub_interrupt = (global_intstat & MSS_HUB_GLOBAL_MASK) >> MSS_HUB_GLOBAL_SHIFT; 521 + /* Handle interrupt from hub */ 522 + for_each_set_bit(hub, &hub_interrupt, 32) { 523 + /* Read MSS_HUB_INTRSTATUS_0 from block MCi */ 524 + intstat = mc_ch_readl(mc, hub, MSS_HUB_INTRSTATUS_0); 525 + if (intstat != 0) 526 + hub_log_fault(mc, hub, intstat); 527 + } 528 + 529 + /* Clear global interrupt status register */ 530 + mc_ch_writel(mc, mc_hubc_aperture_number, global_intstat, MSS_HUB_GLOBAL_INTSTATUS_0); 531 + return IRQ_HANDLED; 532 + } 533 + 534 + static irqreturn_t handle_disp_hub_irq(int irq, void *data) 535 + { 536 + return handle_hub_irq(irq, data, mc_hubc_aperture_number[0]); 537 + } 538 + 539 + static irqreturn_t handle_system_hub_irq(int irq, void *data) 540 + { 541 + return handle_hub_irq(irq, data, mc_hubc_aperture_number[1]); 542 + } 543 + 544 + static irqreturn_t handle_vision_hub_irq(int irq, void *data) 545 + { 546 + return handle_hub_irq(irq, data, mc_hubc_aperture_number[2]); 547 + } 548 + 549 + static irqreturn_t handle_uphy_hub_irq(int irq, void *data) 550 + { 551 + return handle_hub_irq(irq, data, mc_hubc_aperture_number[3]); 552 + } 553 + 554 + static irqreturn_t handle_top_hub_irq(int irq, void *data) 555 + { 556 + return handle_hub_irq(irq, data, mc_hubc_aperture_number[4]); 557 + } 558 + 559 + static irqreturn_t handle_generic_irq(struct tegra_mc *mc, unsigned long intstat_reg) 560 + { 561 + u32 intstat, i; 562 + 563 + /* Iterate over all MC blocks to read INTSTATUS */ 564 + for (i = 0; i < mc->num_channels; i++) { 565 + intstat = mc_ch_readl(mc, i, intstat_reg); 566 + if (intstat) { 567 + dev_err_ratelimited(mc->dev, "channel: %i status: 0x%x\n", i, intstat); 568 + /* Clear interrupt */ 569 + mc_ch_writel(mc, i, intstat, intstat_reg); 570 + } 571 + } 572 + 573 + return IRQ_HANDLED; 574 + } 575 + 576 + static irqreturn_t handle_sbs_irq(int irq, void *data) 577 + { 578 + return handle_generic_irq((struct tegra_mc *)data, MSS_SBS_INTSTATUS_0); 579 + } 580 + 581 + static irqreturn_t handle_channel_irq(int irq, void *data) 582 + { 583 + return handle_generic_irq((struct tegra_mc *)data, MC_CH_INTSTATUS_0); 584 + } 585 + 586 + static const irq_handler_t tegra264_mc_irq_handlers[8] = { 587 + handle_mcf_irq, handle_disp_hub_irq, handle_vision_hub_irq, 588 + handle_system_hub_irq, handle_uphy_hub_irq, handle_top_hub_irq, 589 + handle_sbs_irq, handle_channel_irq 590 + }; 591 + 321 592 static const struct tegra_mc_icc_ops tegra264_mc_icc_ops = { 322 593 .xlate = tegra_mc_icc_xlate, 323 594 .aggregate = tegra264_mc_icc_aggregate, 324 595 .get_bw = tegra264_mc_icc_get_init_bw, 325 596 .set = tegra264_mc_icc_set, 597 + }; 598 + 599 + static const struct tegra_mc_regs tegra264_mc_regs = { 600 + .cfg_channel_enable = 0x8870, 601 + .err_status = 0xbc00, 602 + .err_add = 0xbc04, 603 + .err_add_hi = 0xbc08, 604 + .err_vpr_status = 0xbc20, 605 + .err_vpr_add = 0xbc24, 606 + .err_sec_status = 0xbc3c, 607 + .err_sec_add = 0xbc40, 608 + .err_mts_status = 0xbc5c, 609 + .err_mts_add = 0xbc60, 610 + .err_gen_co_status = 0xbc78, 611 + .err_gen_co_add = 0xbc7c, 612 + .err_route_status = 0xbc64, 613 + .err_route_add = 0xbc68, 614 + }; 615 + 616 + static const struct tegra_mc_intmask tegra264_mc_intmasks[] = { 617 + { 618 + .reg = MCF_INTMASK_0, 619 + .mask = MC_INT_DECERR_ROUTE_SANITY_GIC_MSI | MC_INT_DECERR_ROUTE_SANITY | 620 + MC_INT_DECERR_GENERALIZED_CARVEOUT | MC_INT_DECERR_MTS | 621 + MC_INT_SECERR_SEC | MC_INT_DECERR_VPR | MC_INT_SECURITY_VIOLATION | 622 + MC_INT_DECERR_EMEM, 623 + }, 624 + { 625 + .reg = MCF_INTPRIORITY_0, 626 + .mask = MC_INT_DECERR_ROUTE_SANITY_GIC_MSI | MC_INT_DECERR_ROUTE_SANITY | 627 + MC_INT_DECERR_GENERALIZED_CARVEOUT | MC_INT_DECERR_MTS | 628 + MC_INT_SECERR_SEC | MC_INT_DECERR_VPR | MC_INT_SECURITY_VIOLATION | 629 + MC_INT_DECERR_EMEM, 630 + }, 631 + { 632 + .reg = MSS_HUB_INTRMASK_0, 633 + .mask = MSS_HUB_COALESCER_ERR_INTMASK | MSS_HUB_SMMU_BYPASS_ALLOW_ERR_INTMASK | 634 + MSS_HUB_ILLEGAL_TBUGRP_ID_INTMASK | MSS_HUB_MSI_ERR_INTMASK | 635 + MSS_HUB_POISON_RSP_INTMASK | MSS_HUB_RESTRICTED_ACCESS_ERR_INTMASK | 636 + MSS_HUB_RESERVED_PA_ERR_INTMASK, 637 + }, 638 + { 639 + .reg = MSS_HUB_INTRPRIORITY_0, 640 + .mask = MSS_HUB_COALESCER_ERR_INTMASK | MSS_HUB_SMMU_BYPASS_ALLOW_ERR_INTMASK | 641 + MSS_HUB_ILLEGAL_TBUGRP_ID_INTMASK | MSS_HUB_MSI_ERR_INTMASK | 642 + MSS_HUB_POISON_RSP_INTMASK | MSS_HUB_RESTRICTED_ACCESS_ERR_INTMASK | 643 + MSS_HUB_RESERVED_PA_ERR_INTMASK, 644 + }, 645 + { 646 + .reg = MSS_HUB_HUBC_INTMASK_0, 647 + .mask = MSS_HUB_HUBC_SCRUB_DONE_INTMASK, 648 + }, 649 + { 650 + .reg = MSS_HUB_HUBC_INTPRIORITY_0, 651 + .mask = MSS_HUB_HUBC_SCRUB_DONE_INTMASK, 652 + }, 653 + { 654 + .reg = MSS_SBS_INTMASK_0, 655 + .mask = MSS_SBS_FILL_FIFO_ISO_OVERFLOW_INTMASK | 656 + MSS_SBS_FILL_FIFO_SISO_OVERFLOW_INTMASK | 657 + MSS_SBS_FILL_FIFO_NISO_OVERFLOW_INTMASK, 658 + }, 659 + { 660 + .reg = MC_CH_INTMASK_0, 661 + .mask = WCAM_ERR_INTMASK, 662 + } 326 663 }; 327 664 328 665 const struct tegra_mc_soc tegra264_mc_soc = { ··· 703 296 .num_address_bits = 40, 704 297 .num_channels = 16, 705 298 .client_id_mask = 0x1ff, 706 - .intmask = MC_INT_DECERR_ROUTE_SANITY | 707 - MC_INT_DECERR_GENERALIZED_CARVEOUT | MC_INT_DECERR_MTS | 708 - MC_INT_SECERR_SEC | MC_INT_DECERR_VPR | 709 - MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM, 299 + .intmasks = tegra264_mc_intmasks, 300 + .num_intmasks = ARRAY_SIZE(tegra264_mc_intmasks), 710 301 .has_addr_hi_reg = true, 711 302 .ops = &tegra186_mc_ops, 712 303 .icc_ops = &tegra264_mc_icc_ops, ··· 715 310 * supported. 716 311 */ 717 312 .num_carveouts = 32, 313 + .mc_addr_hi_mask = 0xff, 314 + .mc_err_status_type_mask = (0x3 << 28), 315 + .regs = &tegra264_mc_regs, 316 + .handle_irq = tegra264_mc_irq_handlers, 317 + .num_interrupts = ARRAY_SIZE(tegra264_mc_irq_handlers), 718 318 };
+3 -3
drivers/memory/tegra/tegra30-emc.c
··· 554 554 emc->emc_cfg = readl_relaxed(emc->regs + EMC_CFG); 555 555 emc_dbg = readl_relaxed(emc->regs + EMC_DBG); 556 556 557 - if (emc->dll_on == !!(timing->emc_mode_1 & 0x1)) 557 + if (emc->dll_on == !(timing->emc_mode_1 & 0x1)) 558 558 dll_change = DLL_CHANGE_NONE; 559 - else if (timing->emc_mode_1 & 0x1) 559 + else if (!(timing->emc_mode_1 & 0x1)) 560 560 dll_change = DLL_CHANGE_ON; 561 561 else 562 562 dll_change = DLL_CHANGE_OFF; 563 563 564 - emc->dll_on = !!(timing->emc_mode_1 & 0x1); 564 + emc->dll_on = !(timing->emc_mode_1 & 0x1); 565 565 566 566 if (timing->data[80] && !readl_relaxed(emc->regs + EMC_ZCAL_INTERVAL)) 567 567 emc->zcal_long = true;
+15 -3
drivers/memory/tegra/tegra30.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 - * Copyright (C) 2014 NVIDIA CORPORATION. All rights reserved. 3 + * Copyright (C) 2014-2026 NVIDIA CORPORATION. All rights reserved. 4 4 */ 5 5 6 6 #include <linux/device.h> ··· 1384 1384 .set = tegra30_mc_icc_set, 1385 1385 }; 1386 1386 1387 + static const struct tegra_mc_intmask tegra30_mc_intmasks[] = { 1388 + { 1389 + .reg = MC_INTMASK, 1390 + .mask = MC_INT_INVALID_SMMU_PAGE | MC_INT_SECURITY_VIOLATION | 1391 + MC_INT_DECERR_EMEM, 1392 + }, 1393 + }; 1394 + 1387 1395 const struct tegra_mc_soc tegra30_mc_soc = { 1388 1396 .clients = tegra30_mc_clients, 1389 1397 .num_clients = ARRAY_SIZE(tegra30_mc_clients), ··· 1401 1393 .smmu = &tegra30_smmu_soc, 1402 1394 .emem_regs = tegra30_mc_emem_regs, 1403 1395 .num_emem_regs = ARRAY_SIZE(tegra30_mc_emem_regs), 1404 - .intmask = MC_INT_INVALID_SMMU_PAGE | MC_INT_SECURITY_VIOLATION | 1405 - MC_INT_DECERR_EMEM, 1396 + .intmasks = tegra30_mc_intmasks, 1397 + .num_intmasks = ARRAY_SIZE(tegra30_mc_intmasks), 1406 1398 .reset_ops = &tegra_mc_reset_ops_common, 1407 1399 .resets = tegra30_mc_resets, 1408 1400 .num_resets = ARRAY_SIZE(tegra30_mc_resets), 1409 1401 .icc_ops = &tegra30_mc_icc_ops, 1410 1402 .ops = &tegra30_mc_ops, 1403 + .regs = &tegra20_mc_regs, 1404 + .handle_irq = tegra30_mc_irq_handlers, 1405 + .num_interrupts = ARRAY_SIZE(tegra30_mc_irq_handlers), 1406 + .mc_err_status_type_mask = (0x7 << 28), 1411 1407 };
+35 -5
include/soc/tegra/mc.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 2 /* 3 - * Copyright (C) 2014 NVIDIA Corporation 3 + * Copyright (C) 2014-2026 NVIDIA Corporation 4 4 */ 5 5 6 6 #ifndef __SOC_TEGRA_MC_H__ ··· 10 10 #include <linux/debugfs.h> 11 11 #include <linux/err.h> 12 12 #include <linux/interconnect-provider.h> 13 + #include <linux/interrupt.h> 13 14 #include <linux/irq.h> 14 15 #include <linux/reset-controller.h> 15 - #include <linux/types.h> 16 16 #include <linux/tegra-icc.h> 17 + #include <linux/types.h> 17 18 18 19 struct clk; 19 20 struct device; ··· 165 164 int (*probe)(struct tegra_mc *mc); 166 165 void (*remove)(struct tegra_mc *mc); 167 166 int (*resume)(struct tegra_mc *mc); 168 - irqreturn_t (*handle_irq)(int irq, void *data); 169 167 int (*probe_device)(struct tegra_mc *mc, struct device *dev); 168 + }; 169 + 170 + struct tegra_mc_regs { 171 + unsigned int cfg_channel_enable; 172 + unsigned int err_status; 173 + unsigned int err_add; 174 + unsigned int err_add_hi; 175 + unsigned int err_vpr_status; 176 + unsigned int err_vpr_add; 177 + unsigned int err_sec_status; 178 + unsigned int err_sec_add; 179 + unsigned int err_mts_status; 180 + unsigned int err_mts_add; 181 + unsigned int err_gen_co_status; 182 + unsigned int err_gen_co_add; 183 + unsigned int err_route_status; 184 + unsigned int err_route_add; 185 + }; 186 + 187 + struct tegra_mc_intmask { 188 + u32 reg; 189 + u32 mask; 170 190 }; 171 191 172 192 struct tegra_mc_soc { ··· 207 185 208 186 const struct tegra_smmu_soc *smmu; 209 187 210 - u32 intmask; 211 188 u32 ch_intmask; 212 189 u32 global_intstatus_channel_shift; 213 190 bool has_addr_hi_reg; ··· 217 196 218 197 const struct tegra_mc_icc_ops *icc_ops; 219 198 const struct tegra_mc_ops *ops; 199 + const struct tegra_mc_regs *regs; 200 + 201 + const irq_handler_t *handle_irq; 202 + unsigned int num_interrupts; 203 + unsigned int mc_addr_hi_mask; 204 + unsigned int mc_err_status_type_mask; 205 + const struct tegra_mc_intmask *intmasks; 206 + unsigned int num_intmasks; 220 207 }; 221 208 222 209 struct tegra_mc { ··· 235 206 void __iomem *bcast_ch_regs; 236 207 void __iomem **ch_regs; 237 208 struct clk *clk; 238 - int irq; 239 209 240 210 const struct tegra_mc_soc *soc; 241 211 unsigned long tick; ··· 283 255 return -ENODEV; 284 256 } 285 257 #endif 258 + 259 + extern const struct tegra_mc_regs tegra20_mc_regs; 286 260 287 261 #endif /* __SOC_TEGRA_MC_H__ */