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 88 static int tegra186_emc_debug_available_rates_open(struct inode *inode, 89 struct file *file) 90 { 91 return single_open(file, tegra186_emc_debug_available_rates_show, 92 inode->i_private); 93 } 94 95 static const struct file_operations tegra186_emc_debug_available_rates_fops = { 96 .open = tegra186_emc_debug_available_rates_open, 97 .read = seq_read, 98 .llseek = seq_lseek, 99 .release = single_release, 100 }; 101 102 static int tegra186_emc_debug_min_rate_get(void *data, u64 *rate) 103 { 104 struct tegra186_emc *emc = data; 105 106 *rate = emc->debugfs.min_rate; 107 108 return 0; 109 } 110 111 static int tegra186_emc_debug_min_rate_set(void *data, u64 rate) 112 { 113 struct tegra186_emc *emc = data; 114 int err; 115 116 if (!tegra186_emc_validate_rate(emc, rate)) 117 return -EINVAL; 118 119 err = clk_set_min_rate(emc->clk, rate); 120 if (err < 0) 121 return err; 122 123 emc->debugfs.min_rate = rate; 124 125 return 0; 126 } 127 128 DEFINE_SIMPLE_ATTRIBUTE(tegra186_emc_debug_min_rate_fops, 129 tegra186_emc_debug_min_rate_get, 130 tegra186_emc_debug_min_rate_set, "%llu\n"); 131 132 static int tegra186_emc_debug_max_rate_get(void *data, u64 *rate) 133 { 134 struct tegra186_emc *emc = data; 135 136 *rate = emc->debugfs.max_rate; 137 138 return 0; 139 } 140 141 static int tegra186_emc_debug_max_rate_set(void *data, u64 rate) 142 { 143 struct tegra186_emc *emc = data; 144 int err; 145 146 if (!tegra186_emc_validate_rate(emc, rate)) 147 return -EINVAL; 148 149 err = clk_set_max_rate(emc->clk, rate); 150 if (err < 0) 151 return err; 152 153 emc->debugfs.max_rate = rate; 154 155 return 0; 156 } 157 158 DEFINE_SIMPLE_ATTRIBUTE(tegra186_emc_debug_max_rate_fops, 159 tegra186_emc_debug_max_rate_get, 160 tegra186_emc_debug_max_rate_set, "%llu\n"); 161 162 static int tegra186_emc_probe(struct platform_device *pdev) 163 { 164 struct mrq_emc_dvfs_latency_response response; 165 struct tegra_bpmp_message msg; 166 struct tegra186_emc *emc; 167 unsigned int i; 168 int err; 169 170 emc = devm_kzalloc(&pdev->dev, sizeof(*emc), GFP_KERNEL); 171 if (!emc) 172 return -ENOMEM; 173 174 emc->bpmp = tegra_bpmp_get(&pdev->dev); 175 if (IS_ERR(emc->bpmp)) { 176 err = PTR_ERR(emc->bpmp); 177 178 if (err != -EPROBE_DEFER) 179 dev_err(&pdev->dev, "failed to get BPMP: %d\n", err); 180 181 return err; 182 } 183 184 emc->clk = devm_clk_get(&pdev->dev, "emc"); 185 if (IS_ERR(emc->clk)) { 186 err = PTR_ERR(emc->clk); 187 dev_err(&pdev->dev, "failed to get EMC clock: %d\n", err); 188 goto put_bpmp; 189 } 190 191 platform_set_drvdata(pdev, emc); 192 emc->dev = &pdev->dev; 193 194 memset(&msg, 0, sizeof(msg)); 195 msg.mrq = MRQ_EMC_DVFS_LATENCY; 196 msg.tx.data = NULL; 197 msg.tx.size = 0; 198 msg.rx.data = &response; 199 msg.rx.size = sizeof(response); 200 201 err = tegra_bpmp_transfer(emc->bpmp, &msg); 202 if (err < 0) { 203 dev_err(&pdev->dev, "failed to EMC DVFS pairs: %d\n", err); 204 goto put_bpmp; 205 } 206 207 emc->debugfs.min_rate = ULONG_MAX; 208 emc->debugfs.max_rate = 0; 209 210 emc->num_dvfs = response.num_pairs; 211 212 emc->dvfs = devm_kmalloc_array(&pdev->dev, emc->num_dvfs, 213 sizeof(*emc->dvfs), GFP_KERNEL); 214 if (!emc->dvfs) { 215 err = -ENOMEM; 216 goto put_bpmp; 217 } 218 219 dev_dbg(&pdev->dev, "%u DVFS pairs:\n", emc->num_dvfs); 220 221 for (i = 0; i < emc->num_dvfs; i++) { 222 emc->dvfs[i].rate = response.pairs[i].freq * 1000; 223 emc->dvfs[i].latency = response.pairs[i].latency; 224 225 if (emc->dvfs[i].rate < emc->debugfs.min_rate) 226 emc->debugfs.min_rate = emc->dvfs[i].rate; 227 228 if (emc->dvfs[i].rate > emc->debugfs.max_rate) 229 emc->debugfs.max_rate = emc->dvfs[i].rate; 230 231 dev_dbg(&pdev->dev, " %2u: %lu Hz -> %lu us\n", i, 232 emc->dvfs[i].rate, emc->dvfs[i].latency); 233 } 234 235 err = clk_set_rate_range(emc->clk, emc->debugfs.min_rate, 236 emc->debugfs.max_rate); 237 if (err < 0) { 238 dev_err(&pdev->dev, 239 "failed to set rate range [%lu-%lu] for %pC\n", 240 emc->debugfs.min_rate, emc->debugfs.max_rate, 241 emc->clk); 242 goto put_bpmp; 243 } 244 245 emc->debugfs.root = debugfs_create_dir("emc", NULL); 246 debugfs_create_file("available_rates", S_IRUGO, emc->debugfs.root, 247 emc, &tegra186_emc_debug_available_rates_fops); 248 debugfs_create_file("min_rate", S_IRUGO | S_IWUSR, emc->debugfs.root, 249 emc, &tegra186_emc_debug_min_rate_fops); 250 debugfs_create_file("max_rate", S_IRUGO | S_IWUSR, emc->debugfs.root, 251 emc, &tegra186_emc_debug_max_rate_fops); 252 253 return 0; 254 255 put_bpmp: 256 tegra_bpmp_put(emc->bpmp); 257 return err; 258 } 259 260 static int tegra186_emc_remove(struct platform_device *pdev) 261 { 262 struct tegra186_emc *emc = platform_get_drvdata(pdev); 263 264 debugfs_remove_recursive(emc->debugfs.root); 265 tegra_bpmp_put(emc->bpmp); 266 267 return 0; 268 } 269 270 static const struct of_device_id tegra186_emc_of_match[] = { 271 #if defined(CONFIG_ARCH_TEGRA_186_SOC) 272 { .compatible = "nvidia,tegra186-emc" }, 273 #endif 274 #if defined(CONFIG_ARCH_TEGRA_194_SOC) 275 { .compatible = "nvidia,tegra194-emc" }, 276 #endif 277 { /* sentinel */ } 278 }; 279 MODULE_DEVICE_TABLE(of, tegra186_emc_of_match); 280 281 static struct platform_driver tegra186_emc_driver = { 282 .driver = { 283 .name = "tegra186-emc", 284 .of_match_table = tegra186_emc_of_match, 285 .suppress_bind_attrs = true, 286 }, 287 .probe = tegra186_emc_probe, 288 .remove = tegra186_emc_remove, 289 }; 290 module_platform_driver(tegra186_emc_driver); 291 292 MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>"); 293 MODULE_DESCRIPTION("NVIDIA Tegra186 External Memory Controller driver"); 294 MODULE_LICENSE("GPL v2"); 295