Merge "platform: msm8994: Add support for Dynamic smem"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index dd8b1ba..24025a3 100755
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -630,7 +630,7 @@
 int check_aboot_addr_range_overlap(uint32_t start, uint32_t size)
 {
 	/* Check for boundary conditions. */
-	if ((start + size) < start)
+	if ((UINT_MAX - start) < size)
 		return -1;
 
 	/* Check for memory overlap. */
diff --git a/platform/ferrum/acpuclock.c b/platform/ferrum/acpuclock.c
new file mode 100644
index 0000000..334a1f3
--- /dev/null
+++ b/platform/ferrum/acpuclock.c
@@ -0,0 +1,93 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <err.h>
+#include <assert.h>
+#include <debug.h>
+#include <reg.h>
+#include <platform/timer.h>
+#include <platform/iomap.h>
+#include <mmc.h>
+#include <clock.h>
+#include <platform/clock.h>
+#include <blsp_qup.h>
+
+void hsusb_clock_init(void)
+{
+
+}
+
+void clock_init_mmc(uint32_t interface)
+{
+
+}
+
+/* Configure MMC clock */
+void clock_config_mmc(uint32_t interface, uint32_t freq)
+{
+
+}
+
+/* Configure UART clock based on the UART block id*/
+void clock_config_uart_dm(uint8_t id)
+{
+
+}
+
+/* Function to asynchronously reset CE.
+ * Function assumes that all the CE clocks are off.
+ */
+static void ce_async_reset(uint8_t instance)
+{
+
+}
+
+void clock_ce_enable(uint8_t instance)
+{
+
+}
+
+void clock_ce_disable(uint8_t instance)
+{
+
+}
+
+void clock_config_ce(uint8_t instance)
+{
+	/* Need to enable the clock before disabling since the clk_disable()
+	 * has a check to default to nop when the clk_enable() is not called
+	 * on that particular clock.
+	 */
+	clock_ce_enable(instance);
+
+	clock_ce_disable(instance);
+
+	ce_async_reset(instance);
+
+	clock_ce_enable(instance);
+}
diff --git a/platform/ferrum/ferrum-clock.c b/platform/ferrum/ferrum-clock.c
new file mode 100644
index 0000000..7ae8a5f
--- /dev/null
+++ b/platform/ferrum/ferrum-clock.c
@@ -0,0 +1,543 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <reg.h>
+#include <err.h>
+#include <clock.h>
+#include <clock_pll.h>
+#include <clock_lib2.h>
+#include <platform/clock.h>
+#include <platform/iomap.h>
+
+
+/* Mux source select values */
+#define cxo_source_val    0
+#define gpll0_source_val  1
+#define cxo_mm_source_val 0
+#define gpll0_mm_source_val 1
+struct clk_freq_tbl rcg_dummy_freq = F_END;
+
+
+/* Clock Operations */
+static struct clk_ops clk_ops_branch =
+{
+	.enable     = clock_lib2_branch_clk_enable,
+	.disable    = clock_lib2_branch_clk_disable,
+	.set_rate   = clock_lib2_branch_set_rate,
+};
+
+static struct clk_ops clk_ops_rcg_mnd =
+{
+	.enable     = clock_lib2_rcg_enable,
+	.set_rate   = clock_lib2_rcg_set_rate,
+};
+
+static struct clk_ops clk_ops_rcg =
+{
+	.enable     = clock_lib2_rcg_enable,
+	.set_rate   = clock_lib2_rcg_set_rate,
+};
+
+static struct clk_ops clk_ops_cxo =
+{
+	.enable     = cxo_clk_enable,
+	.disable    = cxo_clk_disable,
+};
+
+static struct clk_ops clk_ops_pll_vote =
+{
+	.enable     = pll_vote_clk_enable,
+	.disable    = pll_vote_clk_disable,
+	.auto_off   = pll_vote_clk_disable,
+	.is_enabled = pll_vote_clk_is_enabled,
+};
+
+static struct clk_ops clk_ops_vote =
+{
+	.enable     = clock_lib2_vote_clk_enable,
+	.disable    = clock_lib2_vote_clk_disable,
+};
+
+/* Clock Sources */
+static struct fixed_clk cxo_clk_src =
+{
+	.c = {
+		.rate     = 19200000,
+		.dbg_name = "cxo_clk_src",
+		.ops      = &clk_ops_cxo,
+	},
+};
+
+static struct pll_vote_clk gpll0_clk_src =
+{
+	.en_reg       = (void *) APCS_GPLL_ENA_VOTE,
+	.en_mask      = BIT(0),
+	.status_reg   = (void *) GPLL0_STATUS,
+	.status_mask  = BIT(17),
+	.parent       = &cxo_clk_src.c,
+
+	.c = {
+		.rate     = 800000000,
+		.dbg_name = "gpll0_clk_src",
+		.ops      = &clk_ops_pll_vote,
+	},
+};
+
+/* SDCC Clocks */
+static struct clk_freq_tbl ftbl_gcc_sdcc1_2_apps_clk[] =
+{
+	F(   144000,    cxo,  16,   3,  25),
+	F(   400000,    cxo,  12,   1,   4),
+	F( 20000000,  gpll0,  10,   1,   4),
+	F( 25000000,  gpll0,  16,   1,   2),
+	F( 50000000,  gpll0,  16,   0,   0),
+	F(100000000,  gpll0,   8,   0,   0),
+	F(177770000,  gpll0, 4.5,   0,   0),
+	F(200000000,  gpll0,   4,   0,   0),
+	F_END
+};
+
+static struct rcg_clk sdcc1_apps_clk_src =
+{
+	.cmd_reg      = (uint32_t *) SDCC1_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) SDCC1_CFG_RCGR,
+	.m_reg        = (uint32_t *) SDCC1_M,
+	.n_reg        = (uint32_t *) SDCC1_N,
+	.d_reg        = (uint32_t *) SDCC1_D,
+
+	.set_rate     = clock_lib2_rcg_set_rate_mnd,
+	.freq_tbl     = ftbl_gcc_sdcc1_2_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "sdc1_clk",
+		.ops      = &clk_ops_rcg_mnd,
+	},
+};
+
+/* BLSP1_QUP2 Clocks */
+static struct clk_freq_tbl ftbl_gcc_blsp1_qup2_i2c_apps_clk_src[] =
+{
+	F(      96000,    cxo,  10,   1,  2),
+	F(    4800000,    cxo,   4,   0,  0),
+	F(    9600000,    cxo,   2,   0,  0),
+	F(   16000000,  gpll0,  10,   1,  5),
+	F(   19200000,  gpll0,   1,   0,  0),
+	F(   25000000,  gpll0,  16,   1,  2),
+	F(   50000000,  gpll0,  16,   0,  0),
+	F_END
+};
+
+static struct branch_clk gcc_sdcc1_apps_clk =
+{
+	.cbcr_reg     = (uint32_t *) SDCC1_APPS_CBCR,
+	.parent       = &sdcc1_apps_clk_src.c,
+
+	.c = {
+		.dbg_name = "gcc_sdcc1_apps_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+static struct branch_clk gcc_sdcc1_ahb_clk =
+{
+	.cbcr_reg     = (uint32_t *) SDCC1_AHB_CBCR,
+	.has_sibling  = 1,
+
+	.c = {
+		.dbg_name = "gcc_sdcc1_ahb_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+static struct rcg_clk sdcc2_apps_clk_src =
+{
+	.cmd_reg      = (uint32_t *) SDCC2_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) SDCC2_CFG_RCGR,
+	.m_reg        = (uint32_t *) SDCC2_M,
+	.n_reg        = (uint32_t *) SDCC2_N,
+	.d_reg        = (uint32_t *) SDCC2_D,
+
+	.set_rate     = clock_lib2_rcg_set_rate_mnd,
+	.freq_tbl     = ftbl_gcc_sdcc1_2_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "sdc2_clk",
+		.ops      = &clk_ops_rcg_mnd,
+	},
+};
+
+static struct branch_clk gcc_sdcc2_apps_clk =
+{
+	.cbcr_reg     = (uint32_t *) SDCC2_APPS_CBCR,
+	.parent       = &sdcc2_apps_clk_src.c,
+
+	.c = {
+		.dbg_name = "gcc_sdcc2_apps_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+static struct branch_clk gcc_sdcc2_ahb_clk =
+{
+	.cbcr_reg     = (uint32_t *) SDCC2_AHB_CBCR,
+	.has_sibling  = 1,
+
+	.c = {
+		.dbg_name = "gcc_sdcc2_ahb_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+/* UART Clocks */
+static struct clk_freq_tbl ftbl_gcc_blsp1_2_uart1_6_apps_clk[] =
+{
+	F( 3686400,  gpll0,    1,  72,  15625),
+	F( 7372800,  gpll0,    1, 144,  15625),
+	F(14745600,  gpll0,    1, 288,  15625),
+	F(16000000,  gpll0,   10,   1,      5),
+	F(19200000,    cxo,    1,   0,      0),
+	F(24000000,  gpll0,    1,   3,    100),
+	F(25000000,  gpll0,   16,   1,      2),
+	F(32000000,  gpll0,    1,   1,     25),
+	F(40000000,  gpll0,    1,   1,     20),
+	F(46400000,  gpll0,    1,  29,    500),
+	F(48000000,  gpll0,    1,   3,     50),
+	F(51200000,  gpll0,    1,   8,    125),
+	F(56000000,  gpll0,    1,   7,    100),
+	F(58982400,  gpll0,    1,1152,  15625),
+	F(60000000,  gpll0,    1,   3,     40),
+	F_END
+};
+
+static struct rcg_clk blsp1_uart2_apps_clk_src =
+{
+	.cmd_reg      = (uint32_t *) BLSP1_UART2_APPS_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) BLSP1_UART2_APPS_CFG_RCGR,
+	.m_reg        = (uint32_t *) BLSP1_UART2_APPS_M,
+	.n_reg        = (uint32_t *) BLSP1_UART2_APPS_N,
+	.d_reg        = (uint32_t *) BLSP1_UART2_APPS_D,
+
+	.set_rate     = clock_lib2_rcg_set_rate_mnd,
+	.freq_tbl     = ftbl_gcc_blsp1_2_uart1_6_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "blsp1_uart2_apps_clk",
+		.ops      = &clk_ops_rcg_mnd,
+	},
+};
+
+static struct branch_clk gcc_blsp1_uart2_apps_clk =
+{
+	.cbcr_reg     = (uint32_t *) BLSP1_UART2_APPS_CBCR,
+	.parent       = &blsp1_uart2_apps_clk_src.c,
+
+	.c = {
+		.dbg_name = "gcc_blsp1_uart2_apps_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+static struct vote_clk gcc_blsp1_ahb_clk = {
+	.cbcr_reg     = (uint32_t *) BLSP1_AHB_CBCR,
+	.vote_reg     = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask      = BIT(10),
+
+	.c = {
+		.dbg_name = "gcc_blsp1_ahb_clk",
+		.ops      = &clk_ops_vote,
+	},
+};
+
+/* USB Clocks */
+static struct clk_freq_tbl ftbl_gcc_usb_hs_system_clk[] =
+{
+	F(80000000,  gpll0,   10,   0,   0),
+	F_END
+};
+
+static struct rcg_clk usb_hs_system_clk_src =
+{
+	.cmd_reg      = (uint32_t *) USB_HS_SYSTEM_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) USB_HS_SYSTEM_CFG_RCGR,
+
+	.set_rate     = clock_lib2_rcg_set_rate_hid,
+	.freq_tbl     = ftbl_gcc_usb_hs_system_clk,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "usb_hs_system_clk",
+		.ops      = &clk_ops_rcg,
+	},
+};
+
+static struct branch_clk gcc_usb_hs_system_clk =
+{
+	.cbcr_reg     = (uint32_t *) USB_HS_SYSTEM_CBCR,
+	.parent       = &usb_hs_system_clk_src.c,
+
+	.c = {
+		.dbg_name = "gcc_usb_hs_system_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+static struct branch_clk gcc_usb_hs_ahb_clk =
+{
+	.cbcr_reg     = (uint32_t *) USB_HS_AHB_CBCR,
+	.has_sibling  = 1,
+
+	.c = {
+		.dbg_name = "gcc_usb_hs_ahb_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+/* Display clocks */
+static struct clk_freq_tbl ftbl_mdss_esc0_1_clk[] = {
+	F_MM(19200000,    cxo,   1,   0,   0),
+	F_END
+};
+
+static struct clk_freq_tbl ftbl_mdp_clk[] = {
+	F_MM( 80000000,  gpll0,   10,    0,    0),
+	F_MM( 100000000, gpll0,   8,    0,    0),
+	F_MM( 200000000, gpll0,   4,    0,    0),
+	F_MM( 320000000, gpll0,   2.5,    0,    0),
+	F_END
+};
+
+static struct rcg_clk dsi_esc0_clk_src = {
+	.cmd_reg  = (uint32_t *) DSI_ESC0_CMD_RCGR,
+	.cfg_reg  = (uint32_t *) DSI_ESC0_CFG_RCGR,
+	.set_rate = clock_lib2_rcg_set_rate_hid,
+	.freq_tbl = ftbl_mdss_esc0_1_clk,
+
+	.c        = {
+		.dbg_name = "dsi_esc0_clk_src",
+		.ops      = &clk_ops_rcg,
+	},
+};
+
+static struct clk_freq_tbl ftbl_mdss_vsync_clk[] = {
+	F_MM(19200000,    cxo,   1,   0,   0),
+	F_END
+};
+
+static struct rcg_clk vsync_clk_src = {
+	.cmd_reg  = (uint32_t *) VSYNC_CMD_RCGR,
+	.cfg_reg  = (uint32_t *) VSYNC_CFG_RCGR,
+	.set_rate = clock_lib2_rcg_set_rate_hid,
+	.freq_tbl = ftbl_mdss_vsync_clk,
+
+	.c        = {
+		.dbg_name = "vsync_clk_src",
+		.ops      = &clk_ops_rcg,
+	},
+};
+
+static struct branch_clk mdss_esc0_clk = {
+	.cbcr_reg    = (uint32_t *) DSI_ESC0_CBCR,
+	.parent      = &dsi_esc0_clk_src.c,
+	.has_sibling = 0,
+
+	.c           = {
+		.dbg_name = "mdss_esc0_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+static struct branch_clk mdss_axi_clk = {
+	.cbcr_reg    = (uint32_t *) MDP_AXI_CBCR,
+	.has_sibling = 1,
+
+	.c           = {
+		.dbg_name = "mdss_axi_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+static struct branch_clk mdp_ahb_clk = {
+	.cbcr_reg    = (uint32_t *) MDP_AHB_CBCR,
+	.has_sibling = 1,
+
+	.c           = {
+		.dbg_name = "mdp_ahb_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+static struct rcg_clk mdss_mdp_clk_src = {
+	.cmd_reg      = (uint32_t *) MDP_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) MDP_CFG_RCGR,
+	.set_rate     = clock_lib2_rcg_set_rate_hid,
+	.freq_tbl     = ftbl_mdp_clk,
+	.current_freq = &rcg_dummy_freq,
+
+	.c            = {
+		.dbg_name = "mdss_mdp_clk_src",
+		.ops      = &clk_ops_rcg,
+	},
+};
+
+static struct branch_clk mdss_mdp_clk = {
+	.cbcr_reg    = (uint32_t *) MDP_CBCR,
+	.parent      = &mdss_mdp_clk_src.c,
+	.has_sibling = 0,
+
+	.c           = {
+		.dbg_name = "mdss_mdp_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+static struct branch_clk mdss_vsync_clk = {
+	.cbcr_reg    = MDSS_VSYNC_CBCR,
+	.parent      = &vsync_clk_src.c,
+	.has_sibling = 0,
+
+	.c           = {
+		.dbg_name = "mdss_vsync_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_ce1_clk[] = {
+	F(160000000,  gpll0,   5,   0,   0),
+	F_END
+};
+
+static struct rcg_clk ce1_clk_src = {
+	.cmd_reg      = (uint32_t *) GCC_CRYPTO_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) GCC_CRYPTO_CFG_RCGR,
+	.set_rate     = clock_lib2_rcg_set_rate_hid,
+	.freq_tbl     = ftbl_gcc_ce1_clk,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "ce1_clk_src",
+		.ops      = &clk_ops_rcg,
+	},
+};
+
+static struct vote_clk gcc_ce1_clk = {
+	.cbcr_reg      = (uint32_t *) GCC_CRYPTO_CBCR,
+	.vote_reg      = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask       = BIT(2),
+
+	.c = {
+		.dbg_name  = "gcc_ce1_clk",
+		.ops       = &clk_ops_vote,
+	},
+};
+
+static struct vote_clk gcc_ce1_ahb_clk = {
+	.cbcr_reg     = (uint32_t *) GCC_CRYPTO_AHB_CBCR,
+	.vote_reg     = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask      = BIT(0),
+
+	.c = {
+		.dbg_name = "gcc_ce1_ahb_clk",
+		.ops      = &clk_ops_vote,
+	},
+};
+
+static struct vote_clk gcc_ce1_axi_clk = {
+	.cbcr_reg     = (uint32_t *) GCC_CRYPTO_AXI_CBCR,
+	.vote_reg     = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask      = BIT(1),
+
+	.c = {
+		.dbg_name = "gcc_ce1_axi_clk",
+		.ops      = &clk_ops_vote,
+	},
+};
+
+
+static struct rcg_clk gcc_blsp1_qup2_i2c_apps_clk_src =
+{
+	.cmd_reg      = (uint32_t *) GCC_BLSP1_QUP2_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) GCC_BLSP1_QUP2_CFG_RCGR,
+	.set_rate     = clock_lib2_rcg_set_rate_hid,
+	.freq_tbl     = ftbl_gcc_blsp1_qup2_i2c_apps_clk_src,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "gcc_blsp1_qup2_i2c_apps_clk_src",
+		.ops      = &clk_ops_rcg,
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup2_i2c_apps_clk = {
+	.cbcr_reg = GCC_BLSP1_QUP2_APPS_CBCR,
+	.parent   = &gcc_blsp1_qup2_i2c_apps_clk_src.c,
+
+	.c = {
+		.dbg_name = "gcc_blsp1_qup2_i2c_apps_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+/* Clock lookup table */
+static struct clk_lookup msm_clocks_ferrum[] =
+{
+	CLK_LOOKUP("sdc1_iface_clk", gcc_sdcc1_ahb_clk.c),
+	CLK_LOOKUP("sdc1_core_clk",  gcc_sdcc1_apps_clk.c),
+
+	CLK_LOOKUP("sdc2_iface_clk", gcc_sdcc2_ahb_clk.c),
+	CLK_LOOKUP("sdc2_core_clk",  gcc_sdcc2_apps_clk.c),
+
+	CLK_LOOKUP("uart2_iface_clk", gcc_blsp1_ahb_clk.c),
+	CLK_LOOKUP("uart2_core_clk",  gcc_blsp1_uart2_apps_clk.c),
+
+	CLK_LOOKUP("usb_iface_clk",  gcc_usb_hs_ahb_clk.c),
+	CLK_LOOKUP("usb_core_clk",   gcc_usb_hs_system_clk.c),
+
+	CLK_LOOKUP("mdp_ahb_clk",          mdp_ahb_clk.c),
+	CLK_LOOKUP("mdss_esc0_clk",        mdss_esc0_clk.c),
+	CLK_LOOKUP("mdss_axi_clk",         mdss_axi_clk.c),
+	CLK_LOOKUP("mdss_vsync_clk",       mdss_vsync_clk.c),
+	CLK_LOOKUP("mdss_mdp_clk_src",     mdss_mdp_clk_src.c),
+	CLK_LOOKUP("mdss_mdp_clk",         mdss_mdp_clk.c),
+
+	CLK_LOOKUP("ce1_ahb_clk",  gcc_ce1_ahb_clk.c),
+	CLK_LOOKUP("ce1_axi_clk",  gcc_ce1_axi_clk.c),
+	CLK_LOOKUP("ce1_core_clk", gcc_ce1_clk.c),
+	CLK_LOOKUP("ce1_src_clk",  ce1_clk_src.c),
+
+	CLK_LOOKUP("blsp1_qup2_ahb_iface_clk", gcc_blsp1_ahb_clk.c),
+	CLK_LOOKUP("gcc_blsp1_qup2_i2c_apps_clk_src", gcc_blsp1_qup2_i2c_apps_clk_src.c),
+	CLK_LOOKUP("gcc_blsp1_qup2_i2c_apps_clk", gcc_blsp1_qup2_i2c_apps_clk.c),
+};
+
+void platform_clock_init(void)
+{
+	clk_init(msm_clocks_ferrum, ARRAY_SIZE(msm_clocks_ferrum));
+}
diff --git a/platform/ferrum/gpio.c b/platform/ferrum/gpio.c
new file mode 100644
index 0000000..5a9889c
--- /dev/null
+++ b/platform/ferrum/gpio.c
@@ -0,0 +1,64 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <debug.h>
+#include <reg.h>
+#include <platform/iomap.h>
+#include <platform/gpio.h>
+#include <blsp_qup.h>
+
+void gpio_tlmm_config(uint32_t gpio, uint8_t func,
+			uint8_t dir, uint8_t pull,
+			uint8_t drvstr, uint32_t enable)
+{
+	uint32_t val = 0;
+	val |= pull;
+	val |= func << 2;
+	val |= drvstr << 6;
+	val |= enable << 9;
+	writel(val, (uint32_t *)GPIO_CONFIG_ADDR(gpio));
+	return;
+}
+
+void gpio_set(uint32_t gpio, uint32_t dir)
+{
+	writel(dir, (uint32_t *)GPIO_IN_OUT_ADDR(gpio));
+	return;
+}
+
+/* Configure gpio for blsp uart 2 */
+void gpio_config_uart_dm(uint8_t id)
+{
+	/* configure rx gpio */
+	gpio_tlmm_config(5, 2, GPIO_INPUT, GPIO_NO_PULL,
+				GPIO_8MA, GPIO_DISABLE);
+
+	/* configure tx gpio */
+	gpio_tlmm_config(4, 2, GPIO_OUTPUT, GPIO_NO_PULL,
+				GPIO_8MA, GPIO_DISABLE);
+}
diff --git a/platform/ferrum/include/platform/clock.h b/platform/ferrum/include/platform/clock.h
new file mode 100644
index 0000000..ab23e03
--- /dev/null
+++ b/platform/ferrum/include/platform/clock.h
@@ -0,0 +1,44 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __FERRUM_CLOCK_H
+#define __FERRUM_CLOCK_H
+
+#include <clock.h>
+#include <clock_lib2.h>
+
+#define UART_DM_CLK_RX_TX_BIT_RATE 0xCC
+
+void platform_clock_init(void);
+
+void clock_init_mmc(uint32_t interface);
+void clock_config_mmc(uint32_t interface, uint32_t freq);
+void clock_config_uart_dm(uint8_t id);
+void hsusb_clock_init(void);
+void clock_config_ce(uint8_t instance);
+#endif
diff --git a/platform/ferrum/include/platform/gpio.h b/platform/ferrum/include/platform/gpio.h
new file mode 100644
index 0000000..0114b3e
--- /dev/null
+++ b/platform/ferrum/include/platform/gpio.h
@@ -0,0 +1,59 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PLATFORM_FERRUM_GPIO_H
+#define __PLATFORM_FERRUM_GPIO_H
+
+
+/* GPIO TLMM: Direction */
+#define GPIO_INPUT      0
+#define GPIO_OUTPUT     1
+
+/* GPIO TLMM: Pullup/Pulldown */
+#define GPIO_NO_PULL    0
+#define GPIO_PULL_DOWN  1
+#define GPIO_KEEPER     2
+#define GPIO_PULL_UP    3
+
+/* GPIO TLMM: Drive Strength */
+#define GPIO_2MA        0
+#define GPIO_4MA        1
+#define GPIO_6MA        2
+#define GPIO_8MA        3
+#define GPIO_10MA       4
+#define GPIO_12MA       5
+#define GPIO_14MA       6
+#define GPIO_16MA       7
+
+/* GPIO TLMM: Status */
+#define GPIO_ENABLE     0
+#define GPIO_DISABLE    1
+
+
+void gpio_config_uart_dm(uint8_t id);
+#endif
diff --git a/platform/ferrum/include/platform/iomap.h b/platform/ferrum/include/platform/iomap.h
new file mode 100644
index 0000000..5ac39ac
--- /dev/null
+++ b/platform/ferrum/include/platform/iomap.h
@@ -0,0 +1,117 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PLATFORM_FERRUM_IOMAP_H_
+#define _PLATFORM_FERRUM_IOMAP_H_
+
+#define MSM_IOMAP_BASE              0x00000000
+#define MSM_IOMAP_END               0x08000000
+
+#define SDRAM_START_ADDR            0x80000000
+
+#define MSM_SHARED_BASE             0x86300000
+
+#define APPS_SS_BASE                0x0B000000
+
+#define MSM_GIC_DIST_BASE           APPS_SS_BASE
+#define MSM_GIC_CPU_BASE            (APPS_SS_BASE + 0x2000)
+#define APPS_APCS_QTMR_AC_BASE      (APPS_SS_BASE + 0x00020000)
+#define APPS_APCS_F0_QTMR_V1_BASE   (APPS_SS_BASE + 0x00021000)
+#define QTMR_BASE                   APPS_APCS_F0_QTMR_V1_BASE
+
+#define PERIPH_SS_BASE              0x07800000
+
+#define MSM_SDC1_BASE               (PERIPH_SS_BASE + 0x00024000)
+#define MSM_SDC1_SDHCI_BASE         (PERIPH_SS_BASE + 0x00024900)
+#define MSM_SDC2_BASE               (PERIPH_SS_BASE + 0x00064000)
+#define MSM_SDC2_SDHCI_BASE         (PERIPH_SS_BASE + 0x00064900)
+
+/* SDHCI */
+#define SDCC_MCI_HC_MODE            (0x00000078)
+#define SDCC_HC_PWRCTL_STATUS_REG   (0x000000DC)
+#define SDCC_HC_PWRCTL_MASK_REG     (0x000000E0)
+#define SDCC_HC_PWRCTL_CLEAR_REG    (0x000000E4)
+#define SDCC_HC_PWRCTL_CTL_REG      (0x000000E8)
+
+#define BLSP1_UART0_BASE            (PERIPH_SS_BASE + 0x000AF000)
+#define BLSP1_UART1_BASE            (PERIPH_SS_BASE + 0x000B0000)
+#define MSM_USB_BASE                (PERIPH_SS_BASE + 0x000D9000)
+
+#define CLK_CTL_BASE                0x1800000
+
+#define SPMI_BASE                   0x02000000
+#define SPMI_GENI_BASE              (SPMI_BASE + 0xA000)
+#define SPMI_PIC_BASE               (SPMI_BASE +  0x01800000)
+
+#define TLMM_BASE_ADDR              0x1000000
+#define GPIO_CONFIG_ADDR(x)         (TLMM_BASE_ADDR + (x)*0x1000)
+#define GPIO_IN_OUT_ADDR(x)         (TLMM_BASE_ADDR + 0x00000004 + (x)*0x1000)
+
+#define MPM2_MPM_CTRL_BASE          0x004A0000
+#define MPM2_MPM_PS_HOLD            0x004AB000
+
+/* CRYPTO ENGINE */
+#define  MSM_CE1_BASE               0x073A000
+#define  MSM_CE1_BAM_BASE           0x0704000
+
+
+/* GPLL */
+#define GPLL0_STATUS                (CLK_CTL_BASE + 0x21024)
+#define APCS_GPLL_ENA_VOTE          (CLK_CTL_BASE + 0x45000)
+#define APCS_CLOCK_BRANCH_ENA_VOTE  (CLK_CTL_BASE + 0x45004)
+
+/* SDCC */
+#define SDC1_HDRV_PULL_CTL          (TLMM_BASE_ADDR + 0x10A000)
+#define SDCC1_BCR                   (CLK_CTL_BASE + 0x42000) /* block reset*/
+#define SDCC1_APPS_CBCR             (CLK_CTL_BASE + 0x42018) /* branch ontrol */
+#define SDCC1_AHB_CBCR              (CLK_CTL_BASE + 0x4201C)
+#define SDCC1_CMD_RCGR              (CLK_CTL_BASE + 0x42004) /* cmd */
+#define SDCC1_CFG_RCGR              (CLK_CTL_BASE + 0x42008) /* cfg */
+#define SDCC1_M                     (CLK_CTL_BASE + 0x4200C) /* m */
+#define SDCC1_N                     (CLK_CTL_BASE + 0x42010) /* n */
+#define SDCC1_D                     (CLK_CTL_BASE + 0x42014) /* d */
+
+
+/* UART */
+#define BLSP1_AHB_CBCR              (CLK_CTL_BASE + 0x1008)
+#define BLSP1_UART2_APPS_CBCR       (CLK_CTL_BASE + 0x302C)
+#define BLSP1_UART2_APPS_CMD_RCGR   (CLK_CTL_BASE + 0x3034)
+#define BLSP1_UART2_APPS_CFG_RCGR   (CLK_CTL_BASE + 0x3038)
+#define BLSP1_UART2_APPS_M          (CLK_CTL_BASE + 0x303C)
+#define BLSP1_UART2_APPS_N          (CLK_CTL_BASE + 0x3040)
+#define BLSP1_UART2_APPS_D          (CLK_CTL_BASE + 0x3044)
+
+
+/* USB */
+#define USB_HS_BCR                  (CLK_CTL_BASE + 0x41000)
+#define USB_HS_SYSTEM_CBCR          (CLK_CTL_BASE + 0x41004)
+#define USB_HS_AHB_CBCR             (CLK_CTL_BASE + 0x41008)
+#define USB_HS_SYSTEM_CMD_RCGR      (CLK_CTL_BASE + 0x41010)
+#define USB_HS_SYSTEM_CFG_RCGR      (CLK_CTL_BASE + 0x41014)
+
+#endif
diff --git a/platform/ferrum/include/platform/irqs.h b/platform/ferrum/include/platform/irqs.h
new file mode 100644
index 0000000..47e7f04
--- /dev/null
+++ b/platform/ferrum/include/platform/irqs.h
@@ -0,0 +1,66 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __IRQS_FERRUM_H
+#define __IRQS_FERRUM_H
+
+/* MSM ACPU Interrupt Numbers */
+
+/* 0-15:  STI/SGI (software triggered/generated interrupts)
+ * 16-31: PPI (private peripheral interrupts)
+ * 32+:   SPI (shared peripheral interrupts)
+ */
+int qtmr_irq();
+
+#define GIC_PPI_START                          16
+#define GIC_SPI_START                          32
+
+#define INT_QTMR_NON_SECURE_PHY_TIMER_EXP      (GIC_PPI_START + 3)
+#define INT_QTMR_VIRTUAL_TIMER_EXP             (GIC_PPI_START + 4)
+
+#define INT_QTMR_FRM_0_PHYSICAL_TIMER_EXP      (GIC_SPI_START + 8)
+
+#define USB1_HS_BAM_IRQ                        (GIC_SPI_START + 135)
+#define USB1_HS_IRQ                            (GIC_SPI_START + 134)
+
+#define SDCC1_PWRCTL_IRQ                       (GIC_SPI_START + 138)
+#define SDCC2_PWRCTL_IRQ                       (GIC_SPI_START + 221)
+
+/* Retrofit universal macro names */
+#define INT_USB_HS                             USB1_HS_IRQ
+
+#define EE0_KRAIT_HLOS_SPMI_PERIPH_IRQ         (GIC_SPI_START + 190)
+
+#define NR_MSM_IRQS                            256
+#define NR_GPIO_IRQS                           173
+#define NR_BOARD_IRQS                          0
+
+#define NR_IRQS                                (NR_MSM_IRQS + NR_GPIO_IRQS + \
+                                               NR_BOARD_IRQS)
+
+#endif /* __IRQS_FERRUM_H */
diff --git a/platform/ferrum/platform.c b/platform/ferrum/platform.c
new file mode 100644
index 0000000..1895fe6
--- /dev/null
+++ b/platform/ferrum/platform.c
@@ -0,0 +1,52 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <debug.h>
+#include <reg.h>
+#include <platform/iomap.h>
+#include <qgic.h>
+#include <qtimer.h>
+#include <mmu.h>
+#include <arch/arm/mmu.h>
+#include <smem.h>
+
+void platform_early_init(void)
+{
+	qgic_init();
+	qtimer_init();
+}
+
+void platform_init(void)
+{
+	dprintf(INFO, "platform_init()\n");
+}
+
+void platform_uninit(void)
+{
+	qtimer_uninit();
+}
diff --git a/platform/ferrum/rules.mk b/platform/ferrum/rules.mk
new file mode 100644
index 0000000..da6f955
--- /dev/null
+++ b/platform/ferrum/rules.mk
@@ -0,0 +1,25 @@
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+ARCH    := arm
+#Compiling this as cortex-a8 until the compiler supports krait
+ARM_CPU := cortex-a8
+CPU     := generic
+
+DEFINES += ARM_CPU_CORE_A7
+
+MMC_SLOT         := 1
+
+DEFINES += PERIPH_BLK_BLSP=1
+DEFINES += WITH_CPU_EARLY_INIT=0 WITH_CPU_WARM_BOOT=0 \
+           MMC_SLOT=$(MMC_SLOT)
+
+INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared/include
+
+OBJS += \
+       $(LOCAL_DIR)/platform.o \
+       $(LOCAL_DIR)/acpuclock.o \
+       $(LOCAL_DIR)/gpio.o
+
+LINKER_SCRIPT += $(BUILDDIR)/system-onesegment.ld
+
+include platform/msm_shared/rules.mk
diff --git a/platform/msm_shared/dev_tree.c b/platform/msm_shared/dev_tree.c
index 19b5e74..e4505d4 100644
--- a/platform/msm_shared/dev_tree.c
+++ b/platform/msm_shared/dev_tree.c
@@ -305,8 +305,11 @@
 
 	memcpy((void*) &app_dtb_offset, (void*) (kernel + DTB_OFFSET), sizeof(uint32_t));
 
+	if (((uintptr_t)kernel + (uintptr_t)app_dtb_offset) < (uintptr_t)kernel) {
+		return NULL;
+	}
 	dtb = kernel + app_dtb_offset;
-	while (dtb + sizeof(struct fdt_header) < kernel_end) {
+	while (((uintptr_t)dtb + sizeof(struct fdt_header)) < (uintptr_t)kernel_end) {
 		uint32_t dtb_soc_rev_id;
 		struct fdt_header dtb_hdr;
 		uint32_t dtb_size;
@@ -315,7 +318,8 @@
 		 * and operate on it separately */
 		memcpy(&dtb_hdr, dtb, sizeof(struct fdt_header));
 		if (fdt_check_header((const void *)&dtb_hdr) != 0 ||
-		    (dtb + fdt_totalsize((const void *)&dtb_hdr) > kernel_end))
+		    ((uintptr_t)dtb + (uintptr_t)fdt_totalsize((const void *)&dtb_hdr) < (uintptr_t)dtb) ||
+			((uintptr_t)dtb + (uintptr_t)fdt_totalsize((const void *)&dtb_hdr) > (uintptr_t)kernel_end))
 			break;
 		dtb_size = fdt_totalsize(&dtb_hdr);
 
diff --git a/platform/msm_shared/qpic_nand.c b/platform/msm_shared/qpic_nand.c
index f638e37..0c858d9 100644
--- a/platform/msm_shared/qpic_nand.c
+++ b/platform/msm_shared/qpic_nand.c
@@ -607,6 +607,7 @@
 
 	/* Allocate memory required to read the onfi param page */
 	buffer = (unsigned char*) malloc(ONFI_READ_PARAM_PAGE_BUFFER_SIZE);
+	ASSERT(buffer != NULL);
 
 	/* Read the vld and dev_cmd1 registers before modifying */
 	vld = qpic_nand_read_reg(NAND_DEV_CMD_VLD, 0, ce_array);
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index 9b03643..7fb5ef3 100755
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -402,6 +402,24 @@
 			$(LOCAL_DIR)/qusb2_phy.o
 endif
 
+ifeq ($(PLATFORM),ferrum)
+	OBJS += $(LOCAL_DIR)/qgic.o \
+			$(LOCAL_DIR)/qtimer.o \
+			$(LOCAL_DIR)/qtimer_mmap.o \
+			$(LOCAL_DIR)/interrupts.o \
+			$(LOCAL_DIR)/clock.o \
+			$(LOCAL_DIR)/clock_pll.o \
+			$(LOCAL_DIR)/clock_lib2.o \
+			$(LOCAL_DIR)/uart_dm.o \
+			$(LOCAL_DIR)/board.o \
+			$(LOCAL_DIR)/spmi.o \
+			$(LOCAL_DIR)/bam.o \
+			$(LOCAL_DIR)/qpic_nand.o \
+			$(LOCAL_DIR)/scm.o \
+			$(LOCAL_DIR)/dev_tree.o \
+			$(LOCAL_DIR)/gpio.o
+endif
+
 ifeq ($(ENABLE_BOOT_CONFIG_SUPPORT), 1)
 	OBJS += \
 		$(LOCAL_DIR)/boot_device.o
diff --git a/platform/msm_shared/smem.h b/platform/msm_shared/smem.h
index e2ac883..392d781 100644
--- a/platform/msm_shared/smem.h
+++ b/platform/msm_shared/smem.h
@@ -363,10 +363,12 @@
 	APQ8039  = 241,
 	MSM8236  = 242,
 	MSM8636  = 243,
+	MSM8909  = 245,
 	APQ8016  = 247,
 	MSM8216  = 248,
 	MSM8116  = 249,
 	MSM8616  = 250,
+	APQ8094  = 253,
 };
 
 enum platform {
diff --git a/platform/msmzirc/include/platform/iomap.h b/platform/msmzirc/include/platform/iomap.h
index e3962ba..a401803 100644
--- a/platform/msmzirc/include/platform/iomap.h
+++ b/platform/msmzirc/include/platform/iomap.h
@@ -139,6 +139,7 @@
 #define USB_HS_AHB_CBCR             (CLK_CTL_BASE + 0x41008)
 #define USB_HS_SYSTEM_CMD_RCGR      (CLK_CTL_BASE + 0x41010)
 #define USB_HS_SYSTEM_CFG_RCGR      (CLK_CTL_BASE + 0x41014)
+#define QUSB2A_PHY_BCR              (CLK_CTL_BASE + 0x41028)
 
 /* USB 3.0 clock */
 #define SYS_NOC_USB3_AXI_CBCR       (CLK_CTL_BASE + 0x5E084)
diff --git a/platform/msmzirc/msmzirc-clock.c b/platform/msmzirc/msmzirc-clock.c
index aee1076..ca97cb0 100644
--- a/platform/msmzirc/msmzirc-clock.c
+++ b/platform/msmzirc/msmzirc-clock.c
@@ -357,6 +357,15 @@
 	},
 };
 
+static struct reset_clk gcc_usb2a_phy_sleep_clk = {
+	.bcr_reg = (uint32_t *) QUSB2A_PHY_BCR,
+
+	.c = {
+		.dbg_name = "usb2b_phy_sleep_clk",
+		.ops      = &clk_ops_reset,
+	},
+};
+
 static struct clk_lookup msm_clocks_zirc[] =
 {
 	CLK_LOOKUP("sdc1_iface_clk", gcc_sdcc1_ahb_clk.c),
@@ -370,6 +379,7 @@
 	CLK_LOOKUP("usb30_pipe_clk",   gcc_usb30_pipe_clk.c),
 	CLK_LOOKUP("usb30_aux_clk",    gcc_usb30_aux_clk.c),
 
+	CLK_LOOKUP("usb2b_phy_sleep_clk", gcc_usb2a_phy_sleep_clk.c),
 	CLK_LOOKUP("usb30_phy_reset",     gcc_usb30_phy_reset.c),
 
 	CLK_LOOKUP("usb_phy_cfg_ahb_clk", gcc_usb_phy_cfg_ahb_clk.c),
diff --git a/project/ferrum.mk b/project/ferrum.mk
new file mode 100644
index 0000000..2ffb029
--- /dev/null
+++ b/project/ferrum.mk
@@ -0,0 +1,35 @@
+# top level project rules for the ferrum project
+#
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+TARGET := ferrum
+
+MODULES += app/aboot
+
+DEBUG := 1
+EMMC_BOOT := 1
+
+#DEFINES += WITH_DEBUG_DCC=1
+DEFINES += WITH_DEBUG_UART=1
+#DEFINES += WITH_DEBUG_FBCON=1
+DEFINES += DEVICE_TREE=1
+#DEFINES += MMC_BOOT_BAM=1
+#DEFINES += CRYPTO_BAM=1
+#DEFINES += ABOOT_IGNORE_BOOT_HEADER_ADDRS=1
+
+#DEFINES += ABOOT_FORCE_KERNEL_ADDR=0x80008000
+#DEFINES += ABOOT_FORCE_RAMDISK_ADDR=0x82000000
+#DEFINES += ABOOT_FORCE_TAGS_ADDR=0x81E00000
+
+#Disable thumb mode
+ENABLE_THUMB := false
+
+ENABLE_SDHCI_SUPPORT := 1
+
+ifeq ($(ENABLE_SDHCI_SUPPORT),1)
+DEFINES += MMC_SDHCI_SUPPORT=1
+endif
+
+ifeq ($(EMMC_BOOT),1)
+DEFINES += _EMMC_BOOT=1
+endif
diff --git a/target/ferrum/init.c b/target/ferrum/init.c
new file mode 100644
index 0000000..5e87b2e
--- /dev/null
+++ b/target/ferrum/init.c
@@ -0,0 +1,172 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <debug.h>
+#include <platform/iomap.h>
+#include <reg.h>
+#include <target.h>
+#include <platform.h>
+#include <uart_dm.h>
+#include <mmc.h>
+#include <dev/keys.h>
+#include <spmi_v2.h>
+#include <pm8x41.h>
+#include <board.h>
+#include <baseband.h>
+#include <hsusb.h>
+#include <scm.h>
+#include <platform/gpio.h>
+#include <platform/irqs.h>
+#include <platform/clock.h>
+#include <crypto5_wrapper.h>
+#include <partition_parser.h>
+#include <stdlib.h>
+#include <gpio.h>
+
+#define PMIC_ARB_CHANNEL_NUM    0
+#define PMIC_ARB_OWNER_ID       0
+
+
+struct mmc_device *dev;
+
+static uint32_t mmc_pwrctl_base[] =
+	{ MSM_SDC1_BASE, MSM_SDC2_BASE };
+
+static uint32_t mmc_sdhci_base[] =
+	{ MSM_SDC1_SDHCI_BASE, MSM_SDC2_SDHCI_BASE };
+
+static uint32_t  mmc_sdc_pwrctl_irq[] =
+	{ SDCC1_PWRCTL_IRQ, SDCC2_PWRCTL_IRQ };
+
+static void set_sdc_power_ctrl(void);
+
+void target_early_init(void)
+{
+#if WITH_DEBUG_UART
+	uart_dm_init(1, 0, BLSP1_UART1_BASE);
+#endif
+}
+
+void target_sdc_init()
+{
+	struct mmc_config_data config;
+
+	/* Set drive strength & pull ctrl values */
+	set_sdc_power_ctrl();
+
+	config.bus_width = DATA_BUS_WIDTH_8BIT;
+	config.max_clk_rate = MMC_CLK_177MHZ;
+
+	/* Try slot 1*/
+	config.slot         = 1;
+	config.sdhc_base    = mmc_sdhci_base[config.slot - 1];
+	config.pwrctl_base  = mmc_pwrctl_base[config.slot - 1];
+	config.pwr_irq      = mmc_sdc_pwrctl_irq[config.slot - 1];
+	config.hs400_support = 0;
+
+	if (!(dev = mmc_init(&config))) {
+	/* Try slot 2 */
+		config.slot         = 2;
+		config.max_clk_rate = MMC_CLK_200MHZ;
+		config.sdhc_base    = mmc_sdhci_base[config.slot - 1];
+		config.pwrctl_base  = mmc_pwrctl_base[config.slot - 1];
+		config.pwr_irq      = mmc_sdc_pwrctl_irq[config.slot - 1];
+
+		if (!(dev = mmc_init(&config))) {
+			dprintf(CRITICAL, "mmc init failed!");
+			ASSERT(0);
+		}
+	}
+}
+
+void *target_mmc_device()
+{
+	return (void *) dev;
+}
+
+static void target_keystatus()
+{
+}
+
+static void set_sdc_power_ctrl()
+{
+	/* Drive strength configs for sdc pins */
+	struct tlmm_cfgs sdc1_hdrv_cfg[] =
+	{
+		{ SDC1_CLK_HDRV_CTL_OFF,  TLMM_CUR_VAL_16MA, TLMM_HDRV_MASK },
+		{ SDC1_CMD_HDRV_CTL_OFF,  TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK },
+		{ SDC1_DATA_HDRV_CTL_OFF, TLMM_CUR_VAL_6MA, TLMM_HDRV_MASK },
+	};
+
+	/* Pull configs for sdc pins */
+	struct tlmm_cfgs sdc1_pull_cfg[] =
+	{
+		{ SDC1_CLK_PULL_CTL_OFF,  TLMM_NO_PULL, TLMM_PULL_MASK },
+		{ SDC1_CMD_PULL_CTL_OFF,  TLMM_PULL_UP, TLMM_PULL_MASK },
+		{ SDC1_DATA_PULL_CTL_OFF, TLMM_PULL_UP, TLMM_PULL_MASK },
+	};
+
+	/* Set the drive strength & pull control values */
+	tlmm_set_hdrive_ctrl(sdc1_hdrv_cfg, ARRAY_SIZE(sdc1_hdrv_cfg));
+	tlmm_set_pull_ctrl(sdc1_pull_cfg, ARRAY_SIZE(sdc1_pull_cfg));
+}
+
+void target_init(void)
+{
+	uint32_t base_addr;
+	uint8_t slot;
+
+	dprintf(INFO, "target_init()\n");
+
+	spmi_init(PMIC_ARB_CHANNEL_NUM, PMIC_ARB_OWNER_ID);
+
+	target_keystatus();
+
+	target_sdc_init();
+
+	if (partition_read_table())
+	{
+		dprintf(CRITICAL, "Error reading the partition table info\n");
+		ASSERT(0);
+	}
+
+}
+
+void target_serialno(unsigned char *buf)
+{
+	uint32_t serialno;
+	if (target_is_emmc_boot()) {
+		serialno = mmc_get_psn();
+		snprintf((char *)buf, 13, "%x", serialno);
+	}
+}
+
+unsigned board_machtype(void)
+{
+}
+
diff --git a/target/ferrum/meminfo.c b/target/ferrum/meminfo.c
new file mode 100644
index 0000000..9d76bf6
--- /dev/null
+++ b/target/ferrum/meminfo.c
@@ -0,0 +1,85 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <reg.h>
+#include <debug.h>
+#include <malloc.h>
+#include <smem.h>
+#include <stdint.h>
+#include <libfdt.h>
+#include <platform/iomap.h>
+#include <dev_tree.h>
+
+uint32_t target_dev_tree_mem(void *fdt, uint32_t memory_node_offset)
+{
+	ram_partition ptn_entry;
+	unsigned int index;
+	int ret = 0;
+	uint32_t len = 0;
+
+	/* Make sure RAM partition table is initialized */
+	ASSERT(smem_ram_ptable_init_v1());
+
+	len = smem_get_ram_ptable_len();
+
+	/* Calculating the size of the mem_info_ptr */
+	for (index = 0 ; index < len; index++)
+	{
+		smem_get_ram_ptable_entry(&ptn_entry, index);
+
+		if((ptn_entry.category == SDRAM) &&
+			(ptn_entry.type == SYS_MEMORY))
+		{
+
+			/* Pass along all other usable memory regions to Linux */
+			ret = dev_tree_add_mem_info(fdt,
+							memory_node_offset,
+							ptn_entry.start,
+							ptn_entry.size);
+
+			if (ret)
+			{
+				dprintf(CRITICAL, "Failed to add secondary banks memory addresses\n");
+				goto target_dev_tree_mem_err;
+			}
+		}
+	}
+target_dev_tree_mem_err:
+
+	return ret;
+}
+
+void *target_get_scratch_address(void)
+{
+	return ((void *)SCRATCH_ADDR);
+}
+
+unsigned target_get_max_flash_size(void)
+{
+	return (256 * 1024 * 1024);
+}
diff --git a/target/ferrum/rules.mk b/target/ferrum/rules.mk
new file mode 100644
index 0000000..1e8c4f4
--- /dev/null
+++ b/target/ferrum/rules.mk
@@ -0,0 +1,29 @@
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared
+
+PLATFORM := ferrum
+
+MEMBASE := 0x8F600000 # SDRAM
+MEMSIZE := 0x00100000 # 1MB
+
+BASE_ADDR        := 0x80000000
+SCRATCH_ADDR     := 0x90000000
+
+MODULES += \
+	dev/keys \
+	dev/vib \
+	lib/ptable \
+	dev/pmic/pm8x41 \
+	lib/libfdt
+
+DEFINES += \
+	MEMSIZE=$(MEMSIZE) \
+	MEMBASE=$(MEMBASE) \
+	BASE_ADDR=$(BASE_ADDR) \
+	SCRATCH_ADDR=$(SCRATCH_ADDR)
+
+
+OBJS += \
+	$(LOCAL_DIR)/init.o \
+	$(LOCAL_DIR)/meminfo.o
diff --git a/target/ferrum/tools/makefile b/target/ferrum/tools/makefile
new file mode 100644
index 0000000..da48f0d
--- /dev/null
+++ b/target/ferrum/tools/makefile
@@ -0,0 +1,12 @@
+#Makefile to generate appsboot.mbn
+
+ifeq ($(BOOTLOADER_OUT),.)
+APPSBOOTOUT_DIR  := $(BUILDDIR)
+else
+APPSBOOTOUT_DIR  := $(BOOTLOADER_OUT)/../..
+endif
+
+APPSBOOTHEADER: emmc_appsboot.mbn
+
+emmc_appsboot.mbn: $(OUTELF_STRIP)
+	$(hide) cp -f $(OUTELF_STRIP) $(APPSBOOTOUT_DIR)/emmc_appsboot.mbn
diff --git a/target/msm8994/init.c b/target/msm8994/init.c
index 5c993c2..b381f48 100644
--- a/target/msm8994/init.c
+++ b/target/msm8994/init.c
@@ -304,6 +304,9 @@
 	case MSM8994:
 		board->baseband = BASEBAND_MSM;
 		break;
+	case APQ8094:
+		board->baseband = BASEBAND_APQ;
+		break;
 	default:
 		dprintf(CRITICAL, "Platform type: %u is not supported\n",platform);
 		ASSERT(0);
diff --git a/target/msmzirc/rules.mk b/target/msmzirc/rules.mk
index a69e059..c0831cc 100644
--- a/target/msmzirc/rules.mk
+++ b/target/msmzirc/rules.mk
@@ -4,14 +4,14 @@
 
 PLATFORM := msmzirc
 
-MEMBASE                             := 0x8F100000
+MEMBASE                             := 0x87C00000
 MEMSIZE                             := 0x00100000 # 1MB
 BASE_ADDR                           := 0x80000000
-SCRATCH_ADDR                        := 0x90000000
-SCRATCH_REGION1                     := 0x90000000
-SCRATCH_REGION1_SIZE                := 0x01000000 #16MB
-SCRATCH_REGION2                     := 0x91300000
-SCRATCH_REGION2_SIZE                := 0x06B00000 # 107MB
+SCRATCH_ADDR                        := 0x80000000
+SCRATCH_REGION1                     := 0x80000000
+SCRATCH_REGION1_SIZE                := 0x07C00000 # 124MB
+SCRATCH_REGION2                     := 0x88000000
+SCRATCH_REGION2_SIZE                := 0x08000000 # 128MB
 
 DEFINES += NO_KEYPAD_DRIVER=1
 DEFINES += PERIPH_BLK_BLSP=1