drivers/memory/tegra/tegra186-emc.c

Source file repositories/reference/linux-study-clean/drivers/memory/tegra/tegra186-emc.c

File Facts

System
Linux kernel
Corpus path
drivers/memory/tegra/tegra186-emc.c
Extension
.c
Size
10615 bytes
Lines
421
Domain
Driver Families
Bucket
drivers/memory
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct tegra186_emc_dvfs {
	unsigned long latency;
	unsigned long rate;
};

struct tegra186_emc {
	struct tegra_bpmp *bpmp;
	struct device *dev;
	struct clk *clk;
	struct clk *clk_dbb;

	struct tegra186_emc_dvfs *dvfs;
	unsigned int num_dvfs;

	struct {
		struct dentry *root;
		unsigned long min_rate;
		unsigned long max_rate;
	} debugfs;

	struct icc_provider provider;
};

/*
 * debugfs interface
 *
 * The memory controller driver exposes some files in debugfs that can be used
 * to control the EMC frequency. The top-level directory can be found here:
 *
 *   /sys/kernel/debug/emc
 *
 * It contains the following files:
 *
 *   - available_rates: This file contains a list of valid, space-separated
 *     EMC frequencies.
 *
 *   - min_rate: Writing a value to this file sets the given frequency as the
 *       floor of the permitted range. If this is higher than the currently
 *       configured EMC frequency, this will cause the frequency to be
 *       increased so that it stays within the valid range.
 *
 *   - max_rate: Similarily to the min_rate file, writing a value to this file
 *       sets the given frequency as the ceiling of the permitted range. If
 *       the value is lower than the currently configured EMC frequency, this
 *       will cause the frequency to be decreased so that it stays within the
 *       valid range.
 */

static bool tegra186_emc_validate_rate(struct tegra186_emc *emc,
				       unsigned long rate)
{
	unsigned int i;

	for (i = 0; i < emc->num_dvfs; i++)
		if (rate == emc->dvfs[i].rate)
			return true;

	return false;
}

static int tegra186_emc_debug_available_rates_show(struct seq_file *s,
						   void *data)
{
	struct tegra186_emc *emc = s->private;
	const char *prefix = "";
	unsigned int i;

	for (i = 0; i < emc->num_dvfs; i++) {
		seq_printf(s, "%s%lu", prefix, emc->dvfs[i].rate);
		prefix = " ";
	}

	seq_puts(s, "\n");

	return 0;
}
DEFINE_SHOW_ATTRIBUTE(tegra186_emc_debug_available_rates);

static int tegra186_emc_debug_min_rate_get(void *data, u64 *rate)
{
	struct tegra186_emc *emc = data;

	*rate = emc->debugfs.min_rate;

	return 0;
}

static int tegra186_emc_debug_min_rate_set(void *data, u64 rate)
{
	struct tegra186_emc *emc = data;

Annotation

Implementation Notes