2
     ˆÈÇ„ì¶ÏÆÀÄ ?÷     /* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Generic OPP Interface
 *
 * Copyright (C) 2009-2010 Texas Instruments Incorporated.
 *	Nishanth Menon
 *	Romit Dasgupta
 *	Kevin Hilman
 */

#ifndef __LINUX_OPP_H__
#define __LINUX_OPP_H__

#include <linux/energy_model.h>
#include <linux/err.h>
#include <linux/notifier.h>

struct clk;
struct regulator;
struct dev_pm_opp;
struct device;
struct opp_table;

enum dev_pm_opp_event {
	OPP_EVENT_ADD, OPP_EVENT_REMOVE, OPP_EVENT_ENABLE, OPP_EVENT_DISABLE,
	OPP_EVENT_ADJUST_VOLTAGE,
};

/**
 * struct dev_pm_opp_supply - Power supply voltage/current values
 * @u_volt:	Target voltage in microvolts corresponding to this OPP
 * @u_volt_min:	Minimum voltage in microvolts corresponding to this OPP
 * @u_volt_max:	Maximum voltage in microvolts corresponding to this OPP
 * @u_amp:	Maximum current drawn by the device in microamperes
 * @u_watt:	Power used by the device in microwatts
 *
 * This structure stores the voltage/current/power values for a single power
 * supply.
 */
struct dev_pm_opp_supply {
	unsigned long u_volt;
	unsigned long u_volt_min;
	unsigned long u_volt_max;
	unsigned long u_amp;
	unsigned long u_watt;
};

/**
 * struct dev_pm_opp_icc_bw - Interconnect bandwidth values
 * @avg:	Average bandwidth corresponding to this OPP (in icc units)
 * @peak:	Peak bandwidth corresponding to this OPP (in icc units)
 *
 * This structure stores the bandwidth values for a single interconnect path.
 */
struct dev_pm_opp_icc_bw {
	u32 avg;
	u32 peak;
};

typedef int (*config_regulators_t)(struct device *dev,
			struct dev_pm_opp *old_opp, struct dev_pm_opp *new_opp,
			struct regulator **regulators, unsigned int count);

typedef int (*config_clks_t)(struct device *dev, struct opp_table *opp_table,
			struct dev_pm_opp *opp, void *data, bool scaling_down);

/**
 * struct dev_pm_opp_config - Device OPP configuration values
 * @clk_names: Clk names, NULL terminated array.
 * @config_clks: Custom set clk helper.
 * @prop_name: Name to postfix to properties.
 * @config_regulators: Custom set regulator helper.
 * @supported_hw: Array of hierarchy of versions to match.
 * @supported_hw_count: Number of elements in the array.
 * @regulator_names: Array of pointers to the names of the regulator, NULL terminated.
 * @genpd_names: Null terminated array of pointers containing names of genpd to
 *		attach. Mutually exclusive with required_dev.
 * @virt_devs: Pointer to return the array of genpd virtual devices. Mutually
 *		exclusive with required_dev.
 * @required_dev: Required OPP device. Mutually exclusive with genpd_names/virt_devs.
 * @required_dev_index: The index of the required OPP for the @required_dev.
 *
 * This structure contains platform specific OPP configurations for the device.
 */
struct dev_pm_opp_config {
	/* NULL terminated */
	const char * const *clk_names;
	config_clks_t config_clks;
	const char *prop_name;
	config_regulators_t config_regulators;
	const unsigned int *supported_hw;
	unsigned int supported_hw_count;
	const char * const *regulator_names;
	const char * const *genpd_names;
	struct device ***virt_devs;
	struct device *required_dev;
	unsigned int required_dev_index;
};

#define OPP_LEVEL_UNSET			U32_MAX

/**
 * struct dev_pm_opp_data - The data to use to initialize an OPP.
 * @turbo: Flag to indicate whether the OPP is to be marked turbo or not.
 * @level: The performance level for the OPP. Set level to OPP_LEVEL_UNSET if
 * level field isn't used.
 * @freq: The clock rate in Hz for the OPP.
 * @u_volt: The voltage in uV for the OPP.
 */
struct dev_pm_opp_data {
	bool turbo;
	unsigned int level;
	unsigned long freq;
	unsigned long u_volt;
};

#if defined(CONFIG_PM_OPP)

struct opp_table *dev_pm_opp_get_opp_table(struct device *dev);
void dev_pm_opp_put_opp_table(struct opp_table *opp_table);

unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp);

int dev_pm_opp_get_supplies(struct dev_pm_opp *opp, struct dev_pm_opp_supply *supplies);

unsigned long dev_pm_opp_get_power(struct dev_pm_opp *opp);

unsigned long dev_pm_opp_get_freq_in