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/platform_device.h> 11 12 #include <soc/tegra/bpmp.h> 13 14 struct tegra186_emc_dvfs { 15 unsigned long latency; 16 unsigned long rate; 17 }; 18 19 struct tegra186_emc { 20 struct tegra_bpmp *bpmp; 21 struct device *dev; 22 struct clk *clk; 23 24 struct tegra186_emc_dvfs *dvfs; 25 unsigned int num_dvfs; 26 27 struct { 28 struct dentry *root; 29 unsigned long min_rate; 30 unsigned long max_rate; 31 } debugfs; 32 }; 33 34 /* 35 * debugfs interface 36 * 37 * The memory controller driver exposes some files in debugfs that can be used 38 * to control the EMC frequency. The top-level directory can be found here: 39 * 40 * /sys/kernel/debug/emc 41 * 42 * It contains the following files: 43 * 44 * - available_rates: This file contains a list of valid, space-separated 45 * EMC frequencies. 46 * 47 * - min_rate: Writing a value to this file sets the given frequency as the 48 * floor of the permitted range. If this is higher than the currently 49 * configured EMC frequency, this will cause the frequency to be 50 * increased so that it stays within the valid range. 51 * 52 * - max_rate: Similarily to the min_rate file, writing a value to this file 53 * sets the given frequency as the ceiling of the permitted range. If 54 * the value is lower than the currently configured EMC frequency, this 55 * will cause the frequency to be decreased so that it stays within the 56 * valid range. 57 */ 58 59 static bool tegra186_emc_validate_rate(struct tegra186_emc *emc, 60 unsigned long rate) 61 { 62 unsigned int i; 63 64 for (i = 0; i < emc->num_dvfs; i++) 65 if (rate == emc->dvfs[i].rate) 66 return true; 67 68 return false; 69 } 70 71 static int tegra186_emc_debug_available_rates_show(struct seq_file *s, 72 void *data) 73 { 74 struct tegra186_emc *emc = s->private; 75 const char *prefix = ""; 76 unsigned int i; 77 78 for (i = 0; i < emc->num_dvfs; i++) { 79 seq_printf(s, "%s%lu", prefix, emc->dvfs[i].rate); 80 prefix = " "; 81 } 82 83 seq_puts(s, "\n"); 84 85 return 0; 86 } 87 DEFINE_SHOW_ATTRIBUTE(tegra186_emc_debug_available_rates); 88 89 static int tegra186_emc_debug_min_rate_get(void *data, u64 *rate) 90 { 91 struct tegra186_emc *emc = data; 92 93 *rate = emc->debugfs.min_rate; 94 95 return 0; 96 } 97 98 static int tegra186_emc_debug_min_rate_set(void *data, u64 rate) 99 { 100 struct tegra186_emc *emc = data; 101 int err; 102 103 if (!tegra186_emc_validate_rate(emc, rate)) 104 return -EINVAL; 105 106 err = clk_set_min_rate(emc->clk, rate); 107 if (err < 0) 108 return err; 109 110 emc->debugfs.min_rate = rate; 111 112 return 0; 113 } 114 115 DEFINE_DEBUGFS_ATTRIBUTE(tegra186_emc_debug_min_rate_fops, 116 tegra186_emc_debug_min_rate_get, 117 tegra186_emc_debug_min_rate_set, "%llu\n"); 118 119 static int tegra186_emc_debug_max_rate_get(void *data, u64 *rate) 120 { 121 struct tegra186_emc *emc = data; 122 123 *rate = emc->debugfs.max_rate; 124 125 return 0; 126 } 127 128 static int tegra186_emc_debug_max_rate_set(void *data, u64 rate) 129 { 130 struct tegra186_emc *emc = data; 131 int err; 132 133 if (!tegra186_emc_validate_rate(emc, rate)) 134 return -EINVAL; 135 136 err = clk_set_max_rate(emc->clk, rate); 137 if (err < 0) 138 return err; 139 140 emc->debugfs.max_rate = rate; 141 142 return 0; 143 } 144 145 DEFINE_DEBUGFS_ATTRIBUTE(tegra186_emc_debug_max_rate_fops, 146 tegra186_emc_debug_max_rate_get, 147 tegra186_emc_debug_max_rate_set, "%llu\n"); 148 149 static int tegra186_emc_probe(struct platform_device *pdev) 150 { 151 struct mrq_emc_dvfs_latency_response response; 152 struct tegra_bpmp_message msg; 153 struct tegra186_emc *emc; 154 unsigned int i; 155 int err; 156 157 emc = devm_kzalloc(&pdev->dev, sizeof(*emc), GFP_KERNEL); 158 if (!emc) 159 return -ENOMEM; 160 161 emc->bpmp = tegra_bpmp_get(&pdev->dev); 162 if (IS_ERR(emc->bpmp)) 163 return dev_err_probe(&pdev->dev, PTR_ERR(emc->bpmp), "failed to get BPMP\n"); 164 165 emc->clk = devm_clk_get(&pdev->dev, "emc"); 166 if (IS_ERR(emc->clk)) { 167 err = PTR_ERR(emc->clk); 168 dev_err(&pdev->dev, "failed to get EMC clock: %d\n", err); 169 goto put_bpmp; 170 } 171 172 platform_set_drvdata(pdev, emc); 173 emc->dev = &pdev->dev; 174 175 memset(&msg, 0, sizeof(msg)); 176 msg.mrq = MRQ_EMC_DVFS_LATENCY; 177 msg.tx.data = NULL; 178 msg.tx.size = 0; 179 msg.rx.data = &response; 180 msg.rx.size = sizeof(response); 181 182 err = tegra_bpmp_transfer(emc->bpmp, &msg); 183 if (err < 0) { 184 dev_err(&pdev->dev, "failed to EMC DVFS pairs: %d\n", err); 185 goto put_bpmp; 186 } 187 if (msg.rx.ret < 0) { 188 err = -EINVAL; 189 dev_err(&pdev->dev, "EMC DVFS MRQ failed: %d (BPMP error code)\n", msg.rx.ret); 190 goto put_bpmp; 191 } 192 193 emc->debugfs.min_rate = ULONG_MAX; 194 emc->debugfs.max_rate = 0; 195 196 emc->num_dvfs = response.num_pairs; 197 198 emc->dvfs = devm_kmalloc_array(&pdev->dev, emc->num_dvfs, 199 sizeof(*emc->dvfs), GFP_KERNEL); 200 if (!emc->dvfs) { 201 err = -ENOMEM; 202 goto put_bpmp; 203 } 204 205 dev_dbg(&pdev->dev, "%u DVFS pairs:\n", emc->num_dvfs); 206 207 for (i = 0; i < emc->num_dvfs; i++) { 208 emc->dvfs[i].rate = response.pairs[i].freq * 1000; 209 emc->dvfs[i].latency = response.pairs[i].latency; 210 211 if (emc->dvfs[i].rate < emc->debugfs.min_rate) 212 emc->debugfs.min_rate = emc->dvfs[i].rate; 213 214 if (emc->dvfs[i].rate > emc->debugfs.max_rate) 215 emc->debugfs.max_rate = emc->dvfs[i].rate; 216 217 dev_dbg(&pdev->dev, " %2u: %lu Hz -> %lu us\n", i, 218 emc->dvfs[i].rate, emc->dvfs[i].latency); 219 } 220 221 err = clk_set_rate_range(emc->clk, emc->debugfs.min_rate, 222 emc->debugfs.max_rate); 223 if (err < 0) { 224 dev_err(&pdev->dev, 225 "failed to set rate range [%lu-%lu] for %pC\n", 226 emc->debugfs.min_rate, emc->debugfs.max_rate, 227 emc->clk); 228 goto put_bpmp; 229 } 230 231 emc->debugfs.root = debugfs_create_dir("emc", NULL); 232 debugfs_create_file("available_rates", S_IRUGO, emc->debugfs.root, 233 emc, &tegra186_emc_debug_available_rates_fops); 234 debugfs_create_file("min_rate", S_IRUGO | S_IWUSR, emc->debugfs.root, 235 emc, &tegra186_emc_debug_min_rate_fops); 236 debugfs_create_file("max_rate", S_IRUGO | S_IWUSR, emc->debugfs.root, 237 emc, &tegra186_emc_debug_max_rate_fops); 238 239 return 0; 240 241 put_bpmp: 242 tegra_bpmp_put(emc->bpmp); 243 return err; 244 } 245 246 static int tegra186_emc_remove(struct platform_device *pdev) 247 { 248 struct tegra186_emc *emc = platform_get_drvdata(pdev); 249 250 debugfs_remove_recursive(emc->debugfs.root); 251 tegra_bpmp_put(emc->bpmp); 252 253 return 0; 254 } 255 256 static const struct of_device_id tegra186_emc_of_match[] = { 257 #if defined(CONFIG_ARCH_TEGRA_186_SOC) 258 { .compatible = "nvidia,tegra186-emc" }, 259 #endif 260 #if defined(CONFIG_ARCH_TEGRA_194_SOC) 261 { .compatible = "nvidia,tegra194-emc" }, 262 #endif 263 #if defined(CONFIG_ARCH_TEGRA_234_SOC) 264 { .compatible = "nvidia,tegra234-emc" }, 265 #endif 266 { /* sentinel */ } 267 }; 268 MODULE_DEVICE_TABLE(of, tegra186_emc_of_match); 269 270 static struct platform_driver tegra186_emc_driver = { 271 .driver = { 272 .name = "tegra186-emc", 273 .of_match_table = tegra186_emc_of_match, 274 .suppress_bind_attrs = true, 275 }, 276 .probe = tegra186_emc_probe, 277 .remove = tegra186_emc_remove, 278 }; 279 module_platform_driver(tegra186_emc_driver); 280 281 MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>"); 282 MODULE_DESCRIPTION("NVIDIA Tegra186 External Memory Controller driver"); 283 MODULE_LICENSE("GPL v2"); 284