Merge "regulator: add snapshot of cpr3-regulator and dependent drivers"

This commit is contained in:
qctecmdr 2019-12-18 22:55:16 -08:00 committed by Gerrit - the friendly Code Review server
commit 15fbed51b5
10 changed files with 14322 additions and 0 deletions

View File

@ -0,0 +1,622 @@
Qualcomm Technologies, Inc. CPR3 Regulator - Platform Independent Bindings
Core Power Reduction (CPR) version 3 controllers are used by some Qualcomm
Technologies, Inc. (QTI) SoCs to manage important voltage regulators. CPR3
controllers are capable of monitoring several ring oscillator sensing loops
simultaneously. The CPR3 controller informs software when the silicon
conditions require the supply voltage to be increased or decreased. On certain
supply rails, the CPR3 controller is able to propagate the voltage increase
or decrease requests all the way to the PMIC without software involvement.
This document describes the common platform independent bindings that apply
to all CPR3 controllers.
=======================
Required Node Structure
=======================
CPR3 regulators must be described in three levels of devices nodes. The first
level describes the CPR3 controller. The second level describes one or more
hardware threads managed by the controller. The third level describes one or
more logical regulators handled by each CPR thread.
====================================
First Level Nodes - CPR3 Controllers
====================================
Platform independent properties:
- compatible
Usage: required
Value type: <string>
Definition: The value to use for this property is defined in the
platform specific cpr3-regulator binding documentation
files.
- reg
Usage: required
Value type: <prop-encoded-array>
Definition: Addresses and sizes for the memory of the CPR3 controller,
the first fuse row, and optionally a register used to check
if aging measurements are possible.
- reg-names
Usage: required
Value type: <stringlist>
Definition: Address names. Must include "cpr_ctrl" and "fuse_base".
"aging_allowed" may also be specified. The strings must be
specified in the same order as the corresponding addresses
are specified in the reg property.
- qcom,cpr-ctrl-name
Usage: required
Value type: <string>
Definition: Name for this CPR controller
- vdd-supply
Usage: required
Value type: <phandle>
Definition: phandle of the underlying regulator device that is managed
by this CPR controller.
- system-supply
Usage: optional
Value type: <phandle>
Definition: phandle of the system-level regulator device which the
vdd-supply depends upon. Requests for this regulator must
be made before increasing the vdd-supply voltage and after
decreasing the vdd-supply voltage.
- mem-acc-supply
Usage: optional
Value type: <phandle>
Definition: phandle of the mem-acc regulator device which is used to
configure memory array circuitry settings based upon
the performance operating point. Requests for this regulator
must be made before decreasing the vdd-supply voltage and
after increasing the vdd-supply voltage.
- clocks
Usage: optional
Value type: <prop-encoded-array>
Definition: Array of clock tuples in which each tuple consists of a
phandle to a clock device and a clock ID number. The CPR3
core clock must be specified for some targets. See platform
specific cpr3-regulator binding documentation for additional
clocks that may also need to be specified.
- clock-names
Usage: optional
Value type: <stringlist>
Definition: Clock names. This list must match up 1-to-1 with the clocks
specified in the 'clocks' property. "core_clk" must be
specified for some platforms. Other clocks may be required
for some platforms.
- interrupts
Usage: required
Value type: <prop-encoded-array>
Definition: CPR interrupt specifier and optionally a hardware
closed-loop ceiling interrupt specifier.
- interrupt-names
Usage: required
Value type: <stringlist>
Definition: Interrupt names. This list must match up 1-to-1 with the
interrupts specified in the 'interrupts' property. "cpr"
must be specified. "ceiling" may be specified for some
platforms.
- qcom,cpr-interrupt-affinity
Usage: optional
Value type: <prop-encoded-array>
Definition: A list of CPU phandles which correspond to the cores that
the "cpr" interrupt should have affinity for.
- qcom,cpr-sensor-time
Usage: required
Value type: <u32>
Definition: The time in nanoseconds that each CPR sensor within the
sensing loop takes to perform a measurement.
- qcom,cpr-loop-time
Usage: required
Value type: <u32>
Definition: The time in nanoseconds between consecutive CPR
measurements.
- qcom,cpr-idle-cycles
Usage: required
Value type: <u32>
Definition: The number of CPR core clock cycles for the CPR controller
to wait in transitional states.
Supported values: 0 - 31.
- qcom,voltage-step
Usage: required
Value type: <u32>
Definition: The voltage in microvolts of a single step of the VDD supply
regulator being controlled by CPR.
- qcom,cpr-step-quot-init-min
Usage: required
Value type: <u32>
Definition: The default minimum CPR step quotient value. The step
quotient is the number of additional ring oscillator ticks
observed for each qcom,voltage-step increase in vdd-supply
output voltage. Supported values: 0 - 63.
- qcom,cpr-step-quot-init-max
Usage: required
Value type: <u32>
Definition: The default maximum CPR step quotient value.
Supported values: 0 - 63.
- qcom,cpr-count-mode
Usage: required
Value type: <u32>
Definition: The CPR counting mode to use during CPR measurements.
Supported values:
0 - Read all sensors at once and use the minimum
quotient value observed in repeated measurements.
1 - Read all sensors at once and use the maximum
quotient value observed in repeated measurements.
2 - Read each sensor once in a sequential, staggered
fashion.
- qcom,cpr-count-repeat
Usage: optional
Value type: <u32>
Definition: The number of times to read CPR sensors during a single CPR
measurement when using one of the all-at-once count modes.
- qcom,cpr-enable
Usage: optional
Value type: <empty>
Definition: Boolean flag which indicates that the CPR3 controller
should operate in closed-loop mode (i.e. CPR sensing loop
enabled) as opposed to open-loop mode (i.e. CPR sensing loop
disabled) by default.
- qcom,cpr-aging-ref-voltage
Usage: required if qcom,allow-aging-voltage-adjustment is specified
for any third level nodes
Value type: <u32>
Definition: Specifies the CPR aging reference voltage in microvolts.
This is the voltage that vdd-supply must be set to when
performing an aging measurement.
- qcom,cpr-aging-allowed-reg-mask
Usage: required if "aging_allowed" register is specified
Value type: <u32>
Definition: Bitmask used to mask off the "aging_allowed" register.
- qcom,cpr-aging-allowed-reg-value
Usage: required if "aging_allowed" register is specified
Value type: <u32>
Definition: Value required in the masked off "aging_allowed" register
bits in order for a CPR aging measurement to be possible.
- qcom,cpr-panic-reg-addr-list
Usage: optional
Value type: <prop-encoded-array>
Definition: Array of register addresses to be dumped when device resets.
- qcom,cpr-panic-reg-name-list
Usage: optional, though only meaningful if
qcom,cpr-panic-reg-addr-list is specified
Value type: <prop-encoded-array>
Definition: Address names. Must be specified in the same order
as the corresponding addresses are specified in
the qcom,cpr-panic-reg-addr-list property.
=================================================
Second Level Nodes - CPR Threads for a Controller
=================================================
Platform independent properties:
- qcom,cpr-thread-id
Usage: required
Value type: <u32>
Definition: Specifies the hardware thread ID of this thread within the
CPR controller.
- qcom,cpr-consecutive-up
Usage: required
Value type: <u32>
Definition: The number of consecutive CPR step up events needed to
to trigger an up interrupt. Supported values: 0 - 15.
- qcom,cpr-consecutive-down
Usage: required
Value type: <u32>
Definition: The number of consecutive CPR step down events needed to
to trigger a down interrupt. Supported values: 0 - 15.
- qcom,cpr-up-threshold
Usage: required
Value type: <u32>
Definition: The number CPR error steps required to generate an up event.
Supported values: 0 - 31.
- qcom,cpr-down-threshold
Usage: required
Value type: <u32>
Definition: The number CPR error steps required to generate a down
event. Supported values: 0 - 31.
===============================================
Third Level Nodes - CPR Regulators for a Thread
===============================================
Platform independent properties:
- regulator-name
Usage: required
Value type: <string>
Definition: Specifies the name for this CPR3 regulator.
- regulator-min-microvolt
Usage: required
Value type: <u32>
Definition: Minimum corner value which should be 1 to represent the
lowest supported corner.
- regulator-max-microvolt
Usage: required
Value type: <u32>
Definition: Maximum corner value which should be equal to largest value
listed in qcom,cpr-corners.
- qcom,cpr-fuse-corners
Usage: required
Value type: <u32>
Definition: Specifies the number of fuse corners. See platform specific
binding files for further requirements.
- qcom,cpr-fuse-combos
Usage: required
Value type: <u32>
Definition: Specifies the number of fuse combinations being supported by
the device. This value is utilized by several other
properties. Supported values are 1 up to the maximum
possible for a given regulator type. See platform specific
binding files for further details.
- qcom,cpr-speed-bins
Usage: optional
Value type: <u32>
Definition: Specifies the number of speed bins being supported by the
device. This value is utilized by several other properties.
Supported values are 1 up to the maximum possible for a
given regulator type. See platform specific binding files
for further details.
This property can only be utilized if the number of corners
for all fuse combinations associated with a given speed bin
is the same.
- qcom,cpr-corners
Usage: required
Value type: <prop-encoded-array>
Definition: A list of integers which defines how many voltage corners
are to be used for each fuse combination. The list must
contain either qcom,cpr-fuse-combos number of elements in
which case the corner counts are applied to fuse
combinations 1-to-1 or the list must contain exactly 1
element which is used regardless of the fuse combination
found on a given chip.
- qcom,cpr-speed-bin-corners
Usage: required if qcom,cpr-speed-bins is specified
Value type: <prop-encoded-array>
Definition: A list of integers which defines how many voltage corners
are to be used for each speed bin. The list must contain
qcom,cpr-speed-bins number of elements.
- qcom,cpr-corner-fmax-map
Usage: required
Value type: <prop-encoded-array>
Definition: A list of integer tuples which each define the highest
(i.e. maximum frequency) 1-based corner value associated
with each fuse-corner.
Each tuple must have a number of elements equal to the value
of the qcom,cpr-fuse-corners property. The elements of a
tuple are ordered from lowest to highest fuse corner.
The list must contain qcom,cpr-fuse-combos number of tuples
in which case the tuples are matched to fuse combinations
1-to-1 or qcom,cpr-speed-bins number of tuples in which case
the tuples are matched to speed bins 1-to-1 or exactly 1
tuple which is used regardless of the fuse combination and
speed bin found on a given chip.
- qcom,cpr-voltage-ceiling
Usage: required
Value type: <prop-encoded-array>
Definition: A list of integer tuples which each define the CPR ceiling
voltage in microvolts for each voltage corner in order from
lowest to highest.
The list must contain qcom,cpr-fuse-combos number of tuples
in which case the tuples are matched to fuse combinations
1-to-1 or qcom,cpr-speed-bins number of tuples in which case
the tuples are matched to speed bins 1-to-1 or exactly 1
tuple which is used regardless of the fuse combination and
speed bin found on a given chip.
Each tuple must be of the length defined in the
corresponding element of the qcom,cpr-corners property or
the qcom,cpr-speed-bins property. A single tuple may only
be specified if all of the corner counts in qcom,cpr-corners
are the same.
- qcom,cpr-voltage-floor
Usage: required
Value type: <prop-encoded-array>
Definition: A list of integer tuples which each define the CPR floor
voltage in microvolts for each voltage corner in order from
lowest to highest.
The list and tuples must meet the same size requirements as
those specified for qcom,cpr-voltage-ceiling above.
- qcom,cpr-floor-to-ceiling-max-range
Usage: optional
Value type: <prop-encoded-array>
Definition: A list of integer tuples which each define the maximum
allowed difference between the final floor voltage and the
final ceiling voltage in microvolts for each voltage corner
in order from lowest to highest. A negative value may be
specified for an element to indicate that there is no
limitation of the floor to ceiling voltage range for the
corresponding corner.
In the case that the initial floor to ceiling voltage is
greater than the max range specified, the floor voltage will
be increased in order to satisfy the max range constraint.
The list and tuples must meet the same size requirements as
those specified for qcom,cpr-voltage-ceiling above.
- qcom,system-voltage
Usage: optional
Value type: <prop-encoded-array>
Definition: A list of integer tuples which each define the system-supply
voltage in microvolts or corners or levels for each voltage
corner in order from lowest to highest.
The list and tuples must meet the same size requirements as
those specified for qcom,cpr-voltage-ceiling above.
- qcom,corner-frequencies
Usage: required
Value type: <prop-encoded-array>
Definition: A list of integer tuples which each define the CPU frequency
in Hertz corresponding to each voltage corner in order from
lowest to highest.
The list and tuples must meet the same size requirements as
those specified for qcom,cpr-voltage-ceiling above.
- qcom,allow-voltage-interpolation
Usage: optional
Value type: <empty>
Definition: Boolean flag which indicates that it is acceptable to use
interpolated open-loop voltage values. These values are
interpolated between the open-loop voltage Fmax fuse values.
- qcom,cpr-scaled-open-loop-voltage-as-ceiling
Usage: optional
Value type: <empty>
Definition: Boolean flag which indicates that it is acceptable to use
the interpolated open-loop voltage for each corner as the
CPR ceiling voltage for each corner.
- qcom,cpr-open-loop-voltage-fuse-adjustment
Usage: optional
Value type: <prop-encoded-array>
Definition: A list of integer tuples which each define the open-loop
voltage adjustment in microvolts for each fused voltage
corner in order from lowest to highest. This adjustment is
applied to the values read from fuses before the values are
used in interpolation for intermediate corners.
The list and tuples must meet the same size requirements as
those specified for qcom,cpr-corner-fmax-map above.
The open-loop voltage for a given fuse corner corresponds to
the voltage that is safe to use under all circumstances.
It is used as a starting voltage for CPR and may also be
specified as a ceiling voltage for CPR scaling.
- qcom,cpr-open-loop-voltage-adjustment
Usage: optional
Value type: <prop-encoded-array>
Definition: A list of integer tuples which each define the open-loop
voltage adjustment in microvolts for each voltage corner in
order from lowest to highest. This adjustment is applied to
the open-loop voltage values after they have been
interpolated for intermediate corners.
The list and tuples must meet the same size requirements as
those specified for qcom,cpr-voltage-ceiling above.
- qcom,cpr-open-loop-voltage-min-diff
Usage: optional; only meaningful if the
qcom,cpr-open-loop-voltage-adjustment property is specified
Value type: <prop-encoded-array>
Definition: A list of integer tuples which each define the minimum
allowed open-loop voltage difference in microvolts between
each voltage corner and the one immediately preceding it.
The elements in a tuple are ordered from the lowest to the
highest corner. The value specified for the first corner is
ignored since there is no corner before it.
Negative voltage values may be specified for this property.
A negative value means that the open-loop voltage of a
corner may be lower than that of the preceding corner.
The minimum difference is enforced after the open-loop
voltage values have been interpolated for intermediate
corners and after adjustments have been applied.
The list and tuples must meet the same size requirements as
those specified for qcom,cpr-voltage-ceiling above.
If this property is not specified, then the minimum
difference is assumed to be 0 uV for all corners.
- qcom,cpr-closed-loop-voltage-fuse-adjustment
Usage: optional
Value type: <prop-encoded-array>
Definition: A list of integer tuples which each define the closed-loop
voltage adjustment in microvolts for each fused voltage
corner in order from lowest to highest. This adjustment is
applied to the values read from fuses before the values are
used in interpolation for intermediate corners.
The list and tuples must meet the same size requirements as
those specified for qcom,cpr-corner-fmax-map above.
The qcom,cpr-ro-scaling-factor property must be specified in
order to utilize this property.
The closed-loop voltage for a given fuse corner corresponds
to the voltage that the CPR controller settles the VDD
supply rail to based upon the programmed CPR target
quotients and the current silicon conditions.
- qcom,cpr-closed-loop-voltage-adjustment
Usage: optional
Value type: <prop-encoded-array>
Definition: A list of integer tuples which each define the closed-loop
voltage adjustment in microvolts for each voltage corner in
order from lowest to highest. This adjustment is applied to
target quotient values after they have been interpolated
for intermediate corners.
The list and tuples must meet the same size requirements as
those specified for qcom,cpr-voltage-ceiling above.
The qcom,cpr-ro-scaling-factor property must be specified in
order to utilize this property.
- qcom,cpr-ro-scaling-factor
Usage: required if qcom,cpr-closed-loop-voltage-fuse-adjustment,
qcom,cpr-closed-loop-voltage-adjustment, or
qcom,allow-aging-voltage-adjustment is specified
Value type: <prop-encoded-array>
Definition: A grouping of integer tuple lists. Each tuple defines the
CPR ring oscillator (RO) scaling factor with units of QUOT/V
for each RO for a given fuse corner. Since CPR3 supports
exactly 16 ROs, each tuple must contain 16 elements
corresponding to RO0 through RO15 in order. If a given RO
is unused for a fuse corner, then its scaling factor may be
specified as 0.
Each tuple list must contain the number of tuples defined in
the qcom,cpr-fuse-corners property. The tuples in a given
list are ordered from the lowest fuse corner to the highest
fuse corner.
The tuple list grouping must contain qcom,cpr-fuse-combos
number of tuple lists in which case the lists are matched to
fuse combinations 1-to-1 or qcom,cpr-speed-bins number of
tuple lists in which case the lists are matched to
speed bins 1-to-1 or exactly 1 list which is used regardless
of the fuse combination and speed bin found on a given chip.
The target quotient adjustment to apply for each RO of a
given corner is determined by multiplying the adjustment
value in qcom,cpr-closed-loop-voltage-fuse-adjustment or
qcom,cpr-closed-loop-voltage-adjustment by the relevant RO
scaling factor in this property.
- qcom,allow-aging-voltage-adjustment
Usage: optional
Value type: <prop-encoded-array>
Definition: A list of integers which specifies if CPR aging adjustment
should be performed for each fuse combination.
Supported per-combo element values:
0 - do not perform CPR aging adjustment
1 - perform CPR aging adjustment
The list must contain qcom,cpr-fuse-combos number of
elements in which case the elements are matched to fuse
combinations 1-to-1 or qcom,cpr-speed-bins number of
elements in which case the elements are matched to
speed bins 1-to-1 or exactly 1 element which is used
regardless of the fuse combination and speed bin found
on a given chip.
- qcom,allow-aging-open-loop-voltage-adjustment
Usage: optional
Value type: <prop-encoded-array>
Definition: A list of integers which specifies if CPR aging adjustment
should be applied to open-loop voltages for each fuse
combination. Note that aging adjustment must be allowed via
qcom,allow-aging-voltage-adjustment in order for this
property to have an effect.
Supported per-combo element values:
0 - do not perform CPR aging adjustment
1 - perform CPR aging adjustment
The list must meet the same size requirements as those
specified for qcom,allow-aging-voltage-adjustment above.
- qcom,cpr-aging-max-voltage-adjustment
Usage: required if qcom,allow-aging-voltage-adjustment is specified
Value type: <prop-encoded-array>
Definition: A list of integers which defines the maximum CPR aging
voltage margin adjustment in microvolts that may be added
for each fuse combination. If this property is specified
and the adjustment specified is greater than 0, then aging
adjustments are required for this regulator.
The list must meet the same size requirements as those
specified for qcom,allow-aging-voltage-adjustment above.
- qcom,cpr-aging-ref-corner
Usage: required if qcom,allow-aging-voltage-adjustment is specified
Value type: <prop-encoded-array>
Definition: A list of integers which defines the CPR reference corner
for this regulator to use during aging measurements for each
fuse combination.
The list must meet the same size requirements as those
specified for qcom,allow-aging-voltage-adjustment above.
- qcom,cpr-aging-ro-scaling-factor
Usage: required if qcom,allow-aging-voltage-adjustment is specified
Value type: <prop-encoded-array>
Definition: A list of integers which defines the CPR aging ring
oscillator (RO) scaling factor with units of QUOT/V to use
during aging measurements for each fuse combination.
The list must meet the same size requirements as those
specified for qcom,allow-aging-voltage-adjustment above.
- qcom,cpr-aging-derate
Usage: optional, though only meaningful if
qcom,allow-aging-voltage-adjustment is specified
Value type: <prop-encoded-array>
Definition: A list of integer tuples which each define the CPR aging
derating scaling factor to apply to the closed-loop voltage
margin adjustment for each corner. The individual scaling
factors have units of uV/mV and are ordered from lowest to
highest corner per tuple. For example, a value of 900
specifies that the voltage adjustment for the corner should
be 90% (900/1000) of that for the reference corner.
The list and tuples must meet the same size requirements as
those specified for qcom,cpr-voltage-ceiling above.
If this property is not specified, then it is assumed that
no corners require derating (i.e. the scaling factor would
be 1000).
All properties specified within the core regulator framework can also be used in
third level nodes. These bindings can be found in:
Documentation/devicetree/bindings/regulator/regulator.txt.
See platform specific cpr3-regulator binding documentation files for examples.

View File

@ -0,0 +1,321 @@
Qualcomm Technologies, Inc. CPR4 Regulator - MMSS LDO Specific Bindings
MMSS LDO CPR4 controllers each support one CPR thread that monitors the voltage
of the graphics processor (MMSS) supply regulator. The CPR open-loop voltages
are stored in hardware fuses for MMSS CPR4 controllers. However, the CPR target
quotients must be defined in device tree.
This document describes the MMSS LDO specific CPR4 bindings.
=======================
Required Node Structure
=======================
CPR3 regulators must be described in three levels of devices nodes. The first
level describes the CPR3 controller. The second level describes exacly one
hardware thread managed by the controller. The third level describes one or
more logical regulators handled by the CPR thread.
All platform independent cpr3-regulator binding guidelines defined in
cpr3-regulator.txt also apply to cpr4-mmss-ldo-regulator devices.
====================================
First Level Nodes - CPR3 Controllers
====================================
MMSS LDO specific properties:
- compatible
Usage: required
Value type: <string>
Definition: should be the following:
"qcom,cpr4-sdm660-mmss-ldo-regulator".
- clocks
Usage: required
Value type: <prop-encoded-array>
Definition: Array of clock tuples in which each tuple consists of a
phandle to a clock device and a clock ID number. The
following clocks must be specified: MMSS RBCPR and MMSS
RBCPR AHB.
- clock-names
Usage: required
Value type: <stringlist>
Definition: Clock names. This list must match up 1-to-1 with the clocks
specified in the 'clocks' property. "core_clk", and "bus_clk"
must be specified.
- qcom,cpr-step-quot-fixed
Usage: Optional
Value type: <u32>
Definition: Fixed step quotient value used by controller for applying
the SDELTA margin adjustments on the programmed target
quotient values. The step quotient is the number of
additional ring oscillator ticks observed for each
qcom,voltage-step increase in vdd-supply output voltage.
Supported values: 0 - 63.
=================================================
Second Level Nodes - CPR Threads for a Controller
=================================================
MMSS specific properties:
N/A
===============================================
Third Level Nodes - CPR Regulators for a Thread
===============================================
MMSS specific properties:
- qcom,cpr-fuse-corners
Usage: required
Value type: <u32>
Definition: Specifies the number of fuse corners. This value must be 6
for sdm660 GFX LDO. These fuse corners are: MinSVS,
LowSVS, SVS, SVSP, NOM and NOMP. The open-loop voltage fuses
are allocated for LowSVS, SVS, NOM and NOMP corners. The
open-loop voltages for MinSVS and SVSP are derived by
applying fixed offset from LowSVS and NOM open-loop voltages
respectively. The closed-loop offset voltage fuses are
allocated for LowSVS, SVS, NOM and NOMP corners. The MinSVS
and SVSP corners use the closed-loop offset voltage fuses of
LowSVS and NOM corners respectively.
- qcom,cpr-fuse-combos
Usage: required
Value type: <u32>
Definition: Specifies the number of fuse combinations being supported by
the device. This value is utilized by several other
properties. Supported values are 1 up to the maximum
possible for a given regulator type. For MMSS the maximum
supported value is 8. These combos correspond to CPR
revision fuse values from 0 to 7 in order.
- qcom,mem-acc-voltage
Usage: required if mem-acc-supply is specified for the CPR3 controller
containing this CPR3 regulator
Value type: <prop-encoded-array>
Definition: A list of integer tuples which each define the mem-acc-supply
corner for each voltage corner in order from lowest to highest.
The list must contain qcom,cpr-fuse-combos number of tuples
in which case the tuples are matched to fuse combinations
1-to-1 or qcom,cpr-speed-bins number of tuples in which case
the tuples are matched to speed bins 1-to-1 or exactly 1
tuple which is used regardless of the fuse combination and
speed bin found on a given chip.
Each tuple must be of the length defined in the
corresponding element of the qcom,cpr-corners property or
the qcom,cpr-speed-bins property. A single tuple may only
be specified if all of the corner counts in qcom,cpr-corners
are the same.
- qcom,cpr-target-quotients
Usage: required
Value type: <prop-encoded-array>
Definition: A grouping of integer tuple lists. Each tuple defines the
CPR target quotient for each ring oscillator (RO) for a
given corner. Since CPR3 supports exactly 16 ROs, each
tuple must contain 16 elements corresponding to RO0 through
RO15 in order. If a given RO is unused for a corner, then
its target quotient should be specified as 0.
Each tuple list in the grouping must meet the same size
requirements as those specified for qcom,mem-acc-voltage
above. The tuples in a given list are ordered from the
lowest corner to the highest corner.
- qcom,cpr-ro-scaling-factor
Usage: required if qcom,cpr-closed-loop-voltage-adjustment is
specified
Value type: <prop-encoded-array>
Definition: The common definition of this property in cpr3-regulator.txt
is accurate for MMSS CPR3 controllers except for this
modification:
Each tuple list must contain the number of tuples defined in
the corresponding element of the qcom,cpr-corners property
or the qcom,cpr-speed-bins property as opposed to the value
of the qcom,cpr-fuse-corners property.
- qcom,cpr-fused-closed-loop-voltage-adjustment-map
Usage: optional
Value type: <prop-encoded-array>
Definition: A list of integer tuples which each define the CPR fused
corner closed-loop offset adjustment fuse to utilize for
each voltage corner in order from lowest to highest.
The list must contain qcom,cpr-fuse-combos number of tuples
in which case the tuples are matched to fuse combinations
1-to-1 or qcom,cpr-speed-bins number of tuples in which case
the tuples are matched to speed bins 1-to-1 or exactly 1
tuple which is used regardless of the fuse combination and
speed bin found on a given chip.
Each tuple must be of the length defined in the
corresponding element of the qcom,cpr-corners property or
the qcom,cpr-speed-bins property. A single tuple may only
be specified if all of the corner counts in qcom,cpr-corners
are the same.
Each tuple element must be either 0 or in the range 1 to
qcom,cpr-fuse-corners. A value of 0 signifies that no fuse
based adjustment should be applied to the fuse corner.
Values 1 to qcom,cpr-fuse-corners denote the specific fuse
corner that should be used by a given voltage corner.
- qcom,cpr-corner-allow-ldo-mode
Usage: optional
Value type: <prop-encoded-array>
Definition: A list of integer tuples which each define the LDO mode
allowed state for each voltage corner in order from lowest
to highest. Each element in the tuple should be either
0 (LDO mode not allowed) or 1 (LDO mode allowed).
The list must contain qcom,cpr-fuse-combos number of tuples
in which case the tuples are matched to fuse combinations
1-to-1 or qcom,cpr-speed-bins number of tuples in which case
the tuples are matched to speed bins 1-to-1 or exactly 1
tuple which is used regardless of the fuse combination and
speed bin found on a given chip.
Each tuple must be of the length defined in the
corresponding element of the qcom,cpr-corners property or
the qcom,cpr-speed-bin-corners property. A single tuple may
only be specified if all of the corner counts in
qcom,cpr-corners are the same.
- qcom,cpr-corner-allow-closed-loop
Usage: optional
Value type: <prop-encoded-array>
Definition: A list of integer tuples which each define the CPR
closed-loop operation allowed state for each voltage corner
in order from lowest to highest. Each element in the tuple
should be either 0 (CPR closed-loop operation not allowed)
or 1 (CPR closed-loop operation allowed).
The list must contain qcom,cpr-fuse-combos number of tuples
in which case the tuples are matched to fuse combinations
1-to-1 or qcom,cpr-speed-bins number of tuples in which case
the tuples are matched to speed bins 1-to-1 or exactly 1
tuple which is used regardless of the fuse combination and
speed bin found on a given chip.
Each tuple must be of the length defined in the
corresponding element of the qcom,cpr-corners property or
the qcom,cpr-speed-bin-corners property. A single tuple may
only be specified if all of the corner counts in
qcom,cpr-corners are the same.
Note that the qcom,cpr-closed-loop-voltage-fuse-adjustment property is not
meaningful for MMSS LDO CPR3 regulator nodes since target quotients are not
defined in fuses.
=======
Example
=======
gfx_cpr: cpr4-ctrl@05061000 {
compatible = "qcom,cpr4-sdm660-mmss-ldo-regulator";
reg = <0x05061000 0x4000>, <0x00784000 0x1000>;
reg-names = "cpr_ctrl", "fuse_base";
interrupts = <GIC_SPI 285 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "cpr";
qcom,cpr-ctrl-name = "gfx";
qcom,cpr-sensor-time = <1000>;
qcom,cpr-loop-time = <5000000>;
qcom,cpr-idle-cycles = <15>;
qcom,cpr-step-quot-init-min = <8>;
qcom,cpr-step-quot-init-max = <12>;
qcom,cpr-count-mode = <0>; /* All at once */
vdd-supply = <&gfx_stub_vreg>;
mem-acc-supply = <&gfx_mem_acc_vreg>;
system-supply = <&pm660l_s3_level>; /* vdd_cx */
qcom,voltage-step = <5000>;
vdd-thread0-ldo-supply = <&gfx_ldo_vreg>;
qcom,cpr-enable;
thread@0 {
qcom,cpr-thread-id = <0>;
qcom,cpr-consecutive-up = <0>;
qcom,cpr-consecutive-down = <2>;
qcom,cpr-up-threshold = <0>;
qcom,cpr-down-threshold = <2>;
gfx_vreg_corner: regulator {
regulator-name = "gfx_corner";
regulator-min-microvolt = <1>;
regulator-max-microvolt = <7>;
qcom,cpr-fuse-corners = <6>;
qcom,cpr-fuse-combos = <8>;
qcom,cpr-corners = <7>;
qcom,cpr-corner-fmax-map = <1 2 3 4 5 6>;
qcom,cpr-voltage-ceiling =
<584000 644000 724000 788000
868000 924000 1068000>;
qcom,cpr-voltage-floor =
<504000 504000 596000 652000
712000 744000 1068000>;
qcom,mem-acc-voltage = <1 1 1 2 2 2 2>;
qcom,system-voltage =
<RPM_SMD_REGULATOR_LEVEL_MIN_SVS>,
<RPM_SMD_REGULATOR_LEVEL_LOW_SVS>,
<RPM_SMD_REGULATOR_LEVEL_SVS>,
<RPM_SMD_REGULATOR_LEVEL_SVS_PLUS>,
<RPM_SMD_REGULATOR_LEVEL_NOM>,
<RPM_SMD_REGULATOR_LEVEL_NOM_PLUS>,
<RPM_SMD_REGULATOR_LEVEL_TURBO>;
qcom,corner-frequencies =
<160000000 266000000 370000000
465000000 588000000 647000000
800000000>;
qcom,cpr-target-quotients =
<0 0 0 0 0 0 185 179
291 299 304 319 0 0 0 0>,
<0 0 0 0 0 0 287 273
425 426 443 453 0 0 0 0>,
<0 0 0 0 0 0 414 392
584 576 608 612 0 0 0 0>,
<0 0 0 0 0 0 459 431
684 644 692 679 0 0 0 0>,
<0 0 0 0 0 0 577 543
798 768 823 810 0 0 0 0>,
<0 0 0 0 0 0 669 629
886 864 924 911 0 0 0 0>,
<0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0>;
qcom,cpr-ro-scaling-factor =
< 0 0 0 0 0 0 2035 1917
1959 2131 2246 2253 0 0 0 0>,
< 0 0 0 0 0 0 2035 1917
1959 2131 2246 2253 0 0 0 0>,
< 0 0 0 0 0 0 2035 1917
1959 2131 2246 2253 0 0 0 0>,
< 0 0 0 0 0 0 2035 1917
1959 2131 2246 2253 0 0 0 0>,
< 0 0 0 0 0 0 2035 1917
1959 2131 2246 2253 0 0 0 0>,
< 0 0 0 0 0 0 2035 1917
1959 2131 2246 2253 0 0 0 0>,
< 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0>;
qcom,cpr-scaled-open-loop-voltage-as-ceiling;
qcom,cpr-corner-ldo-mode-allowed =
<1 1 1 1 1 1 0>;
qcom,cpr-corner-use-closed-loop =
<1 1 1 1 1 1 0>;
};
};
};

View File

@ -0,0 +1,459 @@
Qualcomm Technologies, Inc. CPRh Regulator - KBSS Specific Bindings
KBSS CPRh controllers each support one CPR thread that monitors the voltage
of a single Kryo-B CPU subystem (KBSS) cluster that is powered by a single
regulator supply. The DCVSh block interacts with the CPRh controller for full
hardware DCVS support.
Both CPR open-loop voltages and CPR target quotients are stored in hardware
fuses for KBSS CPRh controllers.
This document describes the KBSS specific CPRh bindings.
=======================
Required Node Structure
=======================
CPRh regulators must be described in three levels of devices nodes. The first
level describes the CPRh controller. The second level describes one hardware
thread managed by the controller. The third level describes one regulator
handled by the CPR thread.
All platform independent cpr3-regulator binding guidelines defined in
cpr3-regulator.txt also apply to cprh-kbss-regulator devices.
====================================
First Level Nodes - CPR3 Controllers
====================================
KBSS specific properties:
- compatible
Usage: required
Value type: <string>
Definition: should be one of the following:
"qcom,cprh-msm8998-v1-kbss-regulator",
"qcom,cprh-msm8998-v2-kbss-regulator",
"qcom,cprh-msm8998-kbss-regulator",
"qcom,cprh-sdm660-kbss-regulator".
If the SoC revision is not specified, then it is assumed to
be the most recent revision of MSM8998, i.e. v2.
- qcom,cpr-controller-id
Usage: required
Value type: <u32>
Definition: Identifies the controller number for subsystems that are managed
by multiple CPR controllers. For KBSS, the supported values are 0
and 1, corresponding to each cluster.
- qcom,apm-threshold-voltage
Usage: optional
Value type: <u32>
Definition: Specifies the APM threshold voltage in microvolts. The
floor to ceiling range for every corner is adjusted to ensure
it does not intersect this voltage. The value of this property
must match with the APM threshold voltage defined in the OSM
device to ensure that if the VDD_APCC supply voltage is above
this level, then the APM is switched to use VDD_APCC and if
VDD_APCC is below this level, then the APM is switched to use
VDD_MX.
- qcom,apm-crossover-voltage
Usage: required if qcom,apm-threshold-voltage is specified
Value type: <u32>
Definition: Specifies the APM crossover voltage in microvolts which
corresponds to the voltage the VDD supply must be set at
during an APM switch transition.
- qcom,apm-hysteresis-voltage
Usage: optional
Value type: <u32>
Definition: Specifies the voltage in microvolts used to adjust floor
voltages with respect to the APM threshold voltage. This
voltage is used to reduce the number of corners whose floor
must be raised to ensure stable operation with manual APM
switching. If this property is not specified, then a value
of 0 is assumed.
- qcom,mem-acc-threshold-voltage
Usage: optional
Value type: <u32>
Definition: Specifies the highest memory accelerator (MEM ACC) threshold
voltage in microvolts. The floor to ceiling voltage range
for every corner is adjusted to ensure that it does not
intersect this voltage. The value of this property must
match with the MEM ACC threshold voltage defined in the OSM
device to ensure that MEM ACC settings are switched
appropriately.
- qcom,mem-acc-crossover-voltage
Usage: required if qcom,mem-acc-threshold-voltage is specified
Value type: <u32>
Definition: Specifies the MEM ACC crossover voltage in microvolts which
corresponds to the voltage the VDD supply must be set to
when switching the MEM ACC configuration.
- qcom,voltage-base
Usage: required
Value type: <u32>
Definition: Specifies the voltage in microvolts used by the CRR controller
to resolve open-loop and floor voltages. In particular, this
voltage is added to the programmed open-loop and floor voltages
and it corresponds to the minimum supported setpoint of the
vdd-supply.
- qcom,cpr-saw-use-unit-mV
Usage: optional
Value type: <empty>
Definition: Boolean flag which indicates that the unit used in SAW PVC
interface is mV. Use this for vdd-supply regulators which
do not use PMIC voltage control register LSBs per actually
unique PMIC regulator output voltage.
- qcom,cpr-up-down-delay-time
Usage: required
Value type: <u32>
Definition: The time to delay in nanoseconds between consecutive CPR
measurements when the last measurement recommended
increasing or decreasing the vdd-supply voltage.
- qcom,cpr-down-error-step-limit
Usage: required
Value type: <u32>
Definition: CPRh 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.
- qcom,cpr-up-error-step-limit
Usage: required
Value type: <u32>
Definition: CPRh 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.
- qcom,cpr-step-quot-fixed
Usage: optional
Value type: <u32>
Definition: Fixed step quotient value used by controller for applying
the SDELTA margin adjustments on the programmed target
quotient values. The step quotient is the number of
additional ring oscillator ticks observed for each
qcom,voltage-step increase in vdd-supply output voltage.
Supported values: 0 - 63.
- qcom,cpr-voltage-settling-time
Usage: optional
Value type: <u32>
The time in nanoseconds that it takes for the vdd-supply
voltage to settle after being increased or decreased by
qcom,voltage-step microvolts. This is used as the wait
time after applying SDELTA voltage margin adjustments.
- qcom,cpr-corner-switch-delay-time
Usage: optional
Value type: <u32>
The time in nanoseconds that the CPR controller must delay
to allow voltage settling per 1 mV of voltage change after a
corner change.
- qcom,cpr-hw-closed-loop
Usage: optional
Value type: <empty>
Definition: Boolean flag which indicates that the KBSS CPRh controller
should operate in hardware closed-loop mode as opposed to
open-loop.
- qcom,cpr-temp-point-map
Usage: required if qcom,corner-band-allow-temp-adjustment is specified
for at least one of the CPR3 regulators.
Value type: <prop-encoded-array>
Definition: The temperature points in decidegrees Celsius which indicate
the range of temperature bands supported. If t1, t2, and t3
are the temperature points, then the temperature bands are:
(-inf, t1], (t1, t2], (t2, t3], and (t3, inf). A maximum of
three temperature points can be specified to define a total
of four different temperature bands.
- qcom,cpr-initial-temp-band
Usage: required if qcom,corner-band-allow-temp-adjustment is specified
for at least one of the CPR3 regulators.
Value type: <u32>
Definition: The initial temp band considering 0-based index at which
the baseline target quotients are derived and fused.
=================================================
Second Level Nodes - CPR Threads for a Controller
=================================================
KBSS specific properties:
N/A
===============================================
Third Level Nodes - CPR Regulators for a Thread
===============================================
KBSS specific properties:
- qcom,cpr-fuse-corners
Usage: required
Value type: <u32>
Definition: Specifies the number of fuse corners. This value must be 4
for KBSS. These fuse corners are: LowSVS, SVS, Nominal,
and Turbo.
- qcom,cpr-fuse-combos
Usage: required
Value type: <u32>
Definition: Specifies the number of fuse combinations being supported by
the device. This value is utilized by several other
properties. Supported values are 1 up to the maximum
possible for a given regulator type. For KBSS the maximum
supported value is 8. These combos correspond to CPR
revision fuse values 0 to 7 in order.
- qcom,allow-quotient-interpolation
Usage: optional
Value type: <empty>
Definition: Boolean flag which indicates that it is acceptable to use
interpolated CPR target quotient values. These values are
interpolated between the target quotient Fmax fuse values.
- qcom,cpr-corner-bands
Usage: required if qcom,corner-band-allow-core-count-adjustment
or qcom,corner-band-allow-temp-adjustment is specified
for this CPR3 regulator.
Value type: <prop-encoded-array>
Definition: A list of integers which defines how many corner bands
exist for each fuse combination. Supported values are 1 to 4.
The list must contain either qcom,cpr-fuse-combos number of
elements in which case the corner band counts are applied to
fuse combinations 1-to-1 or the list must contain exactly 1
element which is used regardless of the fuse combination
found on a given chip.
- qcom,cpr-speed-bin-corner-bands
Usage: required if qcom,cpr-speed-bins and
qcom,corner-band-allow-core-count-adjustment or
qcom,corner-band-allow-temp-adjustment are specified for
this CPR3 regulator.
Value type: <prop-encded-array>
Definition: A list of integers which defines how many corner bands
are to be used for each speed bin. The list must contain
qcom,cpr-speed-bins number of elements.
- qcom,corner-band-allow-core-count-adjustment
Usage: optional
Value type: <prop-encoded-array>
Definition: A list of integer tuples which each define the CPR core
count adjustment feature enable state for each corner band
in order from lowest to highest. Each element in the tuple
should be either 0 (per-core-count adjustment not allowed)
or 1 (per-core-count adjustment allowed). A maximum of four
corner bands may be used to partition the corner space into
contiguous corner ranges. For all corners within a corner band,
the same per-core-count adjustments are applied.
The list must contain qcom,cpr-fuse-combos number of tuples
in which case the tuples are matched to fuse combinations
1-to-1 or qcom,cpr-speed-bins number of tuples in which case
the tuples are matched to speed bins 1-to-1 or exactly 1
tuple which is used regardless of the fuse combination and
speed bin found on a given chip.
Each tuple must be of the length defined in the corresponding
element of the qcom,cpr-corner-bands property.
- qcom,max-core-count
Usage: required if qcom,corner-band-allow-core-count-adjustment is
specified for this CPR3 regulator.
Value type: <u32>
Definition: The maximum number of cores considered for core-count vmin
adjustments specified for this regulator's corner bands.
- qcom,corner-band-allow-temp-adjustment
Usage: optional
Value type: <prop-encoded-array>
Definition: A list of integer tuples which each define the temperature
adjustment feature enable state for each corner band
in order from lowest to highest. Each element in the tuple
should be either 0 (temperature adjustment not allowed)
or 1 (temperature adjustment allowed). A maximum of four
corner bands may be used to partition the corner space into
contiguous corner ranges. For all corners within a corner band,
the same temperature adjustments are applied.
The list must contain qcom,cpr-fuse-combos number of tuples
in which case the tuples are matched to fuse combinations
1-to-1 or qcom,cpr-speed-bins number of tuples in which case
the tuples are matched to speed bins 1-to-1 or exactly 1
tuple which is used regardless of the fuse combination and
speed bin found on a given chip.
Each tuple must be of the length defined in the corresponding
element of the qcom,cpr-corner-bands property.
- qcom,cpr-corner-band-map
Usage: required if qcom,corner-band-allow-core-count-adjustment
or qcom,corner-band-allow-temp-adjustment is specified
for this CPR3 regulator.
Value type: <prop-encoded-array>
Definition: A list of integer tuples which correspond to corner numbers
and define the corner bands to be used for temperature or
per-core-count adjustments. The corner numbers must be specified
in increasing order to result in partitioning the corner space
into contiguous corner ranges. The supported tuple size is 1
to 4 elements. For example, a tuple with corners defined as
c1, c2, c3, c4 results in the following corner band mapping:
[c1, c2) -> Corner Band 1
[c2, c3) -> Corner Band 2
[c3, c4) -> Corner Band 3
[c4, inf)-> Corner Band 4
Corners less than c1 will have no per-core-count or temperature
adjustments. Adjustments associated with each corner band X are
defined in the corresponding
qcom,cpr-corner-bandX-temp-core-voltage-adjustment property.
The list must contain qcom,cpr-fuse-combos number of tuples
in which case the tuples are matched to fuse combinations
1-to-1 or qcom,cpr-speed-bins number of tuples in which case
the tuples are matched to speed bins 1-to-1 or exactly 1
tuple which is used regardless of the fuse combination and
speed bin found on a given chip.
Each tuple must be of the length defined in the corresponding
element of the qcom,cpr-corner-bands property.
- qcom,cpr-corner-bandX-temp-core-voltage-adjustment
Usage: required if qcom,corner-band-allow-core-count-adjustment
is specified for this CPR3 regulator.
Value type: <prop-encoded-array>
Definition: A grouping of integer tuple lists for corner bandX. The possible
values for X are 1 to 4. Each tuple defines the temperature based
voltage adjustment in microvolts for each temperature band
from lowest to highest for a given number of online cores. Each
tuple must have a number of elements equal to either (the number
of elements in qcom,cpr-temp-point-map + 1), if
qcom,cpr-temp-point-map is specified, or 1.
Each tuple list must contain a number of tuples equal to
either qcom,max-core-count, if qcom,max-core-count is
specified, or 1. The tuples should be ordered from lowest
to highest core count.
The tuple list grouping must contain qcom,cpr-fuse-combos
number of tuple lists in which case the lists are matched to
fuse combinations 1-to-1 or qcom,cpr-speed-bins number of
tuple lists in which case the lists are matched to
speed bins 1-to-1 or exactly 1 list which is used regardless
of the fuse combination and speed bin found on a given chip.
=======
Example
=======
apc0_cpr: cprh-ctrl@179c8000 {
compatible = "qcom,cprh-msm8998-kbss-regulator";
reg = <0x179c8000 0x4000>, <0x00784000 0x1000>;
reg-names = "cpr_ctrl", "fuse_base";
clocks = <&clock_gcc clk_gcc_hmss_rbcpr_clk>;
clock-names = "core_clk";
qcom,cpr-ctrl-name = "apc0";
qcom,cpr-controller-id = <0>;
qcom,cpr-sensor-time = <1000>;
qcom,cpr-loop-time = <5000000>;
qcom,cpr-idle-cycles = <15>;
qcom,cpr-up-down-delay-time = <3000>;
qcom,cpr-step-quot-init-min = <11>;
qcom,cpr-step-quot-init-max = <13>;
qcom,cpr-count-mode = <2>; /* Staggered */
qcom,cpr-down-error-step-limit = <1>;
qcom,cpr-up-error-step-limit = <1>;
qcom,cpr-corner-switch-delay-time = <1600>;
qcom,cpr-voltage-settling-time = <1600>;
qcom,apm-threshold-voltage = <800000>;
qcom,apm-hysteresis-voltage = <4000>;
qcom,voltage-step = <4000>;
qcom,voltage-base = <352000>;
qcom,cpr-saw-use-unit-mV;
qcom,cpr-enable;
qcom,cpr-hw-closed-loop;
qcom,cpr-initial-temp-band = <3>;
qcom,cpr-temp-point-map = <0 25 85>;
thread@0 {
qcom,cpr-thread-id = <0>;
qcom,cpr-consecutive-up = <2>;
qcom,cpr-consecutive-down = <2>;
qcom,cpr-up-threshold = <0>;
qcom,cpr-down-threshold = <0>;
apc0_pwrcl_vreg: regulator-pwrcl {
regulator-name = "apc0_pwrcl_corner";
regulator-min-microvolt = <1>;
regulator-max-microvolt = <24>;
qcom,cpr-fuse-corners = <4>;
qcom,cpr-fuse-combos = <1>;
qcom,cpr-corners = <23>;
qcom,cpr-corner-fmax-map = <7 10 17 23>;
qcom,cpr-voltage-ceiling =
<632000 632000 632000 632000 632000
632000 632000 700000 700000 700000
828000 828000 828000 828000 828000
828000 828000 1024000 1024000 1024000
1024000 1024000 1024000>;
qcom,cpr-voltage-floor =
<572000 572000 572000 572000 572000
572000 572000 568000 568000 568000
684000 684000 684000 684000 684000
684000 684000 856000 856000 856000
856000 856000 856000>;
qcom,corner-frequencies =
<300000000 345600000 422400000
499200000 576000000 633600000
710400000 806400000 883200000
960000000 1036800000 1113600000
1190400000 1248000000 1324800000
1401600000 1478400000 1497600000
1574400000 1651200000 1728000000
1804800000 1881600000>;
};
qcom,cpr-corner-bands = <4>;
qcom,corner-band-allow-core-count-adjustment = <1 1 1 1>;
qcom,corner-band-allow-temp-adjustment = <1 0 0 0>;
qcom,cpr-corner-band-map = <7 14 18 20>;
qcom,max-core-count = <4>;
qcom,cpr-corner-band1-temp-core-voltage-adjustment =
<(-24000) (-20000) (-20000) (-16000)>,
<(-16000) (-16000) (-12000) (-8000)>,
<(-8000) (-8000) (-4000) (-4000)>,
<0 0 0 0>;
qcom,cpr-corner-band2-temp-core-voltage-adjustment =
<(-36000) 0 0 0>,
<(-32000) 0 0 0>,
<(-24000) 0 0 0>,
< 0 0 0 0>;
qcom,cpr-corner-band3-temp-core-voltage-adjustment =
<(-40000) 0 0 0>,
<(-36000) 0 0 0>,
<(-32000) 0 0 0>,
< 0 0 0 0>;
qcom,cpr-corner-band4-temp-core-voltage-adjustment =
<(-44000) 0 0 0>,
<(-32000) 0 0 0>,
<(-24000) 0 0 0>,
< 0 0 0 0>;
};
};
}

View File

@ -1025,6 +1025,41 @@ config REGULATOR_CPR
to voltage value before writing to a voltage regulator API, such as
that provided by spm-regulator driver.
config REGULATOR_CPR3
bool "CPR3 regulator core support"
help
This driver supports Core Power Reduction (CPR) version 3 controllers
which are used by some Qualcomm Technologies, Inc. (QTI) SoCs to
manage important voltage regulators. CPR3 controllers are capable of
monitoring several ring oscillator sensing loops simultaneously. The
CPR3 controller informs software when the silicon conditions require
the supply voltage to be increased or decreased. On certain supply
rails, the CPR3 controller is able to propagate the voltage increase
or decrease requests all the way to the PMIC without software
involvement.
config REGULATOR_CPR4_MMSS_LDO
bool "RBCPR3 regulator for MMSS LDO"
depends on OF
select REGULATOR_CPR3
help
This driver supports Qualcomm Technologies, Inc. MMSS graphics
processor specific features. The MMSS CPR3 controller only uses one
thread to monitor the MMSS LDO voltage requirements. This driver reads
initial voltage values out of hardware fuses and CPR target quotient
values out of device tree.
config REGULATOR_CPRH_KBSS
bool "CPRH regulator for KBSS"
depends on OF
select REGULATOR_CPR3
help
This driver supports Qualcomm Technologies, Inc. KBSS application
processor specific features including CPR hardening (CPRh) and two
CPRh controllers which monitor the two KBSS clusters each powered by
independent voltage supplies. This driver reads both initial voltage
and CPR target quotient values out of hardware fuses.
config REGULATOR_MEM_ACC
tristate "QTI Memory accelerator regulator driver"
help

View File

@ -129,6 +129,10 @@ obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o
obj-$(CONFIG_REGULATOR_CPR) += cpr-regulator.o
obj-$(CONFIG_REGULATOR_CPR3) += cpr3-regulator.o cpr3-util.o
obj-$(CONFIG_REGULATOR_CPR4_MMSS_LDO) += cpr4-mmss-ldo-regulator.o
obj-$(CONFIG_REGULATOR_CPR4_HMSS_LDO) += cpr4-hmss-ldo-regulator.o
obj-$(CONFIG_REGULATOR_CPRH_KBSS) += cprh-kbss-regulator.o
obj-$(CONFIG_REGULATOR_MEM_ACC) += mem-acc-regulator.o
obj-$(CONFIG_REGULATOR_MSM_GFX_LDO) += msm_gfx_ldo.o
obj-$(CONFIG_REGULATOR_REFGEN) += refgen.o

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,769 @@
/*
* Copyright (c) 2016-2019, 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.
*/
#define pr_fmt(fmt) "%s: " fmt, __func__
#include <linux/bitops.h>
#include <linux/debugfs.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_opp.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/uaccess.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/msm-ldo-regulator.h>
#include "cpr3-regulator.h"
#define SDM660_MMSS_FUSE_CORNERS 6
/**
* struct cpr4_sdm660_mmss_fuses - MMSS specific fuse data for SDM660
* @init_voltage: Initial (i.e. open-loop) voltage fuse parameter value
* for each fuse corner (raw, not converted to a voltage)
* @offset_voltage: The closed-loop voltage margin adjustment fuse parameter
* value for each fuse corner (raw, not converted to a
* voltage)
* @cpr_fusing_rev: CPR fusing revision fuse parameter value
* @ldo_enable: The ldo enable fuse parameter for each fuse corner
* indicates that VDD_GFX can be configured to LDO mode in
* the corresponding fuse corner.
* @ldo_cpr_cl_enable: A fuse parameter indicates that GFX CPR can be
* configured to operate in closed-loop mode when VDD_GFX
* is configured for LDO sub-regulated mode.
*
* This struct holds the values for all of the fuses read from memory.
*/
struct cpr4_sdm660_mmss_fuses {
u64 init_voltage[SDM660_MMSS_FUSE_CORNERS];
u64 offset_voltage[SDM660_MMSS_FUSE_CORNERS];
u64 cpr_fusing_rev;
u64 ldo_enable[SDM660_MMSS_FUSE_CORNERS];
u64 ldo_cpr_cl_enable;
};
/* Fuse combos 0 - 7 map to CPR fusing revision 0 - 7 */
#define CPR4_SDM660_MMSS_FUSE_COMBO_COUNT 8
/*
* SDM660 MMSS fuse parameter locations:
*
* Structs are organized with the following dimensions:
* Outer: 0 to 3 for fuse corners from lowest to highest corner
* Inner: large enough to hold the longest set of parameter segments which
* fully defines a fuse parameter, +1 (for NULL termination).
* Each segment corresponds to a contiguous group of bits from a
* single fuse row. These segments are concatentated together in
* order to form the full fuse parameter value. The segments for
* a given parameter may correspond to different fuse rows.
*/
static const struct cpr3_fuse_param
sdm660_mmss_init_voltage_param[SDM660_MMSS_FUSE_CORNERS][2] = {
{{65, 39, 43}, {} },
{{65, 39, 43}, {} },
{{65, 34, 38}, {} },
{{65, 34, 38}, {} },
{{65, 29, 33}, {} },
{{65, 24, 28}, {} },
};
static const struct cpr3_fuse_param sdm660_cpr_fusing_rev_param[] = {
{71, 34, 36},
{},
};
static const struct cpr3_fuse_param
sdm660_mmss_offset_voltage_param[SDM660_MMSS_FUSE_CORNERS][2] = {
{{} },
{{} },
{{} },
{{65, 52, 55}, {} },
{{65, 48, 51}, {} },
{{65, 44, 47}, {} },
};
static const struct cpr3_fuse_param
sdm660_mmss_ldo_enable_param[SDM660_MMSS_FUSE_CORNERS][2] = {
{{73, 62, 62}, {} },
{{73, 61, 61}, {} },
{{73, 60, 60}, {} },
{{73, 59, 59}, {} },
{{73, 58, 58}, {} },
{{73, 57, 57}, {} },
};
static const struct cpr3_fuse_param sdm660_ldo_cpr_cl_enable_param[] = {
{71, 38, 38},
{},
};
/* Additional SDM660 specific data: */
/* Open loop voltage fuse reference voltages in microvolts */
static const int sdm660_mmss_fuse_ref_volt[SDM660_MMSS_FUSE_CORNERS] = {
585000,
645000,
725000,
790000,
870000,
925000,
};
#define SDM660_MMSS_FUSE_STEP_VOLT 10000
#define SDM660_MMSS_OFFSET_FUSE_STEP_VOLT 10000
#define SDM660_MMSS_VOLTAGE_FUSE_SIZE 5
#define SDM660_MMSS_CPR_SENSOR_COUNT 11
#define SDM660_MMSS_CPR_CLOCK_RATE 19200000
/**
* cpr4_sdm660_mmss_read_fuse_data() - load MMSS specific fuse parameter
* values
* @vreg: Pointer to the CPR3 regulator
*
* This function allocates a cpr4_sdm660_mmss_fuses struct, fills it with
* values read out of hardware fuses, and finally copies common fuse values
* into the regulator struct.
*
* Return: 0 on success, errno on failure
*/
static int cpr4_sdm660_mmss_read_fuse_data(struct cpr3_regulator *vreg)
{
void __iomem *base = vreg->thread->ctrl->fuse_base;
struct cpr4_sdm660_mmss_fuses *fuse;
int i, rc;
fuse = devm_kzalloc(vreg->thread->ctrl->dev, sizeof(*fuse), GFP_KERNEL);
if (!fuse)
return -ENOMEM;
rc = cpr3_read_fuse_param(base, sdm660_cpr_fusing_rev_param,
&fuse->cpr_fusing_rev);
if (rc) {
cpr3_err(vreg, "Unable to read CPR fusing revision fuse, rc=%d\n",
rc);
return rc;
}
cpr3_info(vreg, "CPR fusing revision = %llu\n", fuse->cpr_fusing_rev);
rc = cpr3_read_fuse_param(base, sdm660_ldo_cpr_cl_enable_param,
&fuse->ldo_cpr_cl_enable);
if (rc) {
cpr3_err(vreg, "Unable to read ldo cpr closed-loop enable fuse, rc=%d\n",
rc);
return rc;
}
for (i = 0; i < SDM660_MMSS_FUSE_CORNERS; i++) {
rc = cpr3_read_fuse_param(base,
sdm660_mmss_init_voltage_param[i],
&fuse->init_voltage[i]);
if (rc) {
cpr3_err(vreg, "Unable to read fuse-corner %d initial voltage fuse, rc=%d\n",
i, rc);
return rc;
}
rc = cpr3_read_fuse_param(base,
sdm660_mmss_offset_voltage_param[i],
&fuse->offset_voltage[i]);
if (rc) {
cpr3_err(vreg, "Unable to read fuse-corner %d offset voltage fuse, rc=%d\n",
i, rc);
return rc;
}
rc = cpr3_read_fuse_param(base,
sdm660_mmss_ldo_enable_param[i],
&fuse->ldo_enable[i]);
if (rc) {
cpr3_err(vreg, "Unable to read fuse-corner %d ldo enable fuse, rc=%d\n",
i, rc);
return rc;
}
}
vreg->fuse_combo = fuse->cpr_fusing_rev;
if (vreg->fuse_combo >= CPR4_SDM660_MMSS_FUSE_COMBO_COUNT) {
cpr3_err(vreg, "invalid CPR fuse combo = %d found, not in range 0 - %d\n",
vreg->fuse_combo,
CPR4_SDM660_MMSS_FUSE_COMBO_COUNT - 1);
return -EINVAL;
}
vreg->cpr_rev_fuse = fuse->cpr_fusing_rev;
vreg->fuse_corner_count = SDM660_MMSS_FUSE_CORNERS;
vreg->platform_fuses = fuse;
return 0;
}
/**
* cpr3_sdm660_mmss_calculate_open_loop_voltages() - calculate the open-loop
* voltage for each corner of a CPR3 regulator
* @vreg: Pointer to the CPR3 regulator
*
* Return: 0 on success, errno on failure
*/
static int cpr4_sdm660_mmss_calculate_open_loop_voltages(
struct cpr3_regulator *vreg)
{
struct cpr4_sdm660_mmss_fuses *fuse = vreg->platform_fuses;
int i, rc = 0;
const int *ref_volt;
int *fuse_volt;
fuse_volt = kcalloc(vreg->fuse_corner_count, sizeof(*fuse_volt),
GFP_KERNEL);
if (!fuse_volt)
return -ENOMEM;
ref_volt = sdm660_mmss_fuse_ref_volt;
for (i = 0; i < vreg->fuse_corner_count; i++) {
fuse_volt[i] = cpr3_convert_open_loop_voltage_fuse(ref_volt[i],
SDM660_MMSS_FUSE_STEP_VOLT, fuse->init_voltage[i],
SDM660_MMSS_VOLTAGE_FUSE_SIZE);
cpr3_info(vreg, "fuse_corner[%d] open-loop=%7d uV\n",
i, fuse_volt[i]);
}
rc = cpr3_adjust_fused_open_loop_voltages(vreg, fuse_volt);
if (rc) {
cpr3_err(vreg, "fused open-loop voltage adjustment failed, rc=%d\n",
rc);
goto done;
}
for (i = 1; i < vreg->fuse_corner_count; i++) {
if (fuse_volt[i] < fuse_volt[i - 1]) {
cpr3_debug(vreg, "fuse corner %d voltage=%d uV < fuse corner %d voltage=%d uV; overriding: fuse corner %d voltage=%d\n",
i, fuse_volt[i], i - 1, fuse_volt[i - 1],
i, fuse_volt[i - 1]);
fuse_volt[i] = fuse_volt[i - 1];
}
}
for (i = 0; i < vreg->corner_count; i++)
vreg->corner[i].open_loop_volt
= fuse_volt[vreg->corner[i].cpr_fuse_corner];
cpr3_debug(vreg, "unadjusted per-corner open-loop voltages:\n");
for (i = 0; i < vreg->corner_count; i++)
cpr3_debug(vreg, "open-loop[%2d] = %d uV\n", i,
vreg->corner[i].open_loop_volt);
rc = cpr3_adjust_open_loop_voltages(vreg);
if (rc)
cpr3_err(vreg, "open-loop voltage adjustment failed, rc=%d\n",
rc);
done:
kfree(fuse_volt);
return rc;
}
/**
* cpr4_mmss_parse_ldo_mode_data() - Parse the LDO mode enable state for each
* corner of a CPR3 regulator
* @vreg: Pointer to the CPR3 regulator
*
* This function considers 2 sets of data: one set from device node and other
* set from fuses and applies set intersection to decide the final LDO mode
* enable state of each corner. If the device node configuration is not
* specified, then the function applies LDO mode disable for all corners.
*
* Return: 0 on success, errno on failure
*/
static int cpr4_mmss_parse_ldo_mode_data(struct cpr3_regulator *vreg)
{
struct cpr4_sdm660_mmss_fuses *fuse = vreg->platform_fuses;
int i, rc = 0;
u32 *ldo_allowed;
char *prop_str = "qcom,cpr-corner-allow-ldo-mode";
if (!of_find_property(vreg->of_node, prop_str, NULL)) {
cpr3_debug(vreg, "%s property is missing. LDO mode is disabled for all corners\n",
prop_str);
return 0;
}
ldo_allowed = kcalloc(vreg->corner_count, sizeof(*ldo_allowed),
GFP_KERNEL);
if (!ldo_allowed)
return -ENOMEM;
rc = cpr3_parse_corner_array_property(vreg, prop_str, 1, ldo_allowed);
if (rc) {
cpr3_err(vreg, "%s read failed, rc=%d\n", prop_str, rc);
goto done;
}
for (i = 0; i < vreg->corner_count; i++)
vreg->corner[i].ldo_mode_allowed
= (ldo_allowed[i] && fuse->ldo_enable[i]);
done:
kfree(ldo_allowed);
return rc;
}
/**
* cpr4_mmss_parse_corner_operating_mode() - Parse the CPR closed-loop operation
* enable state for each corner of a CPR3 regulator
* @vreg: Pointer to the CPR3 regulator
*
* This function ensures that closed-loop operation is enabled only for LDO
* mode allowed corners.
*
* Return: 0 on success, errno on failure
*/
static int cpr4_mmss_parse_corner_operating_mode(struct cpr3_regulator *vreg)
{
struct cpr4_sdm660_mmss_fuses *fuse = vreg->platform_fuses;
int i, rc = 0;
u32 *use_closed_loop;
char *prop_str = "qcom,cpr-corner-allow-closed-loop";
if (!of_find_property(vreg->of_node, prop_str, NULL)) {
cpr3_debug(vreg, "%s property is missing. Use open-loop for all corners\n",
prop_str);
for (i = 0; i < vreg->corner_count; i++)
vreg->corner[i].use_open_loop = true;
return 0;
}
use_closed_loop = kcalloc(vreg->corner_count, sizeof(*use_closed_loop),
GFP_KERNEL);
if (!use_closed_loop)
return -ENOMEM;
rc = cpr3_parse_corner_array_property(vreg, prop_str, 1,
use_closed_loop);
if (rc) {
cpr3_err(vreg, "%s read failed, rc=%d\n", prop_str, rc);
goto done;
}
for (i = 0; i < vreg->corner_count; i++)
vreg->corner[i].use_open_loop
= !(fuse->ldo_cpr_cl_enable && use_closed_loop[i]
&& vreg->corner[i].ldo_mode_allowed);
done:
kfree(use_closed_loop);
return rc;
}
/**
* cpr4_mmss_parse_corner_data() - parse MMSS corner data from device tree
* properties of the regulator's device node
* @vreg: Pointer to the CPR3 regulator
*
* Return: 0 on success, errno on failure
*/
static int cpr4_mmss_parse_corner_data(struct cpr3_regulator *vreg)
{
int i, rc;
u32 *temp;
rc = cpr3_parse_common_corner_data(vreg);
if (rc) {
cpr3_err(vreg, "error reading corner data, rc=%d\n", rc);
return rc;
}
temp = kcalloc(vreg->corner_count * CPR3_RO_COUNT, sizeof(*temp),
GFP_KERNEL);
if (!temp)
return -ENOMEM;
rc = cpr3_parse_corner_array_property(vreg, "qcom,cpr-target-quotients",
CPR3_RO_COUNT, temp);
if (rc) {
cpr3_err(vreg, "could not load target quotients, rc=%d\n", rc);
goto done;
}
for (i = 0; i < vreg->corner_count; i++)
memcpy(vreg->corner[i].target_quot, &temp[i * CPR3_RO_COUNT],
sizeof(*temp) * CPR3_RO_COUNT);
done:
kfree(temp);
return rc;
}
/**
* cpr4_sdm660_mmss_adjust_target_quotients() - adjust the target quotients for
* each corner according to device tree values and fuse values
* @vreg: Pointer to the CPR3 regulator
*
* Return: 0 on success, errno on failure
*/
static int cpr4_sdm660_mmss_adjust_target_quotients(struct cpr3_regulator *vreg)
{
struct cpr4_sdm660_mmss_fuses *fuse = vreg->platform_fuses;
const struct cpr3_fuse_param (*offset_param)[2];
int *volt_offset;
int i, fuse_len, rc = 0;
volt_offset = kcalloc(vreg->fuse_corner_count, sizeof(*volt_offset),
GFP_KERNEL);
if (!volt_offset)
return -ENOMEM;
offset_param = sdm660_mmss_offset_voltage_param;
for (i = 0; i < vreg->fuse_corner_count; i++) {
fuse_len = offset_param[i][0].bit_end + 1
- offset_param[i][0].bit_start;
volt_offset[i] = cpr3_convert_open_loop_voltage_fuse(
0, SDM660_MMSS_OFFSET_FUSE_STEP_VOLT,
fuse->offset_voltage[i], fuse_len);
if (volt_offset[i])
cpr3_info(vreg, "fuse_corner[%d] offset=%7d uV\n",
i, volt_offset[i]);
}
rc = cpr3_adjust_target_quotients(vreg, volt_offset);
if (rc)
cpr3_err(vreg, "adjust target quotients failed, rc=%d\n", rc);
kfree(volt_offset);
return rc;
}
/**
* cpr4_mmss_print_settings() - print out MMSS CPR configuration settings into
* the kernel log for debugging purposes
* @vreg: Pointer to the CPR3 regulator
*/
static void cpr4_mmss_print_settings(struct cpr3_regulator *vreg)
{
struct cpr3_corner *corner;
int i;
cpr3_debug(vreg, "Corner: Frequency (Hz), Fuse Corner, Floor (uV), Open-Loop (uV), Ceiling (uV)\n");
for (i = 0; i < vreg->corner_count; i++) {
corner = &vreg->corner[i];
cpr3_debug(vreg, "%3d: %10u, %2d, %7d, %7d, %7d\n",
i, corner->proc_freq, corner->cpr_fuse_corner,
corner->floor_volt, corner->open_loop_volt,
corner->ceiling_volt);
}
}
/**
* cpr4_mmss_init_thread() - perform all steps necessary to initialize the
* configuration data for a CPR3 thread
* @thread: Pointer to the CPR3 thread
*
* Return: 0 on success, errno on failure
*/
static int cpr4_mmss_init_thread(struct cpr3_thread *thread)
{
struct cpr3_controller *ctrl = thread->ctrl;
struct cpr3_regulator *vreg = &thread->vreg[0];
int rc;
rc = cpr3_parse_common_thread_data(thread);
if (rc) {
cpr3_err(vreg, "unable to read CPR thread data from device tree, rc=%d\n",
rc);
return rc;
}
if (!of_find_property(ctrl->dev->of_node, "vdd-thread0-ldo-supply",
NULL)) {
cpr3_err(vreg, "ldo supply regulator is not specified\n");
return -EINVAL;
}
vreg->ldo_regulator = devm_regulator_get(ctrl->dev, "vdd-thread0-ldo");
if (IS_ERR(vreg->ldo_regulator)) {
rc = PTR_ERR(vreg->ldo_regulator);
if (rc != -EPROBE_DEFER)
cpr3_err(vreg, "unable to request vdd-thread0-ldo regulator, rc=%d\n",
rc);
return rc;
}
vreg->ldo_mode_allowed = !of_property_read_bool(vreg->of_node,
"qcom,ldo-disable");
vreg->ldo_regulator_bypass = BHS_MODE;
vreg->ldo_type = CPR3_LDO300;
rc = cpr4_sdm660_mmss_read_fuse_data(vreg);
if (rc) {
cpr3_err(vreg, "unable to read CPR fuse data, rc=%d\n", rc);
return rc;
}
rc = cpr4_mmss_parse_corner_data(vreg);
if (rc) {
cpr3_err(vreg, "unable to read CPR corner data from device tree, rc=%d\n",
rc);
return rc;
}
rc = cpr4_sdm660_mmss_adjust_target_quotients(vreg);
if (rc) {
cpr3_err(vreg, "unable to adjust target quotients, rc=%d\n",
rc);
return rc;
}
rc = cpr4_sdm660_mmss_calculate_open_loop_voltages(vreg);
if (rc) {
cpr3_err(vreg, "unable to calculate open-loop voltages, rc=%d\n",
rc);
return rc;
}
rc = cpr3_limit_open_loop_voltages(vreg);
if (rc) {
cpr3_err(vreg, "unable to limit open-loop voltages, rc=%d\n",
rc);
return rc;
}
cpr3_open_loop_voltage_as_ceiling(vreg);
rc = cpr3_limit_floor_voltages(vreg);
if (rc) {
cpr3_err(vreg, "unable to limit floor voltages, rc=%d\n", rc);
return rc;
}
rc = cpr4_mmss_parse_ldo_mode_data(vreg);
if (rc) {
cpr3_err(vreg, "unable to parse ldo mode data, rc=%d\n", rc);
return rc;
}
rc = cpr4_mmss_parse_corner_operating_mode(vreg);
if (rc) {
cpr3_err(vreg, "unable to parse closed-loop operating mode data, rc=%d\n",
rc);
return rc;
}
cpr4_mmss_print_settings(vreg);
return 0;
}
/**
* cpr4_mmss_init_controller() - perform MMSS CPR4 controller specific
* initializations
* @ctrl: Pointer to the CPR3 controller
*
* Return: 0 on success, errno on failure
*/
static int cpr4_mmss_init_controller(struct cpr3_controller *ctrl)
{
int rc;
rc = cpr3_parse_common_ctrl_data(ctrl);
if (rc) {
if (rc != -EPROBE_DEFER)
cpr3_err(ctrl, "unable to parse common controller data, rc=%d\n",
rc);
return rc;
}
ctrl->sensor_count = SDM660_MMSS_CPR_SENSOR_COUNT;
/*
* MMSS only has one thread (0) so the zeroed array does not need
* further modification.
*/
ctrl->sensor_owner = devm_kcalloc(ctrl->dev, ctrl->sensor_count,
sizeof(*ctrl->sensor_owner), GFP_KERNEL);
if (!ctrl->sensor_owner)
return -ENOMEM;
ctrl->cpr_clock_rate = SDM660_MMSS_CPR_CLOCK_RATE;
ctrl->ctrl_type = CPR_CTRL_TYPE_CPR4;
ctrl->support_ldo300_vreg = true;
/*
* Use fixed step quotient if specified otherwise use dynamic
* calculated per RO step quotient
*/
of_property_read_u32(ctrl->dev->of_node,
"qcom,cpr-step-quot-fixed",
&ctrl->step_quot_fixed);
ctrl->use_dynamic_step_quot = !ctrl->step_quot_fixed;
/* iface_clk is optional for sdm660 */
ctrl->iface_clk = NULL;
ctrl->bus_clk = devm_clk_get(ctrl->dev, "bus_clk");
if (IS_ERR(ctrl->bus_clk)) {
rc = PTR_ERR(ctrl->bus_clk);
if (rc != -EPROBE_DEFER)
cpr3_err(ctrl, "unable request bus clock, rc=%d\n",
rc);
return rc;
}
return 0;
}
static int cpr4_mmss_regulator_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct cpr3_controller *ctrl;
int rc;
if (!dev->of_node) {
dev_err(dev, "Device tree node is missing\n");
return -EINVAL;
}
ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
if (!ctrl)
return -ENOMEM;
ctrl->dev = dev;
/* Set to false later if anything precludes CPR operation. */
ctrl->cpr_allowed_hw = true;
rc = of_property_read_string(dev->of_node, "qcom,cpr-ctrl-name",
&ctrl->name);
if (rc) {
cpr3_err(ctrl, "unable to read qcom,cpr-ctrl-name, rc=%d\n",
rc);
return rc;
}
rc = cpr3_map_fuse_base(ctrl, pdev);
if (rc) {
cpr3_err(ctrl, "could not map fuse base address\n");
return rc;
}
rc = cpr3_allocate_threads(ctrl, 0, 0);
if (rc) {
cpr3_err(ctrl, "failed to allocate CPR thread array, rc=%d\n",
rc);
return rc;
}
if (ctrl->thread_count != 1) {
cpr3_err(ctrl, "expected 1 thread but found %d\n",
ctrl->thread_count);
return -EINVAL;
} else if (ctrl->thread[0].vreg_count != 1) {
cpr3_err(ctrl, "expected 1 regulator but found %d\n",
ctrl->thread[0].vreg_count);
return -EINVAL;
}
rc = cpr4_mmss_init_controller(ctrl);
if (rc) {
if (rc != -EPROBE_DEFER)
cpr3_err(ctrl, "failed to initialize CPR controller parameters, rc=%d\n",
rc);
return rc;
}
rc = cpr4_mmss_init_thread(&ctrl->thread[0]);
if (rc) {
cpr3_err(&ctrl->thread[0].vreg[0], "thread initialization failed, rc=%d\n",
rc);
return rc;
}
rc = cpr3_mem_acc_init(&ctrl->thread[0].vreg[0]);
if (rc) {
cpr3_err(ctrl, "failed to initialize mem-acc configuration, rc=%d\n",
rc);
return rc;
}
platform_set_drvdata(pdev, ctrl);
return cpr3_regulator_register(pdev, ctrl);
}
static int cpr4_mmss_regulator_remove(struct platform_device *pdev)
{
struct cpr3_controller *ctrl = platform_get_drvdata(pdev);
return cpr3_regulator_unregister(ctrl);
}
static int cpr4_mmss_regulator_suspend(struct platform_device *pdev,
pm_message_t state)
{
struct cpr3_controller *ctrl = platform_get_drvdata(pdev);
return cpr3_regulator_suspend(ctrl);
}
static int cpr4_mmss_regulator_resume(struct platform_device *pdev)
{
struct cpr3_controller *ctrl = platform_get_drvdata(pdev);
return cpr3_regulator_resume(ctrl);
}
/* Data corresponds to the SoC revision */
static const struct of_device_id cpr4_mmss_regulator_match_table[] = {
{
.compatible = "qcom,cpr4-sdm660-mmss-ldo-regulator",
.data = (void *)NULL,
},
{ },
};
static struct platform_driver cpr4_mmss_regulator_driver = {
.driver = {
.name = "qcom,cpr4-mmss-ldo-regulator",
.of_match_table = cpr4_mmss_regulator_match_table,
.owner = THIS_MODULE,
},
.probe = cpr4_mmss_regulator_probe,
.remove = cpr4_mmss_regulator_remove,
.suspend = cpr4_mmss_regulator_suspend,
.resume = cpr4_mmss_regulator_resume,
};
static int cpr_regulator_init(void)
{
return platform_driver_register(&cpr4_mmss_regulator_driver);
}
static void cpr_regulator_exit(void)
{
platform_driver_unregister(&cpr4_mmss_regulator_driver);
}
MODULE_DESCRIPTION("CPR4 MMSS LDO regulator driver");
MODULE_LICENSE("GPL v2");
arch_initcall(cpr_regulator_init);
module_exit(cpr_regulator_exit);

File diff suppressed because it is too large Load Diff