.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. |
---|
3 | 4 | * |
---|
4 | 5 | * Author: |
---|
5 | 6 | * Mikko Perttunen <mperttunen@nvidia.com> |
---|
6 | | - * |
---|
7 | | - * This software is licensed under the terms of the GNU General Public |
---|
8 | | - * License version 2, as published by the Free Software Foundation, and |
---|
9 | | - * may be copied, distributed, and modified under those terms. |
---|
10 | | - * |
---|
11 | | - * This program is distributed in the hope that it will be useful, |
---|
12 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
13 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
14 | | - * GNU General Public License for more details. |
---|
15 | | - * |
---|
16 | 7 | */ |
---|
17 | 8 | |
---|
18 | 9 | #include <linux/clk-provider.h> |
---|
.. | .. |
---|
20 | 11 | #include <linux/clkdev.h> |
---|
21 | 12 | #include <linux/debugfs.h> |
---|
22 | 13 | #include <linux/delay.h> |
---|
| 14 | +#include <linux/io.h> |
---|
23 | 15 | #include <linux/of_address.h> |
---|
24 | 16 | #include <linux/of_platform.h> |
---|
25 | 17 | #include <linux/platform_device.h> |
---|
.. | .. |
---|
273 | 265 | #define EMC_PUTERM_ADJ 0x574 |
---|
274 | 266 | |
---|
275 | 267 | #define DRAM_DEV_SEL_ALL 0 |
---|
276 | | -#define DRAM_DEV_SEL_0 (2 << 30) |
---|
277 | | -#define DRAM_DEV_SEL_1 (1 << 30) |
---|
| 268 | +#define DRAM_DEV_SEL_0 BIT(31) |
---|
| 269 | +#define DRAM_DEV_SEL_1 BIT(30) |
---|
278 | 270 | |
---|
279 | 271 | #define EMC_CFG_POWER_FEATURES_MASK \ |
---|
280 | 272 | (EMC_CFG_DYN_SREF | EMC_CFG_DRAM_ACPD | EMC_CFG_DRAM_CLKSTOP_SR | \ |
---|
.. | .. |
---|
475 | 467 | |
---|
476 | 468 | void __iomem *regs; |
---|
477 | 469 | |
---|
| 470 | + struct clk *clk; |
---|
| 471 | + |
---|
478 | 472 | enum emc_dram_type dram_type; |
---|
479 | 473 | unsigned int dram_num; |
---|
480 | 474 | |
---|
481 | 475 | struct emc_timing last_timing; |
---|
482 | 476 | struct emc_timing *timings; |
---|
483 | 477 | unsigned int num_timings; |
---|
| 478 | + |
---|
| 479 | + struct { |
---|
| 480 | + struct dentry *root; |
---|
| 481 | + unsigned long min_rate; |
---|
| 482 | + unsigned long max_rate; |
---|
| 483 | + } debugfs; |
---|
484 | 484 | }; |
---|
485 | 485 | |
---|
486 | 486 | /* Timing change sequence functions */ |
---|
.. | .. |
---|
888 | 888 | |
---|
889 | 889 | err = of_property_read_u32(node, "clock-frequency", &value); |
---|
890 | 890 | if (err) { |
---|
891 | | - dev_err(emc->dev, "timing %s: failed to read rate: %d\n", |
---|
892 | | - node->name, err); |
---|
| 891 | + dev_err(emc->dev, "timing %pOFn: failed to read rate: %d\n", |
---|
| 892 | + node, err); |
---|
893 | 893 | return err; |
---|
894 | 894 | } |
---|
895 | 895 | |
---|
.. | .. |
---|
900 | 900 | ARRAY_SIZE(timing->emc_burst_data)); |
---|
901 | 901 | if (err) { |
---|
902 | 902 | dev_err(emc->dev, |
---|
903 | | - "timing %s: failed to read emc burst data: %d\n", |
---|
904 | | - node->name, err); |
---|
| 903 | + "timing %pOFn: failed to read emc burst data: %d\n", |
---|
| 904 | + node, err); |
---|
905 | 905 | return err; |
---|
906 | 906 | } |
---|
907 | 907 | |
---|
908 | 908 | #define EMC_READ_PROP(prop, dtprop) { \ |
---|
909 | 909 | err = of_property_read_u32(node, dtprop, &timing->prop); \ |
---|
910 | 910 | if (err) { \ |
---|
911 | | - dev_err(emc->dev, "timing %s: failed to read " #prop ": %d\n", \ |
---|
912 | | - node->name, err); \ |
---|
| 911 | + dev_err(emc->dev, "timing %pOFn: failed to read " #prop ": %d\n", \ |
---|
| 912 | + node, err); \ |
---|
913 | 913 | return err; \ |
---|
914 | 914 | } \ |
---|
915 | 915 | } |
---|
.. | .. |
---|
984 | 984 | |
---|
985 | 985 | static const struct of_device_id tegra_emc_of_match[] = { |
---|
986 | 986 | { .compatible = "nvidia,tegra124-emc" }, |
---|
| 987 | + { .compatible = "nvidia,tegra132-emc" }, |
---|
987 | 988 | {} |
---|
988 | 989 | }; |
---|
989 | 990 | |
---|
.. | .. |
---|
1006 | 1007 | return NULL; |
---|
1007 | 1008 | } |
---|
1008 | 1009 | |
---|
1009 | | -/* Debugfs entry */ |
---|
| 1010 | +/* |
---|
| 1011 | + * debugfs interface |
---|
| 1012 | + * |
---|
| 1013 | + * The memory controller driver exposes some files in debugfs that can be used |
---|
| 1014 | + * to control the EMC frequency. The top-level directory can be found here: |
---|
| 1015 | + * |
---|
| 1016 | + * /sys/kernel/debug/emc |
---|
| 1017 | + * |
---|
| 1018 | + * It contains the following files: |
---|
| 1019 | + * |
---|
| 1020 | + * - available_rates: This file contains a list of valid, space-separated |
---|
| 1021 | + * EMC frequencies. |
---|
| 1022 | + * |
---|
| 1023 | + * - min_rate: Writing a value to this file sets the given frequency as the |
---|
| 1024 | + * floor of the permitted range. If this is higher than the currently |
---|
| 1025 | + * configured EMC frequency, this will cause the frequency to be |
---|
| 1026 | + * increased so that it stays within the valid range. |
---|
| 1027 | + * |
---|
| 1028 | + * - max_rate: Similarily to the min_rate file, writing a value to this file |
---|
| 1029 | + * sets the given frequency as the ceiling of the permitted range. If |
---|
| 1030 | + * the value is lower than the currently configured EMC frequency, this |
---|
| 1031 | + * will cause the frequency to be decreased so that it stays within the |
---|
| 1032 | + * valid range. |
---|
| 1033 | + */ |
---|
1010 | 1034 | |
---|
1011 | | -static int emc_debug_rate_get(void *data, u64 *rate) |
---|
| 1035 | +static bool tegra_emc_validate_rate(struct tegra_emc *emc, unsigned long rate) |
---|
1012 | 1036 | { |
---|
1013 | | - struct clk *c = data; |
---|
| 1037 | + unsigned int i; |
---|
1014 | 1038 | |
---|
1015 | | - *rate = clk_get_rate(c); |
---|
| 1039 | + for (i = 0; i < emc->num_timings; i++) |
---|
| 1040 | + if (rate == emc->timings[i].rate) |
---|
| 1041 | + return true; |
---|
1016 | 1042 | |
---|
1017 | | - return 0; |
---|
| 1043 | + return false; |
---|
1018 | 1044 | } |
---|
1019 | 1045 | |
---|
1020 | | -static int emc_debug_rate_set(void *data, u64 rate) |
---|
1021 | | -{ |
---|
1022 | | - struct clk *c = data; |
---|
1023 | | - |
---|
1024 | | - return clk_set_rate(c, rate); |
---|
1025 | | -} |
---|
1026 | | - |
---|
1027 | | -DEFINE_SIMPLE_ATTRIBUTE(emc_debug_rate_fops, emc_debug_rate_get, |
---|
1028 | | - emc_debug_rate_set, "%lld\n"); |
---|
1029 | | - |
---|
1030 | | -static int emc_debug_supported_rates_show(struct seq_file *s, void *data) |
---|
| 1046 | +static int tegra_emc_debug_available_rates_show(struct seq_file *s, |
---|
| 1047 | + void *data) |
---|
1031 | 1048 | { |
---|
1032 | 1049 | struct tegra_emc *emc = s->private; |
---|
1033 | 1050 | const char *prefix = ""; |
---|
1034 | 1051 | unsigned int i; |
---|
1035 | 1052 | |
---|
1036 | 1053 | for (i = 0; i < emc->num_timings; i++) { |
---|
1037 | | - struct emc_timing *timing = &emc->timings[i]; |
---|
1038 | | - |
---|
1039 | | - seq_printf(s, "%s%lu", prefix, timing->rate); |
---|
1040 | | - |
---|
| 1054 | + seq_printf(s, "%s%lu", prefix, emc->timings[i].rate); |
---|
1041 | 1055 | prefix = " "; |
---|
1042 | 1056 | } |
---|
1043 | 1057 | |
---|
.. | .. |
---|
1046 | 1060 | return 0; |
---|
1047 | 1061 | } |
---|
1048 | 1062 | |
---|
1049 | | -static int emc_debug_supported_rates_open(struct inode *inode, |
---|
1050 | | - struct file *file) |
---|
| 1063 | +DEFINE_SHOW_ATTRIBUTE(tegra_emc_debug_available_rates); |
---|
| 1064 | + |
---|
| 1065 | +static int tegra_emc_debug_min_rate_get(void *data, u64 *rate) |
---|
1051 | 1066 | { |
---|
1052 | | - return single_open(file, emc_debug_supported_rates_show, |
---|
1053 | | - inode->i_private); |
---|
| 1067 | + struct tegra_emc *emc = data; |
---|
| 1068 | + |
---|
| 1069 | + *rate = emc->debugfs.min_rate; |
---|
| 1070 | + |
---|
| 1071 | + return 0; |
---|
1054 | 1072 | } |
---|
1055 | 1073 | |
---|
1056 | | -static const struct file_operations emc_debug_supported_rates_fops = { |
---|
1057 | | - .open = emc_debug_supported_rates_open, |
---|
1058 | | - .read = seq_read, |
---|
1059 | | - .llseek = seq_lseek, |
---|
1060 | | - .release = single_release, |
---|
1061 | | -}; |
---|
| 1074 | +static int tegra_emc_debug_min_rate_set(void *data, u64 rate) |
---|
| 1075 | +{ |
---|
| 1076 | + struct tegra_emc *emc = data; |
---|
| 1077 | + int err; |
---|
| 1078 | + |
---|
| 1079 | + if (!tegra_emc_validate_rate(emc, rate)) |
---|
| 1080 | + return -EINVAL; |
---|
| 1081 | + |
---|
| 1082 | + err = clk_set_min_rate(emc->clk, rate); |
---|
| 1083 | + if (err < 0) |
---|
| 1084 | + return err; |
---|
| 1085 | + |
---|
| 1086 | + emc->debugfs.min_rate = rate; |
---|
| 1087 | + |
---|
| 1088 | + return 0; |
---|
| 1089 | +} |
---|
| 1090 | + |
---|
| 1091 | +DEFINE_SIMPLE_ATTRIBUTE(tegra_emc_debug_min_rate_fops, |
---|
| 1092 | + tegra_emc_debug_min_rate_get, |
---|
| 1093 | + tegra_emc_debug_min_rate_set, "%llu\n"); |
---|
| 1094 | + |
---|
| 1095 | +static int tegra_emc_debug_max_rate_get(void *data, u64 *rate) |
---|
| 1096 | +{ |
---|
| 1097 | + struct tegra_emc *emc = data; |
---|
| 1098 | + |
---|
| 1099 | + *rate = emc->debugfs.max_rate; |
---|
| 1100 | + |
---|
| 1101 | + return 0; |
---|
| 1102 | +} |
---|
| 1103 | + |
---|
| 1104 | +static int tegra_emc_debug_max_rate_set(void *data, u64 rate) |
---|
| 1105 | +{ |
---|
| 1106 | + struct tegra_emc *emc = data; |
---|
| 1107 | + int err; |
---|
| 1108 | + |
---|
| 1109 | + if (!tegra_emc_validate_rate(emc, rate)) |
---|
| 1110 | + return -EINVAL; |
---|
| 1111 | + |
---|
| 1112 | + err = clk_set_max_rate(emc->clk, rate); |
---|
| 1113 | + if (err < 0) |
---|
| 1114 | + return err; |
---|
| 1115 | + |
---|
| 1116 | + emc->debugfs.max_rate = rate; |
---|
| 1117 | + |
---|
| 1118 | + return 0; |
---|
| 1119 | +} |
---|
| 1120 | + |
---|
| 1121 | +DEFINE_SIMPLE_ATTRIBUTE(tegra_emc_debug_max_rate_fops, |
---|
| 1122 | + tegra_emc_debug_max_rate_get, |
---|
| 1123 | + tegra_emc_debug_max_rate_set, "%llu\n"); |
---|
1062 | 1124 | |
---|
1063 | 1125 | static void emc_debugfs_init(struct device *dev, struct tegra_emc *emc) |
---|
1064 | 1126 | { |
---|
1065 | | - struct dentry *root, *file; |
---|
1066 | | - struct clk *clk; |
---|
| 1127 | + unsigned int i; |
---|
| 1128 | + int err; |
---|
1067 | 1129 | |
---|
1068 | | - root = debugfs_create_dir("emc", NULL); |
---|
1069 | | - if (!root) { |
---|
| 1130 | + emc->clk = devm_clk_get(dev, "emc"); |
---|
| 1131 | + if (IS_ERR(emc->clk)) { |
---|
| 1132 | + if (PTR_ERR(emc->clk) != -ENODEV) { |
---|
| 1133 | + dev_err(dev, "failed to get EMC clock: %ld\n", |
---|
| 1134 | + PTR_ERR(emc->clk)); |
---|
| 1135 | + return; |
---|
| 1136 | + } |
---|
| 1137 | + } |
---|
| 1138 | + |
---|
| 1139 | + emc->debugfs.min_rate = ULONG_MAX; |
---|
| 1140 | + emc->debugfs.max_rate = 0; |
---|
| 1141 | + |
---|
| 1142 | + for (i = 0; i < emc->num_timings; i++) { |
---|
| 1143 | + if (emc->timings[i].rate < emc->debugfs.min_rate) |
---|
| 1144 | + emc->debugfs.min_rate = emc->timings[i].rate; |
---|
| 1145 | + |
---|
| 1146 | + if (emc->timings[i].rate > emc->debugfs.max_rate) |
---|
| 1147 | + emc->debugfs.max_rate = emc->timings[i].rate; |
---|
| 1148 | + } |
---|
| 1149 | + |
---|
| 1150 | + if (!emc->num_timings) { |
---|
| 1151 | + emc->debugfs.min_rate = clk_get_rate(emc->clk); |
---|
| 1152 | + emc->debugfs.max_rate = emc->debugfs.min_rate; |
---|
| 1153 | + } |
---|
| 1154 | + |
---|
| 1155 | + err = clk_set_rate_range(emc->clk, emc->debugfs.min_rate, |
---|
| 1156 | + emc->debugfs.max_rate); |
---|
| 1157 | + if (err < 0) { |
---|
| 1158 | + dev_err(dev, "failed to set rate range [%lu-%lu] for %pC\n", |
---|
| 1159 | + emc->debugfs.min_rate, emc->debugfs.max_rate, |
---|
| 1160 | + emc->clk); |
---|
| 1161 | + return; |
---|
| 1162 | + } |
---|
| 1163 | + |
---|
| 1164 | + emc->debugfs.root = debugfs_create_dir("emc", NULL); |
---|
| 1165 | + if (!emc->debugfs.root) { |
---|
1070 | 1166 | dev_err(dev, "failed to create debugfs directory\n"); |
---|
1071 | 1167 | return; |
---|
1072 | 1168 | } |
---|
1073 | 1169 | |
---|
1074 | | - clk = clk_get_sys("tegra-clk-debug", "emc"); |
---|
1075 | | - if (IS_ERR(clk)) { |
---|
1076 | | - dev_err(dev, "failed to get debug clock: %ld\n", PTR_ERR(clk)); |
---|
1077 | | - return; |
---|
1078 | | - } |
---|
1079 | | - |
---|
1080 | | - file = debugfs_create_file("rate", S_IRUGO | S_IWUSR, root, clk, |
---|
1081 | | - &emc_debug_rate_fops); |
---|
1082 | | - if (!file) |
---|
1083 | | - dev_err(dev, "failed to create debugfs entry\n"); |
---|
1084 | | - |
---|
1085 | | - file = debugfs_create_file("supported_rates", S_IRUGO, root, emc, |
---|
1086 | | - &emc_debug_supported_rates_fops); |
---|
1087 | | - if (!file) |
---|
1088 | | - dev_err(dev, "failed to create debugfs entry\n"); |
---|
| 1170 | + debugfs_create_file("available_rates", 0444, emc->debugfs.root, emc, |
---|
| 1171 | + &tegra_emc_debug_available_rates_fops); |
---|
| 1172 | + debugfs_create_file("min_rate", 0644, emc->debugfs.root, |
---|
| 1173 | + emc, &tegra_emc_debug_min_rate_fops); |
---|
| 1174 | + debugfs_create_file("max_rate", 0644, emc->debugfs.root, |
---|
| 1175 | + emc, &tegra_emc_debug_max_rate_fops); |
---|
1089 | 1176 | } |
---|
1090 | 1177 | |
---|
1091 | 1178 | static int tegra_emc_probe(struct platform_device *pdev) |
---|