aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Collins <collinsd@codeaurora.org>2018-07-13 21:50:59 -0400
committerMark Brown <broonie@kernel.org>2018-08-10 12:30:29 -0400
commit46fc033eba42f5a4fb583b2ab53f0a9918468452 (patch)
treed094438bf9135787f0347733ee230ca2bc3433f7
parent0db021f7a2731cc559f0c5beb19ff3f677ff8626 (diff)
regulator: add QCOM RPMh regulator driver
Add the QCOM RPMh regulator driver to manage PMIC regulators which are controlled via RPMh on some Qualcomm Technologies, Inc. SoCs. RPMh is a hardware block which contains several accelerators which are used to manage various hardware resources that are shared between the processors of the SoC. The final hardware state of a regulator is determined within RPMh by performing max aggregation of the requests made by all of the processors. Add support for PMIC regulator control via the voltage regulator manager (VRM) and oscillator buffer (XOB) RPMh accelerators. VRM supports manipulation of enable state, voltage, and mode. XOB supports manipulation of enable state. Signed-off-by: David Collins <collinsd@codeaurora.org> Reviewed-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Matthias Kaehlcke <mka@chromium.org> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/regulator/Kconfig9
-rw-r--r--drivers/regulator/Makefile1
-rw-r--r--drivers/regulator/qcom-rpmh-regulator.c769
3 files changed, 779 insertions, 0 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 347351e79b1e..329cdd33ed62 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -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
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 18bfed61e7fe..801d9a34a203 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -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
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);