From 5b78b500a9ef076594ed5d17fd1b4b21ad7c01c8 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 12 Jun 2019 17:45:53 +0200 Subject: [PATCH] rtc: tegra: Implement suspend clock source The suspend clock source for Tegra210 and earlier is currently implemented in the Tegra timer driver. However, the suspend clock source code accesses registers that are part of the RTC hardware block, so both can step on each others' toes. In practice this isn't an issue, but there is no reason why the RTC driver can't implement the clock source, so move the code over to the tegra-rtc driver. Signed-off-by: Thierry Reding --- drivers/clocksource/timer-tegra.c | 44 ------------------------------- drivers/rtc/rtc-tegra.c | 42 +++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 44 deletions(-) diff --git a/drivers/clocksource/timer-tegra.c b/drivers/clocksource/timer-tegra.c index e9635c25eef4..c15ba84f0bd1 100644 --- a/drivers/clocksource/timer-tegra.c +++ b/drivers/clocksource/timer-tegra.c @@ -23,10 +23,6 @@ #include "timer-of.h" -#define RTC_SECONDS 0x08 -#define RTC_SHADOW_SECONDS 0x0c -#define RTC_MILLISECONDS 0x10 - #define TIMERUS_CNTR_1US 0x10 #define TIMERUS_USEC_CFG 0x14 #define TIMERUS_CNTR_FREEZE 0x4c @@ -181,34 +177,6 @@ static struct delay_timer tegra_delay_timer = { }; #endif -static struct timer_of suspend_rtc_to = { - .flags = TIMER_OF_BASE | TIMER_OF_CLOCK, -}; - -/* - * tegra_rtc_read - Reads the Tegra RTC registers - * Care must be taken that this function is not called while the - * tegra_rtc driver could be executing to avoid race conditions - * on the RTC shadow register - */ -static u64 tegra_rtc_read_ms(struct clocksource *cs) -{ - void __iomem *reg_base = timer_of_base(&suspend_rtc_to); - - u32 ms = readl_relaxed(reg_base + RTC_MILLISECONDS); - u32 s = readl_relaxed(reg_base + RTC_SHADOW_SECONDS); - - return (u64)s * MSEC_PER_SEC + ms; -} - -static struct clocksource suspend_rtc_clocksource = { - .name = "tegra_suspend_timer", - .rating = 200, - .read = tegra_rtc_read_ms, - .mask = CLOCKSOURCE_MASK(32), - .flags = CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_SUSPEND_NONSTOP, -}; - static inline unsigned int tegra_base_for_cpu(int cpu, bool tegra20) { if (tegra20) { @@ -402,15 +370,3 @@ static int __init tegra20_init_timer(struct device_node *np) return tegra_init_timer(np, true, rating); } TIMER_OF_DECLARE(tegra20_timer, "nvidia,tegra20-timer", tegra20_init_timer); - -static int __init tegra20_init_rtc(struct device_node *np) -{ - int ret; - - ret = timer_of_init(np, &suspend_rtc_to); - if (ret) - return ret; - - return clocksource_register_hz(&suspend_rtc_clocksource, 1000); -} -TIMER_OF_DECLARE(tegra20_rtc, "nvidia,tegra20-rtc", tegra20_init_rtc); diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c index 441e0a66b215..000ca81ea0c6 100644 --- a/drivers/rtc/rtc-tegra.c +++ b/drivers/rtc/rtc-tegra.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -52,8 +53,15 @@ struct tegra_rtc_info { struct clk *clk; int irq; /* alarm and periodic IRQ */ spinlock_t lock; + + struct clocksource clksrc; }; +static inline struct tegra_rtc_info *to_tegra_rtc(struct clocksource *clksrc) +{ + return container_of(clksrc, struct tegra_rtc_info, clksrc); +} + /* * RTC hardware is busy when it is updating its values over AHB once every * eight 32 kHz clocks (~250 us). Outside of these updates the CPU is free to @@ -268,6 +276,17 @@ static const struct rtc_class_ops tegra_rtc_ops = { .alarm_irq_enable = tegra_rtc_alarm_irq_enable, }; +static u64 tegra_rtc_read_ms(struct clocksource *clksrc) +{ + struct tegra_rtc_info *info = to_tegra_rtc(clksrc); + u32 ms, s; + + ms = readl_relaxed(info->base + TEGRA_RTC_REG_MILLI_SECONDS); + s = readl_relaxed(info->base + TEGRA_RTC_REG_SHADOW_SECONDS); + + return (u64)s * MSEC_PER_SEC + ms; +} + static const struct of_device_id tegra_rtc_dt_match[] = { { .compatible = "nvidia,tegra20-rtc", }, {} @@ -333,6 +352,28 @@ static int tegra_rtc_probe(struct platform_device *pdev) if (ret) goto disable_clk; + /* + * The Tegra RTC is the only reliable clock source that persists + * across an SC7 transition (VDD_CPU and VDD_CORE off) on Tegra210 + * and earlier. Starting with Tegra186, the ARM v8 architected timer + * is in an always on power partition and its reference clock keeps + * running during SC7. Therefore, we technically don't need to have + * the RTC register as a clock source on Tegra186 and later, but it + * doesn't hurt either, so we just register it unconditionally here. + */ + info->clksrc.name = "tegra_rtc"; + info->clksrc.rating = 200; + info->clksrc.read = tegra_rtc_read_ms; + info->clksrc.mask = CLOCKSOURCE_MASK(42); + info->clksrc.flags = CLOCK_SOURCE_SUSPEND_NONSTOP | + CLOCK_SOURCE_IS_CONTINUOUS; + + ret = clocksource_register_hz(&info->clksrc, 1000); + if (ret) { + dev_err(&pdev->dev, "failed to register clock source: %d\n", ret); + goto disable_clk; + } + dev_notice(&pdev->dev, "Tegra internal Real Time Clock\n"); return 0; @@ -346,6 +387,7 @@ static void tegra_rtc_remove(struct platform_device *pdev) { struct tegra_rtc_info *info = platform_get_drvdata(pdev); + clocksource_unregister(&info->clksrc); clk_disable_unprepare(info->clk); } -- 2.44.0 From 358f95ff76d353fb3b0e15ce352777b0729f4211 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Thu, 12 Oct 2023 11:49:09 +0100 Subject: [PATCH] memory: tegra: Add Tegra234 clients for RCE and VI Add the Tegra234 memory client entries for the Real-time Camera Engine (RCE) and Video Input (VI) devices. Signed-off-by: Jon Hunter Acked-by: Thierry Reding Link: https://lore.kernel.org/r/20231012104909.48518-1-jonathanh@nvidia.com Signed-off-by: Krzysztof Kozlowski --- drivers/memory/tegra/tegra234.c | 60 +++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/drivers/memory/tegra/tegra234.c b/drivers/memory/tegra/tegra234.c index fa40c49b070d..b8a7af2d36c1 100644 --- a/drivers/memory/tegra/tegra234.c +++ b/drivers/memory/tegra/tegra234.c @@ -449,6 +449,18 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { .security = 0x38c, }, }, + }, { + .id = TEGRA234_MEMORY_CLIENT_VIW, + .name = "viw", + .bpmp_id = TEGRA_ICC_BPMP_VI, + .type = TEGRA_ICC_ISO_VI, + .sid = TEGRA234_SID_ISO_VI, + .regs = { + .sid = { + .override = 0x390, + .security = 0x394, + }, + }, }, { .id = TEGRA234_MEMORY_CLIENT_NVDECSRD, .name = "nvdecsrd", @@ -621,6 +633,30 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { .security = 0x50c, }, }, + }, { + .id = TEGRA234_MEMORY_CLIENT_VIFALR, + .name = "vifalr", + .bpmp_id = TEGRA_ICC_BPMP_VIFAL, + .type = TEGRA_ICC_ISO_VIFAL, + .sid = TEGRA234_SID_ISO_VIFALC, + .regs = { + .sid = { + .override = 0x5e0, + .security = 0x5e4, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_VIFALW, + .name = "vifalw", + .bpmp_id = TEGRA_ICC_BPMP_VIFAL, + .type = TEGRA_ICC_ISO_VIFAL, + .sid = TEGRA234_SID_ISO_VIFALC, + .regs = { + .sid = { + .override = 0x5e8, + .security = 0x5ec, + }, + }, }, { .id = TEGRA234_MEMORY_CLIENT_DLA0RDA, .name = "dla0rda", @@ -701,6 +737,30 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { .security = 0x62c, }, }, + }, { + .id = TEGRA234_MEMORY_CLIENT_RCER, + .name = "rcer", + .bpmp_id = TEGRA_ICC_BPMP_RCE, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_RCE, + .regs = { + .sid = { + .override = 0x690, + .security = 0x694, + }, + }, + }, { + .id = TEGRA234_MEMORY_CLIENT_RCEW, + .name = "rcew", + .bpmp_id = TEGRA_ICC_BPMP_RCE, + .type = TEGRA_ICC_NISO, + .sid = TEGRA234_SID_RCE, + .regs = { + .sid = { + .override = 0x698, + .security = 0x69c, + }, + }, }, { .id = TEGRA234_MEMORY_CLIENT_PCIE0R, .name = "pcie0r", -- 2.44.0 From 25c7cb88f78928b48fae9e200a55ec0d4db41925 Mon Sep 17 00:00:00 2001 From: Ninad Malwade Date: Fri, 29 Sep 2023 11:36:49 +0100 Subject: [PATCH] hwmon: (ina3221) Add support for channel summation disable The INA3221 allows the Critical alert pin to be controlled by the summation control function. This function adds the single shunt-voltage conversions for the desired channels in order to compare the combined sum to the programmed limit. The Shunt-Voltage Sum Limit register contains the programmed value that is compared to the value in the Shunt-Voltage Sum register in order to determine if the total summed limit is exceeded. If the shunt-voltage sum limit value is exceeded, the Critical alert pin pulls low. For the summation limit to have a meaningful value, we have to use the same shunt-resistor value on all included channels. Unless equal shunt-resistor values are used for each channel, the summation control function cannot be used and it is not enabled by the driver. To address this, add support to disable the summation of specific channels via device tree property "ti,summation-disable". The channel which has this property would be excluded from the calculation of summation control function. For example, summation control function calculates Shunt-Voltage Sum as: - input_shunt_voltage_summation = input_shunt_voltage_channel1 + input_shunt_voltage_channel2 + input_shunt_voltage_channel3 If we want the summation to only use channel1 and channel3, we can add 'ti,summation-disable' property in device tree node for channel2. Then the calculation will skip channel2. - input_shunt_voltage_summation = input_shunt_voltage_channel1 + input_shunt_voltage_channel3 Note that we only want the channel to be skipped for summation control function rather than completely disabled. Therefore, even if we add the property 'ti,summation-disable', the channel is still enabled and functional. Finally, create debugfs entries that display if summation is disabled for each of the channels. Signed-off-by: Rajkumar Kasirajan Signed-off-by: Ninad Malwade Co-developed-by: Jon Hunter Signed-off-by: Jon Hunter Link: https://lore.kernel.org/r/20230929103650.86074-4-jonathanh@nvidia.com Signed-off-by: Guenter Roeck --- drivers/hwmon/ina3221.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/drivers/hwmon/ina3221.c b/drivers/hwmon/ina3221.c index 5ab944056ec0..5ffdc94db436 100644 --- a/drivers/hwmon/ina3221.c +++ b/drivers/hwmon/ina3221.c @@ -6,6 +6,7 @@ * Andrew F. Davis */ +#include #include #include #include @@ -99,11 +100,13 @@ enum ina3221_channels { * @label: label of channel input source * @shunt_resistor: shunt resistor value of channel input source * @disconnected: connection status of channel input source + * @summation_disable: channel summation status of input source */ struct ina3221_input { const char *label; int shunt_resistor; bool disconnected; + bool summation_disable; }; /** @@ -113,8 +116,10 @@ struct ina3221_input { * @fields: Register fields of the device * @inputs: Array of channel input source specific structures * @lock: mutex lock to serialize sysfs attribute accesses + * @debugfs: Pointer to debugfs entry for device * @reg_config: Register value of INA3221_CONFIG * @summation_shunt_resistor: equivalent shunt resistor value for summation + * @summation_channel_control: Value written to SCC field in INA3221_MASK_ENABLE * @single_shot: running in single-shot operating mode */ struct ina3221_data { @@ -123,8 +128,10 @@ struct ina3221_data { struct regmap_field *fields[F_MAX_FIELDS]; struct ina3221_input inputs[INA3221_NUM_CHANNELS]; struct mutex lock; + struct dentry *debugfs; u32 reg_config; int summation_shunt_resistor; + u32 summation_channel_control; bool single_shot; }; @@ -154,7 +161,8 @@ static inline int ina3221_summation_shunt_resistor(struct ina3221_data *ina) int i, shunt_resistor = 0; for (i = 0; i < INA3221_NUM_CHANNELS; i++) { - if (input[i].disconnected || !input[i].shunt_resistor) + if (input[i].disconnected || !input[i].shunt_resistor || + input[i].summation_disable) continue; if (!shunt_resistor) { /* Found the reference shunt resistor value */ @@ -786,6 +794,9 @@ static int ina3221_probe_child_from_dt(struct device *dev, /* Save the connected input label if available */ of_property_read_string(child, "label", &input->label); + /* summation channel control */ + input->summation_disable = of_property_read_bool(child, "ti,summation-disable"); + /* Overwrite default shunt resistor value optionally */ if (!of_property_read_u32(child, "shunt-resistor-micro-ohms", &val)) { if (val < 1 || val > INT_MAX) { @@ -827,6 +838,7 @@ static int ina3221_probe(struct i2c_client *client) struct device *dev = &client->dev; struct ina3221_data *ina; struct device *hwmon_dev; + char name[32]; int i, ret; ina = devm_kzalloc(dev, sizeof(*ina), GFP_KERNEL); @@ -873,6 +885,10 @@ static int ina3221_probe(struct i2c_client *client) /* Initialize summation_shunt_resistor for summation channel control */ ina->summation_shunt_resistor = ina3221_summation_shunt_resistor(ina); + for (i = 0; i < INA3221_NUM_CHANNELS; i++) { + if (!ina->inputs[i].summation_disable) + ina->summation_channel_control |= BIT(14 - i); + } ina->pm_dev = dev; mutex_init(&ina->lock); @@ -900,6 +916,15 @@ static int ina3221_probe(struct i2c_client *client) goto fail; } + scnprintf(name, sizeof(name), "%s-%s", INA3221_DRIVER_NAME, dev_name(dev)); + ina->debugfs = debugfs_create_dir(name, NULL); + + for (i = 0; i < INA3221_NUM_CHANNELS; i++) { + scnprintf(name, sizeof(name), "in%d_summation_disable", i); + debugfs_create_bool(name, 0400, ina->debugfs, + &ina->inputs[i].summation_disable); + } + return 0; fail: @@ -918,6 +943,8 @@ static void ina3221_remove(struct i2c_client *client) struct ina3221_data *ina = dev_get_drvdata(&client->dev); int i; + debugfs_remove_recursive(ina->debugfs); + pm_runtime_disable(ina->pm_dev); pm_runtime_set_suspended(ina->pm_dev); @@ -978,13 +1005,13 @@ static int ina3221_resume(struct device *dev) /* Initialize summation channel control */ if (ina->summation_shunt_resistor) { /* - * Take all three channels into summation by default + * Sum only channels that are not disabled for summation. * Shunt measurements of disconnected channels should * be 0, so it does not matter for summation. */ ret = regmap_update_bits(ina->regmap, INA3221_MASK_ENABLE, INA3221_MASK_ENABLE_SCC_MASK, - INA3221_MASK_ENABLE_SCC_MASK); + ina->summation_channel_control); if (ret) { dev_err(dev, "Unable to control summation channel\n"); return ret; -- 2.44.0 From 25a9a0d4819018096742defddaf6fd6ea237e76f Mon Sep 17 00:00:00 2001 From: Sumit Gupta Date: Wed, 4 Oct 2023 19:35:36 +0530 Subject: [PATCH] cpufreq: tegra194: save CPU data to avoid repeated SMP calls Currently, we make SMP call on every frequency set request to get the physical 'CPU ID' and 'CLUSTER ID' for the target CPU. This change optimizes the repeated calls by storing the physical IDs and the per core frequency register offset for all CPUs during boot. Later this info is used directly when required to set the frequency or read it from ACTMON counters. Signed-off-by: Sumit Gupta Signed-off-by: Viresh Kumar --- drivers/cpufreq/tegra194-cpufreq.c | 79 +++++++++++++++++++----------- 1 file changed, 51 insertions(+), 28 deletions(-) diff --git a/drivers/cpufreq/tegra194-cpufreq.c b/drivers/cpufreq/tegra194-cpufreq.c index 386aed3637b4..f6a8e6cf6d94 100644 --- a/drivers/cpufreq/tegra194-cpufreq.c +++ b/drivers/cpufreq/tegra194-cpufreq.c @@ -39,6 +39,12 @@ /* cpufreq transisition latency */ #define TEGRA_CPUFREQ_TRANSITION_LATENCY (300 * 1000) /* unit in nanoseconds */ +struct tegra_cpu_data { + u32 cpuid; + u32 clusterid; + void __iomem *freq_core_reg; +}; + struct tegra_cpu_ctr { u32 cpu; u32 coreclk_cnt, last_coreclk_cnt; @@ -69,6 +75,7 @@ struct tegra194_cpufreq_data { struct cpufreq_frequency_table **bpmp_luts; const struct tegra_cpufreq_soc *soc; bool icc_dram_bw_scaling; + struct tegra_cpu_data *cpu_data; }; static struct workqueue_struct *read_counters_wq; @@ -116,14 +123,8 @@ static void tegra234_get_cpu_cluster_id(u32 cpu, u32 *cpuid, u32 *clusterid) static int tegra234_get_cpu_ndiv(u32 cpu, u32 cpuid, u32 clusterid, u64 *ndiv) { struct tegra194_cpufreq_data *data = cpufreq_get_driver_data(); - void __iomem *freq_core_reg; - u64 mpidr_id; - - /* use physical id to get address of per core frequency register */ - mpidr_id = (clusterid * data->soc->maxcpus_per_cluster) + cpuid; - freq_core_reg = SCRATCH_FREQ_CORE_REG(data, mpidr_id); - *ndiv = readl(freq_core_reg) & NDIV_MASK; + *ndiv = readl(data->cpu_data[cpu].freq_core_reg) & NDIV_MASK; return 0; } @@ -131,19 +132,10 @@ static int tegra234_get_cpu_ndiv(u32 cpu, u32 cpuid, u32 clusterid, u64 *ndiv) static void tegra234_set_cpu_ndiv(struct cpufreq_policy *policy, u64 ndiv) { struct tegra194_cpufreq_data *data = cpufreq_get_driver_data(); - void __iomem *freq_core_reg; - u32 cpu, cpuid, clusterid; - u64 mpidr_id; - - for_each_cpu_and(cpu, policy->cpus, cpu_online_mask) { - data->soc->ops->get_cpu_cluster_id(cpu, &cpuid, &clusterid); - - /* use physical id to get address of per core frequency register */ - mpidr_id = (clusterid * data->soc->maxcpus_per_cluster) + cpuid; - freq_core_reg = SCRATCH_FREQ_CORE_REG(data, mpidr_id); + u32 cpu; - writel(ndiv, freq_core_reg); - } + for_each_cpu_and(cpu, policy->cpus, cpu_online_mask) + writel(ndiv, data->cpu_data[cpu].freq_core_reg); } /* @@ -157,11 +149,10 @@ static void tegra234_read_counters(struct tegra_cpu_ctr *c) { struct tegra194_cpufreq_data *data = cpufreq_get_driver_data(); void __iomem *actmon_reg; - u32 cpuid, clusterid; u64 val; - data->soc->ops->get_cpu_cluster_id(c->cpu, &cpuid, &clusterid); - actmon_reg = CORE_ACTMON_CNTR_REG(data, clusterid, cpuid); + actmon_reg = CORE_ACTMON_CNTR_REG(data, data->cpu_data[c->cpu].clusterid, + data->cpu_data[c->cpu].cpuid); val = readq(actmon_reg); c->last_refclk_cnt = upper_32_bits(val); @@ -357,19 +348,17 @@ static void tegra194_set_cpu_ndiv(struct cpufreq_policy *policy, u64 ndiv) static unsigned int tegra194_get_speed(u32 cpu) { struct tegra194_cpufreq_data *data = cpufreq_get_driver_data(); + u32 clusterid = data->cpu_data[cpu].clusterid; struct cpufreq_frequency_table *pos; - u32 cpuid, clusterid; unsigned int rate; u64 ndiv; int ret; - data->soc->ops->get_cpu_cluster_id(cpu, &cpuid, &clusterid); - /* reconstruct actual cpu freq using counters */ rate = tegra194_calculate_speed(cpu); /* get last written ndiv value */ - ret = data->soc->ops->get_cpu_ndiv(cpu, cpuid, clusterid, &ndiv); + ret = data->soc->ops->get_cpu_ndiv(cpu, data->cpu_data[cpu].cpuid, clusterid, &ndiv); if (WARN_ON_ONCE(ret)) return rate; @@ -475,13 +464,12 @@ static int tegra194_cpufreq_init(struct cpufreq_policy *policy) { struct tegra194_cpufreq_data *data = cpufreq_get_driver_data(); int maxcpus_per_cluster = data->soc->maxcpus_per_cluster; + u32 clusterid = data->cpu_data[policy->cpu].clusterid; struct cpufreq_frequency_table *freq_table; struct cpufreq_frequency_table *bpmp_lut; u32 start_cpu, cpu; - u32 clusterid; int ret; - data->soc->ops->get_cpu_cluster_id(policy->cpu, NULL, &clusterid); if (clusterid >= data->soc->num_clusters || !data->bpmp_luts[clusterid]) return -EINVAL; @@ -659,6 +647,28 @@ tegra_cpufreq_bpmp_read_lut(struct platform_device *pdev, struct tegra_bpmp *bpm return freq_table; } +static int tegra194_cpufreq_store_physids(unsigned int cpu, struct tegra194_cpufreq_data *data) +{ + int num_cpus = data->soc->maxcpus_per_cluster * data->soc->num_clusters; + u32 cpuid, clusterid; + u64 mpidr_id; + + if (cpu > (num_cpus - 1)) { + pr_err("cpufreq: wrong num of cpus or clusters in soc data\n"); + return -EINVAL; + } + + data->soc->ops->get_cpu_cluster_id(cpu, &cpuid, &clusterid); + + mpidr_id = (clusterid * data->soc->maxcpus_per_cluster) + cpuid; + + data->cpu_data[cpu].cpuid = cpuid; + data->cpu_data[cpu].clusterid = clusterid; + data->cpu_data[cpu].freq_core_reg = SCRATCH_FREQ_CORE_REG(data, mpidr_id); + + return 0; +} + static int tegra194_cpufreq_probe(struct platform_device *pdev) { const struct tegra_cpufreq_soc *soc; @@ -666,6 +676,7 @@ static int tegra194_cpufreq_probe(struct platform_device *pdev) struct tegra_bpmp *bpmp; struct device *cpu_dev; int err, i; + u32 cpu; data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); if (!data) @@ -692,6 +703,12 @@ static int tegra194_cpufreq_probe(struct platform_device *pdev) return PTR_ERR(data->regs); } + data->cpu_data = devm_kcalloc(&pdev->dev, data->soc->num_clusters * + data->soc->maxcpus_per_cluster, + sizeof(*data->cpu_data), GFP_KERNEL); + if (!data->cpu_data) + return -ENOMEM; + platform_set_drvdata(pdev, data); bpmp = tegra_bpmp_get(&pdev->dev); @@ -713,6 +730,12 @@ static int tegra194_cpufreq_probe(struct platform_device *pdev) } } + for_each_possible_cpu(cpu) { + err = tegra194_cpufreq_store_physids(cpu, data); + if (err) + goto err_free_res; + } + tegra194_cpufreq_driver.driver_data = data; /* Check for optional OPPv2 and interconnect paths on CPU0 to enable ICC scaling */ -- 2.44.0 From 4bbfa5e4d6e16ed13acff33abc92913428530593 Mon Sep 17 00:00:00 2001 From: Sumit Gupta Date: Wed, 4 Oct 2023 19:35:37 +0530 Subject: [PATCH] cpufreq: tegra194: use refclk delta based loop instead of udelay Use reference clock count based loop instead of "udelay()" for sampling of counters to improve the accuracy of re-generated CPU frequency. "udelay()" internally calls "WFE" which stops the counters and results in bigger delta between the last set freq and the re-generated value from counters. The counter sampling window used in loop is the minimum number of reference clock cycles which is known to give a stable value of CPU frequency. The change also helps to reduce the sampling window from "500us" to "<50us". Suggested-by: Antti Miettinen Signed-off-by: Sumit Gupta Signed-off-by: Viresh Kumar --- drivers/cpufreq/tegra194-cpufreq.c | 72 +++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 17 deletions(-) diff --git a/drivers/cpufreq/tegra194-cpufreq.c b/drivers/cpufreq/tegra194-cpufreq.c index f6a8e6cf6d94..9dae6195e0e7 100644 --- a/drivers/cpufreq/tegra194-cpufreq.c +++ b/drivers/cpufreq/tegra194-cpufreq.c @@ -5,7 +5,6 @@ #include #include -#include #include #include #include @@ -21,10 +20,11 @@ #define KHZ 1000 #define REF_CLK_MHZ 408 /* 408 MHz */ -#define US_DELAY 500 #define CPUFREQ_TBL_STEP_HZ (50 * KHZ * KHZ) #define MAX_CNT ~0U +#define MAX_DELTA_KHZ 115200 + #define NDIV_MASK 0x1FF #define CORE_OFFSET(cpu) (cpu * 8) @@ -68,6 +68,7 @@ struct tegra_cpufreq_soc { int maxcpus_per_cluster; unsigned int num_clusters; phys_addr_t actmon_cntr_base; + u32 refclk_delta_min; }; struct tegra194_cpufreq_data { @@ -149,6 +150,8 @@ static void tegra234_read_counters(struct tegra_cpu_ctr *c) { struct tegra194_cpufreq_data *data = cpufreq_get_driver_data(); void __iomem *actmon_reg; + u32 delta_refcnt; + int cnt = 0; u64 val; actmon_reg = CORE_ACTMON_CNTR_REG(data, data->cpu_data[c->cpu].clusterid, @@ -157,10 +160,25 @@ static void tegra234_read_counters(struct tegra_cpu_ctr *c) val = readq(actmon_reg); c->last_refclk_cnt = upper_32_bits(val); c->last_coreclk_cnt = lower_32_bits(val); - udelay(US_DELAY); - val = readq(actmon_reg); - c->refclk_cnt = upper_32_bits(val); - c->coreclk_cnt = lower_32_bits(val); + + /* + * The sampling window is based on the minimum number of reference + * clock cycles which is known to give a stable value of CPU frequency. + */ + do { + val = readq(actmon_reg); + c->refclk_cnt = upper_32_bits(val); + c->coreclk_cnt = lower_32_bits(val); + if (c->refclk_cnt < c->last_refclk_cnt) + delta_refcnt = c->refclk_cnt + (MAX_CNT - c->last_refclk_cnt); + else + delta_refcnt = c->refclk_cnt - c->last_refclk_cnt; + if (++cnt >= 0xFFFF) { + pr_warn("cpufreq: problem with refclk on cpu:%d, delta_refcnt:%u, cnt:%d\n", + c->cpu, delta_refcnt, cnt); + break; + } + } while (delta_refcnt < data->soc->refclk_delta_min); } static struct tegra_cpufreq_ops tegra234_cpufreq_ops = { @@ -175,6 +193,7 @@ static const struct tegra_cpufreq_soc tegra234_cpufreq_soc = { .actmon_cntr_base = 0x9000, .maxcpus_per_cluster = 4, .num_clusters = 3, + .refclk_delta_min = 16000, }; static const struct tegra_cpufreq_soc tegra239_cpufreq_soc = { @@ -182,6 +201,7 @@ static const struct tegra_cpufreq_soc tegra239_cpufreq_soc = { .actmon_cntr_base = 0x4000, .maxcpus_per_cluster = 8, .num_clusters = 1, + .refclk_delta_min = 16000, }; static void tegra194_get_cpu_cluster_id(u32 cpu, u32 *cpuid, u32 *clusterid) @@ -222,15 +242,33 @@ static inline u32 map_ndiv_to_freq(struct mrq_cpu_ndiv_limits_response static void tegra194_read_counters(struct tegra_cpu_ctr *c) { + struct tegra194_cpufreq_data *data = cpufreq_get_driver_data(); + u32 delta_refcnt; + int cnt = 0; u64 val; val = read_freq_feedback(); c->last_refclk_cnt = lower_32_bits(val); c->last_coreclk_cnt = upper_32_bits(val); - udelay(US_DELAY); - val = read_freq_feedback(); - c->refclk_cnt = lower_32_bits(val); - c->coreclk_cnt = upper_32_bits(val); + + /* + * The sampling window is based on the minimum number of reference + * clock cycles which is known to give a stable value of CPU frequency. + */ + do { + val = read_freq_feedback(); + c->refclk_cnt = lower_32_bits(val); + c->coreclk_cnt = upper_32_bits(val); + if (c->refclk_cnt < c->last_refclk_cnt) + delta_refcnt = c->refclk_cnt + (MAX_CNT - c->last_refclk_cnt); + else + delta_refcnt = c->refclk_cnt - c->last_refclk_cnt; + if (++cnt >= 0xFFFF) { + pr_warn("cpufreq: problem with refclk on cpu:%d, delta_refcnt:%u, cnt:%d\n", + c->cpu, delta_refcnt, cnt); + break; + } + } while (delta_refcnt < data->soc->refclk_delta_min); } static void tegra_read_counters(struct work_struct *work) @@ -288,9 +326,8 @@ static unsigned int tegra194_calculate_speed(u32 cpu) u32 rate_mhz; /* - * udelay() is required to reconstruct cpu frequency over an - * observation window. Using workqueue to call udelay() with - * interrupts enabled. + * Reconstruct cpu frequency over an observation/sampling window. + * Using workqueue to keep interrupts enabled during the interval. */ read_counters_work.c.cpu = cpu; INIT_WORK_ONSTACK(&read_counters_work.work, tegra_read_counters); @@ -372,9 +409,9 @@ static unsigned int tegra194_get_speed(u32 cpu) if (pos->driver_data != ndiv) continue; - if (abs(pos->frequency - rate) > 115200) { - pr_warn("cpufreq: cpu%d,cur:%u,set:%u,set ndiv:%llu\n", - cpu, rate, pos->frequency, ndiv); + if (abs(pos->frequency - rate) > MAX_DELTA_KHZ) { + pr_warn("cpufreq: cpu%d,cur:%u,set:%u,delta:%d,set ndiv:%llu\n", + cpu, rate, pos->frequency, abs(rate - pos->frequency), ndiv); } else { rate = pos->frequency; } @@ -568,6 +605,7 @@ static const struct tegra_cpufreq_soc tegra194_cpufreq_soc = { .ops = &tegra194_cpufreq_ops, .maxcpus_per_cluster = 2, .num_clusters = 4, + .refclk_delta_min = 16000, }; static void tegra194_cpufreq_free_resources(void) @@ -684,7 +722,7 @@ static int tegra194_cpufreq_probe(struct platform_device *pdev) soc = of_device_get_match_data(&pdev->dev); - if (soc->ops && soc->maxcpus_per_cluster && soc->num_clusters) { + if (soc->ops && soc->maxcpus_per_cluster && soc->num_clusters && soc->refclk_delta_min) { data->soc = soc; } else { dev_err(&pdev->dev, "soc data missing\n"); -- 2.44.0 From a9aa1762789716af85861e67349ccb7eedaca61a Mon Sep 17 00:00:00 2001 From: Sumit Gupta Date: Mon, 9 Oct 2023 13:54:23 +0530 Subject: [PATCH] cpufreq: tegra194: remove redundant AND with cpu_online_mask Remove redundant 'AND' with cpu_online_mask as the policy->cpus always contains only the currently online CPUs. Suggested-by: Viresh Kumar Link: https://lore.kernel.org/lkml/20231003050019.a6mcchw2o2z2wkrh@vireshk-i7/ Signed-off-by: Sumit Gupta [ Viresh: Fix rebase conflict ] Signed-off-by: Viresh Kumar --- drivers/cpufreq/tegra194-cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cpufreq/tegra194-cpufreq.c b/drivers/cpufreq/tegra194-cpufreq.c index 9dae6195e0e7..59865ea455a8 100644 --- a/drivers/cpufreq/tegra194-cpufreq.c +++ b/drivers/cpufreq/tegra194-cpufreq.c @@ -135,7 +135,7 @@ static void tegra234_set_cpu_ndiv(struct cpufreq_policy *policy, u64 ndiv) struct tegra194_cpufreq_data *data = cpufreq_get_driver_data(); u32 cpu; - for_each_cpu_and(cpu, policy->cpus, cpu_online_mask) + for_each_cpu(cpu, policy->cpus) writel(ndiv, data->cpu_data[cpu].freq_core_reg); } -- 2.44.0 From 2d739084b8bf97d5aa230127cd9de200164641cb Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 1 Nov 2023 18:20:16 +0100 Subject: [PATCH] fbdev/simplefb: Support memory-region property The simple-framebuffer bindings specify that the "memory-region" property can be used as an alternative to the "reg" property to define the framebuffer memory used by the display hardware. Implement support for this in the simplefb driver. Reviewed-by: Hans de Goede Signed-off-by: Thierry Reding Signed-off-by: Hans de Goede Link: https://patchwork.freedesktop.org/patch/msgid/20231101172017.3872242-2-thierry.reding@gmail.com --- drivers/video/fbdev/simplefb.c | 35 +++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c index 62f99f6fccd3..18025f34fde7 100644 --- a/drivers/video/fbdev/simplefb.c +++ b/drivers/video/fbdev/simplefb.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -121,12 +122,13 @@ struct simplefb_params { u32 height; u32 stride; struct simplefb_format *format; + struct resource memory; }; static int simplefb_parse_dt(struct platform_device *pdev, struct simplefb_params *params) { - struct device_node *np = pdev->dev.of_node; + struct device_node *np = pdev->dev.of_node, *mem; int ret; const char *format; int i; @@ -166,6 +168,23 @@ static int simplefb_parse_dt(struct platform_device *pdev, return -EINVAL; } + mem = of_parse_phandle(np, "memory-region", 0); + if (mem) { + ret = of_address_to_resource(mem, 0, ¶ms->memory); + if (ret < 0) { + dev_err(&pdev->dev, "failed to parse memory-region\n"); + of_node_put(mem); + return ret; + } + + if (of_property_present(np, "reg")) + dev_warn(&pdev->dev, "preferring \"memory-region\" over \"reg\" property\n"); + + of_node_put(mem); + } else { + memset(¶ms->memory, 0, sizeof(params->memory)); + } + return 0; } @@ -193,6 +212,8 @@ static int simplefb_parse_pd(struct platform_device *pdev, return -EINVAL; } + memset(¶ms->memory, 0, sizeof(params->memory)); + return 0; } @@ -431,10 +452,14 @@ static int simplefb_probe(struct platform_device *pdev) if (ret) return ret; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "No memory resource\n"); - return -EINVAL; + if (params.memory.start == 0 && params.memory.end == 0) { + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "No memory resource\n"); + return -EINVAL; + } + } else { + res = ¶ms.memory; } mem = request_mem_region(res->start, resource_size(res), "simplefb"); -- 2.44.0 From eda00f6c55deb6824ed12f8451e8079184447f18 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 1 Nov 2023 18:20:17 +0100 Subject: [PATCH] fbdev/simplefb: Add support for generic power-domains The simple-framebuffer device tree bindings document the power-domains property, so make sure that simplefb supports it. This ensures that the power domains remain enabled as long as simplefb is active. v2: - remove unnecessary call to simplefb_detach_genpds() since that's already done automatically by devres - fix crash if power-domains property is missing in DT Signed-off-by: Thierry Reding Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede Link: https://patchwork.freedesktop.org/patch/msgid/20231101172017.3872242-3-thierry.reding@gmail.com --- drivers/video/fbdev/simplefb.c | 93 ++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c index 18025f34fde7..fe682af63827 100644 --- a/drivers/video/fbdev/simplefb.c +++ b/drivers/video/fbdev/simplefb.c @@ -25,6 +25,7 @@ #include #include #include +#include #include static const struct fb_fix_screeninfo simplefb_fix = { @@ -78,6 +79,11 @@ struct simplefb_par { unsigned int clk_count; struct clk **clks; #endif +#if defined CONFIG_OF && defined CONFIG_PM_GENERIC_DOMAINS + unsigned int num_genpds; + struct device **genpds; + struct device_link **genpd_links; +#endif #if defined CONFIG_OF && defined CONFIG_REGULATOR bool regulators_enabled; u32 regulator_count; @@ -432,6 +438,89 @@ static void simplefb_regulators_enable(struct simplefb_par *par, static void simplefb_regulators_destroy(struct simplefb_par *par) { } #endif +#if defined CONFIG_OF && defined CONFIG_PM_GENERIC_DOMAINS +static void simplefb_detach_genpds(void *res) +{ + struct simplefb_par *par = res; + unsigned int i = par->num_genpds; + + if (par->num_genpds <= 1) + return; + + while (i--) { + if (par->genpd_links[i]) + device_link_del(par->genpd_links[i]); + + if (!IS_ERR_OR_NULL(par->genpds[i])) + dev_pm_domain_detach(par->genpds[i], true); + } +} + +static int simplefb_attach_genpds(struct simplefb_par *par, + struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + unsigned int i; + int err; + + err = of_count_phandle_with_args(dev->of_node, "power-domains", + "#power-domain-cells"); + if (err < 0) { + dev_info(dev, "failed to parse power-domains: %d\n", err); + return err; + } + + par->num_genpds = err; + + /* + * Single power-domain devices are handled by the driver core, so + * nothing to do here. + */ + if (par->num_genpds <= 1) + return 0; + + par->genpds = devm_kcalloc(dev, par->num_genpds, sizeof(*par->genpds), + GFP_KERNEL); + if (!par->genpds) + return -ENOMEM; + + par->genpd_links = devm_kcalloc(dev, par->num_genpds, + sizeof(*par->genpd_links), + GFP_KERNEL); + if (!par->genpd_links) + return -ENOMEM; + + for (i = 0; i < par->num_genpds; i++) { + par->genpds[i] = dev_pm_domain_attach_by_id(dev, i); + if (IS_ERR(par->genpds[i])) { + err = PTR_ERR(par->genpds[i]); + if (err == -EPROBE_DEFER) { + simplefb_detach_genpds(par); + return err; + } + + dev_warn(dev, "failed to attach domain %u: %d\n", i, err); + continue; + } + + par->genpd_links[i] = device_link_add(dev, par->genpds[i], + DL_FLAG_STATELESS | + DL_FLAG_PM_RUNTIME | + DL_FLAG_RPM_ACTIVE); + if (!par->genpd_links[i]) + dev_warn(dev, "failed to link power-domain %u\n", i); + } + + return devm_add_action_or_reset(dev, simplefb_detach_genpds, par); +} +#else +static int simplefb_attach_genpds(struct simplefb_par *par, + struct platform_device *pdev) +{ + return 0; +} +#endif + static int simplefb_probe(struct platform_device *pdev) { int ret; @@ -518,6 +607,10 @@ static int simplefb_probe(struct platform_device *pdev) if (ret < 0) goto error_clocks; + ret = simplefb_attach_genpds(par, pdev); + if (ret < 0) + goto error_regulators; + simplefb_clocks_enable(par, pdev); simplefb_regulators_enable(par, pdev); -- 2.44.0 From 7af6e409a0adf6df45a80d23654fd2ea9b23c619 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 13 Oct 2023 17:51:04 +0200 Subject: [PATCH] thermal/drivers/max77620: Remove duplicate error message The thermal_of_zone_register() function already prints an error message when appropriate, so remove the extra one from the MAX77620 thermal driver. This fixes a spurious error message when no thermal zone was defined for the MAX77620 in device tree. Reported-by: Nicolas Chauvet Signed-off-by: Thierry Reding Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20231013155104.1781197-1-thierry.reding@gmail.com --- drivers/thermal/max77620_thermal.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/thermal/max77620_thermal.c b/drivers/thermal/max77620_thermal.c index 919b6ee208d8..85a12e98d6dc 100644 --- a/drivers/thermal/max77620_thermal.c +++ b/drivers/thermal/max77620_thermal.c @@ -114,12 +114,8 @@ static int max77620_thermal_probe(struct platform_device *pdev) mtherm->tz_device = devm_thermal_of_zone_register(&pdev->dev, 0, mtherm, &max77620_thermal_ops); - if (IS_ERR(mtherm->tz_device)) { - ret = PTR_ERR(mtherm->tz_device); - dev_err(&pdev->dev, "Failed to register thermal zone: %d\n", - ret); - return ret; - } + if (IS_ERR(mtherm->tz_device)) + return PTR_ERR(mtherm->tz_device); ret = devm_request_threaded_irq(&pdev->dev, mtherm->irq_tjalarm1, NULL, max77620_thermal_irq, -- 2.44.0 From 652292925b6083912c3ffd597811556f2aa5414a Mon Sep 17 00:00:00 2001 From: Rayyan Ansari Date: Thu, 10 Aug 2023 22:45:41 +0100 Subject: [PATCH] arm64: tegra: Enable IOMMU for host1x on Tegra132 Add the iommu property to the host1x node to register it with its swgroup. Signed-off-by: Rayyan Ansari Signed-off-by: Thierry Reding --- arch/arm64/boot/dts/nvidia/tegra132.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/nvidia/tegra132.dtsi b/arch/arm64/boot/dts/nvidia/tegra132.dtsi index 8b78be8f4f9d..7e24a212c7e4 100644 --- a/arch/arm64/boot/dts/nvidia/tegra132.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra132.dtsi @@ -93,6 +93,8 @@ host1x@50000000 { resets = <&tegra_car 28>; reset-names = "host1x"; + iommus = <&mc TEGRA_SWGROUP_HC>; + #address-cells = <2>; #size-cells = <2>; -- 2.44.0 From 6539557c68954d2a0038290d596920b597797d47 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 26 Jul 2023 18:27:38 +0200 Subject: [PATCH] dt-bindings: arm: tegra: pmc: Improve property descriptions Reformat the description of various properties to make them more consistent with existing ones. Make use of json-schema's ability to provide a description for individual list items to make improve the documentation further. Reviewed-by: Rob Herring Signed-off-by: Thierry Reding --- .../arm/tegra/nvidia,tegra20-pmc.yaml | 212 +++++++++--------- 1 file changed, 103 insertions(+), 109 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml index 89191cfdf619..38fe66142547 100644 --- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml @@ -26,12 +26,10 @@ properties: clock-names: items: + # Tegra clock of the same name - const: pclk + # 32 KHz clock input - const: clk32k_in - description: - Must includes entries pclk and clk32k_in. - pclk is the Tegra clock of that name and clk32k_in is 32KHz clock - input to Tegra. clocks: maxItems: 2 @@ -41,105 +39,103 @@ properties: '#clock-cells': const: 1 - description: - Tegra PMC has clk_out_1, clk_out_2, and clk_out_3. - PMC also has blink control which allows 32Khz clock output to - Tegra blink pad. - Consumer of PMC clock should specify the desired clock by having - the clock ID in its "clocks" phandle cell with pmc clock provider. - See include/dt-bindings/soc/tegra-pmc.h for the list of Tegra PMC - clock IDs. + description: | + Tegra PMC has clk_out_1, clk_out_2, and clk_out_3. PMC also has blink + control which allows 32Khz clock output to Tegra blink pad. + + Consumer of PMC clock should specify the desired clock by having the + clock ID in its "clocks" phandle cell with PMC clock provider. See + include/dt-bindings/soc/tegra-pmc.h for the list of Tegra PMC clock IDs. '#interrupt-cells': const: 2 - description: - Specifies number of cells needed to encode an interrupt source. - The value must be 2. + description: Specifies number of cells needed to encode an interrupt + source. interrupt-controller: true nvidia,invert-interrupt: $ref: /schemas/types.yaml#/definitions/flag - description: Inverts the PMU interrupt signal. - The PMU is an external Power Management Unit, whose interrupt output - signal is fed into the PMC. This signal is optionally inverted, and - then fed into the ARM GIC. The PMC is not involved in the detection - or handling of this interrupt signal, merely its inversion. + description: Inverts the PMU interrupt signal. The PMU is an external Power + Management Unit, whose interrupt output signal is fed into the PMC. This + signal is optionally inverted, and then fed into the ARM GIC. The PMC is + not involved in the detection or handling of this interrupt signal, + merely its inversion. nvidia,core-power-req-active-high: $ref: /schemas/types.yaml#/definitions/flag - description: Core power request active-high. + description: core power request active-high nvidia,sys-clock-req-active-high: $ref: /schemas/types.yaml#/definitions/flag - description: System clock request active-high. + description: system clock request active-high nvidia,combined-power-req: $ref: /schemas/types.yaml#/definitions/flag - description: combined power request for CPU and Core. + description: combined power request for CPU and core nvidia,cpu-pwr-good-en: $ref: /schemas/types.yaml#/definitions/flag - description: - CPU power good signal from external PMIC to PMC is enabled. + description: CPU power good signal from external PMIC to PMC is enabled nvidia,suspend-mode: $ref: /schemas/types.yaml#/definitions/uint32 - enum: [0, 1, 2] - description: - The suspend mode that the platform should use. - Mode 0 is for LP0, CPU + Core voltage off and DRAM in self-refresh - Mode 1 is for LP1, CPU voltage off and DRAM in self-refresh - Mode 2 is for LP2, CPU voltage off + description: the suspend mode that the platform should use + oneOf: + - description: LP0, CPU + Core voltage off and DRAM in self-refresh + const: 0 + - description: LP1, CPU voltage off and DRAM in self-refresh + const: 1 + - description: LP2, CPU voltage off + const: 2 nvidia,cpu-pwr-good-time: $ref: /schemas/types.yaml#/definitions/uint32 - description: CPU power good time in uSec. + description: CPU power good time in microseconds nvidia,cpu-pwr-off-time: $ref: /schemas/types.yaml#/definitions/uint32 - description: CPU power off time in uSec. + description: CPU power off time in microseconds nvidia,core-pwr-good-time: $ref: /schemas/types.yaml#/definitions/uint32-array - description: - - Core power good time in uSec. + description: core power good time in microseconds + items: + - description: oscillator stable time + - description: power stable time nvidia,core-pwr-off-time: $ref: /schemas/types.yaml#/definitions/uint32 - description: Core power off time in uSec. + description: core power off time in microseconds nvidia,lp0-vec: $ref: /schemas/types.yaml#/definitions/uint32-array - description: - Starting address and length of LP0 vector. - The LP0 vector contains the warm boot code that is executed - by AVP when resuming from the LP0 state. - The AVP (Audio-Video Processor) is an ARM7 processor and - always being the first boot processor when chip is power on - or resume from deep sleep mode. When the system is resumed - from the deep sleep mode, the warm boot code will restore - some PLLs, clocks and then brings up CPU0 for resuming the - system. + description: | + Starting address and length of LP0 vector. The LP0 vector contains the + warm boot code that is executed by AVP when resuming from the LP0 state. + The AVP (Audio-Video Processor) is an ARM7 processor and always being + the first boot processor when chip is power on or resume from deep sleep + mode. When the system is resumed from the deep sleep mode, the warm boot + code will restore some PLLs, clocks and then brings up CPU0 for resuming + the system. + items: + - description: starting address of LP0 vector + - description: length of LP0 vector core-supply: - description: - Phandle to voltage regulator connected to the SoC Core power rail. + description: phandle to voltage regulator connected to the SoC core power + rail core-domain: type: object - description: | - The vast majority of hardware blocks of Tegra SoC belong to a - Core power domain, which has a dedicated voltage rail that powers - the blocks. - + description: The vast majority of hardware blocks of Tegra SoC belong to a + core power domain, which has a dedicated voltage rail that powers the + blocks. properties: operating-points-v2: - description: - Should contain level, voltages and opp-supported-hw property. - The supported-hw is a bitfield indicating SoC speedo or process - ID mask. + description: Should contain level, voltages and opp-supported-hw + property. The supported-hw is a bitfield indicating SoC speedo or + process ID mask. "#power-domain-cells": const: 0 @@ -152,37 +148,32 @@ properties: i2c-thermtrip: type: object - description: - On Tegra30, Tegra114 and Tegra124 if i2c-thermtrip subnode exists, - hardware-triggered thermal reset will be enabled. - + description: On Tegra30, Tegra114 and Tegra124 if i2c-thermtrip subnode + exists, hardware-triggered thermal reset will be enabled. properties: nvidia,i2c-controller-id: $ref: /schemas/types.yaml#/definitions/uint32 - description: - ID of I2C controller to send poweroff command to PMU. - Valid values are described in section 9.2.148 - "APBDEV_PMC_SCRATCH53_0" of the Tegra K1 Technical Reference - Manual. + description: ID of I2C controller to send poweroff command to PMU. + Valid values are described in section 9.2.148 "APBDEV_PMC_SCRATCH53_0" + of the Tegra K1 Technical Reference Manual. nvidia,bus-addr: $ref: /schemas/types.yaml#/definitions/uint32 - description: Bus address of the PMU on the I2C bus. + description: bus address of the PMU on the I2C bus nvidia,reg-addr: $ref: /schemas/types.yaml#/definitions/uint32 - description: PMU I2C register address to issue poweroff command. + description: PMU I2C register address to issue poweroff command nvidia,reg-data: $ref: /schemas/types.yaml#/definitions/uint32 - description: Poweroff command to write to PMU. + description: power-off command to write to PMU nvidia,pinmux-id: $ref: /schemas/types.yaml#/definitions/uint32 - description: - Pinmux used by the hardware when issuing Poweroff command. - Defaults to 0. Valid values are described in section 12.5.2 - "Pinmux Support" of the Tegra4 Technical Reference Manual. + description: Pinmux used by the hardware when issuing power-off command. + Defaults to 0. Valid values are described in section 12.5.2 "Pinmux + Support" of the Tegra4 Technical Reference Manual. required: - nvidia,i2c-controller-id @@ -195,41 +186,44 @@ properties: powergates: type: object description: | - This node contains a hierarchy of power domain nodes, which should - match the powergates on the Tegra SoC. Each powergate node - represents a power-domain on the Tegra SoC that can be power-gated - by the Tegra PMC. - Hardware blocks belonging to a power domain should contain - "power-domains" property that is a phandle pointing to corresponding - powergate node. - The name of the powergate node should be one of the below. Note that - not every powergate is applicable to all Tegra devices and the following - list shows which powergates are applicable to which devices. - Please refer to Tegra TRM for mode details on the powergate nodes to - use for each power-gate block inside Tegra. - Name Description Devices Applicable - 3d 3D Graphics Tegra20/114/124/210 - 3d0 3D Graphics 0 Tegra30 - 3d1 3D Graphics 1 Tegra30 - aud Audio Tegra210 - dfd Debug Tegra210 - dis Display A Tegra114/124/210 - disb Display B Tegra114/124/210 - heg 2D Graphics Tegra30/114/124/210 - iram Internal RAM Tegra124/210 - mpe MPEG Encode All - nvdec NVIDIA Video Decode Engine Tegra210 - nvjpg NVIDIA JPEG Engine Tegra210 - pcie PCIE Tegra20/30/124/210 - sata SATA Tegra30/124/210 - sor Display interfaces Tegra124/210 - ve2 Video Encode Engine 2 Tegra210 - venc Video Encode Engine All - vdec Video Decode Engine Tegra20/30/114/124 - vic Video Imaging Compositor Tegra124/210 - xusba USB Partition A Tegra114/124/210 - xusbb USB Partition B Tegra114/124/210 - xusbc USB Partition C Tegra114/124/210 + This node contains a hierarchy of power domain nodes, which should match + the powergates on the Tegra SoC. Each powergate node represents a power- + domain on the Tegra SoC that can be power-gated by the Tegra PMC. + + Hardware blocks belonging to a power domain should contain "power-domains" + property that is a phandle pointing to corresponding powergate node. + + The name of the powergate node should be one of the below. Note that not + every powergate is applicable to all Tegra devices and the following list + shows which powergates are applicable to which devices. + + Please refer to Tegra TRM for mode details on the powergate nodes to use + for each power-gate block inside Tegra. + + Name Description Devices Applicable + -------------------------------------------------------------- + 3d 3D Graphics Tegra20/114/124/210 + 3d0 3D Graphics 0 Tegra30 + 3d1 3D Graphics 1 Tegra30 + aud Audio Tegra210 + dfd Debug Tegra210 + dis Display A Tegra114/124/210 + disb Display B Tegra114/124/210 + heg 2D Graphics Tegra30/114/124/210 + iram Internal RAM Tegra124/210 + mpe MPEG Encode All + nvdec NVIDIA Video Decode Engine Tegra210 + nvjpg NVIDIA JPEG Engine Tegra210 + pcie PCIE Tegra20/30/124/210 + sata SATA Tegra30/124/210 + sor Display interfaces Tegra124/210 + ve2 Video Encode Engine 2 Tegra210 + venc Video Encode Engine All + vdec Video Decode Engine Tegra20/30/114/124 + vic Video Imaging Compositor Tegra124/210 + xusba USB Partition A Tegra114/124/210 + xusbb USB Partition B Tegra114/124/210 + xusbc USB Partition C Tegra114/124/210 patternProperties: "^[a-z0-9]+$": -- 2.44.0 From 97b2d1274a657915726c3a579781769aebfac0fe Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 26 Jul 2023 18:27:39 +0200 Subject: [PATCH] dt-bindings: arm: tegra: pmc: Remove useless boilerplate descriptions The descriptions for the clocks and resets properties are no longer useful in the context of json-schema, so drop them. Reviewed-by: Rob Herring Signed-off-by: Thierry Reding --- .../bindings/arm/tegra/nvidia,tegra20-pmc.yaml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml index 38fe66142547..0ac258bc7be0 100644 --- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml @@ -21,8 +21,6 @@ properties: reg: maxItems: 1 - description: - Offset and length of the register set for the device. clock-names: items: @@ -33,9 +31,6 @@ properties: clocks: maxItems: 2 - description: - Must contain an entry for each entry in clock-names. - See ../clocks/clocks-bindings.txt for details. '#clock-cells': const: 1 @@ -234,18 +229,10 @@ properties: clocks: minItems: 1 maxItems: 8 - description: - Must contain an entry for each clock required by the PMC - for controlling a power-gate. - See ../clocks/clock-bindings.txt document for more details. resets: minItems: 1 maxItems: 8 - description: - Must contain an entry for each reset required by the PMC - for controlling a power-gate. - See ../reset/reset.txt for more details. power-domains: maxItems: 1 -- 2.44.0 From 834f699bde1c647a300da5271f7b5f791f91830e Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 26 Jul 2023 18:27:40 +0200 Subject: [PATCH] dt-bindings: arm: tegra: pmc: Move additionalProperties For indented subschemas it can be difficult to understand which block an additionalProperties property belongs to. Moving it closer to the beginning of a block is a good way to clarify this. Reviewed-by: Rob Herring Signed-off-by: Thierry Reding --- .../bindings/arm/tegra/nvidia,tegra20-pmc.yaml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml index 0ac258bc7be0..d6f2c5862841 100644 --- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml @@ -126,6 +126,7 @@ properties: description: The vast majority of hardware blocks of Tegra SoC belong to a core power domain, which has a dedicated voltage rail that powers the blocks. + additionalProperties: false properties: operating-points-v2: description: Should contain level, voltages and opp-supported-hw @@ -139,12 +140,11 @@ properties: - operating-points-v2 - "#power-domain-cells" - additionalProperties: false - i2c-thermtrip: type: object description: On Tegra30, Tegra114 and Tegra124 if i2c-thermtrip subnode exists, hardware-triggered thermal reset will be enabled. + additionalProperties: false properties: nvidia,i2c-controller-id: $ref: /schemas/types.yaml#/definitions/uint32 @@ -176,10 +176,9 @@ properties: - nvidia,reg-addr - nvidia,reg-data - additionalProperties: false - powergates: type: object + additionalProperties: false description: | This node contains a hierarchy of power domain nodes, which should match the powergates on the Tegra SoC. Each powergate node represents a power- @@ -224,7 +223,6 @@ properties: "^[a-z0-9]+$": type: object additionalProperties: false - properties: clocks: minItems: 1 @@ -246,8 +244,6 @@ properties: - resets - '#power-domain-cells' - additionalProperties: false - patternProperties: "^[a-f0-9]+-[a-f0-9]+$": type: object -- 2.44.0 From 26b5a37071c58ee3407509bb5c314a6eb411b1f0 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 26 Jul 2023 18:27:41 +0200 Subject: [PATCH] dt-bindings: arm: tegra: pmc: Increase maximum number of clocks per powergate Some powergate definitions need more than 8 clocks, so bump the number up to 10, which is the current maximum in any known device tree file. Acked-by: Rob Herring Signed-off-by: Thierry Reding --- .../devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml index d6f2c5862841..a336a75d8b82 100644 --- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml @@ -226,7 +226,7 @@ properties: properties: clocks: minItems: 1 - maxItems: 8 + maxItems: 10 resets: minItems: 1 -- 2.44.0 From 4cf88bea8e6712b62479720c695dab39735a5560 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 26 Jul 2023 18:27:42 +0200 Subject: [PATCH] dt-bindings: arm: tegra: pmc: Restructure pad configuration node schema The pad configuration node schema in its current form can accidentally match other properties as well. Restructure the schema to better match how the device trees are using these. Reviewed-by: Rob Herring Signed-off-by: Thierry Reding --- .../arm/tegra/nvidia,tegra20-pmc.yaml | 171 +++++++++++------- 1 file changed, 109 insertions(+), 62 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml index a336a75d8b82..de1b23167658 100644 --- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml @@ -244,69 +244,76 @@ properties: - resets - '#power-domain-cells' -patternProperties: - "^[a-f0-9]+-[a-f0-9]+$": + pinmux: type: object - description: - This is a Pad configuration node. On Tegra SOCs a pad is a set of - pins which are configured as a group. The pin grouping is a fixed - attribute of the hardware. The PMC can be used to set pad power state - and signaling voltage. A pad can be either in active or power down mode. - The support for power state and signaling voltage configuration varies - depending on the pad in question. 3.3V and 1.8V signaling voltages - are supported on pins where software controllable signaling voltage - switching is available. - - The pad configuration state nodes are placed under the pmc node and they - are referred to by the pinctrl client properties. For more information - see Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt. - The pad name should be used as the value of the pins property in pin - configuration nodes. - - The following pads are present on Tegra124 and Tegra132 - audio, bb, cam, comp, csia, csb, cse, dsi, dsib, dsic, dsid, hdmi, hsic, - hv, lvds, mipi-bias, nand, pex-bias, pex-clk1, pex-clk2, pex-cntrl, - sdmmc1, sdmmc3, sdmmc4, sys_ddc, uart, usb0, usb1, usb2, usb_bias. - - The following pads are present on Tegra210 - audio, audio-hv, cam, csia, csib, csic, csid, csie, csif, dbg, - debug-nonao, dmic, dp, dsi, dsib, dsic, dsid, emmc, emmc2, gpio, hdmi, - hsic, lvds, mipi-bias, pex-bias, pex-clk1, pex-clk2, pex-cntrl, sdmmc1, - sdmmc3, spi, spi-hv, uart, usb0, usb1, usb2, usb3, usb-bias. - - properties: - pins: - $ref: /schemas/types.yaml#/definitions/string - description: Must contain name of the pad(s) to be configured. - - low-power-enable: - $ref: /schemas/types.yaml#/definitions/flag - description: Configure the pad into power down mode. - - low-power-disable: - $ref: /schemas/types.yaml#/definitions/flag - description: Configure the pad into active mode. - - power-source: - $ref: /schemas/types.yaml#/definitions/uint32 - description: - Must contain either TEGRA_IO_PAD_VOLTAGE_1V8 or - TEGRA_IO_PAD_VOLTAGE_3V3 to select between signaling voltages. - The values are defined in - include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h. - Power state can be configured on all Tegra124 and Tegra132 - pads. None of the Tegra124 or Tegra132 pads support signaling - voltage switching. - All of the listed Tegra210 pads except pex-cntrl support power - state configuration. Signaling voltage switching is supported - on below Tegra210 pads. - audio, audio-hv, cam, dbg, dmic, gpio, pex-cntrl, sdmmc1, - sdmmc3, spi, spi-hv, and uart. - - required: - - pins - - additionalProperties: false + additionalProperties: + type: object + description: | + This is a pad configuration node. On Tegra SoCs a pad is a set of pins + which are configured as a group. The pin grouping is a fixed attribute + of the hardware. The PMC can be used to set pad power state and + signaling voltage. A pad can be either in active or power down mode. + The support for power state and signaling voltage configuration varies + depending on the pad in question. 3.3V and 1.8V signaling voltages are + supported on pins where software controllable signaling voltage + switching is available. + + The pad configuration state nodes are placed under the pmc node and + they are referred to by the pinctrl client properties. For more + information see: + + Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt + + The pad name should be used as the value of the pins property in pin + configuration nodes. + + The following pads are present on Tegra124 and Tegra132: + + audio, bb, cam, comp, csia, csb, cse, dsi, dsib, dsic, dsid, hdmi, + hsic, hv, lvds, mipi-bias, nand, pex-bias, pex-clk1, pex-clk2, + pex-cntrl, sdmmc1, sdmmc3, sdmmc4, sys_ddc, uart, usb0, usb1, usb2, + usb_bias + + The following pads are present on Tegra210: + + audio, audio-hv, cam, csia, csib, csic, csid, csie, csif, dbg, + debug-nonao, dmic, dp, dsi, dsib, dsic, dsid, emmc, emmc2, gpio, + hdmi, hsic, lvds, mipi-bias, pex-bias, pex-clk1, pex-clk2, pex-cntrl, + sdmmc1, sdmmc3, spi, spi-hv, uart, usb0, usb1, usb2, usb3, usb-bias + additionalProperties: false + properties: + pins: + $ref: /schemas/types.yaml#/definitions/string-array + description: Must contain name of the pad(s) to be configured. + + low-power-enable: + $ref: /schemas/types.yaml#/definitions/flag + description: Configure the pad into power down mode. + + low-power-disable: + $ref: /schemas/types.yaml#/definitions/flag + description: Configure the pad into active mode. + + power-source: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + Must contain either TEGRA_IO_PAD_VOLTAGE_1V8 or + TEGRA_IO_PAD_VOLTAGE_3V3 to select between signaling voltages. The + values are defined in: + + include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h + + Power state can be configured on all Tegra124 and Tegra132 pads. + None of the Tegra124 or Tegra132 pads support signaling voltage + switching. All of the listed Tegra210 pads except pex-cntrl support + power state configuration. Signaling voltage switching is supported + on the following Tegra210 pads: + + audio, audio-hv, cam, dbg, dmic, gpio, pex-cntrl, sdmmc1, sdmmc3, + spi, spi-hv, uart + + required: + - pins required: - compatible @@ -315,6 +322,46 @@ required: - clocks - '#clock-cells' +allOf: + - if: + properties: + compatible: + contains: + const: nvidia,tegra124-pmc + then: + properties: + pinmux: + additionalProperties: + type: object + properties: + pins: + items: + enum: [ audio, bb, cam, comp, csia, csb, cse, dsi, dsib, + dsic, dsid, hdmi, hsic, hv, lvds, mipi-bias, nand, + pex-bias, pex-clk1, pex-clk2, pex-cntrl, sdmmc1, + sdmmc3, sdmmc4, sys_ddc, uart, usb0, usb1, usb2, + usb_bias ] + + - if: + properties: + compatible: + contains: + const: nvidia,tegra210-pmc + then: + properties: + pinmux: + additionalProperties: + type: object + properties: + pins: + items: + enum: [ audio, audio-hv, cam, csia, csib, csic, csid, csie, + csif, dbg, debug-nonao, dmic, dp, dsi, dsib, dsic, + dsid, emmc, emmc2, gpio, hdmi, hsic, lvds, mipi-bias, + pex-bias, pex-clk1, pex-clk2, pex-cntrl, sdmmc1, + sdmmc3, spi, spi-hv, uart, usb0, usb1, usb2, usb3, + usb-bias ] + additionalProperties: false dependencies: -- 2.44.0 From fb41b6eaf418755926840a60d17a1947f08f8b19 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 26 Jul 2023 18:27:43 +0200 Subject: [PATCH] dt-bindings: arm: tegra: pmc: Reformat example Reformat the example using 4 spaces for indentation. Acked-by: Rob Herring Signed-off-by: Thierry Reding --- .../arm/tegra/nvidia,tegra20-pmc.yaml | 77 +++++++++---------- 1 file changed, 38 insertions(+), 39 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml index de1b23167658..a54b562e2a1c 100644 --- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml @@ -371,47 +371,46 @@ dependencies: examples: - | - #include #include #include - tegra_pmc: pmc@7000e400 { - compatible = "nvidia,tegra210-pmc"; - reg = <0x7000e400 0x400>; - core-supply = <®ulator>; - clocks = <&tegra_car TEGRA210_CLK_PCLK>, <&clk32k_in>; - clock-names = "pclk", "clk32k_in"; - #clock-cells = <1>; - - nvidia,invert-interrupt; - nvidia,suspend-mode = <0>; - nvidia,cpu-pwr-good-time = <0>; - nvidia,cpu-pwr-off-time = <0>; - nvidia,core-pwr-good-time = <4587 3876>; - nvidia,core-pwr-off-time = <39065>; - nvidia,core-power-req-active-high; - nvidia,sys-clock-req-active-high; - - pd_core: core-domain { - operating-points-v2 = <&core_opp_table>; - #power-domain-cells = <0>; - }; - - powergates { - pd_audio: aud { - clocks = <&tegra_car TEGRA210_CLK_APE>, - <&tegra_car TEGRA210_CLK_APB2APE>; - resets = <&tegra_car 198>; - power-domains = <&pd_core>; - #power-domain-cells = <0>; - }; - - pd_xusbss: xusba { - clocks = <&tegra_car TEGRA210_CLK_XUSB_SS>; - resets = <&tegra_car TEGRA210_CLK_XUSB_SS>; - power-domains = <&pd_core>; - #power-domain-cells = <0>; - }; - }; + pmc@7000e400 { + compatible = "nvidia,tegra210-pmc"; + reg = <0x7000e400 0x400>; + core-supply = <®ulator>; + clocks = <&tegra_car TEGRA210_CLK_PCLK>, <&clk32k_in>; + clock-names = "pclk", "clk32k_in"; + #clock-cells = <1>; + + nvidia,invert-interrupt; + nvidia,suspend-mode = <0>; + nvidia,cpu-pwr-good-time = <0>; + nvidia,cpu-pwr-off-time = <0>; + nvidia,core-pwr-good-time = <4587 3876>; + nvidia,core-pwr-off-time = <39065>; + nvidia,core-power-req-active-high; + nvidia,sys-clock-req-active-high; + + pd_core: core-domain { + operating-points-v2 = <&core_opp_table>; + #power-domain-cells = <0>; + }; + + powergates { + pd_audio: aud { + clocks = <&tegra_car TEGRA210_CLK_APE>, + <&tegra_car TEGRA210_CLK_APB2APE>; + resets = <&tegra_car 198>; + power-domains = <&pd_core>; + #power-domain-cells = <0>; + }; + + pd_xusbss: xusba { + clocks = <&tegra_car TEGRA210_CLK_XUSB_SS>; + resets = <&tegra_car TEGRA210_CLK_XUSB_SS>; + power-domains = <&pd_core>; + #power-domain-cells = <0>; + }; + }; }; -- 2.44.0 From 3935ccef7c301603373cf87a19d68e606b8e34ec Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 26 Jul 2023 18:27:44 +0200 Subject: [PATCH] dt-bindings: arm: tegra: pmc: Relicense and move into soc/tegra directory Dual-license this binding for consistency with other Tegra bindings and move it into the soc/tegra directory. Reviewed-by: Rob Herring Signed-off-by: Thierry Reding --- .../bindings/{arm => soc}/tegra/nvidia,tegra20-pmc.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename Documentation/devicetree/bindings/{arm => soc}/tegra/nvidia,tegra20-pmc.yaml (99%) diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml b/Documentation/devicetree/bindings/soc/tegra/nvidia,tegra20-pmc.yaml similarity index 99% rename from Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml rename to Documentation/devicetree/bindings/soc/tegra/nvidia,tegra20-pmc.yaml index a54b562e2a1c..b86f6f53ca95 100644 --- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml +++ b/Documentation/devicetree/bindings/soc/tegra/nvidia,tegra20-pmc.yaml @@ -1,7 +1,7 @@ -# SPDX-License-Identifier: GPL-2.0 +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2 --- -$id: http://devicetree.org/schemas/arm/tegra/nvidia,tegra20-pmc.yaml# +$id: http://devicetree.org/schemas/soc/tegra/nvidia,tegra20-pmc.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: Tegra Power Management Controller (PMC) -- 2.44.0 From dd7e1d02ac6e219c99752588166011889a8702d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Mon, 25 Sep 2023 11:55:23 +0200 Subject: [PATCH] soc/tegra: cbb: tegra194-cbb: Convert to platform remove callback returning void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning) and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new() which already returns void. Eventually after all drivers are converted, .remove_new() will be renamed to .remove(). Trivially convert this driver from always returning zero in the remove callback to the void returning variant. Signed-off-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- drivers/soc/tegra/cbb/tegra194-cbb.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/soc/tegra/cbb/tegra194-cbb.c b/drivers/soc/tegra/cbb/tegra194-cbb.c index cf6886f362d3..9cbc562ae7d3 100644 --- a/drivers/soc/tegra/cbb/tegra194-cbb.c +++ b/drivers/soc/tegra/cbb/tegra194-cbb.c @@ -2293,7 +2293,7 @@ static int tegra194_cbb_probe(struct platform_device *pdev) return tegra_cbb_register(&cbb->base); } -static int tegra194_cbb_remove(struct platform_device *pdev) +static void tegra194_cbb_remove(struct platform_device *pdev) { struct tegra194_cbb *cbb = platform_get_drvdata(pdev); struct tegra_cbb *noc, *tmp; @@ -2311,8 +2311,6 @@ static int tegra194_cbb_remove(struct platform_device *pdev) } spin_unlock_irqrestore(&cbb_lock, flags); - - return 0; } static int __maybe_unused tegra194_cbb_resume_noirq(struct device *dev) @@ -2332,7 +2330,7 @@ static const struct dev_pm_ops tegra194_cbb_pm = { static struct platform_driver tegra194_cbb_driver = { .probe = tegra194_cbb_probe, - .remove = tegra194_cbb_remove, + .remove_new = tegra194_cbb_remove, .driver = { .name = "tegra194-cbb", .of_match_table = of_match_ptr(tegra194_cbb_match), -- 2.44.0 From 448b1e383a575f0d1f946c462b4d1f89814473e3 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Thu, 12 Oct 2023 17:35:36 +0200 Subject: [PATCH] soc/tegra: pmc: Drop the ->opp_to_performance_state() callback Since commit 7c41cdcd3bbe ("OPP: Simplify the over-designed pstate <-> level dance"), there is no longer any need for genpd providers to assign the ->opp_to_performance_state(), hence let's drop it. Cc: Thierry Reding Cc: Jonathan Hunter Cc: linux-tegra@vger.kernel.org Signed-off-by: Ulf Hansson Signed-off-by: Thierry Reding --- drivers/soc/tegra/pmc.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 162f52456f65..f432aa022ace 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -1393,13 +1393,6 @@ tegra_pmc_core_pd_set_performance_state(struct generic_pm_domain *genpd, return 0; } -static unsigned int -tegra_pmc_core_pd_opp_to_performance_state(struct generic_pm_domain *genpd, - struct dev_pm_opp *opp) -{ - return dev_pm_opp_get_level(opp); -} - static int tegra_pmc_core_pd_add(struct tegra_pmc *pmc, struct device_node *np) { struct generic_pm_domain *genpd; @@ -1412,7 +1405,6 @@ static int tegra_pmc_core_pd_add(struct tegra_pmc *pmc, struct device_node *np) genpd->name = "core"; genpd->set_performance_state = tegra_pmc_core_pd_set_performance_state; - genpd->opp_to_performance_state = tegra_pmc_core_pd_opp_to_performance_state; err = devm_pm_opp_set_regulators(pmc->dev, rname); if (err) -- 2.44.0 From e0bf68d764454da84578a5e2762f6787f600130e Mon Sep 17 00:00:00 2001 From: Deming Wang Date: Tue, 12 Sep 2023 08:10:30 -0400 Subject: [PATCH] firmware: tegra: Fix a typo successfully, not 'succesfully' Signed-off-by: Deming Wang Signed-off-by: Thierry Reding --- include/soc/tegra/bpmp-abi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/soc/tegra/bpmp-abi.h b/include/soc/tegra/bpmp-abi.h index ecefcaec7e66..6b995a8f0f6d 100644 --- a/include/soc/tegra/bpmp-abi.h +++ b/include/soc/tegra/bpmp-abi.h @@ -1194,7 +1194,7 @@ struct cmd_clk_is_enabled_request { */ struct cmd_clk_is_enabled_response { /** - * @brief The state of the clock that has been succesfully + * @brief The state of the clock that has been successfully * requested with CMD_CLK_ENABLE or CMD_CLK_DISABLE by the * master invoking the command earlier. * -- 2.44.0 From 0ac4c434ad6f74ea958ab6b563f88daeac09e4f1 Mon Sep 17 00:00:00 2001 From: Diogo Ivo Date: Mon, 7 Aug 2023 14:33:03 +0100 Subject: [PATCH] arm64: tegra: Add DSI/CSI regulator on Smaug Add the node for the DSI/CSI regulator in the Pixel C. Signed-off-by: Diogo Ivo Signed-off-by: Thierry Reding --- arch/arm64/boot/dts/nvidia/tegra210-smaug.dts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts index 53805555dd2d..9acf33aae902 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts +++ b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts @@ -1932,4 +1932,12 @@ usbc_vbus: regulator-usbc-vbus { regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; }; + + vdd_dsi_csi: regulator-vdd-dsi-csi { + compatible = "regulator-fixed"; + regulator-name = "AVDD_DSI_CSI_1V2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + vin-supply = <&pp1200_avdd>; + }; }; -- 2.44.0 From 1de69533ec2cf33083b3683b521c7ada265c78fd Mon Sep 17 00:00:00 2001 From: Diogo Ivo Date: Mon, 7 Aug 2023 14:33:04 +0100 Subject: [PATCH] arm64: tegra: Add backlight node on Smaug The Google Pixel C has a TI LP8557 backlight controller, so add a DT node for it. Signed-off-by: Diogo Ivo Signed-off-by: Thierry Reding --- arch/arm64/boot/dts/nvidia/tegra210-smaug.dts | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts index 9acf33aae902..9c8ffbf8ef65 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts +++ b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts @@ -1651,6 +1651,37 @@ nau8825@1a { status = "okay"; }; + backlight: backlight@2c { + compatible = "ti,lp8557"; + reg = <0x2c>; + power-supply = <&pplcd_vdd>; + enable-supply = <&pp1800_lcdio>; + bl-name = "lp8557-backlight"; + dev-ctrl = /bits/ 8 <0x01>; + init-brt = /bits/ 8 <0x80>; + + /* Full scale current, 20mA */ + rom-11h { + rom-addr = /bits/ 8 <0x11>; + rom-val = /bits/ 8 <0x05>; + }; + /* Frequency = 4.9kHz, magic undocumented val */ + rom-12h { + rom-addr = /bits/ 8 <0x12>; + rom-val = /bits/ 8 <0x29>; + }; + /* Boost freq = 1MHz, BComp option = 1 */ + rom-13h { + rom-addr = /bits/ 8 <0x13>; + rom-val = /bits/ 8 <0x03>; + }; + /* 4V OV, 6 output LED string enabled */ + rom-14h { + rom-addr = /bits/ 8 <0x14>; + rom-val = /bits/ 8 <0xbf>; + }; + }; + audio-codec@2d { compatible = "realtek,rt5677"; reg = <0x2d>; -- 2.44.0 From ba829ae1312962094bed036a8192f11eacfcec23 Mon Sep 17 00:00:00 2001 From: Diogo Ivo Date: Mon, 7 Aug 2023 14:33:05 +0100 Subject: [PATCH] arm64: tegra: Add display panel node on Smaug The Google Pixel C has a JDI LPM102A188A display panel, so add a DT node for it. Signed-off-by: Diogo Ivo Signed-off-by: Thierry Reding --- arch/arm64/boot/dts/nvidia/tegra210-smaug.dts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts index 9c8ffbf8ef65..9ebb7369256e 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts +++ b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts @@ -31,6 +31,33 @@ memory { }; host1x@50000000 { + dsia: dsi@54300000 { + avdd-dsi-csi-supply = <&vdd_dsi_csi>; + status = "okay"; + + link2: panel@0 { + compatible = "jdi,lpm102a188a"; + reg = <0>; + }; + }; + + dsib: dsi@54400000 { + avdd-dsi-csi-supply = <&vdd_dsi_csi>; + nvidia,ganged-mode = <&dsia>; + status = "okay"; + + link1: panel@0 { + compatible = "jdi,lpm102a188a"; + reg = <0>; + power-supply = <&pplcd_vdd>; + ddi-supply = <&pp1800_lcdio>; + enable-gpios = <&gpio TEGRA_GPIO(V, 1) GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>; + link2 = <&link2>; + backlight = <&backlight>; + }; + }; + dpaux: dpaux@545c0000 { status = "okay"; }; -- 2.44.0 From b18513618ead4d6e9abadeaa19735d1a7f1a9fca Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 17 Aug 2023 16:14:03 +0200 Subject: [PATCH] arm64: tegra: Add missing current-speed for SBSA UART The SBSA UART device tree bindings require a current-speed property that specifies the baud rate configured by the firmware. Add it on Jetson AGX Orin and Jetson Orin Nano/NX. Signed-off-by: Thierry Reding --- arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts | 1 + arch/arm64/boot/dts/nvidia/tegra234-p3768-0000.dtsi | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts b/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts index bf2ccc8ff93c..81a82933e350 100644 --- a/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts +++ b/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts @@ -30,6 +30,7 @@ serial@3100000 { }; serial@31d0000 { + current-speed = <115200>; status = "okay"; }; diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000.dtsi b/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000.dtsi index 39110c1232e0..5d0298b6c30d 100644 --- a/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000.dtsi @@ -29,6 +29,7 @@ eeprom@57 { }; serial@31d0000 { + current-speed = <115200>; status = "okay"; }; -- 2.44.0 From 7aa80cfac4903c7e098a5c46bfd580e652b6cd6f Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 17 Aug 2023 16:14:04 +0200 Subject: [PATCH] arm64: tegra: Remove duplicate nodes on Jetson Orin NX The SBSA UART and TCU as well as the TCU alias and the stdout-path are configured via the P3768 carrier board DTS include, so the can be removed from the system DTS file. Signed-off-by: Thierry Reding --- .../dts/nvidia/tegra234-p3768-0000+p3767-0000.dts | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767-0000.dts b/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767-0000.dts index e9460aedd47c..61b0e69d3d20 100644 --- a/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767-0000.dts +++ b/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767-0000.dts @@ -12,15 +12,10 @@ / { model = "NVIDIA Jetson Orin NX Engineering Reference Developer Kit"; aliases { - serial0 = &tcu; serial1 = &uarta; serial2 = &uarte; }; - chosen { - stdout-path = "serial0:115200n8"; - }; - bus@0 { serial@3100000 { compatible = "nvidia,tegra194-hsuart"; @@ -34,10 +29,6 @@ serial@3140000 { status = "okay"; }; - serial@31d0000 { - status = "okay"; - }; - pwm@32a0000 { assigned-clocks = <&bpmp TEGRA234_CLK_PWM3>; assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>; @@ -94,10 +85,6 @@ vdd_3v3_pcie: regulator-vdd-3v3-pcie { enable-active-high; }; - serial { - status = "okay"; - }; - thermal-zones { tj-thermal { cooling-maps { -- 2.44.0 From f13f2e024fdc163507e6fe7ceacef20bd67a2c7a Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 17 Aug 2023 16:14:05 +0200 Subject: [PATCH] arm64: tegra: Use correct format for clocks property phandle and clock specifier pairs should be enclosed in angular brackets. Signed-off-by: Thierry Reding --- arch/arm64/boot/dts/nvidia/tegra234.dtsi | 32 ++++++++++++------------ 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi index ac69eacf8a6b..1a9866cf1e19 100644 --- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi @@ -705,8 +705,8 @@ gen1_i2c: i2c@3160000 { #address-cells = <1>; #size-cells = <0>; clock-frequency = <400000>; - clocks = <&bpmp TEGRA234_CLK_I2C1 - &bpmp TEGRA234_CLK_PLLP_OUT0>; + clocks = <&bpmp TEGRA234_CLK_I2C1>, + <&bpmp TEGRA234_CLK_PLLP_OUT0>; assigned-clocks = <&bpmp TEGRA234_CLK_I2C1>; assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>; clock-names = "div-clk", "parent"; @@ -724,8 +724,8 @@ cam_i2c: i2c@3180000 { #size-cells = <0>; status = "disabled"; clock-frequency = <400000>; - clocks = <&bpmp TEGRA234_CLK_I2C3 - &bpmp TEGRA234_CLK_PLLP_OUT0>; + clocks = <&bpmp TEGRA234_CLK_I2C3>, + <&bpmp TEGRA234_CLK_PLLP_OUT0>; assigned-clocks = <&bpmp TEGRA234_CLK_I2C3>; assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>; clock-names = "div-clk", "parent"; @@ -743,8 +743,8 @@ dp_aux_ch1_i2c: i2c@3190000 { #size-cells = <0>; status = "disabled"; clock-frequency = <100000>; - clocks = <&bpmp TEGRA234_CLK_I2C4 - &bpmp TEGRA234_CLK_PLLP_OUT0>; + clocks = <&bpmp TEGRA234_CLK_I2C4>, + <&bpmp TEGRA234_CLK_PLLP_OUT0>; assigned-clocks = <&bpmp TEGRA234_CLK_I2C4>; assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>; clock-names = "div-clk", "parent"; @@ -762,8 +762,8 @@ dp_aux_ch0_i2c: i2c@31b0000 { #size-cells = <0>; status = "disabled"; clock-frequency = <100000>; - clocks = <&bpmp TEGRA234_CLK_I2C6 - &bpmp TEGRA234_CLK_PLLP_OUT0>; + clocks = <&bpmp TEGRA234_CLK_I2C6>, + <&bpmp TEGRA234_CLK_PLLP_OUT0>; assigned-clocks = <&bpmp TEGRA234_CLK_I2C6>; assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>; clock-names = "div-clk", "parent"; @@ -781,8 +781,8 @@ dp_aux_ch2_i2c: i2c@31c0000 { #size-cells = <0>; status = "disabled"; clock-frequency = <100000>; - clocks = <&bpmp TEGRA234_CLK_I2C7 - &bpmp TEGRA234_CLK_PLLP_OUT0>; + clocks = <&bpmp TEGRA234_CLK_I2C7>, + <&bpmp TEGRA234_CLK_PLLP_OUT0>; assigned-clocks = <&bpmp TEGRA234_CLK_I2C7>; assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>; clock-names = "div-clk", "parent"; @@ -807,8 +807,8 @@ dp_aux_ch3_i2c: i2c@31e0000 { #size-cells = <0>; status = "disabled"; clock-frequency = <100000>; - clocks = <&bpmp TEGRA234_CLK_I2C9 - &bpmp TEGRA234_CLK_PLLP_OUT0>; + clocks = <&bpmp TEGRA234_CLK_I2C9>, + <&bpmp TEGRA234_CLK_PLLP_OUT0>; assigned-clocks = <&bpmp TEGRA234_CLK_I2C9>; assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>; clock-names = "div-clk", "parent"; @@ -1751,8 +1751,8 @@ gen2_i2c: i2c@c240000 { #size-cells = <0>; status = "disabled"; clock-frequency = <100000>; - clocks = <&bpmp TEGRA234_CLK_I2C2 - &bpmp TEGRA234_CLK_PLLP_OUT0>; + clocks = <&bpmp TEGRA234_CLK_I2C2>, + <&bpmp TEGRA234_CLK_PLLP_OUT0>; clock-names = "div-clk", "parent"; assigned-clocks = <&bpmp TEGRA234_CLK_I2C2>; assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>; @@ -1770,8 +1770,8 @@ gen8_i2c: i2c@c250000 { #size-cells = <0>; status = "disabled"; clock-frequency = <400000>; - clocks = <&bpmp TEGRA234_CLK_I2C8 - &bpmp TEGRA234_CLK_PLLP_OUT0>; + clocks = <&bpmp TEGRA234_CLK_I2C8>, + <&bpmp TEGRA234_CLK_PLLP_OUT0>; clock-names = "div-clk", "parent"; assigned-clocks = <&bpmp TEGRA234_CLK_I2C8>; assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>; -- 2.44.0 From ea43b110d36b5d298b95cfa781ca79209d4f291e Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 17 Aug 2023 16:14:06 +0200 Subject: [PATCH] arm64: tegra: Add dmas and dma-names for Tegra234 UARTE Commit 940acdac99b2 ("arm64: tegra: Add UARTE device tree node on Tegra234") added the device tree node for the UARTE on Tegra234 but didn't include the "dmas" and "dma-names" properties required for this device when it's used in high-speed mode. Signed-off-by: Thierry Reding --- arch/arm64/boot/dts/nvidia/tegra234.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi index 1a9866cf1e19..d1fe41cc3e0b 100644 --- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi @@ -694,6 +694,8 @@ uarte: serial@3140000 { interrupts = ; clocks = <&bpmp TEGRA234_CLK_UARTE>; resets = <&bpmp TEGRA234_RESET_UARTE>; + dmas = <&gpcdma 20>, <&gpcdma 20>; + dma-names = "rx", "tx"; status = "disabled"; }; -- 2.44.0 From 9c5534efd875098bbebde4da8b9a027a54a3c288 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 17 Aug 2023 16:14:07 +0200 Subject: [PATCH] arm64: tegra: Mark Tegra234 SPI as compatible with Tegra114 According to the bindings, both Tegra210 and Tegra114 compatible strings need to be specified since the version of this hardware block found in Tegra210 is backwards-compatible. Signed-off-by: Thierry Reding --- arch/arm64/boot/dts/nvidia/tegra234.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi index d1fe41cc3e0b..3f16595d099c 100644 --- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi @@ -821,7 +821,7 @@ dp_aux_ch3_i2c: i2c@31e0000 { }; spi@3210000 { - compatible = "nvidia,tegra210-spi"; + compatible = "nvidia,tegra210-spi", "nvidia,tegra114-spi"; reg = <0x0 0x03210000 0x0 0x1000>; interrupts = ; #address-cells = <1>; @@ -840,7 +840,7 @@ spi@3210000 { }; spi@3230000 { - compatible = "nvidia,tegra210-spi"; + compatible = "nvidia,tegra210-spi", "nvidia,tegra114-spi"; reg = <0x0 0x03230000 0x0 0x1000>; interrupts = ; #address-cells = <1>; @@ -1784,7 +1784,7 @@ gen8_i2c: i2c@c250000 { }; spi@c260000 { - compatible = "nvidia,tegra210-spi"; + compatible = "nvidia,tegra210-spi", "nvidia,tegra114-spi"; reg = <0x0 0x0c260000 0x0 0x1000>; interrupts = ; #address-cells = <1>; -- 2.44.0 From cd76c21e85a6c7fece6ed4b664de08bddc793151 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Fri, 29 Sep 2023 11:36:50 +0100 Subject: [PATCH] arm64: tegra: Add power-sensors for Tegra234 boards Populate the ina219 and ina3221 power-sensors for the various Tegra234 boards. These sensors are located on the Tegra234 module boards and the configuration of some sensors is common across the different Tegra234 modules. Therefore, add any common sensor configurations to appropriate device tree source file so it can be re-used across modules. Signed-off-by: Jon Hunter Signed-off-by: Thierry Reding --- .../boot/dts/nvidia/tegra234-p3701-0008.dtsi | 33 ++++++++++++ .../arm64/boot/dts/nvidia/tegra234-p3701.dtsi | 53 +++++++++++++++++++ .../arm64/boot/dts/nvidia/tegra234-p3767.dtsi | 29 ++++++++++ 3 files changed, 115 insertions(+) diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3701-0008.dtsi b/arch/arm64/boot/dts/nvidia/tegra234-p3701-0008.dtsi index 62c4fdad0b60..553fa4ba1cd4 100644 --- a/arch/arm64/boot/dts/nvidia/tegra234-p3701-0008.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra234-p3701-0008.dtsi @@ -44,6 +44,39 @@ i2c@c240000 { status = "okay"; }; + i2c@c250000 { + power-sensor@41 { + compatible = "ti,ina3221"; + reg = <0x41>; + #address-cells = <1>; + #size-cells = <0>; + + input@0 { + reg = <0x0>; + label = "CVB_ATX_12V"; + shunt-resistor-micro-ohms = <2000>; + }; + + input@1 { + reg = <0x1>; + label = "CVB_ATX_3V3"; + shunt-resistor-micro-ohms = <2000>; + }; + + input@2 { + reg = <0x2>; + label = "CVB_ATX_5V"; + shunt-resistor-micro-ohms = <2000>; + }; + }; + + power-sensor@44 { + compatible = "ti,ina219"; + reg = <0x44>; + shunt-resistor = <2000>; + }; + }; + rtc@c2a0000 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3701.dtsi b/arch/arm64/boot/dts/nvidia/tegra234-p3701.dtsi index 5e7797df50c2..db6ef711674a 100644 --- a/arch/arm64/boot/dts/nvidia/tegra234-p3701.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra234-p3701.dtsi @@ -1987,5 +1987,58 @@ interrupt-controller@2a40000 { status = "okay"; }; }; + + i2c@c240000 { + status = "okay"; + + power-sensor@40 { + compatible = "ti,ina3221"; + reg = <0x40>; + #address-cells = <1>; + #size-cells = <0>; + + input@0 { + reg = <0x0>; + label = "VDD_GPU_SOC"; + shunt-resistor-micro-ohms = <2000>; + }; + + input@1 { + reg = <0x1>; + label = "VDD_CPU_CV"; + shunt-resistor-micro-ohms = <2000>; + }; + + input@2 { + reg = <0x2>; + label = "VIN_SYS_5V0"; + shunt-resistor-micro-ohms = <2000>; + ti,summation-disable; + }; + }; + + power-sensor@41 { + compatible = "ti,ina3221"; + reg = <0x41>; + #address-cells = <1>; + #size-cells = <0>; + + input@0 { + reg = <0x0>; + status = "disabled"; + }; + + input@1 { + reg = <0x1>; + label = "VDDQ_VDD2_1V8AO"; + shunt-resistor-micro-ohms = <2000>; + }; + + input@2 { + reg = <0x2>; + status = "disabled"; + }; + }; + }; }; }; diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi b/arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi index fe08e131b7b9..59c14ded5e9f 100644 --- a/arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi @@ -55,6 +55,35 @@ padctl@3520000 { avdd-usb-supply = <&vdd_3v3_ao>; }; + i2c@c240000 { + status = "okay"; + + power-sensor@40 { + compatible = "ti,ina3221"; + reg = <0x40>; + #address-cells = <1>; + #size-cells = <0>; + + input@0 { + reg = <0x0>; + label = "VDD_IN"; + shunt-resistor-micro-ohms = <5000>; + }; + + input@1 { + reg = <0x1>; + label = "VDD_CPU_GPU_CV"; + shunt-resistor-micro-ohms = <5000>; + }; + + input@2 { + reg = <0x2>; + label = "VDD_SOC"; + shunt-resistor-micro-ohms = <5000>; + }; + }; + }; + rtc@c2a0000 { status = "okay"; }; -- 2.44.0 From 695a4755e60e4eb197f56aa10c5844224d320eb9 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 12 Nov 2023 08:04:14 +0100 Subject: [PATCH] soc/tegra: pmc: Remove some old and deprecated functions and constants These TEGRA_IO_RAIL_... functions and constants have been deprecated in commit 21b499105178 ("soc/tegra: pmc: Add I/O pad voltage support") in 2016-11. There seems to be no users since kernel 4.16. Remove them now. Signed-off-by: Christophe JAILLET Signed-off-by: Thierry Reding --- drivers/soc/tegra/pmc.c | 24 ------------------------ include/soc/tegra/pmc.h | 18 ------------------ 2 files changed, 42 deletions(-) diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index f432aa022ace..6dfcc7f50ece 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -1777,30 +1777,6 @@ static int tegra_io_pad_get_voltage(struct tegra_pmc *pmc, enum tegra_io_pad id) return TEGRA_IO_PAD_VOLTAGE_3V3; } -/** - * tegra_io_rail_power_on() - enable power to I/O rail - * @id: Tegra I/O pad ID for which to enable power - * - * See also: tegra_io_pad_power_enable() - */ -int tegra_io_rail_power_on(unsigned int id) -{ - return tegra_io_pad_power_enable(id); -} -EXPORT_SYMBOL(tegra_io_rail_power_on); - -/** - * tegra_io_rail_power_off() - disable power to I/O rail - * @id: Tegra I/O pad ID for which to disable power - * - * See also: tegra_io_pad_power_disable() - */ -int tegra_io_rail_power_off(unsigned int id) -{ - return tegra_io_pad_power_disable(id); -} -EXPORT_SYMBOL(tegra_io_rail_power_off); - #ifdef CONFIG_PM_SLEEP enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void) { diff --git a/include/soc/tegra/pmc.h b/include/soc/tegra/pmc.h index aadb845d281d..c545875d0ff1 100644 --- a/include/soc/tegra/pmc.h +++ b/include/soc/tegra/pmc.h @@ -148,10 +148,6 @@ enum tegra_io_pad { TEGRA_IO_PAD_AO_HV, }; -/* deprecated, use TEGRA_IO_PAD_{HDMI,LVDS} instead */ -#define TEGRA_IO_RAIL_HDMI TEGRA_IO_PAD_HDMI -#define TEGRA_IO_RAIL_LVDS TEGRA_IO_PAD_LVDS - #ifdef CONFIG_SOC_TEGRA_PMC int tegra_powergate_power_on(unsigned int id); int tegra_powergate_power_off(unsigned int id); @@ -164,10 +160,6 @@ int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk, int tegra_io_pad_power_enable(enum tegra_io_pad id); int tegra_io_pad_power_disable(enum tegra_io_pad id); -/* deprecated, use tegra_io_pad_power_{enable,disable}() instead */ -int tegra_io_rail_power_on(unsigned int id); -int tegra_io_rail_power_off(unsigned int id); - void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode); void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode); @@ -211,16 +203,6 @@ static inline int tegra_io_pad_get_voltage(enum tegra_io_pad id) return -ENOSYS; } -static inline int tegra_io_rail_power_on(unsigned int id) -{ - return -ENOSYS; -} - -static inline int tegra_io_rail_power_off(unsigned int id) -{ - return -ENOSYS; -} - static inline void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode) { } -- 2.44.0 From f40dfb313467895d3a1ab6183693127e98a0aa19 Mon Sep 17 00:00:00 2001 From: Kartik Date: Tue, 17 Oct 2023 10:53:15 +0530 Subject: [PATCH] mm/util: Introduce kmemdup_array() Introduce kmemdup_array() API to duplicate `n` number of elements from a given array. This internally uses kmemdup to allocate and duplicate the `src` array. Signed-off-by: Kartik Acked-by: Kees Cook Signed-off-by: Thierry Reding --- include/linux/string.h | 1 + mm/util.c | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/include/linux/string.h b/include/linux/string.h index 5077776e995e..361294697f8c 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -219,6 +219,7 @@ extern char *kstrndup(const char *s, size_t len, gfp_t gfp); extern void *kmemdup(const void *src, size_t len, gfp_t gfp) __realloc_size(2); extern void *kvmemdup(const void *src, size_t len, gfp_t gfp) __realloc_size(2); extern char *kmemdup_nul(const char *s, size_t len, gfp_t gfp); +extern void *kmemdup_array(const void *src, size_t element_size, size_t count, gfp_t gfp); extern char **argv_split(gfp_t gfp, const char *str, int *argcp); extern void argv_free(char **argv); diff --git a/mm/util.c b/mm/util.c index be798981acc7..c79e6f174cd9 100644 --- a/mm/util.c +++ b/mm/util.c @@ -135,6 +135,23 @@ void *kmemdup(const void *src, size_t len, gfp_t gfp) } EXPORT_SYMBOL(kmemdup); +/** + * kmemdup_array - duplicate a given array. + * + * @src: array to duplicate. + * @element_size: size of each element of array. + * @count: number of elements to duplicate from array. + * @gfp: GFP mask to use. + * + * Return: duplicated array of @src or %NULL in case of error, + * result is physically contiguous. Use kfree() to free. + */ +void *kmemdup_array(const void *src, size_t element_size, size_t count, gfp_t gfp) +{ + return kmemdup(src, size_mul(element_size, count), gfp); +} +EXPORT_SYMBOL(kmemdup_array); + /** * kvmemdup - duplicate region of memory * -- 2.44.0 From 30f2f37b8894149f442a4f6e15c1a63635be4080 Mon Sep 17 00:00:00 2001 From: Kartik Date: Tue, 17 Oct 2023 10:53:16 +0530 Subject: [PATCH] soc/tegra: fuse: Use dev_err_probe for probe failures Currently, in tegra_fuse_probe() if clock/reset get fails, then the driver prints an error if the error is not caused by -EPROBE_DEFER. This can be improved by using dev_err_probe() instead. So, return dev_err_probe() if clock/reset get fails. Signed-off-by: Kartik Signed-off-by: Thierry Reding --- drivers/soc/tegra/fuse/fuse-tegra.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c index a2c28f493a75..98805885158e 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra.c +++ b/drivers/soc/tegra/fuse/fuse-tegra.c @@ -131,13 +131,8 @@ static int tegra_fuse_probe(struct platform_device *pdev) fuse->phys = res->start; fuse->clk = devm_clk_get(&pdev->dev, "fuse"); - if (IS_ERR(fuse->clk)) { - if (PTR_ERR(fuse->clk) != -EPROBE_DEFER) - dev_err(&pdev->dev, "failed to get FUSE clock: %ld", - PTR_ERR(fuse->clk)); - - return PTR_ERR(fuse->clk); - } + if (IS_ERR(fuse->clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(fuse->clk), "failed to get FUSE clock\n"); platform_set_drvdata(pdev, fuse); fuse->dev = &pdev->dev; @@ -179,12 +174,8 @@ static int tegra_fuse_probe(struct platform_device *pdev) } fuse->rst = devm_reset_control_get_optional(&pdev->dev, "fuse"); - if (IS_ERR(fuse->rst)) { - err = PTR_ERR(fuse->rst); - dev_err(&pdev->dev, "failed to get FUSE reset: %pe\n", - fuse->rst); - return err; - } + if (IS_ERR(fuse->rst)) + return dev_err_probe(&pdev->dev, PTR_ERR(fuse->rst), "failed to get FUSE reset\n"); /* * FUSE clock is enabled at a boot time, hence this resume/suspend -- 2.44.0 From 2f89f2b59621343ca873f7ff6ca2ae9516cf9fae Mon Sep 17 00:00:00 2001 From: Kartik Date: Tue, 17 Oct 2023 10:53:17 +0530 Subject: [PATCH] soc/tegra: fuse: Refactor resource mapping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To prepare for adding ACPI support to the tegra-apbmisc driver, relocate the code responsible for mapping memory resources from the function ‘tegra_init_apbmisc’ to the function ‘tegra_init_apbmisc_resources.’ This adjustment will allow the code to be shared between ‘tegra_init_apbmisc’ and the upcoming ‘tegra_acpi_init_apbmisc’ function. Signed-off-by: Kartik Signed-off-by: Thierry Reding --- drivers/soc/tegra/fuse/tegra-apbmisc.c | 37 +++++++++++++++----------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/drivers/soc/tegra/fuse/tegra-apbmisc.c b/drivers/soc/tegra/fuse/tegra-apbmisc.c index da970f3dbf35..06c1b3a2c7ec 100644 --- a/drivers/soc/tegra/fuse/tegra-apbmisc.c +++ b/drivers/soc/tegra/fuse/tegra-apbmisc.c @@ -160,9 +160,28 @@ void __init tegra_init_revision(void) tegra_sku_info.platform = tegra_get_platform(); } -void __init tegra_init_apbmisc(void) +static void tegra_init_apbmisc_resources(struct resource *apbmisc, + struct resource *straps) { void __iomem *strapping_base; + + apbmisc_base = ioremap(apbmisc->start, resource_size(apbmisc)); + if (apbmisc_base) + chipid = readl_relaxed(apbmisc_base + 4); + else + pr_err("failed to map APBMISC registers\n"); + + strapping_base = ioremap(straps->start, resource_size(straps)); + if (strapping_base) { + strapping = readl_relaxed(strapping_base); + iounmap(strapping_base); + } else { + pr_err("failed to map strapping options registers\n"); + } +} + +void __init tegra_init_apbmisc(void) +{ struct resource apbmisc, straps; struct device_node *np; @@ -219,21 +238,7 @@ void __init tegra_init_apbmisc(void) } } - apbmisc_base = ioremap(apbmisc.start, resource_size(&apbmisc)); - if (!apbmisc_base) { - pr_err("failed to map APBMISC registers\n"); - } else { - chipid = readl_relaxed(apbmisc_base + 4); - } - - strapping_base = ioremap(straps.start, resource_size(&straps)); - if (!strapping_base) { - pr_err("failed to map strapping options registers\n"); - } else { - strapping = readl_relaxed(strapping_base); - iounmap(strapping_base); - } - + tegra_init_apbmisc_resources(&apbmisc, &straps); long_ram_code = of_property_read_bool(np, "nvidia,long-ram-code"); put: -- 2.44.0 From 27d340f90cfca1f5761248436ead6d13affa481b Mon Sep 17 00:00:00 2001 From: Kartik Date: Tue, 17 Oct 2023 10:53:18 +0530 Subject: [PATCH] soc/tegra: fuse: Add tegra_acpi_init_apbmisc() In preparation to ACPI support in Tegra fuse driver add function tegra_acpi_init_apbmisc() to initialize tegra-apbmisc driver. Also, document the reason of calling tegra_init_apbmisc() at early init. Note that function tegra_acpi_init_apbmisc() is not placed in the __init section, because it will be called during probe. Signed-off-by: Kartik Signed-off-by: Thierry Reding --- drivers/soc/tegra/fuse/fuse.h | 1 + drivers/soc/tegra/fuse/tegra-apbmisc.c | 72 ++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/drivers/soc/tegra/fuse/fuse.h b/drivers/soc/tegra/fuse/fuse.h index 90f23be73894..a41e9f85281a 100644 --- a/drivers/soc/tegra/fuse/fuse.h +++ b/drivers/soc/tegra/fuse/fuse.h @@ -69,6 +69,7 @@ struct tegra_fuse { void tegra_init_revision(void); void tegra_init_apbmisc(void); +void tegra_acpi_init_apbmisc(void); u32 __init tegra_fuse_read_spare(unsigned int spare); u32 __init tegra_fuse_read_early(unsigned int offset); diff --git a/drivers/soc/tegra/fuse/tegra-apbmisc.c b/drivers/soc/tegra/fuse/tegra-apbmisc.c index 06c1b3a2c7ec..6457f80821bb 100644 --- a/drivers/soc/tegra/fuse/tegra-apbmisc.c +++ b/drivers/soc/tegra/fuse/tegra-apbmisc.c @@ -3,9 +3,11 @@ * Copyright (c) 2014-2023, NVIDIA CORPORATION. All rights reserved. */ +#include #include #include #include +#include #include #include @@ -180,6 +182,12 @@ static void tegra_init_apbmisc_resources(struct resource *apbmisc, } } +/** + * tegra_init_apbmisc - Initializes Tegra APBMISC and Strapping registers. + * + * This is called during early init as some of the old 32-bit ARM code needs + * information from the APBMISC registers very early during boot. + */ void __init tegra_init_apbmisc(void) { struct resource apbmisc, straps; @@ -244,3 +252,67 @@ void __init tegra_init_apbmisc(void) put: of_node_put(np); } + +#ifdef CONFIG_ACPI +static const struct acpi_device_id apbmisc_acpi_match[] = { + { "NVDA2010" }, + { /* sentinel */ } +}; + +void tegra_acpi_init_apbmisc(void) +{ + struct resource *resources[2] = { NULL }; + struct resource_entry *rentry; + struct acpi_device *adev = NULL; + struct list_head resource_list; + int rcount = 0; + int ret; + + adev = acpi_dev_get_first_match_dev(apbmisc_acpi_match[0].id, NULL, -1); + if (!adev) + return; + + INIT_LIST_HEAD(&resource_list); + + ret = acpi_dev_get_memory_resources(adev, &resource_list); + if (ret < 0) { + pr_err("failed to get APBMISC memory resources"); + goto out_put_acpi_dev; + } + + /* + * Get required memory resources. + * + * resources[0]: apbmisc. + * resources[1]: straps. + */ + resource_list_for_each_entry(rentry, &resource_list) { + if (rcount >= ARRAY_SIZE(resources)) + break; + + resources[rcount++] = rentry->res; + } + + if (!resources[0]) { + pr_err("failed to get APBMISC registers\n"); + goto out_free_resource_list; + } + + if (!resources[1]) { + pr_err("failed to get strapping options registers\n"); + goto out_free_resource_list; + } + + tegra_init_apbmisc_resources(resources[0], resources[1]); + +out_free_resource_list: + acpi_dev_free_resource_list(&resource_list); + +out_put_acpi_dev: + acpi_dev_put(adev); +} +#else +void tegra_acpi_init_apbmisc(void) +{ +} +#endif -- 2.44.0 From 845ff015be575e5420799944dc9fae79d14045da Mon Sep 17 00:00:00 2001 From: Kartik Date: Tue, 17 Oct 2023 10:53:19 +0530 Subject: [PATCH] soc/tegra: fuse: Add function to add lookups Add helper function tegra_fuse_add_lookups() to register Tegra fuse nvmem lookups. So, this can be shared between tegra_fuse_init() and ACPI probe, which is to be introduced later. Use kmemdup_array to duplicate fuse->soc->lookups. Signed-off-by: Kartik Signed-off-by: Thierry Reding --- drivers/soc/tegra/fuse/fuse-tegra.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c index 98805885158e..4ebb5597a77b 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra.c +++ b/drivers/soc/tegra/fuse/fuse-tegra.c @@ -113,6 +113,18 @@ static void tegra_fuse_restore(void *base) fuse->clk = NULL; } +static int tegra_fuse_add_lookups(struct tegra_fuse *fuse) +{ + fuse->lookups = kmemdup_array(fuse->soc->lookups, sizeof(*fuse->lookups), + fuse->soc->num_lookups, GFP_KERNEL); + if (!fuse->lookups) + return -ENOMEM; + + nvmem_add_cell_lookups(fuse->lookups, fuse->soc->num_lookups); + + return 0; +} + static int tegra_fuse_probe(struct platform_device *pdev) { void __iomem *base = fuse->base; @@ -398,6 +410,7 @@ static int __init tegra_init_fuse(void) const struct of_device_id *match; struct device_node *np; struct resource regs; + int err; tegra_init_apbmisc(); @@ -495,15 +508,11 @@ static int __init tegra_init_fuse(void) pr_debug("Tegra CPU Speedo ID %d, SoC Speedo ID %d\n", tegra_sku_info.cpu_speedo_id, tegra_sku_info.soc_speedo_id); - if (fuse->soc->lookups) { - size_t size = sizeof(*fuse->lookups) * fuse->soc->num_lookups; - - fuse->lookups = kmemdup(fuse->soc->lookups, size, GFP_KERNEL); - if (fuse->lookups) - nvmem_add_cell_lookups(fuse->lookups, fuse->soc->num_lookups); - } + err = tegra_fuse_add_lookups(fuse); + if (err) + pr_err("failed to add FUSE lookups\n"); - return 0; + return err; } early_initcall(tegra_init_fuse); -- 2.44.0 From 1c4b913a7b389937f3b2d69d5bcdef4b6ebada14 Mon Sep 17 00:00:00 2001 From: Kartik Date: Tue, 17 Oct 2023 10:53:20 +0530 Subject: [PATCH] soc/tegra: fuse: Add function to print SKU info Add helper function tegra_fuse_print_sku_info() to print Tegra SKU information. So, it can be shared between tegra_fuse_init() and ACPI probe which is to be introduced later. Signed-off-by: Kartik Signed-off-by: Thierry Reding --- drivers/soc/tegra/fuse/fuse-tegra.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c index 4ebb5597a77b..7a93c6512f7b 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra.c +++ b/drivers/soc/tegra/fuse/fuse-tegra.c @@ -113,6 +113,16 @@ static void tegra_fuse_restore(void *base) fuse->clk = NULL; } +static void tegra_fuse_print_sku_info(struct tegra_sku_info *tegra_sku_info) +{ + pr_info("Tegra Revision: %s SKU: %d CPU Process: %d SoC Process: %d\n", + tegra_revision_name[tegra_sku_info->revision], + tegra_sku_info->sku_id, tegra_sku_info->cpu_process_id, + tegra_sku_info->soc_process_id); + pr_debug("Tegra CPU Speedo ID %d, SoC Speedo ID %d\n", + tegra_sku_info->cpu_speedo_id, tegra_sku_info->soc_speedo_id); +} + static int tegra_fuse_add_lookups(struct tegra_fuse *fuse) { fuse->lookups = kmemdup_array(fuse->soc->lookups, sizeof(*fuse->lookups), @@ -501,12 +511,7 @@ static int __init tegra_init_fuse(void) fuse->soc->init(fuse); - pr_info("Tegra Revision: %s SKU: %d CPU Process: %d SoC Process: %d\n", - tegra_revision_name[tegra_sku_info.revision], - tegra_sku_info.sku_id, tegra_sku_info.cpu_process_id, - tegra_sku_info.soc_process_id); - pr_debug("Tegra CPU Speedo ID %d, SoC Speedo ID %d\n", - tegra_sku_info.cpu_speedo_id, tegra_sku_info.soc_speedo_id); + tegra_fuse_print_sku_info(&tegra_sku_info); err = tegra_fuse_add_lookups(fuse); if (err) -- 2.44.0 From b89bfe274e7a49db3b69108037c2fefc50ebec5b Mon Sep 17 00:00:00 2001 From: Kartik Date: Tue, 17 Oct 2023 10:53:21 +0530 Subject: [PATCH] soc/tegra: fuse: Add ACPI support for Tegra194 and Tegra234 Add ACPI support for Tegra194 & Tegra243 SoC's. This requires following modifications to the probe when ACPI boot is used: - Initialize soc data. - Add nvmem lookups. - Register soc device. - use devm_clk_get_optional() instead of devm_clk_get() to get fuse->clk, as fuse clocks are not required when using ACPI boot. Also, drop '__init' keyword for tegra_soc_device_register() as this is also used by tegra_fuse_probe() and use dev_err_probe() wherever applicable. Signed-off-by: Kartik Signed-off-by: Thierry Reding --- drivers/soc/tegra/fuse/fuse-tegra.c | 52 +++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c index 7a93c6512f7b..1c758f121f91 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra.c +++ b/drivers/soc/tegra/fuse/fuse-tegra.c @@ -3,11 +3,13 @@ * Copyright (c) 2013-2023, NVIDIA CORPORATION. All rights reserved. */ +#include #include #include #include #include #include +#include #include #include #include @@ -152,7 +154,38 @@ static int tegra_fuse_probe(struct platform_device *pdev) return PTR_ERR(fuse->base); fuse->phys = res->start; - fuse->clk = devm_clk_get(&pdev->dev, "fuse"); + /* Initialize the soc data and lookups if using ACPI boot. */ + if (is_acpi_node(dev_fwnode(&pdev->dev)) && !fuse->soc) { + u8 chip; + + tegra_acpi_init_apbmisc(); + + chip = tegra_get_chip_id(); + switch (chip) { +#if defined(CONFIG_ARCH_TEGRA_194_SOC) + case TEGRA194: + fuse->soc = &tegra194_fuse_soc; + break; +#endif +#if defined(CONFIG_ARCH_TEGRA_234_SOC) + case TEGRA234: + fuse->soc = &tegra234_fuse_soc; + break; +#endif + default: + return dev_err_probe(&pdev->dev, -EINVAL, "Unsupported SoC: %02x\n", chip); + } + + fuse->soc->init(fuse); + tegra_fuse_print_sku_info(&tegra_sku_info); + tegra_soc_device_register(); + + err = tegra_fuse_add_lookups(fuse); + if (err) + return dev_err_probe(&pdev->dev, err, "failed to add FUSE lookups\n"); + } + + fuse->clk = devm_clk_get_optional(&pdev->dev, "fuse"); if (IS_ERR(fuse->clk)) return dev_err_probe(&pdev->dev, PTR_ERR(fuse->clk), "failed to get FUSE clock\n"); @@ -275,10 +308,17 @@ static const struct dev_pm_ops tegra_fuse_pm = { SET_SYSTEM_SLEEP_PM_OPS(tegra_fuse_suspend, tegra_fuse_resume) }; +static const struct acpi_device_id tegra_fuse_acpi_match[] = { + { "NVDA200F" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(acpi, tegra_fuse_acpi_match); + static struct platform_driver tegra_fuse_driver = { .driver = { .name = "tegra-fuse", .of_match_table = tegra_fuse_match, + .acpi_match_table = tegra_fuse_acpi_match, .pm = &tegra_fuse_pm, .suppress_bind_attrs = true, }, @@ -300,7 +340,13 @@ u32 __init tegra_fuse_read_early(unsigned int offset) int tegra_fuse_readl(unsigned long offset, u32 *value) { - if (!fuse->read || !fuse->clk) + /* + * Wait for fuse->clk to be initialized if device-tree boot is used. + */ + if (is_of_node(dev_fwnode(fuse->dev)) && !fuse->clk) + return -EPROBE_DEFER; + + if (!fuse->read) return -EPROBE_DEFER; if (IS_ERR(fuse->clk)) @@ -383,7 +429,7 @@ const struct attribute_group tegra194_soc_attr_group = { }; #endif -struct device * __init tegra_soc_device_register(void) +struct device *tegra_soc_device_register(void) { struct soc_device_attribute *attr; struct soc_device *dev; -- 2.44.0 From 4009fd6095c6a524606a098c9557d226d31b3bfe Mon Sep 17 00:00:00 2001 From: Kartik Date: Tue, 17 Oct 2023 10:53:22 +0530 Subject: [PATCH] soc/tegra: fuse: Add support for Tegra241 Add support for Tegra241 which use ACPI boot. Signed-off-by: Kartik Signed-off-by: Thierry Reding --- drivers/soc/tegra/Kconfig | 5 +++++ drivers/soc/tegra/fuse/fuse-tegra.c | 5 +++++ drivers/soc/tegra/fuse/fuse-tegra30.c | 20 ++++++++++++++++++++ drivers/soc/tegra/fuse/fuse.h | 4 ++++ drivers/soc/tegra/fuse/tegra-apbmisc.c | 1 + include/soc/tegra/fuse.h | 1 + 6 files changed, 36 insertions(+) diff --git a/drivers/soc/tegra/Kconfig b/drivers/soc/tegra/Kconfig index 6f3098822969..5f5d9d663fef 100644 --- a/drivers/soc/tegra/Kconfig +++ b/drivers/soc/tegra/Kconfig @@ -133,6 +133,11 @@ config ARCH_TEGRA_234_SOC help Enable support for the NVIDIA Tegra234 SoC. +config ARCH_TEGRA_241_SOC + bool "NVIDIA Tegra241 SoC" + help + Enable support for the NVIDIA Tegra241 SoC. + endif endif diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c index 1c758f121f91..233b8e7bb41b 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra.c +++ b/drivers/soc/tegra/fuse/fuse-tegra.c @@ -171,6 +171,11 @@ static int tegra_fuse_probe(struct platform_device *pdev) case TEGRA234: fuse->soc = &tegra234_fuse_soc; break; +#endif +#if defined(CONFIG_ARCH_TEGRA_241_SOC) + case TEGRA241: + fuse->soc = &tegra241_fuse_soc; + break; #endif default: return dev_err_probe(&pdev->dev, -EINVAL, "Unsupported SoC: %02x\n", chip); diff --git a/drivers/soc/tegra/fuse/fuse-tegra30.c b/drivers/soc/tegra/fuse/fuse-tegra30.c index e94d46372a63..2070d36c510d 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra30.c +++ b/drivers/soc/tegra/fuse/fuse-tegra30.c @@ -678,3 +678,23 @@ const struct tegra_fuse_soc tegra234_fuse_soc = { .clk_suspend_on = false, }; #endif + +#if defined(CONFIG_ARCH_TEGRA_241_SOC) +static const struct tegra_fuse_info tegra241_fuse_info = { + .read = tegra30_fuse_read, + .size = 0x16008, + .spare = 0xcf0, +}; + +static const struct nvmem_keepout tegra241_fuse_keepouts[] = { + { .start = 0xc, .end = 0x1600c } +}; + +const struct tegra_fuse_soc tegra241_fuse_soc = { + .init = tegra30_fuse_init, + .info = &tegra241_fuse_info, + .keepouts = tegra241_fuse_keepouts, + .num_keepouts = ARRAY_SIZE(tegra241_fuse_keepouts), + .soc_attr_group = &tegra194_soc_attr_group, +}; +#endif diff --git a/drivers/soc/tegra/fuse/fuse.h b/drivers/soc/tegra/fuse/fuse.h index a41e9f85281a..f3b705327c20 100644 --- a/drivers/soc/tegra/fuse/fuse.h +++ b/drivers/soc/tegra/fuse/fuse.h @@ -136,4 +136,8 @@ extern const struct tegra_fuse_soc tegra194_fuse_soc; extern const struct tegra_fuse_soc tegra234_fuse_soc; #endif +#ifdef CONFIG_ARCH_TEGRA_241_SOC +extern const struct tegra_fuse_soc tegra241_fuse_soc; +#endif + #endif diff --git a/drivers/soc/tegra/fuse/tegra-apbmisc.c b/drivers/soc/tegra/fuse/tegra-apbmisc.c index 6457f80821bb..e2ca5d55fd31 100644 --- a/drivers/soc/tegra/fuse/tegra-apbmisc.c +++ b/drivers/soc/tegra/fuse/tegra-apbmisc.c @@ -64,6 +64,7 @@ bool tegra_is_silicon(void) switch (tegra_get_chip_id()) { case TEGRA194: case TEGRA234: + case TEGRA241: case TEGRA264: if (tegra_get_platform() == 0) return true; diff --git a/include/soc/tegra/fuse.h b/include/soc/tegra/fuse.h index 3a513be50243..8f421b9f7585 100644 --- a/include/soc/tegra/fuse.h +++ b/include/soc/tegra/fuse.h @@ -17,6 +17,7 @@ #define TEGRA186 0x18 #define TEGRA194 0x19 #define TEGRA234 0x23 +#define TEGRA241 0x24 #define TEGRA264 0x26 #define TEGRA_FUSE_SKU_CALIB_0 0xf0 -- 2.44.0 From 9f3808742d74a477f686fe13ac43daa3680233af Mon Sep 17 00:00:00 2001 From: Kartik Date: Wed, 20 Dec 2023 11:40:13 +0530 Subject: [PATCH] soc/tegra: fuse: Define tegra194_soc_attr_group for Tegra241 Tegra241 SoC data uses tegra194_soc_attr_group, which is only defined if config CONFIG_ARCH_TEGRA_194_SOC or CONFIG_ARCH_TEGRA_234_SOC or both are enabled. This causes a build failure if both of these configs are disabled and CONFIG_ARCH_TEGRA_241_SOC is enabled. Define tegra194_soc_attr_group if CONFIG_ARCH_TEGRA_241_SOC is enabled. Signed-off-by: Kartik Acked-by: Randy Dunlap Tested-by: Randy Dunlap # build-tested Signed-off-by: Thierry Reding --- drivers/soc/tegra/fuse/fuse-tegra.c | 3 ++- drivers/soc/tegra/fuse/fuse.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c index 233b8e7bb41b..c34efa5bf44c 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra.c +++ b/drivers/soc/tegra/fuse/fuse-tegra.c @@ -407,7 +407,8 @@ const struct attribute_group tegra_soc_attr_group = { }; #if IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) || \ - IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC) + IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC) || \ + IS_ENABLED(CONFIG_ARCH_TEGRA_241_SOC) static ssize_t platform_show(struct device *dev, struct device_attribute *attr, char *buf) { diff --git a/drivers/soc/tegra/fuse/fuse.h b/drivers/soc/tegra/fuse/fuse.h index f3b705327c20..9fee6ad6ad9e 100644 --- a/drivers/soc/tegra/fuse/fuse.h +++ b/drivers/soc/tegra/fuse/fuse.h @@ -124,7 +124,8 @@ extern const struct tegra_fuse_soc tegra186_fuse_soc; #endif #if IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) || \ - IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC) + IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC) || \ + IS_ENABLED(CONFIG_ARCH_TEGRA_241_SOC) extern const struct attribute_group tegra194_soc_attr_group; #endif -- 2.44.0 From 6f4afa855941eec29f95a5facc3af8ceda9fc613 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Fri, 16 Feb 2024 11:57:48 +0000 Subject: [PATCH] arm64: tegra: Fix Tegra234 MGBE power-domains The MGBE power-domains on Tegra234 are mapped to the MGBE controllers as follows: MGBE0 (0x68000000) --> Power-Domain MGBEB MGBE1 (0x69000000) --> Power-Domain MGBEC MGBE2 (0x6a000000) --> Power-Domain MGBED Update the device-tree nodes for Tegra234 to correct this. Fixes: 610cdf3186bc ("arm64: tegra: Add MGBE nodes on Tegra234") Signed-off-by: Jon Hunter Signed-off-by: Thierry Reding --- arch/arm64/boot/dts/nvidia/tegra234.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi index 3f16595d099c..d1bd328892af 100644 --- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi @@ -1459,7 +1459,7 @@ ethernet@6800000 { <&mc TEGRA234_MEMORY_CLIENT_MGBEAWR &emc>; interconnect-names = "dma-mem", "write"; iommus = <&smmu_niso0 TEGRA234_SID_MGBE>; - power-domains = <&bpmp TEGRA234_POWER_DOMAIN_MGBEA>; + power-domains = <&bpmp TEGRA234_POWER_DOMAIN_MGBEB>; status = "disabled"; }; @@ -1493,7 +1493,7 @@ ethernet@6900000 { <&mc TEGRA234_MEMORY_CLIENT_MGBEBWR &emc>; interconnect-names = "dma-mem", "write"; iommus = <&smmu_niso0 TEGRA234_SID_MGBE_VF1>; - power-domains = <&bpmp TEGRA234_POWER_DOMAIN_MGBEB>; + power-domains = <&bpmp TEGRA234_POWER_DOMAIN_MGBEC>; status = "disabled"; }; @@ -1527,7 +1527,7 @@ ethernet@6a00000 { <&mc TEGRA234_MEMORY_CLIENT_MGBECWR &emc>; interconnect-names = "dma-mem", "write"; iommus = <&smmu_niso0 TEGRA234_SID_MGBE_VF2>; - power-domains = <&bpmp TEGRA234_POWER_DOMAIN_MGBEC>; + power-domains = <&bpmp TEGRA234_POWER_DOMAIN_MGBED>; status = "disabled"; }; -- 2.44.0