Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0f8b7137 authored by Olof Johansson's avatar Olof Johansson
Browse files

Merge tag 'omap-pm-regulator-for-v3.5' of...

Merge tag 'omap-pm-regulator-for-v3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into next/pm

Add support for vdd1 and vdd2 regulators and make voltage code to use them

By Tero Kristo (4) and Kevin Hilman (1)
via Kevin Hilman (3) and Tony Lindgren (1)
* tag 'omap-pm-regulator-for-v3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap:
  ARM: OMAP2+: voltage: ensure voltage used is exact voltage from OPP table
  arm: omap4: add common twl configurations for vdd1, vdd2 and vdd3
  arm: omap3: twl: add external controllers for core voltage regulators
  arm: omap3: add common twl configurations for vdd1 and vdd2
  arm: omap3: voltage: fix channel configuration
parents 69964ea4 a8822e2d
Loading
Loading
Loading
Loading
+147 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@

#include "twl-common.h"
#include "pm.h"
#include "voltage.h"

static struct i2c_board_info __initdata pmic_i2c_board_info = {
	.addr		= 0x48,
@@ -47,6 +48,18 @@ static struct i2c_board_info __initdata omap4_i2c1_board_info[] = {
	},
};

static int twl_set_voltage(void *data, int target_uV)
{
	struct voltagedomain *voltdm = (struct voltagedomain *)data;
	return voltdm_scale(voltdm, target_uV);
}

static int twl_get_voltage(void *data)
{
	struct voltagedomain *voltdm = (struct voltagedomain *)data;
	return voltdm_get_voltage(voltdm);
}

void __init omap_pmic_init(int bus, u32 clkrate,
			   const char *pmic_type, int pmic_irq,
			   struct twl4030_platform_data *pmic_data)
@@ -153,6 +166,48 @@ static struct regulator_init_data omap3_vpll2_idata = {
	.consumer_supplies		= omap3_vpll2_supplies,
};

static struct regulator_consumer_supply omap3_vdd1_supply[] = {
	REGULATOR_SUPPLY("vcc", "mpu.0"),
};

static struct regulator_consumer_supply omap3_vdd2_supply[] = {
	REGULATOR_SUPPLY("vcc", "l3_main.0"),
};

static struct regulator_init_data omap3_vdd1 = {
	.constraints = {
		.name			= "vdd_mpu_iva",
		.min_uV			= 600000,
		.max_uV			= 1450000,
		.valid_modes_mask	= REGULATOR_MODE_NORMAL,
		.valid_ops_mask		= REGULATOR_CHANGE_VOLTAGE,
	},
	.num_consumer_supplies		= ARRAY_SIZE(omap3_vdd1_supply),
	.consumer_supplies		= omap3_vdd1_supply,
};

static struct regulator_init_data omap3_vdd2 = {
	.constraints = {
		.name			= "vdd_core",
		.min_uV			= 600000,
		.max_uV			= 1450000,
		.valid_modes_mask	= REGULATOR_MODE_NORMAL,
		.valid_ops_mask		= REGULATOR_CHANGE_VOLTAGE,
	},
	.num_consumer_supplies		= ARRAY_SIZE(omap3_vdd2_supply),
	.consumer_supplies		= omap3_vdd2_supply,
};

static struct twl_regulator_driver_data omap3_vdd1_drvdata = {
	.get_voltage = twl_get_voltage,
	.set_voltage = twl_set_voltage,
};

static struct twl_regulator_driver_data omap3_vdd2_drvdata = {
	.get_voltage = twl_get_voltage,
	.set_voltage = twl_set_voltage,
};

void __init omap3_pmic_get_config(struct twl4030_platform_data *pmic_data,
				  u32 pdata_flags, u32 regulators_flags)
{
@@ -160,6 +215,16 @@ void __init omap3_pmic_get_config(struct twl4030_platform_data *pmic_data,
		pmic_data->irq_base = TWL4030_IRQ_BASE;
	if (!pmic_data->irq_end)
		pmic_data->irq_end = TWL4030_IRQ_END;
	if (!pmic_data->vdd1) {
		omap3_vdd1.driver_data = &omap3_vdd1_drvdata;
		omap3_vdd1_drvdata.data = voltdm_lookup("mpu_iva");
		pmic_data->vdd1 = &omap3_vdd1;
	}
	if (!pmic_data->vdd2) {
		omap3_vdd2.driver_data = &omap3_vdd2_drvdata;
		omap3_vdd2_drvdata.data = voltdm_lookup("core");
		pmic_data->vdd2 = &omap3_vdd2;
	}

	/* Common platform data configurations */
	if (pdata_flags & TWL_COMMON_PDATA_USB && !pmic_data->usb)
@@ -310,6 +375,70 @@ static struct regulator_init_data omap4_clk32kg_idata = {
	},
};

static struct regulator_consumer_supply omap4_vdd1_supply[] = {
	REGULATOR_SUPPLY("vcc", "mpu.0"),
};

static struct regulator_consumer_supply omap4_vdd2_supply[] = {
	REGULATOR_SUPPLY("vcc", "iva.0"),
};

static struct regulator_consumer_supply omap4_vdd3_supply[] = {
	REGULATOR_SUPPLY("vcc", "l3_main.0"),
};

static struct regulator_init_data omap4_vdd1 = {
	.constraints = {
		.name			= "vdd_mpu",
		.min_uV			= 500000,
		.max_uV			= 1500000,
		.valid_modes_mask	= REGULATOR_MODE_NORMAL,
		.valid_ops_mask		= REGULATOR_CHANGE_VOLTAGE,
	},
	.num_consumer_supplies		= ARRAY_SIZE(omap4_vdd1_supply),
	.consumer_supplies		= omap4_vdd1_supply,
};

static struct regulator_init_data omap4_vdd2 = {
	.constraints = {
		.name			= "vdd_iva",
		.min_uV			= 500000,
		.max_uV			= 1500000,
		.valid_modes_mask	= REGULATOR_MODE_NORMAL,
		.valid_ops_mask		= REGULATOR_CHANGE_VOLTAGE,
	},
	.num_consumer_supplies		= ARRAY_SIZE(omap4_vdd2_supply),
	.consumer_supplies		= omap4_vdd2_supply,
};

static struct regulator_init_data omap4_vdd3 = {
	.constraints = {
		.name			= "vdd_core",
		.min_uV			= 500000,
		.max_uV			= 1500000,
		.valid_modes_mask	= REGULATOR_MODE_NORMAL,
		.valid_ops_mask		= REGULATOR_CHANGE_VOLTAGE,
	},
	.num_consumer_supplies		= ARRAY_SIZE(omap4_vdd3_supply),
	.consumer_supplies		= omap4_vdd3_supply,
};


static struct twl_regulator_driver_data omap4_vdd1_drvdata = {
	.get_voltage = twl_get_voltage,
	.set_voltage = twl_set_voltage,
};

static struct twl_regulator_driver_data omap4_vdd2_drvdata = {
	.get_voltage = twl_get_voltage,
	.set_voltage = twl_set_voltage,
};

static struct twl_regulator_driver_data omap4_vdd3_drvdata = {
	.get_voltage = twl_get_voltage,
	.set_voltage = twl_set_voltage,
};

void __init omap4_pmic_get_config(struct twl4030_platform_data *pmic_data,
				  u32 pdata_flags, u32 regulators_flags)
{
@@ -318,6 +447,24 @@ void __init omap4_pmic_get_config(struct twl4030_platform_data *pmic_data,
	if (!pmic_data->irq_end)
		pmic_data->irq_end = TWL6030_IRQ_END;

	if (!pmic_data->vdd1) {
		omap4_vdd1.driver_data = &omap4_vdd1_drvdata;
		omap4_vdd1_drvdata.data = voltdm_lookup("mpu");
		pmic_data->vdd1 = &omap4_vdd1;
	}

	if (!pmic_data->vdd2) {
		omap4_vdd2.driver_data = &omap4_vdd2_drvdata;
		omap4_vdd2_drvdata.data = voltdm_lookup("iva");
		pmic_data->vdd2 = &omap4_vdd2;
	}

	if (!pmic_data->vdd3) {
		omap4_vdd3.driver_data = &omap4_vdd3_drvdata;
		omap4_vdd3_drvdata.data = voltdm_lookup("core");
		pmic_data->vdd3 = &omap4_vdd3;
	}

	/* Common platform data configurations */
	if (pdata_flags & TWL_COMMON_PDATA_USB && !pmic_data->usb)
		pmic_data->usb = &omap4_usb_pdata;
+1 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ static struct omap_vc_common omap3_vc_common = {
};

struct omap_vc_channel omap3_vc_mpu = {
	.flags = OMAP_VC_CHANNEL_DEFAULT,
	.common = &omap3_vc_common,
	.smps_sa_reg	 = OMAP3_PRM_VC_SMPS_SA_OFFSET,
	.smps_volra_reg	 = OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET,
+18 −3
Original line number Diff line number Diff line
@@ -73,7 +73,8 @@ unsigned long voltdm_get_voltage(struct voltagedomain *voltdm)
int voltdm_scale(struct voltagedomain *voltdm,
		 unsigned long target_volt)
{
	int ret;
	int ret, i;
	unsigned long volt = 0;

	if (!voltdm || IS_ERR(voltdm)) {
		pr_warning("%s: VDD specified does not exist!\n", __func__);
@@ -86,9 +87,23 @@ int voltdm_scale(struct voltagedomain *voltdm,
		return -ENODATA;
	}

	ret = voltdm->scale(voltdm, target_volt);
	/* Adjust voltage to the exact voltage from the OPP table */
	for (i = 0; voltdm->volt_data[i].volt_nominal != 0; i++) {
		if (voltdm->volt_data[i].volt_nominal >= target_volt) {
			volt = voltdm->volt_data[i].volt_nominal;
			break;
		}
	}

	if (!volt) {
		pr_warning("%s: not scaling. OPP voltage for %lu, not found.\n",
			   __func__, target_volt);
		return -EINVAL;
	}

	ret = voltdm->scale(voltdm, volt);
	if (!ret)
		voltdm->nominal_volt = target_volt;
		voltdm->nominal_volt = volt;

	return ret;
}