android_kernel_oneplus_msm8998/drivers/regulator/cpr3-regulator.h
Tirupathi Reddy 86974ccc17 regulator: cpr3: Use scaled gate count for aging measurements
Use scaled gate count (GCNT) for aging measurements to reduce
the noise effect on aging data. The amount of scaling depends
on the noise effect observed in characterization results. Use
a selected scaling factor value to derive the gate count (GCNT)
used for aging measurements.

CRs-Fixed: 1025832
Change-Id: I0eb3fb08d51ddca5cd4c08e26bc83eb9f66fd3ed
Signed-off-by: Tirupathi Reddy <tirupath@codeaurora.org>
2017-03-17 14:47:40 +05:30

1110 lines
43 KiB
C

/*
* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __REGULATOR_CPR3_REGULATOR_H__
#define __REGULATOR_CPR3_REGULATOR_H__
#include <linux/clk.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/power/qcom/apm.h>
#include <linux/regulator/driver.h>
struct cpr3_controller;
struct cpr3_thread;
/**
* struct cpr3_fuse_param - defines one contiguous segment of a fuse parameter
* that is contained within a given row.
* @row: Fuse row number
* @bit_start: The first bit within the row of the fuse parameter segment
* @bit_end: The last bit within the row of the fuse parameter segment
*
* Each fuse row is 64 bits in length. bit_start and bit_end may take values
* from 0 to 63. bit_start must be less than or equal to bit_end.
*/
struct cpr3_fuse_param {
unsigned int row;
unsigned int bit_start;
unsigned int bit_end;
};
/* Each CPR3 sensor has 16 ring oscillators */
#define CPR3_RO_COUNT 16
/* The maximum number of sensors that can be present on a single CPR loop. */
#define CPR3_MAX_SENSOR_COUNT 256
/* This constant is used when allocating array printing buffers. */
#define MAX_CHARS_PER_INT 10
/**
* struct cpr4_sdelta - CPR4 controller specific data structure for the sdelta
* adjustment table which is used to adjust the VDD supply
* voltage automatically based upon the temperature and/or
* the number of online CPU cores.
* @allow_core_count_adj: Core count adjustments are allowed.
* @allow_temp_adj: Temperature based adjustments are allowed.
* @max_core_count: Maximum number of cores considered for core count
* adjustment logic.
* @temp_band_count: Number of temperature bands considered for temperature
* based adjustment logic.
* @cap_volt: CAP in uV to apply to SDELTA margins with multiple
* cpr3-regulators defined for single controller.
* @table: SDELTA table with per-online-core and temperature based
* adjustments of size (max_core_count * temp_band_count)
* Outer: core count
* Inner: temperature band
* Each element has units of VDD supply steps. Positive
* values correspond to a reduction in voltage and negative
* value correspond to an increase (this follows the SDELTA
* register semantics).
* @allow_boost: Voltage boost allowed.
* @boost_num_cores: The number of online cores at which the boost voltage
* adjustments will be applied
* @boost_table: SDELTA table with boost voltage adjustments of size
* temp_band_count. Each element has units of VDD supply
* steps. Positive values correspond to a reduction in
* voltage and negative value correspond to an increase
* (this follows the SDELTA register semantics).
*/
struct cpr4_sdelta {
bool allow_core_count_adj;
bool allow_temp_adj;
int max_core_count;
int temp_band_count;
int cap_volt;
int *table;
bool allow_boost;
int boost_num_cores;
int *boost_table;
};
/**
* struct cpr3_corner - CPR3 virtual voltage corner data structure
* @floor_volt: CPR closed-loop floor voltage in microvolts
* @ceiling_volt: CPR closed-loop ceiling voltage in microvolts
* @open_loop_volt: CPR open-loop voltage (i.e. initial voltage) in
* microvolts
* @last_volt: Last known settled CPR closed-loop voltage which is used
* when switching to a new corner
* @abs_ceiling_volt: The absolute CPR closed-loop ceiling voltage in
* microvolts. This is used to limit the ceiling_volt
* value when it is increased as a result of aging
* adjustment.
* @unaged_floor_volt: The CPR closed-loop floor voltage in microvolts before
* any aging adjustment is performed
* @unaged_ceiling_volt: The CPR closed-loop ceiling voltage in microvolts
* before any aging adjustment is performed
* @unaged_open_loop_volt: The CPR open-loop voltage (i.e. initial voltage) in
* microvolts before any aging adjusment is performed
* @system_volt: The system-supply voltage in microvolts or corners or
* levels
* @mem_acc_volt: The mem-acc-supply voltage in corners
* @proc_freq: Processor frequency in Hertz. For CPR rev. 3 and 4
* conrollers, this field is only used by platform specific
* CPR3 driver for interpolation. For CPRh-compliant
* controllers, this frequency is also utilized by the
* clock driver to determine the corner to CPU clock
* frequency mappings.
* @cpr_fuse_corner: Fused corner index associated with this virtual corner
* (only used by platform specific CPR3 driver for
* mapping purposes)
* @target_quot: Array of target quotient values to use for each ring
* oscillator (RO) for this corner. A value of 0 should be
* specified as the target quotient for each RO that is
* unused by this corner.
* @ro_scale: Array of CPR ring oscillator (RO) scaling factors. The
* scaling factor for each RO is defined from RO0 to RO15
* with units of QUOT/V. A value of 0 may be specified for
* an RO that is unused.
* @ro_mask: Bitmap where each of the 16 LSBs indicate if the
* corresponding ROs should be masked for this corner
* @irq_en: Bitmap of the CPR interrupts to enable for this corner
* @aging_derate: The amount to derate the aging voltage adjustment
* determined for the reference corner in units of uV/mV.
* E.g. a value of 900 would imply that the adjustment for
* this corner should be 90% (900/1000) of that for the
* reference corner.
* @use_open_loop: Boolean indicating that open-loop (i.e CPR disabled) as
* opposed to closed-loop operation must be used for this
* corner on CPRh controllers.
* @ldo_mode_allowed: Boolean which indicates if LDO mode is allowed for this
* corner. This field is applicable for CPR4 controllers
* that manage LDO300 supply regulator.
* @sdelta: The CPR4 controller specific data for this corner. This
* field is applicable for CPR4 controllers.
*
* The value of last_volt is initialized inside of the cpr3_regulator_register()
* call with the open_loop_volt value. It can later be updated to the settled
* VDD supply voltage. The values for unaged_floor_volt, unaged_ceiling_volt,
* and unaged_open_loop_volt are initialized inside of cpr3_regulator_register()
* if ctrl->aging_required == true. These three values must be pre-initialized
* if cpr3_regulator_register() is called with ctrl->aging_required == false and
* ctrl->aging_succeeded == true.
*
* The values of ro_mask and irq_en are initialized inside of the
* cpr3_regulator_register() call.
*/
struct cpr3_corner {
int floor_volt;
int ceiling_volt;
int open_loop_volt;
int last_volt;
int abs_ceiling_volt;
int unaged_floor_volt;
int unaged_ceiling_volt;
int unaged_open_loop_volt;
int system_volt;
int mem_acc_volt;
u32 proc_freq;
int cpr_fuse_corner;
u32 target_quot[CPR3_RO_COUNT];
u32 ro_scale[CPR3_RO_COUNT];
u32 ro_mask;
u32 irq_en;
int aging_derate;
bool use_open_loop;
bool ldo_mode_allowed;
struct cpr4_sdelta *sdelta;
};
/**
* struct cprh_corner_band - CPRh controller specific data structure which
* encapsulates the range of corners and the SDELTA
* adjustment table to be applied to the corners within
* the min and max bounds of the corner band.
* @corner: Corner number which defines the corner band boundary
* @sdelta: The SDELTA adjustment table which contains core-count
* and temp based margin adjustments that are applicable
* to the corner band.
*/
struct cprh_corner_band {
int corner;
struct cpr4_sdelta *sdelta;
};
/**
* enum cpr3_ldo_type - Constants which define the LDO supply regulator
* types used to manage the subsystem component rail voltage.
* %CPR3_LDO_KRYO: Kryo LDO regulator used to sub-regulate the HMSS
* per-cluster voltage.
* %CPR3_LDO300: LDO regulator used to sub-regulate the GFX voltage.
*/
enum cpr3_ldo_type {
CPR3_LDO_KRYO = 0,
CPR3_LDO300 = 1,
};
/**
* struct cpr3_regulator - CPR3 logical regulator instance associated with a
* given CPR3 hardware thread
* @of_node: Device node associated with the device tree child node
* of this CPR3 regulator
* @thread: Pointer to the CPR3 thread which manages this CPR3
* regulator
* @name: Unique name for this CPR3 regulator which is filled
* using the device tree regulator-name property
* @rdesc: Regulator description for this CPR3 regulator
* @rdev: Regulator device pointer for the regulator registered
* for this CPR3 regulator
* @mem_acc_regulator: Pointer to the optional mem-acc supply regulator used
* to manage memory circuitry settings based upon CPR3
* regulator output voltage.
* @ldo_regulator: Pointer to the LDO supply regulator used to manage
* per-cluster LDO voltage and bypass state
* @ldo_regulator_bypass: Cached copy of the LDO regulator bypass state
* @ldo_ret_regulator: Pointer to the LDO retention supply regulator used to
* manage LDO retention bypass state
* @corner: Array of all corners supported by this CPR3 regulator
* @corner_count: The number of elements in the corner array
* @corner_band: Array of all corner bands supported by CPRh compatible
* controllers
* @corner_band_count: The number of elements in the corner band array
* @platform_fuses: Pointer to platform specific CPR fuse data (only used by
* platform specific CPR3 driver)
* @speed_bin_fuse: Value read from the speed bin fuse parameter
* @speed_bins_supported: The number of speed bins supported by the device tree
* configuration for this CPR3 regulator
* @cpr_rev_fuse: Value read from the CPR fusing revision fuse parameter
* @fuse_combo: Platform specific enum value identifying the specific
* combination of fuse values found on a given chip
* @fuse_combos_supported: The number of fuse combinations supported by the
* device tree configuration for this CPR3 regulator
* @fuse_corner_count: Number of corners defined by fuse parameters
* @fuse_corner_map: Array of length fuse_corner_count which specifies the
* highest corner associated with each fuse corner. Note
* that each element must correspond to a valid corner
* and that element values must be strictly increasing.
* Also, it is acceptable for the lowest fuse corner to map
* to a corner other than the lowest. Likewise, it is
* acceptable for the highest fuse corner to map to a
* corner other than the highest.
* @fuse_combo_corner_sum: The sum of the corner counts across all fuse combos
* @fuse_combo_offset: The device tree property array offset for the selected
* fuse combo
* @speed_bin_corner_sum: The sum of the corner counts across all speed bins
* This may be specified as 0 if per speed bin parsing
* support is not required.
* @speed_bin_offset: The device tree property array offset for the selected
* speed bin
* @fuse_combo_corner_band_sum: The sum of the corner band counts across all
* fuse combos
* @fuse_combo_corner_band_offset: The device tree property array offset for
* the corner band count corresponding to the selected
* fuse combo
* @speed_bin_corner_band_sum: The sum of the corner band counts across all
* speed bins. This may be specified as 0 if per speed bin
* parsing support is not required
* @speed_bin_corner_band_offset: The device tree property array offset for the
* corner band count corresponding to the selected speed
* bin
* @pd_bypass_mask: Bit mask of power domains associated with this CPR3
* regulator
* @dynamic_floor_corner: Index identifying the voltage corner for the CPR3
* regulator whose last_volt value should be used as the
* global CPR floor voltage if all of the power domains
* associated with this CPR3 regulator are bypassed
* @uses_dynamic_floor: Boolean flag indicating that dynamic_floor_corner should
* be utilized for the CPR3 regulator
* @current_corner: Index identifying the currently selected voltage corner
* for the CPR3 regulator or less than 0 if no corner has
* been requested
* @last_closed_loop_corner: Index identifying the last voltage corner for the
* CPR3 regulator which was configured when operating in
* CPR closed-loop mode or less than 0 if no corner has
* been requested. CPR registers are only written to when
* using closed-loop mode.
* @aggregated: Boolean flag indicating that this CPR3 regulator
* participated in the last aggregation event
* @debug_corner: Index identifying voltage corner used for displaying
* corner configuration values in debugfs
* @ldo_type: LDO regulator type.
* @ldo_min_headroom_volt: Minimum voltage difference in microvolts required
* between the VDD supply voltage and the LDO output in
* order for the LDO operate
* @ldo_max_headroom_volt: Maximum voltage difference in microvolts between
* the input and output of the active LDO hardware to
* maintain optimum operability.
* @ldo_adjust_volt: Voltage in microvolts used to offset margin assigned
* to IR drop between PMIC and CPU
* @ldo_ret_volt: The lowest supported CPU retention voltage in
* microvolts. This voltage may vary part-to-part based
* upon the value of hardware fuses.
* @ldo_max_volt: The maximum physically supported LDO voltage in
* microvolts
* @ldo_mode_allowed: Boolean which indicates if LDO mode is allowed for this
* CPR3 regulator
* @vreg_enabled: Boolean defining the enable state of the CPR3
* regulator's regulator within the regulator framework.
* @aging_allowed: Boolean defining if CPR aging adjustments are allowed
* for this CPR3 regulator given the fuse combo of the
* device
* @aging_allow_open_loop_adj: Boolean defining if the open-loop voltage of each
* corner of this regulator should be adjusted as a result
* of an aging measurement. This flag can be set to false
* when the open-loop voltage adjustments have been
* specified such that they include the maximum possible
* aging adjustment. This flag is only used if
* aging_allowed == true.
* @aging_corner: The corner that should be configured for this regulator
* when an aging measurement is performed.
* @aging_max_adjust_volt: The maximum aging voltage margin in microvolts that
* may be added to the target quotients of this regulator.
* A value of 0 may be specified if this regulator does not
* require any aging adjustment.
* @allow_core_count_adj: Core count adjustments are allowed for this regulator.
* @allow_temp_adj: Temperature based adjustments are allowed for this
* regulator.
* @max_core_count: Maximum number of cores considered for core count
* adjustment logic.
* @allow_boost: Voltage boost allowed for this regulator.
*
* This structure contains both configuration and runtime state data. The
* elements current_corner, last_closed_loop_corner, aggregated, debug_corner,
* ldo_mode_allowed, and vreg_enabled are state variables.
*/
struct cpr3_regulator {
struct device_node *of_node;
struct cpr3_thread *thread;
const char *name;
struct regulator_desc rdesc;
struct regulator_dev *rdev;
struct regulator *mem_acc_regulator;
struct regulator *ldo_regulator;
bool ldo_regulator_bypass;
struct regulator *ldo_ret_regulator;
struct cpr3_corner *corner;
int corner_count;
struct cprh_corner_band *corner_band;
u32 corner_band_count;
void *platform_fuses;
int speed_bin_fuse;
int speed_bins_supported;
int cpr_rev_fuse;
int fuse_combo;
int fuse_combos_supported;
int fuse_corner_count;
int *fuse_corner_map;
int fuse_combo_corner_sum;
int fuse_combo_offset;
int speed_bin_corner_sum;
int speed_bin_offset;
int fuse_combo_corner_band_sum;
int fuse_combo_corner_band_offset;
int speed_bin_corner_band_sum;
int speed_bin_corner_band_offset;
u32 pd_bypass_mask;
int dynamic_floor_corner;
bool uses_dynamic_floor;
int current_corner;
int last_closed_loop_corner;
bool aggregated;
int debug_corner;
enum cpr3_ldo_type ldo_type;
int ldo_min_headroom_volt;
int ldo_max_headroom_volt;
int ldo_adjust_volt;
int ldo_ret_volt;
int ldo_max_volt;
bool ldo_mode_allowed;
bool vreg_enabled;
bool aging_allowed;
bool aging_allow_open_loop_adj;
int aging_corner;
int aging_max_adjust_volt;
bool allow_core_count_adj;
bool allow_temp_adj;
int max_core_count;
bool allow_boost;
};
/**
* struct cpr3_thread - CPR3 hardware thread data structure
* @thread_id: Hardware thread ID
* @of_node: Device node associated with the device tree child node
* of this CPR3 thread
* @ctrl: Pointer to the CPR3 controller which manages this thread
* @vreg: Array of CPR3 regulators handled by the CPR3 thread
* @vreg_count: Number of elements in the vreg array
* @aggr_corner: CPR corner containing the in process aggregated voltage
* and target quotient configurations which will be applied
* @last_closed_loop_aggr_corner: CPR corner containing the most recent
* configurations which were written into hardware
* registers when operating in closed loop mode (i.e. with
* CPR enabled)
* @consecutive_up: The number of consecutive CPR step up events needed to
* to trigger an up interrupt
* @consecutive_down: The number of consecutive CPR step down events needed to
* to trigger a down interrupt
* @up_threshold: The number CPR error steps required to generate an up
* event
* @down_threshold: The number CPR error steps required to generate a down
* event
*
* This structure contains both configuration and runtime state data. The
* elements aggr_corner and last_closed_loop_aggr_corner are state variables.
*/
struct cpr3_thread {
u32 thread_id;
struct device_node *of_node;
struct cpr3_controller *ctrl;
struct cpr3_regulator *vreg;
int vreg_count;
struct cpr3_corner aggr_corner;
struct cpr3_corner last_closed_loop_aggr_corner;
u32 consecutive_up;
u32 consecutive_down;
u32 up_threshold;
u32 down_threshold;
};
/* Per CPR controller data */
/**
* enum cpr3_mem_acc_corners - Constants which define the number of mem-acc
* regulator corners available in the mem-acc corner map array.
* %CPR3_MEM_ACC_LOW_CORNER: Index in mem-acc corner map array mapping to the
* mem-acc regulator corner
* to be used for low voltage vdd supply
* %CPR3_MEM_ACC_HIGH_CORNER: Index in mem-acc corner map array mapping to the
* mem-acc regulator corner to be used for high
* voltage vdd supply
* %CPR3_MEM_ACC_CORNERS: Number of elements in the mem-acc corner map
* array
*/
enum cpr3_mem_acc_corners {
CPR3_MEM_ACC_LOW_CORNER = 0,
CPR3_MEM_ACC_HIGH_CORNER = 1,
CPR3_MEM_ACC_CORNERS = 2,
};
/**
* enum cpr3_count_mode - CPR3 controller count mode which defines the
* method that CPR sensor data is acquired
* %CPR3_COUNT_MODE_ALL_AT_ONCE_MIN: Capture all CPR sensor readings
* simultaneously and report the minimum
* value seen in successive measurements
* %CPR3_COUNT_MODE_ALL_AT_ONCE_MAX: Capture all CPR sensor readings
* simultaneously and report the maximum
* value seen in successive measurements
* %CPR3_COUNT_MODE_STAGGERED: Read one sensor at a time in a
* sequential fashion
* %CPR3_COUNT_MODE_ALL_AT_ONCE_AGE: Capture all CPR aging sensor readings
* simultaneously.
*/
enum cpr3_count_mode {
CPR3_COUNT_MODE_ALL_AT_ONCE_MIN = 0,
CPR3_COUNT_MODE_ALL_AT_ONCE_MAX = 1,
CPR3_COUNT_MODE_STAGGERED = 2,
CPR3_COUNT_MODE_ALL_AT_ONCE_AGE = 3,
};
/**
* enum cpr_controller_type - supported CPR controller hardware types
* %CPR_CTRL_TYPE_CPR3: HW has CPR3 controller
* %CPR_CTRL_TYPE_CPR4: HW has CPR4 controller
* %CPR_CTRL_TYPE_CPRH: HW has CPRh controller
*/
enum cpr_controller_type {
CPR_CTRL_TYPE_CPR3,
CPR_CTRL_TYPE_CPR4,
CPR_CTRL_TYPE_CPRH,
};
/**
* struct cpr3_aging_sensor_info - CPR3 aging sensor information
* @sensor_id The index of the CPR3 sensor to be used in the aging
* measurement.
* @ro_scale The CPR ring oscillator (RO) scaling factor for the
* aging sensor with units of QUOT/V.
* @init_quot_diff: The fused quotient difference between aged and un-aged
* paths that was measured at manufacturing time.
* @measured_quot_diff: The quotient difference measured at runtime.
* @bypass_mask: Bit mask of the CPR sensors that must be bypassed during
* the aging measurement for this sensor
*
* This structure contains both configuration and runtime state data. The
* element measured_quot_diff is a state variable.
*/
struct cpr3_aging_sensor_info {
u32 sensor_id;
u32 ro_scale;
int init_quot_diff;
int measured_quot_diff;
u32 bypass_mask[CPR3_MAX_SENSOR_COUNT / 32];
};
/**
* struct cpr3_reg_info - Register information data structure
* @name: Register name
* @addr: Register physical address
* @value: Register content
* @virt_addr: Register virtual address
*
* This data structure is used to dump some critical register contents
* when the device crashes due to a kernel panic.
*/
struct cpr3_reg_info {
const char *name;
u32 addr;
u32 value;
void __iomem *virt_addr;
};
/**
* struct cpr3_panic_regs_info - Data structure to dump critical register
* contents.
* @reg_count: Number of elements in the regs array
* @regs: Array of critical registers information
*
* This data structure is used to dump critical register contents when
* the device crashes due to a kernel panic.
*/
struct cpr3_panic_regs_info {
int reg_count;
struct cpr3_reg_info *regs;
};
/**
* struct cpr3_controller - CPR3 controller data structure
* @dev: Device pointer for the CPR3 controller device
* @name: Unique name for the CPR3 controller
* @ctrl_id: Controller ID corresponding to the VDD supply number
* that this CPR3 controller manages.
* @cpr_ctrl_base: Virtual address of the CPR3 controller base register
* @fuse_base: Virtual address of fuse row 0
* @aging_possible_reg: Virtual address of an optional platform-specific
* register that must be ready to determine if it is
* possible to perform an aging measurement.
* @list: list head used in a global cpr3-regulator list so that
* cpr3-regulator structs can be found easily in RAM dumps
* @thread: Array of CPR3 threads managed by the CPR3 controller
* @thread_count: Number of elements in the thread array
* @sensor_owner: Array of thread IDs indicating which thread owns a given
* CPR sensor
* @sensor_count: The number of CPR sensors found on the CPR loop managed
* by this CPR controller. Must be equal to the number of
* elements in the sensor_owner array
* @soc_revision: Revision number of the SoC. This may be unused by
* platforms that do not have different behavior for
* different SoC revisions.
* @lock: Mutex lock used to ensure mutual exclusion between
* all of the threads associated with the controller
* @vdd_regulator: Pointer to the VDD supply regulator which this CPR3
* controller manages
* @system_regulator: Pointer to the optional system-supply regulator upon
* which the VDD supply regulator depends.
* @mem_acc_regulator: Pointer to the optional mem-acc supply regulator used
* to manage memory circuitry settings based upon the
* VDD supply output voltage.
* @vdd_limit_regulator: Pointer to the VDD supply limit regulator which is used
* for hardware closed-loop in order specify ceiling and
* floor voltage limits (platform specific)
* @system_supply_max_volt: Voltage in microvolts which corresponds to the
* absolute ceiling voltage of the system-supply
* @mem_acc_threshold_volt: mem-acc threshold voltage in microvolts
* @mem_acc_corner_map: mem-acc regulator corners mapping to low and high
* voltage mem-acc settings for the memories powered by
* this CPR3 controller and its associated CPR3 regulators
* @mem_acc_crossover_volt: Voltage in microvolts corresponding to the voltage
* that the VDD supply must be set to while a MEM ACC
* switch is in progress. This element must be initialized
* for CPRh controllers when a MEM ACC threshold voltage is
* defined.
* @core_clk: Pointer to the CPR3 controller core clock
* @iface_clk: Pointer to the CPR3 interface clock (platform specific)
* @bus_clk: Pointer to the CPR3 bus clock (platform specific)
* @irq: CPR interrupt number
* @irq_affinity_mask: The cpumask for the CPUs which the CPR interrupt should
* have affinity for
* @cpu_hotplug_notifier: CPU hotplug notifier used to reset IRQ affinity when a
* CPU is brought back online
* @ceiling_irq: Interrupt number for the interrupt that is triggered
* when hardware closed-loop attempts to exceed the ceiling
* voltage
* @apm: Handle to the array power mux (APM)
* @apm_threshold_volt: Voltage in microvolts which defines the threshold
* voltage to determine the APM supply selection for
* each corner
* @apm_crossover_volt: Voltage in microvolts corresponding to the voltage that
* the VDD supply must be set to while an APM switch is in
* progress. This element must be initialized for CPRh
* controllers when an APM threshold voltage is defined
* @apm_adj_volt: Minimum difference between APM threshold voltage and
* open-loop voltage which allows the APM threshold voltage
* to be used as a ceiling
* @apm_high_supply: APM supply to configure if VDD voltage is greater than
* or equal to the APM threshold voltage
* @apm_low_supply: APM supply to configure if the VDD voltage is less than
* the APM threshold voltage
* @base_volt: Minimum voltage in microvolts supported by the VDD
* supply managed by this CPR controller
* @corner_switch_delay_time: The delay time in nanoseconds used by the CPR
* controller to wait for voltage settling before
* acknowledging the OSM block after corner changes
* @cpr_clock_rate: CPR reference clock frequency in Hz.
* @sensor_time: The time in nanoseconds that each sensor takes to
* perform a measurement.
* @loop_time: The time in nanoseconds between consecutive CPR
* measurements.
* @up_down_delay_time: The time to delay in nanoseconds between consecutive CPR
* measurements when the last measurement recommended
* increasing or decreasing the vdd-supply voltage.
* (platform specific)
* @idle_clocks: Number of CPR reference clock ticks that the CPR
* controller waits in transitional states.
* @step_quot_init_min: The default minimum CPR step quotient value. The step
* quotient is the number of additional ring oscillator
* ticks observed when increasing one step in vdd-supply
* output voltage.
* @step_quot_init_max: The default maximum CPR step quotient value.
* @step_volt: Step size in microvolts between available set points
* of the VDD supply
* @down_error_step_limit: CPR4 hardware closed-loop down error step limit which
* defines the maximum number of VDD supply regulator steps
* that the voltage may be reduced as the result of a
* single CPR measurement.
* @up_error_step_limit: CPR4 hardware closed-loop up error step limit which
* defines the maximum number of VDD supply regulator steps
* that the voltage may be increased as the result of a
* single CPR measurement.
* @count_mode: CPR controller count mode
* @count_repeat: Number of times to perform consecutive sensor
* measurements when using all-at-once count modes.
* @proc_clock_throttle: Defines the processor clock frequency throttling
* register value to use. This can be used to reduce the
* clock frequency when a power domain exits a low power
* mode until CPR settles at a new voltage.
* (platform specific)
* @cpr_allowed_hw: Boolean which indicates if closed-loop CPR operation is
* permitted for a given chip based upon hardware fuse
* values
* @cpr_allowed_sw: Boolean which indicates if closed-loop CPR operation is
* permitted based upon software policies
* @supports_hw_closed_loop: Boolean which indicates if this CPR3/4 controller
* physically supports hardware closed-loop CPR operation
* @use_hw_closed_loop: Boolean which indicates that this controller will be
* using hardware closed-loop operation in place of
* software closed-loop operation.
* @ctrl_type: CPR controller type
* @saw_use_unit_mV: Boolean which indicates the unit used in SAW PVC
* interface is mV.
* @aggr_corner: CPR corner containing the most recently aggregated
* voltage configurations which are being used currently
* @cpr_enabled: Boolean which indicates that the CPR controller is
* enabled and operating in closed-loop mode. CPR clocks
* have been prepared and enabled whenever this flag is
* true.
* @last_corner_was_closed_loop: Boolean indicating if the last known corners
* were updated during closed loop operation.
* @cpr_suspended: Boolean which indicates that CPR has been temporarily
* disabled while enterring system suspend.
* @debugfs: Pointer to the debugfs directory of this CPR3 controller
* @aging_ref_volt: Reference voltage in microvolts to configure when
* performing CPR aging measurements.
* @aging_vdd_mode: vdd-supply regulator mode to configure before performing
* a CPR aging measurement. It should be one of
* REGULATOR_MODE_*.
* @aging_complete_vdd_mode: vdd-supply regulator mode to configure after
* performing a CPR aging measurement. It should be one of
* REGULATOR_MODE_*.
* @aging_ref_adjust_volt: The reference aging voltage margin in microvolts that
* should be added to the target quotients of the
* regulators managed by this controller after derating.
* @aging_required: Flag which indicates that a CPR aging measurement still
* needs to be performed for this CPR3 controller.
* @aging_succeeded: Flag which indicates that a CPR aging measurement has
* completed successfully.
* @aging_failed: Flag which indicates that a CPR aging measurement has
* failed to complete successfully.
* @aging_sensor: Array of CPR3 aging sensors which are used to perform
* aging measurements at a runtime.
* @aging_sensor_count: Number of elements in the aging_sensor array
* @aging_possible_mask: Optional bitmask used to mask off the
* aging_possible_reg register.
* @aging_possible_val: Optional value that the masked aging_possible_reg
* register must have in order for a CPR aging measurement
* to be possible.
* @aging_gcnt_scaling_factor: The scaling factor used to derive the gate count
* used for aging measurements. This value is divided by
* 1000 when used as shown in the below equation:
* Aging_GCNT = GCNT_REF * scaling_factor / 1000.
* For example, a value of 1500 specifies that the gate
* count (GCNT) used for aging measurement should be 1.5
* times of reference gate count (GCNT_REF).
* @step_quot_fixed: Fixed step quotient value used for target quotient
* adjustment if use_dynamic_step_quot is not set.
* This parameter is only relevant for CPR4 controllers
* when using the per-online-core or per-temperature
* adjustments.
* @initial_temp_band: Temperature band used for calculation of base-line
* target quotients (fused).
* @use_dynamic_step_quot: Boolean value which indicates that margin adjustment
* of target quotient will be based on the step quotient
* calculated dynamically in hardware for each RO.
* @allow_core_count_adj: Core count adjustments are allowed for this controller
* @allow_temp_adj: Temperature based adjustments are allowed for
* this controller
* @allow_boost: Voltage boost allowed for this controller.
* @temp_band_count: Number of temperature bands used for temperature based
* adjustment logic
* @temp_points: Array of temperature points in decidegrees Celsius used
* to specify the ranges for selected temperature bands.
* The array must have (temp_band_count - 1) elements
* allocated.
* @temp_sensor_id_start: Start ID of temperature sensors used for temperature
* based adjustments.
* @temp_sensor_id_end: End ID of temperature sensors used for temperature
* based adjustments.
* @voltage_settling_time: The time in nanoseconds that it takes for the
* VDD supply voltage to settle after being increased or
* decreased by step_volt microvolts which is used when
* SDELTA voltage margin adjustments are applied.
* @panic_regs_info: Array of panic registers information which provides the
* list of registers to dump when the device crashes.
* @panic_notifier: Notifier block registered to global panic notifier list.
* @support_ldo300_vreg: Boolean value which indicates that this CPR controller
* manages an underlying LDO regulator of type LDO300.
* @reset_step_quot_loop_en: Boolean value which indicates that this CPR
* controller should be configured to reset step_quot on
* each loop_en = 0 transition. This configuration allows
* the CPR controller to first use the default step_quot
* and then later switch to the run-time calibrated
* step_quot.
*
* This structure contains both configuration and runtime state data. The
* elements cpr_allowed_sw, use_hw_closed_loop, aggr_corner, cpr_enabled,
* last_corner_was_closed_loop, cpr_suspended, aging_ref_adjust_volt,
* aging_required, aging_succeeded, and aging_failed are state variables.
*
* The apm* elements do not need to be initialized if the VDD supply managed by
* the CPR3 controller does not utilize an APM.
*
* The elements step_quot_fixed, initial_temp_band, allow_core_count_adj,
* allow_temp_adj and temp* need to be initialized for CPR4 controllers which
* are using per-online-core or per-temperature adjustments.
*/
struct cpr3_controller {
struct device *dev;
const char *name;
int ctrl_id;
void __iomem *cpr_ctrl_base;
void __iomem *fuse_base;
void __iomem *aging_possible_reg;
struct list_head list;
struct cpr3_thread *thread;
int thread_count;
u8 *sensor_owner;
int sensor_count;
int soc_revision;
struct mutex lock;
struct regulator *vdd_regulator;
struct regulator *system_regulator;
struct regulator *mem_acc_regulator;
struct regulator *vdd_limit_regulator;
int system_supply_max_volt;
int mem_acc_threshold_volt;
int mem_acc_corner_map[CPR3_MEM_ACC_CORNERS];
int mem_acc_crossover_volt;
struct clk *core_clk;
struct clk *iface_clk;
struct clk *bus_clk;
int irq;
struct cpumask irq_affinity_mask;
struct notifier_block cpu_hotplug_notifier;
int ceiling_irq;
struct msm_apm_ctrl_dev *apm;
int apm_threshold_volt;
int apm_crossover_volt;
int apm_adj_volt;
enum msm_apm_supply apm_high_supply;
enum msm_apm_supply apm_low_supply;
int base_volt;
u32 corner_switch_delay_time;
u32 cpr_clock_rate;
u32 sensor_time;
u32 loop_time;
u32 up_down_delay_time;
u32 idle_clocks;
u32 step_quot_init_min;
u32 step_quot_init_max;
int step_volt;
u32 down_error_step_limit;
u32 up_error_step_limit;
enum cpr3_count_mode count_mode;
u32 count_repeat;
u32 proc_clock_throttle;
bool cpr_allowed_hw;
bool cpr_allowed_sw;
bool supports_hw_closed_loop;
bool use_hw_closed_loop;
enum cpr_controller_type ctrl_type;
bool saw_use_unit_mV;
struct cpr3_corner aggr_corner;
bool cpr_enabled;
bool last_corner_was_closed_loop;
bool cpr_suspended;
struct dentry *debugfs;
int aging_ref_volt;
unsigned int aging_vdd_mode;
unsigned int aging_complete_vdd_mode;
int aging_ref_adjust_volt;
bool aging_required;
bool aging_succeeded;
bool aging_failed;
struct cpr3_aging_sensor_info *aging_sensor;
int aging_sensor_count;
u32 aging_possible_mask;
u32 aging_possible_val;
u32 aging_gcnt_scaling_factor;
u32 step_quot_fixed;
u32 initial_temp_band;
bool use_dynamic_step_quot;
bool allow_core_count_adj;
bool allow_temp_adj;
bool allow_boost;
int temp_band_count;
int *temp_points;
u32 temp_sensor_id_start;
u32 temp_sensor_id_end;
u32 voltage_settling_time;
struct cpr3_panic_regs_info *panic_regs_info;
struct notifier_block panic_notifier;
bool support_ldo300_vreg;
bool reset_step_quot_loop_en;
};
/* Used for rounding voltages to the closest physically available set point. */
#define CPR3_ROUND(n, d) (DIV_ROUND_UP(n, d) * (d))
#define cpr3_err(cpr3_thread, message, ...) \
pr_err("%s: " message, (cpr3_thread)->name, ##__VA_ARGS__)
#define cpr3_info(cpr3_thread, message, ...) \
pr_info("%s: " message, (cpr3_thread)->name, ##__VA_ARGS__)
#define cpr3_debug(cpr3_thread, message, ...) \
pr_debug("%s: " message, (cpr3_thread)->name, ##__VA_ARGS__)
/*
* Offset subtracted from voltage corner values passed in from the regulator
* framework in order to get internal voltage corner values. This is needed
* since the regulator framework treats 0 as an error value at regulator
* registration time.
*/
#define CPR3_CORNER_OFFSET 1
#ifdef CONFIG_REGULATOR_CPR3
int cpr3_regulator_register(struct platform_device *pdev,
struct cpr3_controller *ctrl);
int cpr3_regulator_unregister(struct cpr3_controller *ctrl);
int cpr3_regulator_suspend(struct cpr3_controller *ctrl);
int cpr3_regulator_resume(struct cpr3_controller *ctrl);
int cpr3_allocate_threads(struct cpr3_controller *ctrl, u32 min_thread_id,
u32 max_thread_id);
int cpr3_map_fuse_base(struct cpr3_controller *ctrl,
struct platform_device *pdev);
int cpr3_read_fuse_param(void __iomem *fuse_base_addr,
const struct cpr3_fuse_param *param, u64 *param_value);
int cpr3_convert_open_loop_voltage_fuse(int ref_volt, int step_volt, u32 fuse,
int fuse_len);
u64 cpr3_interpolate(u64 x1, u64 y1, u64 x2, u64 y2, u64 x);
int cpr3_parse_array_property(struct cpr3_regulator *vreg,
const char *prop_name, int tuple_size, u32 *out);
int cpr3_parse_corner_array_property(struct cpr3_regulator *vreg,
const char *prop_name, int tuple_size, u32 *out);
int cpr3_parse_corner_band_array_property(struct cpr3_regulator *vreg,
const char *prop_name, int tuple_size, u32 *out);
int cpr3_parse_common_corner_data(struct cpr3_regulator *vreg);
int cpr3_parse_thread_u32(struct cpr3_thread *thread, const char *propname,
u32 *out_value, u32 value_min, u32 value_max);
int cpr3_parse_ctrl_u32(struct cpr3_controller *ctrl, const char *propname,
u32 *out_value, u32 value_min, u32 value_max);
int cpr3_parse_common_thread_data(struct cpr3_thread *thread);
int cpr3_parse_common_ctrl_data(struct cpr3_controller *ctrl);
int cpr3_limit_open_loop_voltages(struct cpr3_regulator *vreg);
void cpr3_open_loop_voltage_as_ceiling(struct cpr3_regulator *vreg);
int cpr3_limit_floor_voltages(struct cpr3_regulator *vreg);
void cpr3_print_quots(struct cpr3_regulator *vreg);
int cpr3_adjust_fused_open_loop_voltages(struct cpr3_regulator *vreg,
int *fuse_volt);
int cpr3_adjust_open_loop_voltages(struct cpr3_regulator *vreg);
int cpr3_quot_adjustment(int ro_scale, int volt_adjust);
int cpr3_voltage_adjustment(int ro_scale, int quot_adjust);
int cpr3_parse_closed_loop_voltage_adjustments(struct cpr3_regulator *vreg,
u64 *ro_sel, int *volt_adjust,
int *volt_adjust_fuse, int *ro_scale);
int cpr4_parse_core_count_temp_voltage_adj(struct cpr3_regulator *vreg,
bool use_corner_band);
int cpr3_apm_init(struct cpr3_controller *ctrl);
int cpr3_mem_acc_init(struct cpr3_regulator *vreg);
void cprh_adjust_voltages_for_apm(struct cpr3_regulator *vreg);
void cprh_adjust_voltages_for_mem_acc(struct cpr3_regulator *vreg);
int cpr3_adjust_target_quotients(struct cpr3_regulator *vreg,
int *fuse_volt_adjust);
#else
static inline int cpr3_regulator_register(struct platform_device *pdev,
struct cpr3_controller *ctrl)
{
return -ENXIO;
}
static inline int cpr3_regulator_unregister(struct cpr3_controller *ctrl)
{
return -ENXIO;
}
static inline int cpr3_regulator_suspend(struct cpr3_controller *ctrl)
{
return -ENXIO;
}
static inline int cpr3_regulator_resume(struct cpr3_controller *ctrl)
{
return -ENXIO;
}
static inline int cpr3_get_thread_name(struct cpr3_thread *thread,
struct device_node *thread_node)
{
return -EPERM;
}
static inline int cpr3_allocate_threads(struct cpr3_controller *ctrl,
u32 min_thread_id, u32 max_thread_id)
{
return -EPERM;
}
static inline int cpr3_map_fuse_base(struct cpr3_controller *ctrl,
struct platform_device *pdev)
{
return -ENXIO;
}
static inline int cpr3_read_fuse_param(void __iomem *fuse_base_addr,
const struct cpr3_fuse_param *param, u64 *param_value)
{
return -EPERM;
}
static inline int cpr3_convert_open_loop_voltage_fuse(int ref_volt,
int step_volt, u32 fuse, int fuse_len)
{
return -EPERM;
}
static inline u64 cpr3_interpolate(u64 x1, u64 y1, u64 x2, u64 y2, u64 x)
{
return 0;
}
static inline int cpr3_parse_array_property(struct cpr3_regulator *vreg,
const char *prop_name, int tuple_size, u32 *out)
{
return -EPERM;
}
static inline int cpr3_parse_corner_array_property(struct cpr3_regulator *vreg,
const char *prop_name, int tuple_size, u32 *out)
{
return -EPERM;
}
static inline int cpr3_parse_corner_band_array_property(
struct cpr3_regulator *vreg, const char *prop_name,
int tuple_size, u32 *out)
{
return -EPERM;
}
static inline int cpr3_parse_common_corner_data(struct cpr3_regulator *vreg)
{
return -EPERM;
}
static inline int cpr3_parse_thread_u32(struct cpr3_thread *thread,
const char *propname, u32 *out_value, u32 value_min,
u32 value_max)
{
return -EPERM;
}
static inline int cpr3_parse_ctrl_u32(struct cpr3_controller *ctrl,
const char *propname, u32 *out_value, u32 value_min,
u32 value_max)
{
return -EPERM;
}
static inline int cpr3_parse_common_thread_data(struct cpr3_thread *thread)
{
return -EPERM;
}
static inline int cpr3_parse_common_ctrl_data(struct cpr3_controller *ctrl)
{
return -EPERM;
}
static inline int cpr3_limit_open_loop_voltages(struct cpr3_regulator *vreg)
{
return -EPERM;
}
static inline void cpr3_open_loop_voltage_as_ceiling(
struct cpr3_regulator *vreg)
{
}
static inline int cpr3_limit_floor_voltages(struct cpr3_regulator *vreg)
{
return -EPERM;
}
static inline void cpr3_print_quots(struct cpr3_regulator *vreg)
{
}
static inline int cpr3_adjust_fused_open_loop_voltages(
struct cpr3_regulator *vreg, int *fuse_volt)
{
return -EPERM;
}
static inline int cpr3_adjust_open_loop_voltages(struct cpr3_regulator *vreg)
{
return -EPERM;
}
static inline int cpr3_quot_adjustment(int ro_scale, int volt_adjust)
{
return 0;
}
static inline int cpr3_voltage_adjustment(int ro_scale, int quot_adjust)
{
return 0;
}
static inline int cpr3_parse_closed_loop_voltage_adjustments(
struct cpr3_regulator *vreg, u64 *ro_sel,
int *volt_adjust, int *volt_adjust_fuse, int *ro_scale)
{
return 0;
}
static inline int cpr4_parse_core_count_temp_voltage_adj(
struct cpr3_regulator *vreg, bool use_corner_band)
{
return 0;
}
static inline int cpr3_apm_init(struct cpr3_controller *ctrl)
{
return 0;
}
static inline int cpr3_mem_acc_init(struct cpr3_regulator *vreg)
{
return 0;
}
static inline void cprh_adjust_voltages_for_apm(struct cpr3_regulator *vreg)
{
}
static inline void cprh_adjust_voltages_for_mem_acc(struct cpr3_regulator *vreg)
{
}
static inline int cpr3_adjust_target_quotients(struct cpr3_regulator *vreg,
int *fuse_volt_adjust)
{
return 0;
}
#endif /* CONFIG_REGULATOR_CPR3 */
#endif /* __REGULATOR_CPR_REGULATOR_H__ */