@@ -10,18 +10,6 @@
#include "prm-regbits-44xx.h"
#include "prm44xx.h"
-/*
- * Channel configuration bits, common for OMAP3 & 4
- * OMAP3 register: PRM_VC_CH_CONF
- * OMAP4 register: PRM_VC_CFG_CHANNEL
- */
-#define CFG_CHANNEL_SA BIT(0)
-#define CFG_CHANNEL_RAV BIT(1)
-#define CFG_CHANNEL_RAC BIT(2)
-#define CFG_CHANNEL_RACEN BIT(3)
-#define CFG_CHANNEL_CMD BIT(4)
-#define CFG_CHANNEL_MASK 0x3f
-
/**
* omap_vc_config_channel - configure VC channel to PMIC mappings
* @voltdm: pointer to voltagdomain defining the desired VC channel
@@ -249,6 +237,7 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm)
{
struct omap_vc_channel *vc = voltdm->vc;
u8 on_vsel, onlp_vsel, ret_vsel, off_vsel;
+ struct omap_vc_channel_cfg *cfg_channel_data;
u32 val;
if (!voltdm->pmic || !voltdm->pmic->uv_to_vsel) {
@@ -264,6 +253,14 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm)
return;
}
+ /* Ensure we have VC channel data */
+ if (!vc->cfg_ch_bits) {
+ pr_err("%s: No CFG Channel data for vdd_%s regs\n",
+ __func__, voltdm->name);
+ return;
+ }
+ cfg_channel_data = vc->cfg_ch_bits;
+
vc->cfg_channel = 0;
/* get PMIC/board specific settings */
@@ -276,7 +273,7 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm)
voltdm->rmw(vc->smps_sa_mask,
vc->i2c_slave_addr << __ffs(vc->smps_sa_mask),
vc->common->smps_sa_reg);
- vc->cfg_channel |= CFG_CHANNEL_SA;
+ vc->cfg_channel |= cfg_channel_data->sa;
/*
* Configure the PMIC register addresses.
@@ -284,13 +281,14 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm)
voltdm->rmw(vc->smps_volra_mask,
vc->volt_reg_addr << __ffs(vc->smps_volra_mask),
vc->common->smps_volra_reg);
- vc->cfg_channel |= CFG_CHANNEL_RAV;
+ vc->cfg_channel |= cfg_channel_data->rav;
if (vc->cmd_reg_addr) {
voltdm->rmw(vc->smps_cmdra_mask,
vc->cmd_reg_addr << __ffs(vc->smps_cmdra_mask),
vc->common->smps_cmdra_reg);
- vc->cfg_channel |= CFG_CHANNEL_RAC | CFG_CHANNEL_RACEN;
+ vc->cfg_channel |= cfg_channel_data->rac |
+ cfg_channel_data->racen;
}
/* Set up the on, inactive, retention and off voltage */
@@ -303,7 +301,7 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm)
(ret_vsel << vc->common->cmd_ret_shift) |
(off_vsel << vc->common->cmd_off_shift));
voltdm->write(val, vc->cmdval_reg);
- vc->cfg_channel |= CFG_CHANNEL_CMD;
+ vc->cfg_channel |= cfg_channel_data->cmd;
/* Channel configuration */
omap_vc_config_channel(voltdm);
@@ -62,11 +62,39 @@ struct omap_vc_common {
u8 i2c_mcode_mask;
};
+/*
+ * Channel configuration bits, common for OMAP3 & 4
+ * OMAP3 register: PRM_VC_CH_CONF
+ * OMAP4 register: PRM_VC_CFG_CHANNEL
+ */
+#define CFG_CHANNEL_SA BIT(0)
+#define CFG_CHANNEL_RAV BIT(1)
+#define CFG_CHANNEL_RAC BIT(2)
+#define CFG_CHANNEL_RACEN BIT(3)
+#define CFG_CHANNEL_CMD BIT(4)
+#define CFG_CHANNEL_MASK 0x3f
+/**
+ * struct omap_vc_channel_cfg - describe the cfg_channel bitfield
+ * @sa: SA_VDD_xxx_L
+ * @rav: RAV_VDD_xxx_L
+ * @rac: RAC_VDD_xxx_L
+ * @racen: RACEN_VDD_xxx_L
+ * @cmd: CMD_VDD_xxx_L
+ */
+struct omap_vc_channel_cfg {
+ u8 sa;
+ u8 rav;
+ u8 rac;
+ u8 racen;
+ u8 cmd;
+};
+
/**
* struct omap_vc_channel - VC per-instance data
* @common: pointer to VC common data for this platform
* @smps_sa_mask: i2c slave address bitmask in the PRM_VC_SMPS_SA register
* @smps_volra_mask: VOLRA* bitmask in the PRM_VC_VOL_RA register
+ * @cfg_ch_bits: exception handling for unordered register bits in cfg_channel
*/
struct omap_vc_channel {
/* channel state */
@@ -74,6 +102,7 @@ struct omap_vc_channel {
u8 volt_reg_addr;
u8 cmd_reg_addr;
u8 cfg_channel;
+ struct omap_vc_channel_cfg *cfg_ch_bits;
u16 setup_time;
bool i2c_high_speed;
@@ -49,6 +49,15 @@ static struct omap_vc_common omap3_vc_common = {
.i2c_mcode_mask = OMAP3430_MCODE_MASK,
};
+/* for all channels */
+struct omap_vc_channel_cfg vc3xxx_common_cfg_channel = {
+ .sa = CFG_CHANNEL_SA,
+ .rav = CFG_CHANNEL_RAV,
+ .rac = CFG_CHANNEL_RAC,
+ .racen = CFG_CHANNEL_RACEN,
+ .cmd = CFG_CHANNEL_CMD,
+};
+
struct omap_vc_channel omap3_vc_mpu = {
.common = &omap3_vc_common,
.cmdval_reg = OMAP3_PRM_VC_CMD_VAL_0_OFFSET,
@@ -56,6 +65,7 @@ struct omap_vc_channel omap3_vc_mpu = {
.smps_volra_mask = OMAP3430_VOLRA0_MASK,
.smps_cmdra_mask = OMAP3430_CMDRA0_MASK,
.cfg_channel_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA0_SHIFT,
+ .cfg_ch_bits = &vc3xxx_common_cfg_channel,
};
struct omap_vc_channel omap3_vc_core = {
@@ -65,4 +75,5 @@ struct omap_vc_channel omap3_vc_core = {
.smps_volra_mask = OMAP3430_VOLRA1_MASK,
.smps_cmdra_mask = OMAP3430_CMDRA1_MASK,
.cfg_channel_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT,
+ .cfg_ch_bits = &vc3xxx_common_cfg_channel,
};
@@ -50,6 +50,24 @@ static const struct omap_vc_common omap4_vc_common = {
.i2c_mcode_mask = OMAP4430_HSMCODE_MASK,
};
+/* Handle exception case for vc44xx MPU */
+static struct omap_vc_channel_cfg vc44xx_mpu_cfg_channel = {
+ .sa = CFG_CHANNEL_SA,
+ .cmd = BIT(1),
+ .rav = BIT(2),
+ .rac = BIT(3),
+ .racen = BIT(4),
+};
+
+/* for all other */
+struct omap_vc_channel_cfg vc44xx_common_cfg_channel = {
+ .sa = CFG_CHANNEL_SA,
+ .rav = CFG_CHANNEL_RAV,
+ .rac = CFG_CHANNEL_RAC,
+ .racen = CFG_CHANNEL_RACEN,
+ .cmd = CFG_CHANNEL_CMD,
+};
+
/* VC instance data for each controllable voltage line */
struct omap_vc_channel omap4_vc_mpu = {
.common = &omap4_vc_common,
@@ -58,6 +76,7 @@ struct omap_vc_channel omap4_vc_mpu = {
.smps_volra_mask = OMAP4430_VOLRA_VDD_MPU_L_MASK,
.smps_cmdra_mask = OMAP4430_CMDRA_VDD_MPU_L_MASK,
.cfg_channel_sa_shift = OMAP4430_SA_VDD_MPU_L_SHIFT,
+ .cfg_ch_bits = &vc44xx_mpu_cfg_channel,
};
struct omap_vc_channel omap4_vc_iva = {
@@ -67,6 +86,7 @@ struct omap_vc_channel omap4_vc_iva = {
.smps_volra_mask = OMAP4430_VOLRA_VDD_IVA_L_MASK,
.smps_cmdra_mask = OMAP4430_CMDRA_VDD_IVA_L_MASK,
.cfg_channel_sa_shift = OMAP4430_SA_VDD_IVA_L_SHIFT,
+ .cfg_ch_bits = &vc44xx_common_cfg_channel,
};
struct omap_vc_channel omap4_vc_core = {
@@ -76,5 +96,6 @@ struct omap_vc_channel omap4_vc_core = {
.smps_volra_mask = OMAP4430_VOLRA_VDD_CORE_L_MASK,
.smps_cmdra_mask = OMAP4430_CMDRA_VDD_CORE_L_MASK,
.cfg_channel_sa_shift = OMAP4430_SA_VDD_CORE_L_SHIFT,
+ .cfg_ch_bits = &vc44xx_common_cfg_channel,
};
Patch "OMAP3+: VC: abstract out channel configuration" abstracts out VC channel configuration. However, TRM has it's little surprises such as the following for channel_cfg: CFG_CHANNEL_SA BIT(0) CFG_CHANNEL_RAV BIT(1) CFG_CHANNEL_RAC BIT(2) CFG_CHANNEL_RACEN BIT(3) CFG_CHANNEL_CMD BIT(4) is valid for core and iva, *but* for mpu, the channel offsets are as follows: CFG_CHANNEL_SA BIT(0) CFG_CHANNEL_CMD BIT(1) CFG_CHANNEL_RAV BIT(2) CFG_CHANNEL_RAC BIT(3) CFG_CHANNEL_RACEN BIT(4) To handle this on the fly, add a structure to describe this and use the structure for vc definition. Signed-off-by: Nishanth Menon <nm@ti.com> --- arch/arm/mach-omap2/vc.c | 30 ++++++++++++++---------------- arch/arm/mach-omap2/vc.h | 29 +++++++++++++++++++++++++++++ arch/arm/mach-omap2/vc3xxx_data.c | 11 +++++++++++ arch/arm/mach-omap2/vc44xx_data.c | 21 +++++++++++++++++++++ 4 files changed, 75 insertions(+), 16 deletions(-)