msm: board-8064: Add support for PM8917 regulator power grid

The regulator power grid changes slightly when using a PM8917 in
place of a PM8921 on 8064 targets.  Add configuration data so
that regulators present only on PM8917 are registered when a
PM8917 chip is detected.  Also remove PM8921 only regulators when
PM8917 is detected.  Modify the USB OTG MVS supply chain to
handle the replacement of an external 5V boost regulator with the
boost present inside of the PM8917.

Increase the max_uV value requested in the wlan_riva driver for
the iris_vdddig supply to 1225000 in order to handle the case of
this supply coming from the S1 regulator in the PM8917
configuration.  The S1 regulator only supports 1225000 uV.

Change-Id: Ib5ffa76cbc4590f468003c6863ba73807c4879e7
Signed-off-by: David Collins <collinsd@codeaurora.org>
(cherry picked from commit 793793b277040989d494921ac12cd4bf99939b76)

Signed-off-by: Sudhir Sharma <sudsha@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
index 5543cc7..fbeb1ef 100644
--- a/arch/arm/mach-msm/board-8064-pmic.c
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -26,6 +26,7 @@
 #include <mach/board.h>
 #include <mach/gpiomux.h>
 #include <mach/restart.h>
+#include <mach/socinfo.h>
 #include "devices.h"
 #include "board-8064.h"
 
@@ -403,7 +404,6 @@
 
 static struct pm8921_platform_data
 apq8064_pm8921_platform_data __devinitdata = {
-	.regulator_pdatas	= msm8064_pm8921_regulator_pdata,
 	.irq_pdata		= &apq8064_pm8921_irq_pdata,
 	.gpio_pdata		= &apq8064_pm8921_gpio_pdata,
 	.mpp_pdata		= &apq8064_pm8921_mpp_pdata,
@@ -460,8 +460,17 @@
 						&apq8064_ssbi_pm8921_pdata;
 	apq8064_device_ssbi_pmic2.dev.platform_data =
 				&apq8064_ssbi_pm8821_pdata;
-	apq8064_pm8921_platform_data.num_regulators =
-					msm8064_pm8921_regulator_pdata_len;
+	if (socinfo_get_pmic_model() != PMIC_MODEL_PM8917) {
+		apq8064_pm8921_platform_data.regulator_pdatas
+			= msm8064_pm8921_regulator_pdata;
+		apq8064_pm8921_platform_data.num_regulators
+			= msm8064_pm8921_regulator_pdata_len;
+	} else {
+		apq8064_pm8921_platform_data.regulator_pdatas
+			= msm8064_pm8917_regulator_pdata;
+		apq8064_pm8921_platform_data.num_regulators
+			= msm8064_pm8917_regulator_pdata_len;
+	}
 
 	if (machine_is_apq8064_mtp()) {
 		apq8064_pm8921_bms_pdata.battery_type = BATT_PALLADIUM;
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index 83e94b6..5b1e199 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -18,6 +18,7 @@
 #define VREG_CONSUMERS(_id) \
 	static struct regulator_consumer_supply vreg_consumers_##_id[]
 
+/* Regulators that are present when using either PM8921 or PM8917 */
 /*
  * Consumer specific regulator names:
  *			 regulator name		consumer dev_name
@@ -146,9 +147,6 @@
 VREG_CONSUMERS(L29) = {
 	REGULATOR_SUPPLY("8921_l29",		NULL),
 };
-VREG_CONSUMERS(S1) = {
-	REGULATOR_SUPPLY("8921_s1",		NULL),
-};
 VREG_CONSUMERS(S2) = {
 	REGULATOR_SUPPLY("8921_s2",		NULL),
 	REGULATOR_SUPPLY("iris_vddrfa",		"wcnss_wlan.0"),
@@ -198,10 +196,6 @@
 	REGULATOR_SUPPLY("8921_lvs1",		NULL),
 	REGULATOR_SUPPLY("iris_vddio",		"wcnss_wlan.0"),
 };
-VREG_CONSUMERS(LVS2) = {
-	REGULATOR_SUPPLY("8921_lvs2",		NULL),
-	REGULATOR_SUPPLY("iris_vdddig",		"wcnss_wlan.0"),
-};
 VREG_CONSUMERS(LVS3) = {
 	REGULATOR_SUPPLY("8921_lvs3",		NULL),
 };
@@ -231,13 +225,6 @@
 	REGULATOR_SUPPLY("8921_usb_otg",	NULL),
 	REGULATOR_SUPPLY("vbus_otg",		"msm_otg"),
 };
-VREG_CONSUMERS(HDMI_MVS) = {
-	REGULATOR_SUPPLY("8921_hdmi_mvs",	NULL),
-	REGULATOR_SUPPLY("hdmi_mvs",		"hdmi_msm.0"),
-};
-VREG_CONSUMERS(NCP) = {
-	REGULATOR_SUPPLY("8921_ncp",		NULL),
-};
 VREG_CONSUMERS(8821_S0) = {
 	REGULATOR_SUPPLY("8821_s0",		NULL),
 	REGULATOR_SUPPLY("krait2",		"acpuclk-8064"),
@@ -246,11 +233,6 @@
 	REGULATOR_SUPPLY("8821_s1",		NULL),
 	REGULATOR_SUPPLY("krait3",		"acpuclk-8064"),
 };
-VREG_CONSUMERS(EXT_5V) = {
-	REGULATOR_SUPPLY("ext_5v",		NULL),
-	REGULATOR_SUPPLY("ext_ddr3",		NULL),
-	REGULATOR_SUPPLY("vbus",		"msm_ehci_host.0"),
-};
 VREG_CONSUMERS(EXT_MPP8) = {
 	REGULATOR_SUPPLY("ext_mpp8",		NULL),
 	REGULATOR_SUPPLY("vbus",		"msm_ehci_host.1"),
@@ -284,6 +266,60 @@
 	REGULATOR_SUPPLY("avc_3p3v",	NULL),
 };
 
+/* Regulators that are only present when using PM8921 */
+VREG_CONSUMERS(S1) = {
+	REGULATOR_SUPPLY("8921_s1",		NULL),
+};
+VREG_CONSUMERS(LVS2) = {
+	REGULATOR_SUPPLY("8921_lvs2",		NULL),
+	REGULATOR_SUPPLY("iris_vdddig",		"wcnss_wlan.0"),
+};
+VREG_CONSUMERS(HDMI_MVS) = {
+	REGULATOR_SUPPLY("8921_hdmi_mvs",	NULL),
+	REGULATOR_SUPPLY("hdmi_mvs",		"hdmi_msm.0"),
+};
+VREG_CONSUMERS(NCP) = {
+	REGULATOR_SUPPLY("8921_ncp",		NULL),
+};
+VREG_CONSUMERS(EXT_5V) = {
+	REGULATOR_SUPPLY("ext_5v",		NULL),
+	REGULATOR_SUPPLY("ext_ddr3",		NULL),
+	REGULATOR_SUPPLY("vbus",		"msm_ehci_host.0"),
+};
+
+/* Regulators that are only present when using PM8917 */
+VREG_CONSUMERS(8917_S1) = {
+	REGULATOR_SUPPLY("8921_s1",		NULL),
+	REGULATOR_SUPPLY("iris_vdddig",		"wcnss_wlan.0"),
+};
+VREG_CONSUMERS(L30) = {
+	REGULATOR_SUPPLY("8917_l30",		NULL),
+};
+VREG_CONSUMERS(L31) = {
+	REGULATOR_SUPPLY("8917_l31",		NULL),
+};
+VREG_CONSUMERS(L32) = {
+	REGULATOR_SUPPLY("8917_l32",		NULL),
+};
+VREG_CONSUMERS(L33) = {
+	REGULATOR_SUPPLY("8917_l33",		NULL),
+};
+VREG_CONSUMERS(L34) = {
+	REGULATOR_SUPPLY("8917_l34",		NULL),
+};
+VREG_CONSUMERS(L35) = {
+	REGULATOR_SUPPLY("8917_l35",		NULL),
+};
+VREG_CONSUMERS(L36) = {
+	REGULATOR_SUPPLY("8917_l36",		NULL),
+};
+VREG_CONSUMERS(BOOST) = {
+	REGULATOR_SUPPLY("8917_boost",		NULL),
+	REGULATOR_SUPPLY("ext_ddr3",		NULL),
+	REGULATOR_SUPPLY("vbus",		"msm_ehci_host.0"),
+	REGULATOR_SUPPLY("hdmi_mvs",		"hdmi_msm.0"),
+};
+
 #define PM8XXX_VREG_INIT(_id, _name, _min_uV, _max_uV, _modes, _ops, \
 			 _apply_uV, _pull_down, _always_on, _supply_regulator, \
 			 _system_uA, _enable_time, _reg_id) \
@@ -359,6 +395,12 @@
 		REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS, 0, 0, \
 		_always_on, _supply_regulator, 0, _enable_time, _reg_id)
 
+#define PM8XXX_BOOST(_id, _name, _always_on, _min_uV, _max_uV, _enable_time, \
+		_supply_regulator, _reg_id) \
+	PM8XXX_VREG_INIT(_id, _name, _min_uV, _max_uV, 0, \
+		REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS, 0, 0, \
+		_always_on, _supply_regulator, 0, _enable_time, _reg_id)
+
 /* Pin control initialization */
 #define PM8XXX_PC(_id, _name, _always_on, _pin_fn, _pin_ctrl, \
 		  _supply_regulator, _reg_id) \
@@ -556,6 +598,39 @@
 	PM8XXX_VS300(HDMI_MVS, "8921_hdmi_mvs", 0, 1,         0, "ext_5v", 3),
 };
 
+/* PM8917 regulator constraints */
+struct pm8xxx_regulator_platform_data
+msm8064_pm8917_regulator_pdata[] __devinitdata = {
+	/*
+	 *		ID   name always_on pd min_uV   max_uV   en_t supply
+	 *	system_uA reg_ID
+	 */
+	PM8XXX_NLDO1200(L26, "8921_l26", 0, 1, 375000, 1050000, 200, "8921_s7",
+		0, 1),
+	PM8XXX_LDO(L30,      "8917_l30", 0, 1, 1800000, 1800000, 200, NULL,
+		0, 2),
+	PM8XXX_LDO(L31,      "8917_l31", 0, 1, 1800000, 1800000, 200, NULL,
+		0, 3),
+	PM8XXX_LDO(L32,      "8917_l32", 0, 1, 2800000, 2800000, 200, NULL,
+		0, 4),
+	PM8XXX_LDO(L33,      "8917_l33", 0, 1, 2800000, 2800000, 200, NULL,
+		0, 5),
+	PM8XXX_LDO(L34,      "8917_l34", 0, 1, 1800000, 1800000, 200, NULL,
+		0, 6),
+	PM8XXX_LDO(L35,      "8917_l35", 0, 1, 3000000, 3000000, 200, NULL,
+		0, 7),
+	PM8XXX_LDO(L36,      "8917_l36", 0, 1, 1800000, 1800000, 200, NULL,
+		0, 8),
+
+	/*
+	 *           ID     name   always_on  min_uV   max_uV en_t supply reg_ID
+	 */
+	PM8XXX_BOOST(BOOST, "8917_boost", 0,  5000000, 5000000, 500, NULL, 9),
+
+	/*	     ID        name      always_on pd en_t supply    reg_ID */
+	PM8XXX_VS300(USB_OTG,  "8921_usb_otg",  0, 1, 0,   "8917_boost", 10),
+};
+
 static struct rpm_regulator_init_data
 apq8064_rpm_regulator_init_data[] __devinitdata = {
 	/*	ID a_on pd ss min_uV   max_uV  supply sys_uA  freq  fm  ss_fm */
@@ -596,12 +671,17 @@
 
 	/*     ID  a_on pd ss                   supply */
 	RPM_VS(LVS1, 0, 1, 0,                   "8921_s4"),
-	RPM_VS(LVS2, 0, 1, 0,                   "8921_s1"),
 	RPM_VS(LVS3, 0, 1, 0,                   "8921_s4"),
 	RPM_VS(LVS4, 0, 1, 0,                   "8921_s4"),
 	RPM_VS(LVS5, 0, 1, 0,                   "8921_s4"),
 	RPM_VS(LVS6, 0, 1, 0,                   "8921_s4"),
 	RPM_VS(LVS7, 0, 1, 1,                   "8921_s4"),
+};
+
+static struct rpm_regulator_init_data
+apq8064_rpm_regulator_pm8921_init_data[] __devinitdata = {
+	/*     ID  a_on pd ss                   supply */
+	RPM_VS(LVS2, 0, 1, 0,                   "8921_s1"),
 
 	/*	ID a_on    ss min_uV   max_uV   supply     freq */
 	RPM_NCP(NCP, 0,    0, 1800000, 1800000, "8921_l6", 1p60),
@@ -609,6 +689,8 @@
 
 int msm8064_pm8921_regulator_pdata_len __devinitdata =
 	ARRAY_SIZE(msm8064_pm8921_regulator_pdata);
+int msm8064_pm8917_regulator_pdata_len __devinitdata =
+	ARRAY_SIZE(msm8064_pm8917_regulator_pdata);
 
 #define RPM_REG_MAP(_id, _sleep_also, _voter, _supply, _dev_name) \
 	{ \
@@ -645,3 +727,34 @@
 	.consumer_map		  = msm_rpm_regulator_consumer_mapping,
 	.consumer_map_len = ARRAY_SIZE(msm_rpm_regulator_consumer_mapping),
 };
+
+/* Regulators that are only present when using PM8921 */
+struct rpm_regulator_platform_data
+apq8064_rpm_regulator_pm8921_pdata __devinitdata = {
+	.init_data		  = apq8064_rpm_regulator_pm8921_init_data,
+	.num_regulators	= ARRAY_SIZE(apq8064_rpm_regulator_pm8921_init_data),
+	.version		  = RPM_VREG_VERSION_8960,
+	.vreg_id_vdd_mem	  = RPM_VREG_ID_PM8921_L24,
+	.vreg_id_vdd_dig	  = RPM_VREG_ID_PM8921_S3,
+	.requires_tcxo_workaround = true,
+};
+
+/*
+ * Fix up regulator consumer data that moves to a different regulator when
+ * PM8917 is used.
+ */
+void __init configure_apq8064_pm8917_power_grid(void)
+{
+	static struct rpm_regulator_init_data *rpm_data;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(apq8064_rpm_regulator_init_data); i++) {
+		rpm_data = &apq8064_rpm_regulator_init_data[i];
+		if (rpm_data->id == RPM_VREG_ID_PM8921_S1) {
+			rpm_data->init_data.consumer_supplies
+				= vreg_consumers_8917_S1;
+			rpm_data->init_data.num_consumer_supplies
+				= ARRAY_SIZE(vreg_consumers_8917_S1);
+		}
+	}
+}
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 68aa643..959e749 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -2151,12 +2151,21 @@
 
 static struct platform_device apq8064_device_rpm_regulator __devinitdata = {
 	.name	= "rpm-regulator",
-	.id	= -1,
+	.id	= 0,
 	.dev	= {
 		.platform_data = &apq8064_rpm_regulator_pdata,
 	},
 };
 
+static struct platform_device
+apq8064_pm8921_device_rpm_regulator __devinitdata = {
+	.name	= "rpm-regulator",
+	.id	= 1,
+	.dev	= {
+		.platform_data = &apq8064_rpm_regulator_pm8921_pdata,
+	},
+};
+
 static struct gpio_ir_recv_platform_data gpio_ir_recv_pdata = {
 	.gpio_nr = 88,
 	.active_low = 1,
@@ -2175,16 +2184,30 @@
 	&apq8064_device_qup_i2c_gsbi4,
 };
 
-static struct platform_device *common_devices[] __initdata = {
+static struct platform_device *early_common_devices[] __initdata = {
 	&apq8064_device_acpuclk,
 	&apq8064_device_dmov,
 	&apq8064_device_qup_spi_gsbi5,
+};
+
+static struct platform_device *pm8921_common_devices[] __initdata = {
 	&apq8064_device_ext_5v_vreg,
 	&apq8064_device_ext_mpp8_vreg,
 	&apq8064_device_ext_3p3v_vreg,
 	&apq8064_device_ssbi_pmic1,
 	&apq8064_device_ssbi_pmic2,
 	&apq8064_device_ext_ts_sw_vreg,
+};
+
+static struct platform_device *pm8917_common_devices[] __initdata = {
+	&apq8064_device_ext_mpp8_vreg,
+	&apq8064_device_ext_3p3v_vreg,
+	&apq8064_device_ssbi_pmic1,
+	&apq8064_device_ssbi_pmic2,
+	&apq8064_device_ext_ts_sw_vreg,
+};
+
+static struct platform_device *common_devices[] __initdata = {
 	&msm_device_smd_apq8064,
 	&apq8064_device_otg,
 	&apq8064_device_gadget_peripheral,
@@ -2933,7 +2956,11 @@
 	BUG_ON(msm_rpm_init(&apq8064_rpm_data));
 	BUG_ON(msm_rpmrs_levels_init(&msm_rpmrs_data));
 	regulator_suppress_info_printing();
+	if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917)
+		configure_apq8064_pm8917_power_grid();
 	platform_device_register(&apq8064_device_rpm_regulator);
+	if (socinfo_get_pmic_model() != PMIC_MODEL_PM8917)
+		platform_device_register(&apq8064_pm8921_device_rpm_regulator);
 	if (msm_xo_init())
 		pr_err("Failed to initialize XO votes\n");
 	msm_clock_init(&apq8064_clock_init_data);
@@ -2953,6 +2980,15 @@
 	apq8064_device_otg.dev.platform_data = &msm_otg_pdata;
 	apq8064_ehci_host_init();
 	apq8064_init_buses();
+
+	platform_add_devices(early_common_devices,
+				ARRAY_SIZE(early_common_devices));
+	if (socinfo_get_pmic_model() != PMIC_MODEL_PM8917)
+		platform_add_devices(pm8921_common_devices,
+					ARRAY_SIZE(pm8921_common_devices));
+	else
+		platform_add_devices(pm8917_common_devices,
+					ARRAY_SIZE(pm8917_common_devices));
 	platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
 	if (!(machine_is_mpq8064_cdp() || machine_is_mpq8064_hrd() ||
 			machine_is_mpq8064_dtv()))
diff --git a/arch/arm/mach-msm/board-8064.h b/arch/arm/mach-msm/board-8064.h
index 2258b8d..308c1b1 100644
--- a/arch/arm/mach-msm/board-8064.h
+++ b/arch/arm/mach-msm/board-8064.h
@@ -40,6 +40,11 @@
 
 extern int msm8064_pm8921_regulator_pdata_len __devinitdata;
 
+extern struct pm8xxx_regulator_platform_data
+	msm8064_pm8917_regulator_pdata[] __devinitdata;
+
+extern int msm8064_pm8917_regulator_pdata_len __devinitdata;
+
 #define GPIO_VREG_ID_EXT_5V		0
 #define GPIO_VREG_ID_EXT_3P3V		1
 #define GPIO_VREG_ID_EXT_TS_SW		2
@@ -62,6 +67,9 @@
 extern struct rpm_regulator_platform_data
 	apq8064_rpm_regulator_pdata __devinitdata;
 
+extern struct rpm_regulator_platform_data
+	apq8064_rpm_regulator_pm8921_pdata __devinitdata;
+
 extern struct regulator_init_data msm8064_saw_regulator_pdata_8921_s5;
 extern struct regulator_init_data msm8064_saw_regulator_pdata_8921_s6;
 extern struct regulator_init_data msm8064_saw_regulator_pdata_8821_s0;
@@ -92,6 +100,7 @@
 
 void apq8064_init_gpu(void);
 void apq8064_pm8xxx_gpio_mpp_init(void);
+void __init configure_apq8064_pm8917_power_grid(void);
 
 #define PLATFORM_IS_MPQ8064() \
 	(machine_is_mpq8064_hrd() || \