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