static void __init omap_2430sdp_init_irq(void)
 {
-       omap2_init_common_hw();
+       omap2_init_common_hw(NULL);
        omap_init_irq();
        omap_gpio_init();
        sdp2430_init_smc91x();
 
 
 static void __init omap_3430sdp_init_irq(void)
 {
-       omap2_init_common_hw();
+       omap2_init_common_hw(NULL);
        omap_init_irq();
        omap_gpio_init();
        sdp3430_init_smc91x();
 
 
 static void __init omap_apollon_init_irq(void)
 {
-       omap2_init_common_hw();
+       omap2_init_common_hw(NULL);
        omap_init_irq();
        omap_gpio_init();
        apollon_init_smc91x();
 
 
 static void __init omap_generic_init_irq(void)
 {
-       omap2_init_common_hw();
+       omap2_init_common_hw(NULL);
        omap_init_irq();
 }
 
 
 
 static void __init omap_h4_init_irq(void)
 {
-       omap2_init_common_hw();
+       omap2_init_common_hw(NULL);
        omap_init_irq();
        omap_gpio_init();
        h4_init_flash();
 
 
 static void __init omap_ldp_init_irq(void)
 {
-       omap2_init_common_hw();
+       omap2_init_common_hw(NULL);
        omap_init_irq();
        omap_gpio_init();
 }
 
 
 void __init nokia_n800_init_irq(void)
 {
-       omap2_init_common_hw();
+       omap2_init_common_hw(NULL);
        omap_init_irq();
        omap_gpio_init();
 
 
 
 static void __init omap2_evm_init_irq(void)
 {
-       omap2_init_common_hw();
+       omap2_init_common_hw(NULL);
        omap_init_irq();
        omap_gpio_init();
        omap2evm_init_smc911x();
 
 
 static void __init omap3_beagle_init_irq(void)
 {
-       omap2_init_common_hw();
+       omap2_init_common_hw(NULL);
        omap_init_irq();
        omap_gpio_init();
 }
 
 
 static void __init omap3_evm_init_irq(void)
 {
-       omap2_init_common_hw();
+       omap2_init_common_hw(NULL);
        omap_init_irq();
        omap_gpio_init();
        omap3evm_init_smc911x();
 
        omapfb_reserve_sdram();
 }
 
-void __init omap2_init_common_hw(void)
+void __init omap2_init_common_hw(struct omap_sdrc_params *sp)
 {
        omap2_mux_init();
        pwrdm_init(powerdomains_omap);
        clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps);
        omap2_clk_init();
-       omap2_sdrc_init();
+       omap2_sdrc_init(sp);
        gpmc_init();
 }
 
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#undef DEBUG
 
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <asm/arch/sdrc.h>
 #include "sdrc.h"
 
+static struct omap_sdrc_params *sdrc_init_params;
+
 void __iomem *omap2_sdrc_base;
 void __iomem *omap2_sms_base;
 
+
+/**
+ * omap2_sdrc_get_params - return SDRC register values for a given clock rate
+ * @r: SDRC clock rate (in Hz)
+ *
+ * Return pre-calculated values for the SDRC_ACTIM_CTRLA,
+ * SDRC_ACTIM_CTRLB, SDRC_RFR_CTRL, and SDRC_MR registers, for a given
+ * SDRC clock rate 'r'.  These parameters control various timing
+ * delays in the SDRAM controller that are expressed in terms of the
+ * number of SDRC clock cycles to wait; hence the clock rate
+ * dependency. Note that sdrc_init_params must be sorted rate
+ * descending.  Also assumes that both chip-selects use the same
+ * timing parameters.  Returns a struct omap_sdrc_params * upon
+ * success, or NULL upon failure.
+ */
+struct omap_sdrc_params *omap2_sdrc_get_params(unsigned long r)
+{
+       struct omap_sdrc_params *sp;
+
+       sp = sdrc_init_params;
+
+       while (sp->rate != r)
+               sp++;
+
+       if (!sp->rate)
+               return NULL;
+
+       return sp;
+}
+
+
 void __init omap2_set_globals_sdrc(struct omap_globals *omap2_globals)
 {
        omap2_sdrc_base = omap2_globals->sdrc;
 }
 
 /* turn on smart idle modes for SDRAM scheduler and controller */
-void __init omap2_sdrc_init(void)
+void __init omap2_sdrc_init(struct omap_sdrc_params *sp)
 {
        u32 l;
 
        l &= ~(0x3 << 3);
        l |= (0x2 << 3);
        sdrc_write_reg(l, SDRC_SYSCONFIG);
+
+       sdrc_init_params = sp;
 }
 
 #define omap_writew(v,a)       (*(volatile unsigned short *)IO_ADDRESS(a) = (v))
 #define omap_writel(v,a)       (*(volatile unsigned int   *)IO_ADDRESS(a) = (v))
 
+struct omap_sdrc_params;
+
 extern void omap1_map_common_io(void);
 extern void omap1_init_common_hw(void);
 
 extern void omap2_map_common_io(void);
-extern void omap2_init_common_hw(void);
+extern void omap2_init_common_hw(struct omap_sdrc_params *sp);
 
 #endif
 
 
 
 #ifndef __ASSEMBLER__
 
+/**
+ * struct omap_sdrc_params - SDRC parameters for a given SDRC clock rate
+ * @rate: SDRC clock rate (in Hz)
+ * @actim_ctrla: Value to program to SDRC_ACTIM_CTRLA for this rate
+ * @actim_ctrlb: Value to program to SDRC_ACTIM_CTRLB for this rate
+ * @rfr_ctrl: Value to program to SDRC_RFR_CTRL for this rate
+ * @mr: Value to program to SDRC_MR for this rate
+ *
+ * This structure holds a pre-computed set of register values for the
+ * SDRC for a given SDRC clock rate and SDRAM chip.  These are
+ * intended to be pre-computed and specified in an array in the board-*.c
+ * files.  The structure is keyed off the 'rate' field.
+ */
+struct omap_sdrc_params {
+       unsigned long rate;
+       u32 actim_ctrla;
+       u32 actim_ctrlb;
+       u32 rfr_ctrl;
+       u32 mr;
+};
+
 void __init omap2_sdrc_init(void);
+struct omap_sdrc_params *omap2_sdrc_get_params(unsigned long r);
 
 #ifdef CONFIG_ARCH_OMAP2