linux: linux-yocto: add support as a provider for the tegra kernel

Signed-off-by: Kurt Kiefer <kekiefer@gmail.com>
This commit is contained in:
Kurt Kiefer
2024-08-27 09:16:26 -07:00
committed by Matt Madison
parent 280460dca8
commit 9ba6b25333
19 changed files with 1518 additions and 0 deletions

View File

@@ -0,0 +1,105 @@
From 26ffd973703ca765fce04d644a78de8e0b180725 Mon Sep 17 00:00:00 2001
From: Jon Hunter <jonathanh@nvidia.com>
Date: Thu, 12 Oct 2023 11:49:09 +0100
Subject: [PATCH 1/9] 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.
Upstream-Status: Pending
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
Acked-by: Thierry Reding <treding@nvidia.com>
Link: https://lore.kernel.org/r/20231012104909.48518-1-jonathanh@nvidia.com
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
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.25.1

View File

@@ -0,0 +1,188 @@
From ab5e670e06c3385fd9ec1f6809b4742495558151 Mon Sep 17 00:00:00 2001
From: Ninad Malwade <nmalwade@nvidia.com>
Date: Fri, 29 Sep 2023 11:36:49 +0100
Subject: [PATCH 2/9] 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.
Upstream-Status: Pending
Signed-off-by: Rajkumar Kasirajan <rkasirajan@nvidia.com>
Signed-off-by: Ninad Malwade <nmalwade@nvidia.com>
Co-developed-by: Jon Hunter <jonathanh@nvidia.com>
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
Link: https://lore.kernel.org/r/20230929103650.86074-4-jonathanh@nvidia.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
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 <afd@ti.com>
*/
+#include <linux/debugfs.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/i2c.h>
@@ -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.25.1

View File

@@ -0,0 +1,201 @@
From 72159b110a95f50887784dbb7771cbbcefde7576 Mon Sep 17 00:00:00 2001
From: Sumit Gupta <sumitg@nvidia.com>
Date: Wed, 4 Oct 2023 19:35:36 +0530
Subject: [PATCH 3/9] 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.
Upstream-Status: Pending
Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
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.25.1

View File

@@ -0,0 +1,195 @@
From 417688bed63554f235fdc4b03c078a8ee2efcbc8 Mon Sep 17 00:00:00 2001
From: Sumit Gupta <sumitg@nvidia.com>
Date: Wed, 4 Oct 2023 19:35:37 +0530
Subject: [PATCH 4/9] 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".
Upstream-Status: Pending
Suggested-by: Antti Miettinen <amiettinen@nvidia.com>
Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
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 <linux/cpu.h>
#include <linux/cpufreq.h>
-#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <linux/of.h>
@@ -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.25.1

View File

@@ -0,0 +1,35 @@
From 43194c25943acd2588aff56cce80485dd31238d6 Mon Sep 17 00:00:00 2001
From: Sumit Gupta <sumitg@nvidia.com>
Date: Mon, 9 Oct 2023 13:54:23 +0530
Subject: [PATCH 5/9] 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.
Upstream-Status: Pending
Suggested-by: Viresh Kumar <viresh.kumar@linaro.org>
Link: https://lore.kernel.org/lkml/20231003050019.a6mcchw2o2z2wkrh@vireshk-i7/
Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
[ Viresh: Fix rebase conflict ]
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
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.25.1

View File

@@ -0,0 +1,101 @@
From e9d717f5991936ee8207e5ca65c2b3dc5c13c989 Mon Sep 17 00:00:00 2001
From: Thierry Reding <treding@nvidia.com>
Date: Wed, 1 Nov 2023 18:20:16 +0100
Subject: [PATCH 6/9] 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.
Upstream-Status: Pending
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
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 <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/of.h>
+#include <linux/of_address.h>
#include <linux/of_clk.h>
#include <linux/of_platform.h>
#include <linux/parser.h>
@@ -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, &params->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(&params->memory, 0, sizeof(params->memory));
+ }
+
return 0;
}
@@ -193,6 +212,8 @@ static int simplefb_parse_pd(struct platform_device *pdev,
return -EINVAL;
}
+ memset(&params->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 = &params.memory;
}
mem = request_mem_region(res->start, resource_size(res), "simplefb");
--
2.25.1

View File

@@ -0,0 +1,150 @@
From a0be355e6802345084fbca28646ce9e3c7defddf Mon Sep 17 00:00:00 2001
From: Thierry Reding <treding@nvidia.com>
Date: Wed, 1 Nov 2023 18:20:17 +0100
Subject: [PATCH 7/9] 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
Upstream-Status: Pending
Signed-off-by: Thierry Reding <treding@nvidia.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
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 <linux/of_clk.h>
#include <linux/of_platform.h>
#include <linux/parser.h>
+#include <linux/pm_domain.h>
#include <linux/regulator/consumer.h>
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.25.1

View File

@@ -0,0 +1,98 @@
From 30e70a4c2fec54bce91fa1fc53cca7c9ee9390ca Mon Sep 17 00:00:00 2001
From: Vidya Sagar <vidyas@nvidia.com>
Date: Thu, 13 Oct 2022 23:48:12 +0530
Subject: [PATCH 8/9] UBUNTU: SAUCE: PCI: endpoint: Add core_deinit() callback
support
BugLink: https://bugs.launchpad.net/bugs/2001557
The endpoint function driver should undo the things done in core_init()
and stop hardware access before deinitializing the controller. Add
core_deinit() callback support for function driver to do this cleanup.
This core_deinit() callback should be invoked by the controller driver
before deinitializing the controller.
Upstream-Status: Pending
Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
Signed-off-by: Kartik <kkartik@nvidia.com>
Acked-by: Brad Figg <bfigg@nvidia.com>
Acked-by: Jacob Martin <jacob.martin@canonical.com>
Acked-by: Ian May <ian.may@canonical.com>
Signed-off-by: Brad Figg <bfigg@nvidia.com>
---
drivers/pci/endpoint/pci-epc-core.c | 26 ++++++++++++++++++++++++++
include/linux/pci-epc.h | 1 +
include/linux/pci-epf.h | 2 ++
3 files changed, 29 insertions(+)
diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
index a7d3a92391a4..94e61baedef7 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -757,6 +757,32 @@ void pci_epc_init_notify(struct pci_epc *epc)
}
EXPORT_SYMBOL_GPL(pci_epc_init_notify);
+/**
+ * pci_epc_deinit_notify() - Notify the EPF device that EPC device's core
+ * deinitialization is scheduled.
+ * @epc: the EPC device whose core deinitialization is scheduled
+ *
+ * Invoke to Notify the EPF device that the EPC device's deinitialization
+ * is scheduled.
+ */
+void pci_epc_deinit_notify(struct pci_epc *epc)
+{
+ struct pci_epf *epf;
+
+ if (!epc || IS_ERR(epc))
+ return;
+
+ mutex_lock(&epc->list_lock);
+ list_for_each_entry(epf, &epc->pci_epf, list) {
+ mutex_lock(&epf->lock);
+ if (epf->event_ops->core_deinit)
+ epf->event_ops->core_deinit(epf);
+ mutex_unlock(&epf->lock);
+ }
+ mutex_unlock(&epc->list_lock);
+}
+EXPORT_SYMBOL_GPL(pci_epc_deinit_notify);
+
/**
* pci_epc_bme_notify() - Notify the EPF device that the EPC device has received
* the BME event from the Root complex
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index 5cb694031072..907f69b51ee0 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -205,6 +205,7 @@ int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf,
void pci_epc_linkup(struct pci_epc *epc);
void pci_epc_linkdown(struct pci_epc *epc);
void pci_epc_init_notify(struct pci_epc *epc);
+void pci_epc_deinit_notify(struct pci_epc *epc);
void pci_epc_bme_notify(struct pci_epc *epc);
void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf,
enum pci_epc_interface_type type);
diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h
index 3f44b6aec477..27b2a7f63ceb 100644
--- a/include/linux/pci-epf.h
+++ b/include/linux/pci-epf.h
@@ -70,12 +70,14 @@ struct pci_epf_ops {
/**
* struct pci_epf_event_ops - Callbacks for capturing the EPC events
* @core_init: Callback for the EPC initialization complete event
+ * @core_deinit: Callback for the EPC deinitialization schedule event
* @link_up: Callback for the EPC link up event
* @link_down: Callback for the EPC link down event
* @bme: Callback for the EPC BME (Bus Master Enable) event
*/
struct pci_epc_event_ops {
int (*core_init)(struct pci_epf *epf);
+ int (*core_deinit)(struct pci_epf *epf);
int (*link_up)(struct pci_epf *epf);
int (*link_down)(struct pci_epf *epf);
int (*bme)(struct pci_epf *epf);
--
2.25.1

View File

@@ -0,0 +1,57 @@
CONFIG_DRM=m
CONFIG_DRM_MIPI_DSI=y
CONFIG_DRM_KMS_HELPER=m
CONFIG_DRM_FBDEV_EMULATION=y
CONFIG_DRM_FBDEV_OVERALLOC=100
# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set
CONFIG_DRM_DISPLAY_HELPER=m
CONFIG_DRM_DISPLAY_DP_HELPER=y
CONFIG_DRM_DISPLAY_HDMI_HELPER=y
CONFIG_DRM_TTM=m
CONFIG_DRM_EXEC=m
CONFIG_DRM_VRAM_HELPER=m
CONFIG_DRM_TTM_HELPER=m
CONFIG_DRM_GEM_DMA_HELPER=m
CONFIG_DRM_GEM_SHMEM_HELPER=m
CONFIG_DRM_SCHED=m
CONFIG_DRM_TEGRA=m
# CONFIG_DRM_TEGRA_DEBUG is not set
CONFIG_DRM_TEGRA_STAGING=y
CONFIG_DRM_PANEL=y
#
# Display Panels
#
CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
CONFIG_DRM_PANEL_DSI_CM=m
CONFIG_DRM_PANEL_LVDS=m
CONFIG_DRM_PANEL_SIMPLE=m
CONFIG_DRM_PANEL_EDP=m
CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m
CONFIG_DRM_PANEL_RAYDIUM_RM67191=m
CONFIG_DRM_PANEL_SITRONIX_ST7703=m
CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m
# end of Display Panels
CONFIG_DRM_BRIDGE=y
CONFIG_DRM_PANEL_BRIDGE=y
#
# Display Interface Bridges
#
CONFIG_DRM_DISPLAY_CONNECTOR=m
CONFIG_DRM_SIMPLE_BRIDGE=m
CONFIG_DRM_DW_HDMI=m
CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
CONFIG_DRM_DW_HDMI_I2S_AUDIO=m
CONFIG_DRM_DW_HDMI_CEC=m
CONFIG_DRM_DW_MIPI_DSI=m
CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_SIMPLE=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_BACKLIGHT_PWM=m
CONFIG_BACKLIGHT_LP855X=m
CONFIG_VIDEOMODE_HELPERS=y

View File

@@ -0,0 +1,16 @@
CONFIG_I2C_HID_ACPI=m
CONFIG_I2C_HID_OF=m
CONFIG_I2C_HID_CORE=m
CONFIG_HIDRAW=y
CONFIG_USB_XHCI_PLATFORM=y
CONFIG_SENSORS_ARM_SCMI=y
CONFIG_SENSORS_ARM_SCPI=y
CONFIG_ARM_SCMI_CPUFREQ=y
CONFIG_ARM_SMMU_V3_PMU=m
CONFIG_ARM_SBSA_WATCHDOG=y
CONFIG_ARM_SP805_WATCHDOG=y
CONFIG_ARM_SMC_WATCHDOG=y
CONFIG_ARM_CCI_PMU=m

View File

@@ -0,0 +1,18 @@
CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
CONFIG_THERMAL_GOV_USER_SPACE=y
CONFIG_CPU_FREQ_GOV_ATTR_SET=y
CONFIG_CPU_FREQ_GOV_COMMON=y
CONFIG_CPU_FREQ_STAT=y
CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
CONFIG_CPU_THERMAL=y
CONFIG_CPU_FREQ_THERMAL=y
CONFIG_DEVFREQ_THERMAL=y
CONFIG_DEVFREQ_GOV_PERFORMANCE=y
CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
CONFIG_DEVFREQ_GOV_USERSPACE=m

View File

@@ -0,0 +1,15 @@
CONFIG_PCI_ENDPOINT=y
CONFIG_PCI_ENDPOINT_CONFIGFS=y
CONFIG_PCI_EPF_TEST=m
CONFIG_PCI_HOST_GENERIC=y
CONFIG_PCI_TEGRA=y
CONFIG_PCIE_TEGRA194=m
CONFIG_PCIE_TEGRA194_HOST=m
CONFIG_PCIE_TEGRA194_EP=m
CONFIG_PCIEAER=y
CONFIG_NVME_CORE=m
CONFIG_BLK_DEV_NVME=m
CONFIG_NVME_FABRICS=m
CONFIG_NVME_TARGET=m

View File

@@ -0,0 +1,2 @@
CONFIG_SCSI_UFSHCD=y
CONFIG_SCSI_UFSHCD_PLATFORM=y

View File

@@ -0,0 +1,38 @@
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_AUDIO_GRAPH_CARD=m
CONFIG_SND_DMAENGINE_PCM=y
CONFIG_SND_DYNAMIC_MINORS=y
CONFIG_SND_HWDEP=y
CONFIG_SND_PCM=y
CONFIG_SND_SOC=y
CONFIG_SND_SOC_I2C_AND_SPI=y
CONFIG_SND_TIMER=y
CONFIG_SND_USB_AUDIO=y
CONFIG_SND_HDA=m
CONFIG_SND_HDA_TEGRA=m
CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0
CONFIG_SND_HDA_CORE=m
CONFIG_SND_HDA_ALIGNED_MMIO=y
CONFIG_SND_SOC_DMIC=m
CONFIG_SND_SOC_HDMI_CODEC=m
CONFIG_SND_SOC_SIMPLE_AMPLIFIER=m
CONFIG_SND_SOC_SIMPLE_MUX=m
CONFIG_SND_SOC_SPDIF=m
CONFIG_SND_SOC_TEGRA=m
CONFIG_SND_SOC_TEGRA210_AHUB=m
CONFIG_SND_SOC_TEGRA210_DMIC=m
CONFIG_SND_SOC_TEGRA210_I2S=m
CONFIG_SND_SOC_TEGRA210_OPE=m
CONFIG_SND_SOC_TEGRA186_ASRC=m
CONFIG_SND_SOC_TEGRA186_DSPK=m
CONFIG_SND_SOC_TEGRA210_ADMAIF=m
CONFIG_SND_SOC_TEGRA210_MVC=m
CONFIG_SND_SOC_TEGRA210_SFC=m
CONFIG_SND_SOC_TEGRA210_AMX=m
CONFIG_SND_SOC_TEGRA210_ADX=m
CONFIG_SND_SOC_TEGRA210_MIXER=m
CONFIG_SND_SOC_TEGRA_AUDIO_GRAPH_CARD=m

View File

@@ -0,0 +1,40 @@
CONFIG_EXTCON_USB_GPIO=y
CONFIG_PHY_TEGRA_XUSB=y
CONFIG_PHY_TEGRA194_P2U=m
CONFIG_TYPEC=m
CONFIG_TYPEC_TCPM=m
CONFIG_TYPEC_TCPCI=m
CONFIG_USB_CHIPIDEA=y
CONFIG_USB_CHIPIDEA_TEGRA=y
CONFIG_USB_GADGET=y
CONFIG_USB_TEGRA_XUDC=m
CONFIG_USB_XHCI_TEGRA=y
CONFIG_USB_LIBCOMPOSITE=m
CONFIG_USB_F_ACM=m
CONFIG_USB_U_SERIAL=m
CONFIG_USB_U_ETHER=m
CONFIG_USB_F_SERIAL=m
CONFIG_USB_F_OBEX=m
CONFIG_USB_F_NCM=m
CONFIG_USB_F_ECM=m
CONFIG_USB_F_EEM=m
CONFIG_USB_F_SUBSET=m
CONFIG_USB_F_RNDIS=m
CONFIG_USB_F_MASS_STORAGE=m
CONFIG_USB_F_FS=m
CONFIG_USB_CONFIGFS=m
CONFIG_USB_CONFIGFS_SERIAL=y
CONFIG_USB_CONFIGFS_ACM=y
CONFIG_USB_CONFIGFS_OBEX=y
CONFIG_USB_CONFIGFS_NCM=y
CONFIG_USB_CONFIGFS_ECM=y
CONFIG_USB_CONFIGFS_ECM_SUBSET=y
CONFIG_USB_CONFIGFS_RNDIS=y
CONFIG_USB_CONFIGFS_EEM=y
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
CONFIG_USB_CONFIGFS_F_FS=y

View File

@@ -0,0 +1,8 @@
CONFIG_MEDIA_PLATFORM_DRIVERS=y
CONFIG_V4L2_H264=m
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_VIDEO_TEGRA_VDE=m
CONFIG_VIDEOBUF2_V4L2=m
CONFIG_VIDEO_V4L2_I2C=y
CONFIG_STAGING_MEDIA=y
CONFIG_VIDEO_MUX=y

View File

@@ -0,0 +1,24 @@
CONFIG_GUEST_PERF_EVENTS=y
CONFIG_ARM64_ERRATUM_834220=y
CONFIG_IRQ_BYPASS_MANAGER=y
CONFIG_HAVE_KVM_IRQCHIP=y
CONFIG_HAVE_KVM_IRQ_ROUTING=y
CONFIG_HAVE_KVM_DIRTY_RING=y
CONFIG_HAVE_KVM_DIRTY_RING_ACQ_REL=y
CONFIG_NEED_KVM_DIRTY_RING_WITH_BITMAP=y
CONFIG_KVM_MMIO=y
CONFIG_HAVE_KVM_MSI=y
CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT=y
CONFIG_KVM_VFIO=y
CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT=y
CONFIG_HAVE_KVM_IRQ_BYPASS=y
CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE=y
CONFIG_KVM_XFER_TO_GUEST_WORK=y
CONFIG_KVM_GENERIC_HARDWARE_ENABLING=y
CONFIG_VIRTUALIZATION=y
CONFIG_KVM=y
CONFIG_PREEMPT_NOTIFIERS=y
CONFIG_MMU_NOTIFIER=y
CONFIG_INTERVAL_TREE=y
CONFIG_SCHED_INFO=y
CONFIG_PARAVIRT=y

View File

@@ -0,0 +1,84 @@
CONFIG_ARM64_PMEM=y
# CONFIG_SHADOW_CALL_STACK is not set
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_GPIO=y
CONFIG_SRAM=y
CONFIG_ARM_DSU_PMU=y
CONFIG_ARM_TEGRA186_CPUFREQ=y
CONFIG_ARM_TEGRA194_CPUFREQ=y
CONFIG_TEGRA_ACONNECT=m
CONFIG_TEGRA_IVC=y
CONFIG_TEGRA_BPMP=y
CONFIG_DMA_RESTRICTED_POOL=y
CONFIG_DMA_CMA=y
CONFIG_DMA_NUMA_CMA=y
CONFIG_CMA_SIZE_MBYTES=32
CONFIG_CMA_SIZE_SEL_MBYTES=y
CONFIG_CMA_ALIGNMENT=8
CONFIG_DTC=y
CONFIG_OF=y
CONFIG_OF_FLATTREE=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_KOBJ=y
CONFIG_OF_DYNAMIC=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_IRQ=y
CONFIG_OF_RESERVED_MEM=y
CONFIG_OF_RESOLVE=y
CONFIG_OF_OVERLAY=y
CONFIG_OF_NUMA=y
CONFIG_SENSORS_LM90=m
CONFIG_SENSORS_INA3221=m
CONFIG_SERIAL_TEGRA=y
CONFIG_SERIAL_TEGRA_TCU=y
CONFIG_SERIAL_TEGRA_TCU_CONSOLE=y
CONFIG_I2C_TEGRA=y
CONFIG_I2C_TEGRA_BPMP=y
CONFIG_SPI_TEGRA114=m
CONFIG_PINCTRL_TEGRA=y
CONFIG_PINCTRL_TEGRA124=y
CONFIG_PINCTRL_TEGRA210=y
CONFIG_PINCTRL_TEGRA194=y
CONFIG_PINCTRL_TEGRA234=y
CONFIG_GPIO_TEGRA186=y
CONFIG_TEGRA_SOCTHERM=m
CONFIG_TEGRA_BPMP_THERMAL=m
CONFIG_TEGRA_HOST1X_CONTEXT_BUS=y
CONFIG_TEGRA_HOST1X=m
CONFIG_TEGRA_HOST1X_FIREWALL=y
CONFIG_MMC_SDHCI_TEGRA=y
CONFIG_RTC_DRV_TEGRA=y
CONFIG_DMA_VIRTUAL_CHANNELS=y
CONFIG_TEGRA186_GPC_DMA=y
CONFIG_TEGRA20_APB_DMA=y
CONFIG_TEGRA210_ADMA=m
CONFIG_STAGING=y
CONFIG_CLK_TEGRA_BPMP=y
CONFIG_TEGRA_CLK_DFLL=y
CONFIG_TEGRA_TIMER=y
CONFIG_TEGRA186_TIMER=y
CONFIG_TEGRA_HSP_MBOX=y
CONFIG_ARCH_TEGRA_132_SOC=y
CONFIG_ARCH_TEGRA_210_SOC=y
CONFIG_ARCH_TEGRA_186_SOC=y
CONFIG_ARCH_TEGRA_194_SOC=y
CONFIG_ARCH_TEGRA_234_SOC=y
CONFIG_SOC_TEGRA_FLOWCTRL=y
CONFIG_SOC_TEGRA_PMC=y
CONFIG_SOC_TEGRA_POWERGATE_BPMP=y
CONFIG_SOC_TEGRA_CBB=y
CONFIG_RESET_TEGRA_BPMP=y
CONFIG_HTE=y
CONFIG_HTE_TEGRA194=y
CONFIG_HTE_TEGRA194_TEST=m
CONFIG_CONFIGFS_FS=y
CONFIG_AQUANTIA_PHY=y
CONFIG_DWMAC_TEGRA=m

View File

@@ -0,0 +1,143 @@
FILESEXTRAPATHS:prepend:tegra := "${THISDIR}/${PN}:"
TEGRA_UEFI_SIGNING_CLASS ??= "tegra-uefi-signing"
INHERIT_DEPS = ""
INHERIT_DEPS:tegra = "${TEGRA_UEFI_SIGNING_CLASS}"
inherit ${INHERIT_DEPS}
SRC_URI:append:tegra = " \
file://0001-memory-tegra-Add-Tegra234-clients-for-RCE-and-VI.patch \
file://0002-hwmon-ina3221-Add-support-for-channel-summation-disa.patch \
file://0003-cpufreq-tegra194-save-CPU-data-to-avoid-repeated-SMP.patch \
file://0004-cpufreq-tegra194-use-refclk-delta-based-loop-instead.patch \
file://0005-cpufreq-tegra194-remove-redundant-AND-with-cpu_onlin.patch \
file://0006-fbdev-simplefb-Support-memory-region-property.patch \
file://0007-fbdev-simplefb-Add-support-for-generic-power-domains.patch \
file://0008-UBUNTU-SAUCE-PCI-endpoint-Add-core_deinit-callback-s.patch \
file://tegra.cfg \
file://tegra-drm.cfg \
file://tegra-governors.cfg \
file://tegra-pcie.cfg \
file://tegra-scsi-ufs.cfg \
file://tegra-sound.cfg \
file://tegra-usb.cfg \
file://tegra-v4l2.cfg \
file://tegra-virtualization.cfg \
file://rtw8822ce-wifi.cfg \
"
COMPATIBLE_MACHINE:tegra = "(tegra)"
KMACHINE:tegra = "genericarm64"
KERNEL_FEATURES:append:tegra = " \
features/bluetooth/bluetooth.scc \
features/bluetooth/bluetooth-usb.scc \
features/i2c/i2c.scc \
features/input/touchscreen.scc \
features/media/media.scc \
features/media/media-platform.scc \
features/media/media-usb-webcams.scc \
features/usb/serial.scc \
features/usb/usb-raw-gadget.scc \
features/usb/xhci-hcd.scc \
"
# All of our device trees are out-of-tree
KERNEL_DEVICETREE:forcevariable:tegra = ""
sign_kernel_image() {
tegra_uefi_sbsign "$1"
shift
while [ $# -gt 0 ]; do
tegra_uefi_attach_sign "$1"
shift
done
}
SIGNING_DEPS ?= ""
SIGNING_DEPS:tegra ?= "${TEGRA_UEFI_SIGNING_TASKDEPS}"
do_sign_kernel() {
# do nothing by default
}
do_sign_kernel:tegra() {
sign_kernel_image ${KERNEL_OUTPUT_DIR}/${KERNEL_IMAGETYPE}
}
do_sign_kernel[dirs] = "${B}"
do_sign_kernel[depends] += "${SIGNING_DEPS}"
addtask sign_kernel after do_compile before do_install
sign_bootimg() {
tegra_uefi_attach_sign "$1"
}
bootimg_from_bundled_initramfs() {
if [ ! -z "${INITRAMFS_IMAGE}" -a "${INITRAMFS_IMAGE_BUNDLE}" = "1" ]; then
rm -f ${WORKDIR}/initrd
touch ${WORKDIR}/initrd
for imageType in ${KERNEL_IMAGETYPES} ; do
if [ "$imageType" = "fitImage" ] ; then
continue
fi
initramfs_base_name=${imageType}-${INITRAMFS_NAME}
initramfs_symlink_name=${imageType}-${INITRAMFS_LINK_NAME}
${STAGING_BINDIR_NATIVE}/tegra-flash/mkbootimg \
--kernel $deployDir/${initramfs_base_name}.bin \
--ramdisk ${WORKDIR}/initrd \
--cmdline "${KERNEL_ARGS}" \
--output $deployDir/${initramfs_base_name}.cboot
sign_bootimg $deployDir/${initramfs_base_name}.cboot
chmod 0644 $deployDir/${initramfs_base_name}.cboot
ln -sf ${initramfs_base_name}.cboot $deployDir/${initramfs_symlink_name}.cboot
done
elif [ -z "${INITRAMFS_IMAGE}" ]; then
rm -f ${WORKDIR}/initrd
touch ${WORKDIR}/initrd
for imageType in ${KERNEL_IMAGETYPES} ; do
if [ "$imageType" = "fitImage" ] ; then
continue
fi
baseName=$imageType-${KERNEL_IMAGE_NAME}
${STAGING_BINDIR_NATIVE}/tegra-flash/mkbootimg \
--kernel $deployDir/${baseName}.bin \
--ramdisk ${WORKDIR}/initrd \
--cmdline "${KERNEL_ARGS}" \
--output $deployDir/${baseName}.cboot
sign_bootimg $deployDir/${baseName}.cboot
chmod 0644 $deployDir/${baseName}.cboot
ln -sf ${baseName}.cboot $deployDir/$imageType-${KERNEL_IMAGE_LINK_NAME}.cboot
ln -sf ${baseName}.cboot $deployDir/$imageType.cboot
done
fi
}
do_deploy:append:tegra() {
bootimg_from_bundled_initramfs
}
DEPLOY_DEPS ?= ""
DEPLOY_DEPS:tegra ?= "tegra-flashtools-native:do_populate_sysroot ${TEGRA_UEFI_SIGNING_TASKDEPS}"
do_deploy[depends] += "${DEPLOY_DEPS}"
# RRECOMMENDS:${KERNEL_PACKAGE_NAME}-base:tegra = ""
# kernel.bbclass automatically adds a dependency on the intramfs image
# even if INITRAMFS_IMAGE_BUNDLE is disabled. This creates a circular
# dependency for tegra builds, where we need to combine initramfs (as an
# initrd) and kernel artifacts into a bootable image, so break that
# dependency here.
python () {
mach_overrides = d.getVar('MACHINEOVERRIDES')
mach_overrides = frozenset(mach_overrides.split(':'))
if 'tegra' in mach_overrides and d.getVar('INITRAMFS_IMAGE') and not bb.utils.to_boolean(d.getVar('INITRAMFS_IMAGE_BUNDLE')):
flags = d.getVarFlag('do_bundle_initramfs', 'depends', False).split()
try:
i = flags.index('${INITRAMFS_IMAGE}:do_image_complete')
del flags[i]
d.setVarFlag('do_bundle_initramfs', 'depends', ' '.join(flags))
except ValueError:
bb.warn('did not find it in %s' % ','.join(flags))
pass
}