aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2018-08-10 12:31:24 -0400
committerMark Brown <broonie@kernel.org>2018-08-10 12:31:24 -0400
commitd22d59362b7b2c749245f1269d447011c76ca41d (patch)
treeb3fc0673f62394dc5ed417eac6bad485a28baf25
parenta8afa92ec0d9312b23fd291aa8db95da266f2d5f (diff)
parent46fc033eba42f5a4fb583b2ab53f0a9918468452 (diff)
Merge branch 'regulator-4.19' into regulator-next
-rw-r--r--Documentation/ABI/testing/sysfs-driver-bd9571mwv-regulator27
-rw-r--r--Documentation/devicetree/bindings/arm/msm/qcom,llcc.txt26
-rw-r--r--Documentation/devicetree/bindings/regulator/cpcap-regulator.txt1
-rw-r--r--Documentation/devicetree/bindings/regulator/pfuze100.txt86
-rw-r--r--Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt160
-rw-r--r--Documentation/devicetree/bindings/regulator/rohm,bd71837-regulator.txt8
-rw-r--r--Documentation/devicetree/bindings/regulator/uniphier-regulator.txt57
-rw-r--r--Documentation/devicetree/bindings/soc/qcom/rpmh-rsc.txt137
-rw-r--r--drivers/base/core.c30
-rw-r--r--drivers/regulator/Kconfig25
-rw-r--r--drivers/regulator/Makefile4
-rw-r--r--drivers/regulator/bd71837-regulator.c44
-rw-r--r--drivers/regulator/bd9571mwv-regulator.c72
-rw-r--r--drivers/regulator/core.c44
-rw-r--r--drivers/regulator/cpcap-regulator.c103
-rw-r--r--drivers/regulator/max14577-regulator.c22
-rw-r--r--drivers/regulator/max77686-regulator.c32
-rw-r--r--drivers/regulator/max77693-regulator.c32
-rw-r--r--drivers/regulator/max77802-regulator.c34
-rw-r--r--drivers/regulator/max8997-regulator.c33
-rw-r--r--drivers/regulator/max8998.c28
-rw-r--r--drivers/regulator/pfuze100-regulator.c112
-rw-r--r--drivers/regulator/qcom-rpmh-regulator.c769
-rw-r--r--drivers/regulator/qcom_spmi-regulator.c38
-rw-r--r--drivers/regulator/s2mpa01.c14
-rw-r--r--drivers/regulator/s2mps11.c21
-rw-r--r--drivers/regulator/s5m8767.c16
-rw-r--r--drivers/regulator/tps65217-regulator.c2
-rw-r--r--drivers/regulator/uniphier-regulator.c213
-rw-r--r--drivers/soc/qcom/Kconfig27
-rw-r--r--drivers/soc/qcom/Makefile6
-rw-r--r--drivers/soc/qcom/llcc-sdm845.c94
-rw-r--r--drivers/soc/qcom/llcc-slice.c338
-rw-r--r--drivers/soc/qcom/rmtfs_mem.c3
-rw-r--r--drivers/soc/qcom/rpmh-internal.h114
-rw-r--r--drivers/soc/qcom/rpmh-rsc.c693
-rw-r--r--drivers/soc/qcom/rpmh.c513
-rw-r--r--drivers/soc/qcom/smem.c10
-rw-r--r--drivers/soc/qcom/trace-rpmh.h82
-rw-r--r--include/dt-bindings/regulator/maxim,max77802.h5
-rw-r--r--include/dt-bindings/regulator/qcom,rpmh-regulator.h36
-rw-r--r--include/dt-bindings/soc/qcom,rpmh-rsc.h14
-rw-r--r--include/linux/device.h1
-rw-r--r--include/linux/qcom_scm.h4
-rw-r--r--include/linux/regulator/driver.h4
-rw-r--r--include/linux/regulator/pfuze100.h11
-rw-r--r--include/linux/soc/qcom/llcc-qcom.h180
-rw-r--r--include/soc/qcom/rpmh.h51
-rw-r--r--include/soc/qcom/tcs.h56
49 files changed, 4163 insertions, 269 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-bd9571mwv-regulator b/Documentation/ABI/testing/sysfs-driver-bd9571mwv-regulator
new file mode 100644
index 000000000000..4d63a7904b94
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-bd9571mwv-regulator
@@ -0,0 +1,27 @@
1What: /sys/bus/i2c/devices/.../bd9571mwv-regulator.*.auto/backup_mode
2Date: Jul 2018
3KernelVersion: 4.19
4Contact: Geert Uytterhoeven <geert+renesas@glider.be>
5Description: Read/write the current state of DDR Backup Mode, which controls
6 if DDR power rails will be kept powered during system suspend.
7 ("on"/"1" = enabled, "off"/"0" = disabled).
8 Two types of power switches (or control signals) can be used:
9 A. With a momentary power switch (or pulse signal), DDR
10 Backup Mode is enabled by default when available, as the
11 PMIC will be configured only during system suspend.
12 B. With a toggle power switch (or level signal), the
13 following steps must be followed exactly:
14 1. Configure PMIC for backup mode, to change the role of
15 the accessory power switch from a power switch to a
16 wake-up switch,
17 2. Switch accessory power switch off, to prepare for
18 system suspend, which is a manual step not controlled
19 by software,
20 3. Suspend system,
21 4. Switch accessory power switch on, to resume the
22 system.
23 DDR Backup Mode must be explicitly enabled by the user,
24 to invoke step 1.
25 See also Documentation/devicetree/bindings/mfd/bd9571mwv.txt.
26Users: User space applications for embedded boards equipped with a
27 BD9571MWV PMIC.
diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,llcc.txt b/Documentation/devicetree/bindings/arm/msm/qcom,llcc.txt
new file mode 100644
index 000000000000..5e85749262ae
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/qcom,llcc.txt
@@ -0,0 +1,26 @@
1== Introduction==
2
3LLCC (Last Level Cache Controller) provides last level of cache memory in SOC,
4that can be shared by multiple clients. Clients here are different cores in the
5SOC, the idea is to minimize the local caches at the clients and migrate to
6common pool of memory. Cache memory is divided into partitions called slices
7which are assigned to clients. Clients can query the slice details, activate
8and deactivate them.
9
10Properties:
11- compatible:
12 Usage: required
13 Value type: <string>
14 Definition: must be "qcom,sdm845-llcc"
15
16- reg:
17 Usage: required
18 Value Type: <prop-encoded-array>
19 Definition: Start address and the the size of the register region.
20
21Example:
22
23 cache-controller@1100000 {
24 compatible = "qcom,sdm845-llcc";
25 reg = <0x1100000 0x250000>;
26 };
diff --git a/Documentation/devicetree/bindings/regulator/cpcap-regulator.txt b/Documentation/devicetree/bindings/regulator/cpcap-regulator.txt
index 675f4437ce92..36f5e2f5cc0f 100644
--- a/Documentation/devicetree/bindings/regulator/cpcap-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/cpcap-regulator.txt
@@ -5,6 +5,7 @@ Requires node properties:
5- "compatible" value one of: 5- "compatible" value one of:
6 "motorola,cpcap-regulator" 6 "motorola,cpcap-regulator"
7 "motorola,mapphone-cpcap-regulator" 7 "motorola,mapphone-cpcap-regulator"
8 "motorola,xoom-cpcap-regulator"
8 9
9Required regulator properties: 10Required regulator properties:
10- "regulator-name" 11- "regulator-name"
diff --git a/Documentation/devicetree/bindings/regulator/pfuze100.txt b/Documentation/devicetree/bindings/regulator/pfuze100.txt
index f0ada3b14d70..c7610718adff 100644
--- a/Documentation/devicetree/bindings/regulator/pfuze100.txt
+++ b/Documentation/devicetree/bindings/regulator/pfuze100.txt
@@ -1,9 +1,18 @@
1PFUZE100 family of regulators 1PFUZE100 family of regulators
2 2
3Required properties: 3Required properties:
4- compatible: "fsl,pfuze100", "fsl,pfuze200", "fsl,pfuze3000" 4- compatible: "fsl,pfuze100", "fsl,pfuze200", "fsl,pfuze3000", "fsl,pfuze3001"
5- reg: I2C slave address 5- reg: I2C slave address
6 6
7Optional properties:
8- fsl,pfuze-support-disable-sw: Boolean, if present disable all unused switch
9 regulators to save power consumption. Attention, ensure that all important
10 regulators (e.g. DDR ref, DDR supply) has set the "regulator-always-on"
11 property. If not present, the switched regualtors are always on and can't be
12 disabled. This binding is a workaround to keep backward compatibility with
13 old dtb's which rely on the fact that the switched regulators are always on
14 and don't mark them explicit as "regulator-always-on".
15
7Required child node: 16Required child node:
8- regulators: This is the list of child nodes that specify the regulator 17- regulators: This is the list of child nodes that specify the regulator
9 initialization data for defined regulators. Please refer to below doc 18 initialization data for defined regulators. Please refer to below doc
@@ -16,6 +25,8 @@ Required child node:
16 sw1ab,sw2,sw3a,sw3b,swbst,vsnvs,vrefddr,vgen1~vgen6,coin 25 sw1ab,sw2,sw3a,sw3b,swbst,vsnvs,vrefddr,vgen1~vgen6,coin
17 --PFUZE3000 26 --PFUZE3000
18 sw1a,sw1b,sw2,sw3,swbst,vsnvs,vrefddr,vldo1,vldo2,vccsd,v33,vldo3,vldo4 27 sw1a,sw1b,sw2,sw3,swbst,vsnvs,vrefddr,vldo1,vldo2,vccsd,v33,vldo3,vldo4
28 --PFUZE3001
29 sw1,sw2,sw3,vsnvs,vldo1,vldo2,vccsd,v33,vldo3,vldo4
19 30
20Each regulator is defined using the standard binding for regulators. 31Each regulator is defined using the standard binding for regulators.
21 32
@@ -303,3 +314,76 @@ Example 3: PFUZE3000
303 }; 314 };
304 }; 315 };
305 }; 316 };
317
318Example 4: PFUZE 3001
319
320 pfuze3001: pmic@8 {
321 compatible = "fsl,pfuze3001";
322 reg = <0x08>;
323
324 regulators {
325 sw1_reg: sw1 {
326 regulator-min-microvolt = <700000>;
327 regulator-max-microvolt = <3300000>;
328 regulator-boot-on;
329 regulator-always-on;
330 };
331
332 sw2_reg: sw2 {
333 regulator-min-microvolt = <1500000>;
334 regulator-max-microvolt = <3300000>;
335 regulator-boot-on;
336 regulator-always-on;
337 };
338
339 sw3_reg: sw3 {
340 regulator-min-microvolt = <900000>;
341 regulator-max-microvolt = <1650000>;
342 regulator-boot-on;
343 regulator-always-on;
344 };
345
346 snvs_reg: vsnvs {
347 regulator-min-microvolt = <1000000>;
348 regulator-max-microvolt = <3000000>;
349 regulator-boot-on;
350 regulator-always-on;
351 };
352
353 vgen1_reg: vldo1 {
354 regulator-min-microvolt = <1800000>;
355 regulator-max-microvolt = <3300000>;
356 regulator-always-on;
357 };
358
359 vgen2_reg: vldo2 {
360 regulator-min-microvolt = <800000>;
361 regulator-max-microvolt = <1550000>;
362 regulator-always-on;
363 };
364
365 vgen3_reg: vccsd {
366 regulator-min-microvolt = <2850000>;
367 regulator-max-microvolt = <3300000>;
368 regulator-always-on;
369 };
370
371 vgen4_reg: v33 {
372 regulator-min-microvolt = <2850000>;
373 regulator-max-microvolt = <3300000>;
374 regulator-always-on;
375 };
376
377 vgen5_reg: vldo3 {
378 regulator-min-microvolt = <1800000>;
379 regulator-max-microvolt = <3300000>;
380 regulator-always-on;
381 };
382
383 vgen6_reg: vldo4 {
384 regulator-min-microvolt = <1800000>;
385 regulator-max-microvolt = <3300000>;
386 regulator-always-on;
387 };
388 };
389 };
diff --git a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt
new file mode 100644
index 000000000000..7ef2dbe48e8a
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt
@@ -0,0 +1,160 @@
1Qualcomm Technologies, Inc. RPMh Regulators
2
3rpmh-regulator devices support PMIC regulator management via the Voltage
4Regulator Manager (VRM) and Oscillator Buffer (XOB) RPMh accelerators. The APPS
5processor communicates with these hardware blocks via a Resource State
6Coordinator (RSC) using command packets. The VRM allows changing three
7parameters for a given regulator: enable state, output voltage, and operating
8mode. The XOB allows changing only a single parameter for a given regulator:
9its enable state. Despite its name, the XOB is capable of controlling the
10enable state of any PMIC peripheral. It is used for clock buffers, low-voltage
11switches, and LDO/SMPS regulators which have a fixed voltage and mode.
12
13=======================
14Required Node Structure
15=======================
16
17RPMh regulators must be described in two levels of device nodes. The first
18level describes the PMIC containing the regulators and must reside within an
19RPMh device node. The second level describes each regulator within the PMIC
20which is to be used on the board. Each of these regulators maps to a single
21RPMh resource.
22
23The names used for regulator nodes must match those supported by a given PMIC.
24Supported regulator node names:
25 PM8998: smps1 - smps13, ldo1 - ldo28, lvs1 - lvs2
26 PMI8998: bob
27 PM8005: smps1 - smps4
28
29========================
30First Level Nodes - PMIC
31========================
32
33- compatible
34 Usage: required
35 Value type: <string>
36 Definition: Must be one of: "qcom,pm8998-rpmh-regulators",
37 "qcom,pmi8998-rpmh-regulators" or
38 "qcom,pm8005-rpmh-regulators".
39
40- qcom,pmic-id
41 Usage: required
42 Value type: <string>
43 Definition: RPMh resource name suffix used for the regulators found on
44 this PMIC. Typical values: "a", "b", "c", "d", "e", "f".
45
46- vdd-s1-supply
47- vdd-s2-supply
48- vdd-s3-supply
49- vdd-s4-supply
50 Usage: optional (PM8998 and PM8005 only)
51 Value type: <phandle>
52 Definition: phandle of the parent supply regulator of one or more of the
53 regulators for this PMIC.
54
55- vdd-s5-supply
56- vdd-s6-supply
57- vdd-s7-supply
58- vdd-s8-supply
59- vdd-s9-supply
60- vdd-s10-supply
61- vdd-s11-supply
62- vdd-s12-supply
63- vdd-s13-supply
64- vdd-l1-l27-supply
65- vdd-l2-l8-l17-supply
66- vdd-l3-l11-supply
67- vdd-l4-l5-supply
68- vdd-l6-supply
69- vdd-l7-l12-l14-l15-supply
70- vdd-l9-supply
71- vdd-l10-l23-l25-supply
72- vdd-l13-l19-l21-supply
73- vdd-l16-l28-supply
74- vdd-l18-l22-supply
75- vdd-l20-l24-supply
76- vdd-l26-supply
77- vin-lvs-1-2-supply
78 Usage: optional (PM8998 only)
79 Value type: <phandle>
80 Definition: phandle of the parent supply regulator of one or more of the
81 regulators for this PMIC.
82
83- vdd-bob-supply
84 Usage: optional (PMI8998 only)
85 Value type: <phandle>
86 Definition: BOB regulator parent supply phandle
87
88===============================
89Second Level Nodes - Regulators
90===============================
91
92- qcom,always-wait-for-ack
93 Usage: optional
94 Value type: <empty>
95 Definition: Boolean flag which indicates that the application processor
96 must wait for an ACK or a NACK from RPMh for every request
97 sent for this regulator including those which are for a
98 strictly lower power state.
99
100Other properties defined in Documentation/devicetree/bindings/regulator.txt
101may also be used. regulator-initial-mode and regulator-allowed-modes may be
102specified for VRM regulators using mode values from
103include/dt-bindings/regulator/qcom,rpmh-regulator.h. regulator-allow-bypass
104may be specified for BOB type regulators managed via VRM.
105regulator-allow-set-load may be specified for LDO type regulators managed via
106VRM.
107
108========
109Examples
110========
111
112#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
113
114&apps_rsc {
115 pm8998-rpmh-regulators {
116 compatible = "qcom,pm8998-rpmh-regulators";
117 qcom,pmic-id = "a";
118
119 vdd-l7-l12-l14-l15-supply = <&pm8998_s5>;
120
121 smps2 {
122 regulator-min-microvolt = <1100000>;
123 regulator-max-microvolt = <1100000>;
124 };
125
126 pm8998_s5: smps5 {
127 regulator-min-microvolt = <1904000>;
128 regulator-max-microvolt = <2040000>;
129 };
130
131 ldo7 {
132 regulator-min-microvolt = <1800000>;
133 regulator-max-microvolt = <1800000>;
134 regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
135 regulator-allowed-modes =
136 <RPMH_REGULATOR_MODE_LPM
137 RPMH_REGULATOR_MODE_HPM>;
138 regulator-allow-set-load;
139 };
140
141 lvs1 {
142 regulator-min-microvolt = <1800000>;
143 regulator-max-microvolt = <1800000>;
144 };
145 };
146
147 pmi8998-rpmh-regulators {
148 compatible = "qcom,pmi8998-rpmh-regulators";
149 qcom,pmic-id = "b";
150
151 bob {
152 regulator-min-microvolt = <3312000>;
153 regulator-max-microvolt = <3600000>;
154 regulator-allowed-modes =
155 <RPMH_REGULATOR_MODE_AUTO
156 RPMH_REGULATOR_MODE_HPM>;
157 regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
158 };
159 };
160};
diff --git a/Documentation/devicetree/bindings/regulator/rohm,bd71837-regulator.txt b/Documentation/devicetree/bindings/regulator/rohm,bd71837-regulator.txt
index 4edf3137d9f7..76ead07072b1 100644
--- a/Documentation/devicetree/bindings/regulator/rohm,bd71837-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/rohm,bd71837-regulator.txt
@@ -1,13 +1,5 @@
1ROHM BD71837 Power Management Integrated Circuit (PMIC) regulator bindings 1ROHM BD71837 Power Management Integrated Circuit (PMIC) regulator bindings
2 2
3BD71837MWV is a programmable Power Management
4IC (PMIC) for powering single-core, dual-core, and
5quad-core SoC’s such as NXP-i.MX 8M. It is optimized
6for low BOM cost and compact solution footprint. It
7integrates 8 Buck regulators and 7 LDO’s to provide all
8the power rails required by the SoC and the commonly
9used peripherals.
10
11Required properties: 3Required properties:
12 - regulator-name: should be "buck1", ..., "buck8" and "ldo1", ..., "ldo7" 4 - regulator-name: should be "buck1", ..., "buck8" and "ldo1", ..., "ldo7"
13 5
diff --git a/Documentation/devicetree/bindings/regulator/uniphier-regulator.txt b/Documentation/devicetree/bindings/regulator/uniphier-regulator.txt
new file mode 100644
index 000000000000..c9919f4b92d2
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/uniphier-regulator.txt
@@ -0,0 +1,57 @@
1Socionext UniPhier Regulator Controller
2
3This describes the devicetree bindings for regulator controller implemented
4on Socionext UniPhier SoCs.
5
6USB3 Controller
7---------------
8
9This regulator controls VBUS and belongs to USB3 glue layer. Before using
10the regulator, it is necessary to control the clocks and resets to enable
11this layer. These clocks and resets should be described in each property.
12
13Required properties:
14- compatible: Should be
15 "socionext,uniphier-pro4-usb3-regulator" - for Pro4 SoC
16 "socionext,uniphier-pxs2-usb3-regulator" - for PXs2 SoC
17 "socionext,uniphier-ld20-usb3-regulator" - for LD20 SoC
18 "socionext,uniphier-pxs3-usb3-regulator" - for PXs3 SoC
19- reg: Specifies offset and length of the register set for the device.
20- clocks: A list of phandles to the clock gate for USB3 glue layer.
21 According to the clock-names, appropriate clocks are required.
22- clock-names: Should contain
23 "gio", "link" - for Pro4 SoC
24 "link" - for others
25- resets: A list of phandles to the reset control for USB3 glue layer.
26 According to the reset-names, appropriate resets are required.
27- reset-names: Should contain
28 "gio", "link" - for Pro4 SoC
29 "link" - for others
30
31See Documentation/devicetree/bindings/regulator/regulator.txt
32for more details about the regulator properties.
33
34Example:
35
36 usb-glue@65b00000 {
37 compatible = "socionext,uniphier-ld20-dwc3-glue",
38 "simple-mfd";
39 #address-cells = <1>;
40 #size-cells = <1>;
41 ranges = <0 0x65b00000 0x400>;
42
43 usb_vbus0: regulators@100 {
44 compatible = "socionext,uniphier-ld20-usb3-regulator";
45 reg = <0x100 0x10>;
46 clock-names = "link";
47 clocks = <&sys_clk 14>;
48 reset-names = "link";
49 resets = <&sys_rst 14>;
50 };
51
52 phy {
53 ...
54 phy-supply = <&usb_vbus0>;
55 };
56 ...
57 };
diff --git a/Documentation/devicetree/bindings/soc/qcom/rpmh-rsc.txt b/Documentation/devicetree/bindings/soc/qcom/rpmh-rsc.txt
new file mode 100644
index 000000000000..9b86d1eff219
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/qcom/rpmh-rsc.txt
@@ -0,0 +1,137 @@
1RPMH RSC:
2------------
3
4Resource Power Manager Hardened (RPMH) is the mechanism for communicating with
5the hardened resource accelerators on Qualcomm SoCs. Requests to the resources
6can be written to the Trigger Command Set (TCS) registers and using a (addr,
7val) pair and triggered. Messages in the TCS are then sent in sequence over an
8internal bus.
9
10The hardware block (Direct Resource Voter or DRV) is a part of the h/w entity
11(Resource State Coordinator a.k.a RSC) that can handle multiple sleep and
12active/wake resource requests. Multiple such DRVs can exist in a SoC and can
13be written to from Linux. The structure of each DRV follows the same template
14with a few variations that are captured by the properties here.
15
16A TCS may be triggered from Linux or triggered by the F/W after all the CPUs
17have powered off to facilitate idle power saving. TCS could be classified as -
18
19 ACTIVE /* Triggered by Linux */
20 SLEEP /* Triggered by F/W */
21 WAKE /* Triggered by F/W */
22 CONTROL /* Triggered by F/W */
23
24The order in which they are described in the DT, should match the hardware
25configuration.
26
27Requests can be made for the state of a resource, when the subsystem is active
28or idle. When all subsystems like Modem, GPU, CPU are idle, the resource state
29will be an aggregate of the sleep votes from each of those subsystems. Clients
30may request a sleep value for their shared resources in addition to the active
31mode requests.
32
33Properties:
34
35- compatible:
36 Usage: required
37 Value type: <string>
38 Definition: Should be "qcom,rpmh-rsc".
39
40- reg:
41 Usage: required
42 Value type: <prop-encoded-array>
43 Definition: The first register specifies the base address of the
44 DRV(s). The number of DRVs in the dependent on the RSC.
45 The tcs-offset specifies the start address of the
46 TCS in the DRVs.
47
48- reg-names:
49 Usage: required
50 Value type: <string>
51 Definition: Maps the register specified in the reg property. Must be
52 "drv-0", "drv-1", "drv-2" etc and "tcs-offset". The
53
54- interrupts:
55 Usage: required
56 Value type: <prop-encoded-interrupt>
57 Definition: The interrupt that trips when a message complete/response
58 is received for this DRV from the accelerators.
59
60- qcom,drv-id:
61 Usage: required
62 Value type: <u32>
63 Definition: The id of the DRV in the RSC block that will be used by
64 this controller.
65
66- qcom,tcs-config:
67 Usage: required
68 Value type: <prop-encoded-array>
69 Definition: The tuple defining the configuration of TCS.
70 Must have 2 cells which describe each TCS type.
71 <type number_of_tcs>.
72 The order of the TCS must match the hardware
73 configuration.
74 - Cell #1 (TCS Type): TCS types to be specified -
75 ACTIVE_TCS
76 SLEEP_TCS
77 WAKE_TCS
78 CONTROL_TCS
79 - Cell #2 (Number of TCS): <u32>
80
81- label:
82 Usage: optional
83 Value type: <string>
84 Definition: Name for the RSC. The name would be used in trace logs.
85
86Drivers that want to use the RSC to communicate with RPMH must specify their
87bindings as child nodes of the RSC controllers they wish to communicate with.
88
89Example 1:
90
91For a TCS whose RSC base address is is 0x179C0000 and is at a DRV id of 2, the
92register offsets for DRV2 start at 0D00, the register calculations are like
93this -
94DRV0: 0x179C0000
95DRV2: 0x179C0000 + 0x10000 = 0x179D0000
96DRV2: 0x179C0000 + 0x10000 * 2 = 0x179E0000
97TCS-OFFSET: 0xD00
98
99 apps_rsc: rsc@179c0000 {
100 label = "apps_rsc";
101 compatible = "qcom,rpmh-rsc";
102 reg = <0x179c0000 0x10000>,
103 <0x179d0000 0x10000>,
104 <0x179e0000 0x10000>;
105 reg-names = "drv-0", "drv-1", "drv-2";
106 interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
107 <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
108 <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
109 qcom,tcs-offset = <0xd00>;
110 qcom,drv-id = <2>;
111 qcom,tcs-config = <ACTIVE_TCS 2>,
112 <SLEEP_TCS 3>,
113 <WAKE_TCS 3>,
114 <CONTROL_TCS 1>;
115 };
116
117Example 2:
118
119For a TCS whose RSC base address is 0xAF20000 and is at DRV id of 0, the
120register offsets for DRV0 start at 01C00, the register calculations are like
121this -
122DRV0: 0xAF20000
123TCS-OFFSET: 0x1C00
124
125 disp_rsc: rsc@af20000 {
126 label = "disp_rsc";
127 compatible = "qcom,rpmh-rsc";
128 reg = <0xaf20000 0x10000>;
129 reg-names = "drv-0";
130 interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>;
131 qcom,tcs-offset = <0x1c00>;
132 qcom,drv-id = <0>;
133 qcom,tcs-config = <ACTIVE_TCS 0>,
134 <SLEEP_TCS 1>,
135 <WAKE_TCS 1>,
136 <CONTROL_TCS 0>;
137 };
diff --git a/drivers/base/core.c b/drivers/base/core.c
index df3e1a44707a..2ab316d85651 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -372,6 +372,36 @@ void device_link_del(struct device_link *link)
372} 372}
373EXPORT_SYMBOL_GPL(device_link_del); 373EXPORT_SYMBOL_GPL(device_link_del);
374 374
375/**
376 * device_link_remove - remove a link between two devices.
377 * @consumer: Consumer end of the link.
378 * @supplier: Supplier end of the link.
379 *
380 * The caller must ensure proper synchronization of this function with runtime
381 * PM.
382 */
383void device_link_remove(void *consumer, struct device *supplier)
384{
385 struct device_link *link;
386
387 if (WARN_ON(consumer == supplier))
388 return;
389
390 device_links_write_lock();
391 device_pm_lock();
392
393 list_for_each_entry(link, &supplier->links.consumers, s_node) {
394 if (link->consumer == consumer) {
395 kref_put(&link->kref, __device_link_del);
396 break;
397 }
398 }
399
400 device_pm_unlock();
401 device_links_write_unlock();
402}
403EXPORT_SYMBOL_GPL(device_link_remove);
404
375static void device_links_missing_supplier(struct device *dev) 405static void device_links_missing_supplier(struct device *dev)
376{ 406{
377 struct device_link *link; 407 struct device_link *link;
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 5dbccf5f3037..329cdd33ed62 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -180,9 +180,9 @@ config REGULATOR_BCM590XX
180 BCM590xx PMUs. This will enable support for the software 180 BCM590xx PMUs. This will enable support for the software
181 controllable LDO/Switching regulators. 181 controllable LDO/Switching regulators.
182 182
183config REGULATOR_BD71837 183config REGULATOR_BD718XX
184 tristate "ROHM BD71837 Power Regulator" 184 tristate "ROHM BD71837 Power Regulator"
185 depends on MFD_BD71837 185 depends on MFD_ROHM_BD718XX
186 help 186 help
187 This driver supports voltage regulators on ROHM BD71837 PMIC. 187 This driver supports voltage regulators on ROHM BD71837 PMIC.
188 This will enable support for the software controllable buck 188 This will enable support for the software controllable buck
@@ -633,12 +633,12 @@ config REGULATOR_PCF50633
633 on PCF50633 633 on PCF50633
634 634
635config REGULATOR_PFUZE100 635config REGULATOR_PFUZE100
636 tristate "Freescale PFUZE100/200/3000 regulator driver" 636 tristate "Freescale PFUZE100/200/3000/3001 regulator driver"
637 depends on I2C 637 depends on I2C
638 select REGMAP_I2C 638 select REGMAP_I2C
639 help 639 help
640 Say y here to support the regulators found on the Freescale 640 Say y here to support the regulators found on the Freescale
641 PFUZE100/200/3000 PMIC. 641 PFUZE100/200/3000/3001 PMIC.
642 642
643config REGULATOR_PV88060 643config REGULATOR_PV88060
644 tristate "Powerventure Semiconductor PV88060 regulator" 644 tristate "Powerventure Semiconductor PV88060 regulator"
@@ -682,6 +682,15 @@ config REGULATOR_QCOM_RPM
682 Qualcomm RPM as a module. The module will be named 682 Qualcomm RPM as a module. The module will be named
683 "qcom_rpm-regulator". 683 "qcom_rpm-regulator".
684 684
685config REGULATOR_QCOM_RPMH
686 tristate "Qualcomm Technologies, Inc. RPMh regulator driver"
687 depends on QCOM_RPMH || COMPILE_TEST
688 help
689 This driver supports control of PMIC regulators via the RPMh hardware
690 block found on Qualcomm Technologies Inc. SoCs. RPMh regulator
691 control allows for voting on regulator state between multiple
692 processors within the SoC.
693
685config REGULATOR_QCOM_SMD_RPM 694config REGULATOR_QCOM_SMD_RPM
686 tristate "Qualcomm SMD based RPM regulator driver" 695 tristate "Qualcomm SMD based RPM regulator driver"
687 depends on QCOM_SMD_RPM 696 depends on QCOM_SMD_RPM
@@ -950,6 +959,14 @@ config REGULATOR_TWL4030
950 This driver supports the voltage regulators provided by 959 This driver supports the voltage regulators provided by
951 this family of companion chips. 960 this family of companion chips.
952 961
962config REGULATOR_UNIPHIER
963 tristate "UniPhier regulator driver"
964 depends on ARCH_UNIPHIER || COMPILE_TEST
965 depends on OF && MFD_SYSCON
966 default ARCH_UNIPHIER
967 help
968 Support for regulators implemented on Socionext UniPhier SoCs.
969
953config REGULATOR_VCTRL 970config REGULATOR_VCTRL
954 tristate "Voltage controlled regulators" 971 tristate "Voltage controlled regulators"
955 depends on OF 972 depends on OF
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index bd818ceb7c72..801d9a34a203 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -27,7 +27,7 @@ obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o
27obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o 27obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o
28obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o 28obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o
29obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o 29obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o
30obj-$(CONFIG_REGULATOR_BD71837) += bd71837-regulator.o 30obj-$(CONFIG_REGULATOR_BD718XX) += bd71837-regulator.o
31obj-$(CONFIG_REGULATOR_BD9571MWV) += bd9571mwv-regulator.o 31obj-$(CONFIG_REGULATOR_BD9571MWV) += bd9571mwv-regulator.o
32obj-$(CONFIG_REGULATOR_DA903X) += da903x.o 32obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
33obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o 33obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o
@@ -78,6 +78,7 @@ obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o
78obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o 78obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o
79obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o 79obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o
80obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o 80obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o
81obj-$(CONFIG_REGULATOR_QCOM_RPMH) += qcom-rpmh-regulator.o
81obj-$(CONFIG_REGULATOR_QCOM_SMD_RPM) += qcom_smd-regulator.o 82obj-$(CONFIG_REGULATOR_QCOM_SMD_RPM) += qcom_smd-regulator.o
82obj-$(CONFIG_REGULATOR_QCOM_SPMI) += qcom_spmi-regulator.o 83obj-$(CONFIG_REGULATOR_QCOM_SPMI) += qcom_spmi-regulator.o
83obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o 84obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o
@@ -118,6 +119,7 @@ obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o
118obj-$(CONFIG_REGULATOR_TPS80031) += tps80031-regulator.o 119obj-$(CONFIG_REGULATOR_TPS80031) += tps80031-regulator.o
119obj-$(CONFIG_REGULATOR_TPS65132) += tps65132-regulator.o 120obj-$(CONFIG_REGULATOR_TPS65132) += tps65132-regulator.o
120obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o twl6030-regulator.o 121obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o twl6030-regulator.o
122obj-$(CONFIG_REGULATOR_UNIPHIER) += uniphier-regulator.o
121obj-$(CONFIG_REGULATOR_VCTRL) += vctrl-regulator.o 123obj-$(CONFIG_REGULATOR_VCTRL) += vctrl-regulator.o
122obj-$(CONFIG_REGULATOR_VEXPRESS) += vexpress-regulator.o 124obj-$(CONFIG_REGULATOR_VEXPRESS) += vexpress-regulator.o
123obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o 125obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
diff --git a/drivers/regulator/bd71837-regulator.c b/drivers/regulator/bd71837-regulator.c
index 6eae4d0432a2..0f8ac8dec3e1 100644
--- a/drivers/regulator/bd71837-regulator.c
+++ b/drivers/regulator/bd71837-regulator.c
@@ -2,19 +2,18 @@
2// Copyright (C) 2018 ROHM Semiconductors 2// Copyright (C) 2018 ROHM Semiconductors
3// bd71837-regulator.c ROHM BD71837MWV regulator driver 3// bd71837-regulator.c ROHM BD71837MWV regulator driver
4 4
5#include <linux/kernel.h> 5#include <linux/delay.h>
6#include <linux/module.h>
7#include <linux/init.h>
8#include <linux/err.h> 6#include <linux/err.h>
7#include <linux/gpio.h>
9#include <linux/interrupt.h> 8#include <linux/interrupt.h>
9#include <linux/kernel.h>
10#include <linux/mfd/rohm-bd718x7.h>
11#include <linux/module.h>
10#include <linux/platform_device.h> 12#include <linux/platform_device.h>
11#include <linux/regulator/driver.h> 13#include <linux/regulator/driver.h>
12#include <linux/regulator/machine.h> 14#include <linux/regulator/machine.h>
13#include <linux/delay.h>
14#include <linux/slab.h>
15#include <linux/gpio.h>
16#include <linux/mfd/bd71837.h>
17#include <linux/regulator/of_regulator.h> 15#include <linux/regulator/of_regulator.h>
16#include <linux/slab.h>
18 17
19struct bd71837_pmic { 18struct bd71837_pmic {
20 struct regulator_desc descs[BD71837_REGULATOR_CNT]; 19 struct regulator_desc descs[BD71837_REGULATOR_CNT];
@@ -39,7 +38,7 @@ static int bd71837_buck1234_set_ramp_delay(struct regulator_dev *rdev,
39 int id = rdev->desc->id; 38 int id = rdev->desc->id;
40 unsigned int ramp_value = BUCK_RAMPRATE_10P00MV; 39 unsigned int ramp_value = BUCK_RAMPRATE_10P00MV;
41 40
42 dev_dbg(&(pmic->pdev->dev), "Buck[%d] Set Ramp = %d\n", id + 1, 41 dev_dbg(&pmic->pdev->dev, "Buck[%d] Set Ramp = %d\n", id + 1,
43 ramp_delay); 42 ramp_delay);
44 switch (ramp_delay) { 43 switch (ramp_delay) {
45 case 1 ... 1250: 44 case 1 ... 1250:
@@ -73,14 +72,10 @@ static int bd71837_buck1234_set_ramp_delay(struct regulator_dev *rdev,
73static int bd71837_set_voltage_sel_restricted(struct regulator_dev *rdev, 72static int bd71837_set_voltage_sel_restricted(struct regulator_dev *rdev,
74 unsigned int sel) 73 unsigned int sel)
75{ 74{
76 int ret; 75 if (regulator_is_enabled_regmap(rdev))
77 76 return -EBUSY;
78 ret = regulator_is_enabled_regmap(rdev); 77
79 if (!ret) 78 return regulator_set_voltage_sel_regmap(rdev, sel);
80 ret = regulator_set_voltage_sel_regmap(rdev, sel);
81 else if (ret == 1)
82 ret = -EBUSY;
83 return ret;
84} 79}
85 80
86static struct regulator_ops bd71837_ldo_regulator_ops = { 81static struct regulator_ops bd71837_ldo_regulator_ops = {
@@ -195,7 +190,7 @@ static const struct regulator_linear_range bd71837_ldo1_voltage_ranges[] = {
195 * LDO2 190 * LDO2
196 * 0.8 or 0.9V 191 * 0.8 or 0.9V
197 */ 192 */
198const unsigned int ldo_2_volts[] = { 193static const unsigned int ldo_2_volts[] = {
199 900000, 800000 194 900000, 800000
200}; 195};
201 196
@@ -495,7 +490,6 @@ struct reg_init {
495static int bd71837_probe(struct platform_device *pdev) 490static int bd71837_probe(struct platform_device *pdev)
496{ 491{
497 struct bd71837_pmic *pmic; 492 struct bd71837_pmic *pmic;
498 struct bd71837_board *pdata;
499 struct regulator_config config = { 0 }; 493 struct regulator_config config = { 0 };
500 struct reg_init pmic_regulator_inits[] = { 494 struct reg_init pmic_regulator_inits[] = {
501 { 495 {
@@ -548,8 +542,7 @@ static int bd71837_probe(struct platform_device *pdev)
548 542
549 int i, err; 543 int i, err;
550 544
551 pmic = devm_kzalloc(&pdev->dev, sizeof(struct bd71837_pmic), 545 pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
552 GFP_KERNEL);
553 if (!pmic) 546 if (!pmic)
554 return -ENOMEM; 547 return -ENOMEM;
555 548
@@ -564,7 +557,6 @@ static int bd71837_probe(struct platform_device *pdev)
564 goto err; 557 goto err;
565 } 558 }
566 platform_set_drvdata(pdev, pmic); 559 platform_set_drvdata(pdev, pmic);
567 pdata = dev_get_platdata(pmic->mfd->dev);
568 560
569 /* Register LOCK release */ 561 /* Register LOCK release */
570 err = regmap_update_bits(pmic->mfd->regmap, BD71837_REG_REGLOCK, 562 err = regmap_update_bits(pmic->mfd->regmap, BD71837_REG_REGLOCK,
@@ -573,8 +565,8 @@ static int bd71837_probe(struct platform_device *pdev)
573 dev_err(&pmic->pdev->dev, "Failed to unlock PMIC (%d)\n", err); 565 dev_err(&pmic->pdev->dev, "Failed to unlock PMIC (%d)\n", err);
574 goto err; 566 goto err;
575 } else { 567 } else {
576 dev_dbg(&pmic->pdev->dev, "%s: Unlocked lock register 0x%x\n", 568 dev_dbg(&pmic->pdev->dev, "Unlocked lock register 0x%x\n",
577 __func__, BD71837_REG_REGLOCK); 569 BD71837_REG_REGLOCK);
578 } 570 }
579 571
580 for (i = 0; i < ARRAY_SIZE(pmic_regulator_inits); i++) { 572 for (i = 0; i < ARRAY_SIZE(pmic_regulator_inits); i++) {
@@ -584,9 +576,6 @@ static int bd71837_probe(struct platform_device *pdev)
584 576
585 desc = &pmic->descs[i]; 577 desc = &pmic->descs[i];
586 578
587 if (pdata)
588 config.init_data = pdata->init_data[i];
589
590 config.dev = pdev->dev.parent; 579 config.dev = pdev->dev.parent;
591 config.driver_data = pmic; 580 config.driver_data = pmic;
592 config.regmap = pmic->mfd->regmap; 581 config.regmap = pmic->mfd->regmap;
@@ -619,8 +608,6 @@ static int bd71837_probe(struct platform_device *pdev)
619 pmic->rdev[i] = rdev; 608 pmic->rdev[i] = rdev;
620 } 609 }
621 610
622 return 0;
623
624err: 611err:
625 return err; 612 return err;
626} 613}
@@ -628,7 +615,6 @@ err:
628static struct platform_driver bd71837_regulator = { 615static struct platform_driver bd71837_regulator = {
629 .driver = { 616 .driver = {
630 .name = "bd71837-pmic", 617 .name = "bd71837-pmic",
631 .owner = THIS_MODULE,
632 }, 618 },
633 .probe = bd71837_probe, 619 .probe = bd71837_probe,
634}; 620};
diff --git a/drivers/regulator/bd9571mwv-regulator.c b/drivers/regulator/bd9571mwv-regulator.c
index be574eb444eb..274c5ed7cd73 100644
--- a/drivers/regulator/bd9571mwv-regulator.c
+++ b/drivers/regulator/bd9571mwv-regulator.c
@@ -30,6 +30,7 @@ struct bd9571mwv_reg {
30 /* DDR Backup Power */ 30 /* DDR Backup Power */
31 u8 bkup_mode_cnt_keepon; /* from "rohm,ddr-backup-power" */ 31 u8 bkup_mode_cnt_keepon; /* from "rohm,ddr-backup-power" */
32 u8 bkup_mode_cnt_saved; 32 u8 bkup_mode_cnt_saved;
33 bool bkup_mode_enabled;
33 34
34 /* Power switch type */ 35 /* Power switch type */
35 bool rstbmode_level; 36 bool rstbmode_level;
@@ -171,13 +172,60 @@ static int bd9571mwv_bkup_mode_write(struct bd9571mwv *bd, unsigned int mode)
171 return 0; 172 return 0;
172} 173}
173 174
175static ssize_t backup_mode_show(struct device *dev,
176 struct device_attribute *attr, char *buf)
177{
178 struct bd9571mwv_reg *bdreg = dev_get_drvdata(dev);
179
180 return sprintf(buf, "%s\n", bdreg->bkup_mode_enabled ? "on" : "off");
181}
182
183static ssize_t backup_mode_store(struct device *dev,
184 struct device_attribute *attr,
185 const char *buf, size_t count)
186{
187 struct bd9571mwv_reg *bdreg = dev_get_drvdata(dev);
188 unsigned int mode;
189 int ret;
190
191 if (!count)
192 return 0;
193
194 ret = kstrtobool(buf, &bdreg->bkup_mode_enabled);
195 if (ret)
196 return ret;
197
198 if (!bdreg->rstbmode_level)
199 return count;
200
201 /*
202 * Configure DDR Backup Mode, to change the role of the accessory power
203 * switch from a power switch to a wake-up switch, or vice versa
204 */
205 ret = bd9571mwv_bkup_mode_read(bdreg->bd, &mode);
206 if (ret)
207 return ret;
208
209 mode &= ~BD9571MWV_BKUP_MODE_CNT_KEEPON_MASK;
210 if (bdreg->bkup_mode_enabled)
211 mode |= bdreg->bkup_mode_cnt_keepon;
212
213 ret = bd9571mwv_bkup_mode_write(bdreg->bd, mode);
214 if (ret)
215 return ret;
216
217 return count;
218}
219
220static DEVICE_ATTR_RW(backup_mode);
221
174static int bd9571mwv_suspend(struct device *dev) 222static int bd9571mwv_suspend(struct device *dev)
175{ 223{
176 struct bd9571mwv_reg *bdreg = dev_get_drvdata(dev); 224 struct bd9571mwv_reg *bdreg = dev_get_drvdata(dev);
177 unsigned int mode; 225 unsigned int mode;
178 int ret; 226 int ret;
179 227
180 if (!device_may_wakeup(dev)) 228 if (!bdreg->bkup_mode_enabled)
181 return 0; 229 return 0;
182 230
183 /* Save DDR Backup Mode */ 231 /* Save DDR Backup Mode */
@@ -204,7 +252,7 @@ static int bd9571mwv_resume(struct device *dev)
204{ 252{
205 struct bd9571mwv_reg *bdreg = dev_get_drvdata(dev); 253 struct bd9571mwv_reg *bdreg = dev_get_drvdata(dev);
206 254
207 if (!device_may_wakeup(dev)) 255 if (!bdreg->bkup_mode_enabled)
208 return 0; 256 return 0;
209 257
210 /* Restore DDR Backup Mode */ 258 /* Restore DDR Backup Mode */
@@ -215,9 +263,15 @@ static const struct dev_pm_ops bd9571mwv_pm = {
215 SET_SYSTEM_SLEEP_PM_OPS(bd9571mwv_suspend, bd9571mwv_resume) 263 SET_SYSTEM_SLEEP_PM_OPS(bd9571mwv_suspend, bd9571mwv_resume)
216}; 264};
217 265
266static int bd9571mwv_regulator_remove(struct platform_device *pdev)
267{
268 device_remove_file(&pdev->dev, &dev_attr_backup_mode);
269 return 0;
270}
218#define DEV_PM_OPS &bd9571mwv_pm 271#define DEV_PM_OPS &bd9571mwv_pm
219#else 272#else
220#define DEV_PM_OPS NULL 273#define DEV_PM_OPS NULL
274#define bd9571mwv_regulator_remove NULL
221#endif /* CONFIG_PM_SLEEP */ 275#endif /* CONFIG_PM_SLEEP */
222 276
223static int bd9571mwv_regulator_probe(struct platform_device *pdev) 277static int bd9571mwv_regulator_probe(struct platform_device *pdev)
@@ -270,14 +324,21 @@ static int bd9571mwv_regulator_probe(struct platform_device *pdev)
270 return -EINVAL; 324 return -EINVAL;
271 } 325 }
272 326
327#ifdef CONFIG_PM_SLEEP
273 if (bdreg->bkup_mode_cnt_keepon) { 328 if (bdreg->bkup_mode_cnt_keepon) {
274 device_set_wakeup_capable(&pdev->dev, true); 329 int ret;
330
275 /* 331 /*
276 * Wakeup is enabled by default in pulse mode, but needs 332 * Backup mode is enabled by default in pulse mode, but needs
277 * explicit user setup in level mode. 333 * explicit user setup in level mode.
278 */ 334 */
279 device_set_wakeup_enable(&pdev->dev, bdreg->rstbmode_pulse); 335 bdreg->bkup_mode_enabled = bdreg->rstbmode_pulse;
336
337 ret = device_create_file(&pdev->dev, &dev_attr_backup_mode);
338 if (ret)
339 return ret;
280 } 340 }
341#endif /* CONFIG_PM_SLEEP */
281 342
282 return 0; 343 return 0;
283} 344}
@@ -294,6 +355,7 @@ static struct platform_driver bd9571mwv_regulator_driver = {
294 .pm = DEV_PM_OPS, 355 .pm = DEV_PM_OPS,
295 }, 356 },
296 .probe = bd9571mwv_regulator_probe, 357 .probe = bd9571mwv_regulator_probe,
358 .remove = bd9571mwv_regulator_remove,
297 .id_table = bd9571mwv_regulator_id_table, 359 .id_table = bd9571mwv_regulator_id_table,
298}; 360};
299module_platform_driver(bd9571mwv_regulator_driver); 361module_platform_driver(bd9571mwv_regulator_driver);
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 6ed568b96c0e..bb1324f93143 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1740,6 +1740,8 @@ struct regulator *_regulator_get(struct device *dev, const char *id,
1740 rdev->use_count = 0; 1740 rdev->use_count = 0;
1741 } 1741 }
1742 1742
1743 device_link_add(dev, &rdev->dev, DL_FLAG_STATELESS);
1744
1743 return regulator; 1745 return regulator;
1744} 1746}
1745 1747
@@ -1829,9 +1831,21 @@ static void _regulator_put(struct regulator *regulator)
1829 1831
1830 debugfs_remove_recursive(regulator->debugfs); 1832 debugfs_remove_recursive(regulator->debugfs);
1831 1833
1832 /* remove any sysfs entries */ 1834 if (regulator->dev) {
1833 if (regulator->dev) 1835 int count = 0;
1836 struct regulator *r;
1837
1838 list_for_each_entry(r, &rdev->consumer_list, list)
1839 if (r->dev == regulator->dev)
1840 count++;
1841
1842 if (count == 1)
1843 device_link_remove(regulator->dev, &rdev->dev);
1844
1845 /* remove any sysfs entries */
1834 sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name); 1846 sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name);
1847 }
1848
1835 regulator_lock(rdev); 1849 regulator_lock(rdev);
1836 list_del(&regulator->list); 1850 list_del(&regulator->list);
1837 1851
@@ -4441,7 +4455,7 @@ void regulator_unregister(struct regulator_dev *rdev)
4441EXPORT_SYMBOL_GPL(regulator_unregister); 4455EXPORT_SYMBOL_GPL(regulator_unregister);
4442 4456
4443#ifdef CONFIG_SUSPEND 4457#ifdef CONFIG_SUSPEND
4444static int _regulator_suspend_late(struct device *dev, void *data) 4458static int _regulator_suspend(struct device *dev, void *data)
4445{ 4459{
4446 struct regulator_dev *rdev = dev_to_rdev(dev); 4460 struct regulator_dev *rdev = dev_to_rdev(dev);
4447 suspend_state_t *state = data; 4461 suspend_state_t *state = data;
@@ -4455,20 +4469,20 @@ static int _regulator_suspend_late(struct device *dev, void *data)
4455} 4469}
4456 4470
4457/** 4471/**
4458 * regulator_suspend_late - prepare regulators for system wide suspend 4472 * regulator_suspend - prepare regulators for system wide suspend
4459 * @state: system suspend state 4473 * @state: system suspend state
4460 * 4474 *
4461 * Configure each regulator with it's suspend operating parameters for state. 4475 * Configure each regulator with it's suspend operating parameters for state.
4462 */ 4476 */
4463static int regulator_suspend_late(struct device *dev) 4477static int regulator_suspend(struct device *dev)
4464{ 4478{
4465 suspend_state_t state = pm_suspend_target_state; 4479 suspend_state_t state = pm_suspend_target_state;
4466 4480
4467 return class_for_each_device(&regulator_class, NULL, &state, 4481 return class_for_each_device(&regulator_class, NULL, &state,
4468 _regulator_suspend_late); 4482 _regulator_suspend);
4469} 4483}
4470 4484
4471static int _regulator_resume_early(struct device *dev, void *data) 4485static int _regulator_resume(struct device *dev, void *data)
4472{ 4486{
4473 int ret = 0; 4487 int ret = 0;
4474 struct regulator_dev *rdev = dev_to_rdev(dev); 4488 struct regulator_dev *rdev = dev_to_rdev(dev);
@@ -4481,35 +4495,35 @@ static int _regulator_resume_early(struct device *dev, void *data)
4481 4495
4482 regulator_lock(rdev); 4496 regulator_lock(rdev);
4483 4497
4484 if (rdev->desc->ops->resume_early && 4498 if (rdev->desc->ops->resume &&
4485 (rstate->enabled == ENABLE_IN_SUSPEND || 4499 (rstate->enabled == ENABLE_IN_SUSPEND ||
4486 rstate->enabled == DISABLE_IN_SUSPEND)) 4500 rstate->enabled == DISABLE_IN_SUSPEND))
4487 ret = rdev->desc->ops->resume_early(rdev); 4501 ret = rdev->desc->ops->resume(rdev);
4488 4502
4489 regulator_unlock(rdev); 4503 regulator_unlock(rdev);
4490 4504
4491 return ret; 4505 return ret;
4492} 4506}
4493 4507
4494static int regulator_resume_early(struct device *dev) 4508static int regulator_resume(struct device *dev)
4495{ 4509{
4496 suspend_state_t state = pm_suspend_target_state; 4510 suspend_state_t state = pm_suspend_target_state;
4497 4511
4498 return class_for_each_device(&regulator_class, NULL, &state, 4512 return class_for_each_device(&regulator_class, NULL, &state,
4499 _regulator_resume_early); 4513 _regulator_resume);
4500} 4514}
4501 4515
4502#else /* !CONFIG_SUSPEND */ 4516#else /* !CONFIG_SUSPEND */
4503 4517
4504#define regulator_suspend_late NULL 4518#define regulator_suspend NULL
4505#define regulator_resume_early NULL 4519#define regulator_resume NULL
4506 4520
4507#endif /* !CONFIG_SUSPEND */ 4521#endif /* !CONFIG_SUSPEND */
4508 4522
4509#ifdef CONFIG_PM 4523#ifdef CONFIG_PM
4510static const struct dev_pm_ops __maybe_unused regulator_pm_ops = { 4524static const struct dev_pm_ops __maybe_unused regulator_pm_ops = {
4511 .suspend_late = regulator_suspend_late, 4525 .suspend = regulator_suspend,
4512 .resume_early = regulator_resume_early, 4526 .resume = regulator_resume,
4513}; 4527};
4514#endif 4528#endif
4515 4529
diff --git a/drivers/regulator/cpcap-regulator.c b/drivers/regulator/cpcap-regulator.c
index bd910fe123d9..2131457937b7 100644
--- a/drivers/regulator/cpcap-regulator.c
+++ b/drivers/regulator/cpcap-regulator.c
@@ -271,6 +271,29 @@ static struct regulator_ops cpcap_regulator_ops = {
271}; 271};
272 272
273static const unsigned int unknown_val_tbl[] = { 0, }; 273static const unsigned int unknown_val_tbl[] = { 0, };
274static const unsigned int sw2_sw4_val_tbl[] = { 612500, 625000, 637500,
275 650000, 662500, 675000,
276 687500, 700000, 712500,
277 725000, 737500, 750000,
278 762500, 775000, 787500,
279 800000, 812500, 825000,
280 837500, 850000, 862500,
281 875000, 887500, 900000,
282 912500, 925000, 937500,
283 950000, 962500, 975000,
284 987500, 1000000, 1012500,
285 1025000, 1037500, 1050000,
286 1062500, 1075000, 1087500,
287 1100000, 1112500, 1125000,
288 1137500, 1150000, 1162500,
289 1175000, 1187500, 1200000,
290 1212500, 1225000, 1237500,
291 1250000, 1262500, 1275000,
292 1287500, 1300000, 1312500,
293 1325000, 1337500, 1350000,
294 1362500, 1375000, 1387500,
295 1400000, 1412500, 1425000,
296 1437500, 1450000, 1462500, };
274static const unsigned int sw5_val_tbl[] = { 0, 5050000, }; 297static const unsigned int sw5_val_tbl[] = { 0, 5050000, };
275static const unsigned int vcam_val_tbl[] = { 2600000, 2700000, 2800000, 298static const unsigned int vcam_val_tbl[] = { 2600000, 2700000, 2800000,
276 2900000, }; 299 2900000, };
@@ -389,6 +412,82 @@ static struct cpcap_regulator omap4_regulators[] = {
389 { /* sentinel */ }, 412 { /* sentinel */ },
390}; 413};
391 414
415static struct cpcap_regulator xoom_regulators[] = {
416 CPCAP_REG(SW1, CPCAP_REG_S1C1, CPCAP_REG_ASSIGN2,
417 CPCAP_BIT_SW1_SEL, unknown_val_tbl,
418 0, 0, 0, 0, 0, 0),
419 CPCAP_REG(SW2, CPCAP_REG_S2C1, CPCAP_REG_ASSIGN2,
420 CPCAP_BIT_SW2_SEL, sw2_sw4_val_tbl,
421 0xf00, 0x7f, 0, 0x800, 0, 120),
422 CPCAP_REG(SW3, CPCAP_REG_S3C, CPCAP_REG_ASSIGN2,
423 CPCAP_BIT_SW3_SEL, unknown_val_tbl,
424 0, 0, 0, 0, 0, 0),
425 CPCAP_REG(SW4, CPCAP_REG_S4C1, CPCAP_REG_ASSIGN2,
426 CPCAP_BIT_SW4_SEL, sw2_sw4_val_tbl,
427 0xf00, 0x7f, 0, 0x900, 0, 100),
428 CPCAP_REG(SW5, CPCAP_REG_S5C, CPCAP_REG_ASSIGN2,
429 CPCAP_BIT_SW5_SEL, sw5_val_tbl,
430 0x2a, 0, 0, 0x22, 0, 0),
431 CPCAP_REG(SW6, CPCAP_REG_S6C, CPCAP_REG_ASSIGN2,
432 CPCAP_BIT_SW6_SEL, unknown_val_tbl,
433 0, 0, 0, 0, 0, 0),
434 CPCAP_REG(VCAM, CPCAP_REG_VCAMC, CPCAP_REG_ASSIGN2,
435 CPCAP_BIT_VCAM_SEL, vcam_val_tbl,
436 0x87, 0x30, 4, 0x7, 0, 420),
437 CPCAP_REG(VCSI, CPCAP_REG_VCSIC, CPCAP_REG_ASSIGN3,
438 CPCAP_BIT_VCSI_SEL, vcsi_val_tbl,
439 0x47, 0x10, 4, 0x7, 0, 350),
440 CPCAP_REG(VDAC, CPCAP_REG_VDACC, CPCAP_REG_ASSIGN3,
441 CPCAP_BIT_VDAC_SEL, vdac_val_tbl,
442 0x87, 0x30, 4, 0x3, 0, 420),
443 CPCAP_REG(VDIG, CPCAP_REG_VDIGC, CPCAP_REG_ASSIGN2,
444 CPCAP_BIT_VDIG_SEL, vdig_val_tbl,
445 0x87, 0x30, 4, 0x5, 0, 420),
446 CPCAP_REG(VFUSE, CPCAP_REG_VFUSEC, CPCAP_REG_ASSIGN3,
447 CPCAP_BIT_VFUSE_SEL, vfuse_val_tbl,
448 0x80, 0xf, 0, 0x80, 0, 420),
449 CPCAP_REG(VHVIO, CPCAP_REG_VHVIOC, CPCAP_REG_ASSIGN3,
450 CPCAP_BIT_VHVIO_SEL, vhvio_val_tbl,
451 0x17, 0, 0, 0x2, 0, 0),
452 CPCAP_REG(VSDIO, CPCAP_REG_VSDIOC, CPCAP_REG_ASSIGN2,
453 CPCAP_BIT_VSDIO_SEL, vsdio_val_tbl,
454 0x87, 0x38, 3, 0x2, 0, 420),
455 CPCAP_REG(VPLL, CPCAP_REG_VPLLC, CPCAP_REG_ASSIGN3,
456 CPCAP_BIT_VPLL_SEL, vpll_val_tbl,
457 0x43, 0x18, 3, 0x1, 0, 420),
458 CPCAP_REG(VRF1, CPCAP_REG_VRF1C, CPCAP_REG_ASSIGN3,
459 CPCAP_BIT_VRF1_SEL, vrf1_val_tbl,
460 0xac, 0x2, 1, 0xc, 0, 10),
461 CPCAP_REG(VRF2, CPCAP_REG_VRF2C, CPCAP_REG_ASSIGN3,
462 CPCAP_BIT_VRF2_SEL, vrf2_val_tbl,
463 0x23, 0x8, 3, 0x3, 0, 10),
464 CPCAP_REG(VRFREF, CPCAP_REG_VRFREFC, CPCAP_REG_ASSIGN3,
465 CPCAP_BIT_VRFREF_SEL, vrfref_val_tbl,
466 0x23, 0x8, 3, 0x3, 0, 420),
467 CPCAP_REG(VWLAN1, CPCAP_REG_VWLAN1C, CPCAP_REG_ASSIGN3,
468 CPCAP_BIT_VWLAN1_SEL, vwlan1_val_tbl,
469 0x47, 0x10, 4, 0x5, 0, 420),
470 CPCAP_REG(VWLAN2, CPCAP_REG_VWLAN2C, CPCAP_REG_ASSIGN3,
471 CPCAP_BIT_VWLAN2_SEL, vwlan2_val_tbl,
472 0x20c, 0xc0, 6, 0x8, 0, 420),
473 CPCAP_REG(VSIM, CPCAP_REG_VSIMC, CPCAP_REG_ASSIGN3,
474 0xffff, vsim_val_tbl,
475 0x23, 0x8, 3, 0x3, 0, 420),
476 CPCAP_REG(VSIMCARD, CPCAP_REG_VSIMC, CPCAP_REG_ASSIGN3,
477 0xffff, vsimcard_val_tbl,
478 0x1e80, 0x8, 3, 0x1e00, 0, 420),
479 CPCAP_REG(VVIB, CPCAP_REG_VVIBC, CPCAP_REG_ASSIGN3,
480 CPCAP_BIT_VVIB_SEL, vvib_val_tbl,
481 0x1, 0xc, 2, 0, 0x1, 500),
482 CPCAP_REG(VUSB, CPCAP_REG_VUSBC, CPCAP_REG_ASSIGN3,
483 CPCAP_BIT_VUSB_SEL, vusb_val_tbl,
484 0x11c, 0x40, 6, 0xc, 0, 0),
485 CPCAP_REG(VAUDIO, CPCAP_REG_VAUDIOC, CPCAP_REG_ASSIGN4,
486 CPCAP_BIT_VAUDIO_SEL, vaudio_val_tbl,
487 0x16, 0x1, 0, 0x4, 0, 0),
488 { /* sentinel */ },
489};
490
392static const struct of_device_id cpcap_regulator_id_table[] = { 491static const struct of_device_id cpcap_regulator_id_table[] = {
393 { 492 {
394 .compatible = "motorola,cpcap-regulator", 493 .compatible = "motorola,cpcap-regulator",
@@ -397,6 +496,10 @@ static const struct of_device_id cpcap_regulator_id_table[] = {
397 .compatible = "motorola,mapphone-cpcap-regulator", 496 .compatible = "motorola,mapphone-cpcap-regulator",
398 .data = omap4_regulators, 497 .data = omap4_regulators,
399 }, 498 },
499 {
500 .compatible = "motorola,xoom-cpcap-regulator",
501 .data = xoom_regulators,
502 },
400 {}, 503 {},
401}; 504};
402MODULE_DEVICE_TABLE(of, cpcap_regulator_id_table); 505MODULE_DEVICE_TABLE(of, cpcap_regulator_id_table);
diff --git a/drivers/regulator/max14577-regulator.c b/drivers/regulator/max14577-regulator.c
index 0db288ce319c..bc7f4751bf9c 100644
--- a/drivers/regulator/max14577-regulator.c
+++ b/drivers/regulator/max14577-regulator.c
@@ -1,19 +1,9 @@
1/* 1// SPDX-License-Identifier: GPL-2.0+
2 * max14577.c - Regulator driver for the Maxim 14577/77836 2//
3 * 3// max14577.c - Regulator driver for the Maxim 14577/77836
4 * Copyright (C) 2013,2014 Samsung Electronics 4//
5 * Krzysztof Kozlowski <krzk@kernel.org> 5// Copyright (C) 2013,2014 Samsung Electronics
6 * 6// Krzysztof Kozlowski <krzk@kernel.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17 7
18#include <linux/module.h> 8#include <linux/module.h>
19#include <linux/platform_device.h> 9#include <linux/platform_device.h>
diff --git a/drivers/regulator/max77686-regulator.c b/drivers/regulator/max77686-regulator.c
index c301f3733475..bee060937f56 100644
--- a/drivers/regulator/max77686-regulator.c
+++ b/drivers/regulator/max77686-regulator.c
@@ -1,26 +1,12 @@
1/* 1// SPDX-License-Identifier: GPL-2.0+
2 * max77686.c - Regulator driver for the Maxim 77686 2//
3 * 3// max77686.c - Regulator driver for the Maxim 77686
4 * Copyright (C) 2012 Samsung Electronics 4//
5 * Chiwoong Byun <woong.byun@samsung.com> 5// Copyright (C) 2012 Samsung Electronics
6 * Jonghwa Lee <jonghwa3.lee@samsung.com> 6// Chiwoong Byun <woong.byun@samsung.com>
7 * 7// Jonghwa Lee <jonghwa3.lee@samsung.com>
8 * This program is free software; you can redistribute it and/or modify 8//
9 * it under the terms of the GNU General Public License as published by 9// This driver is based on max8997.c
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 * This driver is based on max8997.c
23 */
24 10
25#include <linux/kernel.h> 11#include <linux/kernel.h>
26#include <linux/bug.h> 12#include <linux/bug.h>
diff --git a/drivers/regulator/max77693-regulator.c b/drivers/regulator/max77693-regulator.c
index e7000e777292..077ecbbfdf76 100644
--- a/drivers/regulator/max77693-regulator.c
+++ b/drivers/regulator/max77693-regulator.c
@@ -1,26 +1,12 @@
1/* 1// SPDX-License-Identifier: GPL-2.0+
2 * max77693.c - Regulator driver for the Maxim 77693 and 77843 2//
3 * 3// max77693.c - Regulator driver for the Maxim 77693 and 77843
4 * Copyright (C) 2013-2015 Samsung Electronics 4//
5 * Jonghwa Lee <jonghwa3.lee@samsung.com> 5// Copyright (C) 2013-2015 Samsung Electronics
6 * Krzysztof Kozlowski <krzk@kernel.org> 6// Jonghwa Lee <jonghwa3.lee@samsung.com>
7 * 7// Krzysztof Kozlowski <krzk@kernel.org>
8 * This program is free software; you can redistribute it and/or modify 8//
9 * it under the terms of the GNU General Public License as published by 9// This driver is based on max77686.c
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 * This driver is based on max77686.c
23 */
24 10
25#include <linux/err.h> 11#include <linux/err.h>
26#include <linux/slab.h> 12#include <linux/slab.h>
diff --git a/drivers/regulator/max77802-regulator.c b/drivers/regulator/max77802-regulator.c
index b6261903818c..c30cf5c9f2de 100644
--- a/drivers/regulator/max77802-regulator.c
+++ b/drivers/regulator/max77802-regulator.c
@@ -1,25 +1,15 @@
1/* 1// SPDX-License-Identifier: GPL-2.0+
2 * max77802.c - Regulator driver for the Maxim 77802 2//
3 * 3// max77802.c - Regulator driver for the Maxim 77802
4 * Copyright (C) 2013-2014 Google, Inc 4//
5 * Simon Glass <sjg@chromium.org> 5// Copyright (C) 2013-2014 Google, Inc
6 * 6// Simon Glass <sjg@chromium.org>
7 * Copyright (C) 2012 Samsung Electronics 7//
8 * Chiwoong Byun <woong.byun@samsung.com> 8// Copyright (C) 2012 Samsung Electronics
9 * Jonghwa Lee <jonghwa3.lee@samsung.com> 9// Chiwoong Byun <woong.byun@samsung.com>
10 * 10// Jonghwa Lee <jonghwa3.lee@samsung.com>
11 * This program is free software; you can redistribute it and/or modify 11//
12 * it under the terms of the GNU General Public License as published by 12// This driver is based on max8997.c
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * This driver is based on max8997.c
22 */
23 13
24#include <linux/kernel.h> 14#include <linux/kernel.h>
25#include <linux/bug.h> 15#include <linux/bug.h>
diff --git a/drivers/regulator/max8997-regulator.c b/drivers/regulator/max8997-regulator.c
index a8ea30ee18a6..ad0c806b0737 100644
--- a/drivers/regulator/max8997-regulator.c
+++ b/drivers/regulator/max8997-regulator.c
@@ -1,25 +1,11 @@
1/* 1// SPDX-License-Identifier: GPL-2.0+
2 * max8997.c - Regulator driver for the Maxim 8997/8966 2//
3 * 3// max8997.c - Regulator driver for the Maxim 8997/8966
4 * Copyright (C) 2011 Samsung Electronics 4//
5 * MyungJoo Ham <myungjoo.ham@samsung.com> 5// Copyright (C) 2011 Samsung Electronics
6 * 6// MyungJoo Ham <myungjoo.ham@samsung.com>
7 * This program is free software; you can redistribute it and/or modify 7//
8 * it under the terms of the GNU General Public License as published by 8// This driver is based on max8998.c
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * This driver is based on max8998.c
22 */
23 9
24#include <linux/bug.h> 10#include <linux/bug.h>
25#include <linux/err.h> 11#include <linux/err.h>
@@ -165,8 +151,7 @@ static int max8997_list_voltage(struct regulator_dev *rdev,
165 int rid = rdev_get_id(rdev); 151 int rid = rdev_get_id(rdev);
166 int val; 152 int val;
167 153
168 if (rid >= ARRAY_SIZE(reg_voltage_map) || 154 if (rid < 0 || rid >= ARRAY_SIZE(reg_voltage_map))
169 rid < 0)
170 return -EINVAL; 155 return -EINVAL;
171 156
172 desc = reg_voltage_map[rid]; 157 desc = reg_voltage_map[rid];
diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c
index 6b9f262ebbb0..271bb736f3f5 100644
--- a/drivers/regulator/max8998.c
+++ b/drivers/regulator/max8998.c
@@ -1,24 +1,10 @@
1/* 1// SPDX-License-Identifier: GPL-2.0+
2 * max8998.c - Voltage regulator driver for the Maxim 8998 2//
3 * 3// max8998.c - Voltage regulator driver for the Maxim 8998
4 * Copyright (C) 2009-2010 Samsung Electronics 4//
5 * Kyungmin Park <kyungmin.park@samsung.com> 5// Copyright (C) 2009-2010 Samsung Electronics
6 * Marek Szyprowski <m.szyprowski@samsung.com> 6// Kyungmin Park <kyungmin.park@samsung.com>
7 * 7// Marek Szyprowski <m.szyprowski@samsung.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22 8
23#include <linux/module.h> 9#include <linux/module.h>
24#include <linux/init.h> 10#include <linux/init.h>
diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c
index 8d9dbcc775ea..31c3a236120a 100644
--- a/drivers/regulator/pfuze100-regulator.c
+++ b/drivers/regulator/pfuze100-regulator.c
@@ -17,6 +17,8 @@
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/regmap.h> 18#include <linux/regmap.h>
19 19
20#define PFUZE_FLAG_DISABLE_SW BIT(1)
21
20#define PFUZE_NUMREGS 128 22#define PFUZE_NUMREGS 128
21#define PFUZE100_VOL_OFFSET 0 23#define PFUZE100_VOL_OFFSET 0
22#define PFUZE100_STANDBY_OFFSET 1 24#define PFUZE100_STANDBY_OFFSET 1
@@ -44,16 +46,18 @@
44#define PFUZE100_VGEN5VOL 0x70 46#define PFUZE100_VGEN5VOL 0x70
45#define PFUZE100_VGEN6VOL 0x71 47#define PFUZE100_VGEN6VOL 0x71
46 48
47enum chips { PFUZE100, PFUZE200, PFUZE3000 = 3 }; 49enum chips { PFUZE100, PFUZE200, PFUZE3000 = 3, PFUZE3001 = 0x31, };
48 50
49struct pfuze_regulator { 51struct pfuze_regulator {
50 struct regulator_desc desc; 52 struct regulator_desc desc;
51 unsigned char stby_reg; 53 unsigned char stby_reg;
52 unsigned char stby_mask; 54 unsigned char stby_mask;
55 bool sw_reg;
53}; 56};
54 57
55struct pfuze_chip { 58struct pfuze_chip {
56 int chip_id; 59 int chip_id;
60 int flags;
57 struct regmap *regmap; 61 struct regmap *regmap;
58 struct device *dev; 62 struct device *dev;
59 struct pfuze_regulator regulator_descs[PFUZE100_MAX_REGULATOR]; 63 struct pfuze_regulator regulator_descs[PFUZE100_MAX_REGULATOR];
@@ -92,6 +96,7 @@ static const struct i2c_device_id pfuze_device_id[] = {
92 {.name = "pfuze100", .driver_data = PFUZE100}, 96 {.name = "pfuze100", .driver_data = PFUZE100},
93 {.name = "pfuze200", .driver_data = PFUZE200}, 97 {.name = "pfuze200", .driver_data = PFUZE200},
94 {.name = "pfuze3000", .driver_data = PFUZE3000}, 98 {.name = "pfuze3000", .driver_data = PFUZE3000},
99 {.name = "pfuze3001", .driver_data = PFUZE3001},
95 { } 100 { }
96}; 101};
97MODULE_DEVICE_TABLE(i2c, pfuze_device_id); 102MODULE_DEVICE_TABLE(i2c, pfuze_device_id);
@@ -100,6 +105,7 @@ static const struct of_device_id pfuze_dt_ids[] = {
100 { .compatible = "fsl,pfuze100", .data = (void *)PFUZE100}, 105 { .compatible = "fsl,pfuze100", .data = (void *)PFUZE100},
101 { .compatible = "fsl,pfuze200", .data = (void *)PFUZE200}, 106 { .compatible = "fsl,pfuze200", .data = (void *)PFUZE200},
102 { .compatible = "fsl,pfuze3000", .data = (void *)PFUZE3000}, 107 { .compatible = "fsl,pfuze3000", .data = (void *)PFUZE3000},
108 { .compatible = "fsl,pfuze3001", .data = (void *)PFUZE3001},
103 { } 109 { }
104}; 110};
105MODULE_DEVICE_TABLE(of, pfuze_dt_ids); 111MODULE_DEVICE_TABLE(of, pfuze_dt_ids);
@@ -108,10 +114,28 @@ static int pfuze100_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
108{ 114{
109 struct pfuze_chip *pfuze100 = rdev_get_drvdata(rdev); 115 struct pfuze_chip *pfuze100 = rdev_get_drvdata(rdev);
110 int id = rdev_get_id(rdev); 116 int id = rdev_get_id(rdev);
117 bool reg_has_ramp_delay;
111 unsigned int ramp_bits; 118 unsigned int ramp_bits;
112 int ret; 119 int ret;
113 120
114 if (id < PFUZE100_SWBST) { 121 switch (pfuze100->chip_id) {
122 case PFUZE3001:
123 /* no dynamic voltage scaling for PF3001 */
124 reg_has_ramp_delay = false;
125 break;
126 case PFUZE3000:
127 reg_has_ramp_delay = (id < PFUZE3000_SWBST);
128 break;
129 case PFUZE200:
130 reg_has_ramp_delay = (id < PFUZE200_SWBST);
131 break;
132 case PFUZE100:
133 default:
134 reg_has_ramp_delay = (id < PFUZE100_SWBST);
135 break;
136 }
137
138 if (reg_has_ramp_delay) {
115 ramp_delay = 12500 / ramp_delay; 139 ramp_delay = 12500 / ramp_delay;
116 ramp_bits = (ramp_delay >> 1) - (ramp_delay >> 3); 140 ramp_bits = (ramp_delay >> 1) - (ramp_delay >> 3);
117 ret = regmap_update_bits(pfuze100->regmap, 141 ret = regmap_update_bits(pfuze100->regmap,
@@ -119,8 +143,9 @@ static int pfuze100_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
119 0xc0, ramp_bits << 6); 143 0xc0, ramp_bits << 6);
120 if (ret < 0) 144 if (ret < 0)
121 dev_err(pfuze100->dev, "ramp failed, err %d\n", ret); 145 dev_err(pfuze100->dev, "ramp failed, err %d\n", ret);
122 } else 146 } else {
123 ret = -EACCES; 147 ret = -EACCES;
148 }
124 149
125 return ret; 150 return ret;
126} 151}
@@ -142,6 +167,14 @@ static const struct regulator_ops pfuze100_fixed_regulator_ops = {
142}; 167};
143 168
144static const struct regulator_ops pfuze100_sw_regulator_ops = { 169static const struct regulator_ops pfuze100_sw_regulator_ops = {
170 .list_voltage = regulator_list_voltage_linear,
171 .set_voltage_sel = regulator_set_voltage_sel_regmap,
172 .get_voltage_sel = regulator_get_voltage_sel_regmap,
173 .set_voltage_time_sel = regulator_set_voltage_time_sel,
174 .set_ramp_delay = pfuze100_set_ramp_delay,
175};
176
177static const struct regulator_ops pfuze100_sw_disable_regulator_ops = {
145 .enable = regulator_enable_regmap, 178 .enable = regulator_enable_regmap,
146 .disable = regulator_disable_regmap, 179 .disable = regulator_disable_regmap,
147 .is_enabled = regulator_is_enabled_regmap, 180 .is_enabled = regulator_is_enabled_regmap,
@@ -192,13 +225,11 @@ static const struct regulator_ops pfuze100_swb_regulator_ops = {
192 .vsel_reg = (base) + PFUZE100_VOL_OFFSET, \ 225 .vsel_reg = (base) + PFUZE100_VOL_OFFSET, \
193 .vsel_mask = 0x3f, \ 226 .vsel_mask = 0x3f, \
194 .enable_reg = (base) + PFUZE100_MODE_OFFSET, \ 227 .enable_reg = (base) + PFUZE100_MODE_OFFSET, \
195 .enable_val = 0xc, \
196 .disable_val = 0x0, \
197 .enable_mask = 0xf, \ 228 .enable_mask = 0xf, \
198 .enable_time = 500, \
199 }, \ 229 }, \
200 .stby_reg = (base) + PFUZE100_STANDBY_OFFSET, \ 230 .stby_reg = (base) + PFUZE100_STANDBY_OFFSET, \
201 .stby_mask = 0x3f, \ 231 .stby_mask = 0x3f, \
232 .sw_reg = true, \
202 } 233 }
203 234
204#define PFUZE100_SWB_REG(_chip, _name, base, mask, voltages) \ 235#define PFUZE100_SWB_REG(_chip, _name, base, mask, voltages) \
@@ -361,6 +392,19 @@ static struct pfuze_regulator pfuze3000_regulators[] = {
361 PFUZE100_VGEN_REG(PFUZE3000, VLDO4, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000), 392 PFUZE100_VGEN_REG(PFUZE3000, VLDO4, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000),
362}; 393};
363 394
395static struct pfuze_regulator pfuze3001_regulators[] = {
396 PFUZE100_SWB_REG(PFUZE3001, SW1, PFUZE100_SW1ABVOL, 0x1f, pfuze3000_sw1a),
397 PFUZE100_SWB_REG(PFUZE3001, SW2, PFUZE100_SW2VOL, 0x7, pfuze3000_sw2lo),
398 PFUZE3000_SW3_REG(PFUZE3001, SW3, PFUZE100_SW3AVOL, 900000, 1650000, 50000),
399 PFUZE100_SWB_REG(PFUZE3001, VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs),
400 PFUZE100_VGEN_REG(PFUZE3001, VLDO1, PFUZE100_VGEN1VOL, 1800000, 3300000, 100000),
401 PFUZE100_VGEN_REG(PFUZE3001, VLDO2, PFUZE100_VGEN2VOL, 800000, 1550000, 50000),
402 PFUZE3000_VCC_REG(PFUZE3001, VCCSD, PFUZE100_VGEN3VOL, 2850000, 3300000, 150000),
403 PFUZE3000_VCC_REG(PFUZE3001, V33, PFUZE100_VGEN4VOL, 2850000, 3300000, 150000),
404 PFUZE100_VGEN_REG(PFUZE3001, VLDO3, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000),
405 PFUZE100_VGEN_REG(PFUZE3001, VLDO4, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000),
406};
407
364#ifdef CONFIG_OF 408#ifdef CONFIG_OF
365/* PFUZE100 */ 409/* PFUZE100 */
366static struct of_regulator_match pfuze100_matches[] = { 410static struct of_regulator_match pfuze100_matches[] = {
@@ -418,6 +462,21 @@ static struct of_regulator_match pfuze3000_matches[] = {
418 { .name = "vldo4", }, 462 { .name = "vldo4", },
419}; 463};
420 464
465/* PFUZE3001 */
466static struct of_regulator_match pfuze3001_matches[] = {
467
468 { .name = "sw1", },
469 { .name = "sw2", },
470 { .name = "sw3", },
471 { .name = "vsnvs", },
472 { .name = "vldo1", },
473 { .name = "vldo2", },
474 { .name = "vccsd", },
475 { .name = "v33", },
476 { .name = "vldo3", },
477 { .name = "vldo4", },
478};
479
421static struct of_regulator_match *pfuze_matches; 480static struct of_regulator_match *pfuze_matches;
422 481
423static int pfuze_parse_regulators_dt(struct pfuze_chip *chip) 482static int pfuze_parse_regulators_dt(struct pfuze_chip *chip)
@@ -430,6 +489,9 @@ static int pfuze_parse_regulators_dt(struct pfuze_chip *chip)
430 if (!np) 489 if (!np)
431 return -EINVAL; 490 return -EINVAL;
432 491
492 if (of_property_read_bool(np, "fsl,pfuze-support-disable-sw"))
493 chip->flags |= PFUZE_FLAG_DISABLE_SW;
494
433 parent = of_get_child_by_name(np, "regulators"); 495 parent = of_get_child_by_name(np, "regulators");
434 if (!parent) { 496 if (!parent) {
435 dev_err(dev, "regulators node not found\n"); 497 dev_err(dev, "regulators node not found\n");
@@ -437,6 +499,11 @@ static int pfuze_parse_regulators_dt(struct pfuze_chip *chip)
437 } 499 }
438 500
439 switch (chip->chip_id) { 501 switch (chip->chip_id) {
502 case PFUZE3001:
503 pfuze_matches = pfuze3001_matches;
504 ret = of_regulator_match(dev, parent, pfuze3001_matches,
505 ARRAY_SIZE(pfuze3001_matches));
506 break;
440 case PFUZE3000: 507 case PFUZE3000:
441 pfuze_matches = pfuze3000_matches; 508 pfuze_matches = pfuze3000_matches;
442 ret = of_regulator_match(dev, parent, pfuze3000_matches, 509 ret = of_regulator_match(dev, parent, pfuze3000_matches,
@@ -508,7 +575,8 @@ static int pfuze_identify(struct pfuze_chip *pfuze_chip)
508 */ 575 */
509 dev_info(pfuze_chip->dev, "Assuming misprogrammed ID=0x8"); 576 dev_info(pfuze_chip->dev, "Assuming misprogrammed ID=0x8");
510 } else if ((value & 0x0f) != pfuze_chip->chip_id && 577 } else if ((value & 0x0f) != pfuze_chip->chip_id &&
511 (value & 0xf0) >> 4 != pfuze_chip->chip_id) { 578 (value & 0xf0) >> 4 != pfuze_chip->chip_id &&
579 (value != pfuze_chip->chip_id)) {
512 /* device id NOT match with your setting */ 580 /* device id NOT match with your setting */
513 dev_warn(pfuze_chip->dev, "Illegal ID: %x\n", value); 581 dev_warn(pfuze_chip->dev, "Illegal ID: %x\n", value);
514 return -ENODEV; 582 return -ENODEV;
@@ -588,6 +656,13 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
588 656
589 /* use the right regulators after identify the right device */ 657 /* use the right regulators after identify the right device */
590 switch (pfuze_chip->chip_id) { 658 switch (pfuze_chip->chip_id) {
659 case PFUZE3001:
660 pfuze_chip->pfuze_regulators = pfuze3001_regulators;
661 regulator_num = ARRAY_SIZE(pfuze3001_regulators);
662 sw_check_start = PFUZE3001_SW2;
663 sw_check_end = PFUZE3001_SW2;
664 sw_hi = 1 << 3;
665 break;
591 case PFUZE3000: 666 case PFUZE3000:
592 pfuze_chip->pfuze_regulators = pfuze3000_regulators; 667 pfuze_chip->pfuze_regulators = pfuze3000_regulators;
593 regulator_num = ARRAY_SIZE(pfuze3000_regulators); 668 regulator_num = ARRAY_SIZE(pfuze3000_regulators);
@@ -611,7 +686,8 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
611 } 686 }
612 dev_info(&client->dev, "pfuze%s found.\n", 687 dev_info(&client->dev, "pfuze%s found.\n",
613 (pfuze_chip->chip_id == PFUZE100) ? "100" : 688 (pfuze_chip->chip_id == PFUZE100) ? "100" :
614 ((pfuze_chip->chip_id == PFUZE200) ? "200" : "3000")); 689 (((pfuze_chip->chip_id == PFUZE200) ? "200" :
690 ((pfuze_chip->chip_id == PFUZE3000) ? "3000" : "3001"))));
615 691
616 memcpy(pfuze_chip->regulator_descs, pfuze_chip->pfuze_regulators, 692 memcpy(pfuze_chip->regulator_descs, pfuze_chip->pfuze_regulators,
617 sizeof(pfuze_chip->regulator_descs)); 693 sizeof(pfuze_chip->regulator_descs));
@@ -636,7 +712,8 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
636 if (i >= sw_check_start && i <= sw_check_end) { 712 if (i >= sw_check_start && i <= sw_check_end) {
637 regmap_read(pfuze_chip->regmap, desc->vsel_reg, &val); 713 regmap_read(pfuze_chip->regmap, desc->vsel_reg, &val);
638 if (val & sw_hi) { 714 if (val & sw_hi) {
639 if (pfuze_chip->chip_id == PFUZE3000) { 715 if (pfuze_chip->chip_id == PFUZE3000 ||
716 pfuze_chip->chip_id == PFUZE3001) {
640 desc->volt_table = pfuze3000_sw2hi; 717 desc->volt_table = pfuze3000_sw2hi;
641 desc->n_voltages = ARRAY_SIZE(pfuze3000_sw2hi); 718 desc->n_voltages = ARRAY_SIZE(pfuze3000_sw2hi);
642 } else { 719 } else {
@@ -647,6 +724,21 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
647 } 724 }
648 } 725 }
649 726
727 /*
728 * Allow SW regulators to turn off. Checking it trough a flag is
729 * a workaround to keep the backward compatibility with existing
730 * old dtb's which may relay on the fact that we didn't disable
731 * the switched regulator till yet.
732 */
733 if (pfuze_chip->flags & PFUZE_FLAG_DISABLE_SW) {
734 if (pfuze_chip->regulator_descs[i].sw_reg) {
735 desc->ops = &pfuze100_sw_disable_regulator_ops;
736 desc->enable_val = 0x8;
737 desc->disable_val = 0x0;
738 desc->enable_time = 500;
739 }
740 }
741
650 config.dev = &client->dev; 742 config.dev = &client->dev;
651 config.init_data = init_data; 743 config.init_data = init_data;
652 config.driver_data = pfuze_chip; 744 config.driver_data = pfuze_chip;
@@ -675,5 +767,5 @@ static struct i2c_driver pfuze_driver = {
675module_i2c_driver(pfuze_driver); 767module_i2c_driver(pfuze_driver);
676 768
677MODULE_AUTHOR("Robin Gong <b38343@freescale.com>"); 769MODULE_AUTHOR("Robin Gong <b38343@freescale.com>");
678MODULE_DESCRIPTION("Regulator Driver for Freescale PFUZE100/200/3000 PMIC"); 770MODULE_DESCRIPTION("Regulator Driver for Freescale PFUZE100/200/3000/3001 PMIC");
679MODULE_LICENSE("GPL v2"); 771MODULE_LICENSE("GPL v2");
diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c
new file mode 100644
index 000000000000..9f27daebd8c8
--- /dev/null
+++ b/drivers/regulator/qcom-rpmh-regulator.c
@@ -0,0 +1,769 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2018, The Linux Foundation. All rights reserved.
3
4#define pr_fmt(fmt) "%s: " fmt, __func__
5
6#include <linux/err.h>
7#include <linux/kernel.h>
8#include <linux/module.h>
9#include <linux/of.h>
10#include <linux/of_device.h>
11#include <linux/platform_device.h>
12#include <linux/slab.h>
13#include <linux/string.h>
14#include <linux/regulator/driver.h>
15#include <linux/regulator/machine.h>
16#include <linux/regulator/of_regulator.h>
17
18#include <soc/qcom/cmd-db.h>
19#include <soc/qcom/rpmh.h>
20
21#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
22
23/**
24 * enum rpmh_regulator_type - supported RPMh accelerator types
25 * %VRM: RPMh VRM accelerator which supports voting on enable, voltage,
26 * and mode of LDO, SMPS, and BOB type PMIC regulators.
27 * %XOB: RPMh XOB accelerator which supports voting on the enable state
28 * of PMIC regulators.
29 */
30enum rpmh_regulator_type {
31 VRM,
32 XOB,
33};
34
35#define RPMH_REGULATOR_REG_VRM_VOLTAGE 0x0
36#define RPMH_REGULATOR_REG_ENABLE 0x4
37#define RPMH_REGULATOR_REG_VRM_MODE 0x8
38
39#define PMIC4_LDO_MODE_RETENTION 4
40#define PMIC4_LDO_MODE_LPM 5
41#define PMIC4_LDO_MODE_HPM 7
42
43#define PMIC4_SMPS_MODE_RETENTION 4
44#define PMIC4_SMPS_MODE_PFM 5
45#define PMIC4_SMPS_MODE_AUTO 6
46#define PMIC4_SMPS_MODE_PWM 7
47
48#define PMIC4_BOB_MODE_PASS 0
49#define PMIC4_BOB_MODE_PFM 1
50#define PMIC4_BOB_MODE_AUTO 2
51#define PMIC4_BOB_MODE_PWM 3
52
53/**
54 * struct rpmh_vreg_hw_data - RPMh regulator hardware configurations
55 * @regulator_type: RPMh accelerator type used to manage this
56 * regulator
57 * @ops: Pointer to regulator ops callback structure
58 * @voltage_range: The single range of voltages supported by this
59 * PMIC regulator type
60 * @n_voltages: The number of unique voltage set points defined
61 * by voltage_range
62 * @hpm_min_load_uA: Minimum load current in microamps that requires
63 * high power mode (HPM) operation. This is used
64 * for LDO hardware type regulators only.
65 * @pmic_mode_map: Array indexed by regulator framework mode
66 * containing PMIC hardware modes. Must be large
67 * enough to index all framework modes supported
68 * by this regulator hardware type.
69 * @of_map_mode: Maps an RPMH_REGULATOR_MODE_* mode value defined
70 * in device tree to a regulator framework mode
71 */
72struct rpmh_vreg_hw_data {
73 enum rpmh_regulator_type regulator_type;
74 const struct regulator_ops *ops;
75 const struct regulator_linear_range voltage_range;
76 int n_voltages;
77 int hpm_min_load_uA;
78 const int *pmic_mode_map;
79 unsigned int (*of_map_mode)(unsigned int mode);
80};
81
82/**
83 * struct rpmh_vreg - individual RPMh regulator data structure encapsulating a
84 * single regulator device
85 * @dev: Device pointer for the top-level PMIC RPMh
86 * regulator parent device. This is used as a
87 * handle in RPMh write requests.
88 * @addr: Base address of the regulator resource within
89 * an RPMh accelerator
90 * @rdesc: Regulator descriptor
91 * @hw_data: PMIC regulator configuration data for this RPMh
92 * regulator
93 * @always_wait_for_ack: Boolean flag indicating if a request must always
94 * wait for an ACK from RPMh before continuing even
95 * if it corresponds to a strictly lower power
96 * state (e.g. enabled --> disabled).
97 * @enabled: Flag indicating if the regulator is enabled or
98 * not
99 * @bypassed: Boolean indicating if the regulator is in
100 * bypass (pass-through) mode or not. This is
101 * only used by BOB rpmh-regulator resources.
102 * @voltage_selector: Selector used for get_voltage_sel() and
103 * set_voltage_sel() callbacks
104 * @mode: RPMh VRM regulator current framework mode
105 */
106struct rpmh_vreg {
107 struct device *dev;
108 u32 addr;
109 struct regulator_desc rdesc;
110 const struct rpmh_vreg_hw_data *hw_data;
111 bool always_wait_for_ack;
112
113 int enabled;
114 bool bypassed;
115 int voltage_selector;
116 unsigned int mode;
117};
118
119/**
120 * struct rpmh_vreg_init_data - initialization data for an RPMh regulator
121 * @name: Name for the regulator which also corresponds
122 * to the device tree subnode name of the regulator
123 * @resource_name: RPMh regulator resource name format string.
124 * This must include exactly one field: '%s' which
125 * is filled at run-time with the PMIC ID provided
126 * by device tree property qcom,pmic-id. Example:
127 * "ldo%s1" for RPMh resource "ldoa1".
128 * @supply_name: Parent supply regulator name
129 * @hw_data: Configuration data for this PMIC regulator type
130 */
131struct rpmh_vreg_init_data {
132 const char *name;
133 const char *resource_name;
134 const char *supply_name;
135 const struct rpmh_vreg_hw_data *hw_data;
136};
137
138/**
139 * rpmh_regulator_send_request() - send the request to RPMh
140 * @vreg: Pointer to the RPMh regulator
141 * @cmd: Pointer to the RPMh command to send
142 * @wait_for_ack: Boolean indicating if execution must wait until the
143 * request has been acknowledged as complete
144 *
145 * Return: 0 on success, errno on failure
146 */
147static int rpmh_regulator_send_request(struct rpmh_vreg *vreg,
148 struct tcs_cmd *cmd, bool wait_for_ack)
149{
150 int ret;
151
152 if (wait_for_ack || vreg->always_wait_for_ack)
153 ret = rpmh_write(vreg->dev, RPMH_ACTIVE_ONLY_STATE, cmd, 1);
154 else
155 ret = rpmh_write_async(vreg->dev, RPMH_ACTIVE_ONLY_STATE, cmd,
156 1);
157
158 return ret;
159}
160
161static int _rpmh_regulator_vrm_set_voltage_sel(struct regulator_dev *rdev,
162 unsigned int selector, bool wait_for_ack)
163{
164 struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
165 struct tcs_cmd cmd = {
166 .addr = vreg->addr + RPMH_REGULATOR_REG_VRM_VOLTAGE,
167 };
168 int ret;
169
170 /* VRM voltage control register is set with voltage in millivolts. */
171 cmd.data = DIV_ROUND_UP(regulator_list_voltage_linear_range(rdev,
172 selector), 1000);
173
174 ret = rpmh_regulator_send_request(vreg, &cmd, wait_for_ack);
175 if (!ret)
176 vreg->voltage_selector = selector;
177
178 return ret;
179}
180
181static int rpmh_regulator_vrm_set_voltage_sel(struct regulator_dev *rdev,
182 unsigned int selector)
183{
184 struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
185
186 if (vreg->enabled == -EINVAL) {
187 /*
188 * Cache the voltage and send it later when the regulator is
189 * enabled or disabled.
190 */
191 vreg->voltage_selector = selector;
192 return 0;
193 }
194
195 return _rpmh_regulator_vrm_set_voltage_sel(rdev, selector,
196 selector > vreg->voltage_selector);
197}
198
199static int rpmh_regulator_vrm_get_voltage_sel(struct regulator_dev *rdev)
200{
201 struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
202
203 return vreg->voltage_selector;
204}
205
206static int rpmh_regulator_is_enabled(struct regulator_dev *rdev)
207{
208 struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
209
210 return vreg->enabled;
211}
212
213static int rpmh_regulator_set_enable_state(struct regulator_dev *rdev,
214 bool enable)
215{
216 struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
217 struct tcs_cmd cmd = {
218 .addr = vreg->addr + RPMH_REGULATOR_REG_ENABLE,
219 .data = enable,
220 };
221 int ret;
222
223 if (vreg->enabled == -EINVAL &&
224 vreg->voltage_selector != -ENOTRECOVERABLE) {
225 ret = _rpmh_regulator_vrm_set_voltage_sel(rdev,
226 vreg->voltage_selector, true);
227 if (ret < 0)
228 return ret;
229 }
230
231 ret = rpmh_regulator_send_request(vreg, &cmd, enable);
232 if (!ret)
233 vreg->enabled = enable;
234
235 return ret;
236}
237
238static int rpmh_regulator_enable(struct regulator_dev *rdev)
239{
240 return rpmh_regulator_set_enable_state(rdev, true);
241}
242
243static int rpmh_regulator_disable(struct regulator_dev *rdev)
244{
245 return rpmh_regulator_set_enable_state(rdev, false);
246}
247
248static int rpmh_regulator_vrm_set_mode_bypass(struct rpmh_vreg *vreg,
249 unsigned int mode, bool bypassed)
250{
251 struct tcs_cmd cmd = {
252 .addr = vreg->addr + RPMH_REGULATOR_REG_VRM_MODE,
253 };
254 int pmic_mode;
255
256 if (mode > REGULATOR_MODE_STANDBY)
257 return -EINVAL;
258
259 pmic_mode = vreg->hw_data->pmic_mode_map[mode];
260 if (pmic_mode < 0)
261 return pmic_mode;
262
263 if (bypassed)
264 cmd.data = PMIC4_BOB_MODE_PASS;
265 else
266 cmd.data = pmic_mode;
267
268 return rpmh_regulator_send_request(vreg, &cmd, true);
269}
270
271static int rpmh_regulator_vrm_set_mode(struct regulator_dev *rdev,
272 unsigned int mode)
273{
274 struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
275 int ret;
276
277 if (mode == vreg->mode)
278 return 0;
279
280 ret = rpmh_regulator_vrm_set_mode_bypass(vreg, mode, vreg->bypassed);
281 if (!ret)
282 vreg->mode = mode;
283
284 return ret;
285}
286
287static unsigned int rpmh_regulator_vrm_get_mode(struct regulator_dev *rdev)
288{
289 struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
290
291 return vreg->mode;
292}
293
294/**
295 * rpmh_regulator_vrm_set_load() - set the regulator mode based upon the load
296 * current requested
297 * @rdev: Regulator device pointer for the rpmh-regulator
298 * @load_uA: Aggregated load current in microamps
299 *
300 * This function is used in the regulator_ops for VRM type RPMh regulator
301 * devices.
302 *
303 * Return: 0 on success, errno on failure
304 */
305static int rpmh_regulator_vrm_set_load(struct regulator_dev *rdev, int load_uA)
306{
307 struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
308 unsigned int mode;
309
310 if (load_uA >= vreg->hw_data->hpm_min_load_uA)
311 mode = REGULATOR_MODE_NORMAL;
312 else
313 mode = REGULATOR_MODE_IDLE;
314
315 return rpmh_regulator_vrm_set_mode(rdev, mode);
316}
317
318static int rpmh_regulator_vrm_set_bypass(struct regulator_dev *rdev,
319 bool enable)
320{
321 struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
322 int ret;
323
324 if (vreg->bypassed == enable)
325 return 0;
326
327 ret = rpmh_regulator_vrm_set_mode_bypass(vreg, vreg->mode, enable);
328 if (!ret)
329 vreg->bypassed = enable;
330
331 return ret;
332}
333
334static int rpmh_regulator_vrm_get_bypass(struct regulator_dev *rdev,
335 bool *enable)
336{
337 struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
338
339 *enable = vreg->bypassed;
340
341 return 0;
342}
343
344static const struct regulator_ops rpmh_regulator_vrm_ops = {
345 .enable = rpmh_regulator_enable,
346 .disable = rpmh_regulator_disable,
347 .is_enabled = rpmh_regulator_is_enabled,
348 .set_voltage_sel = rpmh_regulator_vrm_set_voltage_sel,
349 .get_voltage_sel = rpmh_regulator_vrm_get_voltage_sel,
350 .list_voltage = regulator_list_voltage_linear_range,
351 .set_mode = rpmh_regulator_vrm_set_mode,
352 .get_mode = rpmh_regulator_vrm_get_mode,
353};
354
355static const struct regulator_ops rpmh_regulator_vrm_drms_ops = {
356 .enable = rpmh_regulator_enable,
357 .disable = rpmh_regulator_disable,
358 .is_enabled = rpmh_regulator_is_enabled,
359 .set_voltage_sel = rpmh_regulator_vrm_set_voltage_sel,
360 .get_voltage_sel = rpmh_regulator_vrm_get_voltage_sel,
361 .list_voltage = regulator_list_voltage_linear_range,
362 .set_mode = rpmh_regulator_vrm_set_mode,
363 .get_mode = rpmh_regulator_vrm_get_mode,
364 .set_load = rpmh_regulator_vrm_set_load,
365};
366
367static const struct regulator_ops rpmh_regulator_vrm_bypass_ops = {
368 .enable = rpmh_regulator_enable,
369 .disable = rpmh_regulator_disable,
370 .is_enabled = rpmh_regulator_is_enabled,
371 .set_voltage_sel = rpmh_regulator_vrm_set_voltage_sel,
372 .get_voltage_sel = rpmh_regulator_vrm_get_voltage_sel,
373 .list_voltage = regulator_list_voltage_linear_range,
374 .set_mode = rpmh_regulator_vrm_set_mode,
375 .get_mode = rpmh_regulator_vrm_get_mode,
376 .set_bypass = rpmh_regulator_vrm_set_bypass,
377 .get_bypass = rpmh_regulator_vrm_get_bypass,
378};
379
380static const struct regulator_ops rpmh_regulator_xob_ops = {
381 .enable = rpmh_regulator_enable,
382 .disable = rpmh_regulator_disable,
383 .is_enabled = rpmh_regulator_is_enabled,
384};
385
386/**
387 * rpmh_regulator_init_vreg() - initialize all attributes of an rpmh-regulator
388 * vreg: Pointer to the individual rpmh-regulator resource
389 * dev: Pointer to the top level rpmh-regulator PMIC device
390 * node: Pointer to the individual rpmh-regulator resource
391 * device node
392 * pmic_id: String used to identify the top level rpmh-regulator
393 * PMIC device on the board
394 * pmic_rpmh_data: Pointer to a null-terminated array of rpmh-regulator
395 * resources defined for the top level PMIC device
396 *
397 * Return: 0 on success, errno on failure
398 */
399static int rpmh_regulator_init_vreg(struct rpmh_vreg *vreg, struct device *dev,
400 struct device_node *node, const char *pmic_id,
401 const struct rpmh_vreg_init_data *pmic_rpmh_data)
402{
403 struct regulator_config reg_config = {};
404 char rpmh_resource_name[20] = "";
405 const struct rpmh_vreg_init_data *rpmh_data;
406 struct regulator_init_data *init_data;
407 struct regulator_dev *rdev;
408 int ret;
409
410 vreg->dev = dev;
411
412 for (rpmh_data = pmic_rpmh_data; rpmh_data->name; rpmh_data++)
413 if (!strcmp(rpmh_data->name, node->name))
414 break;
415
416 if (!rpmh_data->name) {
417 dev_err(dev, "Unknown regulator %s\n", node->name);
418 return -EINVAL;
419 }
420
421 scnprintf(rpmh_resource_name, sizeof(rpmh_resource_name),
422 rpmh_data->resource_name, pmic_id);
423
424 vreg->addr = cmd_db_read_addr(rpmh_resource_name);
425 if (!vreg->addr) {
426 dev_err(dev, "%s: could not find RPMh address for resource %s\n",
427 node->name, rpmh_resource_name);
428 return -ENODEV;
429 }
430
431 vreg->rdesc.name = rpmh_data->name;
432 vreg->rdesc.supply_name = rpmh_data->supply_name;
433 vreg->hw_data = rpmh_data->hw_data;
434
435 vreg->enabled = -EINVAL;
436 vreg->voltage_selector = -ENOTRECOVERABLE;
437 vreg->mode = REGULATOR_MODE_INVALID;
438
439 if (rpmh_data->hw_data->n_voltages) {
440 vreg->rdesc.linear_ranges = &rpmh_data->hw_data->voltage_range;
441 vreg->rdesc.n_linear_ranges = 1;
442 vreg->rdesc.n_voltages = rpmh_data->hw_data->n_voltages;
443 }
444
445 vreg->always_wait_for_ack = of_property_read_bool(node,
446 "qcom,always-wait-for-ack");
447
448 vreg->rdesc.owner = THIS_MODULE;
449 vreg->rdesc.type = REGULATOR_VOLTAGE;
450 vreg->rdesc.ops = vreg->hw_data->ops;
451 vreg->rdesc.of_map_mode = vreg->hw_data->of_map_mode;
452
453 init_data = of_get_regulator_init_data(dev, node, &vreg->rdesc);
454 if (!init_data)
455 return -ENOMEM;
456
457 if (rpmh_data->hw_data->regulator_type == XOB &&
458 init_data->constraints.min_uV &&
459 init_data->constraints.min_uV == init_data->constraints.max_uV) {
460 vreg->rdesc.fixed_uV = init_data->constraints.min_uV;
461 vreg->rdesc.n_voltages = 1;
462 }
463
464 reg_config.dev = dev;
465 reg_config.init_data = init_data;
466 reg_config.of_node = node;
467 reg_config.driver_data = vreg;
468
469 rdev = devm_regulator_register(dev, &vreg->rdesc, &reg_config);
470 if (IS_ERR(rdev)) {
471 ret = PTR_ERR(rdev);
472 dev_err(dev, "%s: devm_regulator_register() failed, ret=%d\n",
473 node->name, ret);
474 return ret;
475 }
476
477 dev_dbg(dev, "%s regulator registered for RPMh resource %s @ 0x%05X\n",
478 node->name, rpmh_resource_name, vreg->addr);
479
480 return 0;
481}
482
483static const int pmic_mode_map_pmic4_ldo[REGULATOR_MODE_STANDBY + 1] = {
484 [REGULATOR_MODE_INVALID] = -EINVAL,
485 [REGULATOR_MODE_STANDBY] = PMIC4_LDO_MODE_RETENTION,
486 [REGULATOR_MODE_IDLE] = PMIC4_LDO_MODE_LPM,
487 [REGULATOR_MODE_NORMAL] = PMIC4_LDO_MODE_HPM,
488 [REGULATOR_MODE_FAST] = -EINVAL,
489};
490
491static unsigned int rpmh_regulator_pmic4_ldo_of_map_mode(unsigned int rpmh_mode)
492{
493 unsigned int mode;
494
495 switch (rpmh_mode) {
496 case RPMH_REGULATOR_MODE_HPM:
497 mode = REGULATOR_MODE_NORMAL;
498 break;
499 case RPMH_REGULATOR_MODE_LPM:
500 mode = REGULATOR_MODE_IDLE;
501 break;
502 case RPMH_REGULATOR_MODE_RET:
503 mode = REGULATOR_MODE_STANDBY;
504 break;
505 default:
506 mode = REGULATOR_MODE_INVALID;
507 }
508
509 return mode;
510}
511
512static const int pmic_mode_map_pmic4_smps[REGULATOR_MODE_STANDBY + 1] = {
513 [REGULATOR_MODE_INVALID] = -EINVAL,
514 [REGULATOR_MODE_STANDBY] = PMIC4_SMPS_MODE_RETENTION,
515 [REGULATOR_MODE_IDLE] = PMIC4_SMPS_MODE_PFM,
516 [REGULATOR_MODE_NORMAL] = PMIC4_SMPS_MODE_AUTO,
517 [REGULATOR_MODE_FAST] = PMIC4_SMPS_MODE_PWM,
518};
519
520static unsigned int
521rpmh_regulator_pmic4_smps_of_map_mode(unsigned int rpmh_mode)
522{
523 unsigned int mode;
524
525 switch (rpmh_mode) {
526 case RPMH_REGULATOR_MODE_HPM:
527 mode = REGULATOR_MODE_FAST;
528 break;
529 case RPMH_REGULATOR_MODE_AUTO:
530 mode = REGULATOR_MODE_NORMAL;
531 break;
532 case RPMH_REGULATOR_MODE_LPM:
533 mode = REGULATOR_MODE_IDLE;
534 break;
535 case RPMH_REGULATOR_MODE_RET:
536 mode = REGULATOR_MODE_STANDBY;
537 break;
538 default:
539 mode = REGULATOR_MODE_INVALID;
540 }
541
542 return mode;
543}
544
545static const int pmic_mode_map_pmic4_bob[REGULATOR_MODE_STANDBY + 1] = {
546 [REGULATOR_MODE_INVALID] = -EINVAL,
547 [REGULATOR_MODE_STANDBY] = -EINVAL,
548 [REGULATOR_MODE_IDLE] = PMIC4_BOB_MODE_PFM,
549 [REGULATOR_MODE_NORMAL] = PMIC4_BOB_MODE_AUTO,
550 [REGULATOR_MODE_FAST] = PMIC4_BOB_MODE_PWM,
551};
552
553static unsigned int rpmh_regulator_pmic4_bob_of_map_mode(unsigned int rpmh_mode)
554{
555 unsigned int mode;
556
557 switch (rpmh_mode) {
558 case RPMH_REGULATOR_MODE_HPM:
559 mode = REGULATOR_MODE_FAST;
560 break;
561 case RPMH_REGULATOR_MODE_AUTO:
562 mode = REGULATOR_MODE_NORMAL;
563 break;
564 case RPMH_REGULATOR_MODE_LPM:
565 mode = REGULATOR_MODE_IDLE;
566 break;
567 default:
568 mode = REGULATOR_MODE_INVALID;
569 }
570
571 return mode;
572}
573
574static const struct rpmh_vreg_hw_data pmic4_pldo = {
575 .regulator_type = VRM,
576 .ops = &rpmh_regulator_vrm_drms_ops,
577 .voltage_range = REGULATOR_LINEAR_RANGE(1664000, 0, 255, 8000),
578 .n_voltages = 256,
579 .hpm_min_load_uA = 10000,
580 .pmic_mode_map = pmic_mode_map_pmic4_ldo,
581 .of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
582};
583
584static const struct rpmh_vreg_hw_data pmic4_pldo_lv = {
585 .regulator_type = VRM,
586 .ops = &rpmh_regulator_vrm_drms_ops,
587 .voltage_range = REGULATOR_LINEAR_RANGE(1256000, 0, 127, 8000),
588 .n_voltages = 128,
589 .hpm_min_load_uA = 10000,
590 .pmic_mode_map = pmic_mode_map_pmic4_ldo,
591 .of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
592};
593
594static const struct rpmh_vreg_hw_data pmic4_nldo = {
595 .regulator_type = VRM,
596 .ops = &rpmh_regulator_vrm_drms_ops,
597 .voltage_range = REGULATOR_LINEAR_RANGE(312000, 0, 127, 8000),
598 .n_voltages = 128,
599 .hpm_min_load_uA = 30000,
600 .pmic_mode_map = pmic_mode_map_pmic4_ldo,
601 .of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
602};
603
604static const struct rpmh_vreg_hw_data pmic4_hfsmps3 = {
605 .regulator_type = VRM,
606 .ops = &rpmh_regulator_vrm_ops,
607 .voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000),
608 .n_voltages = 216,
609 .pmic_mode_map = pmic_mode_map_pmic4_smps,
610 .of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
611};
612
613static const struct rpmh_vreg_hw_data pmic4_ftsmps426 = {
614 .regulator_type = VRM,
615 .ops = &rpmh_regulator_vrm_ops,
616 .voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 258, 4000),
617 .n_voltages = 259,
618 .pmic_mode_map = pmic_mode_map_pmic4_smps,
619 .of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
620};
621
622static const struct rpmh_vreg_hw_data pmic4_bob = {
623 .regulator_type = VRM,
624 .ops = &rpmh_regulator_vrm_bypass_ops,
625 .voltage_range = REGULATOR_LINEAR_RANGE(1824000, 0, 83, 32000),
626 .n_voltages = 84,
627 .pmic_mode_map = pmic_mode_map_pmic4_bob,
628 .of_map_mode = rpmh_regulator_pmic4_bob_of_map_mode,
629};
630
631static const struct rpmh_vreg_hw_data pmic4_lvs = {
632 .regulator_type = XOB,
633 .ops = &rpmh_regulator_xob_ops,
634 /* LVS hardware does not support voltage or mode configuration. */
635};
636
637#define RPMH_VREG(_name, _resource_name, _hw_data, _supply_name) \
638{ \
639 .name = _name, \
640 .resource_name = _resource_name, \
641 .hw_data = _hw_data, \
642 .supply_name = _supply_name, \
643}
644
645static const struct rpmh_vreg_init_data pm8998_vreg_data[] = {
646 RPMH_VREG("smps1", "smp%s1", &pmic4_ftsmps426, "vdd-s1"),
647 RPMH_VREG("smps2", "smp%s2", &pmic4_ftsmps426, "vdd-s2"),
648 RPMH_VREG("smps3", "smp%s3", &pmic4_hfsmps3, "vdd-s3"),
649 RPMH_VREG("smps4", "smp%s4", &pmic4_hfsmps3, "vdd-s4"),
650 RPMH_VREG("smps5", "smp%s5", &pmic4_hfsmps3, "vdd-s5"),
651 RPMH_VREG("smps6", "smp%s6", &pmic4_ftsmps426, "vdd-s6"),
652 RPMH_VREG("smps7", "smp%s7", &pmic4_ftsmps426, "vdd-s7"),
653 RPMH_VREG("smps8", "smp%s8", &pmic4_ftsmps426, "vdd-s8"),
654 RPMH_VREG("smps9", "smp%s9", &pmic4_ftsmps426, "vdd-s9"),
655 RPMH_VREG("smps10", "smp%s10", &pmic4_ftsmps426, "vdd-s10"),
656 RPMH_VREG("smps11", "smp%s11", &pmic4_ftsmps426, "vdd-s11"),
657 RPMH_VREG("smps12", "smp%s12", &pmic4_ftsmps426, "vdd-s12"),
658 RPMH_VREG("smps13", "smp%s13", &pmic4_ftsmps426, "vdd-s13"),
659 RPMH_VREG("ldo1", "ldo%s1", &pmic4_nldo, "vdd-l1-l27"),
660 RPMH_VREG("ldo2", "ldo%s2", &pmic4_nldo, "vdd-l2-l8-l17"),
661 RPMH_VREG("ldo3", "ldo%s3", &pmic4_nldo, "vdd-l3-l11"),
662 RPMH_VREG("ldo4", "ldo%s4", &pmic4_nldo, "vdd-l4-l5"),
663 RPMH_VREG("ldo5", "ldo%s5", &pmic4_nldo, "vdd-l4-l5"),
664 RPMH_VREG("ldo6", "ldo%s6", &pmic4_pldo, "vdd-l6"),
665 RPMH_VREG("ldo7", "ldo%s7", &pmic4_pldo_lv, "vdd-l7-l12-l14-l15"),
666 RPMH_VREG("ldo8", "ldo%s8", &pmic4_nldo, "vdd-l2-l8-l17"),
667 RPMH_VREG("ldo9", "ldo%s9", &pmic4_pldo, "vdd-l9"),
668 RPMH_VREG("ldo10", "ldo%s10", &pmic4_pldo, "vdd-l10-l23-l25"),
669 RPMH_VREG("ldo11", "ldo%s11", &pmic4_nldo, "vdd-l3-l11"),
670 RPMH_VREG("ldo12", "ldo%s12", &pmic4_pldo_lv, "vdd-l7-l12-l14-l15"),
671 RPMH_VREG("ldo13", "ldo%s13", &pmic4_pldo, "vdd-l13-l19-l21"),
672 RPMH_VREG("ldo14", "ldo%s14", &pmic4_pldo_lv, "vdd-l7-l12-l14-l15"),
673 RPMH_VREG("ldo15", "ldo%s15", &pmic4_pldo_lv, "vdd-l7-l12-l14-l15"),
674 RPMH_VREG("ldo16", "ldo%s16", &pmic4_pldo, "vdd-l16-l28"),
675 RPMH_VREG("ldo17", "ldo%s17", &pmic4_nldo, "vdd-l2-l8-l17"),
676 RPMH_VREG("ldo18", "ldo%s18", &pmic4_pldo, "vdd-l18-l22"),
677 RPMH_VREG("ldo19", "ldo%s19", &pmic4_pldo, "vdd-l13-l19-l21"),
678 RPMH_VREG("ldo20", "ldo%s20", &pmic4_pldo, "vdd-l20-l24"),
679 RPMH_VREG("ldo21", "ldo%s21", &pmic4_pldo, "vdd-l13-l19-l21"),
680 RPMH_VREG("ldo22", "ldo%s22", &pmic4_pldo, "vdd-l18-l22"),
681 RPMH_VREG("ldo23", "ldo%s23", &pmic4_pldo, "vdd-l10-l23-l25"),
682 RPMH_VREG("ldo24", "ldo%s24", &pmic4_pldo, "vdd-l20-l24"),
683 RPMH_VREG("ldo25", "ldo%s25", &pmic4_pldo, "vdd-l10-l23-l25"),
684 RPMH_VREG("ldo26", "ldo%s26", &pmic4_nldo, "vdd-l26"),
685 RPMH_VREG("ldo27", "ldo%s27", &pmic4_nldo, "vdd-l1-l27"),
686 RPMH_VREG("ldo28", "ldo%s28", &pmic4_pldo, "vdd-l16-l28"),
687 RPMH_VREG("lvs1", "vs%s1", &pmic4_lvs, "vin-lvs-1-2"),
688 RPMH_VREG("lvs2", "vs%s2", &pmic4_lvs, "vin-lvs-1-2"),
689 {},
690};
691
692static const struct rpmh_vreg_init_data pmi8998_vreg_data[] = {
693 RPMH_VREG("bob", "bob%s1", &pmic4_bob, "vdd-bob"),
694 {},
695};
696
697static const struct rpmh_vreg_init_data pm8005_vreg_data[] = {
698 RPMH_VREG("smps1", "smp%s1", &pmic4_ftsmps426, "vdd-s1"),
699 RPMH_VREG("smps2", "smp%s2", &pmic4_ftsmps426, "vdd-s2"),
700 RPMH_VREG("smps3", "smp%s3", &pmic4_ftsmps426, "vdd-s3"),
701 RPMH_VREG("smps4", "smp%s4", &pmic4_ftsmps426, "vdd-s4"),
702 {},
703};
704
705static int rpmh_regulator_probe(struct platform_device *pdev)
706{
707 struct device *dev = &pdev->dev;
708 const struct rpmh_vreg_init_data *vreg_data;
709 struct device_node *node;
710 struct rpmh_vreg *vreg;
711 const char *pmic_id;
712 int ret;
713
714 vreg_data = of_device_get_match_data(dev);
715 if (!vreg_data)
716 return -ENODEV;
717
718 ret = of_property_read_string(dev->of_node, "qcom,pmic-id", &pmic_id);
719 if (ret < 0) {
720 dev_err(dev, "qcom,pmic-id missing in DT node\n");
721 return ret;
722 }
723
724 for_each_available_child_of_node(dev->of_node, node) {
725 vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL);
726 if (!vreg) {
727 of_node_put(node);
728 return -ENOMEM;
729 }
730
731 ret = rpmh_regulator_init_vreg(vreg, dev, node, pmic_id,
732 vreg_data);
733 if (ret < 0) {
734 of_node_put(node);
735 return ret;
736 }
737 }
738
739 return 0;
740}
741
742static const struct of_device_id rpmh_regulator_match_table[] = {
743 {
744 .compatible = "qcom,pm8998-rpmh-regulators",
745 .data = pm8998_vreg_data,
746 },
747 {
748 .compatible = "qcom,pmi8998-rpmh-regulators",
749 .data = pmi8998_vreg_data,
750 },
751 {
752 .compatible = "qcom,pm8005-rpmh-regulators",
753 .data = pm8005_vreg_data,
754 },
755 {}
756};
757MODULE_DEVICE_TABLE(of, rpmh_regulator_match_table);
758
759static struct platform_driver rpmh_regulator_driver = {
760 .driver = {
761 .name = "qcom-rpmh-regulator",
762 .of_match_table = of_match_ptr(rpmh_regulator_match_table),
763 },
764 .probe = rpmh_regulator_probe,
765};
766module_platform_driver(rpmh_regulator_driver);
767
768MODULE_DESCRIPTION("Qualcomm RPMh regulator driver");
769MODULE_LICENSE("GPL v2");
diff --git a/drivers/regulator/qcom_spmi-regulator.c b/drivers/regulator/qcom_spmi-regulator.c
index 9817f1a75342..53a61fb65642 100644
--- a/drivers/regulator/qcom_spmi-regulator.c
+++ b/drivers/regulator/qcom_spmi-regulator.c
@@ -1060,7 +1060,7 @@ static irqreturn_t spmi_regulator_vs_ocp_isr(int irq, void *data)
1060#define SAW3_AVS_CTL_TGGL_MASK 0x8000000 1060#define SAW3_AVS_CTL_TGGL_MASK 0x8000000
1061#define SAW3_AVS_CTL_CLEAR_MASK 0x7efc00 1061#define SAW3_AVS_CTL_CLEAR_MASK 0x7efc00
1062 1062
1063static struct regmap *saw_regmap = NULL; 1063static struct regmap *saw_regmap;
1064 1064
1065static void spmi_saw_set_vdd(void *data) 1065static void spmi_saw_set_vdd(void *data)
1066{ 1066{
@@ -1728,7 +1728,7 @@ static const struct spmi_regulator_data pmi8994_regulators[] = {
1728 { "s2", 0x1700, "vdd_s2", }, 1728 { "s2", 0x1700, "vdd_s2", },
1729 { "s3", 0x1a00, "vdd_s3", }, 1729 { "s3", 0x1a00, "vdd_s3", },
1730 { "l1", 0x4000, "vdd_l1", }, 1730 { "l1", 0x4000, "vdd_l1", },
1731 { } 1731 { }
1732}; 1732};
1733 1733
1734static const struct of_device_id qcom_spmi_regulator_match[] = { 1734static const struct of_device_id qcom_spmi_regulator_match[] = {
@@ -1752,7 +1752,8 @@ static int qcom_spmi_regulator_probe(struct platform_device *pdev)
1752 const char *name; 1752 const char *name;
1753 struct device *dev = &pdev->dev; 1753 struct device *dev = &pdev->dev;
1754 struct device_node *node = pdev->dev.of_node; 1754 struct device_node *node = pdev->dev.of_node;
1755 struct device_node *syscon; 1755 struct device_node *syscon, *reg_node;
1756 struct property *reg_prop;
1756 int ret, lenp; 1757 int ret, lenp;
1757 struct list_head *vreg_list; 1758 struct list_head *vreg_list;
1758 1759
@@ -1774,16 +1775,19 @@ static int qcom_spmi_regulator_probe(struct platform_device *pdev)
1774 syscon = of_parse_phandle(node, "qcom,saw-reg", 0); 1775 syscon = of_parse_phandle(node, "qcom,saw-reg", 0);
1775 saw_regmap = syscon_node_to_regmap(syscon); 1776 saw_regmap = syscon_node_to_regmap(syscon);
1776 of_node_put(syscon); 1777 of_node_put(syscon);
1777 if (IS_ERR(regmap)) 1778 if (IS_ERR(saw_regmap))
1778 dev_err(dev, "ERROR reading SAW regmap\n"); 1779 dev_err(dev, "ERROR reading SAW regmap\n");
1779 } 1780 }
1780 1781
1781 for (reg = match->data; reg->name; reg++) { 1782 for (reg = match->data; reg->name; reg++) {
1782 1783
1783 if (saw_regmap && \ 1784 if (saw_regmap) {
1784 of_find_property(of_find_node_by_name(node, reg->name), \ 1785 reg_node = of_get_child_by_name(node, reg->name);
1785 "qcom,saw-slave", &lenp)) { 1786 reg_prop = of_find_property(reg_node, "qcom,saw-slave",
1786 continue; 1787 &lenp);
1788 of_node_put(reg_node);
1789 if (reg_prop)
1790 continue;
1787 } 1791 }
1788 1792
1789 vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL); 1793 vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL);
@@ -1816,13 +1820,17 @@ static int qcom_spmi_regulator_probe(struct platform_device *pdev)
1816 if (ret) 1820 if (ret)
1817 continue; 1821 continue;
1818 1822
1819 if (saw_regmap && \ 1823 if (saw_regmap) {
1820 of_find_property(of_find_node_by_name(node, reg->name), \ 1824 reg_node = of_get_child_by_name(node, reg->name);
1821 "qcom,saw-leader", &lenp)) { 1825 reg_prop = of_find_property(reg_node, "qcom,saw-leader",
1822 spmi_saw_ops = *(vreg->desc.ops); 1826 &lenp);
1823 spmi_saw_ops.set_voltage_sel = \ 1827 of_node_put(reg_node);
1824 spmi_regulator_saw_set_voltage; 1828 if (reg_prop) {
1825 vreg->desc.ops = &spmi_saw_ops; 1829 spmi_saw_ops = *(vreg->desc.ops);
1830 spmi_saw_ops.set_voltage_sel =
1831 spmi_regulator_saw_set_voltage;
1832 vreg->desc.ops = &spmi_saw_ops;
1833 }
1826 } 1834 }
1827 1835
1828 config.dev = dev; 1836 config.dev = dev;
diff --git a/drivers/regulator/s2mpa01.c b/drivers/regulator/s2mpa01.c
index 48f0ca90743c..095d25f3d2ea 100644
--- a/drivers/regulator/s2mpa01.c
+++ b/drivers/regulator/s2mpa01.c
@@ -1,13 +1,7 @@
1/* 1// SPDX-License-Identifier: GPL-2.0+
2 * Copyright (c) 2013 Samsung Electronics Co., Ltd 2//
3 * http://www.samsung.com 3// Copyright (c) 2013 Samsung Electronics Co., Ltd
4 * 4// http://www.samsung.com
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 */
11 5
12#include <linux/bug.h> 6#include <linux/bug.h>
13#include <linux/err.h> 7#include <linux/err.h>
diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c
index d1207ec683db..5bb6f4ca48db 100644
--- a/drivers/regulator/s2mps11.c
+++ b/drivers/regulator/s2mps11.c
@@ -1,20 +1,7 @@
1/* 1// SPDX-License-Identifier: GPL-2.0+
2 * s2mps11.c 2//
3 * 3// Copyright (c) 2012-2014 Samsung Electronics Co., Ltd
4 * Copyright (c) 2012-2014 Samsung Electronics Co., Ltd 4// http://www.samsung.com
5 * http://www.samsung.com
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18 5
19#include <linux/bug.h> 6#include <linux/bug.h>
20#include <linux/err.h> 7#include <linux/err.h>
diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c
index 0cbc980753c2..667d16dc83ce 100644
--- a/drivers/regulator/s5m8767.c
+++ b/drivers/regulator/s5m8767.c
@@ -1,15 +1,7 @@
1/* 1// SPDX-License-Identifier: GPL-2.0+
2 * s5m8767.c 2//
3 * 3// Copyright (c) 2011 Samsung Electronics Co., Ltd
4 * Copyright (c) 2011 Samsung Electronics Co., Ltd 4// http://www.samsung.com
5 * http://www.samsung.com
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13 5
14#include <linux/err.h> 6#include <linux/err.h>
15#include <linux/of_gpio.h> 7#include <linux/of_gpio.h>
diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c
index fc12badf3805..d84fab616abf 100644
--- a/drivers/regulator/tps65217-regulator.c
+++ b/drivers/regulator/tps65217-regulator.c
@@ -232,6 +232,8 @@ static int tps65217_regulator_probe(struct platform_device *pdev)
232 tps->strobes = devm_kcalloc(&pdev->dev, 232 tps->strobes = devm_kcalloc(&pdev->dev,
233 TPS65217_NUM_REGULATOR, sizeof(u8), 233 TPS65217_NUM_REGULATOR, sizeof(u8),
234 GFP_KERNEL); 234 GFP_KERNEL);
235 if (!tps->strobes)
236 return -ENOMEM;
235 237
236 platform_set_drvdata(pdev, tps); 238 platform_set_drvdata(pdev, tps);
237 239
diff --git a/drivers/regulator/uniphier-regulator.c b/drivers/regulator/uniphier-regulator.c
new file mode 100644
index 000000000000..abf22acbd13e
--- /dev/null
+++ b/drivers/regulator/uniphier-regulator.c
@@ -0,0 +1,213 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// Regulator controller driver for UniPhier SoC
4// Copyright 2018 Socionext Inc.
5// Author: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
6
7#include <linux/clk.h>
8#include <linux/io.h>
9#include <linux/module.h>
10#include <linux/of_device.h>
11#include <linux/platform_device.h>
12#include <linux/regmap.h>
13#include <linux/regulator/driver.h>
14#include <linux/regulator/of_regulator.h>
15#include <linux/reset.h>
16
17#define MAX_CLKS 2
18#define MAX_RSTS 2
19
20struct uniphier_regulator_soc_data {
21 int nclks;
22 const char * const *clock_names;
23 int nrsts;
24 const char * const *reset_names;
25 const struct regulator_desc *desc;
26 const struct regmap_config *regconf;
27};
28
29struct uniphier_regulator_priv {
30 struct clk_bulk_data clk[MAX_CLKS];
31 struct reset_control *rst[MAX_RSTS];
32 const struct uniphier_regulator_soc_data *data;
33};
34
35static struct regulator_ops uniphier_regulator_ops = {
36 .enable = regulator_enable_regmap,
37 .disable = regulator_disable_regmap,
38 .is_enabled = regulator_is_enabled_regmap,
39};
40
41static int uniphier_regulator_probe(struct platform_device *pdev)
42{
43 struct device *dev = &pdev->dev;
44 struct uniphier_regulator_priv *priv;
45 struct regulator_config config = { };
46 struct regulator_dev *rdev;
47 struct regmap *regmap;
48 struct resource *res;
49 void __iomem *base;
50 const char *name;
51 int i, ret, nr;
52
53 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
54 if (!priv)
55 return -ENOMEM;
56
57 priv->data = of_device_get_match_data(dev);
58 if (WARN_ON(!priv->data))
59 return -EINVAL;
60
61 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
62 base = devm_ioremap_resource(dev, res);
63 if (IS_ERR(base))
64 return PTR_ERR(base);
65
66 for (i = 0; i < priv->data->nclks; i++)
67 priv->clk[i].id = priv->data->clock_names[i];
68 ret = devm_clk_bulk_get(dev, priv->data->nclks, priv->clk);
69 if (ret)
70 return ret;
71
72 for (i = 0; i < priv->data->nrsts; i++) {
73 name = priv->data->reset_names[i];
74 priv->rst[i] = devm_reset_control_get_shared(dev, name);
75 if (IS_ERR(priv->rst[i]))
76 return PTR_ERR(priv->rst[i]);
77 }
78
79 ret = clk_bulk_prepare_enable(priv->data->nclks, priv->clk);
80 if (ret)
81 return ret;
82
83 for (nr = 0; nr < priv->data->nrsts; nr++) {
84 ret = reset_control_deassert(priv->rst[nr]);
85 if (ret)
86 goto out_rst_assert;
87 }
88
89 regmap = devm_regmap_init_mmio(dev, base, priv->data->regconf);
90 if (IS_ERR(regmap))
91 return PTR_ERR(regmap);
92
93 config.dev = dev;
94 config.driver_data = priv;
95 config.of_node = dev->of_node;
96 config.regmap = regmap;
97 config.init_data = of_get_regulator_init_data(dev, dev->of_node,
98 priv->data->desc);
99 rdev = devm_regulator_register(dev, priv->data->desc, &config);
100 if (IS_ERR(rdev)) {
101 ret = PTR_ERR(rdev);
102 goto out_rst_assert;
103 }
104
105 platform_set_drvdata(pdev, priv);
106
107 return 0;
108
109out_rst_assert:
110 while (nr--)
111 reset_control_assert(priv->rst[nr]);
112
113 clk_bulk_disable_unprepare(priv->data->nclks, priv->clk);
114
115 return ret;
116}
117
118static int uniphier_regulator_remove(struct platform_device *pdev)
119{
120 struct uniphier_regulator_priv *priv = platform_get_drvdata(pdev);
121 int i;
122
123 for (i = 0; i < priv->data->nrsts; i++)
124 reset_control_assert(priv->rst[i]);
125
126 clk_bulk_disable_unprepare(priv->data->nclks, priv->clk);
127
128 return 0;
129}
130
131/* USB3 controller data */
132#define USB3VBUS_OFFSET 0x0
133#define USB3VBUS_REG BIT(4)
134#define USB3VBUS_REG_EN BIT(3)
135static const struct regulator_desc uniphier_usb3_regulator_desc = {
136 .name = "vbus",
137 .of_match = of_match_ptr("vbus"),
138 .ops = &uniphier_regulator_ops,
139 .type = REGULATOR_VOLTAGE,
140 .owner = THIS_MODULE,
141 .enable_reg = USB3VBUS_OFFSET,
142 .enable_mask = USB3VBUS_REG_EN | USB3VBUS_REG,
143 .enable_val = USB3VBUS_REG_EN | USB3VBUS_REG,
144 .disable_val = USB3VBUS_REG_EN,
145};
146
147static const struct regmap_config uniphier_usb3_regulator_regconf = {
148 .reg_bits = 32,
149 .val_bits = 32,
150 .reg_stride = 4,
151 .max_register = 1,
152};
153
154static const char * const uniphier_pro4_clock_reset_names[] = {
155 "gio", "link",
156};
157
158static const struct uniphier_regulator_soc_data uniphier_pro4_usb3_data = {
159 .nclks = ARRAY_SIZE(uniphier_pro4_clock_reset_names),
160 .clock_names = uniphier_pro4_clock_reset_names,
161 .nrsts = ARRAY_SIZE(uniphier_pro4_clock_reset_names),
162 .reset_names = uniphier_pro4_clock_reset_names,
163 .desc = &uniphier_usb3_regulator_desc,
164 .regconf = &uniphier_usb3_regulator_regconf,
165};
166
167static const char * const uniphier_pxs2_clock_reset_names[] = {
168 "link",
169};
170
171static const struct uniphier_regulator_soc_data uniphier_pxs2_usb3_data = {
172 .nclks = ARRAY_SIZE(uniphier_pxs2_clock_reset_names),
173 .clock_names = uniphier_pxs2_clock_reset_names,
174 .nrsts = ARRAY_SIZE(uniphier_pxs2_clock_reset_names),
175 .reset_names = uniphier_pxs2_clock_reset_names,
176 .desc = &uniphier_usb3_regulator_desc,
177 .regconf = &uniphier_usb3_regulator_regconf,
178};
179
180static const struct of_device_id uniphier_regulator_match[] = {
181 /* USB VBUS */
182 {
183 .compatible = "socionext,uniphier-pro4-usb3-regulator",
184 .data = &uniphier_pro4_usb3_data,
185 },
186 {
187 .compatible = "socionext,uniphier-pxs2-usb3-regulator",
188 .data = &uniphier_pxs2_usb3_data,
189 },
190 {
191 .compatible = "socionext,uniphier-ld20-usb3-regulator",
192 .data = &uniphier_pxs2_usb3_data,
193 },
194 {
195 .compatible = "socionext,uniphier-pxs3-usb3-regulator",
196 .data = &uniphier_pxs2_usb3_data,
197 },
198 { /* Sentinel */ },
199};
200
201static struct platform_driver uniphier_regulator_driver = {
202 .probe = uniphier_regulator_probe,
203 .remove = uniphier_regulator_remove,
204 .driver = {
205 .name = "uniphier-regulator",
206 .of_match_table = uniphier_regulator_match,
207 },
208};
209module_platform_driver(uniphier_regulator_driver);
210
211MODULE_AUTHOR("Kunihiko Hayashi <hayashi.kunihiko@socionext.com>");
212MODULE_DESCRIPTION("UniPhier Regulator Controller Driver");
213MODULE_LICENSE("GPL");
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 5856e792d09c..ba79b609aca2 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -40,6 +40,23 @@ config QCOM_GSBI
40 functions for connecting the underlying serial UART, SPI, and I2C 40 functions for connecting the underlying serial UART, SPI, and I2C
41 devices to the output pins. 41 devices to the output pins.
42 42
43config QCOM_LLCC
44 tristate "Qualcomm Technologies, Inc. LLCC driver"
45 depends on ARCH_QCOM
46 help
47 Qualcomm Technologies, Inc. platform specific
48 Last Level Cache Controller(LLCC) driver. This provides interfaces
49 to clients that use the LLCC. Say yes here to enable LLCC slice
50 driver.
51
52config QCOM_SDM845_LLCC
53 tristate "Qualcomm Technologies, Inc. SDM845 LLCC driver"
54 depends on QCOM_LLCC
55 help
56 Say yes here to enable the LLCC driver for SDM845. This provides
57 data required to configure LLCC so that clients can start using the
58 LLCC slices.
59
43config QCOM_MDT_LOADER 60config QCOM_MDT_LOADER
44 tristate 61 tristate
45 select QCOM_SCM 62 select QCOM_SCM
@@ -75,6 +92,16 @@ config QCOM_RMTFS_MEM
75 92
76 Say y here if you intend to boot the modem remoteproc. 93 Say y here if you intend to boot the modem remoteproc.
77 94
95config QCOM_RPMH
96 bool "Qualcomm RPM-Hardened (RPMH) Communication"
97 depends on ARCH_QCOM && ARM64 && OF || COMPILE_TEST
98 help
99 Support for communication with the hardened-RPM blocks in
100 Qualcomm Technologies Inc (QTI) SoCs. RPMH communication uses an
101 internal bus to transmit state requests for shared resources. A set
102 of hardware components aggregate requests for these resources and
103 help apply the aggregated state on the resource.
104
78config QCOM_SMEM 105config QCOM_SMEM
79 tristate "Qualcomm Shared Memory Manager (SMEM)" 106 tristate "Qualcomm Shared Memory Manager (SMEM)"
80 depends on ARCH_QCOM 107 depends on ARCH_QCOM
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index 19dcf957cb3a..f25b54cd6cf8 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -1,4 +1,5 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2CFLAGS_rpmh-rsc.o := -I$(src)
2obj-$(CONFIG_QCOM_GENI_SE) += qcom-geni-se.o 3obj-$(CONFIG_QCOM_GENI_SE) += qcom-geni-se.o
3obj-$(CONFIG_QCOM_COMMAND_DB) += cmd-db.o 4obj-$(CONFIG_QCOM_COMMAND_DB) += cmd-db.o
4obj-$(CONFIG_QCOM_GLINK_SSR) += glink_ssr.o 5obj-$(CONFIG_QCOM_GLINK_SSR) += glink_ssr.o
@@ -8,6 +9,9 @@ obj-$(CONFIG_QCOM_PM) += spm.o
8obj-$(CONFIG_QCOM_QMI_HELPERS) += qmi_helpers.o 9obj-$(CONFIG_QCOM_QMI_HELPERS) += qmi_helpers.o
9qmi_helpers-y += qmi_encdec.o qmi_interface.o 10qmi_helpers-y += qmi_encdec.o qmi_interface.o
10obj-$(CONFIG_QCOM_RMTFS_MEM) += rmtfs_mem.o 11obj-$(CONFIG_QCOM_RMTFS_MEM) += rmtfs_mem.o
12obj-$(CONFIG_QCOM_RPMH) += qcom_rpmh.o
13qcom_rpmh-y += rpmh-rsc.o
14qcom_rpmh-y += rpmh.o
11obj-$(CONFIG_QCOM_SMD_RPM) += smd-rpm.o 15obj-$(CONFIG_QCOM_SMD_RPM) += smd-rpm.o
12obj-$(CONFIG_QCOM_SMEM) += smem.o 16obj-$(CONFIG_QCOM_SMEM) += smem.o
13obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o 17obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o
@@ -15,3 +19,5 @@ obj-$(CONFIG_QCOM_SMP2P) += smp2p.o
15obj-$(CONFIG_QCOM_SMSM) += smsm.o 19obj-$(CONFIG_QCOM_SMSM) += smsm.o
16obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o 20obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o
17obj-$(CONFIG_QCOM_APR) += apr.o 21obj-$(CONFIG_QCOM_APR) += apr.o
22obj-$(CONFIG_QCOM_LLCC) += llcc-slice.o
23obj-$(CONFIG_QCOM_SDM845_LLCC) += llcc-sdm845.o
diff --git a/drivers/soc/qcom/llcc-sdm845.c b/drivers/soc/qcom/llcc-sdm845.c
new file mode 100644
index 000000000000..2e1e4f0a5db8
--- /dev/null
+++ b/drivers/soc/qcom/llcc-sdm845.c
@@ -0,0 +1,94 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
4 *
5 */
6
7#include <linux/kernel.h>
8#include <linux/module.h>
9#include <linux/of.h>
10#include <linux/of_device.h>
11#include <linux/soc/qcom/llcc-qcom.h>
12
13/*
14 * SCT(System Cache Table) entry contains of the following members:
15 * usecase_id: Unique id for the client's use case
16 * slice_id: llcc slice id for each client
17 * max_cap: The maximum capacity of the cache slice provided in KB
18 * priority: Priority of the client used to select victim line for replacement
19 * fixed_size: Boolean indicating if the slice has a fixed capacity
20 * bonus_ways: Bonus ways are additional ways to be used for any slice,
21 * if client ends up using more than reserved cache ways. Bonus
22 * ways are allocated only if they are not reserved for some
23 * other client.
24 * res_ways: Reserved ways for the cache slice, the reserved ways cannot
25 * be used by any other client than the one its assigned to.
26 * cache_mode: Each slice operates as a cache, this controls the mode of the
27 * slice: normal or TCM(Tightly Coupled Memory)
28 * probe_target_ways: Determines what ways to probe for access hit. When
29 * configured to 1 only bonus and reserved ways are probed.
30 * When configured to 0 all ways in llcc are probed.
31 * dis_cap_alloc: Disable capacity based allocation for a client
32 * retain_on_pc: If this bit is set and client has maintained active vote
33 * then the ways assigned to this client are not flushed on power
34 * collapse.
35 * activate_on_init: Activate the slice immediately after the SCT is programmed
36 */
37#define SCT_ENTRY(uid, sid, mc, p, fs, bway, rway, cmod, ptw, dca, rp, a) \
38 { \
39 .usecase_id = uid, \
40 .slice_id = sid, \
41 .max_cap = mc, \
42 .priority = p, \
43 .fixed_size = fs, \
44 .bonus_ways = bway, \
45 .res_ways = rway, \
46 .cache_mode = cmod, \
47 .probe_target_ways = ptw, \
48 .dis_cap_alloc = dca, \
49 .retain_on_pc = rp, \
50 .activate_on_init = a, \
51 }
52
53static struct llcc_slice_config sdm845_data[] = {
54 SCT_ENTRY(LLCC_CPUSS, 1, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 1),
55 SCT_ENTRY(LLCC_VIDSC0, 2, 512, 2, 1, 0x0, 0x0f0, 0, 0, 1, 1, 0),
56 SCT_ENTRY(LLCC_VIDSC1, 3, 512, 2, 1, 0x0, 0x0f0, 0, 0, 1, 1, 0),
57 SCT_ENTRY(LLCC_ROTATOR, 4, 563, 2, 1, 0x0, 0x00e, 2, 0, 1, 1, 0),
58 SCT_ENTRY(LLCC_VOICE, 5, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0),
59 SCT_ENTRY(LLCC_AUDIO, 6, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0),
60 SCT_ENTRY(LLCC_MDMHPGRW, 7, 1024, 2, 0, 0xfc, 0xf00, 0, 0, 1, 1, 0),
61 SCT_ENTRY(LLCC_MDM, 8, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0),
62 SCT_ENTRY(LLCC_CMPT, 10, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0),
63 SCT_ENTRY(LLCC_GPUHTW, 11, 512, 1, 1, 0xc, 0x0, 0, 0, 1, 1, 0),
64 SCT_ENTRY(LLCC_GPU, 12, 2304, 1, 0, 0xff0, 0x2, 0, 0, 1, 1, 0),
65 SCT_ENTRY(LLCC_MMUHWT, 13, 256, 2, 0, 0x0, 0x1, 0, 0, 1, 0, 1),
66 SCT_ENTRY(LLCC_CMPTDMA, 15, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0),
67 SCT_ENTRY(LLCC_DISP, 16, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0),
68 SCT_ENTRY(LLCC_VIDFW, 17, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0),
69 SCT_ENTRY(LLCC_MDMHPFX, 20, 1024, 2, 1, 0x0, 0xf00, 0, 0, 1, 1, 0),
70 SCT_ENTRY(LLCC_MDMPNG, 21, 1024, 0, 1, 0x1e, 0x0, 0, 0, 1, 1, 0),
71 SCT_ENTRY(LLCC_AUDHW, 22, 1024, 1, 1, 0xffc, 0x2, 0, 0, 1, 1, 0),
72};
73
74static int sdm845_qcom_llcc_probe(struct platform_device *pdev)
75{
76 return qcom_llcc_probe(pdev, sdm845_data, ARRAY_SIZE(sdm845_data));
77}
78
79static const struct of_device_id sdm845_qcom_llcc_of_match[] = {
80 { .compatible = "qcom,sdm845-llcc", },
81 { }
82};
83
84static struct platform_driver sdm845_qcom_llcc_driver = {
85 .driver = {
86 .name = "sdm845-llcc",
87 .of_match_table = sdm845_qcom_llcc_of_match,
88 },
89 .probe = sdm845_qcom_llcc_probe,
90};
91module_platform_driver(sdm845_qcom_llcc_driver);
92
93MODULE_DESCRIPTION("QCOM sdm845 LLCC driver");
94MODULE_LICENSE("GPL v2");
diff --git a/drivers/soc/qcom/llcc-slice.c b/drivers/soc/qcom/llcc-slice.c
new file mode 100644
index 000000000000..54063a31132f
--- /dev/null
+++ b/drivers/soc/qcom/llcc-slice.c
@@ -0,0 +1,338 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
4 *
5 */
6
7#include <linux/bitmap.h>
8#include <linux/bitops.h>
9#include <linux/device.h>
10#include <linux/io.h>
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/mutex.h>
14#include <linux/of_device.h>
15#include <linux/regmap.h>
16#include <linux/slab.h>
17#include <linux/soc/qcom/llcc-qcom.h>
18
19#define ACTIVATE BIT(0)
20#define DEACTIVATE BIT(1)
21#define ACT_CTRL_OPCODE_ACTIVATE BIT(0)
22#define ACT_CTRL_OPCODE_DEACTIVATE BIT(1)
23#define ACT_CTRL_ACT_TRIG BIT(0)
24#define ACT_CTRL_OPCODE_SHIFT 0x01
25#define ATTR1_PROBE_TARGET_WAYS_SHIFT 0x02
26#define ATTR1_FIXED_SIZE_SHIFT 0x03
27#define ATTR1_PRIORITY_SHIFT 0x04
28#define ATTR1_MAX_CAP_SHIFT 0x10
29#define ATTR0_RES_WAYS_MASK GENMASK(11, 0)
30#define ATTR0_BONUS_WAYS_MASK GENMASK(27, 16)
31#define ATTR0_BONUS_WAYS_SHIFT 0x10
32#define LLCC_STATUS_READ_DELAY 100
33
34#define CACHE_LINE_SIZE_SHIFT 6
35
36#define LLCC_COMMON_STATUS0 0x0003000c
37#define LLCC_LB_CNT_MASK GENMASK(31, 28)
38#define LLCC_LB_CNT_SHIFT 28
39
40#define MAX_CAP_TO_BYTES(n) (n * SZ_1K)
41#define LLCC_TRP_ACT_CTRLn(n) (n * SZ_4K)
42#define LLCC_TRP_STATUSn(n) (4 + n * SZ_4K)
43#define LLCC_TRP_ATTR0_CFGn(n) (0x21000 + SZ_8 * n)
44#define LLCC_TRP_ATTR1_CFGn(n) (0x21004 + SZ_8 * n)
45
46#define BANK_OFFSET_STRIDE 0x80000
47
48static struct llcc_drv_data *drv_data;
49
50static const struct regmap_config llcc_regmap_config = {
51 .reg_bits = 32,
52 .reg_stride = 4,
53 .val_bits = 32,
54 .fast_io = true,
55};
56
57/**
58 * llcc_slice_getd - get llcc slice descriptor
59 * @uid: usecase_id for the client
60 *
61 * A pointer to llcc slice descriptor will be returned on success and
62 * and error pointer is returned on failure
63 */
64struct llcc_slice_desc *llcc_slice_getd(u32 uid)
65{
66 const struct llcc_slice_config *cfg;
67 struct llcc_slice_desc *desc;
68 u32 sz, count;
69
70 cfg = drv_data->cfg;
71 sz = drv_data->cfg_size;
72
73 for (count = 0; cfg && count < sz; count++, cfg++)
74 if (cfg->usecase_id == uid)
75 break;
76
77 if (count == sz || !cfg)
78 return ERR_PTR(-ENODEV);
79
80 desc = kzalloc(sizeof(*desc), GFP_KERNEL);
81 if (!desc)
82 return ERR_PTR(-ENOMEM);
83
84 desc->slice_id = cfg->slice_id;
85 desc->slice_size = cfg->max_cap;
86
87 return desc;
88}
89EXPORT_SYMBOL_GPL(llcc_slice_getd);
90
91/**
92 * llcc_slice_putd - llcc slice descritpor
93 * @desc: Pointer to llcc slice descriptor
94 */
95void llcc_slice_putd(struct llcc_slice_desc *desc)
96{
97 kfree(desc);
98}
99EXPORT_SYMBOL_GPL(llcc_slice_putd);
100
101static int llcc_update_act_ctrl(u32 sid,
102 u32 act_ctrl_reg_val, u32 status)
103{
104 u32 act_ctrl_reg;
105 u32 status_reg;
106 u32 slice_status;
107 int ret;
108
109 act_ctrl_reg = drv_data->bcast_off + LLCC_TRP_ACT_CTRLn(sid);
110 status_reg = drv_data->bcast_off + LLCC_TRP_STATUSn(sid);
111
112 /* Set the ACTIVE trigger */
113 act_ctrl_reg_val |= ACT_CTRL_ACT_TRIG;
114 ret = regmap_write(drv_data->regmap, act_ctrl_reg, act_ctrl_reg_val);
115 if (ret)
116 return ret;
117
118 /* Clear the ACTIVE trigger */
119 act_ctrl_reg_val &= ~ACT_CTRL_ACT_TRIG;
120 ret = regmap_write(drv_data->regmap, act_ctrl_reg, act_ctrl_reg_val);
121 if (ret)
122 return ret;
123
124 ret = regmap_read_poll_timeout(drv_data->regmap, status_reg,
125 slice_status, !(slice_status & status),
126 0, LLCC_STATUS_READ_DELAY);
127 return ret;
128}
129
130/**
131 * llcc_slice_activate - Activate the llcc slice
132 * @desc: Pointer to llcc slice descriptor
133 *
134 * A value of zero will be returned on success and a negative errno will
135 * be returned in error cases
136 */
137int llcc_slice_activate(struct llcc_slice_desc *desc)
138{
139 int ret;
140 u32 act_ctrl_val;
141
142 mutex_lock(&drv_data->lock);
143 if (test_bit(desc->slice_id, drv_data->bitmap)) {
144 mutex_unlock(&drv_data->lock);
145 return 0;
146 }
147
148 act_ctrl_val = ACT_CTRL_OPCODE_ACTIVATE << ACT_CTRL_OPCODE_SHIFT;
149
150 ret = llcc_update_act_ctrl(desc->slice_id, act_ctrl_val,
151 DEACTIVATE);
152 if (ret) {
153 mutex_unlock(&drv_data->lock);
154 return ret;
155 }
156
157 __set_bit(desc->slice_id, drv_data->bitmap);
158 mutex_unlock(&drv_data->lock);
159
160 return ret;
161}
162EXPORT_SYMBOL_GPL(llcc_slice_activate);
163
164/**
165 * llcc_slice_deactivate - Deactivate the llcc slice
166 * @desc: Pointer to llcc slice descriptor
167 *
168 * A value of zero will be returned on success and a negative errno will
169 * be returned in error cases
170 */
171int llcc_slice_deactivate(struct llcc_slice_desc *desc)
172{
173 u32 act_ctrl_val;
174 int ret;
175
176 mutex_lock(&drv_data->lock);
177 if (!test_bit(desc->slice_id, drv_data->bitmap)) {
178 mutex_unlock(&drv_data->lock);
179 return 0;
180 }
181 act_ctrl_val = ACT_CTRL_OPCODE_DEACTIVATE << ACT_CTRL_OPCODE_SHIFT;
182
183 ret = llcc_update_act_ctrl(desc->slice_id, act_ctrl_val,
184 ACTIVATE);
185 if (ret) {
186 mutex_unlock(&drv_data->lock);
187 return ret;
188 }
189
190 __clear_bit(desc->slice_id, drv_data->bitmap);
191 mutex_unlock(&drv_data->lock);
192
193 return ret;
194}
195EXPORT_SYMBOL_GPL(llcc_slice_deactivate);
196
197/**
198 * llcc_get_slice_id - return the slice id
199 * @desc: Pointer to llcc slice descriptor
200 */
201int llcc_get_slice_id(struct llcc_slice_desc *desc)
202{
203 return desc->slice_id;
204}
205EXPORT_SYMBOL_GPL(llcc_get_slice_id);
206
207/**
208 * llcc_get_slice_size - return the slice id
209 * @desc: Pointer to llcc slice descriptor
210 */
211size_t llcc_get_slice_size(struct llcc_slice_desc *desc)
212{
213 return desc->slice_size;
214}
215EXPORT_SYMBOL_GPL(llcc_get_slice_size);
216
217static int qcom_llcc_cfg_program(struct platform_device *pdev)
218{
219 int i;
220 u32 attr1_cfg;
221 u32 attr0_cfg;
222 u32 attr1_val;
223 u32 attr0_val;
224 u32 max_cap_cacheline;
225 u32 sz;
226 int ret;
227 const struct llcc_slice_config *llcc_table;
228 struct llcc_slice_desc desc;
229 u32 bcast_off = drv_data->bcast_off;
230
231 sz = drv_data->cfg_size;
232 llcc_table = drv_data->cfg;
233
234 for (i = 0; i < sz; i++) {
235 attr1_cfg = bcast_off +
236 LLCC_TRP_ATTR1_CFGn(llcc_table[i].slice_id);
237 attr0_cfg = bcast_off +
238 LLCC_TRP_ATTR0_CFGn(llcc_table[i].slice_id);
239
240 attr1_val = llcc_table[i].cache_mode;
241 attr1_val |= llcc_table[i].probe_target_ways <<
242 ATTR1_PROBE_TARGET_WAYS_SHIFT;
243 attr1_val |= llcc_table[i].fixed_size <<
244 ATTR1_FIXED_SIZE_SHIFT;
245 attr1_val |= llcc_table[i].priority <<
246 ATTR1_PRIORITY_SHIFT;
247
248 max_cap_cacheline = MAX_CAP_TO_BYTES(llcc_table[i].max_cap);
249
250 /* LLCC instances can vary for each target.
251 * The SW writes to broadcast register which gets propagated
252 * to each llcc instace (llcc0,.. llccN).
253 * Since the size of the memory is divided equally amongst the
254 * llcc instances, we need to configure the max cap accordingly.
255 */
256 max_cap_cacheline = max_cap_cacheline / drv_data->num_banks;
257 max_cap_cacheline >>= CACHE_LINE_SIZE_SHIFT;
258 attr1_val |= max_cap_cacheline << ATTR1_MAX_CAP_SHIFT;
259
260 attr0_val = llcc_table[i].res_ways & ATTR0_RES_WAYS_MASK;
261 attr0_val |= llcc_table[i].bonus_ways << ATTR0_BONUS_WAYS_SHIFT;
262
263 ret = regmap_write(drv_data->regmap, attr1_cfg, attr1_val);
264 if (ret)
265 return ret;
266 ret = regmap_write(drv_data->regmap, attr0_cfg, attr0_val);
267 if (ret)
268 return ret;
269 if (llcc_table[i].activate_on_init) {
270 desc.slice_id = llcc_table[i].slice_id;
271 ret = llcc_slice_activate(&desc);
272 }
273 }
274 return ret;
275}
276
277int qcom_llcc_probe(struct platform_device *pdev,
278 const struct llcc_slice_config *llcc_cfg, u32 sz)
279{
280 u32 num_banks;
281 struct device *dev = &pdev->dev;
282 struct resource *res;
283 void __iomem *base;
284 int ret, i;
285
286 drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL);
287 if (!drv_data)
288 return -ENOMEM;
289
290 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
291 base = devm_ioremap_resource(&pdev->dev, res);
292 if (IS_ERR(base))
293 return PTR_ERR(base);
294
295 drv_data->regmap = devm_regmap_init_mmio(dev, base,
296 &llcc_regmap_config);
297 if (IS_ERR(drv_data->regmap))
298 return PTR_ERR(drv_data->regmap);
299
300 ret = regmap_read(drv_data->regmap, LLCC_COMMON_STATUS0,
301 &num_banks);
302 if (ret)
303 return ret;
304
305 num_banks &= LLCC_LB_CNT_MASK;
306 num_banks >>= LLCC_LB_CNT_SHIFT;
307 drv_data->num_banks = num_banks;
308
309 for (i = 0; i < sz; i++)
310 if (llcc_cfg[i].slice_id > drv_data->max_slices)
311 drv_data->max_slices = llcc_cfg[i].slice_id;
312
313 drv_data->offsets = devm_kcalloc(dev, num_banks, sizeof(u32),
314 GFP_KERNEL);
315 if (!drv_data->offsets)
316 return -ENOMEM;
317
318 for (i = 0; i < num_banks; i++)
319 drv_data->offsets[i] = i * BANK_OFFSET_STRIDE;
320
321 drv_data->bcast_off = num_banks * BANK_OFFSET_STRIDE;
322
323 drv_data->bitmap = devm_kcalloc(dev,
324 BITS_TO_LONGS(drv_data->max_slices), sizeof(unsigned long),
325 GFP_KERNEL);
326 if (!drv_data->bitmap)
327 return -ENOMEM;
328
329 drv_data->cfg = llcc_cfg;
330 drv_data->cfg_size = sz;
331 mutex_init(&drv_data->lock);
332 platform_set_drvdata(pdev, drv_data);
333
334 return qcom_llcc_cfg_program(pdev);
335}
336EXPORT_SYMBOL_GPL(qcom_llcc_probe);
337
338MODULE_LICENSE("GPL v2");
diff --git a/drivers/soc/qcom/rmtfs_mem.c b/drivers/soc/qcom/rmtfs_mem.c
index c8999e38b005..8a3678c2e83c 100644
--- a/drivers/soc/qcom/rmtfs_mem.c
+++ b/drivers/soc/qcom/rmtfs_mem.c
@@ -184,6 +184,7 @@ static int qcom_rmtfs_mem_probe(struct platform_device *pdev)
184 device_initialize(&rmtfs_mem->dev); 184 device_initialize(&rmtfs_mem->dev);
185 rmtfs_mem->dev.parent = &pdev->dev; 185 rmtfs_mem->dev.parent = &pdev->dev;
186 rmtfs_mem->dev.groups = qcom_rmtfs_mem_groups; 186 rmtfs_mem->dev.groups = qcom_rmtfs_mem_groups;
187 rmtfs_mem->dev.release = qcom_rmtfs_mem_release_device;
187 188
188 rmtfs_mem->base = devm_memremap(&rmtfs_mem->dev, rmtfs_mem->addr, 189 rmtfs_mem->base = devm_memremap(&rmtfs_mem->dev, rmtfs_mem->addr,
189 rmtfs_mem->size, MEMREMAP_WC); 190 rmtfs_mem->size, MEMREMAP_WC);
@@ -206,8 +207,6 @@ static int qcom_rmtfs_mem_probe(struct platform_device *pdev)
206 goto put_device; 207 goto put_device;
207 } 208 }
208 209
209 rmtfs_mem->dev.release = qcom_rmtfs_mem_release_device;
210
211 ret = of_property_read_u32(node, "qcom,vmid", &vmid); 210 ret = of_property_read_u32(node, "qcom,vmid", &vmid);
212 if (ret < 0 && ret != -EINVAL) { 211 if (ret < 0 && ret != -EINVAL) {
213 dev_err(&pdev->dev, "failed to parse qcom,vmid\n"); 212 dev_err(&pdev->dev, "failed to parse qcom,vmid\n");
diff --git a/drivers/soc/qcom/rpmh-internal.h b/drivers/soc/qcom/rpmh-internal.h
new file mode 100644
index 000000000000..a7bbbb67991c
--- /dev/null
+++ b/drivers/soc/qcom/rpmh-internal.h
@@ -0,0 +1,114 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
4 */
5
6
7#ifndef __RPM_INTERNAL_H__
8#define __RPM_INTERNAL_H__
9
10#include <linux/bitmap.h>
11#include <soc/qcom/tcs.h>
12
13#define TCS_TYPE_NR 4
14#define MAX_CMDS_PER_TCS 16
15#define MAX_TCS_PER_TYPE 3
16#define MAX_TCS_NR (MAX_TCS_PER_TYPE * TCS_TYPE_NR)
17#define MAX_TCS_SLOTS (MAX_CMDS_PER_TCS * MAX_TCS_PER_TYPE)
18
19struct rsc_drv;
20
21/**
22 * struct tcs_group: group of Trigger Command Sets (TCS) to send state requests
23 * to the controller
24 *
25 * @drv: the controller
26 * @type: type of the TCS in this group - active, sleep, wake
27 * @mask: mask of the TCSes relative to all the TCSes in the RSC
28 * @offset: start of the TCS group relative to the TCSes in the RSC
29 * @num_tcs: number of TCSes in this type
30 * @ncpt: number of commands in each TCS
31 * @lock: lock for synchronizing this TCS writes
32 * @req: requests that are sent from the TCS
33 * @cmd_cache: flattened cache of cmds in sleep/wake TCS
34 * @slots: indicates which of @cmd_addr are occupied
35 */
36struct tcs_group {
37 struct rsc_drv *drv;
38 int type;
39 u32 mask;
40 u32 offset;
41 int num_tcs;
42 int ncpt;
43 spinlock_t lock;
44 const struct tcs_request *req[MAX_TCS_PER_TYPE];
45 u32 *cmd_cache;
46 DECLARE_BITMAP(slots, MAX_TCS_SLOTS);
47};
48
49/**
50 * struct rpmh_request: the message to be sent to rpmh-rsc
51 *
52 * @msg: the request
53 * @cmd: the payload that will be part of the @msg
54 * @completion: triggered when request is done
55 * @dev: the device making the request
56 * @err: err return from the controller
57 * @needs_free: check to free dynamically allocated request object
58 */
59struct rpmh_request {
60 struct tcs_request msg;
61 struct tcs_cmd cmd[MAX_RPMH_PAYLOAD];
62 struct completion *completion;
63 const struct device *dev;
64 int err;
65 bool needs_free;
66};
67
68/**
69 * struct rpmh_ctrlr: our representation of the controller
70 *
71 * @cache: the list of cached requests
72 * @cache_lock: synchronize access to the cache data
73 * @dirty: was the cache updated since flush
74 * @batch_cache: Cache sleep and wake requests sent as batch
75 */
76struct rpmh_ctrlr {
77 struct list_head cache;
78 spinlock_t cache_lock;
79 bool dirty;
80 struct list_head batch_cache;
81};
82
83/**
84 * struct rsc_drv: the Direct Resource Voter (DRV) of the
85 * Resource State Coordinator controller (RSC)
86 *
87 * @name: controller identifier
88 * @tcs_base: start address of the TCS registers in this controller
89 * @id: instance id in the controller (Direct Resource Voter)
90 * @num_tcs: number of TCSes in this DRV
91 * @tcs: TCS groups
92 * @tcs_in_use: s/w state of the TCS
93 * @lock: synchronize state of the controller
94 * @client: handle to the DRV's client.
95 */
96struct rsc_drv {
97 const char *name;
98 void __iomem *tcs_base;
99 int id;
100 int num_tcs;
101 struct tcs_group tcs[TCS_TYPE_NR];
102 DECLARE_BITMAP(tcs_in_use, MAX_TCS_NR);
103 spinlock_t lock;
104 struct rpmh_ctrlr client;
105};
106
107int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg);
108int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv,
109 const struct tcs_request *msg);
110int rpmh_rsc_invalidate(struct rsc_drv *drv);
111
112void rpmh_tx_done(const struct tcs_request *msg, int r);
113
114#endif /* __RPM_INTERNAL_H__ */
diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c
new file mode 100644
index 000000000000..ee75da66d64b
--- /dev/null
+++ b/drivers/soc/qcom/rpmh-rsc.c
@@ -0,0 +1,693 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
4 */
5
6#define pr_fmt(fmt) "%s " fmt, KBUILD_MODNAME
7
8#include <linux/atomic.h>
9#include <linux/delay.h>
10#include <linux/interrupt.h>
11#include <linux/io.h>
12#include <linux/kernel.h>
13#include <linux/list.h>
14#include <linux/of.h>
15#include <linux/of_irq.h>
16#include <linux/of_platform.h>
17#include <linux/platform_device.h>
18#include <linux/slab.h>
19#include <linux/spinlock.h>
20
21#include <soc/qcom/cmd-db.h>
22#include <soc/qcom/tcs.h>
23#include <dt-bindings/soc/qcom,rpmh-rsc.h>
24
25#include "rpmh-internal.h"
26
27#define CREATE_TRACE_POINTS
28#include "trace-rpmh.h"
29
30#define RSC_DRV_TCS_OFFSET 672
31#define RSC_DRV_CMD_OFFSET 20
32
33/* DRV Configuration Information Register */
34#define DRV_PRNT_CHLD_CONFIG 0x0C
35#define DRV_NUM_TCS_MASK 0x3F
36#define DRV_NUM_TCS_SHIFT 6
37#define DRV_NCPT_MASK 0x1F
38#define DRV_NCPT_SHIFT 27
39
40/* Register offsets */
41#define RSC_DRV_IRQ_ENABLE 0x00
42#define RSC_DRV_IRQ_STATUS 0x04
43#define RSC_DRV_IRQ_CLEAR 0x08
44#define RSC_DRV_CMD_WAIT_FOR_CMPL 0x10
45#define RSC_DRV_CONTROL 0x14
46#define RSC_DRV_STATUS 0x18
47#define RSC_DRV_CMD_ENABLE 0x1C
48#define RSC_DRV_CMD_MSGID 0x30
49#define RSC_DRV_CMD_ADDR 0x34
50#define RSC_DRV_CMD_DATA 0x38
51#define RSC_DRV_CMD_STATUS 0x3C
52#define RSC_DRV_CMD_RESP_DATA 0x40
53
54#define TCS_AMC_MODE_ENABLE BIT(16)
55#define TCS_AMC_MODE_TRIGGER BIT(24)
56
57/* TCS CMD register bit mask */
58#define CMD_MSGID_LEN 8
59#define CMD_MSGID_RESP_REQ BIT(8)
60#define CMD_MSGID_WRITE BIT(16)
61#define CMD_STATUS_ISSUED BIT(8)
62#define CMD_STATUS_COMPL BIT(16)
63
64static u32 read_tcs_reg(struct rsc_drv *drv, int reg, int tcs_id, int cmd_id)
65{
66 return readl_relaxed(drv->tcs_base + reg + RSC_DRV_TCS_OFFSET * tcs_id +
67 RSC_DRV_CMD_OFFSET * cmd_id);
68}
69
70static void write_tcs_cmd(struct rsc_drv *drv, int reg, int tcs_id, int cmd_id,
71 u32 data)
72{
73 writel_relaxed(data, drv->tcs_base + reg + RSC_DRV_TCS_OFFSET * tcs_id +
74 RSC_DRV_CMD_OFFSET * cmd_id);
75}
76
77static void write_tcs_reg(struct rsc_drv *drv, int reg, int tcs_id, u32 data)
78{
79 writel_relaxed(data, drv->tcs_base + reg + RSC_DRV_TCS_OFFSET * tcs_id);
80}
81
82static void write_tcs_reg_sync(struct rsc_drv *drv, int reg, int tcs_id,
83 u32 data)
84{
85 writel(data, drv->tcs_base + reg + RSC_DRV_TCS_OFFSET * tcs_id);
86 for (;;) {
87 if (data == readl(drv->tcs_base + reg +
88 RSC_DRV_TCS_OFFSET * tcs_id))
89 break;
90 udelay(1);
91 }
92}
93
94static bool tcs_is_free(struct rsc_drv *drv, int tcs_id)
95{
96 return !test_bit(tcs_id, drv->tcs_in_use) &&
97 read_tcs_reg(drv, RSC_DRV_STATUS, tcs_id, 0);
98}
99
100static struct tcs_group *get_tcs_of_type(struct rsc_drv *drv, int type)
101{
102 return &drv->tcs[type];
103}
104
105static int tcs_invalidate(struct rsc_drv *drv, int type)
106{
107 int m;
108 struct tcs_group *tcs;
109
110 tcs = get_tcs_of_type(drv, type);
111
112 spin_lock(&tcs->lock);
113 if (bitmap_empty(tcs->slots, MAX_TCS_SLOTS)) {
114 spin_unlock(&tcs->lock);
115 return 0;
116 }
117
118 for (m = tcs->offset; m < tcs->offset + tcs->num_tcs; m++) {
119 if (!tcs_is_free(drv, m)) {
120 spin_unlock(&tcs->lock);
121 return -EAGAIN;
122 }
123 write_tcs_reg_sync(drv, RSC_DRV_CMD_ENABLE, m, 0);
124 }
125 bitmap_zero(tcs->slots, MAX_TCS_SLOTS);
126 spin_unlock(&tcs->lock);
127
128 return 0;
129}
130
131/**
132 * rpmh_rsc_invalidate - Invalidate sleep and wake TCSes
133 *
134 * @drv: the RSC controller
135 */
136int rpmh_rsc_invalidate(struct rsc_drv *drv)
137{
138 int ret;
139
140 ret = tcs_invalidate(drv, SLEEP_TCS);
141 if (!ret)
142 ret = tcs_invalidate(drv, WAKE_TCS);
143
144 return ret;
145}
146
147static struct tcs_group *get_tcs_for_msg(struct rsc_drv *drv,
148 const struct tcs_request *msg)
149{
150 int type, ret;
151 struct tcs_group *tcs;
152
153 switch (msg->state) {
154 case RPMH_ACTIVE_ONLY_STATE:
155 type = ACTIVE_TCS;
156 break;
157 case RPMH_WAKE_ONLY_STATE:
158 type = WAKE_TCS;
159 break;
160 case RPMH_SLEEP_STATE:
161 type = SLEEP_TCS;
162 break;
163 default:
164 return ERR_PTR(-EINVAL);
165 }
166
167 /*
168 * If we are making an active request on a RSC that does not have a
169 * dedicated TCS for active state use, then re-purpose a wake TCS to
170 * send active votes.
171 * NOTE: The driver must be aware that this RSC does not have a
172 * dedicated AMC, and therefore would invalidate the sleep and wake
173 * TCSes before making an active state request.
174 */
175 tcs = get_tcs_of_type(drv, type);
176 if (msg->state == RPMH_ACTIVE_ONLY_STATE && !tcs->num_tcs) {
177 tcs = get_tcs_of_type(drv, WAKE_TCS);
178 if (tcs->num_tcs) {
179 ret = rpmh_rsc_invalidate(drv);
180 if (ret)
181 return ERR_PTR(ret);
182 }
183 }
184
185 return tcs;
186}
187
188static const struct tcs_request *get_req_from_tcs(struct rsc_drv *drv,
189 int tcs_id)
190{
191 struct tcs_group *tcs;
192 int i;
193
194 for (i = 0; i < TCS_TYPE_NR; i++) {
195 tcs = &drv->tcs[i];
196 if (tcs->mask & BIT(tcs_id))
197 return tcs->req[tcs_id - tcs->offset];
198 }
199
200 return NULL;
201}
202
203/**
204 * tcs_tx_done: TX Done interrupt handler
205 */
206static irqreturn_t tcs_tx_done(int irq, void *p)
207{
208 struct rsc_drv *drv = p;
209 int i, j, err = 0;
210 unsigned long irq_status;
211 const struct tcs_request *req;
212 struct tcs_cmd *cmd;
213
214 irq_status = read_tcs_reg(drv, RSC_DRV_IRQ_STATUS, 0, 0);
215
216 for_each_set_bit(i, &irq_status, BITS_PER_LONG) {
217 req = get_req_from_tcs(drv, i);
218 if (!req) {
219 WARN_ON(1);
220 goto skip;
221 }
222
223 err = 0;
224 for (j = 0; j < req->num_cmds; j++) {
225 u32 sts;
226
227 cmd = &req->cmds[j];
228 sts = read_tcs_reg(drv, RSC_DRV_CMD_STATUS, i, j);
229 if (!(sts & CMD_STATUS_ISSUED) ||
230 ((req->wait_for_compl || cmd->wait) &&
231 !(sts & CMD_STATUS_COMPL))) {
232 pr_err("Incomplete request: %s: addr=%#x data=%#x",
233 drv->name, cmd->addr, cmd->data);
234 err = -EIO;
235 }
236 }
237
238 trace_rpmh_tx_done(drv, i, req, err);
239skip:
240 /* Reclaim the TCS */
241 write_tcs_reg(drv, RSC_DRV_CMD_ENABLE, i, 0);
242 write_tcs_reg(drv, RSC_DRV_IRQ_CLEAR, 0, BIT(i));
243 spin_lock(&drv->lock);
244 clear_bit(i, drv->tcs_in_use);
245 spin_unlock(&drv->lock);
246 if (req)
247 rpmh_tx_done(req, err);
248 }
249
250 return IRQ_HANDLED;
251}
252
253static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id,
254 const struct tcs_request *msg)
255{
256 u32 msgid, cmd_msgid;
257 u32 cmd_enable = 0;
258 u32 cmd_complete;
259 struct tcs_cmd *cmd;
260 int i, j;
261
262 cmd_msgid = CMD_MSGID_LEN;
263 cmd_msgid |= msg->wait_for_compl ? CMD_MSGID_RESP_REQ : 0;
264 cmd_msgid |= CMD_MSGID_WRITE;
265
266 cmd_complete = read_tcs_reg(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, tcs_id, 0);
267
268 for (i = 0, j = cmd_id; i < msg->num_cmds; i++, j++) {
269 cmd = &msg->cmds[i];
270 cmd_enable |= BIT(j);
271 cmd_complete |= cmd->wait << j;
272 msgid = cmd_msgid;
273 msgid |= cmd->wait ? CMD_MSGID_RESP_REQ : 0;
274
275 write_tcs_cmd(drv, RSC_DRV_CMD_MSGID, tcs_id, j, msgid);
276 write_tcs_cmd(drv, RSC_DRV_CMD_ADDR, tcs_id, j, cmd->addr);
277 write_tcs_cmd(drv, RSC_DRV_CMD_DATA, tcs_id, j, cmd->data);
278 trace_rpmh_send_msg(drv, tcs_id, j, msgid, cmd);
279 }
280
281 write_tcs_reg(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, tcs_id, cmd_complete);
282 cmd_enable |= read_tcs_reg(drv, RSC_DRV_CMD_ENABLE, tcs_id, 0);
283 write_tcs_reg(drv, RSC_DRV_CMD_ENABLE, tcs_id, cmd_enable);
284}
285
286static void __tcs_trigger(struct rsc_drv *drv, int tcs_id)
287{
288 u32 enable;
289
290 /*
291 * HW req: Clear the DRV_CONTROL and enable TCS again
292 * While clearing ensure that the AMC mode trigger is cleared
293 * and then the mode enable is cleared.
294 */
295 enable = read_tcs_reg(drv, RSC_DRV_CONTROL, tcs_id, 0);
296 enable &= ~TCS_AMC_MODE_TRIGGER;
297 write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
298 enable &= ~TCS_AMC_MODE_ENABLE;
299 write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
300
301 /* Enable the AMC mode on the TCS and then trigger the TCS */
302 enable = TCS_AMC_MODE_ENABLE;
303 write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
304 enable |= TCS_AMC_MODE_TRIGGER;
305 write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
306}
307
308static int check_for_req_inflight(struct rsc_drv *drv, struct tcs_group *tcs,
309 const struct tcs_request *msg)
310{
311 unsigned long curr_enabled;
312 u32 addr;
313 int i, j, k;
314 int tcs_id = tcs->offset;
315
316 for (i = 0; i < tcs->num_tcs; i++, tcs_id++) {
317 if (tcs_is_free(drv, tcs_id))
318 continue;
319
320 curr_enabled = read_tcs_reg(drv, RSC_DRV_CMD_ENABLE, tcs_id, 0);
321
322 for_each_set_bit(j, &curr_enabled, MAX_CMDS_PER_TCS) {
323 addr = read_tcs_reg(drv, RSC_DRV_CMD_ADDR, tcs_id, j);
324 for (k = 0; k < msg->num_cmds; k++) {
325 if (addr == msg->cmds[k].addr)
326 return -EBUSY;
327 }
328 }
329 }
330
331 return 0;
332}
333
334static int find_free_tcs(struct tcs_group *tcs)
335{
336 int i;
337
338 for (i = 0; i < tcs->num_tcs; i++) {
339 if (tcs_is_free(tcs->drv, tcs->offset + i))
340 return tcs->offset + i;
341 }
342
343 return -EBUSY;
344}
345
346static int tcs_write(struct rsc_drv *drv, const struct tcs_request *msg)
347{
348 struct tcs_group *tcs;
349 int tcs_id;
350 unsigned long flags;
351 int ret;
352
353 tcs = get_tcs_for_msg(drv, msg);
354 if (IS_ERR(tcs))
355 return PTR_ERR(tcs);
356
357 spin_lock_irqsave(&tcs->lock, flags);
358 spin_lock(&drv->lock);
359 /*
360 * The h/w does not like if we send a request to the same address,
361 * when one is already in-flight or being processed.
362 */
363 ret = check_for_req_inflight(drv, tcs, msg);
364 if (ret) {
365 spin_unlock(&drv->lock);
366 goto done_write;
367 }
368
369 tcs_id = find_free_tcs(tcs);
370 if (tcs_id < 0) {
371 ret = tcs_id;
372 spin_unlock(&drv->lock);
373 goto done_write;
374 }
375
376 tcs->req[tcs_id - tcs->offset] = msg;
377 set_bit(tcs_id, drv->tcs_in_use);
378 spin_unlock(&drv->lock);
379
380 __tcs_buffer_write(drv, tcs_id, 0, msg);
381 __tcs_trigger(drv, tcs_id);
382
383done_write:
384 spin_unlock_irqrestore(&tcs->lock, flags);
385 return ret;
386}
387
388/**
389 * rpmh_rsc_send_data: Validate the incoming message and write to the
390 * appropriate TCS block.
391 *
392 * @drv: the controller
393 * @msg: the data to be sent
394 *
395 * Return: 0 on success, -EINVAL on error.
396 * Note: This call blocks until a valid data is written to the TCS.
397 */
398int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg)
399{
400 int ret;
401
402 if (!msg || !msg->cmds || !msg->num_cmds ||
403 msg->num_cmds > MAX_RPMH_PAYLOAD) {
404 WARN_ON(1);
405 return -EINVAL;
406 }
407
408 do {
409 ret = tcs_write(drv, msg);
410 if (ret == -EBUSY) {
411 pr_info_ratelimited("TCS Busy, retrying RPMH message send: addr=%#x\n",
412 msg->cmds[0].addr);
413 udelay(10);
414 }
415 } while (ret == -EBUSY);
416
417 return ret;
418}
419
420static int find_match(const struct tcs_group *tcs, const struct tcs_cmd *cmd,
421 int len)
422{
423 int i, j;
424
425 /* Check for already cached commands */
426 for_each_set_bit(i, tcs->slots, MAX_TCS_SLOTS) {
427 if (tcs->cmd_cache[i] != cmd[0].addr)
428 continue;
429 if (i + len >= tcs->num_tcs * tcs->ncpt)
430 goto seq_err;
431 for (j = 0; j < len; j++) {
432 if (tcs->cmd_cache[i + j] != cmd[j].addr)
433 goto seq_err;
434 }
435 return i;
436 }
437
438 return -ENODATA;
439
440seq_err:
441 WARN(1, "Message does not match previous sequence.\n");
442 return -EINVAL;
443}
444
445static int find_slots(struct tcs_group *tcs, const struct tcs_request *msg,
446 int *tcs_id, int *cmd_id)
447{
448 int slot, offset;
449 int i = 0;
450
451 /* Find if we already have the msg in our TCS */
452 slot = find_match(tcs, msg->cmds, msg->num_cmds);
453 if (slot >= 0)
454 goto copy_data;
455
456 /* Do over, until we can fit the full payload in a TCS */
457 do {
458 slot = bitmap_find_next_zero_area(tcs->slots, MAX_TCS_SLOTS,
459 i, msg->num_cmds, 0);
460 if (slot == tcs->num_tcs * tcs->ncpt)
461 return -ENOMEM;
462 i += tcs->ncpt;
463 } while (slot + msg->num_cmds - 1 >= i);
464
465copy_data:
466 bitmap_set(tcs->slots, slot, msg->num_cmds);
467 /* Copy the addresses of the resources over to the slots */
468 for (i = 0; i < msg->num_cmds; i++)
469 tcs->cmd_cache[slot + i] = msg->cmds[i].addr;
470
471 offset = slot / tcs->ncpt;
472 *tcs_id = offset + tcs->offset;
473 *cmd_id = slot % tcs->ncpt;
474
475 return 0;
476}
477
478static int tcs_ctrl_write(struct rsc_drv *drv, const struct tcs_request *msg)
479{
480 struct tcs_group *tcs;
481 int tcs_id = 0, cmd_id = 0;
482 unsigned long flags;
483 int ret;
484
485 tcs = get_tcs_for_msg(drv, msg);
486 if (IS_ERR(tcs))
487 return PTR_ERR(tcs);
488
489 spin_lock_irqsave(&tcs->lock, flags);
490 /* find the TCS id and the command in the TCS to write to */
491 ret = find_slots(tcs, msg, &tcs_id, &cmd_id);
492 if (!ret)
493 __tcs_buffer_write(drv, tcs_id, cmd_id, msg);
494 spin_unlock_irqrestore(&tcs->lock, flags);
495
496 return ret;
497}
498
499/**
500 * rpmh_rsc_write_ctrl_data: Write request to the controller
501 *
502 * @drv: the controller
503 * @msg: the data to be written to the controller
504 *
505 * There is no response returned for writing the request to the controller.
506 */
507int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv, const struct tcs_request *msg)
508{
509 if (!msg || !msg->cmds || !msg->num_cmds ||
510 msg->num_cmds > MAX_RPMH_PAYLOAD) {
511 pr_err("Payload error\n");
512 return -EINVAL;
513 }
514
515 /* Data sent to this API will not be sent immediately */
516 if (msg->state == RPMH_ACTIVE_ONLY_STATE)
517 return -EINVAL;
518
519 return tcs_ctrl_write(drv, msg);
520}
521
522static int rpmh_probe_tcs_config(struct platform_device *pdev,
523 struct rsc_drv *drv)
524{
525 struct tcs_type_config {
526 u32 type;
527 u32 n;
528 } tcs_cfg[TCS_TYPE_NR] = { { 0 } };
529 struct device_node *dn = pdev->dev.of_node;
530 u32 config, max_tcs, ncpt, offset;
531 int i, ret, n, st = 0;
532 struct tcs_group *tcs;
533 struct resource *res;
534 void __iomem *base;
535 char drv_id[10] = {0};
536
537 snprintf(drv_id, ARRAY_SIZE(drv_id), "drv-%d", drv->id);
538 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, drv_id);
539 base = devm_ioremap_resource(&pdev->dev, res);
540 if (IS_ERR(base))
541 return PTR_ERR(base);
542
543 ret = of_property_read_u32(dn, "qcom,tcs-offset", &offset);
544 if (ret)
545 return ret;
546 drv->tcs_base = base + offset;
547
548 config = readl_relaxed(base + DRV_PRNT_CHLD_CONFIG);
549
550 max_tcs = config;
551 max_tcs &= DRV_NUM_TCS_MASK << (DRV_NUM_TCS_SHIFT * drv->id);
552 max_tcs = max_tcs >> (DRV_NUM_TCS_SHIFT * drv->id);
553
554 ncpt = config & (DRV_NCPT_MASK << DRV_NCPT_SHIFT);
555 ncpt = ncpt >> DRV_NCPT_SHIFT;
556
557 n = of_property_count_u32_elems(dn, "qcom,tcs-config");
558 if (n != 2 * TCS_TYPE_NR)
559 return -EINVAL;
560
561 for (i = 0; i < TCS_TYPE_NR; i++) {
562 ret = of_property_read_u32_index(dn, "qcom,tcs-config",
563 i * 2, &tcs_cfg[i].type);
564 if (ret)
565 return ret;
566 if (tcs_cfg[i].type >= TCS_TYPE_NR)
567 return -EINVAL;
568
569 ret = of_property_read_u32_index(dn, "qcom,tcs-config",
570 i * 2 + 1, &tcs_cfg[i].n);
571 if (ret)
572 return ret;
573 if (tcs_cfg[i].n > MAX_TCS_PER_TYPE)
574 return -EINVAL;
575 }
576
577 for (i = 0; i < TCS_TYPE_NR; i++) {
578 tcs = &drv->tcs[tcs_cfg[i].type];
579 if (tcs->drv)
580 return -EINVAL;
581 tcs->drv = drv;
582 tcs->type = tcs_cfg[i].type;
583 tcs->num_tcs = tcs_cfg[i].n;
584 tcs->ncpt = ncpt;
585 spin_lock_init(&tcs->lock);
586
587 if (!tcs->num_tcs || tcs->type == CONTROL_TCS)
588 continue;
589
590 if (st + tcs->num_tcs > max_tcs ||
591 st + tcs->num_tcs >= BITS_PER_BYTE * sizeof(tcs->mask))
592 return -EINVAL;
593
594 tcs->mask = ((1 << tcs->num_tcs) - 1) << st;
595 tcs->offset = st;
596 st += tcs->num_tcs;
597
598 /*
599 * Allocate memory to cache sleep and wake requests to
600 * avoid reading TCS register memory.
601 */
602 if (tcs->type == ACTIVE_TCS)
603 continue;
604
605 tcs->cmd_cache = devm_kcalloc(&pdev->dev,
606 tcs->num_tcs * ncpt, sizeof(u32),
607 GFP_KERNEL);
608 if (!tcs->cmd_cache)
609 return -ENOMEM;
610 }
611
612 drv->num_tcs = st;
613
614 return 0;
615}
616
617static int rpmh_rsc_probe(struct platform_device *pdev)
618{
619 struct device_node *dn = pdev->dev.of_node;
620 struct rsc_drv *drv;
621 int ret, irq;
622
623 /*
624 * Even though RPMh doesn't directly use cmd-db, all of its children
625 * do. To avoid adding this check to our children we'll do it now.
626 */
627 ret = cmd_db_ready();
628 if (ret) {
629 if (ret != -EPROBE_DEFER)
630 dev_err(&pdev->dev, "Command DB not available (%d)\n",
631 ret);
632 return ret;
633 }
634
635 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
636 if (!drv)
637 return -ENOMEM;
638
639 ret = of_property_read_u32(dn, "qcom,drv-id", &drv->id);
640 if (ret)
641 return ret;
642
643 drv->name = of_get_property(dn, "label", NULL);
644 if (!drv->name)
645 drv->name = dev_name(&pdev->dev);
646
647 ret = rpmh_probe_tcs_config(pdev, drv);
648 if (ret)
649 return ret;
650
651 spin_lock_init(&drv->lock);
652 bitmap_zero(drv->tcs_in_use, MAX_TCS_NR);
653
654 irq = platform_get_irq(pdev, drv->id);
655 if (irq < 0)
656 return irq;
657
658 ret = devm_request_irq(&pdev->dev, irq, tcs_tx_done,
659 IRQF_TRIGGER_HIGH | IRQF_NO_SUSPEND,
660 drv->name, drv);
661 if (ret)
662 return ret;
663
664 /* Enable the active TCS to send requests immediately */
665 write_tcs_reg(drv, RSC_DRV_IRQ_ENABLE, 0, drv->tcs[ACTIVE_TCS].mask);
666
667 spin_lock_init(&drv->client.cache_lock);
668 INIT_LIST_HEAD(&drv->client.cache);
669 INIT_LIST_HEAD(&drv->client.batch_cache);
670
671 dev_set_drvdata(&pdev->dev, drv);
672
673 return devm_of_platform_populate(&pdev->dev);
674}
675
676static const struct of_device_id rpmh_drv_match[] = {
677 { .compatible = "qcom,rpmh-rsc", },
678 { }
679};
680
681static struct platform_driver rpmh_driver = {
682 .probe = rpmh_rsc_probe,
683 .driver = {
684 .name = "rpmh",
685 .of_match_table = rpmh_drv_match,
686 },
687};
688
689static int __init rpmh_driver_init(void)
690{
691 return platform_driver_register(&rpmh_driver);
692}
693arch_initcall(rpmh_driver_init);
diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c
new file mode 100644
index 000000000000..c7beb6841289
--- /dev/null
+++ b/drivers/soc/qcom/rpmh.c
@@ -0,0 +1,513 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
4 */
5
6#include <linux/atomic.h>
7#include <linux/bug.h>
8#include <linux/interrupt.h>
9#include <linux/jiffies.h>
10#include <linux/kernel.h>
11#include <linux/list.h>
12#include <linux/module.h>
13#include <linux/of.h>
14#include <linux/platform_device.h>
15#include <linux/slab.h>
16#include <linux/spinlock.h>
17#include <linux/types.h>
18#include <linux/wait.h>
19
20#include <soc/qcom/rpmh.h>
21
22#include "rpmh-internal.h"
23
24#define RPMH_TIMEOUT_MS msecs_to_jiffies(10000)
25
26#define DEFINE_RPMH_MSG_ONSTACK(dev, s, q, name) \
27 struct rpmh_request name = { \
28 .msg = { \
29 .state = s, \
30 .cmds = name.cmd, \
31 .num_cmds = 0, \
32 .wait_for_compl = true, \
33 }, \
34 .cmd = { { 0 } }, \
35 .completion = q, \
36 .dev = dev, \
37 .needs_free = false, \
38 }
39
40#define ctrlr_to_drv(ctrlr) container_of(ctrlr, struct rsc_drv, client)
41
42/**
43 * struct cache_req: the request object for caching
44 *
45 * @addr: the address of the resource
46 * @sleep_val: the sleep vote
47 * @wake_val: the wake vote
48 * @list: linked list obj
49 */
50struct cache_req {
51 u32 addr;
52 u32 sleep_val;
53 u32 wake_val;
54 struct list_head list;
55};
56
57/**
58 * struct batch_cache_req - An entry in our batch catch
59 *
60 * @list: linked list obj
61 * @count: number of messages
62 * @rpm_msgs: the messages
63 */
64
65struct batch_cache_req {
66 struct list_head list;
67 int count;
68 struct rpmh_request rpm_msgs[];
69};
70
71static struct rpmh_ctrlr *get_rpmh_ctrlr(const struct device *dev)
72{
73 struct rsc_drv *drv = dev_get_drvdata(dev->parent);
74
75 return &drv->client;
76}
77
78void rpmh_tx_done(const struct tcs_request *msg, int r)
79{
80 struct rpmh_request *rpm_msg = container_of(msg, struct rpmh_request,
81 msg);
82 struct completion *compl = rpm_msg->completion;
83
84 rpm_msg->err = r;
85
86 if (r)
87 dev_err(rpm_msg->dev, "RPMH TX fail in msg addr=%#x, err=%d\n",
88 rpm_msg->msg.cmds[0].addr, r);
89
90 if (!compl)
91 goto exit;
92
93 /* Signal the blocking thread we are done */
94 complete(compl);
95
96exit:
97 if (rpm_msg->needs_free)
98 kfree(rpm_msg);
99}
100
101static struct cache_req *__find_req(struct rpmh_ctrlr *ctrlr, u32 addr)
102{
103 struct cache_req *p, *req = NULL;
104
105 list_for_each_entry(p, &ctrlr->cache, list) {
106 if (p->addr == addr) {
107 req = p;
108 break;
109 }
110 }
111
112 return req;
113}
114
115static struct cache_req *cache_rpm_request(struct rpmh_ctrlr *ctrlr,
116 enum rpmh_state state,
117 struct tcs_cmd *cmd)
118{
119 struct cache_req *req;
120 unsigned long flags;
121
122 spin_lock_irqsave(&ctrlr->cache_lock, flags);
123 req = __find_req(ctrlr, cmd->addr);
124 if (req)
125 goto existing;
126
127 req = kzalloc(sizeof(*req), GFP_ATOMIC);
128 if (!req) {
129 req = ERR_PTR(-ENOMEM);
130 goto unlock;
131 }
132
133 req->addr = cmd->addr;
134 req->sleep_val = req->wake_val = UINT_MAX;
135 INIT_LIST_HEAD(&req->list);
136 list_add_tail(&req->list, &ctrlr->cache);
137
138existing:
139 switch (state) {
140 case RPMH_ACTIVE_ONLY_STATE:
141 if (req->sleep_val != UINT_MAX)
142 req->wake_val = cmd->data;
143 break;
144 case RPMH_WAKE_ONLY_STATE:
145 req->wake_val = cmd->data;
146 break;
147 case RPMH_SLEEP_STATE:
148 req->sleep_val = cmd->data;
149 break;
150 default:
151 break;
152 }
153
154 ctrlr->dirty = true;
155unlock:
156 spin_unlock_irqrestore(&ctrlr->cache_lock, flags);
157
158 return req;
159}
160
161/**
162 * __rpmh_write: Cache and send the RPMH request
163 *
164 * @dev: The device making the request
165 * @state: Active/Sleep request type
166 * @rpm_msg: The data that needs to be sent (cmds).
167 *
168 * Cache the RPMH request and send if the state is ACTIVE_ONLY.
169 * SLEEP/WAKE_ONLY requests are not sent to the controller at
170 * this time. Use rpmh_flush() to send them to the controller.
171 */
172static int __rpmh_write(const struct device *dev, enum rpmh_state state,
173 struct rpmh_request *rpm_msg)
174{
175 struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev);
176 int ret = -EINVAL;
177 struct cache_req *req;
178 int i;
179
180 rpm_msg->msg.state = state;
181
182 /* Cache the request in our store and link the payload */
183 for (i = 0; i < rpm_msg->msg.num_cmds; i++) {
184 req = cache_rpm_request(ctrlr, state, &rpm_msg->msg.cmds[i]);
185 if (IS_ERR(req))
186 return PTR_ERR(req);
187 }
188
189 rpm_msg->msg.state = state;
190
191 if (state == RPMH_ACTIVE_ONLY_STATE) {
192 WARN_ON(irqs_disabled());
193 ret = rpmh_rsc_send_data(ctrlr_to_drv(ctrlr), &rpm_msg->msg);
194 } else {
195 ret = rpmh_rsc_write_ctrl_data(ctrlr_to_drv(ctrlr),
196 &rpm_msg->msg);
197 /* Clean up our call by spoofing tx_done */
198 rpmh_tx_done(&rpm_msg->msg, ret);
199 }
200
201 return ret;
202}
203
204static int __fill_rpmh_msg(struct rpmh_request *req, enum rpmh_state state,
205 const struct tcs_cmd *cmd, u32 n)
206{
207 if (!cmd || !n || n > MAX_RPMH_PAYLOAD)
208 return -EINVAL;
209
210 memcpy(req->cmd, cmd, n * sizeof(*cmd));
211
212 req->msg.state = state;
213 req->msg.cmds = req->cmd;
214 req->msg.num_cmds = n;
215
216 return 0;
217}
218
219/**
220 * rpmh_write_async: Write a set of RPMH commands
221 *
222 * @dev: The device making the request
223 * @state: Active/sleep set
224 * @cmd: The payload data
225 * @n: The number of elements in payload
226 *
227 * Write a set of RPMH commands, the order of commands is maintained
228 * and will be sent as a single shot.
229 */
230int rpmh_write_async(const struct device *dev, enum rpmh_state state,
231 const struct tcs_cmd *cmd, u32 n)
232{
233 struct rpmh_request *rpm_msg;
234 int ret;
235
236 rpm_msg = kzalloc(sizeof(*rpm_msg), GFP_ATOMIC);
237 if (!rpm_msg)
238 return -ENOMEM;
239 rpm_msg->needs_free = true;
240
241 ret = __fill_rpmh_msg(rpm_msg, state, cmd, n);
242 if (ret) {
243 kfree(rpm_msg);
244 return ret;
245 }
246
247 return __rpmh_write(dev, state, rpm_msg);
248}
249EXPORT_SYMBOL(rpmh_write_async);
250
251/**
252 * rpmh_write: Write a set of RPMH commands and block until response
253 *
254 * @rc: The RPMH handle got from rpmh_get_client
255 * @state: Active/sleep set
256 * @cmd: The payload data
257 * @n: The number of elements in @cmd
258 *
259 * May sleep. Do not call from atomic contexts.
260 */
261int rpmh_write(const struct device *dev, enum rpmh_state state,
262 const struct tcs_cmd *cmd, u32 n)
263{
264 DECLARE_COMPLETION_ONSTACK(compl);
265 DEFINE_RPMH_MSG_ONSTACK(dev, state, &compl, rpm_msg);
266 int ret;
267
268 if (!cmd || !n || n > MAX_RPMH_PAYLOAD)
269 return -EINVAL;
270
271 memcpy(rpm_msg.cmd, cmd, n * sizeof(*cmd));
272 rpm_msg.msg.num_cmds = n;
273
274 ret = __rpmh_write(dev, state, &rpm_msg);
275 if (ret)
276 return ret;
277
278 ret = wait_for_completion_timeout(&compl, RPMH_TIMEOUT_MS);
279 WARN_ON(!ret);
280 return (ret > 0) ? 0 : -ETIMEDOUT;
281}
282EXPORT_SYMBOL(rpmh_write);
283
284static void cache_batch(struct rpmh_ctrlr *ctrlr, struct batch_cache_req *req)
285{
286 unsigned long flags;
287
288 spin_lock_irqsave(&ctrlr->cache_lock, flags);
289 list_add_tail(&req->list, &ctrlr->batch_cache);
290 spin_unlock_irqrestore(&ctrlr->cache_lock, flags);
291}
292
293static int flush_batch(struct rpmh_ctrlr *ctrlr)
294{
295 struct batch_cache_req *req;
296 const struct rpmh_request *rpm_msg;
297 unsigned long flags;
298 int ret = 0;
299 int i;
300
301 /* Send Sleep/Wake requests to the controller, expect no response */
302 spin_lock_irqsave(&ctrlr->cache_lock, flags);
303 list_for_each_entry(req, &ctrlr->batch_cache, list) {
304 for (i = 0; i < req->count; i++) {
305 rpm_msg = req->rpm_msgs + i;
306 ret = rpmh_rsc_write_ctrl_data(ctrlr_to_drv(ctrlr),
307 &rpm_msg->msg);
308 if (ret)
309 break;
310 }
311 }
312 spin_unlock_irqrestore(&ctrlr->cache_lock, flags);
313
314 return ret;
315}
316
317static void invalidate_batch(struct rpmh_ctrlr *ctrlr)
318{
319 struct batch_cache_req *req, *tmp;
320 unsigned long flags;
321
322 spin_lock_irqsave(&ctrlr->cache_lock, flags);
323 list_for_each_entry_safe(req, tmp, &ctrlr->batch_cache, list)
324 kfree(req);
325 INIT_LIST_HEAD(&ctrlr->batch_cache);
326 spin_unlock_irqrestore(&ctrlr->cache_lock, flags);
327}
328
329/**
330 * rpmh_write_batch: Write multiple sets of RPMH commands and wait for the
331 * batch to finish.
332 *
333 * @dev: the device making the request
334 * @state: Active/sleep set
335 * @cmd: The payload data
336 * @n: The array of count of elements in each batch, 0 terminated.
337 *
338 * Write a request to the RSC controller without caching. If the request
339 * state is ACTIVE, then the requests are treated as completion request
340 * and sent to the controller immediately. The function waits until all the
341 * commands are complete. If the request was to SLEEP or WAKE_ONLY, then the
342 * request is sent as fire-n-forget and no ack is expected.
343 *
344 * May sleep. Do not call from atomic contexts for ACTIVE_ONLY requests.
345 */
346int rpmh_write_batch(const struct device *dev, enum rpmh_state state,
347 const struct tcs_cmd *cmd, u32 *n)
348{
349 struct batch_cache_req *req;
350 struct rpmh_request *rpm_msgs;
351 DECLARE_COMPLETION_ONSTACK(compl);
352 struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev);
353 unsigned long time_left;
354 int count = 0;
355 int ret, i, j;
356
357 if (!cmd || !n)
358 return -EINVAL;
359
360 while (n[count] > 0)
361 count++;
362 if (!count)
363 return -EINVAL;
364
365 req = kzalloc(sizeof(*req) + count * sizeof(req->rpm_msgs[0]),
366 GFP_ATOMIC);
367 if (!req)
368 return -ENOMEM;
369 req->count = count;
370 rpm_msgs = req->rpm_msgs;
371
372 for (i = 0; i < count; i++) {
373 __fill_rpmh_msg(rpm_msgs + i, state, cmd, n[i]);
374 cmd += n[i];
375 }
376
377 if (state != RPMH_ACTIVE_ONLY_STATE) {
378 cache_batch(ctrlr, req);
379 return 0;
380 }
381
382 for (i = 0; i < count; i++) {
383 rpm_msgs[i].completion = &compl;
384 ret = rpmh_rsc_send_data(ctrlr_to_drv(ctrlr), &rpm_msgs[i].msg);
385 if (ret) {
386 pr_err("Error(%d) sending RPMH message addr=%#x\n",
387 ret, rpm_msgs[i].msg.cmds[0].addr);
388 for (j = i; j < count; j++)
389 rpmh_tx_done(&rpm_msgs[j].msg, ret);
390 break;
391 }
392 }
393
394 time_left = RPMH_TIMEOUT_MS;
395 for (i = 0; i < count; i++) {
396 time_left = wait_for_completion_timeout(&compl, time_left);
397 if (!time_left) {
398 /*
399 * Better hope they never finish because they'll signal
400 * the completion on our stack and that's bad once
401 * we've returned from the function.
402 */
403 WARN_ON(1);
404 ret = -ETIMEDOUT;
405 goto exit;
406 }
407 }
408
409exit:
410 kfree(req);
411
412 return ret;
413}
414EXPORT_SYMBOL(rpmh_write_batch);
415
416static int is_req_valid(struct cache_req *req)
417{
418 return (req->sleep_val != UINT_MAX &&
419 req->wake_val != UINT_MAX &&
420 req->sleep_val != req->wake_val);
421}
422
423static int send_single(const struct device *dev, enum rpmh_state state,
424 u32 addr, u32 data)
425{
426 DEFINE_RPMH_MSG_ONSTACK(dev, state, NULL, rpm_msg);
427 struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev);
428
429 /* Wake sets are always complete and sleep sets are not */
430 rpm_msg.msg.wait_for_compl = (state == RPMH_WAKE_ONLY_STATE);
431 rpm_msg.cmd[0].addr = addr;
432 rpm_msg.cmd[0].data = data;
433 rpm_msg.msg.num_cmds = 1;
434
435 return rpmh_rsc_write_ctrl_data(ctrlr_to_drv(ctrlr), &rpm_msg.msg);
436}
437
438/**
439 * rpmh_flush: Flushes the buffered active and sleep sets to TCS
440 *
441 * @dev: The device making the request
442 *
443 * Return: -EBUSY if the controller is busy, probably waiting on a response
444 * to a RPMH request sent earlier.
445 *
446 * This function is always called from the sleep code from the last CPU
447 * that is powering down the entire system. Since no other RPMH API would be
448 * executing at this time, it is safe to run lockless.
449 */
450int rpmh_flush(const struct device *dev)
451{
452 struct cache_req *p;
453 struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev);
454 int ret;
455
456 if (!ctrlr->dirty) {
457 pr_debug("Skipping flush, TCS has latest data.\n");
458 return 0;
459 }
460
461 /* First flush the cached batch requests */
462 ret = flush_batch(ctrlr);
463 if (ret)
464 return ret;
465
466 /*
467 * Nobody else should be calling this function other than system PM,
468 * hence we can run without locks.
469 */
470 list_for_each_entry(p, &ctrlr->cache, list) {
471 if (!is_req_valid(p)) {
472 pr_debug("%s: skipping RPMH req: a:%#x s:%#x w:%#x",
473 __func__, p->addr, p->sleep_val, p->wake_val);
474 continue;
475 }
476 ret = send_single(dev, RPMH_SLEEP_STATE, p->addr, p->sleep_val);
477 if (ret)
478 return ret;
479 ret = send_single(dev, RPMH_WAKE_ONLY_STATE,
480 p->addr, p->wake_val);
481 if (ret)
482 return ret;
483 }
484
485 ctrlr->dirty = false;
486
487 return 0;
488}
489EXPORT_SYMBOL(rpmh_flush);
490
491/**
492 * rpmh_invalidate: Invalidate all sleep and active sets
493 * sets.
494 *
495 * @dev: The device making the request
496 *
497 * Invalidate the sleep and active values in the TCS blocks.
498 */
499int rpmh_invalidate(const struct device *dev)
500{
501 struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev);
502 int ret;
503
504 invalidate_batch(ctrlr);
505 ctrlr->dirty = true;
506
507 do {
508 ret = rpmh_rsc_invalidate(ctrlr_to_drv(ctrlr));
509 } while (ret == -EAGAIN);
510
511 return ret;
512}
513EXPORT_SYMBOL(rpmh_invalidate);
diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
index 70b2ee80d6bd..bf4bd71ab53f 100644
--- a/drivers/soc/qcom/smem.c
+++ b/drivers/soc/qcom/smem.c
@@ -364,11 +364,6 @@ static int qcom_smem_alloc_private(struct qcom_smem *smem,
364 end = phdr_to_last_uncached_entry(phdr); 364 end = phdr_to_last_uncached_entry(phdr);
365 cached = phdr_to_last_cached_entry(phdr); 365 cached = phdr_to_last_cached_entry(phdr);
366 366
367 if (smem->global_partition) {
368 dev_err(smem->dev, "Already found the global partition\n");
369 return -EINVAL;
370 }
371
372 while (hdr < end) { 367 while (hdr < end) {
373 if (hdr->canary != SMEM_PRIVATE_CANARY) 368 if (hdr->canary != SMEM_PRIVATE_CANARY)
374 goto bad_canary; 369 goto bad_canary;
@@ -736,6 +731,11 @@ static int qcom_smem_set_global_partition(struct qcom_smem *smem)
736 bool found = false; 731 bool found = false;
737 int i; 732 int i;
738 733
734 if (smem->global_partition) {
735 dev_err(smem->dev, "Already found the global partition\n");
736 return -EINVAL;
737 }
738
739 ptable = qcom_smem_get_ptable(smem); 739 ptable = qcom_smem_get_ptable(smem);
740 if (IS_ERR(ptable)) 740 if (IS_ERR(ptable))
741 return PTR_ERR(ptable); 741 return PTR_ERR(ptable);
diff --git a/drivers/soc/qcom/trace-rpmh.h b/drivers/soc/qcom/trace-rpmh.h
new file mode 100644
index 000000000000..feb0cb455e37
--- /dev/null
+++ b/drivers/soc/qcom/trace-rpmh.h
@@ -0,0 +1,82 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
4 */
5
6#if !defined(_TRACE_RPMH_H) || defined(TRACE_HEADER_MULTI_READ)
7#define _TRACE_RPMH_H
8
9#undef TRACE_SYSTEM
10#define TRACE_SYSTEM rpmh
11
12#include <linux/tracepoint.h>
13#include "rpmh-internal.h"
14
15TRACE_EVENT(rpmh_tx_done,
16
17 TP_PROTO(struct rsc_drv *d, int m, const struct tcs_request *r, int e),
18
19 TP_ARGS(d, m, r, e),
20
21 TP_STRUCT__entry(
22 __string(name, d->name)
23 __field(int, m)
24 __field(u32, addr)
25 __field(u32, data)
26 __field(int, err)
27 ),
28
29 TP_fast_assign(
30 __assign_str(name, d->name);
31 __entry->m = m;
32 __entry->addr = r->cmds[0].addr;
33 __entry->data = r->cmds[0].data;
34 __entry->err = e;
35 ),
36
37 TP_printk("%s: ack: tcs-m: %d addr: %#x data: %#x errno: %d",
38 __get_str(name), __entry->m, __entry->addr, __entry->data,
39 __entry->err)
40);
41
42TRACE_EVENT(rpmh_send_msg,
43
44 TP_PROTO(struct rsc_drv *d, int m, int n, u32 h,
45 const struct tcs_cmd *c),
46
47 TP_ARGS(d, m, n, h, c),
48
49 TP_STRUCT__entry(
50 __string(name, d->name)
51 __field(int, m)
52 __field(int, n)
53 __field(u32, hdr)
54 __field(u32, addr)
55 __field(u32, data)
56 __field(bool, wait)
57 ),
58
59 TP_fast_assign(
60 __assign_str(name, d->name);
61 __entry->m = m;
62 __entry->n = n;
63 __entry->hdr = h;
64 __entry->addr = c->addr;
65 __entry->data = c->data;
66 __entry->wait = c->wait;
67 ),
68
69 TP_printk("%s: send-msg: tcs(m): %d cmd(n): %d msgid: %#x addr: %#x data: %#x complete: %d",
70 __get_str(name), __entry->m, __entry->n, __entry->hdr,
71 __entry->addr, __entry->data, __entry->wait)
72);
73
74#endif /* _TRACE_RPMH_H */
75
76#undef TRACE_INCLUDE_PATH
77#define TRACE_INCLUDE_PATH .
78
79#undef TRACE_INCLUDE_FILE
80#define TRACE_INCLUDE_FILE trace-rpmh
81
82#include <trace/define_trace.h>
diff --git a/include/dt-bindings/regulator/maxim,max77802.h b/include/dt-bindings/regulator/maxim,max77802.h
index cf28631d7109..d0baba1973d4 100644
--- a/include/dt-bindings/regulator/maxim,max77802.h
+++ b/include/dt-bindings/regulator/maxim,max77802.h
@@ -1,10 +1,7 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * Copyright (C) 2014 Google, Inc 3 * Copyright (C) 2014 Google, Inc
3 * 4 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Device Tree binding constants for the Maxim 77802 PMIC regulators 5 * Device Tree binding constants for the Maxim 77802 PMIC regulators
9 */ 6 */
10 7
diff --git a/include/dt-bindings/regulator/qcom,rpmh-regulator.h b/include/dt-bindings/regulator/qcom,rpmh-regulator.h
new file mode 100644
index 000000000000..86713dcf9e02
--- /dev/null
+++ b/include/dt-bindings/regulator/qcom,rpmh-regulator.h
@@ -0,0 +1,36 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (c) 2018, The Linux Foundation. All rights reserved. */
3
4#ifndef __QCOM_RPMH_REGULATOR_H
5#define __QCOM_RPMH_REGULATOR_H
6
7/*
8 * These mode constants may be used to specify modes for various RPMh regulator
9 * device tree properties (e.g. regulator-initial-mode). Each type of regulator
10 * supports a subset of the possible modes.
11 *
12 * %RPMH_REGULATOR_MODE_RET: Retention mode in which only an extremely small
13 * load current is allowed. This mode is supported
14 * by LDO and SMPS type regulators.
15 * %RPMH_REGULATOR_MODE_LPM: Low power mode in which a small load current is
16 * allowed. This mode corresponds to PFM for SMPS
17 * and BOB type regulators. This mode is supported
18 * by LDO, HFSMPS, BOB, and PMIC4 FTSMPS type
19 * regulators.
20 * %RPMH_REGULATOR_MODE_AUTO: Auto mode in which the regulator hardware
21 * automatically switches between LPM and HPM based
22 * upon the real-time load current. This mode is
23 * supported by HFSMPS, BOB, and PMIC4 FTSMPS type
24 * regulators.
25 * %RPMH_REGULATOR_MODE_HPM: High power mode in which the full rated current
26 * of the regulator is allowed. This mode
27 * corresponds to PWM for SMPS and BOB type
28 * regulators. This mode is supported by all types
29 * of regulators.
30 */
31#define RPMH_REGULATOR_MODE_RET 0
32#define RPMH_REGULATOR_MODE_LPM 1
33#define RPMH_REGULATOR_MODE_AUTO 2
34#define RPMH_REGULATOR_MODE_HPM 3
35
36#endif
diff --git a/include/dt-bindings/soc/qcom,rpmh-rsc.h b/include/dt-bindings/soc/qcom,rpmh-rsc.h
new file mode 100644
index 000000000000..868f998ea998
--- /dev/null
+++ b/include/dt-bindings/soc/qcom,rpmh-rsc.h
@@ -0,0 +1,14 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
4 */
5
6#ifndef __DT_QCOM_RPMH_RSC_H__
7#define __DT_QCOM_RPMH_RSC_H__
8
9#define SLEEP_TCS 0
10#define WAKE_TCS 1
11#define ACTIVE_TCS 2
12#define CONTROL_TCS 3
13
14#endif /* __DT_QCOM_RPMH_RSC_H__ */
diff --git a/include/linux/device.h b/include/linux/device.h
index 055a69dbcd18..9c1c3b1d5e11 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -1316,6 +1316,7 @@ extern const char *dev_driver_string(const struct device *dev);
1316struct device_link *device_link_add(struct device *consumer, 1316struct device_link *device_link_add(struct device *consumer,
1317 struct device *supplier, u32 flags); 1317 struct device *supplier, u32 flags);
1318void device_link_del(struct device_link *link); 1318void device_link_del(struct device_link *link);
1319void device_link_remove(void *consumer, struct device *supplier);
1319 1320
1320#ifdef CONFIG_PRINTK 1321#ifdef CONFIG_PRINTK
1321 1322
diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h
index b401b962afff..5d65521260b3 100644
--- a/include/linux/qcom_scm.h
+++ b/include/linux/qcom_scm.h
@@ -87,6 +87,10 @@ static inline int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr,
87static inline int 87static inline int
88qcom_scm_pas_auth_and_reset(u32 peripheral) { return -ENODEV; } 88qcom_scm_pas_auth_and_reset(u32 peripheral) { return -ENODEV; }
89static inline int qcom_scm_pas_shutdown(u32 peripheral) { return -ENODEV; } 89static inline int qcom_scm_pas_shutdown(u32 peripheral) { return -ENODEV; }
90static inline int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
91 unsigned int *src,
92 struct qcom_scm_vmperm *newvm,
93 int dest_cnt) { return -ENODEV; }
90static inline void qcom_scm_cpu_power_down(u32 flags) {} 94static inline void qcom_scm_cpu_power_down(u32 flags) {}
91static inline u32 qcom_scm_get_version(void) { return 0; } 95static inline u32 qcom_scm_get_version(void) { return 0; }
92static inline u32 96static inline u32
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index fc2dc8df476f..0fd8fbb74763 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -46,7 +46,7 @@ enum regulator_status {
46/** 46/**
47 * struct regulator_linear_range - specify linear voltage ranges 47 * struct regulator_linear_range - specify linear voltage ranges
48 * 48 *
49 * Specify a range of voltages for regulator_map_linar_range() and 49 * Specify a range of voltages for regulator_map_linear_range() and
50 * regulator_list_linear_range(). 50 * regulator_list_linear_range().
51 * 51 *
52 * @min_uV: Lowest voltage in range 52 * @min_uV: Lowest voltage in range
@@ -220,7 +220,7 @@ struct regulator_ops {
220 /* set regulator suspend operating mode (defined in consumer.h) */ 220 /* set regulator suspend operating mode (defined in consumer.h) */
221 int (*set_suspend_mode) (struct regulator_dev *, unsigned int mode); 221 int (*set_suspend_mode) (struct regulator_dev *, unsigned int mode);
222 222
223 int (*resume_early)(struct regulator_dev *rdev); 223 int (*resume)(struct regulator_dev *rdev);
224 224
225 int (*set_pull_down) (struct regulator_dev *); 225 int (*set_pull_down) (struct regulator_dev *);
226}; 226};
diff --git a/include/linux/regulator/pfuze100.h b/include/linux/regulator/pfuze100.h
index e0ccf46f66cf..cb5aecd40f07 100644
--- a/include/linux/regulator/pfuze100.h
+++ b/include/linux/regulator/pfuze100.h
@@ -64,6 +64,17 @@
64#define PFUZE3000_VLDO3 11 64#define PFUZE3000_VLDO3 11
65#define PFUZE3000_VLDO4 12 65#define PFUZE3000_VLDO4 12
66 66
67#define PFUZE3001_SW1 0
68#define PFUZE3001_SW2 1
69#define PFUZE3001_SW3 2
70#define PFUZE3001_VSNVS 3
71#define PFUZE3001_VLDO1 4
72#define PFUZE3001_VLDO2 5
73#define PFUZE3001_VCCSD 6
74#define PFUZE3001_V33 7
75#define PFUZE3001_VLDO3 8
76#define PFUZE3001_VLDO4 9
77
67struct regulator_init_data; 78struct regulator_init_data;
68 79
69struct pfuze_regulator_platform_data { 80struct pfuze_regulator_platform_data {
diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h
new file mode 100644
index 000000000000..7e3b9c605ab2
--- /dev/null
+++ b/include/linux/soc/qcom/llcc-qcom.h
@@ -0,0 +1,180 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
4 *
5 */
6
7#include <linux/platform_device.h>
8#ifndef __LLCC_QCOM__
9#define __LLCC_QCOM__
10
11#define LLCC_CPUSS 1
12#define LLCC_VIDSC0 2
13#define LLCC_VIDSC1 3
14#define LLCC_ROTATOR 4
15#define LLCC_VOICE 5
16#define LLCC_AUDIO 6
17#define LLCC_MDMHPGRW 7
18#define LLCC_MDM 8
19#define LLCC_CMPT 10
20#define LLCC_GPUHTW 11
21#define LLCC_GPU 12
22#define LLCC_MMUHWT 13
23#define LLCC_CMPTDMA 15
24#define LLCC_DISP 16
25#define LLCC_VIDFW 17
26#define LLCC_MDMHPFX 20
27#define LLCC_MDMPNG 21
28#define LLCC_AUDHW 22
29
30/**
31 * llcc_slice_desc - Cache slice descriptor
32 * @slice_id: llcc slice id
33 * @slice_size: Size allocated for the llcc slice
34 */
35struct llcc_slice_desc {
36 u32 slice_id;
37 size_t slice_size;
38};
39
40/**
41 * llcc_slice_config - Data associated with the llcc slice
42 * @usecase_id: usecase id for which the llcc slice is used
43 * @slice_id: llcc slice id assigned to each slice
44 * @max_cap: maximum capacity of the llcc slice
45 * @priority: priority of the llcc slice
46 * @fixed_size: whether the llcc slice can grow beyond its size
47 * @bonus_ways: bonus ways associated with llcc slice
48 * @res_ways: reserved ways associated with llcc slice
49 * @cache_mode: mode of the llcc slice
50 * @probe_target_ways: Probe only reserved and bonus ways on a cache miss
51 * @dis_cap_alloc: Disable capacity based allocation
52 * @retain_on_pc: Retain through power collapse
53 * @activate_on_init: activate the slice on init
54 */
55struct llcc_slice_config {
56 u32 usecase_id;
57 u32 slice_id;
58 u32 max_cap;
59 u32 priority;
60 bool fixed_size;
61 u32 bonus_ways;
62 u32 res_ways;
63 u32 cache_mode;
64 u32 probe_target_ways;
65 bool dis_cap_alloc;
66 bool retain_on_pc;
67 bool activate_on_init;
68};
69
70/**
71 * llcc_drv_data - Data associated with the llcc driver
72 * @regmap: regmap associated with the llcc device
73 * @cfg: pointer to the data structure for slice configuration
74 * @lock: mutex associated with each slice
75 * @cfg_size: size of the config data table
76 * @max_slices: max slices as read from device tree
77 * @bcast_off: Offset of the broadcast bank
78 * @num_banks: Number of llcc banks
79 * @bitmap: Bit map to track the active slice ids
80 * @offsets: Pointer to the bank offsets array
81 */
82struct llcc_drv_data {
83 struct regmap *regmap;
84 const struct llcc_slice_config *cfg;
85 struct mutex lock;
86 u32 cfg_size;
87 u32 max_slices;
88 u32 bcast_off;
89 u32 num_banks;
90 unsigned long *bitmap;
91 u32 *offsets;
92};
93
94#if IS_ENABLED(CONFIG_QCOM_LLCC)
95/**
96 * llcc_slice_getd - get llcc slice descriptor
97 * @uid: usecase_id of the client
98 */
99struct llcc_slice_desc *llcc_slice_getd(u32 uid);
100
101/**
102 * llcc_slice_putd - llcc slice descritpor
103 * @desc: Pointer to llcc slice descriptor
104 */
105void llcc_slice_putd(struct llcc_slice_desc *desc);
106
107/**
108 * llcc_get_slice_id - get slice id
109 * @desc: Pointer to llcc slice descriptor
110 */
111int llcc_get_slice_id(struct llcc_slice_desc *desc);
112
113/**
114 * llcc_get_slice_size - llcc slice size
115 * @desc: Pointer to llcc slice descriptor
116 */
117size_t llcc_get_slice_size(struct llcc_slice_desc *desc);
118
119/**
120 * llcc_slice_activate - Activate the llcc slice
121 * @desc: Pointer to llcc slice descriptor
122 */
123int llcc_slice_activate(struct llcc_slice_desc *desc);
124
125/**
126 * llcc_slice_deactivate - Deactivate the llcc slice
127 * @desc: Pointer to llcc slice descriptor
128 */
129int llcc_slice_deactivate(struct llcc_slice_desc *desc);
130
131/**
132 * qcom_llcc_probe - program the sct table
133 * @pdev: platform device pointer
134 * @table: soc sct table
135 * @sz: Size of the config table
136 */
137int qcom_llcc_probe(struct platform_device *pdev,
138 const struct llcc_slice_config *table, u32 sz);
139#else
140static inline struct llcc_slice_desc *llcc_slice_getd(u32 uid)
141{
142 return NULL;
143}
144
145static inline void llcc_slice_putd(struct llcc_slice_desc *desc)
146{
147
148};
149
150static inline int llcc_get_slice_id(struct llcc_slice_desc *desc)
151{
152 return -EINVAL;
153}
154
155static inline size_t llcc_get_slice_size(struct llcc_slice_desc *desc)
156{
157 return 0;
158}
159static inline int llcc_slice_activate(struct llcc_slice_desc *desc)
160{
161 return -EINVAL;
162}
163
164static inline int llcc_slice_deactivate(struct llcc_slice_desc *desc)
165{
166 return -EINVAL;
167}
168static inline int qcom_llcc_probe(struct platform_device *pdev,
169 const struct llcc_slice_config *table, u32 sz)
170{
171 return -ENODEV;
172}
173
174static inline int qcom_llcc_remove(struct platform_device *pdev)
175{
176 return -ENODEV;
177}
178#endif
179
180#endif
diff --git a/include/soc/qcom/rpmh.h b/include/soc/qcom/rpmh.h
new file mode 100644
index 000000000000..619e07c75da9
--- /dev/null
+++ b/include/soc/qcom/rpmh.h
@@ -0,0 +1,51 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
4 */
5
6#ifndef __SOC_QCOM_RPMH_H__
7#define __SOC_QCOM_RPMH_H__
8
9#include <soc/qcom/tcs.h>
10#include <linux/platform_device.h>
11
12
13#if IS_ENABLED(CONFIG_QCOM_RPMH)
14int rpmh_write(const struct device *dev, enum rpmh_state state,
15 const struct tcs_cmd *cmd, u32 n);
16
17int rpmh_write_async(const struct device *dev, enum rpmh_state state,
18 const struct tcs_cmd *cmd, u32 n);
19
20int rpmh_write_batch(const struct device *dev, enum rpmh_state state,
21 const struct tcs_cmd *cmd, u32 *n);
22
23int rpmh_flush(const struct device *dev);
24
25int rpmh_invalidate(const struct device *dev);
26
27#else
28
29static inline int rpmh_write(const struct device *dev, enum rpmh_state state,
30 const struct tcs_cmd *cmd, u32 n)
31{ return -ENODEV; }
32
33static inline int rpmh_write_async(const struct device *dev,
34 enum rpmh_state state,
35 const struct tcs_cmd *cmd, u32 n)
36{ return -ENODEV; }
37
38static inline int rpmh_write_batch(const struct device *dev,
39 enum rpmh_state state,
40 const struct tcs_cmd *cmd, u32 *n)
41{ return -ENODEV; }
42
43static inline int rpmh_flush(const struct device *dev)
44{ return -ENODEV; }
45
46static inline int rpmh_invalidate(const struct device *dev)
47{ return -ENODEV; }
48
49#endif /* CONFIG_QCOM_RPMH */
50
51#endif /* __SOC_QCOM_RPMH_H__ */
diff --git a/include/soc/qcom/tcs.h b/include/soc/qcom/tcs.h
new file mode 100644
index 000000000000..262876a59e86
--- /dev/null
+++ b/include/soc/qcom/tcs.h
@@ -0,0 +1,56 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
4 */
5
6#ifndef __SOC_QCOM_TCS_H__
7#define __SOC_QCOM_TCS_H__
8
9#define MAX_RPMH_PAYLOAD 16
10
11/**
12 * rpmh_state: state for the request
13 *
14 * RPMH_SLEEP_STATE: State of the resource when the processor subsystem
15 * is powered down. There is no client using the
16 * resource actively.
17 * RPMH_WAKE_ONLY_STATE: Resume resource state to the value previously
18 * requested before the processor was powered down.
19 * RPMH_ACTIVE_ONLY_STATE: Active or AMC mode requests. Resource state
20 * is aggregated immediately.
21 */
22enum rpmh_state {
23 RPMH_SLEEP_STATE,
24 RPMH_WAKE_ONLY_STATE,
25 RPMH_ACTIVE_ONLY_STATE,
26};
27
28/**
29 * struct tcs_cmd: an individual request to RPMH.
30 *
31 * @addr: the address of the resource slv_id:18:16 | offset:0:15
32 * @data: the resource state request
33 * @wait: wait for this request to be complete before sending the next
34 */
35struct tcs_cmd {
36 u32 addr;
37 u32 data;
38 u32 wait;
39};
40
41/**
42 * struct tcs_request: A set of tcs_cmds sent together in a TCS
43 *
44 * @state: state for the request.
45 * @wait_for_compl: wait until we get a response from the h/w accelerator
46 * @num_cmds: the number of @cmds in this request
47 * @cmds: an array of tcs_cmds
48 */
49struct tcs_request {
50 enum rpmh_state state;
51 u32 wait_for_compl;
52 u32 num_cmds;
53 struct tcs_cmd *cmds;
54};
55
56#endif /* __SOC_QCOM_TCS_H__ */