Merge "msm_shared: mmc: Add support for erase and WP function"
diff --git a/dev/pmic/pm8x41/include/pm8x41.h b/dev/pmic/pm8x41/include/pm8x41.h
index 03de67d..3678bea 100644
--- a/dev/pmic/pm8x41/include/pm8x41.h
+++ b/dev/pmic/pm8x41/include/pm8x41.h
@@ -83,6 +83,101 @@
 	int disable_pin;
 };
 
+struct pm8x41_ldo {
+	uint8_t  type;
+	uint32_t base;
+};
+
+/* LDO base addresses. */
+#define PM8x41_LDO2                           0x14100
+#define PM8x41_LDO4                           0x14300
+#define PM8x41_LDO12                          0x14B00
+#define PM8x41_LDO14                          0x14D00
+#define PM8x41_LDO19                          0x15200
+#define PM8x41_LDO22                          0x15500
+
+/* LDO voltage ranges */
+#define NLDO_UV_MIN                           375000
+#define NLDO_UV_MAX                           1537500
+#define NLDO_UV_STEP                          12500
+#define NLDO_UV_VMIN_LOW                      750000
+
+#define PLDO_UV_VMIN_LOW                      750000
+#define PLDO_UV_VMIN_MID                      1500000
+#define PLDO_UV_VMIN_HIGH                     1750000
+
+#define PLDO_UV_MIN                           1537500
+#define PDLO_UV_MID                           3075000
+#define PLDO_UV_MAX                           4900000
+#define PLDO_UV_STEP_LOW                      12500
+#define PLDO_UV_STEP_MID                      25000
+#define PLDO_UV_STEP_HIGH                     50000
+
+#define LDO_RANGE_SEL_BIT                     0
+#define LDO_VSET_SEL_BIT                      0
+#define LDO_VREG_ENABLE_BIT                   7
+#define LDO_NORMAL_PWR_BIT                    7
+
+#define PLDO_TYPE                             0
+#define NLDO_TYPE                             1
+
+#define LDO(_base, _type) \
+{ \
+	.type = _type, \
+	.base = _base, \
+}
+
+enum mpp_vin_select
+{
+	MPP_VIN0,
+	MPP_VIN1,
+	MPP_VIN2,
+	MPP_VIN3,
+};
+
+enum mpp_mode_en_source_select
+{
+	MPP_LOW,
+	MPP_HIGH,
+	MPP_PAIRED_MPP,
+	MPP_NOT_PAIRED_MPP,
+	MPP_DTEST1 = 8,
+	MPP_NOT_DTEST1,
+	MPP_DTEST2,
+	MPP_NOT_DTEST2,
+	MPP_DTEST3,
+	MPP_NOT_DTEST3,
+	MPP_DTEST4,
+	MPP_NOT_DTEST4,
+};
+
+enum mpp_en_ctl
+{
+	MPP_DISABLE,
+	MPP_ENABLE,
+};
+
+enum mpp_mode
+{
+	MPP_DIGITAL_INPUT,
+	MPP_DIGITAL_OUTPUT,
+	MPP_DIGITAL_IN_AND_OUT,
+	MPP_BIDIRECTIONAL,
+	MPP_ANALOG_INPUT,
+	MPP_ANALOG_OUTPUT,
+	MPP_CURRENT_SINK,
+	MPP_RESERVED,
+};
+
+struct pm8x41_mpp
+{
+	uint32_t                       base;
+	enum mpp_vin_select            vin;
+	enum mpp_mode_en_source_select mode;
+};
+
+#define PM8x41_MMP3_BASE                      0xA200
+
 int pm8x41_gpio_get(uint8_t gpio, uint8_t *status);
 int pm8x41_gpio_set(uint8_t gpio, uint8_t value);
 int pm8x41_gpio_config(uint8_t gpio, struct pm8x41_gpio *config);
@@ -91,17 +186,11 @@
 uint32_t pm8x41_resin_bark_workaround_status();
 void pm8x41_reset_configure(uint8_t);
 void pm8x41_v2_reset_configure(uint8_t);
-int pm8x41_ldo_set_voltage(const char *, uint32_t);
-int pm8x41_ldo_control(const char *, uint8_t);
+int pm8x41_ldo_set_voltage(struct pm8x41_ldo *ldo, uint32_t voltage);
+int pm8x41_ldo_control(struct pm8x41_ldo *ldo, uint8_t enable);
 uint8_t pm8x41_get_pmic_rev();
 uint8_t pm8x41_get_pon_reason();
+void pm8x41_config_output_mpp(struct pm8x41_mpp *mpp);
+void pm8x41_enable_mpp(struct pm8x41_mpp *mpp, enum mpp_en_ctl enable);
 
-struct pm8x41_ldo {
-	const char *name;
-	uint8_t type;
-	uint32_t base;
-	uint32_t range_reg;
-	uint32_t step_reg;
-	uint32_t enable_reg;
-};
 #endif
diff --git a/dev/pmic/pm8x41/include/pm8x41_hw.h b/dev/pmic/pm8x41/include/pm8x41_hw.h
index cfc72fb..8a275ad 100644
--- a/dev/pmic/pm8x41/include/pm8x41_hw.h
+++ b/dev/pmic/pm8x41/include/pm8x41_hw.h
@@ -79,6 +79,14 @@
 #define S2_RESET_TYPE_WARM                    0x1
 #define PON_RESIN_N_RESET_S2_TIMER_MAX_VALUE  0x7
 
+/* MPP registers */
+#define MPP_DIG_VIN_CTL                       0x41
+#define MPP_MODE_CTL                          0x40
+#define MPP_EN_CTL                            0x46
+
+#define MPP_MODE_CTL_MODE_SHIFT               4
+#define MPP_EN_CTL_ENABLE_SHIFT               7
+
 void pm8x41_reg_write(uint32_t addr, uint8_t val);
 uint8_t pm8x41_reg_read(uint32_t addr);
 
@@ -90,44 +98,9 @@
 #define PERIPH_ID(_addr)    (((_addr) & 0xFF00) >> 8)
 #define SLAVE_ID(_addr)     ((_addr) >> 16)
 
-/* LDO voltage ranges */
-#define NLDO_UV_MIN                           375000
-#define NLDO_UV_MAX                           1537500
-#define NLDO_UV_STEP                          12500
-#define NLDO_UV_VMIN_LOW                      750000
-
-#define PLDO_UV_VMIN_LOW                      750000
-#define PLDO_UV_VMIN_MID                      1500000
-#define PLDO_UV_VMIN_HIGH                     1750000
-
-#define PLDO_UV_MIN                           1537500
-#define PDLO_UV_MID                           3075000
-#define PLDO_UV_MAX                           4900000
-#define PLDO_UV_STEP_LOW                      12500
-#define PLDO_UV_STEP_MID                      25000
-#define PLDO_UV_STEP_HIGH                     50000
-
-#define LDO_RANGE_SEL_BIT                     0
-#define LDO_VSET_SEL_BIT                      0
-#define LDO_VREG_ENABLE_BIT                   7
-#define LDO_NORMAL_PWR_BIT                    7
-
 #define LDO_RANGE_CTRL                        0x40
 #define LDO_STEP_CTRL                         0x41
 #define LDO_POWER_MODE                        0x45
 #define LDO_EN_CTL_REG                        0x46
 
-#define PLDO_TYPE                             0
-#define NLDO_TYPE                             1
-
-#define LDO(_name, _type, _base, _range, _step, _enable) \
-{ \
-	.name = _name, \
-	.type = _type, \
-	.base = _base, \
-	.range_reg = _range, \
-	.step_reg = _step, \
-	.enable_reg = _enable, \
-}
-
 #endif
diff --git a/dev/pmic/pm8x41/pm8x41.c b/dev/pmic/pm8x41/pm8x41.c
index ca7d230..93b5e57 100644
--- a/dev/pmic/pm8x41/pm8x41.c
+++ b/dev/pmic/pm8x41/pm8x41.c
@@ -35,12 +35,6 @@
 #include <pm8x41.h>
 #include <platform/timer.h>
 
-struct pm8x41_ldo ldo_data[] = {
-	LDO("LDO2",  NLDO_TYPE, 0x14100, LDO_RANGE_CTRL, LDO_STEP_CTRL, LDO_EN_CTL_REG),
-	LDO("LDO12", PLDO_TYPE, 0x14B00, LDO_RANGE_CTRL, LDO_STEP_CTRL, LDO_EN_CTL_REG),
-	LDO("LDO22", PLDO_TYPE, 0x15500, LDO_RANGE_CTRL, LDO_STEP_CTRL, LDO_EN_CTL_REG),
-};
-
 /* SPMI helper functions */
 uint8_t pm8x41_reg_read(uint32_t addr)
 {
@@ -260,34 +254,20 @@
 	REG_WRITE(PON_PS_HOLD_RESET_CTL2, BIT(S2_RESET_EN_BIT));
 }
 
-static struct pm8x41_ldo *ldo_get(const char *ldo_name)
-{
-	uint8_t i;
-	struct pm8x41_ldo *ldo = NULL;
-
-	for (i = 0; i < ARRAY_SIZE(ldo_data); i++) {
-		ldo = &ldo_data[i];
-		if (!strncmp(ldo->name, ldo_name, strlen(ldo_name)))
-			break;
-	}
-	return ldo;
-}
-
 /*
  * LDO set voltage, takes ldo name & voltage in UV as input
  */
-int pm8x41_ldo_set_voltage(const char *name, uint32_t voltage)
+int pm8x41_ldo_set_voltage(struct pm8x41_ldo *ldo, uint32_t voltage)
 {
 	uint32_t range = 0;
 	uint32_t step = 0;
 	uint32_t mult = 0;
 	uint32_t val = 0;
 	uint32_t vmin = 0;
-	struct pm8x41_ldo *ldo;
 
-	ldo = ldo_get(name);
-	if (!ldo) {
-		dprintf(CRITICAL, "LDO requsted is not supported: %s\n", name);
+	if (!ldo)
+	{
+		dprintf(CRITICAL, "LDO pointer is invalid: %p\n", ldo);
 		return 1;
 	}
 
@@ -300,21 +280,29 @@
 	 * Select range, step & vmin based on input voltage & type of LDO
 	 * LDO can operate in low, mid, high power mode
 	 */
-	if (ldo->type == PLDO_TYPE) {
-		if (voltage < PLDO_UV_MIN) {
+	if (ldo->type == PLDO_TYPE)
+	{
+		if (voltage < PLDO_UV_MIN)
+		{
 			range = 2;
 			step = PLDO_UV_STEP_LOW;
 			vmin = PLDO_UV_VMIN_LOW;
-		} else if (voltage < PDLO_UV_MID) {
+		}
+		else if (voltage < PDLO_UV_MID)
+		{
 			range = 3;
 			step = PLDO_UV_STEP_MID;
 			vmin = PLDO_UV_VMIN_MID;
-		} else {
+		}
+		else
+		{
 			range = 4;
 			step = PLDO_UV_STEP_HIGH;
 			vmin = PLDO_UV_VMIN_HIGH;
 		}
-	} else {
+	}
+	else
+	{
 		range = 2;
 		step = NLDO_UV_STEP;
 		vmin = NLDO_UV_VMIN_LOW;
@@ -325,12 +313,12 @@
 	/* Set Range in voltage ctrl register */
 	val = 0x0;
 	val = range << LDO_RANGE_SEL_BIT;
-	REG_WRITE((ldo->base + ldo->range_reg), val);
+	REG_WRITE((ldo->base + LDO_RANGE_CTRL), val);
 
 	/* Set multiplier in voltage ctrl register */
 	val = 0x0;
 	val = mult << LDO_VSET_SEL_BIT;
-	REG_WRITE((ldo->base + ldo->step_reg), val);
+	REG_WRITE((ldo->base + LDO_STEP_CTRL), val);
 
 	return 0;
 }
@@ -338,14 +326,13 @@
 /*
  * Enable or Disable LDO
  */
-int pm8x41_ldo_control(const char *name, uint8_t enable)
+int pm8x41_ldo_control(struct pm8x41_ldo *ldo, uint8_t enable)
 {
 	uint32_t val = 0;
-	struct pm8x41_ldo *ldo;
 
-	ldo = ldo_get(name);
-	if (!ldo) {
-		dprintf(CRITICAL, "Requested LDO is not supported : %s\n", name);
+	if (!ldo)
+	{
+		dprintf(CRITICAL, "LDO pointer is invalid: %p\n", ldo);
 		return 1;
 	}
 
@@ -355,7 +342,7 @@
 	else
 		val = (0 << LDO_VREG_ENABLE_BIT);
 
-	REG_WRITE((ldo->base + ldo->enable_reg), val);
+	REG_WRITE((ldo->base + LDO_EN_CTL_REG), val);
 
 	return 0;
 }
@@ -369,3 +356,19 @@
 {
 	return REG_READ(PON_PON_REASON1);
 }
+
+void pm8x41_enable_mpp(struct pm8x41_mpp *mpp, enum mpp_en_ctl enable)
+{
+	ASSERT(mpp);
+
+	REG_WRITE(mpp->base + MPP_EN_CTL, enable << MPP_EN_CTL_ENABLE_SHIFT);
+}
+
+void pm8x41_config_output_mpp(struct pm8x41_mpp *mpp)
+{
+	ASSERT(mpp);
+
+	REG_WRITE(mpp->base + MPP_DIG_VIN_CTL, mpp->vin);
+
+	REG_WRITE(mpp->base + MPP_MODE_CTL, mpp->mode | (MPP_DIGITAL_OUTPUT << MPP_MODE_CTL_MODE_SHIFT));
+}
diff --git a/platform/msm_shared/mmc_wrapper.c b/platform/msm_shared/mmc_wrapper.c
index c56a61e..d18c6a6 100644
--- a/platform/msm_shared/mmc_wrapper.c
+++ b/platform/msm_shared/mmc_wrapper.c
@@ -58,9 +58,9 @@
  */
 uint32_t mmc_write(uint64_t data_addr, uint32_t data_len, void *in)
 {
-	int val = 0;
+	uint32_t val = 0;
 	uint32_t write_size = SDHCI_ADMA_MAX_TRANS_SZ;
-	void *sptr = in;
+	uint8_t *sptr = (uint8_t *)in;
 	struct mmc_device *dev;
 
 	dev = target_mmc_device();
@@ -76,14 +76,22 @@
 	 * limitations
 	 */
 	while (data_len > write_size) {
-		val = mmc_sdhci_write(dev, sptr, (data_addr / MMC_BLK_SZ), (write_size / MMC_BLK_SZ));
+		val = mmc_sdhci_write(dev, (void *)sptr, (data_addr / MMC_BLK_SZ), (write_size / MMC_BLK_SZ));
+		if (val)
+		{
+			dprintf(CRITICAL, "Failed Writing block @ %x\n", (data_addr / MMC_BLK_SZ));
+			return val;
+		}
 		sptr += write_size;
 		data_addr += write_size;
 		data_len -= write_size;
 	}
 
 	if (data_len)
-		val = mmc_sdhci_write(dev, sptr, (data_addr / MMC_BLK_SZ), (data_len / MMC_BLK_SZ));
+		val = mmc_sdhci_write(dev, (void *)sptr, (data_addr / MMC_BLK_SZ), (data_len / MMC_BLK_SZ));
+
+	if (val)
+		dprintf(CRITICAL, "Failed Writing block @ %x\n", (data_addr / MMC_BLK_SZ));
 
 	return val;
 }
@@ -99,7 +107,7 @@
 	uint32_t ret = 0;
 	uint32_t read_size = SDHCI_ADMA_MAX_TRANS_SZ;
 	struct mmc_device *dev;
-	void *sptr = out;
+	uint8_t *sptr = (uint8_t *)out;
 
 	ASSERT(!(data_addr % MMC_BLK_SZ));
 	ASSERT(!(data_len % MMC_BLK_SZ));
@@ -112,14 +120,22 @@
 	 * limitations
 	 */
 	while (data_len > read_size) {
-		ret = mmc_sdhci_read(dev, sptr, (data_addr / MMC_BLK_SZ), (read_size / MMC_BLK_SZ));
+		ret = mmc_sdhci_read(dev, (void *)sptr, (data_addr / MMC_BLK_SZ), (read_size / MMC_BLK_SZ));
+		if (ret)
+		{
+			dprintf(CRITICAL, "Failed Reading block @ %x\n", (data_addr / MMC_BLK_SZ));
+			return ret;
+		}
 		sptr += read_size;
 		data_addr += read_size;
 		data_len -= read_size;
 	}
 
 	if (data_len)
-		ret = mmc_sdhci_read(dev, sptr, (data_addr / MMC_BLK_SZ), (data_len / MMC_BLK_SZ));
+		ret = mmc_sdhci_read(dev, (void *)sptr, (data_addr / MMC_BLK_SZ), (data_len / MMC_BLK_SZ));
+
+	if (ret)
+		dprintf(CRITICAL, "Failed Reading block @ %x\n", (data_addr / MMC_BLK_SZ));
 
 	return ret;
 }
diff --git a/project/msm8226.mk b/project/msm8226.mk
index 6896d27..a4315ad 100644
--- a/project/msm8226.mk
+++ b/project/msm8226.mk
@@ -17,6 +17,9 @@
 #DEFINES += MMC_BOOT_BAM=1
 DEFINES += CRYPTO_BAM=1
 
+#Disable thumb mode
+ENABLE_THUMB := false
+
 ifeq ($(ENABLE_SDHCI_SUPPORT),1)
 DEFINES += MMC_SDHCI_SUPPORT=1
 endif
diff --git a/project/msm8974.mk b/project/msm8974.mk
index d84f39e..17f564b 100644
--- a/project/msm8974.mk
+++ b/project/msm8974.mk
@@ -18,7 +18,6 @@
 DEFINES += CRYPTO_BAM=1
 DEFINES += CRYPTO_REG_ACCESS=1
 DEFINES += ABOOT_IGNORE_BOOT_HEADER_ADDRS=1
-DEFINES += ASSERT_ON_TAMPER=1
 
 #Disable thumb mode
 ENABLE_THUMB := false
diff --git a/target/msm8974/target_display.c b/target/msm8974/target_display.c
index da6b3cc..cf0f6cc 100644
--- a/target/msm8974/target_display.c
+++ b/target/msm8974/target_display.c
@@ -130,6 +130,11 @@
 
 static int msm8974_mipi_panel_power(uint8_t enable)
 {
+
+	struct pm8x41_ldo ldo2  = LDO(PM8x41_LDO2, NLDO_TYPE);
+	struct pm8x41_ldo ldo12 = LDO(PM8x41_LDO12, PLDO_TYPE);
+	struct pm8x41_ldo ldo22 = LDO(PM8x41_LDO22, PLDO_TYPE);
+
 	if (enable) {
 
 		/* Enable backlight */
@@ -137,18 +142,18 @@
 
 		/* Turn on LDO8 for lcd1 mipi vdd */
 		dprintf(SPEW, " Setting LDO22\n");
-		pm8x41_ldo_set_voltage("LDO22", 3000000);
-		pm8x41_ldo_control("LDO22", enable);
+		pm8x41_ldo_set_voltage(&ldo22, 3000000);
+		pm8x41_ldo_control(&ldo22, enable);
 
 		dprintf(SPEW, " Setting LDO12\n");
 		/* Turn on LDO23 for lcd1 mipi vddio */
-		pm8x41_ldo_set_voltage("LDO12", 1800000);
-		pm8x41_ldo_control("LDO12", enable);
+		pm8x41_ldo_set_voltage(&ldo12, 1800000);
+		pm8x41_ldo_control(&ldo12, enable);
 
 		dprintf(SPEW, " Setting LDO2\n");
 		/* Turn on LDO2 for vdda_mipi_dsi */
-		pm8x41_ldo_set_voltage("LDO2", 1200000);
-		pm8x41_ldo_control("LDO2", enable);
+		pm8x41_ldo_set_voltage(&ldo2, 1200000);
+		pm8x41_ldo_control(&ldo2, enable);
 
 		dprintf(SPEW, " Panel Reset \n");
 		/* Panel Reset */
@@ -157,8 +162,8 @@
 	} else {
 		msm8974_mdss_mipi_panel_reset(enable);
 		pm8x41_wled_enable(enable);
-		pm8x41_ldo_control("LDO2", enable);
-		pm8x41_ldo_control("LDO22", enable);
+		pm8x41_ldo_control(&ldo2, enable);
+		pm8x41_ldo_control(&ldo22, enable);
 
 	}