drivers/soc/tegra/regulators-tegra30.c

Source file repositories/reference/linux-study-clean/drivers/soc/tegra/regulators-tegra30.c

File Facts

System
Linux kernel
Corpus path
drivers/soc/tegra/regulators-tegra30.c
Extension
.c
Size
13047 bytes
Lines
535
Domain
Driver Families
Bucket
drivers/soc
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 tegra_regulator_coupler {
	struct regulator_coupler coupler;
	struct regulator_dev *core_rdev;
	struct regulator_dev *cpu_rdev;
	struct notifier_block reboot_notifier;
	struct notifier_block suspend_notifier;
	int core_min_uV, cpu_min_uV;
	bool sys_reboot_mode_req;
	bool sys_reboot_mode;
	bool sys_suspend_mode_req;
	bool sys_suspend_mode;
};

static inline struct tegra_regulator_coupler *
to_tegra_coupler(struct regulator_coupler *coupler)
{
	return container_of(coupler, struct tegra_regulator_coupler, coupler);
}

static int tegra30_core_limit(struct tegra_regulator_coupler *tegra,
			      struct regulator_dev *core_rdev)
{
	int core_min_uV = 0;
	int core_max_uV;
	int core_cur_uV;
	int err;

	/*
	 * Tegra30 SoC has critical DVFS-capable devices that are
	 * permanently-active or active at a boot time, like EMC
	 * (DRAM controller) or Display controller for example.
	 *
	 * The voltage of a CORE SoC power domain shall not be dropped below
	 * a minimum level, which is determined by device's clock rate.
	 * This means that we can't fully allow CORE voltage scaling until
	 * the state of all DVFS-critical CORE devices is synced.
	 */
	if (tegra_pmc_core_domain_state_synced() && !tegra->sys_reboot_mode) {
		pr_info_once("voltage state synced\n");
		return 0;
	}

	if (tegra->core_min_uV > 0)
		return tegra->core_min_uV;

	core_cur_uV = regulator_get_voltage_rdev(core_rdev);
	if (core_cur_uV < 0)
		return core_cur_uV;

	core_max_uV = max(core_cur_uV, 1200000);

	err = regulator_check_voltage(core_rdev, &core_min_uV, &core_max_uV);
	if (err)
		return err;

	/*
	 * Limit minimum CORE voltage to a value left from bootloader or,
	 * if it's unreasonably low value, to the most common 1.2v or to
	 * whatever maximum value defined via board's device-tree.
	 */
	tegra->core_min_uV = core_max_uV;

	pr_info("core voltage initialized to %duV\n", tegra->core_min_uV);

	return tegra->core_min_uV;
}

static int tegra30_core_cpu_limit(int cpu_uV)
{
	if (cpu_uV < 800000)
		return 950000;

	if (cpu_uV < 900000)
		return 1000000;

	if (cpu_uV < 1000000)
		return 1100000;

	if (cpu_uV < 1100000)
		return 1200000;

	if (cpu_uV < 1250000) {
		switch (tegra_sku_info.cpu_speedo_id) {
		case 0 ... 1:
		case 4:
		case 7 ... 8:
			return 1200000;

		default:
			return 1300000;

Annotation

Implementation Notes