1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2019-2025 NVIDIA CORPORATION. All rights reserved. 4 */ 5 6 #include <linux/cleanup.h> 7 #include <linux/clk.h> 8 #include <linux/debugfs.h> 9 #include <linux/fs.h> 10 #include <linux/module.h> 11 #include <linux/mutex.h> 12 #include <linux/of_platform.h> 13 #include <linux/platform_device.h> 14 15 #include <soc/tegra/bpmp.h> 16 #include "mc.h" 17 18 static DEFINE_MUTEX(tegra_emc_debugfs_root_lock); 19 static struct dentry *tegra_emc_debugfs_root; 20 21 struct tegra186_emc_dvfs { 22 unsigned long latency; 23 unsigned long rate; 24 }; 25 26 struct tegra186_emc { 27 struct tegra_bpmp *bpmp; 28 struct device *dev; 29 struct clk *clk; 30 struct clk *clk_dbb; 31 32 struct tegra186_emc_dvfs *dvfs; 33 unsigned int num_dvfs; 34 35 struct { 36 struct dentry *root; 37 unsigned long min_rate; 38 unsigned long max_rate; 39 } debugfs; 40 41 struct icc_provider provider; 42 }; 43 44 /* 45 * debugfs interface 46 * 47 * The memory controller driver exposes some files in debugfs that can be used 48 * to control the EMC frequency. The top-level directory can be found here: 49 * 50 * /sys/kernel/debug/emc 51 * 52 * It contains the following files: 53 * 54 * - available_rates: This file contains a list of valid, space-separated 55 * EMC frequencies. 56 * 57 * - min_rate: Writing a value to this file sets the given frequency as the 58 * floor of the permitted range. If this is higher than the currently 59 * configured EMC frequency, this will cause the frequency to be 60 * increased so that it stays within the valid range. 61 * 62 * - max_rate: Similarily to the min_rate file, writing a value to this file 63 * sets the given frequency as the ceiling of the permitted range. If 64 * the value is lower than the currently configured EMC frequency, this 65 * will cause the frequency to be decreased so that it stays within the 66 * valid range. 67 */ 68 69 static bool tegra186_emc_validate_rate(struct tegra186_emc *emc, 70 unsigned long rate) 71 { 72 unsigned int i; 73 74 for (i = 0; i < emc->num_dvfs; i++) 75 if (rate == emc->dvfs[i].rate) 76 return true; 77 78 return false; 79 } 80 81 static int tegra186_emc_debug_available_rates_show(struct seq_file *s, 82 void *data) 83 { 84 struct tegra186_emc *emc = s->private; 85 const char *prefix = ""; 86 unsigned int i; 87 88 for (i = 0; i < emc->num_dvfs; i++) { 89 seq_printf(s, "%s%lu", prefix, emc->dvfs[i].rate); 90 prefix = " "; 91 } 92 93 seq_puts(s, "\n"); 94 95 return 0; 96 } 97 DEFINE_SHOW_ATTRIBUTE(tegra186_emc_debug_available_rates); 98 99 static int tegra186_emc_debug_min_rate_get(void *data, u64 *rate) 100 { 101 struct tegra186_emc *emc = data; 102 103 *rate = emc->debugfs.min_rate; 104 105 return 0; 106 } 107 108 static int tegra186_emc_debug_min_rate_set(void *data, u64 rate) 109 { 110 struct tegra186_emc *emc = data; 111 int err; 112 113 if (!tegra186_emc_validate_rate(emc, rate)) 114 return -EINVAL; 115 116 err = clk_set_min_rate(emc->clk, rate); 117 if (err < 0) 118 return err; 119 120 emc->debugfs.min_rate = rate; 121 122 return 0; 123 } 124 125 DEFINE_DEBUGFS_ATTRIBUTE(tegra186_emc_debug_min_rate_fops, 126 tegra186_emc_debug_min_rate_get, 127 tegra186_emc_debug_min_rate_set, "%llu\n"); 128 129 static int tegra186_emc_debug_max_rate_get(void *data, u64 *rate) 130 { 131 struct tegra186_emc *emc = data; 132 133 *rate = emc->debugfs.max_rate; 134 135 return 0; 136 } 137 138 static int tegra186_emc_debug_max_rate_set(void *data, u64 rate) 139 { 140 struct tegra186_emc *emc = data; 141 int err; 142 143 if (!tegra186_emc_validate_rate(emc, rate)) 144 return -EINVAL; 145 146 err = clk_set_max_rate(emc->clk, rate); 147 if (err < 0) 148 return err; 149 150 emc->debugfs.max_rate = rate; 151 152 return 0; 153 } 154 155 DEFINE_DEBUGFS_ATTRIBUTE(tegra186_emc_debug_max_rate_fops, 156 tegra186_emc_debug_max_rate_get, 157 tegra186_emc_debug_max_rate_set, "%llu\n"); 158 159 static int tegra186_emc_get_emc_dvfs_latency(struct tegra186_emc *emc) 160 { 161 struct mrq_emc_dvfs_latency_response response; 162 struct tegra_bpmp_message msg; 163 unsigned int i; 164 int err; 165 166 memset(&msg, 0, sizeof(msg)); 167 msg.mrq = MRQ_EMC_DVFS_LATENCY; 168 msg.tx.data = NULL; 169 msg.tx.size = 0; 170 msg.rx.data = &response; 171 msg.rx.size = sizeof(response); 172 173 err = tegra_bpmp_transfer(emc->bpmp, &msg); 174 if (err < 0) { 175 dev_err(emc->dev, "failed to EMC DVFS pairs: %d\n", err); 176 return err; 177 } 178 if (msg.rx.ret < 0) { 179 dev_err(emc->dev, "EMC DVFS MRQ failed: %d (BPMP error code)\n", msg.rx.ret); 180 return -EINVAL; 181 } 182 183 emc->debugfs.min_rate = ULONG_MAX; 184 emc->debugfs.max_rate = 0; 185 186 emc->num_dvfs = response.num_pairs; 187 188 emc->dvfs = devm_kmalloc_array(emc->dev, emc->num_dvfs, sizeof(*emc->dvfs), GFP_KERNEL); 189 if (!emc->dvfs) 190 return -ENOMEM; 191 192 dev_dbg(emc->dev, "%u DVFS pairs:\n", emc->num_dvfs); 193 194 for (i = 0; i < emc->num_dvfs; i++) { 195 emc->dvfs[i].rate = response.pairs[i].freq * 1000; 196 emc->dvfs[i].latency = response.pairs[i].latency; 197 198 if (emc->dvfs[i].rate < emc->debugfs.min_rate) 199 emc->debugfs.min_rate = emc->dvfs[i].rate; 200 201 if (emc->dvfs[i].rate > emc->debugfs.max_rate) 202 emc->debugfs.max_rate = emc->dvfs[i].rate; 203 204 dev_dbg(emc->dev, " %2u: %lu Hz -> %lu us\n", i, 205 emc->dvfs[i].rate, emc->dvfs[i].latency); 206 } 207 208 err = clk_set_rate_range(emc->clk, emc->debugfs.min_rate, emc->debugfs.max_rate); 209 if (err < 0) { 210 dev_err(emc->dev, "failed to set rate range [%lu-%lu] for %pC\n", 211 emc->debugfs.min_rate, emc->debugfs.max_rate, emc->clk); 212 return err; 213 } 214 215 scoped_guard(mutex, &tegra_emc_debugfs_root_lock) { 216 if (!tegra_emc_debugfs_root) 217 tegra_emc_debugfs_root = debugfs_create_dir("emc", NULL); 218 219 if (dev_to_node(emc->dev) == NUMA_NO_NODE) 220 emc->debugfs.root = tegra_emc_debugfs_root; 221 else 222 emc->debugfs.root = debugfs_create_dir(dev_name(emc->dev), 223 tegra_emc_debugfs_root); 224 } 225 226 debugfs_create_file("available_rates", 0444, emc->debugfs.root, emc, 227 &tegra186_emc_debug_available_rates_fops); 228 debugfs_create_file("min_rate", 0644, emc->debugfs.root, emc, 229 &tegra186_emc_debug_min_rate_fops); 230 debugfs_create_file("max_rate", 0644, emc->debugfs.root, emc, 231 &tegra186_emc_debug_max_rate_fops); 232 233 return 0; 234 } 235 236 /* 237 * tegra186_emc_icc_set_bw() - Set BW api for EMC provider 238 * @src: ICC node for External Memory Controller (EMC) 239 * @dst: ICC node for External Memory (DRAM) 240 * 241 * Do nothing here as info to BPMP-FW is now passed in the BW set function 242 * of the MC driver. BPMP-FW sets the final Freq based on the passed values. 243 */ 244 static int tegra186_emc_icc_set_bw(struct icc_node *src, struct icc_node *dst) 245 { 246 return 0; 247 } 248 249 static struct icc_node * 250 tegra186_emc_of_icc_xlate(const struct of_phandle_args *spec, void *data) 251 { 252 struct icc_provider *provider = data; 253 struct icc_node *node; 254 255 /* External Memory is the only possible ICC route */ 256 list_for_each_entry(node, &provider->nodes, node_list) { 257 if (tegra_mc_client_id_from_node(node) != TEGRA_ICC_EMEM) 258 continue; 259 260 return node; 261 } 262 263 return ERR_PTR(-EPROBE_DEFER); 264 } 265 266 static int tegra186_emc_icc_get_init_bw(struct icc_node *node, u32 *avg, u32 *peak) 267 { 268 *avg = 0; 269 *peak = 0; 270 271 return 0; 272 } 273 274 static int tegra186_emc_interconnect_init(struct tegra186_emc *emc) 275 { 276 int node_id = dev_to_node(emc->dev->parent); 277 struct icc_node *node; 278 int err; 279 280 emc->provider.dev = emc->dev; 281 emc->provider.set = tegra186_emc_icc_set_bw; 282 emc->provider.data = &emc->provider; 283 emc->provider.aggregate = icc_std_aggregate; 284 emc->provider.xlate = tegra186_emc_of_icc_xlate; 285 emc->provider.get_bw = tegra186_emc_icc_get_init_bw; 286 287 icc_provider_init(&emc->provider); 288 289 /* create External Memory Controller node */ 290 node = tegra_mc_icc_node_create(node_id, TEGRA_ICC_EMC); 291 if (IS_ERR(node)) { 292 err = PTR_ERR(node); 293 goto remove_nodes; 294 } 295 296 if (node_id == NUMA_NO_NODE) 297 node->name = "External Memory Controller"; 298 else 299 node->name = dev_name(emc->dev); 300 301 icc_node_add(node, &emc->provider); 302 303 /* link External Memory Controller to External Memory (DRAM) */ 304 err = tegra_mc_icc_link_create(node, node_id, TEGRA_ICC_EMEM); 305 if (err) 306 goto remove_nodes; 307 308 /* create External Memory node */ 309 node = tegra_mc_icc_node_create(node_id, TEGRA_ICC_EMEM); 310 if (IS_ERR(node)) { 311 err = PTR_ERR(node); 312 goto remove_nodes; 313 } 314 315 if (node_id == NUMA_NO_NODE) 316 node->name = "External Memory (DRAM)"; 317 else 318 node->name = devm_kasprintf(emc->dev, GFP_KERNEL, "%d-dram", node_id); 319 320 icc_node_add(node, &emc->provider); 321 322 err = icc_provider_register(&emc->provider); 323 if (err) 324 goto remove_nodes; 325 326 return 0; 327 328 remove_nodes: 329 icc_nodes_remove(&emc->provider); 330 331 return dev_err_probe(emc->dev, err, "failed to initialize ICC\n"); 332 } 333 334 static int tegra186_emc_probe(struct platform_device *pdev) 335 { 336 struct tegra_mc *mc = dev_get_drvdata(pdev->dev.parent); 337 struct tegra186_emc *emc; 338 int err; 339 340 emc = devm_kzalloc(&pdev->dev, sizeof(*emc), GFP_KERNEL); 341 if (!emc) 342 return -ENOMEM; 343 344 emc->bpmp = tegra_bpmp_get(&pdev->dev); 345 if (IS_ERR(emc->bpmp)) 346 return dev_err_probe(&pdev->dev, PTR_ERR(emc->bpmp), 347 "failed to get BPMP\n"); 348 349 emc->clk = devm_clk_get(&pdev->dev, "emc"); 350 if (IS_ERR(emc->clk)) { 351 err = dev_err_probe(&pdev->dev, PTR_ERR(emc->clk), 352 "failed to get EMC clock\n"); 353 goto put_bpmp; 354 } 355 356 emc->clk_dbb = devm_clk_get_optional_enabled(&pdev->dev, "dbb"); 357 if (IS_ERR(emc->clk_dbb)) { 358 err = dev_err_probe(&pdev->dev, PTR_ERR(emc->clk_dbb), 359 "failed to get DBB clock\n"); 360 goto put_bpmp; 361 } 362 363 platform_set_drvdata(pdev, emc); 364 emc->dev = &pdev->dev; 365 366 if (tegra_bpmp_mrq_is_supported(emc->bpmp, MRQ_EMC_DVFS_LATENCY)) { 367 err = tegra186_emc_get_emc_dvfs_latency(emc); 368 if (err) 369 goto put_bpmp; 370 } 371 372 if (mc && mc->soc->icc_ops) { 373 if (tegra_bpmp_mrq_is_supported(emc->bpmp, MRQ_BWMGR_INT)) { 374 mc->bwmgr_mrq_supported = true; 375 376 /* 377 * MC driver probe can't get BPMP reference as it gets probed 378 * earlier than BPMP. So, save the BPMP ref got from the EMC 379 * DT node in the mc->bpmp and use it in MC's icc_set hook. 380 */ 381 mc->bpmp = emc->bpmp; 382 barrier(); 383 } 384 385 /* 386 * Initialize the ICC even if BPMP-FW doesn't support 'MRQ_BWMGR_INT'. 387 * Use the flag 'mc->bwmgr_mrq_supported' within MC driver and return 388 * EINVAL instead of passing the request to BPMP-FW later when the BW 389 * request is made by client with 'icc_set_bw()' call. 390 */ 391 err = tegra186_emc_interconnect_init(emc); 392 if (err) { 393 mc->bpmp = NULL; 394 goto put_bpmp; 395 } 396 } 397 398 return 0; 399 400 put_bpmp: 401 tegra_bpmp_put(emc->bpmp); 402 return err; 403 } 404 405 static void tegra186_emc_remove(struct platform_device *pdev) 406 { 407 struct tegra_mc *mc = dev_get_drvdata(pdev->dev.parent); 408 struct tegra186_emc *emc = platform_get_drvdata(pdev); 409 410 debugfs_remove_recursive(emc->debugfs.root); 411 412 scoped_guard(mutex, &tegra_emc_debugfs_root_lock) { 413 if (emc->debugfs.root == tegra_emc_debugfs_root) { 414 tegra_emc_debugfs_root = NULL; 415 } else if (tegra_emc_debugfs_root && 416 simple_empty(tegra_emc_debugfs_root)) { 417 debugfs_remove(tegra_emc_debugfs_root); 418 tegra_emc_debugfs_root = NULL; 419 } 420 } 421 422 mc->bpmp = NULL; 423 tegra_bpmp_put(emc->bpmp); 424 } 425 426 static const struct of_device_id tegra186_emc_of_match[] = { 427 #if defined(CONFIG_ARCH_TEGRA_186_SOC) 428 { .compatible = "nvidia,tegra186-emc" }, 429 #endif 430 #if defined(CONFIG_ARCH_TEGRA_194_SOC) 431 { .compatible = "nvidia,tegra194-emc" }, 432 #endif 433 #if defined(CONFIG_ARCH_TEGRA_234_SOC) 434 { .compatible = "nvidia,tegra234-emc" }, 435 #endif 436 #if defined(CONFIG_ARCH_TEGRA_264_SOC) 437 { .compatible = "nvidia,tegra264-emc" }, 438 #endif 439 { /* sentinel */ } 440 }; 441 MODULE_DEVICE_TABLE(of, tegra186_emc_of_match); 442 443 static struct platform_driver tegra186_emc_driver = { 444 .driver = { 445 .name = "tegra186-emc", 446 .of_match_table = tegra186_emc_of_match, 447 .suppress_bind_attrs = true, 448 .sync_state = icc_sync_state, 449 }, 450 .probe = tegra186_emc_probe, 451 .remove = tegra186_emc_remove, 452 }; 453 module_platform_driver(tegra186_emc_driver); 454 455 MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>"); 456 MODULE_DESCRIPTION("NVIDIA Tegra186 External Memory Controller driver"); 457