* [RFC WIP 0/2] Qualcomm family A RPM driver and example client
@ 2014-04-22 18:20 Bjorn Andersson
2014-04-22 18:20 ` [RFC WIP 1/2] mfd: msm_rpm: Initial driver for the Qualcomm RPM Bjorn Andersson
2014-04-22 18:20 ` [RFC WIP 2/2] regulator: msm_rpm: Initial regulator driver for " Bjorn Andersson
0 siblings, 2 replies; 3+ messages in thread
From: Bjorn Andersson @ 2014-04-22 18:20 UTC (permalink / raw)
To: joshc, linux-arm-msm
To be used for reference in the design discussion related to RPM driver
implementation for family A.
Regulator driver is a not even close to the shape it should be, but shows a
user of the api. Instead of having every regulator exposed as it's own
compatible, I would now have it take a resource id as reg and just be
compatible with the specific resource consumer.
The difference with Josh's proposal is the mapping table in msm_rpm.c, that
makes the rpm driver expose logical resources and therefor hides the details of
the rpm communication from its clients. This gives, in my mind, a cleaner
abstraction and api.
Bjorn Andersson (2):
mfd: msm_rpm: Initial driver for the Qualcomm RPM
regulator: msm_rpm: Initial regulator driver for Qualcomm RPM
drivers/mfd/Kconfig | 7 +
drivers/mfd/Makefile | 1 +
drivers/mfd/msm_rpm-8064.h | 420 +++++++++++++++++++++++++++
drivers/mfd/msm_rpm-8960.h | 400 ++++++++++++++++++++++++++
drivers/mfd/msm_rpm.c | 525 ++++++++++++++++++++++++++++++++++
drivers/regulator/Kconfig | 7 +
drivers/regulator/Makefile | 1 +
drivers/regulator/msm_rpm-regulator.c | 467 ++++++++++++++++++++++++++++++
include/linux/mfd/msm_rpm.h | 87 ++++++
9 files changed, 1915 insertions(+)
create mode 100644 drivers/mfd/msm_rpm-8064.h
create mode 100644 drivers/mfd/msm_rpm-8960.h
create mode 100644 drivers/mfd/msm_rpm.c
create mode 100644 drivers/regulator/msm_rpm-regulator.c
create mode 100644 include/linux/mfd/msm_rpm.h
--
1.8.2.2
^ permalink raw reply [flat|nested] 3+ messages in thread
* [RFC WIP 1/2] mfd: msm_rpm: Initial driver for the Qualcomm RPM
2014-04-22 18:20 [RFC WIP 0/2] Qualcomm family A RPM driver and example client Bjorn Andersson
@ 2014-04-22 18:20 ` Bjorn Andersson
2014-04-22 18:20 ` [RFC WIP 2/2] regulator: msm_rpm: Initial regulator driver for " Bjorn Andersson
1 sibling, 0 replies; 3+ messages in thread
From: Bjorn Andersson @ 2014-04-22 18:20 UTC (permalink / raw)
To: joshc, linux-arm-msm
Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
---
drivers/mfd/Kconfig | 7 +
drivers/mfd/Makefile | 1 +
drivers/mfd/msm_rpm-8064.h | 420 +++++++++++++++++++++++++++++++++++
drivers/mfd/msm_rpm-8960.h | 400 +++++++++++++++++++++++++++++++++
drivers/mfd/msm_rpm.c | 525 ++++++++++++++++++++++++++++++++++++++++++++
include/linux/mfd/msm_rpm.h | 87 ++++++++
6 files changed, 1440 insertions(+)
create mode 100644 drivers/mfd/msm_rpm-8064.h
create mode 100644 drivers/mfd/msm_rpm-8960.h
create mode 100644 drivers/mfd/msm_rpm.c
create mode 100644 include/linux/mfd/msm_rpm.h
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 49bb445..e8395b1 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -468,6 +468,13 @@ config UCB1400_CORE
To compile this driver as a module, choose M here: the
module will be called ucb1400_core.
+config MFD_MSM_RPM
+ tristate "Qualcomm RPM"
+ depends on ARCH_MSM
+ select MFD_CORE
+ help
+ Select this option to enable the Qualcomm RPM driver.
+
config MFD_PM8XXX
tristate
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 5aea5ef..b371ec9 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -149,6 +149,7 @@ obj-$(CONFIG_MFD_SI476X_CORE) += si476x-core.o
obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o
obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o omap-usb-tll.o
+obj-$(CONFIG_MFD_MSM_RPM) += msm_rpm.o
obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o ssbi.o
obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o
obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o
diff --git a/drivers/mfd/msm_rpm-8064.h b/drivers/mfd/msm_rpm-8064.h
new file mode 100644
index 0000000..ef762f4
--- /dev/null
+++ b/drivers/mfd/msm_rpm-8064.h
@@ -0,0 +1,420 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_RPM_8064_H
+#define __ARCH_ARM_MACH_MSM_RPM_8064_H
+
+/* RPM resource select enums defined for RPM core
+ NOT IN SEQUENTIAL ORDER */
+enum {
+ MSM_RPM_8064_SEL_NOTIFICATION = 0,
+ MSM_RPM_8064_SEL_INVALIDATE = 1,
+ MSM_RPM_8064_SEL_TRIGGER_TIMED = 2,
+ MSM_RPM_8064_SEL_RPM_CTL = 3,
+
+ MSM_RPM_8064_SEL_CXO_CLK = 5,
+ MSM_RPM_8064_SEL_PXO_CLK = 6,
+ MSM_RPM_8064_SEL_QDSS_CLK = 7,
+ MSM_RPM_8064_SEL_APPS_FABRIC_CLK = 8,
+ MSM_RPM_8064_SEL_SYSTEM_FABRIC_CLK = 9,
+ MSM_RPM_8064_SEL_MM_FABRIC_CLK = 10,
+ MSM_RPM_8064_SEL_DAYTONA_FABRIC_CLK = 11,
+ MSM_RPM_8064_SEL_SFPB_CLK = 12,
+ MSM_RPM_8064_SEL_CFPB_CLK = 13,
+ MSM_RPM_8064_SEL_MMFPB_CLK = 14,
+ MSM_RPM_8064_SEL_EBI1_CLK = 16,
+
+ MSM_RPM_8064_SEL_APPS_FABRIC_CFG_HALT = 18,
+ MSM_RPM_8064_SEL_APPS_FABRIC_CFG_CLKMOD = 19,
+ MSM_RPM_8064_SEL_APPS_FABRIC_CFG_IOCTL = 20,
+ MSM_RPM_8064_SEL_APPS_FABRIC_ARB = 21,
+
+ MSM_RPM_8064_SEL_SYS_FABRIC_CFG_HALT = 22,
+ MSM_RPM_8064_SEL_SYS_FABRIC_CFG_CLKMOD = 23,
+ MSM_RPM_8064_SEL_SYS_FABRIC_CFG_IOCTL = 24,
+ MSM_RPM_8064_SEL_SYSTEM_FABRIC_ARB = 25,
+
+ MSM_RPM_8064_SEL_MMSS_FABRIC_CFG_HALT = 26,
+ MSM_RPM_8064_SEL_MMSS_FABRIC_CFG_CLKMOD = 27,
+ MSM_RPM_8064_SEL_MMSS_FABRIC_CFG_IOCTL = 28,
+ MSM_RPM_8064_SEL_MM_FABRIC_ARB = 29,
+
+ MSM_RPM_8064_SEL_PM8921_S1 = 30,
+ MSM_RPM_8064_SEL_PM8921_S2 = 31,
+ MSM_RPM_8064_SEL_PM8921_S3 = 32,
+ MSM_RPM_8064_SEL_PM8921_S4 = 33,
+ MSM_RPM_8064_SEL_PM8921_S5 = 34,
+ MSM_RPM_8064_SEL_PM8921_S6 = 35,
+ MSM_RPM_8064_SEL_PM8921_S7 = 36,
+ MSM_RPM_8064_SEL_PM8921_S8 = 37,
+ MSM_RPM_8064_SEL_PM8921_L1 = 38,
+ MSM_RPM_8064_SEL_PM8921_L2 = 39,
+ MSM_RPM_8064_SEL_PM8921_L3 = 40,
+ MSM_RPM_8064_SEL_PM8921_L4 = 41,
+ MSM_RPM_8064_SEL_PM8921_L5 = 42,
+ MSM_RPM_8064_SEL_PM8921_L6 = 43,
+ MSM_RPM_8064_SEL_PM8921_L7 = 44,
+ MSM_RPM_8064_SEL_PM8921_L8 = 45,
+ MSM_RPM_8064_SEL_PM8921_L9 = 46,
+ MSM_RPM_8064_SEL_PM8921_L10 = 47,
+ MSM_RPM_8064_SEL_PM8921_L11 = 48,
+ MSM_RPM_8064_SEL_PM8921_L12 = 49,
+ MSM_RPM_8064_SEL_PM8921_L13 = 50,
+ MSM_RPM_8064_SEL_PM8921_L14 = 51,
+ MSM_RPM_8064_SEL_PM8921_L15 = 52,
+ MSM_RPM_8064_SEL_PM8921_L16 = 53,
+ MSM_RPM_8064_SEL_PM8921_L17 = 54,
+ MSM_RPM_8064_SEL_PM8921_L18 = 55,
+ MSM_RPM_8064_SEL_PM8921_L19 = 56,
+ MSM_RPM_8064_SEL_PM8921_L20 = 57,
+ MSM_RPM_8064_SEL_PM8921_L21 = 58,
+ MSM_RPM_8064_SEL_PM8921_L22 = 59,
+ MSM_RPM_8064_SEL_PM8921_L23 = 60,
+ MSM_RPM_8064_SEL_PM8921_L24 = 61,
+ MSM_RPM_8064_SEL_PM8921_L25 = 62,
+ MSM_RPM_8064_SEL_PM8921_L26 = 63,
+ MSM_RPM_8064_SEL_PM8921_L27 = 64,
+ MSM_RPM_8064_SEL_PM8921_L28 = 65,
+ MSM_RPM_8064_SEL_PM8921_L29 = 66,
+ MSM_RPM_8064_SEL_PM8921_CLK1 = 67,
+ MSM_RPM_8064_SEL_PM8921_CLK2 = 68,
+ MSM_RPM_8064_SEL_PM8921_LVS1 = 69,
+ MSM_RPM_8064_SEL_PM8921_LVS2 = 70,
+ MSM_RPM_8064_SEL_PM8921_LVS3 = 71,
+ MSM_RPM_8064_SEL_PM8921_LVS4 = 72,
+ MSM_RPM_8064_SEL_PM8921_LVS5 = 73,
+ MSM_RPM_8064_SEL_PM8921_LVS6 = 74,
+ MSM_RPM_8064_SEL_PM8921_LVS7 = 75,
+ MSM_RPM_8064_SEL_PM8821_S1 = 76,
+ MSM_RPM_8064_SEL_PM8821_S2 = 77,
+ MSM_RPM_8064_SEL_PM8821_L1 = 78,
+
+ MSM_RPM_8064_SEL_NCP = 80,
+ MSM_RPM_8064_SEL_CXO_BUFFERS = 81,
+ MSM_RPM_8064_SEL_USB_OTG_SWITCH = 82,
+ MSM_RPM_8064_SEL_HDMI_SWITCH = 83,
+ MSM_RPM_8064_SEL_DDR_DMM = 84,
+
+ MSM_RPM_8064_SEL_VDDMIN_GPIO = 89,
+
+ MSM_RPM_8064_SEL_LAST = MSM_RPM_8064_SEL_VDDMIN_GPIO,
+};
+
+/* RPM resource (4 byte) word ID enum */
+enum {
+ MSM_RPM_8064_ID_NOTIFICATION_CONFIGURED = 0,
+ MSM_RPM_8064_ID_NOTIFICATION_CONFIGURED_3 =
+ MSM_RPM_8064_ID_NOTIFICATION_CONFIGURED + 3,
+
+ MSM_RPM_8064_ID_NOTIFICATION_REGISTERED = 4,
+ MSM_RPM_8064_ID_NOTIFICATION_REGISTERED_3 =
+ MSM_RPM_8064_ID_NOTIFICATION_REGISTERED + 3,
+
+ MSM_RPM_8064_ID_INVALIDATE = 8,
+ MSM_RPM_8064_ID_INVALIDATE_7 =
+ MSM_RPM_8064_ID_INVALIDATE + 7,
+
+ MSM_RPM_8064_ID_TRIGGER_TIMED_TO = 16,
+ MSM_RPM_8064_ID_TRIGGER_TIMED_SCLK_COUNT = 17,
+
+ MSM_RPM_8064_ID_RPM_CTL = 18,
+
+ /* TRIGGER_CLEAR/SET deprecated in these 24 RESERVED bytes */
+ MSM_RPM_8064_ID_RESERVED = 19,
+ MSM_RPM_8064_ID_RESERVED_5 =
+ MSM_RPM_8064_ID_RESERVED + 5,
+
+ MSM_RPM_8064_ID_CXO_CLK = 25,
+ MSM_RPM_8064_ID_PXO_CLK = 26,
+ MSM_RPM_8064_ID_APPS_FABRIC_CLK = 27,
+ MSM_RPM_8064_ID_SYSTEM_FABRIC_CLK = 28,
+ MSM_RPM_8064_ID_MM_FABRIC_CLK = 29,
+ MSM_RPM_8064_ID_DAYTONA_FABRIC_CLK = 30,
+ MSM_RPM_8064_ID_SFPB_CLK = 31,
+ MSM_RPM_8064_ID_CFPB_CLK = 32,
+ MSM_RPM_8064_ID_MMFPB_CLK = 33,
+ MSM_RPM_8064_ID_EBI1_CLK = 34,
+
+ MSM_RPM_8064_ID_APPS_FABRIC_CFG_HALT = 35,
+ MSM_RPM_8064_ID_APPS_FABRIC_CFG_HALT_1 = 36,
+ MSM_RPM_8064_ID_APPS_FABRIC_CFG_CLKMOD = 37,
+ MSM_RPM_8064_ID_APPS_FABRIC_CFG_CLKMOD_1 = 38,
+ MSM_RPM_8064_ID_APPS_FABRIC_CFG_CLKMOD_2 = 39,
+ MSM_RPM_8064_ID_APPS_FABRIC_CFG_IOCTL = 40,
+ MSM_RPM_8064_ID_APPS_FABRIC_ARB = 41,
+ MSM_RPM_8064_ID_APPS_FABRIC_ARB_11 =
+ MSM_RPM_8064_ID_APPS_FABRIC_ARB + 11,
+
+ MSM_RPM_8064_ID_SYS_FABRIC_CFG_HALT = 53,
+ MSM_RPM_8064_ID_SYS_FABRIC_CFG_HALT_1 = 54,
+ MSM_RPM_8064_ID_SYS_FABRIC_CFG_CLKMOD = 55,
+ MSM_RPM_8064_ID_SYS_FABRIC_CFG_CLKMOD_1 = 56,
+ MSM_RPM_8064_ID_SYS_FABRIC_CFG_CLKMOD_2 = 57,
+ MSM_RPM_8064_ID_SYS_FABRIC_CFG_IOCTL = 58,
+ MSM_RPM_8064_ID_SYSTEM_FABRIC_ARB = 59,
+ MSM_RPM_8064_ID_SYSTEM_FABRIC_ARB_29 =
+ MSM_RPM_8064_ID_SYSTEM_FABRIC_ARB + 29,
+
+ MSM_RPM_8064_ID_MMSS_FABRIC_CFG_HALT = 89,
+ MSM_RPM_8064_ID_MMSS_FABRIC_CFG_HALT_1 = 90,
+ MSM_RPM_8064_ID_MMSS_FABRIC_CFG_CLKMOD = 91,
+ MSM_RPM_8064_ID_MMSS_FABRIC_CFG_CLKMOD_1 = 92,
+ MSM_RPM_8064_ID_MMSS_FABRIC_CFG_CLKMOD_2 = 93,
+ MSM_RPM_8064_ID_MMSS_FABRIC_CFG_IOCTL = 94,
+ MSM_RPM_8064_ID_MM_FABRIC_ARB = 95,
+ MSM_RPM_8064_ID_MM_FABRIC_ARB_20 =
+ MSM_RPM_8064_ID_MM_FABRIC_ARB + 20,
+
+ MSM_RPM_8064_ID_PM8921_S1 = 116,
+ MSM_RPM_8064_ID_PM8921_S1_1 = 117,
+ MSM_RPM_8064_ID_PM8921_S2 = 118,
+ MSM_RPM_8064_ID_PM8921_S2_1 = 119,
+ MSM_RPM_8064_ID_PM8921_S3 = 120,
+ MSM_RPM_8064_ID_PM8921_S3_1 = 121,
+ MSM_RPM_8064_ID_PM8921_S4 = 122,
+ MSM_RPM_8064_ID_PM8921_S4_1 = 123,
+ MSM_RPM_8064_ID_PM8921_S5 = 124,
+ MSM_RPM_8064_ID_PM8921_S5_1 = 125,
+ MSM_RPM_8064_ID_PM8921_S6 = 126,
+ MSM_RPM_8064_ID_PM8921_S6_1 = 127,
+ MSM_RPM_8064_ID_PM8921_S7 = 128,
+ MSM_RPM_8064_ID_PM8921_S7_1 = 129,
+ MSM_RPM_8064_ID_PM8921_S8 = 130,
+ MSM_RPM_8064_ID_PM8921_S8_1 = 131,
+ MSM_RPM_8064_ID_PM8921_L1 = 132,
+ MSM_RPM_8064_ID_PM8921_L1_1 = 133,
+ MSM_RPM_8064_ID_PM8921_L2 = 134,
+ MSM_RPM_8064_ID_PM8921_L2_1 = 135,
+ MSM_RPM_8064_ID_PM8921_L3 = 136,
+ MSM_RPM_8064_ID_PM8921_L3_1 = 137,
+ MSM_RPM_8064_ID_PM8921_L4 = 138,
+ MSM_RPM_8064_ID_PM8921_L4_1 = 139,
+ MSM_RPM_8064_ID_PM8921_L5 = 140,
+ MSM_RPM_8064_ID_PM8921_L5_1 = 141,
+ MSM_RPM_8064_ID_PM8921_L6 = 142,
+ MSM_RPM_8064_ID_PM8921_L6_1 = 143,
+ MSM_RPM_8064_ID_PM8921_L7 = 144,
+ MSM_RPM_8064_ID_PM8921_L7_1 = 145,
+ MSM_RPM_8064_ID_PM8921_L8 = 146,
+ MSM_RPM_8064_ID_PM8921_L8_1 = 147,
+ MSM_RPM_8064_ID_PM8921_L9 = 148,
+ MSM_RPM_8064_ID_PM8921_L9_1 = 149,
+ MSM_RPM_8064_ID_PM8921_L10 = 150,
+ MSM_RPM_8064_ID_PM8921_L10_1 = 151,
+ MSM_RPM_8064_ID_PM8921_L11 = 152,
+ MSM_RPM_8064_ID_PM8921_L11_1 = 153,
+ MSM_RPM_8064_ID_PM8921_L12 = 154,
+ MSM_RPM_8064_ID_PM8921_L12_1 = 155,
+ MSM_RPM_8064_ID_PM8921_L13 = 156,
+ MSM_RPM_8064_ID_PM8921_L13_1 = 157,
+ MSM_RPM_8064_ID_PM8921_L14 = 158,
+ MSM_RPM_8064_ID_PM8921_L14_1 = 159,
+ MSM_RPM_8064_ID_PM8921_L15 = 160,
+ MSM_RPM_8064_ID_PM8921_L15_1 = 161,
+ MSM_RPM_8064_ID_PM8921_L16 = 162,
+ MSM_RPM_8064_ID_PM8921_L16_1 = 163,
+ MSM_RPM_8064_ID_PM8921_L17 = 164,
+ MSM_RPM_8064_ID_PM8921_L17_1 = 165,
+ MSM_RPM_8064_ID_PM8921_L18 = 166,
+ MSM_RPM_8064_ID_PM8921_L18_1 = 167,
+ MSM_RPM_8064_ID_PM8921_L19 = 168,
+ MSM_RPM_8064_ID_PM8921_L19_1 = 169,
+ MSM_RPM_8064_ID_PM8921_L20 = 170,
+ MSM_RPM_8064_ID_PM8921_L20_1 = 171,
+ MSM_RPM_8064_ID_PM8921_L21 = 172,
+ MSM_RPM_8064_ID_PM8921_L21_1 = 173,
+ MSM_RPM_8064_ID_PM8921_L22 = 174,
+ MSM_RPM_8064_ID_PM8921_L22_1 = 175,
+ MSM_RPM_8064_ID_PM8921_L23 = 176,
+ MSM_RPM_8064_ID_PM8921_L23_1 = 177,
+ MSM_RPM_8064_ID_PM8921_L24 = 178,
+ MSM_RPM_8064_ID_PM8921_L24_1 = 179,
+ MSM_RPM_8064_ID_PM8921_L25 = 180,
+ MSM_RPM_8064_ID_PM8921_L25_1 = 181,
+ MSM_RPM_8064_ID_PM8921_L26 = 182,
+ MSM_RPM_8064_ID_PM8921_L26_1 = 183,
+ MSM_RPM_8064_ID_PM8921_L27 = 184,
+ MSM_RPM_8064_ID_PM8921_L27_1 = 185,
+ MSM_RPM_8064_ID_PM8921_L28 = 186,
+ MSM_RPM_8064_ID_PM8921_L28_1 = 187,
+ MSM_RPM_8064_ID_PM8921_L29 = 188,
+ MSM_RPM_8064_ID_PM8921_L29_1 = 189,
+ MSM_RPM_8064_ID_PM8921_CLK1 = 190,
+ MSM_RPM_8064_ID_PM8921_CLK1_1 = 191,
+ MSM_RPM_8064_ID_PM8921_CLK2 = 192,
+ MSM_RPM_8064_ID_PM8921_CLK2_1 = 193,
+ MSM_RPM_8064_ID_PM8921_LVS1 = 194,
+ MSM_RPM_8064_ID_PM8921_LVS2 = 195,
+ MSM_RPM_8064_ID_PM8921_LVS3 = 196,
+ MSM_RPM_8064_ID_PM8921_LVS4 = 197,
+ MSM_RPM_8064_ID_PM8921_LVS5 = 198,
+ MSM_RPM_8064_ID_PM8921_LVS6 = 199,
+ MSM_RPM_8064_ID_PM8921_LVS7 = 200,
+ MSM_RPM_8064_ID_PM8821_S1 = 201,
+ MSM_RPM_8064_ID_PM8821_S1_1 = 202,
+ MSM_RPM_8064_ID_PM8821_S2 = 203,
+ MSM_RPM_8064_ID_PM8821_S2_1 = 204,
+ MSM_RPM_8064_ID_PM8821_L1 = 205,
+ MSM_RPM_8064_ID_PM8821_L1_1 = 206,
+ MSM_RPM_8064_ID_NCP = 207,
+ MSM_RPM_8064_ID_NCP_1 = 208,
+ MSM_RPM_8064_ID_CXO_BUFFERS = 209,
+ MSM_RPM_8064_ID_USB_OTG_SWITCH = 210,
+ MSM_RPM_8064_ID_HDMI_SWITCH = 211,
+ MSM_RPM_8064_ID_DDR_DMM = 212,
+ MSM_RPM_8064_ID_DDR_DMM_1 = 213,
+ MSM_RPM_8064_ID_QDSS_CLK = 214,
+ MSM_RPM_8064_ID_VDDMIN_GPIO = 215,
+
+ MSM_RPM_8064_ID_LAST = MSM_RPM_8064_ID_VDDMIN_GPIO,
+};
+
+
+/* RPM status ID enum */
+enum {
+ MSM_RPM_8064_STATUS_ID_VERSION_MAJOR = 0,
+ MSM_RPM_8064_STATUS_ID_VERSION_MINOR = 1,
+ MSM_RPM_8064_STATUS_ID_VERSION_BUILD = 2,
+ MSM_RPM_8064_STATUS_ID_SUPPORTED_RESOURCES = 3,
+ MSM_RPM_8064_STATUS_ID_SUPPORTED_RESOURCES_1 = 4,
+ MSM_RPM_8064_STATUS_ID_SUPPORTED_RESOURCES_2 = 5,
+ MSM_RPM_8064_STATUS_ID_RESERVED_SUPPORTED_RESOURCES = 6,
+ MSM_RPM_8064_STATUS_ID_SEQUENCE = 7,
+ MSM_RPM_8064_STATUS_ID_RPM_CTL = 8,
+ MSM_RPM_8064_STATUS_ID_CXO_CLK = 9,
+ MSM_RPM_8064_STATUS_ID_PXO_CLK = 10,
+ MSM_RPM_8064_STATUS_ID_APPS_FABRIC_CLK = 11,
+ MSM_RPM_8064_STATUS_ID_SYSTEM_FABRIC_CLK = 12,
+ MSM_RPM_8064_STATUS_ID_MM_FABRIC_CLK = 13,
+ MSM_RPM_8064_STATUS_ID_DAYTONA_FABRIC_CLK = 14,
+ MSM_RPM_8064_STATUS_ID_SFPB_CLK = 15,
+ MSM_RPM_8064_STATUS_ID_CFPB_CLK = 16,
+ MSM_RPM_8064_STATUS_ID_MMFPB_CLK = 17,
+ MSM_RPM_8064_STATUS_ID_EBI1_CLK = 18,
+ MSM_RPM_8064_STATUS_ID_APPS_FABRIC_CFG_HALT = 19,
+ MSM_RPM_8064_STATUS_ID_APPS_FABRIC_CFG_CLKMOD = 20,
+ MSM_RPM_8064_STATUS_ID_APPS_FABRIC_CFG_IOCTL = 21,
+ MSM_RPM_8064_STATUS_ID_APPS_FABRIC_ARB = 22,
+ MSM_RPM_8064_STATUS_ID_SYS_FABRIC_CFG_HALT = 23,
+ MSM_RPM_8064_STATUS_ID_SYS_FABRIC_CFG_CLKMOD = 24,
+ MSM_RPM_8064_STATUS_ID_SYS_FABRIC_CFG_IOCTL = 25,
+ MSM_RPM_8064_STATUS_ID_SYSTEM_FABRIC_ARB = 26,
+ MSM_RPM_8064_STATUS_ID_MMSS_FABRIC_CFG_HALT = 27,
+ MSM_RPM_8064_STATUS_ID_MMSS_FABRIC_CFG_CLKMOD = 28,
+ MSM_RPM_8064_STATUS_ID_MMSS_FABRIC_CFG_IOCTL = 29,
+ MSM_RPM_8064_STATUS_ID_MM_FABRIC_ARB = 30,
+ MSM_RPM_8064_STATUS_ID_PM8921_S1 = 31,
+ MSM_RPM_8064_STATUS_ID_PM8921_S1_1 = 32,
+ MSM_RPM_8064_STATUS_ID_PM8921_S2 = 33,
+ MSM_RPM_8064_STATUS_ID_PM8921_S2_1 = 34,
+ MSM_RPM_8064_STATUS_ID_PM8921_S3 = 35,
+ MSM_RPM_8064_STATUS_ID_PM8921_S3_1 = 36,
+ MSM_RPM_8064_STATUS_ID_PM8921_S4 = 37,
+ MSM_RPM_8064_STATUS_ID_PM8921_S4_1 = 38,
+ MSM_RPM_8064_STATUS_ID_PM8921_S5 = 39,
+ MSM_RPM_8064_STATUS_ID_PM8921_S5_1 = 40,
+ MSM_RPM_8064_STATUS_ID_PM8921_S6 = 41,
+ MSM_RPM_8064_STATUS_ID_PM8921_S6_1 = 42,
+ MSM_RPM_8064_STATUS_ID_PM8921_S7 = 43,
+ MSM_RPM_8064_STATUS_ID_PM8921_S7_1 = 44,
+ MSM_RPM_8064_STATUS_ID_PM8921_S8 = 45,
+ MSM_RPM_8064_STATUS_ID_PM8921_S8_1 = 46,
+ MSM_RPM_8064_STATUS_ID_PM8921_L1 = 47,
+ MSM_RPM_8064_STATUS_ID_PM8921_L1_1 = 48,
+ MSM_RPM_8064_STATUS_ID_PM8921_L2 = 49,
+ MSM_RPM_8064_STATUS_ID_PM8921_L2_1 = 50,
+ MSM_RPM_8064_STATUS_ID_PM8921_L3 = 51,
+ MSM_RPM_8064_STATUS_ID_PM8921_L3_1 = 52,
+ MSM_RPM_8064_STATUS_ID_PM8921_L4 = 53,
+ MSM_RPM_8064_STATUS_ID_PM8921_L4_1 = 54,
+ MSM_RPM_8064_STATUS_ID_PM8921_L5 = 55,
+ MSM_RPM_8064_STATUS_ID_PM8921_L5_1 = 56,
+ MSM_RPM_8064_STATUS_ID_PM8921_L6 = 57,
+ MSM_RPM_8064_STATUS_ID_PM8921_L6_1 = 58,
+ MSM_RPM_8064_STATUS_ID_PM8921_L7 = 59,
+ MSM_RPM_8064_STATUS_ID_PM8921_L7_1 = 60,
+ MSM_RPM_8064_STATUS_ID_PM8921_L8 = 61,
+ MSM_RPM_8064_STATUS_ID_PM8921_L8_1 = 62,
+ MSM_RPM_8064_STATUS_ID_PM8921_L9 = 63,
+ MSM_RPM_8064_STATUS_ID_PM8921_L9_1 = 64,
+ MSM_RPM_8064_STATUS_ID_PM8921_L10 = 65,
+ MSM_RPM_8064_STATUS_ID_PM8921_L10_1 = 66,
+ MSM_RPM_8064_STATUS_ID_PM8921_L11 = 67,
+ MSM_RPM_8064_STATUS_ID_PM8921_L11_1 = 68,
+ MSM_RPM_8064_STATUS_ID_PM8921_L12 = 69,
+ MSM_RPM_8064_STATUS_ID_PM8921_L12_1 = 70,
+ MSM_RPM_8064_STATUS_ID_PM8921_L13 = 71,
+ MSM_RPM_8064_STATUS_ID_PM8921_L13_1 = 72,
+ MSM_RPM_8064_STATUS_ID_PM8921_L14 = 73,
+ MSM_RPM_8064_STATUS_ID_PM8921_L14_1 = 74,
+ MSM_RPM_8064_STATUS_ID_PM8921_L15 = 75,
+ MSM_RPM_8064_STATUS_ID_PM8921_L15_1 = 76,
+ MSM_RPM_8064_STATUS_ID_PM8921_L16 = 77,
+ MSM_RPM_8064_STATUS_ID_PM8921_L16_1 = 78,
+ MSM_RPM_8064_STATUS_ID_PM8921_L17 = 79,
+ MSM_RPM_8064_STATUS_ID_PM8921_L17_1 = 80,
+ MSM_RPM_8064_STATUS_ID_PM8921_L18 = 81,
+ MSM_RPM_8064_STATUS_ID_PM8921_L18_1 = 82,
+ MSM_RPM_8064_STATUS_ID_PM8921_L19 = 83,
+ MSM_RPM_8064_STATUS_ID_PM8921_L19_1 = 84,
+ MSM_RPM_8064_STATUS_ID_PM8921_L20 = 85,
+ MSM_RPM_8064_STATUS_ID_PM8921_L20_1 = 86,
+ MSM_RPM_8064_STATUS_ID_PM8921_L21 = 87,
+ MSM_RPM_8064_STATUS_ID_PM8921_L21_1 = 88,
+ MSM_RPM_8064_STATUS_ID_PM8921_L22 = 89,
+ MSM_RPM_8064_STATUS_ID_PM8921_L22_1 = 90,
+ MSM_RPM_8064_STATUS_ID_PM8921_L23 = 91,
+ MSM_RPM_8064_STATUS_ID_PM8921_L23_1 = 92,
+ MSM_RPM_8064_STATUS_ID_PM8921_L24 = 93,
+ MSM_RPM_8064_STATUS_ID_PM8921_L24_1 = 94,
+ MSM_RPM_8064_STATUS_ID_PM8921_L25 = 95,
+ MSM_RPM_8064_STATUS_ID_PM8921_L25_1 = 96,
+ MSM_RPM_8064_STATUS_ID_PM8921_L26 = 97,
+ MSM_RPM_8064_STATUS_ID_PM8921_L26_1 = 98,
+ MSM_RPM_8064_STATUS_ID_PM8921_L27 = 99,
+ MSM_RPM_8064_STATUS_ID_PM8921_L27_1 = 100,
+ MSM_RPM_8064_STATUS_ID_PM8921_L28 = 101,
+ MSM_RPM_8064_STATUS_ID_PM8921_L28_1 = 102,
+ MSM_RPM_8064_STATUS_ID_PM8921_L29 = 103,
+ MSM_RPM_8064_STATUS_ID_PM8921_L29_1 = 104,
+ MSM_RPM_8064_STATUS_ID_PM8921_CLK1 = 105,
+ MSM_RPM_8064_STATUS_ID_PM8921_CLK1_1 = 106,
+ MSM_RPM_8064_STATUS_ID_PM8921_CLK2 = 107,
+ MSM_RPM_8064_STATUS_ID_PM8921_CLK2_1 = 108,
+ MSM_RPM_8064_STATUS_ID_PM8921_LVS1 = 109,
+ MSM_RPM_8064_STATUS_ID_PM8921_LVS2 = 110,
+ MSM_RPM_8064_STATUS_ID_PM8921_LVS3 = 111,
+ MSM_RPM_8064_STATUS_ID_PM8921_LVS4 = 112,
+ MSM_RPM_8064_STATUS_ID_PM8921_LVS5 = 113,
+ MSM_RPM_8064_STATUS_ID_PM8921_LVS6 = 114,
+ MSM_RPM_8064_STATUS_ID_PM8921_LVS7 = 115,
+ MSM_RPM_8064_STATUS_ID_PM8821_S1 = 116,
+ MSM_RPM_8064_STATUS_ID_PM8821_S1_1 = 117,
+ MSM_RPM_8064_STATUS_ID_PM8821_S2 = 118,
+ MSM_RPM_8064_STATUS_ID_PM8821_S2_1 = 119,
+ MSM_RPM_8064_STATUS_ID_PM8821_L1 = 120,
+ MSM_RPM_8064_STATUS_ID_PM8821_L1_1 = 121,
+ MSM_RPM_8064_STATUS_ID_NCP = 122,
+ MSM_RPM_8064_STATUS_ID_NCP_1 = 123,
+ MSM_RPM_8064_STATUS_ID_CXO_BUFFERS = 124,
+ MSM_RPM_8064_STATUS_ID_USB_OTG_SWITCH = 125,
+ MSM_RPM_8064_STATUS_ID_HDMI_SWITCH = 126,
+ MSM_RPM_8064_STATUS_ID_DDR_DMM = 127,
+ MSM_RPM_8064_STATUS_ID_DDR_DMM_1 = 128,
+ MSM_RPM_8064_STATUS_ID_EBI1_CH0_RANGE = 129,
+ MSM_RPM_8064_STATUS_ID_EBI1_CH1_RANGE = 130,
+ MSM_RPM_8064_STATUS_ID_VDDMIN_GPIO = 131,
+
+ MSM_RPM_8064_STATUS_ID_LAST = MSM_RPM_8064_STATUS_ID_VDDMIN_GPIO,
+};
+
+#endif /* __ARCH_ARM_MACH_MSM_RPM_8064_H */
diff --git a/drivers/mfd/msm_rpm-8960.h b/drivers/mfd/msm_rpm-8960.h
new file mode 100644
index 0000000..6513037
--- /dev/null
+++ b/drivers/mfd/msm_rpm-8960.h
@@ -0,0 +1,400 @@
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_RPM_8960_H
+#define __ARCH_ARM_MACH_MSM_RPM_8960_H
+
+/* RPM resource select enums defined for RPM core
+ NOT IN SEQUENTIAL ORDER */
+enum {
+ MSM_RPM_8960_SEL_NOTIFICATION = 0,
+ MSM_RPM_8960_SEL_INVALIDATE = 1,
+ MSM_RPM_8960_SEL_TRIGGER_TIMED = 2,
+ MSM_RPM_8960_SEL_RPM_CTL = 3,
+
+ MSM_RPM_8960_SEL_CXO_CLK = 5,
+ MSM_RPM_8960_SEL_PXO_CLK = 6,
+ MSM_RPM_8960_SEL_QDSS_CLK = 7,
+ MSM_RPM_8960_SEL_APPS_FABRIC_CLK = 8,
+ MSM_RPM_8960_SEL_SYSTEM_FABRIC_CLK = 9,
+ MSM_RPM_8960_SEL_MM_FABRIC_CLK = 10,
+ MSM_RPM_8960_SEL_DAYTONA_FABRIC_CLK = 11,
+ MSM_RPM_8960_SEL_SFPB_CLK = 12,
+ MSM_RPM_8960_SEL_CFPB_CLK = 13,
+ MSM_RPM_8960_SEL_MMFPB_CLK = 14,
+ MSM_RPM_8960_SEL_EBI1_CLK = 16,
+
+ MSM_RPM_8960_SEL_APPS_FABRIC_CFG_HALT = 18,
+ MSM_RPM_8960_SEL_APPS_FABRIC_CFG_CLKMOD = 19,
+ MSM_RPM_8960_SEL_APPS_FABRIC_CFG_IOCTL = 20,
+ MSM_RPM_8960_SEL_APPS_FABRIC_ARB = 21,
+
+ MSM_RPM_8960_SEL_SYS_FABRIC_CFG_HALT = 22,
+ MSM_RPM_8960_SEL_SYS_FABRIC_CFG_CLKMOD = 23,
+ MSM_RPM_8960_SEL_SYS_FABRIC_CFG_IOCTL = 24,
+ MSM_RPM_8960_SEL_SYSTEM_FABRIC_ARB = 25,
+
+ MSM_RPM_8960_SEL_MMSS_FABRIC_CFG_HALT = 26,
+ MSM_RPM_8960_SEL_MMSS_FABRIC_CFG_CLKMOD = 27,
+ MSM_RPM_8960_SEL_MMSS_FABRIC_CFG_IOCTL = 28,
+ MSM_RPM_8960_SEL_MM_FABRIC_ARB = 29,
+
+ MSM_RPM_8960_SEL_PM8921_S1 = 30,
+ MSM_RPM_8960_SEL_PM8921_S2 = 31,
+ MSM_RPM_8960_SEL_PM8921_S3 = 32,
+ MSM_RPM_8960_SEL_PM8921_S4 = 33,
+ MSM_RPM_8960_SEL_PM8921_S5 = 34,
+ MSM_RPM_8960_SEL_PM8921_S6 = 35,
+ MSM_RPM_8960_SEL_PM8921_S7 = 36,
+ MSM_RPM_8960_SEL_PM8921_S8 = 37,
+ MSM_RPM_8960_SEL_PM8921_L1 = 38,
+ MSM_RPM_8960_SEL_PM8921_L2 = 39,
+ MSM_RPM_8960_SEL_PM8921_L3 = 40,
+ MSM_RPM_8960_SEL_PM8921_L4 = 41,
+ MSM_RPM_8960_SEL_PM8921_L5 = 42,
+ MSM_RPM_8960_SEL_PM8921_L6 = 43,
+ MSM_RPM_8960_SEL_PM8921_L7 = 44,
+ MSM_RPM_8960_SEL_PM8921_L8 = 45,
+ MSM_RPM_8960_SEL_PM8921_L9 = 46,
+ MSM_RPM_8960_SEL_PM8921_L10 = 47,
+ MSM_RPM_8960_SEL_PM8921_L11 = 48,
+ MSM_RPM_8960_SEL_PM8921_L12 = 49,
+ MSM_RPM_8960_SEL_PM8921_L13 = 50,
+ MSM_RPM_8960_SEL_PM8921_L14 = 51,
+ MSM_RPM_8960_SEL_PM8921_L15 = 52,
+ MSM_RPM_8960_SEL_PM8921_L16 = 53,
+ MSM_RPM_8960_SEL_PM8921_L17 = 54,
+ MSM_RPM_8960_SEL_PM8921_L18 = 55,
+ MSM_RPM_8960_SEL_PM8921_L19 = 56,
+ MSM_RPM_8960_SEL_PM8921_L20 = 57,
+ MSM_RPM_8960_SEL_PM8921_L21 = 58,
+ MSM_RPM_8960_SEL_PM8921_L22 = 59,
+ MSM_RPM_8960_SEL_PM8921_L23 = 60,
+ MSM_RPM_8960_SEL_PM8921_L24 = 61,
+ MSM_RPM_8960_SEL_PM8921_L25 = 62,
+ MSM_RPM_8960_SEL_PM8921_L26 = 63,
+ MSM_RPM_8960_SEL_PM8921_L27 = 64,
+ MSM_RPM_8960_SEL_PM8921_L28 = 65,
+ MSM_RPM_8960_SEL_PM8921_L29 = 66,
+ MSM_RPM_8960_SEL_PM8921_CLK1 = 67,
+ MSM_RPM_8960_SEL_PM8921_CLK2 = 68,
+ MSM_RPM_8960_SEL_PM8921_LVS1 = 69,
+ MSM_RPM_8960_SEL_PM8921_LVS2 = 70,
+ MSM_RPM_8960_SEL_PM8921_LVS3 = 71,
+ MSM_RPM_8960_SEL_PM8921_LVS4 = 72,
+ MSM_RPM_8960_SEL_PM8921_LVS5 = 73,
+ MSM_RPM_8960_SEL_PM8921_LVS6 = 74,
+ MSM_RPM_8960_SEL_PM8921_LVS7 = 75,
+
+ MSM_RPM_8960_SEL_NCP = 80,
+ MSM_RPM_8960_SEL_CXO_BUFFERS = 81,
+ MSM_RPM_8960_SEL_USB_OTG_SWITCH = 82,
+ MSM_RPM_8960_SEL_HDMI_SWITCH = 83,
+ MSM_RPM_8960_SEL_DDR_DMM = 84,
+
+ MSM_RPM_8960_SEL_LAST = MSM_RPM_8960_SEL_DDR_DMM,
+};
+
+/* RPM resource (4 byte) word ID enum */
+enum {
+ MSM_RPM_8960_ID_NOTIFICATION_CONFIGURED = 0,
+ MSM_RPM_8960_ID_NOTIFICATION_CONFIGURED_3 =
+ MSM_RPM_8960_ID_NOTIFICATION_CONFIGURED + 3,
+
+ MSM_RPM_8960_ID_NOTIFICATION_REGISTERED = 4,
+ MSM_RPM_8960_ID_NOTIFICATION_REGISTERED_3 =
+ MSM_RPM_8960_ID_NOTIFICATION_REGISTERED + 3,
+
+ MSM_RPM_8960_ID_INVALIDATE = 8,
+ MSM_RPM_8960_ID_INVALIDATE_7 =
+ MSM_RPM_8960_ID_INVALIDATE + 7,
+
+ MSM_RPM_8960_ID_TRIGGER_TIMED_TO = 16,
+ MSM_RPM_8960_ID_TRIGGER_TIMED_SCLK_COUNT = 17,
+
+ MSM_RPM_8960_ID_RPM_CTL = 18,
+
+ /* TRIGGER_CLEAR/SET deprecated in these 24 RESERVED bytes */
+ MSM_RPM_8960_ID_RESERVED = 19,
+ MSM_RPM_8960_ID_RESERVED_5 =
+ MSM_RPM_8960_ID_RESERVED + 5,
+
+ MSM_RPM_8960_ID_CXO_CLK = 25,
+ MSM_RPM_8960_ID_PXO_CLK = 26,
+ MSM_RPM_8960_ID_APPS_FABRIC_CLK = 27,
+ MSM_RPM_8960_ID_SYSTEM_FABRIC_CLK = 28,
+ MSM_RPM_8960_ID_MM_FABRIC_CLK = 29,
+ MSM_RPM_8960_ID_DAYTONA_FABRIC_CLK = 30,
+ MSM_RPM_8960_ID_SFPB_CLK = 31,
+ MSM_RPM_8960_ID_CFPB_CLK = 32,
+ MSM_RPM_8960_ID_MMFPB_CLK = 33,
+ MSM_RPM_8960_ID_EBI1_CLK = 34,
+
+ MSM_RPM_8960_ID_APPS_FABRIC_CFG_HALT = 35,
+ MSM_RPM_8960_ID_APPS_FABRIC_CFG_HALT_1 = 36,
+ MSM_RPM_8960_ID_APPS_FABRIC_CFG_CLKMOD = 37,
+ MSM_RPM_8960_ID_APPS_FABRIC_CFG_CLKMOD_1 = 38,
+ MSM_RPM_8960_ID_APPS_FABRIC_CFG_CLKMOD_2 = 39,
+ MSM_RPM_8960_ID_APPS_FABRIC_CFG_IOCTL = 40,
+ MSM_RPM_8960_ID_APPS_FABRIC_ARB = 41,
+ MSM_RPM_8960_ID_APPS_FABRIC_ARB_11 =
+ MSM_RPM_8960_ID_APPS_FABRIC_ARB + 11,
+
+ MSM_RPM_8960_ID_SYS_FABRIC_CFG_HALT = 53,
+ MSM_RPM_8960_ID_SYS_FABRIC_CFG_HALT_1 = 54,
+ MSM_RPM_8960_ID_SYS_FABRIC_CFG_CLKMOD = 55,
+ MSM_RPM_8960_ID_SYS_FABRIC_CFG_CLKMOD_1 = 56,
+ MSM_RPM_8960_ID_SYS_FABRIC_CFG_CLKMOD_2 = 57,
+ MSM_RPM_8960_ID_SYS_FABRIC_CFG_IOCTL = 58,
+ MSM_RPM_8960_ID_SYSTEM_FABRIC_ARB = 59,
+ MSM_RPM_8960_ID_SYSTEM_FABRIC_ARB_28 =
+ MSM_RPM_8960_ID_SYSTEM_FABRIC_ARB + 28,
+
+ MSM_RPM_8960_ID_MMSS_FABRIC_CFG_HALT = 88,
+ MSM_RPM_8960_ID_MMSS_FABRIC_CFG_HALT_1 = 89,
+ MSM_RPM_8960_ID_MMSS_FABRIC_CFG_CLKMOD = 90,
+ MSM_RPM_8960_ID_MMSS_FABRIC_CFG_CLKMOD_1 = 91,
+ MSM_RPM_8960_ID_MMSS_FABRIC_CFG_CLKMOD_2 = 92,
+ MSM_RPM_8960_ID_MMSS_FABRIC_CFG_IOCTL = 93,
+ MSM_RPM_8960_ID_MM_FABRIC_ARB = 94,
+ MSM_RPM_8960_ID_MM_FABRIC_ARB_22 =
+ MSM_RPM_8960_ID_MM_FABRIC_ARB + 22,
+
+ MSM_RPM_8960_ID_PM8921_S1 = 117,
+ MSM_RPM_8960_ID_PM8921_S1_1 = 118,
+ MSM_RPM_8960_ID_PM8921_S2 = 119,
+ MSM_RPM_8960_ID_PM8921_S2_1 = 120,
+ MSM_RPM_8960_ID_PM8921_S3 = 121,
+ MSM_RPM_8960_ID_PM8921_S3_1 = 122,
+ MSM_RPM_8960_ID_PM8921_S4 = 123,
+ MSM_RPM_8960_ID_PM8921_S4_1 = 124,
+ MSM_RPM_8960_ID_PM8921_S5 = 125,
+ MSM_RPM_8960_ID_PM8921_S5_1 = 126,
+ MSM_RPM_8960_ID_PM8921_S6 = 127,
+ MSM_RPM_8960_ID_PM8921_S6_1 = 128,
+ MSM_RPM_8960_ID_PM8921_S7 = 129,
+ MSM_RPM_8960_ID_PM8921_S7_1 = 130,
+ MSM_RPM_8960_ID_PM8921_S8 = 131,
+ MSM_RPM_8960_ID_PM8921_S8_1 = 132,
+ MSM_RPM_8960_ID_PM8921_L1 = 133,
+ MSM_RPM_8960_ID_PM8921_L1_1 = 134,
+ MSM_RPM_8960_ID_PM8921_L2 = 135,
+ MSM_RPM_8960_ID_PM8921_L2_1 = 136,
+ MSM_RPM_8960_ID_PM8921_L3 = 137,
+ MSM_RPM_8960_ID_PM8921_L3_1 = 138,
+ MSM_RPM_8960_ID_PM8921_L4 = 139,
+ MSM_RPM_8960_ID_PM8921_L4_1 = 140,
+ MSM_RPM_8960_ID_PM8921_L5 = 141,
+ MSM_RPM_8960_ID_PM8921_L5_1 = 142,
+ MSM_RPM_8960_ID_PM8921_L6 = 143,
+ MSM_RPM_8960_ID_PM8921_L6_1 = 144,
+ MSM_RPM_8960_ID_PM8921_L7 = 145,
+ MSM_RPM_8960_ID_PM8921_L7_1 = 146,
+ MSM_RPM_8960_ID_PM8921_L8 = 147,
+ MSM_RPM_8960_ID_PM8921_L8_1 = 148,
+ MSM_RPM_8960_ID_PM8921_L9 = 149,
+ MSM_RPM_8960_ID_PM8921_L9_1 = 150,
+ MSM_RPM_8960_ID_PM8921_L10 = 151,
+ MSM_RPM_8960_ID_PM8921_L10_1 = 152,
+ MSM_RPM_8960_ID_PM8921_L11 = 153,
+ MSM_RPM_8960_ID_PM8921_L11_1 = 154,
+ MSM_RPM_8960_ID_PM8921_L12 = 155,
+ MSM_RPM_8960_ID_PM8921_L12_1 = 156,
+ MSM_RPM_8960_ID_PM8921_L13 = 157,
+ MSM_RPM_8960_ID_PM8921_L13_1 = 158,
+ MSM_RPM_8960_ID_PM8921_L14 = 159,
+ MSM_RPM_8960_ID_PM8921_L14_1 = 160,
+ MSM_RPM_8960_ID_PM8921_L15 = 161,
+ MSM_RPM_8960_ID_PM8921_L15_1 = 162,
+ MSM_RPM_8960_ID_PM8921_L16 = 163,
+ MSM_RPM_8960_ID_PM8921_L16_1 = 164,
+ MSM_RPM_8960_ID_PM8921_L17 = 165,
+ MSM_RPM_8960_ID_PM8921_L17_1 = 166,
+ MSM_RPM_8960_ID_PM8921_L18 = 167,
+ MSM_RPM_8960_ID_PM8921_L18_1 = 168,
+ MSM_RPM_8960_ID_PM8921_L19 = 169,
+ MSM_RPM_8960_ID_PM8921_L19_1 = 170,
+ MSM_RPM_8960_ID_PM8921_L20 = 171,
+ MSM_RPM_8960_ID_PM8921_L20_1 = 172,
+ MSM_RPM_8960_ID_PM8921_L21 = 173,
+ MSM_RPM_8960_ID_PM8921_L21_1 = 174,
+ MSM_RPM_8960_ID_PM8921_L22 = 175,
+ MSM_RPM_8960_ID_PM8921_L22_1 = 176,
+ MSM_RPM_8960_ID_PM8921_L23 = 177,
+ MSM_RPM_8960_ID_PM8921_L23_1 = 178,
+ MSM_RPM_8960_ID_PM8921_L24 = 179,
+ MSM_RPM_8960_ID_PM8921_L24_1 = 180,
+ MSM_RPM_8960_ID_PM8921_L25 = 181,
+ MSM_RPM_8960_ID_PM8921_L25_1 = 182,
+ MSM_RPM_8960_ID_PM8921_L26 = 183,
+ MSM_RPM_8960_ID_PM8921_L26_1 = 184,
+ MSM_RPM_8960_ID_PM8921_L27 = 185,
+ MSM_RPM_8960_ID_PM8921_L27_1 = 186,
+ MSM_RPM_8960_ID_PM8921_L28 = 187,
+ MSM_RPM_8960_ID_PM8921_L28_1 = 188,
+ MSM_RPM_8960_ID_PM8921_L29 = 189,
+ MSM_RPM_8960_ID_PM8921_L29_1 = 190,
+ MSM_RPM_8960_ID_PM8921_CLK1 = 191,
+ MSM_RPM_8960_ID_PM8921_CLK1_1 = 192,
+ MSM_RPM_8960_ID_PM8921_CLK2 = 193,
+ MSM_RPM_8960_ID_PM8921_CLK2_1 = 194,
+ MSM_RPM_8960_ID_PM8921_LVS1 = 195,
+ MSM_RPM_8960_ID_PM8921_LVS2 = 196,
+ MSM_RPM_8960_ID_PM8921_LVS3 = 197,
+ MSM_RPM_8960_ID_PM8921_LVS4 = 198,
+ MSM_RPM_8960_ID_PM8921_LVS5 = 199,
+ MSM_RPM_8960_ID_PM8921_LVS6 = 200,
+ MSM_RPM_8960_ID_PM8921_LVS7 = 201,
+ MSM_RPM_8960_ID_NCP = 202,
+ MSM_RPM_8960_ID_NCP_1 = 203,
+ MSM_RPM_8960_ID_CXO_BUFFERS = 204,
+ MSM_RPM_8960_ID_USB_OTG_SWITCH = 205,
+ MSM_RPM_8960_ID_HDMI_SWITCH = 206,
+ MSM_RPM_8960_ID_DDR_DMM = 207,
+ MSM_RPM_8960_ID_DDR_DMM_1 = 208,
+ MSM_RPM_8960_ID_QDSS_CLK = 209,
+
+ MSM_RPM_8960_ID_LAST = MSM_RPM_8960_ID_QDSS_CLK,
+};
+
+/* RPM status ID enum */
+enum {
+ MSM_RPM_8960_STATUS_ID_VERSION_MAJOR = 0,
+ MSM_RPM_8960_STATUS_ID_VERSION_MINOR = 1,
+ MSM_RPM_8960_STATUS_ID_VERSION_BUILD = 2,
+ MSM_RPM_8960_STATUS_ID_SUPPORTED_RESOURCES = 3,
+ MSM_RPM_8960_STATUS_ID_SUPPORTED_RESOURCES_1 = 4,
+ MSM_RPM_8960_STATUS_ID_SUPPORTED_RESOURCES_2 = 5,
+ MSM_RPM_8960_STATUS_ID_RESERVED_SUPPORTED_RESOURCES = 6,
+ MSM_RPM_8960_STATUS_ID_SEQUENCE = 7,
+ MSM_RPM_8960_STATUS_ID_RPM_CTL = 8,
+ MSM_RPM_8960_STATUS_ID_CXO_CLK = 9,
+ MSM_RPM_8960_STATUS_ID_PXO_CLK = 10,
+ MSM_RPM_8960_STATUS_ID_APPS_FABRIC_CLK = 11,
+ MSM_RPM_8960_STATUS_ID_SYSTEM_FABRIC_CLK = 12,
+ MSM_RPM_8960_STATUS_ID_MM_FABRIC_CLK = 13,
+ MSM_RPM_8960_STATUS_ID_DAYTONA_FABRIC_CLK = 14,
+ MSM_RPM_8960_STATUS_ID_SFPB_CLK = 15,
+ MSM_RPM_8960_STATUS_ID_CFPB_CLK = 16,
+ MSM_RPM_8960_STATUS_ID_MMFPB_CLK = 17,
+ MSM_RPM_8960_STATUS_ID_EBI1_CLK = 18,
+ MSM_RPM_8960_STATUS_ID_APPS_FABRIC_CFG_HALT = 19,
+ MSM_RPM_8960_STATUS_ID_APPS_FABRIC_CFG_CLKMOD = 20,
+ MSM_RPM_8960_STATUS_ID_APPS_FABRIC_CFG_IOCTL = 21,
+ MSM_RPM_8960_STATUS_ID_APPS_FABRIC_ARB = 22,
+ MSM_RPM_8960_STATUS_ID_SYS_FABRIC_CFG_HALT = 23,
+ MSM_RPM_8960_STATUS_ID_SYS_FABRIC_CFG_CLKMOD = 24,
+ MSM_RPM_8960_STATUS_ID_SYS_FABRIC_CFG_IOCTL = 25,
+ MSM_RPM_8960_STATUS_ID_SYSTEM_FABRIC_ARB = 26,
+ MSM_RPM_8960_STATUS_ID_MMSS_FABRIC_CFG_HALT = 27,
+ MSM_RPM_8960_STATUS_ID_MMSS_FABRIC_CFG_CLKMOD = 28,
+ MSM_RPM_8960_STATUS_ID_MMSS_FABRIC_CFG_IOCTL = 29,
+ MSM_RPM_8960_STATUS_ID_MM_FABRIC_ARB = 30,
+ MSM_RPM_8960_STATUS_ID_PM8921_S1 = 31,
+ MSM_RPM_8960_STATUS_ID_PM8921_S1_1 = 32,
+ MSM_RPM_8960_STATUS_ID_PM8921_S2 = 33,
+ MSM_RPM_8960_STATUS_ID_PM8921_S2_1 = 34,
+ MSM_RPM_8960_STATUS_ID_PM8921_S3 = 35,
+ MSM_RPM_8960_STATUS_ID_PM8921_S3_1 = 36,
+ MSM_RPM_8960_STATUS_ID_PM8921_S4 = 37,
+ MSM_RPM_8960_STATUS_ID_PM8921_S4_1 = 38,
+ MSM_RPM_8960_STATUS_ID_PM8921_S5 = 39,
+ MSM_RPM_8960_STATUS_ID_PM8921_S5_1 = 40,
+ MSM_RPM_8960_STATUS_ID_PM8921_S6 = 41,
+ MSM_RPM_8960_STATUS_ID_PM8921_S6_1 = 42,
+ MSM_RPM_8960_STATUS_ID_PM8921_S7 = 43,
+ MSM_RPM_8960_STATUS_ID_PM8921_S7_1 = 44,
+ MSM_RPM_8960_STATUS_ID_PM8921_S8 = 45,
+ MSM_RPM_8960_STATUS_ID_PM8921_S8_1 = 46,
+ MSM_RPM_8960_STATUS_ID_PM8921_L1 = 47,
+ MSM_RPM_8960_STATUS_ID_PM8921_L1_1 = 48,
+ MSM_RPM_8960_STATUS_ID_PM8921_L2 = 49,
+ MSM_RPM_8960_STATUS_ID_PM8921_L2_1 = 50,
+ MSM_RPM_8960_STATUS_ID_PM8921_L3 = 51,
+ MSM_RPM_8960_STATUS_ID_PM8921_L3_1 = 52,
+ MSM_RPM_8960_STATUS_ID_PM8921_L4 = 53,
+ MSM_RPM_8960_STATUS_ID_PM8921_L4_1 = 54,
+ MSM_RPM_8960_STATUS_ID_PM8921_L5 = 55,
+ MSM_RPM_8960_STATUS_ID_PM8921_L5_1 = 56,
+ MSM_RPM_8960_STATUS_ID_PM8921_L6 = 57,
+ MSM_RPM_8960_STATUS_ID_PM8921_L6_1 = 58,
+ MSM_RPM_8960_STATUS_ID_PM8921_L7 = 59,
+ MSM_RPM_8960_STATUS_ID_PM8921_L7_1 = 60,
+ MSM_RPM_8960_STATUS_ID_PM8921_L8 = 61,
+ MSM_RPM_8960_STATUS_ID_PM8921_L8_1 = 62,
+ MSM_RPM_8960_STATUS_ID_PM8921_L9 = 63,
+ MSM_RPM_8960_STATUS_ID_PM8921_L9_1 = 64,
+ MSM_RPM_8960_STATUS_ID_PM8921_L10 = 65,
+ MSM_RPM_8960_STATUS_ID_PM8921_L10_1 = 66,
+ MSM_RPM_8960_STATUS_ID_PM8921_L11 = 67,
+ MSM_RPM_8960_STATUS_ID_PM8921_L11_1 = 68,
+ MSM_RPM_8960_STATUS_ID_PM8921_L12 = 69,
+ MSM_RPM_8960_STATUS_ID_PM8921_L12_1 = 70,
+ MSM_RPM_8960_STATUS_ID_PM8921_L13 = 71,
+ MSM_RPM_8960_STATUS_ID_PM8921_L13_1 = 72,
+ MSM_RPM_8960_STATUS_ID_PM8921_L14 = 73,
+ MSM_RPM_8960_STATUS_ID_PM8921_L14_1 = 74,
+ MSM_RPM_8960_STATUS_ID_PM8921_L15 = 75,
+ MSM_RPM_8960_STATUS_ID_PM8921_L15_1 = 76,
+ MSM_RPM_8960_STATUS_ID_PM8921_L16 = 77,
+ MSM_RPM_8960_STATUS_ID_PM8921_L16_1 = 78,
+ MSM_RPM_8960_STATUS_ID_PM8921_L17 = 79,
+ MSM_RPM_8960_STATUS_ID_PM8921_L17_1 = 80,
+ MSM_RPM_8960_STATUS_ID_PM8921_L18 = 81,
+ MSM_RPM_8960_STATUS_ID_PM8921_L18_1 = 82,
+ MSM_RPM_8960_STATUS_ID_PM8921_L19 = 83,
+ MSM_RPM_8960_STATUS_ID_PM8921_L19_1 = 84,
+ MSM_RPM_8960_STATUS_ID_PM8921_L20 = 85,
+ MSM_RPM_8960_STATUS_ID_PM8921_L20_1 = 86,
+ MSM_RPM_8960_STATUS_ID_PM8921_L21 = 87,
+ MSM_RPM_8960_STATUS_ID_PM8921_L21_1 = 88,
+ MSM_RPM_8960_STATUS_ID_PM8921_L22 = 89,
+ MSM_RPM_8960_STATUS_ID_PM8921_L22_1 = 90,
+ MSM_RPM_8960_STATUS_ID_PM8921_L23 = 91,
+ MSM_RPM_8960_STATUS_ID_PM8921_L23_1 = 92,
+ MSM_RPM_8960_STATUS_ID_PM8921_L24 = 93,
+ MSM_RPM_8960_STATUS_ID_PM8921_L24_1 = 94,
+ MSM_RPM_8960_STATUS_ID_PM8921_L25 = 95,
+ MSM_RPM_8960_STATUS_ID_PM8921_L25_1 = 96,
+ MSM_RPM_8960_STATUS_ID_PM8921_L26 = 97,
+ MSM_RPM_8960_STATUS_ID_PM8921_L26_1 = 98,
+ MSM_RPM_8960_STATUS_ID_PM8921_L27 = 99,
+ MSM_RPM_8960_STATUS_ID_PM8921_L27_1 = 100,
+ MSM_RPM_8960_STATUS_ID_PM8921_L28 = 101,
+ MSM_RPM_8960_STATUS_ID_PM8921_L28_1 = 102,
+ MSM_RPM_8960_STATUS_ID_PM8921_L29 = 103,
+ MSM_RPM_8960_STATUS_ID_PM8921_L29_1 = 104,
+ MSM_RPM_8960_STATUS_ID_PM8921_CLK1 = 105,
+ MSM_RPM_8960_STATUS_ID_PM8921_CLK1_1 = 106,
+ MSM_RPM_8960_STATUS_ID_PM8921_CLK2 = 107,
+ MSM_RPM_8960_STATUS_ID_PM8921_CLK2_1 = 108,
+ MSM_RPM_8960_STATUS_ID_PM8921_LVS1 = 109,
+ MSM_RPM_8960_STATUS_ID_PM8921_LVS2 = 110,
+ MSM_RPM_8960_STATUS_ID_PM8921_LVS3 = 111,
+ MSM_RPM_8960_STATUS_ID_PM8921_LVS4 = 112,
+ MSM_RPM_8960_STATUS_ID_PM8921_LVS5 = 113,
+ MSM_RPM_8960_STATUS_ID_PM8921_LVS6 = 114,
+ MSM_RPM_8960_STATUS_ID_PM8921_LVS7 = 115,
+ MSM_RPM_8960_STATUS_ID_NCP = 116,
+ MSM_RPM_8960_STATUS_ID_NCP_1 = 117,
+ MSM_RPM_8960_STATUS_ID_CXO_BUFFERS = 118,
+ MSM_RPM_8960_STATUS_ID_USB_OTG_SWITCH = 119,
+ MSM_RPM_8960_STATUS_ID_HDMI_SWITCH = 120,
+ MSM_RPM_8960_STATUS_ID_DDR_DMM = 121,
+ MSM_RPM_8960_STATUS_ID_DDR_DMM_1 = 122,
+ MSM_RPM_8960_STATUS_ID_EBI1_CH0_RANGE = 123,
+ MSM_RPM_8960_STATUS_ID_EBI1_CH1_RANGE = 124,
+
+ MSM_RPM_8960_STATUS_ID_LAST = MSM_RPM_8960_STATUS_ID_EBI1_CH1_RANGE,
+};
+
+#endif /* __ARCH_ARM_MACH_MSM_RPM_8960_H */
diff --git a/drivers/mfd/msm_rpm.c b/drivers/mfd/msm_rpm.c
new file mode 100644
index 0000000..63df2e2
--- /dev/null
+++ b/drivers/mfd/msm_rpm.c
@@ -0,0 +1,525 @@
+/*
+ * Copyright (c) 2013, Sony Mobile Communications AB.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+
+#include <linux/mfd/msm_rpm.h>
+
+#include "msm_rpm-8064.h"
+#include "msm_rpm-8960.h"
+
+struct msm_rpm_resource;
+
+struct msm_rpm {
+ struct device *dev;
+ struct completion ack;
+ struct mutex lock;
+
+ int irq_ack;
+ int irq_err;
+ int irq_wakeup;
+
+ void __iomem *status_regs;
+ void __iomem *ctrl_regs;
+ void __iomem *req_regs;
+ void __iomem *ack_regs;
+
+ void __iomem *ipc_rpm_reg;
+
+ unsigned long ack_status;
+
+ u32 version[3];
+
+ const struct msm_rpm_resource *resource_table;
+ unsigned nresources;
+};
+
+#define MSM_STATUS_REG(rpm, i) ((rpm)->status_regs + (i) * 4)
+#define MSM_CTRL_REG(rpm, i) ((rpm)->ctrl_regs + (i) * 4)
+#define MSM_REQ_REG(rpm, i) ((rpm)->req_regs + (i) * 4)
+#define MSM_ACK_REG(rpm, i) ((rpm)->ack_regs + (i) * 4)
+
+struct msm_rpm_resource {
+ unsigned target_id;
+ unsigned status_id;
+ unsigned select_id;
+ unsigned size;
+};
+
+#define MSM_RPM_VERSION 0
+#define MSM_RPM_REQ_CTX 3
+#define MSM_RPM_REQ_SEL 11
+#define MSM_RPM_REQ_SEL_COUNT 7
+#define MSM_RPM_ACK_CTX 15
+#define MSM_RPM_ACK_SEL 23
+#define MSM_RPM_ACK_SEL_COUNT 7
+
+/*
+ * APQ8064 data
+ */
+#define APQ8064_RESOURCE(id, size) \
+ [MSM_RPM_ ## id] = { \
+ MSM_RPM_8064_ID_ ## id, \
+ MSM_RPM_8064_STATUS_ID_ ## id, \
+ MSM_RPM_8064_SEL_ ## id, \
+ size \
+ }
+
+static const struct msm_rpm_resource apq8064_rpm_resource_table[] = {
+ APQ8064_RESOURCE(CXO_CLK, 1),
+ APQ8064_RESOURCE(PXO_CLK, 1),
+ APQ8064_RESOURCE(APPS_FABRIC_CLK, 1),
+ APQ8064_RESOURCE(SYSTEM_FABRIC_CLK, 1),
+ APQ8064_RESOURCE(MM_FABRIC_CLK, 1),
+ APQ8064_RESOURCE(DAYTONA_FABRIC_CLK, 1),
+ APQ8064_RESOURCE(SFPB_CLK, 1),
+ APQ8064_RESOURCE(CFPB_CLK, 1),
+ APQ8064_RESOURCE(MMFPB_CLK, 1),
+ APQ8064_RESOURCE(EBI1_CLK, 1),
+
+ APQ8064_RESOURCE(APPS_FABRIC_CFG_HALT, 1),
+ APQ8064_RESOURCE(APPS_FABRIC_CFG_CLKMOD, 1),
+ APQ8064_RESOURCE(APPS_FABRIC_CFG_IOCTL, 1),
+ APQ8064_RESOURCE(APPS_FABRIC_ARB, 12),
+
+ APQ8064_RESOURCE(SYS_FABRIC_CFG_HALT, 1),
+ APQ8064_RESOURCE(SYS_FABRIC_CFG_CLKMOD, 1),
+ APQ8064_RESOURCE(SYS_FABRIC_CFG_IOCTL, 1),
+ APQ8064_RESOURCE(SYSTEM_FABRIC_ARB, 30),
+
+ APQ8064_RESOURCE(MMSS_FABRIC_CFG_HALT, 1),
+ APQ8064_RESOURCE(MMSS_FABRIC_CFG_CLKMOD, 1),
+ APQ8064_RESOURCE(MMSS_FABRIC_CFG_IOCTL, 1),
+ APQ8064_RESOURCE(MM_FABRIC_ARB, 21),
+
+ APQ8064_RESOURCE(PM8921_S1, 2),
+ APQ8064_RESOURCE(PM8921_S2, 2),
+ APQ8064_RESOURCE(PM8921_S3, 2),
+ APQ8064_RESOURCE(PM8921_S4, 2),
+ APQ8064_RESOURCE(PM8921_S5, 2),
+ APQ8064_RESOURCE(PM8921_S6, 2),
+ APQ8064_RESOURCE(PM8921_S7, 2),
+ APQ8064_RESOURCE(PM8921_S8, 2),
+
+ APQ8064_RESOURCE(PM8921_L1, 2),
+ APQ8064_RESOURCE(PM8921_L2, 2),
+ APQ8064_RESOURCE(PM8921_L3, 2),
+ APQ8064_RESOURCE(PM8921_L4, 2),
+ APQ8064_RESOURCE(PM8921_L5, 2),
+ APQ8064_RESOURCE(PM8921_L6, 2),
+ APQ8064_RESOURCE(PM8921_L7, 2),
+ APQ8064_RESOURCE(PM8921_L8, 2),
+ APQ8064_RESOURCE(PM8921_L9, 2),
+ APQ8064_RESOURCE(PM8921_L10, 2),
+ APQ8064_RESOURCE(PM8921_L11, 2),
+ APQ8064_RESOURCE(PM8921_L12, 2),
+ APQ8064_RESOURCE(PM8921_L13, 2),
+ APQ8064_RESOURCE(PM8921_L14, 2),
+ APQ8064_RESOURCE(PM8921_L15, 2),
+ APQ8064_RESOURCE(PM8921_L16, 2),
+ APQ8064_RESOURCE(PM8921_L17, 2),
+ APQ8064_RESOURCE(PM8921_L18, 2),
+ APQ8064_RESOURCE(PM8921_L19, 2),
+ APQ8064_RESOURCE(PM8921_L20, 2),
+ APQ8064_RESOURCE(PM8921_L21, 2),
+ APQ8064_RESOURCE(PM8921_L22, 2),
+ APQ8064_RESOURCE(PM8921_L23, 2),
+ APQ8064_RESOURCE(PM8921_L24, 2),
+ APQ8064_RESOURCE(PM8921_L25, 2),
+ APQ8064_RESOURCE(PM8921_L26, 2),
+ APQ8064_RESOURCE(PM8921_L27, 2),
+ APQ8064_RESOURCE(PM8921_L28, 2),
+ APQ8064_RESOURCE(PM8921_L29, 2),
+
+ APQ8064_RESOURCE(PM8921_CLK1, 2),
+ APQ8064_RESOURCE(PM8921_CLK2, 2),
+
+ APQ8064_RESOURCE(PM8921_LVS1, 1),
+ APQ8064_RESOURCE(PM8921_LVS2, 1),
+ APQ8064_RESOURCE(PM8921_LVS3, 1),
+ APQ8064_RESOURCE(PM8921_LVS4, 1),
+ APQ8064_RESOURCE(PM8921_LVS5, 1),
+ APQ8064_RESOURCE(PM8921_LVS6, 1),
+ APQ8064_RESOURCE(PM8921_LVS7, 1),
+
+ APQ8064_RESOURCE(PM8821_S1, 2),
+ APQ8064_RESOURCE(PM8821_S2, 2),
+
+ APQ8064_RESOURCE(PM8821_L1, 2),
+
+ APQ8064_RESOURCE(NCP, 2),
+
+ APQ8064_RESOURCE(CXO_BUFFERS, 1),
+
+ APQ8064_RESOURCE(USB_OTG_SWITCH, 1),
+ APQ8064_RESOURCE(HDMI_SWITCH, 1),
+
+ APQ8064_RESOURCE(DDR_DMM, 2),
+ APQ8064_RESOURCE(VDDMIN_GPIO, 1),
+};
+
+static const struct msm_rpm apq8064_template = {
+ .version = { 3, 0, 0 },
+ .resource_table = apq8064_rpm_resource_table,
+ .nresources = ARRAY_SIZE(apq8064_rpm_resource_table),
+};
+
+/*
+ * MSM8960 data
+ */
+#define MSM8960_RESOURCE(id, size) \
+ [MSM_RPM_ ## id] = { \
+ MSM_RPM_8960_ID_ ## id, \
+ MSM_RPM_8960_STATUS_ID_ ## id, \
+ MSM_RPM_8960_SEL_ ## id, \
+ size \
+ }
+
+static const struct msm_rpm_resource msm8960_rpm_resource_table[] = {
+ MSM8960_RESOURCE(CXO_CLK, 1),
+ MSM8960_RESOURCE(PXO_CLK, 1),
+ MSM8960_RESOURCE(APPS_FABRIC_CLK, 1),
+ MSM8960_RESOURCE(SYSTEM_FABRIC_CLK, 1),
+ MSM8960_RESOURCE(MM_FABRIC_CLK, 1),
+ MSM8960_RESOURCE(DAYTONA_FABRIC_CLK, 1),
+ MSM8960_RESOURCE(SFPB_CLK, 1),
+ MSM8960_RESOURCE(CFPB_CLK, 1),
+ MSM8960_RESOURCE(MMFPB_CLK, 1),
+ MSM8960_RESOURCE(EBI1_CLK, 1),
+
+ MSM8960_RESOURCE(APPS_FABRIC_CFG_HALT, 1),
+ MSM8960_RESOURCE(APPS_FABRIC_CFG_CLKMOD, 1),
+ MSM8960_RESOURCE(APPS_FABRIC_CFG_IOCTL, 1),
+ MSM8960_RESOURCE(APPS_FABRIC_ARB, 12),
+
+ MSM8960_RESOURCE(SYS_FABRIC_CFG_HALT, 1),
+ MSM8960_RESOURCE(SYS_FABRIC_CFG_CLKMOD, 1),
+ MSM8960_RESOURCE(SYS_FABRIC_CFG_IOCTL, 1),
+ MSM8960_RESOURCE(SYSTEM_FABRIC_ARB, 29),
+
+ MSM8960_RESOURCE(MMSS_FABRIC_CFG_HALT, 1),
+ MSM8960_RESOURCE(MMSS_FABRIC_CFG_CLKMOD, 1),
+ MSM8960_RESOURCE(MMSS_FABRIC_CFG_IOCTL, 1),
+ MSM8960_RESOURCE(MM_FABRIC_ARB, 23),
+
+ MSM8960_RESOURCE(PM8921_S1, 2),
+ MSM8960_RESOURCE(PM8921_S2, 2),
+ MSM8960_RESOURCE(PM8921_S3, 2),
+ MSM8960_RESOURCE(PM8921_S4, 2),
+ MSM8960_RESOURCE(PM8921_S5, 2),
+ MSM8960_RESOURCE(PM8921_S6, 2),
+ MSM8960_RESOURCE(PM8921_S7, 2),
+ MSM8960_RESOURCE(PM8921_S8, 2),
+ MSM8960_RESOURCE(PM8921_L1, 2),
+ MSM8960_RESOURCE(PM8921_L2, 2),
+ MSM8960_RESOURCE(PM8921_L3, 2),
+ MSM8960_RESOURCE(PM8921_L4, 2),
+ MSM8960_RESOURCE(PM8921_L5, 2),
+ MSM8960_RESOURCE(PM8921_L6, 2),
+ MSM8960_RESOURCE(PM8921_L7, 2),
+ MSM8960_RESOURCE(PM8921_L8, 2),
+ MSM8960_RESOURCE(PM8921_L9, 2),
+ MSM8960_RESOURCE(PM8921_L10, 2),
+ MSM8960_RESOURCE(PM8921_L11, 2),
+ MSM8960_RESOURCE(PM8921_L12, 2),
+ MSM8960_RESOURCE(PM8921_L13, 2),
+ MSM8960_RESOURCE(PM8921_L14, 2),
+ MSM8960_RESOURCE(PM8921_L15, 2),
+ MSM8960_RESOURCE(PM8921_L16, 2),
+ MSM8960_RESOURCE(PM8921_L17, 2),
+ MSM8960_RESOURCE(PM8921_L18, 2),
+ MSM8960_RESOURCE(PM8921_L19, 2),
+ MSM8960_RESOURCE(PM8921_L20, 2),
+ MSM8960_RESOURCE(PM8921_L21, 2),
+ MSM8960_RESOURCE(PM8921_L22, 2),
+ MSM8960_RESOURCE(PM8921_L23, 2),
+ MSM8960_RESOURCE(PM8921_L24, 2),
+ MSM8960_RESOURCE(PM8921_L25, 2),
+ MSM8960_RESOURCE(PM8921_L26, 2),
+ MSM8960_RESOURCE(PM8921_L27, 2),
+ MSM8960_RESOURCE(PM8921_L28, 2),
+ MSM8960_RESOURCE(PM8921_L29, 2),
+ MSM8960_RESOURCE(PM8921_CLK1, 2),
+ MSM8960_RESOURCE(PM8921_CLK2, 2),
+ MSM8960_RESOURCE(PM8921_LVS1, 1),
+ MSM8960_RESOURCE(PM8921_LVS2, 1),
+ MSM8960_RESOURCE(PM8921_LVS3, 1),
+ MSM8960_RESOURCE(PM8921_LVS4, 1),
+ MSM8960_RESOURCE(PM8921_LVS5, 1),
+ MSM8960_RESOURCE(PM8921_LVS6, 1),
+ MSM8960_RESOURCE(PM8921_LVS7, 1),
+
+ MSM8960_RESOURCE(NCP, 2),
+ MSM8960_RESOURCE(CXO_BUFFERS, 1),
+ MSM8960_RESOURCE(USB_OTG_SWITCH, 1),
+ MSM8960_RESOURCE(HDMI_SWITCH, 1),
+ MSM8960_RESOURCE(DDR_DMM, 2),
+};
+
+static const struct msm_rpm msm8960_template = {
+ .version = { 3, 0, 0 },
+ .resource_table = msm8960_rpm_resource_table,
+ .nresources = ARRAY_SIZE(msm8960_rpm_resource_table),
+};
+
+static const struct of_device_id msm_rpm_of_match[] = {
+ { .compatible = "qcom,apq8064-rpm", .data = &apq8064_template },
+ { .compatible = "qcom,msm8960-rpm", .data = &msm8960_template },
+};
+MODULE_DEVICE_TABLE(of, msm_rpm_of_match);
+
+int msm_rpm_write(const struct device *dev, enum msm_rpm_resource_id resource, u32 *buf, size_t size)
+{
+ const struct msm_rpm_resource *res;
+ struct msm_rpm *rpm = dev_get_drvdata(dev);
+ unsigned long sel_mask[MSM_RPM_REQ_SEL_COUNT] = { 0 };
+ int ret = 0;
+ int i;
+
+ if (WARN_ON(resource < 0 || resource >= rpm->nresources))
+ return -EINVAL;
+
+ res = &rpm->resource_table[resource];
+ if (WARN_ON(res->size != size))
+ return -EINVAL;
+
+ mutex_lock(&rpm->lock);
+
+ for (i = 0; i < res->size; i++)
+ writel(buf[i], MSM_REQ_REG(rpm, res->target_id + i));
+
+ bitmap_set(sel_mask, res->select_id, 1);
+ for (i = 0; i < ARRAY_SIZE(sel_mask); i++)
+ writel(sel_mask[i], MSM_CTRL_REG(rpm, MSM_RPM_REQ_SEL + i));
+
+ /* BIT(0) is active mode */
+ writel(BIT(0), MSM_CTRL_REG(rpm, MSM_RPM_REQ_CTX));
+
+ reinit_completion(&rpm->ack);
+
+ writel(4, rpm->ipc_rpm_reg);
+
+ wait_for_completion(&rpm->ack);
+
+ /* BIT(31) is rejected */
+ if (rpm->ack_status & BIT(31))
+ ret = -EIO;
+
+ mutex_unlock(&rpm->lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(msm_rpm_write);
+
+static irqreturn_t msm_rpm_ack_interrupt(int irq, void *dev)
+{
+ struct msm_rpm *rpm = dev;
+ unsigned long sel[MSM_RPM_ACK_SEL_COUNT];
+ unsigned long ack;
+ int i;
+
+ ack = readl(MSM_CTRL_REG(rpm, MSM_RPM_ACK_CTX));
+ for (i = 0; i < MSM_RPM_ACK_SEL_COUNT; i++) {
+ sel[i] = readl(MSM_CTRL_REG(rpm, MSM_RPM_ACK_SEL + i));
+ writel(0, MSM_CTRL_REG(rpm, MSM_RPM_ACK_SEL + i));
+ }
+ writel(0, MSM_CTRL_REG(rpm, MSM_RPM_ACK_CTX));
+
+ /* BIT(30) is notification */
+ if (ack & BIT(30)) {
+ dev_err(rpm->dev, "notification!\n");
+ } else {
+ rpm->ack_status = ack;
+ complete(&rpm->ack);
+ dev_dbg(rpm->dev, "completed ack\n");
+ }
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t msm_rpm_err_interrupt(int irq, void *dev)
+{
+ struct msm_rpm *rpm = dev;
+
+ writel(0x1, rpm->ipc_rpm_reg);
+ panic("Fatal RPM error");
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t msm_rpm_wakeup_interrupt(int irq, void *dev)
+{
+ return IRQ_HANDLED;
+}
+
+static int msm_rpm_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *match;
+ const struct msm_rpm *template;
+ struct resource *res;
+ struct msm_rpm *rpm;
+ u32 fw_version[3];
+ int ret;
+
+ dev_dbg(&pdev->dev, "================ msm_rpm_probe ================\n");
+
+ rpm = devm_kzalloc(&pdev->dev, sizeof(*rpm), GFP_KERNEL);
+ if (!rpm) {
+ dev_err(&pdev->dev, "Can't allocate msm_rpm\n");
+ return -ENOMEM;
+ }
+ rpm->dev = &pdev->dev;
+ mutex_init(&rpm->lock);
+ init_completion(&rpm->ack);
+
+ rpm->irq_ack = platform_get_irq_byname(pdev, "ack");
+ if (rpm->irq_ack < 0) {
+ dev_err(&pdev->dev, "required ack interrupt missing\n");
+ return -EINVAL;
+ }
+
+ rpm->irq_err = platform_get_irq_byname(pdev, "err");
+ if (rpm->irq_err < 0) {
+ dev_err(&pdev->dev, "required err interrupt missing\n");
+ return -EINVAL;
+ }
+
+ rpm->irq_wakeup = platform_get_irq_byname(pdev, "wakeup");
+ if (rpm->irq_wakeup < 0) {
+ dev_err(&pdev->dev, "required wakeup interrupt missing\n");
+ return -EINVAL;
+ }
+
+ match = of_match_device(msm_rpm_of_match, &pdev->dev);
+ template = match->data;
+ memcpy(rpm->version, template->version, sizeof(rpm->version));
+ rpm->resource_table = template->resource_table;
+ rpm->nresources = template->nresources;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ rpm->status_regs = devm_ioremap_resource(&pdev->dev, res);
+ rpm->ctrl_regs = rpm->status_regs + 0x400;
+ rpm->req_regs = rpm->status_regs + 0x600;
+ rpm->ack_regs = rpm->status_regs + 0xa00;
+ if (IS_ERR(rpm->status_regs))
+ return PTR_ERR(rpm->status_regs);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ rpm->ipc_rpm_reg = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(rpm->ipc_rpm_reg))
+ return PTR_ERR(rpm->ipc_rpm_reg);
+
+ dev_set_drvdata(&pdev->dev, rpm);
+
+ fw_version[0] = readl(MSM_STATUS_REG(rpm, MSM_RPM_VERSION + 0));
+ fw_version[1] = readl(MSM_STATUS_REG(rpm, MSM_RPM_VERSION + 1));
+ fw_version[2] = readl(MSM_STATUS_REG(rpm, MSM_RPM_VERSION + 2));
+ if (fw_version[0] != rpm->version[0]) {
+ dev_err(&pdev->dev, "RPM version %u.%u.%u incompatible with "
+ "this driver version %u.%u.%u\n",
+ fw_version[0],
+ fw_version[1],
+ fw_version[2],
+ rpm->version[0],
+ rpm->version[1],
+ rpm->version[2]);
+ return -EFAULT;
+ }
+
+ dev_info(&pdev->dev, "RPM firmware %u.%u.%u\n", fw_version[0],
+ fw_version[1],
+ fw_version[2]);
+
+ writel(fw_version[0], MSM_CTRL_REG(rpm, MSM_RPM_VERSION + 0));
+ writel(fw_version[1], MSM_CTRL_REG(rpm, MSM_RPM_VERSION + 1));
+ writel(fw_version[2], MSM_CTRL_REG(rpm, MSM_RPM_VERSION + 2));
+
+ ret = devm_request_irq(&pdev->dev,
+ rpm->irq_ack,
+ msm_rpm_ack_interrupt,
+ IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND,
+ "msm_rpm ack",
+ rpm);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to request ack interrupt\n");
+ return ret;
+ }
+
+#if 0
+ ret = irq_set_irq_wake(rpm->irq_ack, 1);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to enable wakeup for ack interrupt\n");
+ return ret;
+ }
+#endif
+
+ ret = devm_request_irq(&pdev->dev,
+ rpm->irq_err,
+ msm_rpm_err_interrupt,
+ IRQF_TRIGGER_RISING,
+ "msm_rpm err",
+ rpm);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to request err interrupt\n");
+ return ret;
+ }
+
+ ret = devm_request_irq(&pdev->dev,
+ rpm->irq_wakeup,
+ msm_rpm_wakeup_interrupt,
+ IRQF_TRIGGER_RISING,
+ "msm_rpm wakeup",
+ rpm);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to request wakeup interrupt\n");
+ return ret;
+ }
+
+#if 0
+ ret = irq_set_irq_wake(rpm->irq_wakeup, 1);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to enable wakeup for wakeup interrupt\n");
+ return ret;
+ }
+#endif
+
+ return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+}
+
+static struct platform_driver msm_rpm_driver = {
+ .probe = msm_rpm_probe,
+ .driver = {
+ .name = "msm_rpm",
+ .owner = THIS_MODULE,
+ .of_match_table = msm_rpm_of_match,
+ },
+};
+
+static int __init msm_rpm_init(void)
+{
+ return platform_driver_register(&msm_rpm_driver);
+}
+arch_initcall(msm_rpm_init);
+
+static void __exit msm_rpm_exit(void)
+{
+ platform_driver_unregister(&msm_rpm_driver);
+}
+module_exit(msm_rpm_exit)
+
+MODULE_DESCRIPTION("MSM RPM driver");
+MODULE_LICENSE("GPLv2");
diff --git a/include/linux/mfd/msm_rpm.h b/include/linux/mfd/msm_rpm.h
new file mode 100644
index 0000000..26d78bc
--- /dev/null
+++ b/include/linux/mfd/msm_rpm.h
@@ -0,0 +1,87 @@
+#ifndef __MSM_RPM_H__
+#define __MSM_RPM_H__
+
+enum msm_rpm_resource_id {
+ MSM_RPM_APPS_FABRIC_ARB = 1,
+ MSM_RPM_APPS_FABRIC_CFG_CLKMOD,
+ MSM_RPM_APPS_FABRIC_CFG_HALT,
+ MSM_RPM_APPS_FABRIC_CFG_IOCTL,
+ MSM_RPM_APPS_FABRIC_CLK,
+ MSM_RPM_CFPB_CLK,
+ MSM_RPM_CXO_BUFFERS,
+ MSM_RPM_CXO_CLK,
+ MSM_RPM_DAYTONA_FABRIC_CLK,
+ MSM_RPM_DDR_DMM,
+ MSM_RPM_EBI1_CLK,
+ MSM_RPM_HDMI_SWITCH,
+ MSM_RPM_MMFPB_CLK,
+ MSM_RPM_MMSS_FABRIC_CFG_CLKMOD,
+ MSM_RPM_MMSS_FABRIC_CFG_HALT,
+ MSM_RPM_MMSS_FABRIC_CFG_IOCTL,
+ MSM_RPM_MM_FABRIC_ARB,
+ MSM_RPM_MM_FABRIC_CLK,
+ MSM_RPM_NCP,
+ MSM_RPM_PM8821_L1,
+ MSM_RPM_PM8821_S1,
+ MSM_RPM_PM8821_S2,
+ MSM_RPM_PM8921_CLK1,
+ MSM_RPM_PM8921_CLK2,
+ MSM_RPM_PM8921_L1,
+ MSM_RPM_PM8921_L2,
+ MSM_RPM_PM8921_L3,
+ MSM_RPM_PM8921_L4,
+ MSM_RPM_PM8921_L5,
+ MSM_RPM_PM8921_L6,
+ MSM_RPM_PM8921_L7,
+ MSM_RPM_PM8921_L8,
+ MSM_RPM_PM8921_L9,
+ MSM_RPM_PM8921_L10,
+ MSM_RPM_PM8921_L11,
+ MSM_RPM_PM8921_L12,
+ MSM_RPM_PM8921_L13,
+ MSM_RPM_PM8921_L14,
+ MSM_RPM_PM8921_L15,
+ MSM_RPM_PM8921_L16,
+ MSM_RPM_PM8921_L17,
+ MSM_RPM_PM8921_L18,
+ MSM_RPM_PM8921_L19,
+ MSM_RPM_PM8921_L20,
+ MSM_RPM_PM8921_L21,
+ MSM_RPM_PM8921_L22,
+ MSM_RPM_PM8921_L23,
+ MSM_RPM_PM8921_L24,
+ MSM_RPM_PM8921_L25,
+ MSM_RPM_PM8921_L26,
+ MSM_RPM_PM8921_L27,
+ MSM_RPM_PM8921_L28,
+ MSM_RPM_PM8921_L29,
+ MSM_RPM_PM8921_LVS1,
+ MSM_RPM_PM8921_LVS2,
+ MSM_RPM_PM8921_LVS3,
+ MSM_RPM_PM8921_LVS4,
+ MSM_RPM_PM8921_LVS5,
+ MSM_RPM_PM8921_LVS6,
+ MSM_RPM_PM8921_LVS7,
+ MSM_RPM_PM8921_S1,
+ MSM_RPM_PM8921_S2,
+ MSM_RPM_PM8921_S3,
+ MSM_RPM_PM8921_S4,
+ MSM_RPM_PM8921_S5,
+ MSM_RPM_PM8921_S6,
+ MSM_RPM_PM8921_S7,
+ MSM_RPM_PM8921_S8,
+ MSM_RPM_PXO_CLK,
+ MSM_RPM_QDSS_CLK,
+ MSM_RPM_SFPB_CLK,
+ MSM_RPM_SYSTEM_FABRIC_ARB,
+ MSM_RPM_SYSTEM_FABRIC_CLK,
+ MSM_RPM_SYS_FABRIC_CFG_CLKMOD,
+ MSM_RPM_SYS_FABRIC_CFG_HALT,
+ MSM_RPM_SYS_FABRIC_CFG_IOCTL,
+ MSM_RPM_USB_OTG_SWITCH,
+ MSM_RPM_VDDMIN_GPIO,
+};
+
+int msm_rpm_write(const struct device *dev, enum msm_rpm_resource_id resource, u32 *buf, size_t count);
+
+#endif
--
1.8.2.2
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [RFC WIP 2/2] regulator: msm_rpm: Initial regulator driver for Qualcomm RPM
2014-04-22 18:20 [RFC WIP 0/2] Qualcomm family A RPM driver and example client Bjorn Andersson
2014-04-22 18:20 ` [RFC WIP 1/2] mfd: msm_rpm: Initial driver for the Qualcomm RPM Bjorn Andersson
@ 2014-04-22 18:20 ` Bjorn Andersson
1 sibling, 0 replies; 3+ messages in thread
From: Bjorn Andersson @ 2014-04-22 18:20 UTC (permalink / raw)
To: joshc, linux-arm-msm
Initial regulator driver for ldos on the pm8921 controlled by RPM.
Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
---
drivers/regulator/Kconfig | 7 +
drivers/regulator/Makefile | 1 +
drivers/regulator/msm_rpm-regulator.c | 467 ++++++++++++++++++++++++++++++++++
3 files changed, 475 insertions(+)
create mode 100644 drivers/regulator/msm_rpm-regulator.c
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 6a79328..a1d35316 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -372,6 +372,13 @@ config REGULATOR_MC13892
Say y here to support the regulators found on the Freescale MC13892
PMIC.
+config REGULATOR_MSM_RPM
+ tristate "Qualcomm RPM regulator driver"
+ depends on MFD_MSM_RPM
+ help
+ This driver provides support for regulators controlled by the
+ Qualcomm RPM.
+
config REGULATOR_PALMAS
tristate "TI Palmas PMIC Regulators"
depends on MFD_PALMAS
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 979f9dd..c1cb250 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_REGULATOR_MAX77693) += max77693.o
obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o
+obj-$(CONFIG_REGULATOR_MSM_RPM) += msm_rpm-regulator.o
obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o
obj-$(CONFIG_REGULATOR_PFUZE100) += pfuze100-regulator.o
obj-$(CONFIG_REGULATOR_TPS51632) += tps51632-regulator.o
diff --git a/drivers/regulator/msm_rpm-regulator.c b/drivers/regulator/msm_rpm-regulator.c
new file mode 100644
index 0000000..4c1cd6a
--- /dev/null
+++ b/drivers/regulator/msm_rpm-regulator.c
@@ -0,0 +1,467 @@
+/*
+ * Copyright (c) 2013, Sony Mobile Communications AB.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+
+#include <linux/mfd/msm_rpm.h>
+
+struct rpm_vreg_parts;
+struct vreg_range;
+
+struct msm_rpm_reg {
+ struct mutex lock;
+ struct device *dev;
+ struct regulator_desc desc;
+
+ const struct rpm_vreg_parts *parts;
+ const struct vreg_range *ranges;
+ int n_ranges;
+
+ const int resource;
+
+ int is_enabled;
+
+ u32 val[2];
+
+ int uV;
+ const int hpm_min_load;
+};
+
+#define REQUEST_MEMBER(_word, _mask, _shift) \
+{ \
+ .word = _word, \
+ .mask = _mask, \
+ .shift = _shift, \
+}
+
+struct request_member {
+ int word;
+ unsigned int mask;
+ int shift;
+};
+
+/* Possible RPM regulator request members */
+struct rpm_vreg_parts {
+ struct request_member mV; /* voltage: used if voltage is in mV */
+ struct request_member uV; /* voltage: used if voltage is in uV */
+ struct request_member ip; /* peak current in mA */
+ struct request_member pd; /* pull down enable */
+ struct request_member ia; /* average current in mA */
+ struct request_member fm; /* force mode */
+ struct request_member pm; /* power mode */
+ struct request_member pc; /* pin control */
+ struct request_member pf; /* pin function */
+ struct request_member enable_state; /* NCP and switch */
+ struct request_member comp_mode; /* NCP */
+ struct request_member freq; /* frequency: NCP and SMPS */
+ struct request_member freq_clk_src; /* clock source: SMPS */
+ struct request_member hpm; /* switch: control OCP and SS */
+ int request_len;
+};
+
+struct vreg_range {
+ int min_uV;
+ int max_uV;
+ int step_uV;
+};
+
+#define VOLTAGE_RANGE(_min_uV, _max_uV, _step_uV) \
+{ \
+ .min_uV = _min_uV, \
+ .max_uV = _max_uV, \
+ .step_uV = _step_uV, \
+}
+
+#define SET_POINTS(_ranges) \
+{ \
+ .range = _ranges, \
+ .count = ARRAY_SIZE(_ranges), \
+};
+
+/* Minimum high power mode loads in uA. */
+#define RPM_VREG_8960_LDO_50_HPM_MIN_LOAD 5000
+#define RPM_VREG_8960_LDO_150_HPM_MIN_LOAD 10000
+#define RPM_VREG_8960_LDO_300_HPM_MIN_LOAD 10000
+#define RPM_VREG_8960_LDO_600_HPM_MIN_LOAD 10000
+#define RPM_VREG_8960_LDO_1200_HPM_MIN_LOAD 10000
+#define RPM_VREG_8960_SMPS_1500_HPM_MIN_LOAD 100000
+#define RPM_VREG_8960_SMPS_2000_HPM_MIN_LOAD 100000
+
+/*
+ * Physically available PMIC regulator voltage setpoint ranges
+ */
+static const struct vreg_range pldo_ranges[] = {
+ VOLTAGE_RANGE( 750000, 1487500, 12500),
+ VOLTAGE_RANGE(1500000, 3075000, 25000),
+ VOLTAGE_RANGE(3100000, 4900000, 50000),
+};
+
+static const struct vreg_range nldo_ranges[] = {
+ VOLTAGE_RANGE( 750000, 1537500, 12500),
+};
+
+static const struct vreg_range nldo1200_ranges[] = {
+ VOLTAGE_RANGE( 375000, 743750, 6250),
+ VOLTAGE_RANGE( 750000, 1537500, 12500),
+};
+
+static const struct vreg_range ln_ldo_ranges[] = {
+ VOLTAGE_RANGE( 690000, 1110000, 60000),
+ VOLTAGE_RANGE(1380000, 2220000, 120000),
+};
+
+static const struct vreg_range smps_ranges[] = {
+ VOLTAGE_RANGE( 375000, 737500, 12500),
+ VOLTAGE_RANGE( 750000, 1487500, 12500),
+ VOLTAGE_RANGE(1500000, 3075000, 25000),
+};
+
+static const struct vreg_range ftsmps_ranges[] = {
+ VOLTAGE_RANGE( 350000, 650000, 50000),
+ VOLTAGE_RANGE( 700000, 1400000, 12500),
+ VOLTAGE_RANGE(1500000, 3300000, 50000),
+};
+
+static const struct vreg_range ncp_ranges[] = {
+ VOLTAGE_RANGE(1500000, 3050000, 50000),
+};
+
+/*
+ * RPM regulator request formats for MSM8660
+ */
+static const struct rpm_vreg_parts ldo_parts_8660 = {
+ .request_len = 2,
+ .mV = REQUEST_MEMBER(0, 0x00000FFF, 0),
+ .ip = REQUEST_MEMBER(0, 0x00FFF000, 12),
+ .fm = REQUEST_MEMBER(0, 0x03000000, 24),
+ .pc = REQUEST_MEMBER(0, 0x3C000000, 26),
+ .pf = REQUEST_MEMBER(0, 0xC0000000, 30),
+ .pd = REQUEST_MEMBER(1, 0x00000001, 0),
+ .ia = REQUEST_MEMBER(1, 0x00001FFE, 1),
+};
+
+static const struct rpm_vreg_parts smps_parts_8660 = {
+ .request_len = 2,
+ .mV = REQUEST_MEMBER(0, 0x00000FFF, 0),
+ .ip = REQUEST_MEMBER(0, 0x00FFF000, 12),
+ .fm = REQUEST_MEMBER(0, 0x03000000, 24),
+ .pc = REQUEST_MEMBER(0, 0x3C000000, 26),
+ .pf = REQUEST_MEMBER(0, 0xC0000000, 30),
+ .pd = REQUEST_MEMBER(1, 0x00000001, 0),
+ .ia = REQUEST_MEMBER(1, 0x00001FFE, 1),
+ .freq = REQUEST_MEMBER(1, 0x001FE000, 13),
+ .freq_clk_src = REQUEST_MEMBER(1, 0x00600000, 21),
+};
+
+static const struct rpm_vreg_parts switch_parts_8660 = {
+ .request_len = 1,
+ .enable_state = REQUEST_MEMBER(0, 0x00000001, 0),
+ .pd = REQUEST_MEMBER(0, 0x00000002, 1),
+ .pc = REQUEST_MEMBER(0, 0x0000003C, 2),
+ .pf = REQUEST_MEMBER(0, 0x000000C0, 6),
+ .hpm = REQUEST_MEMBER(0, 0x00000300, 8),
+};
+
+static const struct rpm_vreg_parts ncp_parts_8660 = {
+ .request_len = 1,
+ .mV = REQUEST_MEMBER(0, 0x00000FFF, 0),
+ .enable_state = REQUEST_MEMBER(0, 0x00001000, 12),
+ .comp_mode = REQUEST_MEMBER(0, 0x00002000, 13),
+ .freq = REQUEST_MEMBER(0, 0x003FC000, 14),
+};
+
+/*
+ * RPM regulator request formats for MSM8960 and APQ8064
+ */
+static const struct rpm_vreg_parts ldo_parts_8960 = {
+ .request_len = 2,
+ .uV = REQUEST_MEMBER(0, 0x007FFFFF, 0),
+ .pd = REQUEST_MEMBER(0, 0x00800000, 23),
+ .pc = REQUEST_MEMBER(0, 0x0F000000, 24),
+ .pf = REQUEST_MEMBER(0, 0xF0000000, 28),
+ .ip = REQUEST_MEMBER(1, 0x000003FF, 0),
+ .ia = REQUEST_MEMBER(1, 0x000FFC00, 10),
+ .fm = REQUEST_MEMBER(1, 0x00700000, 20),
+};
+
+static const struct rpm_vreg_parts smps_parts_8960 = {
+ .request_len = 2,
+ .uV = REQUEST_MEMBER(0, 0x007FFFFF, 0),
+ .pd = REQUEST_MEMBER(0, 0x00800000, 23),
+ .pc = REQUEST_MEMBER(0, 0x0F000000, 24),
+ .pf = REQUEST_MEMBER(0, 0xF0000000, 28),
+ .ip = REQUEST_MEMBER(1, 0x000003FF, 0),
+ .ia = REQUEST_MEMBER(1, 0x000FFC00, 10),
+ .fm = REQUEST_MEMBER(1, 0x00700000, 20),
+ .pm = REQUEST_MEMBER(1, 0x00800000, 23),
+ .freq = REQUEST_MEMBER(1, 0x1F000000, 24),
+ .freq_clk_src = REQUEST_MEMBER(1, 0x60000000, 29),
+};
+
+static const struct rpm_vreg_parts switch_parts_8960 = {
+ .request_len = 1,
+ .enable_state = REQUEST_MEMBER(0, 0x00000001, 0),
+ .pd = REQUEST_MEMBER(0, 0x00000002, 1),
+ .pc = REQUEST_MEMBER(0, 0x0000003C, 2),
+ .pf = REQUEST_MEMBER(0, 0x000003C0, 6),
+ .hpm = REQUEST_MEMBER(0, 0x00000C00, 10),
+};
+
+static const struct rpm_vreg_parts ncp_parts_8960 = {
+ .request_len = 1,
+ .uV = REQUEST_MEMBER(0, 0x007FFFFF, 0),
+ .enable_state = REQUEST_MEMBER(0, 0x00800000, 23),
+ .comp_mode = REQUEST_MEMBER(0, 0x01000000, 24),
+ .freq = REQUEST_MEMBER(0, 0x3E000000, 25),
+};
+
+static const struct msm_rpm_reg msm8960_ldo16 = {
+ .resource = MSM_RPM_PM8921_L16,
+
+ .desc.name = "pm8921_ldo16",
+ .ranges = pldo_ranges,
+ .n_ranges = ARRAY_SIZE(pldo_ranges),
+ .parts = &ldo_parts_8960,
+ .hpm_min_load = RPM_VREG_8960_LDO_300_HPM_MIN_LOAD,
+};
+
+static const struct msm_rpm_reg msm8960_ldo17 = {
+ .resource = MSM_RPM_PM8921_L17,
+
+ .desc.name = "pm8921_ldo17",
+ .ranges = pldo_ranges,
+ .n_ranges = ARRAY_SIZE(pldo_ranges),
+ .parts = &ldo_parts_8960,
+ .hpm_min_load = RPM_VREG_8960_LDO_300_HPM_MIN_LOAD,
+};
+
+static const struct msm_rpm_reg msm8960_ldo29 = {
+ .resource = MSM_RPM_PM8921_L29,
+
+ .desc.name = "pm8921_ldo29",
+ .ranges = pldo_ranges,
+ .n_ranges = ARRAY_SIZE(pldo_ranges),
+ .parts = &ldo_parts_8960,
+ .hpm_min_load = RPM_VREG_8960_LDO_300_HPM_MIN_LOAD,
+};
+
+static const struct of_device_id rpm_of_match[] = {
+ { .compatible = "qcom,msm8960-regulator-l16", .data = &msm8960_ldo16 },
+ { .compatible = "qcom,apq8064-regulator-l17", .data = &msm8960_ldo17 },
+ { .compatible = "qcom,apq8064-regulator-l29", .data = &msm8960_ldo29 },
+};
+MODULE_DEVICE_TABLE(of, rpm_of_match);
+
+static int rpm_reg_write(struct msm_rpm_reg *vreg,
+ const struct request_member *req,
+ const int value)
+{
+ vreg->val[req->word] &= ~req->mask;
+ vreg->val[req->word] |= value << req->shift;
+
+ return msm_rpm_write(vreg->dev->parent,
+ vreg->resource,
+ vreg->val,
+ vreg->parts->request_len);
+}
+
+static int rpm_reg_enable(struct regulator_dev *rdev)
+{
+ struct msm_rpm_reg *vreg = rdev_get_drvdata(rdev);
+ const struct rpm_vreg_parts *parts = vreg->parts;
+ int ret;
+
+ mutex_lock(&vreg->lock);
+ ret = rpm_reg_write(vreg, &parts->uV, vreg->uV);
+ if (!ret)
+ vreg->is_enabled = 1;
+ mutex_unlock(&vreg->lock);
+
+ return ret;
+}
+
+static int rpm_reg_is_enabled(struct regulator_dev *rdev)
+{
+ struct msm_rpm_reg *vreg = rdev_get_drvdata(rdev);
+
+ return vreg->is_enabled;
+}
+
+static int rpm_reg_disable(struct regulator_dev *rdev)
+{
+ struct msm_rpm_reg *vreg = rdev_get_drvdata(rdev);
+ const struct rpm_vreg_parts *parts = vreg->parts;
+ int ret;
+
+ mutex_lock(&vreg->lock);
+ ret = rpm_reg_write(vreg, &parts->uV, 0);
+ if (!ret)
+ vreg->is_enabled = 0;
+ mutex_unlock(&vreg->lock);
+
+ return ret;
+}
+
+static int rpm_reg_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
+ unsigned *selector)
+{
+ struct msm_rpm_reg *vreg = rdev_get_drvdata(rdev);
+ const struct rpm_vreg_parts *parts = vreg->parts;
+ const struct vreg_range *range = NULL;
+ int ret = 0;
+ int uV;
+ int i;
+
+ dev_dbg(vreg->dev, "set_voltage(%d, %d)\n", min_uV, max_uV);
+
+ /*
+ * Snap to the voltage to a supported level.
+ */
+ for (i = 0; i < vreg->n_ranges; i++) {
+ range = &vreg->ranges[i];
+ if (min_uV <= range->max_uV && max_uV >= range->min_uV)
+ break;
+ }
+
+ if (i == vreg->n_ranges) {
+ dev_err(vreg->dev,
+ "requested voltage %d-%d outside possible ranges\n",
+ min_uV, max_uV);
+ return -EINVAL;
+ }
+
+ if (min_uV < range->min_uV)
+ uV = range->min_uV;
+ else
+ uV = min_uV;
+
+ uV = roundup(uV, range->step_uV);
+
+ dev_dbg(vreg->dev, "snapped voltage %duV\n", uV);
+
+ /*
+ * Update the register.
+ */
+ mutex_lock(&vreg->lock);
+ vreg->uV = uV;
+ if (vreg->is_enabled)
+ ret = rpm_reg_write(vreg, &parts->uV, vreg->uV);
+ mutex_unlock(&vreg->lock);
+
+ return ret;
+}
+
+static int rpm_reg_get_voltage(struct regulator_dev *rdev)
+{
+ struct msm_rpm_reg *vreg = rdev_get_drvdata(rdev);
+ return vreg->uV;
+}
+
+static struct regulator_ops ldo_ops = {
+ .enable = rpm_reg_enable,
+ .disable = rpm_reg_disable,
+ .is_enabled = rpm_reg_is_enabled,
+
+ .set_voltage = rpm_reg_set_voltage,
+ .get_voltage = rpm_reg_get_voltage,
+};
+
+static int rpm_reg_probe(struct platform_device *pdev)
+{
+ struct regulator_init_data *initdata;
+ const struct msm_rpm_reg *template;
+ const struct of_device_id *match;
+ struct regulator_config config = { };
+ struct regulator_desc *desc;
+ struct regulator_dev *rdev;
+ struct msm_rpm_reg *vreg;
+
+ match = of_match_device(rpm_of_match, &pdev->dev);
+ template = match->data;
+
+ initdata = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node);
+ if (!initdata)
+ return -EINVAL;
+
+ vreg = devm_kmalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL);
+ if (!vreg) {
+ dev_err(&pdev->dev, "failed to allocate vreg\n");
+ return -ENOMEM;
+ }
+ memcpy(vreg, template, sizeof(*vreg));
+
+ mutex_init(&vreg->lock);
+ vreg->dev = &pdev->dev;
+
+ /* XXX:
+ * tighten constraints of initdata
+ * round min_uV and max_uV to step values
+ */
+
+ desc = &vreg->desc;
+ desc->id = -1;
+ desc->ops = &ldo_ops;
+ desc->owner = THIS_MODULE;
+ desc->type = REGULATOR_VOLTAGE;
+
+ config.dev = &pdev->dev;
+ config.init_data = initdata;
+ config.driver_data = vreg;
+ config.of_node = pdev->dev.of_node;
+ rdev = devm_regulator_register(&pdev->dev, desc, &config);
+ if (IS_ERR(rdev)) {
+ dev_err(&pdev->dev, "can't register regulator\n");
+ return PTR_ERR(rdev);
+ }
+
+ platform_set_drvdata(pdev, rdev);
+
+ return 0;
+}
+
+static int rpm_reg_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static struct platform_driver rpm_reg_driver = {
+ .probe = rpm_reg_probe,
+ .remove = rpm_reg_remove,
+ .driver = {
+ .name = "msm_rpm_reg",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(rpm_of_match),
+ },
+};
+
+static int __init rpm_reg_init(void)
+{
+ return platform_driver_register(&rpm_reg_driver);
+}
+arch_initcall(rpm_reg_init);
+
+static void __exit rpm_reg_exit(void)
+{
+ platform_driver_unregister(&rpm_reg_driver);
+}
+module_exit(rpm_reg_exit)
+
+MODULE_DESCRIPTION("MSM RPM regulator driver");
+MODULE_LICENSE("GPLv2");
+
--
1.8.2.2
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-04-22 18:20 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-04-22 18:20 [RFC WIP 0/2] Qualcomm family A RPM driver and example client Bjorn Andersson
2014-04-22 18:20 ` [RFC WIP 1/2] mfd: msm_rpm: Initial driver for the Qualcomm RPM Bjorn Andersson
2014-04-22 18:20 ` [RFC WIP 2/2] regulator: msm_rpm: Initial regulator driver for " Bjorn Andersson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).