Skip to contentSkip to conversation

OMAP3: PM: OMAP3630 support for smartreflex driver

PATCH Superseded Thara Gopinath 2 participants 6 messages Mar 31, 2010

Subsystems (4)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

v2 cover OMAP3: PM: OMAP3630 support for smartreflex driver

This patch series adds support for the updated 45nm smrtrelfex IP supported in OMAP3630 and OMAP4 in the smartreflex driver and adds support to enable smartreflex autocompensation for OMAP3630 using test nvalues.

This patch series is based on the V2 version of Smartreflex and voltage revamp patch series, link to which is the following.

	http://marc.info/?l=linux-omap&m=126890378014626&w=2

This patch series has been tested on OMAP3630 SDP board with CONFIG_OMAP_SMARTREFLEX_TESTING option enabled in the menuconfig.

This patch series has been based on Kevin's PM tree origin/pm-wip-opp branch.

Thara Gopinath (3):
OMAP3: PM: Fix crash when enabling SmartReflex on non-supported
OMAPs.
OMAP3: PM: Smartreflex IP update changes for OMAP3630
OMAP3: PM: Adding OMAP3630 support in smartreflex driver

 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |   47 +++++-
 arch/arm/mach-omap2/smartreflex.c          |  280 +++++++++++++++++++++-------
 arch/arm/mach-omap2/smartreflex.h          |   50 ++++-
 arch/arm/mach-omap2/sr_device.c            |   94 +++++++++-
 arch/arm/mach-omap2/voltage.c              |   47 ++++-
 arch/arm/mach-omap2/voltage.h              |   32 +++-
 arch/arm/plat-omap/include/plat/control.h  |    8 +
 7 files changed, 464 insertions(+), 94 deletions(-)
#1 lore raw

PATCH v2 1/3 OMAP3: PM: Fix crash when enabling SmartReflex on non-supported OMAPs.

This patch sets and unsets is_sr_reset is appropriate places so that trying to enable smart reflex in a non-supported OMAP chip does not lead to unnecessary crash. Basically today if sr_enable fails, sr_disable will crash due to accessing sr registers when sr clocks are not turned on. By checking on is_sr_reset flag and setting and unsetting this flag appropriately this crash is fixed in this patch.

---
 arch/arm/mach-omap2/smartreflex.c |   31 +++++++++++++++++++++----------
 1 files changed, 21 insertions(+), 10 deletions(-)
arch/arm/mach-omap2/smartreflex.c +21 -10
index 1d7d2e6..3f4b47b 100644
@@ -115,9 +115,14 @@ static int sr_clk_enable(struct omap_sr *sr)
 {
 	struct omap_smartreflex_data *pdata = sr->pdev->dev.platform_data;
 
+	if (!sr->is_sr_reset)
+		return 0;
+
 	if (pdata->device_enable)
 		pdata->device_enable(sr->pdev);
 
+	sr->is_sr_reset = 0;
+
 	return 0;
 }
 
@@ -125,6 +130,9 @@ static void sr_clk_disable(struct omap_sr *sr)
 {
 	struct omap_smartreflex_data *pdata = sr->pdev->dev.platform_data;
 
+	if (sr->is_sr_reset)
+		return;
+
 	if (pdata->device_idle)
 		pdata->device_idle(sr->pdev);
 
@@ -308,7 +316,6 @@ static void sr_configure(struct omap_sr *sr)
 			 ERRCONFIG_MCUVALIDINTEN | ERRCONFIG_MCUVALIDINTST |
 			 ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_MCUBOUNDINTST));
 	}
-	sr->is_sr_reset = 0;
 }
 
 static void sr_start_vddautocomp(int srid)
@@ -329,8 +336,7 @@ static void sr_start_vddautocomp(int srid)
 	sr->is_autocomp_active = 1;
 	if (!sr_class->enable(srid)) {
 		sr->is_autocomp_active = 0;
-		if (sr->is_sr_reset == 1)
-			sr_clk_disable(sr);
+		sr_clk_disable(sr);
 	}
 }
 
@@ -350,8 +356,10 @@ static void  sr_stop_vddautocomp(int srid)
 	}
 
 	if (sr->is_autocomp_active == 1) {
-		sr_class->disable(srid);
-		sr_clk_disable(sr);
+		if (!sr->is_sr_reset) {
+			sr_class->disable(srid);
+			sr_clk_disable(sr);
+		}
 		sr->is_autocomp_active = 0;
 	}
 }
@@ -431,6 +439,11 @@ int sr_enable(int srid, unsigned long volt)
 
 	/* Enable the clocks and configure SR */
 	sr_clk_enable(sr);
+
+	/* Check if SR is already enabled. If yes do nothing */
+	if (sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE)
+		return true;
+
 	sr_configure(sr);
 
 	sr_write_reg(sr, NVALUERECIPROCAL, nvalue_reciprocal);
@@ -518,10 +531,8 @@ void omap_smartreflex_enable(int srid)
 	}
 
 	if (sr->is_autocomp_active == 1) {
-		if (sr->is_sr_reset == 1) {
-			if (!sr_class->enable(srid))
-				sr_clk_disable(sr);
-		}
+		if (!sr_class->enable(srid))
+			sr_clk_disable(sr);
 	}
 }
 
@@ -550,7 +561,7 @@ void omap_smartreflex_disable(int srid)
 	}
 
 	if (sr->is_autocomp_active == 1) {
-		if (sr->is_sr_reset == 0) {
+		if (!sr->is_sr_reset) {
 			sr_class->disable(srid);
 			/* Disable SR clk */
 			sr_clk_disable(sr);
Signature · 1 line
1.7.0.rc1.33.g07cf0f
#2 lore raw

PATCH v2 2/3 OMAP3: PM: Smartreflex IP update changes for OMAP3630

OMAP3430 uses the 65nm version of the smartreflex IP where as OMAP3630 and OMAP4430 uses the 45nm updated IP.

This patch adds support for the updated smartreflex IP used in OMAP3630 and OMAP4 in the smartreflex driver.

Major changes between the two versions of IP involve:
1. Change in offset position for ERRCONFIG and SENERROR registers
2. Change in bit positions for VP bound interrupt enable and status in ERRCONFIG register.
3. Change in bit positions and width of SENNENABLE and SENPENABLE bits in SRCONFIG registers.
4. Introduction of separate irq registers for MCU bound interrupts.
5. Removal of clockactivity bits in ERRCONFIG and introduction of idlemode and wakeupenable bits in ERRCONFIG.

---
 arch/arm/mach-omap2/smartreflex.c |  211 ++++++++++++++++++++++++++++---------
 arch/arm/mach-omap2/smartreflex.h |   45 +++++++--
 2 files changed, 199 insertions(+), 57 deletions(-)
arch/arm/mach-omap2/smartreflex.c +161 -50
index 3f4b47b..0e5c052 100644
@@ -42,6 +42,7 @@ struct omap_sr {
 	int				srid;
 	int				is_sr_reset;
 	int				is_autocomp_active;
+	int				sr_ip_type;
 	u32				clk_length;
 	u32				err_weight;
 	u32				err_minlimit;
@@ -59,6 +60,18 @@ struct omap_sr {
 static LIST_HEAD(sr_list);
 static struct omap_smartreflex_class_data *sr_class;
 
+static inline int sr_type(void)
+{
+	if (cpu_is_omap3630())
+		return SR_TYPE_V2;
+	else if (cpu_is_omap343x())
+		return SR_TYPE_V1;
+	else {
+		pr_err("Trying to enable SR for Chip not support SR!\n");
+		return 0;
+	}
+}
+
 static inline void sr_write_reg(struct omap_sr *sr, unsigned offset, u32 value)
 {
 	struct omap_device *odev = to_omap_device(sr->pdev);
@@ -71,6 +84,7 @@ static inline void sr_modify_reg(struct omap_sr *sr, unsigned offset, u32 mask,
 {
 	struct omap_device *odev = to_omap_device(sr->pdev);
 	u32 reg_val;
+	u32 errconfig_offs, errconfig_mask;
 
 	reg_val = omap_hwmod_readl(odev->hwmods[0], offset);
 	reg_val &= ~mask;
@@ -82,8 +96,15 @@ static inline void sr_modify_reg(struct omap_sr *sr, unsigned offset, u32 mask,
 	 * value. Now if there is an actual reguest to write to these bits
 	 * they will be set in the nex step.
 	 */
-	if (offset == ERRCONFIG)
-		reg_val &= ~ERRCONFIG_STATUS_MASK;
+	if (sr->sr_ip_type == SR_TYPE_V1) {
+		errconfig_offs = ERRCONFIG_V1;
+		errconfig_mask = ERRCONFIG_STATUS_V1_MASK;
+	} else if (sr->sr_ip_type == SR_TYPE_V2) {
+		errconfig_offs = ERRCONFIG_V2;
+		errconfig_mask = ERRCONFIG_VPBOUNDINTST_V2;
+	}
+	if (offset == errconfig_offs)
+		reg_val &= ~errconfig_mask;
 
 	reg_val |= value;
 
@@ -163,13 +184,21 @@ static int sr_match_volt(struct omap_sr *sr, unsigned long volt,
 static irqreturn_t sr_omap_isr(int irq, void *data)
 {
 	struct omap_sr *sr_info = (struct omap_sr *)data;
-	u32 status;
+	u32 status = 0;
+
+	if (sr_info->sr_ip_type == SR_TYPE_V1) {
+		/* Read the status bits */
+		status = sr_read_reg(sr_info, ERRCONFIG_V1);
 
-	/* Read the status bits */
-	status = sr_read_reg(sr_info, ERRCONFIG);
+		/* Clear them by writing back */
+		sr_write_reg(sr_info, ERRCONFIG_V1, status);
+	} else if (sr_info->sr_ip_type == SR_TYPE_V2) {
+		/* Read the status bits */
+		sr_read_reg(sr_info, IRQSTATUS);
 
-	/* Clear them by writing back */
-	sr_write_reg(sr_info, ERRCONFIG, status);
+		/* Clear them by writing back */
+		sr_write_reg(sr_info, IRQSTATUS, status);
+	}
 
 	/* Call the class driver notify function if registered*/
 	if (sr_class->class_type == SR_CLASS2 && sr_class->notify)
@@ -254,6 +283,7 @@ static void sr_configure(struct omap_sr *sr)
 {
 	u32 sr_config;
 	u32 senp_en , senn_en;
+	u8 senp_shift, senn_shift;
 	struct omap_smartreflex_data *pdata = sr->pdev->dev.platform_data;
 
 	/* Common settings for SR Class3 and SR Class2 */
@@ -264,8 +294,16 @@ static void sr_configure(struct omap_sr *sr)
 	senn_en = pdata->senn_mod;
 
 	sr_config = (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
-		SRCONFIG_SENENABLE | (senn_en << SRCONFIG_SENNENABLE_SHIFT) |
-		(senp_en << SRCONFIG_SENPENABLE_SHIFT) | SRCONFIG_DELAYCTRL;
+		SRCONFIG_SENENABLE;
+	if (sr->sr_ip_type == SR_TYPE_V1) {
+		sr_config |= SRCONFIG_DELAYCTRL;
+		senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT;
+		senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT;
+	} else if (sr->sr_ip_type == SR_TYPE_V2) {
+		senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT;
+		senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT;
+	}
+	sr_config |= ((senn_en << senn_shift) | (senp_en << senp_shift));
 	sr_write_reg(sr, SRCONFIG, sr_config);
 
 	if ((sr_class->class_type == SR_CLASS3) || (sr_class->class_type ==
@@ -276,20 +314,30 @@ static void sr_configure(struct omap_sr *sr)
 		 * SR CLASS 2 can choose between ERROR module and MINMAXAVG
 		 * module.
 		 */
-		u32 sr_errconfig;
+		u32 sr_errconfig, errconfig_offs;
+		u32 vpboundint_en, vpboundint_st;
+
+		if (sr->sr_ip_type == SR_TYPE_V1) {
+			errconfig_offs = ERRCONFIG_V1;
+			vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V1;
+			vpboundint_st = ERRCONFIG_VPBOUNDINTST_V1;
+		} else if (sr->sr_ip_type == SR_TYPE_V2) {
+			errconfig_offs = ERRCONFIG_V2;
+			vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V2;
+			vpboundint_st = ERRCONFIG_VPBOUNDINTST_V2;
+		}
 
 		sr_modify_reg(sr, SRCONFIG, SRCONFIG_ERRGEN_EN,
 			SRCONFIG_ERRGEN_EN);
 		sr_errconfig = (sr->err_weight << ERRCONFIG_ERRWEIGHT_SHIFT) |
 			(sr->err_maxlimit << ERRCONFIG_ERRMAXLIMIT_SHIFT) |
 			(sr->err_minlimit <<  ERRCONFIG_ERRMiNLIMIT_SHIFT);
-		sr_modify_reg(sr, ERRCONFIG, (SR_ERRWEIGHT_MASK |
+		sr_modify_reg(sr, errconfig_offs, (SR_ERRWEIGHT_MASK |
 			SR_ERRMAXLIMIT_MASK | SR_ERRMINLIMIT_MASK),
 			sr_errconfig);
 		/* Enabling the interrupts if the ERROR module is used */
-		sr_modify_reg(sr, ERRCONFIG,
-			(ERRCONFIG_VPBOUNDINTEN),
-			(ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST));
+		sr_modify_reg(sr, errconfig_offs,
+			(vpboundint_en), (vpboundint_en | vpboundint_st));
 	} else if ((sr_class->class_type == SR_CLASS2) &&
 			(sr_class->calib_mode == SR_USE_MINMAXAVG_MOD)) {
 		/*
@@ -309,12 +357,27 @@ static void sr_configure(struct omap_sr *sr)
 		 * Enabling the interrupts if MINMAXAVG module is used.
 		 * TODO: check if all the interrupts are mandatory
 		 */
-		sr_modify_reg(sr, ERRCONFIG,
-			(ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN |
-			ERRCONFIG_MCUBOUNDINTEN),
-			(ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUACCUMINTST |
-			 ERRCONFIG_MCUVALIDINTEN | ERRCONFIG_MCUVALIDINTST |
-			 ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_MCUBOUNDINTST));
+		if (sr->sr_ip_type == SR_TYPE_V1) {
+			sr_modify_reg(sr, ERRCONFIG_V1,
+				(ERRCONFIG_MCUACCUMINTEN |
+				ERRCONFIG_MCUVALIDINTEN |
+				ERRCONFIG_MCUBOUNDINTEN),
+				(ERRCONFIG_MCUACCUMINTEN |
+				ERRCONFIG_MCUACCUMINTST |
+				ERRCONFIG_MCUVALIDINTEN |
+				ERRCONFIG_MCUVALIDINTST |
+				ERRCONFIG_MCUBOUNDINTEN |
+				ERRCONFIG_MCUBOUNDINTST));
+		} else if (sr->sr_ip_type == SR_TYPE_V2) {
+			sr_write_reg(sr, IRQSTATUS,
+				IRQSTATUS_MCUACCUMINT | IRQSTATUS_MCVALIDINT |
+				IRQSTATUS_MCBOUNDSINT |
+				IRQSTATUS_MCUDISABLEACKINT);
+			sr_write_reg(sr, IRQENABLE_SET,
+				IRQENABLE_MCUACCUMINT | IRQENABLE_MCUVALIDINT |
+				IRQENABLE_MCUBOUNDSINT |
+				IRQENABLE_MCUDISABLEACKINT);
+		}
 	}
 }
 
@@ -399,6 +462,77 @@ static int sr_late_init(struct omap_sr *sr_info)
 	return ret;
 }
 
+static void sr_v1_disable(struct omap_sr *sr)
+{
+	int timeout = 0;
+
+	/* Enable MCUDisableAcknowledge interrupt */
+	sr_modify_reg(sr, ERRCONFIG_V1,
+			ERRCONFIG_MCUDISACKINTEN, ERRCONFIG_MCUDISACKINTEN);
+
+	/* SRCONFIG - disable SR */
+	sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0);
+
+	/* Disable all other SR interrupts and clear the status */
+	sr_modify_reg(sr, ERRCONFIG_V1,
+			(ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN |
+			ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_VPBOUNDINTEN_V1),
+			(ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTST |
+			ERRCONFIG_MCUBOUNDINTST |
+			ERRCONFIG_VPBOUNDINTST_V1));
+
+	/*
+	 * Wait for SR to be disabled.
+	 * wait until ERRCONFIG.MCUDISACKINTST = 1. Typical latency is 1us.
+	 */
+	omap_test_timeout((sr_read_reg(sr, ERRCONFIG_V1) &
+			ERRCONFIG_MCUDISACKINTST), SR_DISABLE_TIMEOUT,
+			timeout);
+
+	if (timeout >= SR_DISABLE_TIMEOUT)
+		pr_warning("SR%d disable timedout\n", sr->srid);
+
+	/* Disable MCUDisableAcknowledge interrupt & clear pending interrupt */
+	sr_modify_reg(sr, ERRCONFIG_V1, ERRCONFIG_MCUDISACKINTEN,
+			ERRCONFIG_MCUDISACKINTST);
+}
+
+static void sr_v2_disable(struct omap_sr *sr)
+{
+	int timeout = 0;
+
+	/* Enable MCUDisableAcknowledge interrupt */
+	sr_write_reg(sr, IRQENABLE_SET, IRQENABLE_MCUDISABLEACKINT);
+
+	/* SRCONFIG - disable SR */
+	sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0);
+
+	/* Disable all other SR interrupts and clear the status */
+	sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2,
+			ERRCONFIG_VPBOUNDINTST_V2);
+	sr_write_reg(sr, IRQENABLE_CLR, (IRQENABLE_MCUACCUMINT |
+			IRQENABLE_MCUVALIDINT |
+			IRQENABLE_MCUBOUNDSINT));
+	sr_write_reg(sr, IRQSTATUS, (IRQSTATUS_MCUACCUMINT |
+			IRQSTATUS_MCVALIDINT |
+			IRQSTATUS_MCBOUNDSINT));
+
+	/*
+	 * Wait for SR to be disabled.
+	 * wait until IRQSTATUS.MCUDISACKINTST = 1. Typical latency is 1us.
+	 */
+	omap_test_timeout((sr_read_reg(sr, IRQSTATUS) &
+			IRQSTATUS_MCUDISABLEACKINT), SR_DISABLE_TIMEOUT,
+			timeout);
+
+	if (timeout >= SR_DISABLE_TIMEOUT)
+		pr_warning("SR%d disable timedout\n", sr->srid);
+
+	/* Disable MCUDisableAcknowledge interrupt & clear pending interrupt */
+	sr_write_reg(sr, IRQENABLE_CLR, IRQENABLE_MCUDISABLEACKINT);
+	sr_write_reg(sr, IRQSTATUS, IRQSTATUS_MCUDISABLEACKINT);
+}
+
 /* Public Functions */
 
 /**
@@ -462,7 +596,6 @@ int sr_enable(int srid, unsigned long volt)
 void sr_disable(int srid)
 {
 	struct omap_sr *sr = _sr_lookup(srid);
-	int timeout = 0;
 
 	if (!sr) {
 		pr_warning("omap_sr struct corresponding to SR%d not found\n",
@@ -474,35 +607,12 @@ void sr_disable(int srid)
 	if (!(sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE))
 		return;
 
-	/* Enable MCUDisableAcknowledge interrupt */
-	sr_modify_reg(sr, ERRCONFIG,
-			ERRCONFIG_MCUDISACKINTEN, ERRCONFIG_MCUDISACKINTEN);
-
-	/* SRCONFIG - disable SR */
-	sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0);
-
-	/* Disable all other SR interrupts and clear the status */
-	sr_modify_reg(sr, ERRCONFIG,
-			(ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN |
-			ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_VPBOUNDINTEN),
-			(ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTST |
-			ERRCONFIG_MCUBOUNDINTST | ERRCONFIG_VPBOUNDINTST));
-
-	/* Wait for SR to be disabled.
-	 * wait until ERRCONFIG.MCUDISACKINTST = 1. Typical latency is 1us.
-	 */
-	omap_test_timeout((sr_read_reg(sr, ERRCONFIG) &
-			ERRCONFIG_MCUDISACKINTST), SR_DISABLE_TIMEOUT,
-			timeout);
-
-	if (timeout >= SR_DISABLE_TIMEOUT)
-		pr_warning("SR%d disable timedout\n", srid);
-
-	/* Disable MCUDisableAcknowledge interrupt & clear pending interrupt
-	 * Also enable VPBOUND interrrupt
-	 */
-	sr_modify_reg(sr, ERRCONFIG, ERRCONFIG_MCUDISACKINTEN,
-			ERRCONFIG_MCUDISACKINTST);
+	if (sr->sr_ip_type == SR_TYPE_V1)
+		sr_v1_disable(sr);
+	else if (sr->sr_ip_type == SR_TYPE_V2)
+		sr_v2_disable(sr);
+	else
+		return;
 }
 
 /**
@@ -663,6 +773,7 @@ static int __devinit omap_smartreflex_probe(struct platform_device *pdev)
 	sr_info->is_sr_reset = 1,
 	sr_info->is_autocomp_active = 0;
 	sr_info->clk_length = 0;
+	sr_info->sr_ip_type = sr_type();
 	if (odev->hwmods[0]->mpu_irqs)
 		sr_info->irq = odev->hwmods[0]->mpu_irqs[0].irq;
 	sr_set_clk_length(sr_info);
arch/arm/mach-omap2/smartreflex.h +38 -7

82 lines not on this page · raw message

Signature · 1 line
1.7.0.rc1.33.g07cf0f
#3 lore raw

PATCH v2 3/3 OMAP3: PM: Adding OMAP3630 support in smartreflex driver

This patch adapts smartreflex driver to support OMAP3630 also. Changes involve:
1. Separate hwmod structures for OMAP3630 distinguished from 3430 structures using omap_chip attribute.
2. Introducing new test nvalues for OMAP3630.
3. OMAP3630 specific changes for srconfig err_minlimit field, vpx_config errorgain field and vpx_vlimitto vddmax and vddmin fields.

---
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |   47 +++++++++++++-
 arch/arm/mach-omap2/smartreflex.c          |   38 ++++++++---
 arch/arm/mach-omap2/smartreflex.h          |    5 +-
 arch/arm/mach-omap2/sr_device.c            |   94 +++++++++++++++++++++++++++-
 arch/arm/mach-omap2/voltage.c              |   47 ++++++++++++--
 arch/arm/mach-omap2/voltage.h              |   32 ++++++++--
 arch/arm/plat-omap/include/plat/control.h  |    8 +++
 7 files changed, 244 insertions(+), 27 deletions(-)
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +45 -2
index 9c0c9e3..c78f128 100644
@@ -222,6 +222,25 @@ static struct omap_hwmod_class omap34xx_smartreflex_hwmod_class = {
 	.rev  = 1,
 };
 
+static struct omap_hwmod_sysc_fields omap36xx_sr_sysc_fields = {
+	.sidle_shift	= 24,
+	.enwkup_shift	= 26
+};
+
+static struct omap_hwmod_class_sysconfig omap36xx_sr_sysc = {
+	.sysc_offs	= 0x38,
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+	.sysc_flags	= (SYSC_HAS_SIDLEMODE | SYSC_HAS_ENAWAKEUP |
+			SYSC_NO_CACHE),
+	.sysc_fields	= &omap36xx_sr_sysc_fields,
+};
+
+static struct omap_hwmod_class omap36xx_smartreflex_hwmod_class = {
+	.name = "smartreflex",
+	.sysc = &omap36xx_sr_sysc,
+	.rev  = 2,
+};
+
 /* SR1 */
 static struct omap_hwmod_ocp_if *omap34xx_sr1_slaves[] = {
 	&omap3_l4_core__sr1,
@@ -235,10 +254,21 @@ static struct omap_hwmod omap34xx_sr1_hwmod = {
 	.main_clk	= "sr1_fck",
 	.slaves		= omap34xx_sr1_slaves,
 	.slaves_cnt	= ARRAY_SIZE(omap34xx_sr1_slaves),
-	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2 |
+					CHIP_IS_OMAP3430ES3_0 |
+					CHIP_IS_OMAP3430ES3_1),
 	.flags		= HWMOD_SET_DEFAULT_CLOCKACT,
 };
 
+static struct omap_hwmod omap36xx_sr1_hwmod = {
+	.name		= "sr1_hwmod",
+	.class		= &omap36xx_smartreflex_hwmod_class,
+	.main_clk	= "sr1_fck",
+	.slaves		= omap34xx_sr1_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap34xx_sr1_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3630ES1),
+};
+
 /* SR2 */
 static struct omap_hwmod_ocp_if *omap34xx_sr2_slaves[] = {
 	&omap3_l4_core__sr2,
@@ -252,10 +282,21 @@ static struct omap_hwmod omap34xx_sr2_hwmod = {
 	.main_clk	= "sr2_fck",
 	.slaves		= omap34xx_sr2_slaves,
 	.slaves_cnt	= ARRAY_SIZE(omap34xx_sr2_slaves),
-	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2 |
+					CHIP_IS_OMAP3430ES3_0 |
+					CHIP_IS_OMAP3430ES3_1),
 	.flags		= HWMOD_SET_DEFAULT_CLOCKACT,
 };
 
+static struct omap_hwmod omap36xx_sr2_hwmod = {
+	.name		= "sr2_hwmod",
+	.class		= &omap36xx_smartreflex_hwmod_class,
+	.main_clk	= "sr2_fck",
+	.slaves		= omap34xx_sr2_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap34xx_sr2_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3630ES1),
+};
+
 static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
 	&omap3xxx_l3_hwmod,
 	&omap3xxx_l4_core_hwmod,
@@ -264,6 +305,8 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
 	&omap3xxx_mpu_hwmod,
 	&omap34xx_sr1_hwmod,
 	&omap34xx_sr2_hwmod,
+	&omap36xx_sr1_hwmod,
+	&omap36xx_sr2_hwmod,
 	NULL,
 };
 
arch/arm/mach-omap2/smartreflex.c +28 -10
index 0e5c052..9ff306c 100644
@@ -246,7 +246,7 @@ static void sr_set_regfields(struct omap_sr *sr)
 	 * file or pmic specific data structure. In that case these structure
 	 * fields will have to be populated using the pdata or pmic structure.
 	 */
-	if (cpu_is_omap343x()) {
+	if (cpu_is_omap34xx()) {
 		struct omap_smartreflex_data *pdata =
 					sr->pdev->dev.platform_data;
 		sr->err_weight = OMAP3430_SR_ERRWEIGHT;
@@ -255,28 +255,46 @@ static void sr_set_regfields(struct omap_sr *sr)
 		if (sr->srid == SR1) {
 			sr->senn_avgweight = OMAP3430_SR1_SENNAVGWEIGHT;
 			sr->senp_avgweight = OMAP3430_SR1_SENPAVGWEIGHT;
-			pdata->sr_volt_data[0].sr_errminlimit =
+			if (cpu_is_omap3630()) {
+				pdata->sr_volt_data[0].sr_errminlimit =
 					OMAP3430_SR_ERRMINLIMIT_LOWOPP;
-			pdata->sr_volt_data[1].sr_errminlimit =
+				pdata->sr_volt_data[1].sr_errminlimit =
+					OMAP3430_SR_ERRMINLIMIT_HIGHOPP;
+				pdata->sr_volt_data[2].sr_errminlimit =
+					OMAP3630_SR_ERRMINLIMIT_OPPTB;
+				pdata->sr_volt_data[3].sr_errminlimit =
+					OMAP3630_SR_ERRMINLIMIT_OPPTB;
+			} else {
+				pdata->sr_volt_data[0].sr_errminlimit =
+					OMAP3430_SR_ERRMINLIMIT_LOWOPP;
+				pdata->sr_volt_data[1].sr_errminlimit =
 					OMAP3430_SR_ERRMINLIMIT_LOWOPP;
-			pdata->sr_volt_data[2].sr_errminlimit =
+				pdata->sr_volt_data[2].sr_errminlimit =
 					OMAP3430_SR_ERRMINLIMIT_HIGHOPP;
-			pdata->sr_volt_data[3].sr_errminlimit =
+				pdata->sr_volt_data[3].sr_errminlimit =
 					OMAP3430_SR_ERRMINLIMIT_HIGHOPP;
-			pdata->sr_volt_data[4].sr_errminlimit =
+				pdata->sr_volt_data[4].sr_errminlimit =
 					OMAP3430_SR_ERRMINLIMIT_HIGHOPP;
+			}
 		} else {
 			sr->senn_avgweight = OMAP3430_SR2_SENNAVGWEIGHT;
 			sr->senp_avgweight = OMAP3430_SR2_SENPAVGWEIGHT;
-			pdata->sr_volt_data[0].sr_errminlimit =
+			if (cpu_is_omap3630()) {
+				pdata->sr_volt_data[0].sr_errminlimit =
+					OMAP3430_SR_ERRMINLIMIT_LOWOPP;
+				pdata->sr_volt_data[1].sr_errminlimit =
+					OMAP3430_SR_ERRMINLIMIT_HIGHOPP;
+			} else {
+				pdata->sr_volt_data[0].sr_errminlimit =
 					OMAP3430_SR_ERRMINLIMIT_LOWOPP;
-			pdata->sr_volt_data[1].sr_errminlimit =
+				pdata->sr_volt_data[1].sr_errminlimit =
 					OMAP3430_SR_ERRMINLIMIT_LOWOPP;
-			pdata->sr_volt_data[2].sr_errminlimit =
+				pdata->sr_volt_data[2].sr_errminlimit =
 					OMAP3430_SR_ERRMINLIMIT_HIGHOPP;
+			}
 		}
 	}
-	/* TODO: 3630 and Omap4 specific bit field values */
+	/* TODO: Omap4 specific bit field values */
 }
 
 static void sr_configure(struct omap_sr *sr)
arch/arm/mach-omap2/smartreflex.h +4 -1
index 66c3770..a126362 100644
@@ -146,7 +146,10 @@ extern struct dentry *pm_dbg_main_dir;
 #define OMAP3430_SR_ERRMINLIMIT_HIGHOPP	0xF9
 #define OMAP3430_SR_ERRMINLIMIT_LOWOPP	0xF4
 
-/* TODO:3630/OMAP4 values if it has to come from this file */
+/* OMAP3630 specific values */
+#define OMAP3630_SR_ERRMINLIMIT_OPPTB   0xFA
+
+/* TODO:OMAP4 specific values */
 
 /* Info for enabling SR in T2/gaia. ToDo: Move it to twl4030_power.c */
 #define PHY_TO_OFF_PM_RECIEVER(p)	(p - 0x5b)
arch/arm/mach-omap2/sr_device.c +92 -2

121 lines not on this page · raw message

arch/arm/mach-omap2/voltage.c +41 -6

73 lines not on this page · raw message

arch/arm/mach-omap2/voltage.h +26 -6
index a350444..61b3220 100644
@@ -54,19 +54,39 @@
  * board file or PMIC data structure
  */
 #define OMAP3_VP_CONFIG_ERROROFFSET		0x00
-#define OMAP3_VP_CONFIG_ERRORGAIN_LOWOPP	0x0C
-#define OMAP3_VP_CONFIG_ERRORGAIN_HIGHOPP	0x18
 #define OMAP3_VP_VSTEPMIN_SMPSWAITTIMEMIN	0x3C
 #define OMAP3_VP_VSTEPMIN_VSTEPMIN		0x1
 #define OMAP3_VP_VSTEPMAX_SMPSWAITTIMEMAX	0x3C
 #define OMAP3_VP_VSTEPMAX_VSTEPMAX		0x04
-#define OMAP3_VP1_VLIMITTO_VDDMIN		0x14
-#define OMAP3_VP1_VLIMITTO_VDDMAX		0x42
-#define OMAP3_VP2_VLIMITTO_VDDMAX		0x2C
-#define OMAP3_VP2_VLIMITTO_VDDMIN		0x18
 #define OMAP3_VP_VLIMITTO_TIMEOUT_US		0x200
 
 #define VOLTAGE_MOD	OMAP3430_GR_MOD
+
+/*
+ * Omap3430 specific VP register values. Maybe these need to come from
+ * board file or PMIC data structure
+ */
+#define OMAP3430_VP_CONFIG_ERRORGAIN_LOWOPP	0x0C
+#define OMAP3430_VP_CONFIG_ERRORGAIN_HIGHOPP	0x18
+#define OMAP3430_VP1_VLIMITTO_VDDMIN		0x14
+#define OMAP3430_VP1_VLIMITTO_VDDMAX		0x42
+#define OMAP3430_VP2_VLIMITTO_VDDMAX		0x2C
+#define OMAP3430_VP2_VLIMITTO_VDDMIN		0x18
+
+/*
+ * Omap3630 specific VP register values. Maybe these need to come from
+ * board file or PMIC data structure
+ */
+#define OMAP3630_VP_CONFIG_ERRORGAIN_OPP50	0x0C
+#define OMAP3630_VP_CONFIG_ERRORGAIN_OPP100	0x16
+#define OMAP3630_VP_CONFIG_ERRORGAIN_OPPTB	0x23
+#define OMAP3630_VP_CONFIG_ERRORGAIN_OPP1G	0x27
+#define OMAP3630_VP1_VLIMITTO_VDDMIN		0x18
+#define OMAP3630_VP1_VLIMITTO_VDDMAX		0x3C
+#define OMAP3630_VP2_VLIMITTO_VDDMIN		0x18
+#define OMAP3630_VP2_VLIMITTO_VDDMAX		0x30
+
+
 /* TODO OMAP4 VP register values if the same file is used for OMAP4*/
 
 void omap_voltageprocessor_enable(int vp_id);
arch/arm/plat-omap/include/plat/control.h +8 -0
index d540ae8..7a94feb 100644
@@ -169,6 +169,14 @@
 #define OMAP343X_CONTROL_SRAMLDO5	(OMAP2_CONTROL_GENERAL + 0x02C0)
 #define OMAP343X_CONTROL_CSI		(OMAP2_CONTROL_GENERAL + 0x02C4)
 
+/* OMAP3630 only CONTROL_GENERAL register offsets */
+#define OMAP3630_CONTROL_FUSE_OPP50_VDD1	(OMAP2_CONTROL_GENERAL + 0x0114)
+#define OMAP3630_CONTROL_FUSE_OPP100_VDD1	(OMAP2_CONTROL_GENERAL + 0x0118)
+#define OMAP3630_CONTROL_FUSE_OPP120_VDD1	(OMAP2_CONTROL_GENERAL + 0x011C)
+#define OMAP3630_CONTROL_FUSE_OPPTM_VDD1	(OMAP2_CONTROL_GENERAL + 0x0120)
+#define OMAP3630_CONTROL_FUSE_OPP50_VDD2	(OMAP2_CONTROL_GENERAL + 0x0128)
+#define OMAP3630_CONTROL_FUSE_OPP100_VDD2	(OMAP2_CONTROL_GENERAL + 0x012C)
+
 /* AM35XX only CONTROL_GENERAL register offsets */
 #define AM35XX_CONTROL_MSUSPENDMUX_6    (OMAP2_CONTROL_GENERAL + 0x0038)
 #define AM35XX_CONTROL_DEVCONF2         (OMAP2_CONTROL_GENERAL + 0x0310)
Signature · 1 line
1.7.0.rc1.33.g07cf0f
#4 lore raw

Re: [PATCHv2 3/3] OMAP3: PM: Adding OMAP3630 support in smartreflex driver

Thara Gopinath said the following on 03/31/2010 01:30 AM:

Quoted 110 lines

This patch adapts smartreflex driver to support OMAP3630 also. Changes involve:
1. Separate hwmod structures for OMAP3630 distinguished from 3430 structures using omap_chip attribute.
2. Introducing new test nvalues for OMAP3630.
3. OMAP3630 specific changes for srconfig err_minlimit field, vpx_config errorgain field and vpx_vlimitto vddmax and vddmin fields.

---
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |   47 +++++++++++++-
 arch/arm/mach-omap2/smartreflex.c          |   38 ++++++++---
 arch/arm/mach-omap2/smartreflex.h          |    5 +-
 arch/arm/mach-omap2/sr_device.c            |   94 +++++++++++++++++++++++++++-
 arch/arm/mach-omap2/voltage.c              |   47 ++++++++++++--
 arch/arm/mach-omap2/voltage.h              |   32 ++++++++--
 arch/arm/plat-omap/include/plat/control.h  |    8 +++
 7 files changed, 244 insertions(+), 27 deletions(-)
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +45 -2
index 9c0c9e3..c78f128 100644
@@ -222,6 +222,25 @@ static struct omap_hwmod_class omap34xx_smartreflex_hwmod_class = {
 	.rev  = 1,
 };
 
+static struct omap_hwmod_sysc_fields omap36xx_sr_sysc_fields = {
+	.sidle_shift	= 24,
+	.enwkup_shift	= 26
+};
+
+static struct omap_hwmod_class_sysconfig omap36xx_sr_sysc = {
+	.sysc_offs	= 0x38,
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+	.sysc_flags	= (SYSC_HAS_SIDLEMODE | SYSC_HAS_ENAWAKEUP |
+			SYSC_NO_CACHE),
+	.sysc_fields	= &omap36xx_sr_sysc_fields,
+};
+
+static struct omap_hwmod_class omap36xx_smartreflex_hwmod_class = {
+	.name = "smartreflex",
+	.sysc = &omap36xx_sr_sysc,
+	.rev  = 2,
+};
+
 /* SR1 */
 static struct omap_hwmod_ocp_if *omap34xx_sr1_slaves[] = {
 	&omap3_l4_core__sr1,
@@ -235,10 +254,21 @@ static struct omap_hwmod omap34xx_sr1_hwmod = {
 	.main_clk	= "sr1_fck",
 	.slaves		= omap34xx_sr1_slaves,
 	.slaves_cnt	= ARRAY_SIZE(omap34xx_sr1_slaves),
-	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2 |
+					CHIP_IS_OMAP3430ES3_0 |
+					CHIP_IS_OMAP3430ES3_1),
 	.flags		= HWMOD_SET_DEFAULT_CLOCKACT,
 };
 
+static struct omap_hwmod omap36xx_sr1_hwmod = {
+	.name		= "sr1_hwmod",
+	.class		= &omap36xx_smartreflex_hwmod_class,
+	.main_clk	= "sr1_fck",
+	.slaves		= omap34xx_sr1_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap34xx_sr1_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3630ES1),
+};
+
 /* SR2 */
 static struct omap_hwmod_ocp_if *omap34xx_sr2_slaves[] = {
 	&omap3_l4_core__sr2,
@@ -252,10 +282,21 @@ static struct omap_hwmod omap34xx_sr2_hwmod = {
 	.main_clk	= "sr2_fck",
 	.slaves		= omap34xx_sr2_slaves,
 	.slaves_cnt	= ARRAY_SIZE(omap34xx_sr2_slaves),
-	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2 |
+					CHIP_IS_OMAP3430ES3_0 |
+					CHIP_IS_OMAP3430ES3_1),
 	.flags		= HWMOD_SET_DEFAULT_CLOCKACT,
 };
 
+static struct omap_hwmod omap36xx_sr2_hwmod = {
+	.name		= "sr2_hwmod",
+	.class		= &omap36xx_smartreflex_hwmod_class,
+	.main_clk	= "sr2_fck",
+	.slaves		= omap34xx_sr2_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap34xx_sr2_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3630ES1),
+};
+
 static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
 	&omap3xxx_l3_hwmod,
 	&omap3xxx_l4_core_hwmod,
@@ -264,6 +305,8 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
 	&omap3xxx_mpu_hwmod,
 	&omap34xx_sr1_hwmod,
 	&omap34xx_sr2_hwmod,
+	&omap36xx_sr1_hwmod,
+	&omap36xx_sr2_hwmod,
 	NULL,
 };
 
arch/arm/mach-omap2/smartreflex.c +0 -0
index 0e5c052..9ff306c 100644

arch/arm/mach-omap2/smartreflex.c static void sr_set_regfields(struct omap_sr *sr) · line 250

Quoted 6 lines
arch/arm/mach-omap2/smartreflex.c +1 -1
@@ -246,7 +246,7 @@ static void sr_set_regfields(struct omap_sr *sr)
 	 * file or pmic specific data structure. In that case these structure
 	 * fields will have to be populated using the pdata or pmic structure.
 	 */
-	if (cpu_is_omap343x()) {
+	if (cpu_is_omap34xx()) {
 

I dont see any change here.

Quoted 47 lines
arch/arm/mach-omap2/smartreflex.c +0 -0
 		struct omap_smartreflex_data *pdata =
 					sr->pdev->dev.platform_data;
arch/arm/mach-omap2/smartreflex.c +24 -7
 		sr->err_weight = OMAP3430_SR_ERRWEIGHT;
@@ -255,28 +255,46 @@ static void sr_set_regfields(struct omap_sr *sr)
 		if (sr->srid == SR1) {
 			sr->senn_avgweight = OMAP3430_SR1_SENNAVGWEIGHT;
 			sr->senp_avgweight = OMAP3430_SR1_SENPAVGWEIGHT;
-			pdata->sr_volt_data[0].sr_errminlimit =
+			if (cpu_is_omap3630()) {
+				pdata->sr_volt_data[0].sr_errminlimit =
 					OMAP3430_SR_ERRMINLIMIT_LOWOPP;
-			pdata->sr_volt_data[1].sr_errminlimit =
+				pdata->sr_volt_data[1].sr_errminlimit =
+					OMAP3430_SR_ERRMINLIMIT_HIGHOPP;
+				pdata->sr_volt_data[2].sr_errminlimit =
+					OMAP3630_SR_ERRMINLIMIT_OPPTB;
+				pdata->sr_volt_data[3].sr_errminlimit =
+					OMAP3630_SR_ERRMINLIMIT_OPPTB;
+			} else {
+				pdata->sr_volt_data[0].sr_errminlimit =
+					OMAP3430_SR_ERRMINLIMIT_LOWOPP;
+				pdata->sr_volt_data[1].sr_errminlimit =
 					OMAP3430_SR_ERRMINLIMIT_LOWOPP;
-			pdata->sr_volt_data[2].sr_errminlimit =
+				pdata->sr_volt_data[2].sr_errminlimit =
 					OMAP3430_SR_ERRMINLIMIT_HIGHOPP;
-			pdata->sr_volt_data[3].sr_errminlimit =
+				pdata->sr_volt_data[3].sr_errminlimit =
 					OMAP3430_SR_ERRMINLIMIT_HIGHOPP;
-			pdata->sr_volt_data[4].sr_errminlimit =
+				pdata->sr_volt_data[4].sr_errminlimit =
 					OMAP3430_SR_ERRMINLIMIT_HIGHOPP;
+			}
 		} else {
 			sr->senn_avgweight = OMAP3430_SR2_SENNAVGWEIGHT;
 			sr->senp_avgweight = OMAP3430_SR2_SENPAVGWEIGHT;
-			pdata->sr_volt_data[0].sr_errminlimit =
+			if (cpu_is_omap3630()) {
+				pdata->sr_volt_data[0].sr_errminlimit =
+					OMAP3430_SR_ERRMINLIMIT_LOWOPP;
+				pdata->sr_volt_data[1].sr_errminlimit =
+					OMAP3430_SR_ERRMINLIMIT_HIGHOPP;
+			} else {
+				pdata->sr_volt_data[0].sr_errminlimit =
 					OMAP3430_SR_ERRMINLIMIT_LOWOPP;
-			pdata->sr_volt_data[1].sr_errminlimit =
+				pdata->sr_volt_data[1].sr_errminlimit =

arch/arm/mach-omap2/smartreflex.c static void sr_set_regfields(struct omap_sr *sr) · line 298

Quoted 10 lines
arch/arm/mach-omap2/smartreflex.c +3 -2
 					OMAP3430_SR_ERRMINLIMIT_LOWOPP;
-			pdata->sr_volt_data[2].sr_errminlimit =
+				pdata->sr_volt_data[2].sr_errminlimit =
 					OMAP3430_SR_ERRMINLIMIT_HIGHOPP;
+			}
 		}
 	}
-	/* TODO: 3630 and Omap4 specific bit field values */
+	/* TODO: Omap4 specific bit field values */
 

if there was an intent to use OMAP4 with similar code, I wonder if we should already add a if condition for that too

arch/arm/mach-omap2/smartreflex.c static void sr_set_regfields(struct omap_sr *sr) · line 300

Quoted 2 lines
arch/arm/mach-omap2/smartreflex.c +0 -0
 }
 

http://marc.info/?l=linux-omap&m=126937469121771&w=2
Again - NAK on hardcoded indexing :(

Quoted 52 lines

static void sr_configure(struct omap_sr *sr)

arch/arm/mach-omap2/smartreflex.h +4 -1
index 66c3770..a126362 100644
@@ -146,7 +146,10 @@ extern struct dentry *pm_dbg_main_dir;
 #define OMAP3430_SR_ERRMINLIMIT_HIGHOPP	0xF9
 #define OMAP3430_SR_ERRMINLIMIT_LOWOPP	0xF4
 
-/* TODO:3630/OMAP4 values if it has to come from this file */
+/* OMAP3630 specific values */
+#define OMAP3630_SR_ERRMINLIMIT_OPPTB   0xFA
+
+/* TODO:OMAP4 specific values */
 
 /* Info for enabling SR in T2/gaia. ToDo: Move it to twl4030_power.c */
 #define PHY_TO_OFF_PM_RECIEVER(p)	(p - 0x5b)
arch/arm/mach-omap2/sr_device.c +26 -0
index 209909c..2dcd1ba 100644
@@ -107,16 +107,82 @@ static void __init omap34xx_sr_set_testing_nvalues(
 	}
 }
 
+static void __init omap3630_sr_read_efuse(
+			struct omap_smartreflex_data *sr_data, int sr_id)
+{
+	if (WARN_ON(!sr_data->sr_volt_data))
+		return;
+
+	if (sr_id == SR1) {
+		sr_data->senn_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
+					OMAP343X_SR1_SENNENABLE_MASK) >>
+					OMAP343X_SR1_SENNENABLE_SHIFT;
+		sr_data->senp_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
+					OMAP343X_SR1_SENPENABLE_MASK) >>
+					OMAP343X_SR1_SENPENABLE_SHIFT;
+		sr_data->sr_volt_data[3].sr_nvalue = omap_ctrl_readl(
+					OMAP3630_CONTROL_FUSE_OPPTM_VDD1);
+		sr_data->sr_volt_data[2].sr_nvalue = omap_ctrl_readl(
+					OMAP3630_CONTROL_FUSE_OPP120_VDD1);
+		sr_data->sr_volt_data[1].sr_nvalue = omap_ctrl_readl(
+					OMAP3630_CONTROL_FUSE_OPP100_VDD1);
+		sr_data->sr_volt_data[0].sr_nvalue = omap_ctrl_readl(
+					OMAP3630_CONTROL_FUSE_OPP50_VDD1);
+	} else if (sr_id == SR2) {
+
+		sr_data->senn_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
+					OMAP343X_SR2_SENNENABLE_MASK) >>
+					OMAP343X_SR2_SENNENABLE_SHIFT;

arch/arm/mach-omap2/sr_device.c static void __init omap34xx_sr_set_testing_nvalues( · line 145

Quoted 10 lines
arch/arm/mach-omap2/sr_device.c +9 -0
+		sr_data->senp_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
+					OMAP343X_SR2_SENPENABLE_MASK) >>
+					OMAP343X_SR2_SENPENABLE_SHIFT;
+		sr_data->sr_volt_data[1].sr_nvalue = omap_ctrl_readl(
+					OMAP3630_CONTROL_FUSE_OPP100_VDD2);
+		sr_data->sr_volt_data[0].sr_nvalue = omap_ctrl_readl(
+					OMAP3630_CONTROL_FUSE_OPP50_VDD2);
+	}
+}
 

sorry NAK again. we seem to replicate the logic in the same style of old code - if register offsets changed, keep them as variables in some struct initialized and please dont duplicate code all over again - it helps the code to be modular and be IP specific instead of silicon specific - helps portability etc. NAK.

Quoted 15 lines
arch/arm/mach-omap2/sr_device.c +15 -0
+
+/* OMAP3630 Hard coded nvalues for testing purposes.*/
+static void __init omap3630_sr_set_testing_nvalues(
+			struct omap_smartreflex_data *sr_data, int srid)
+{
+	if (WARN_ON(!sr_data->sr_volt_data))
+		return;
+
+	if (srid == SR1) {
+		sr_data->senp_mod = 0x1;
+		sr_data->senn_mod = 0x1;
+		/* OMAP3630 nvalues for each VDD1 opp */
+		sr_data->sr_volt_data[3].sr_nvalue = 0xaab197;
+		sr_data->sr_volt_data[2].sr_nvalue = 0xaac5a8;
+		sr_data->sr_volt_data[1].sr_nvalue = 0x999b83;

arch/arm/mach-omap2/sr_device.c static void __init omap34xx_sr_set_testing_nvalues(

Quoted 10 lines
arch/arm/mach-omap2/sr_device.c +9 -0
+		sr_data->sr_volt_data[0].sr_nvalue = 0x898beb;
+	} else if (srid == SR2) {
+		sr_data->senp_mod = 0x1;
+		sr_data->senn_mod = 0x1;
+		/* OMAP3630 nvalues for each VDD2 opp */
+		sr_data->sr_volt_data[1].sr_nvalue = 0x9a8cee;
+		sr_data->sr_volt_data[0].sr_nvalue = 0x898beb;
+	}
+}
 

NAK - I have seen value if the nvalues are programmed from userspace - debugfs- esp given that these recommendations vary per silicon (in this case it is being hardcoded) and no means to check/dump on a board reported to be faulty.

Quoted 7 lines
arch/arm/mach-omap2/sr_device.c +3 -1
+
 static void __init sr_set_nvalues(struct omap_smartreflex_data *sr_data,
 						int srid)
 {
-	if (cpu_is_omap34xx()) {
+	if (cpu_is_omap3630()) {
+		if (SR_TESTING_NVALUES)

arch/arm/mach-omap2/sr_device.c static void __init omap34xx_sr_set_testing_nvalues(

Quoted 10 lines
arch/arm/mach-omap2/sr_device.c +4 -0
+			omap3630_sr_set_testing_nvalues(sr_data, srid);
+		else
+			omap3630_sr_read_efuse(sr_data, srid);
+	} else if (cpu_is_omap34xx()) {
 		if (SR_TESTING_NVALUES)
 			omap34xx_sr_set_testing_nvalues(sr_data, srid);
 		else
 			omap34xx_sr_read_efuse(sr_data, srid);
 	}
 

aah - this highlights my crib about this codebase and it's tendency to ctrl+c, ctrl+v when things could be done much cleaner! NAK.

Quoted 13 lines
arch/arm/mach-omap2/sr_device.c +1 -0
 }
+

static void __init omap34xx_sr_volt_details(struct omap_smartreflex_data

arch/arm/mach-omap2/sr_device.c +3 -0
 						*sr_data, int srid)
 {
@@ -141,6 +207,28 @@ static void __init omap34xx_sr_volt_details(struct omap_smartreflex_data
 	}
 }
 
+static void __init omap3630_sr_volt_details(struct omap_smartreflex_data
+						*sr_data, int srid)
+{

arch/arm/mach-omap2/sr_device.c static void __init omap34xx_sr_volt_details(struct omap_smartreflex_data · line 222

Quoted 10 lines
arch/arm/mach-omap2/sr_device.c +9 -0
+	if (srid == SR1) {
+		sr_data->no_opp = 4;
+		sr_data->sr_volt_data = kzalloc(sizeof(sr_data->sr_volt_data) *
+				sr_data->no_opp , GFP_KERNEL);
+		WARN_ON(!sr_data->sr_volt_data);
+		sr_data->sr_volt_data[0].voltage = 930000;
+		sr_data->sr_volt_data[1].voltage = 1100000;
+		sr_data->sr_volt_data[2].voltage = 1260000;
+		sr_data->sr_volt_data[3].voltage = 1310000;
 

this voltage is wrong.. :(

arch/arm/mach-omap2/sr_device.c static void __init omap34xx_sr_volt_details(struct omap_smartreflex_data

Quoted 10 lines
arch/arm/mach-omap2/sr_device.c +9 -0
+	} else if (srid == SR2) {
+		sr_data->no_opp = 2;
+		sr_data->sr_volt_data = kzalloc(sizeof(sr_data->sr_volt_data) *
+				sr_data->no_opp , GFP_KERNEL);
+		WARN_ON(!sr_data->sr_volt_data);
+		sr_data->sr_volt_data[0].voltage = 930000;
+		sr_data->sr_volt_data[1].voltage = 1137500;
+	}
+}
 

NAK NAK - please do not duplicate cpufreq_34xx.c - always have one place where this information is stored.

Quoted 5 lines
arch/arm/mach-omap2/sr_device.c +1 -0
+
 static int __init omap_devinit_smartreflex(void)

{

arch/arm/mach-omap2/sr_device.c +0 -0
 	int i = 0;

arch/arm/mach-omap2/sr_device.c static int __init omap_devinit_smartreflex(void) · line 275

Quoted 9 lines
arch/arm/mach-omap2/sr_device.c +3 -1
@@ -180,7 +268,9 @@ static int __init omap_devinit_smartreflex(void)
 		sr_data->device_enable = omap_device_enable;
 		sr_data->device_shutdown = omap_device_shutdown;
 		sr_data->device_idle = omap_device_idle;
-		if (cpu_is_omap34xx())
+		if (cpu_is_omap3630())
+			omap3630_sr_volt_details(sr_data, i + 1);
+		else if (cpu_is_omap34xx())
 			omap34xx_sr_volt_details(sr_data, i + 1);
 

NAK on code duplication again.

Quoted 11 lines
arch/arm/mach-omap2/sr_device.c +0 -0
 		sr_set_nvalues(sr_data, i + 1);
arch/arm/mach-omap2/sr_device.c +0 -0
 		od = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data),
arch/arm/mach-omap2/voltage.c +1 -0
index 8fd1949..9690b8d 100644
@@ -224,6 +224,23 @@ static u8 omap3_get_vp_errorgain(int vp_id, unsigned long volt)
 {
 	unsigned long lowopp_volt;
 
+	if (cpu_is_omap3630()) {

arch/arm/mach-omap2/voltage.c static u8 omap3_get_vp_errorgain(int vp_id, unsigned long volt) · line 237

Quoted 10 lines
arch/arm/mach-omap2/voltage.c +9 -0
+		switch (volt) {
+		case 930000:
+			return OMAP3630_VP_CONFIG_ERRORGAIN_OPP50;
+		case 1100000:
+		case 1137500:
+			return OMAP3630_VP_CONFIG_ERRORGAIN_OPP100;
+		case 1260000:
+			return OMAP3630_VP_CONFIG_ERRORGAIN_OPPTB;
+		case 1310000:
 

this voltage is wrong :(

arch/arm/mach-omap2/voltage.c static u8 omap3_get_vp_errorgain(int vp_id, unsigned long volt) · line 239

Quoted 2 lines
arch/arm/mach-omap2/voltage.c +1 -0
+			return OMAP3630_VP_CONFIG_ERRORGAIN_OPP1G;
 

a) why not part of volt_data? if this is a variant, for 3430, we could have it constant value in the struct.
b) hardcoded indexed off voltage? i am already having maintenance nightmare if i had to change OPP voltage somwhere..

Quoted 10 lines
arch/arm/mach-omap2/voltage.c +6 -0
+		default:
+			pr_warning("Wrong voltage. Unable to retrieve \
+				error gain for VP %d", vp_id + 1);
+			return 0;
+		}
+	}
 	if (vp_id == VP1)
arch/arm/mach-omap2/voltage.c +0 -0
 		lowopp_volt = VDD1_LOWOPP_VOLT;
 	else if (vp_id == VP2)

arch/arm/mach-omap2/voltage.c static u8 omap3_get_vp_errorgain(int vp_id, unsigned long volt) · line 254

Quoted 8 lines
arch/arm/mach-omap2/voltage.c +2 -2
@@ -232,8 +249,8 @@ static u8 omap3_get_vp_errorgain(int vp_id, unsigned long volt)
 		pr_warning("Voltage processor%d does not exisit", vp_id);
 		return 0;
 	}
-	return ((volt > lowopp_volt) ? (OMAP3_VP_CONFIG_ERRORGAIN_HIGHOPP) :
-		(OMAP3_VP_CONFIG_ERRORGAIN_LOWOPP));
+	return ((volt > lowopp_volt) ? (OMAP3430_VP_CONFIG_ERRORGAIN_HIGHOPP) :
+		(OMAP3430_VP_CONFIG_ERRORGAIN_LOWOPP));
 

why am i applying 3430 error gain for 3630?

Quoted 9 lines
arch/arm/mach-omap2/voltage.c +0 -0
 }
 static void vp_latch_vsel(int vp_id)

{

arch/arm/mach-omap2/voltage.c +2 -0
@@ -311,18 +328,36 @@ static void __init vp_reg_configure(int vp_id)
 
 		vp_reg[vp_id].vp_offs = omap3_vp_offs[vp_id];
 		if (vp_id == VP1) {
+			u8 vlimitto_vddmin, vlimitto_vddmax;
+

arch/arm/mach-omap2/voltage.c static void __init vp_reg_configure(int vp_id) · line 341

Quoted 10 lines
arch/arm/mach-omap2/voltage.c +7 -1
 			curr_volt = get_curr_vdd1_voltage();
-			vp_reg[vp_id].vp_vddmin = (OMAP3_VP1_VLIMITTO_VDDMIN <<
+			if (cpu_is_omap3630()) {
+				vlimitto_vddmin = OMAP3630_VP1_VLIMITTO_VDDMIN;
+				vlimitto_vddmax = OMAP3630_VP1_VLIMITTO_VDDMAX;
+			} else {
+				vlimitto_vddmin = OMAP3430_VP1_VLIMITTO_VDDMIN;
+				vlimitto_vddmax = OMAP3430_VP1_VLIMITTO_VDDMAX;
+			}
 

NAK for reasons of code duplication.

Quoted 97 lines
arch/arm/mach-omap2/voltage.c +13 -3
+			vp_reg[vp_id].vp_vddmin = (vlimitto_vddmin <<
 					OMAP3430_VDDMIN_SHIFT);
-			vp_reg[vp_id].vp_vddmax = (OMAP3_VP1_VLIMITTO_VDDMAX <<
+			vp_reg[vp_id].vp_vddmax = (vlimitto_vddmax <<
 					OMAP3430_VDDMAX_SHIFT);
 			vp_reg[vp_id].vp_tranxdone_status =
 					OMAP3430_VP1_TRANXDONE_ST;
 		} else if (vp_id == VP2) {
+			u8 vlimitto_vddmin, vlimitto_vddmax;
+
 			curr_volt = get_curr_vdd2_voltage();
-			vp_reg[vp_id].vp_vddmin = (OMAP3_VP2_VLIMITTO_VDDMIN <<
+			if (cpu_is_omap3630()) {
+				vlimitto_vddmin = OMAP3630_VP2_VLIMITTO_VDDMIN;
+				vlimitto_vddmax = OMAP3630_VP2_VLIMITTO_VDDMAX;
+			} else {
+				vlimitto_vddmin = OMAP3430_VP2_VLIMITTO_VDDMIN;
+				vlimitto_vddmax = OMAP3430_VP2_VLIMITTO_VDDMAX;
+			}
 
+			vp_reg[vp_id].vp_vddmin = (vlimitto_vddmin <<
 					OMAP3430_VDDMIN_SHIFT);
-			vp_reg[vp_id].vp_vddmax = (OMAP3_VP2_VLIMITTO_VDDMAX <<
+			vp_reg[vp_id].vp_vddmax = (vlimitto_vddmax <<
 					OMAP3430_VDDMAX_SHIFT);
arch/arm/mach-omap2/voltage.c +0 -0
 			vp_reg[vp_id].vp_tranxdone_status =
 					OMAP3430_VP2_TRANXDONE_ST;
arch/arm/mach-omap2/voltage.h +26 -6
index a350444..61b3220 100644
@@ -54,19 +54,39 @@
  * board file or PMIC data structure
  */
 #define OMAP3_VP_CONFIG_ERROROFFSET		0x00
-#define OMAP3_VP_CONFIG_ERRORGAIN_LOWOPP	0x0C
-#define OMAP3_VP_CONFIG_ERRORGAIN_HIGHOPP	0x18
 #define OMAP3_VP_VSTEPMIN_SMPSWAITTIMEMIN	0x3C
 #define OMAP3_VP_VSTEPMIN_VSTEPMIN		0x1
 #define OMAP3_VP_VSTEPMAX_SMPSWAITTIMEMAX	0x3C
 #define OMAP3_VP_VSTEPMAX_VSTEPMAX		0x04
-#define OMAP3_VP1_VLIMITTO_VDDMIN		0x14
-#define OMAP3_VP1_VLIMITTO_VDDMAX		0x42
-#define OMAP3_VP2_VLIMITTO_VDDMAX		0x2C
-#define OMAP3_VP2_VLIMITTO_VDDMIN		0x18
 #define OMAP3_VP_VLIMITTO_TIMEOUT_US		0x200
 
 #define VOLTAGE_MOD	OMAP3430_GR_MOD
+
+/*
+ * Omap3430 specific VP register values. Maybe these need to come from
+ * board file or PMIC data structure
+ */
+#define OMAP3430_VP_CONFIG_ERRORGAIN_LOWOPP	0x0C
+#define OMAP3430_VP_CONFIG_ERRORGAIN_HIGHOPP	0x18
+#define OMAP3430_VP1_VLIMITTO_VDDMIN		0x14
+#define OMAP3430_VP1_VLIMITTO_VDDMAX		0x42
+#define OMAP3430_VP2_VLIMITTO_VDDMAX		0x2C
+#define OMAP3430_VP2_VLIMITTO_VDDMIN		0x18
+
+/*
+ * Omap3630 specific VP register values. Maybe these need to come from
+ * board file or PMIC data structure
+ */
+#define OMAP3630_VP_CONFIG_ERRORGAIN_OPP50	0x0C
+#define OMAP3630_VP_CONFIG_ERRORGAIN_OPP100	0x16
+#define OMAP3630_VP_CONFIG_ERRORGAIN_OPPTB	0x23
+#define OMAP3630_VP_CONFIG_ERRORGAIN_OPP1G	0x27
+#define OMAP3630_VP1_VLIMITTO_VDDMIN		0x18
+#define OMAP3630_VP1_VLIMITTO_VDDMAX		0x3C
+#define OMAP3630_VP2_VLIMITTO_VDDMIN		0x18
+#define OMAP3630_VP2_VLIMITTO_VDDMAX		0x30
+
+
 /* TODO OMAP4 VP register values if the same file is used for OMAP4*/
 
 void omap_voltageprocessor_enable(int vp_id);
arch/arm/plat-omap/include/plat/control.h +8 -0
index d540ae8..7a94feb 100644
@@ -169,6 +169,14 @@
 #define OMAP343X_CONTROL_SRAMLDO5	(OMAP2_CONTROL_GENERAL + 0x02C0)
 #define OMAP343X_CONTROL_CSI		(OMAP2_CONTROL_GENERAL + 0x02C4)
 
+/* OMAP3630 only CONTROL_GENERAL register offsets */
+#define OMAP3630_CONTROL_FUSE_OPP50_VDD1	(OMAP2_CONTROL_GENERAL + 0x0114)
+#define OMAP3630_CONTROL_FUSE_OPP100_VDD1	(OMAP2_CONTROL_GENERAL + 0x0118)
+#define OMAP3630_CONTROL_FUSE_OPP120_VDD1	(OMAP2_CONTROL_GENERAL + 0x011C)
+#define OMAP3630_CONTROL_FUSE_OPPTM_VDD1	(OMAP2_CONTROL_GENERAL + 0x0120)
+#define OMAP3630_CONTROL_FUSE_OPP50_VDD2	(OMAP2_CONTROL_GENERAL + 0x0128)
+#define OMAP3630_CONTROL_FUSE_OPP100_VDD2	(OMAP2_CONTROL_GENERAL + 0x012C)
+
 /* AM35XX only CONTROL_GENERAL register offsets */
 #define AM35XX_CONTROL_MSUSPENDMUX_6    (OMAP2_CONTROL_GENERAL + 0x0038)
 #define AM35XX_CONTROL_DEVCONF2         (OMAP2_CONTROL_GENERAL + 0x0310)
Signature · 1 line
Regards, Nishanth Menon
#5 lore raw

Re: [PATCHv2 1/3] OMAP3: PM: Fix crash when enabling SmartReflex on non-supported OMAPs.

In reply to Thara Gopinath

Thara Gopinath said the following on 03/31/2010 01:30 AM:

Quoted 10 lines

This patch sets and unsets is_sr_reset is appropriate places so that trying to enable smart reflex in a non-supported OMAP chip does not lead to unnecessary crash. Basically today if sr_enable fails, sr_disable will crash due to accessing sr registers when sr clocks are not turned on. By checking on is_sr_reset flag and setting and unsetting this flag appropriately this crash is fixed in this patch.

I think this may belong in your first series - 34xx patchset as this does not have much to do with 3630..

Signature · 2 lines
Regards,
Nishanth Menon