Merge "copper: clock support"
diff --git a/platform/copper/acpuclock.c b/platform/copper/acpuclock.c
index ec8ff10..763c81f 100644
--- a/platform/copper/acpuclock.c
+++ b/platform/copper/acpuclock.c
@@ -26,40 +26,94 @@
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <err.h>
+#include <assert.h>
 #include <debug.h>
 #include <reg.h>
 #include <platform/iomap.h>
-#include <platform/clock.h>
 #include <mmc.h>
+#include <clock.h>
+#include <platform/clock.h>
 
+void hsusb_clock_init(void)
+{
+	int ret;
+
+	ret = clk_get_set_enable("usb_iface_clk", 0, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set usb_iface_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	ret = clk_get_set_enable("usb_core_clk", 75000000, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set usb_core_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
+}
 
 void clock_init_mmc(uint32_t interface)
 {
-	/* Nothing to be done. */
+	int ret;
+
+	/* enable interface clock */
+	ret = clk_get_set_enable("sdc1_iface_clk", 0, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set sdc1_iface_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
 }
 
 /* Configure MMC clock */
 void clock_config_mmc(uint32_t interface, uint32_t freq)
 {
-
+	int ret;
 	uint32_t reg;
 
-	/* Not setting the clock rate for now.
-	 * using the clock override in Virtio
-	 */
+	if(freq == MMC_CLK_400KHZ)
+	{
+		ret = clk_get_set_enable("sdc1_core_clk", 400000, 1);
+	}
+	else if(freq == MMC_CLK_50MHZ)
+	{
+		ret = clk_get_set_enable("sdc1_core_clk", 50000000, 1);
+	}
+	else
+	{
+		dprintf(CRITICAL, "sdc frequency (%d) is not supported\n", freq);
+		ASSERT(0);
+	}
+
+
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set sdc1_core_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
 
 	reg = 0;
 	reg |= MMC_BOOT_MCI_CLK_ENABLE;
 	reg |= MMC_BOOT_MCI_CLK_ENA_FLOW;
 	reg |= MMC_BOOT_MCI_CLK_IN_FEEDBACK;
 	writel(reg, MMC_BOOT_MCI_CLK);
-
 }
 
 /* Configure UART clock based on the UART block id*/
 void clock_config_uart_dm(uint8_t id)
 {
-       /* Enable blsp_uart_clk */
-      /* Turned on by simulation by default */
+	int ret;
 
+	/* Enable blsp_uart_clk */
+	/* TODO: Find out correct frequency and UART_DM_CLK_RX_TX_BIT_RATE
+	 * combination for generating 115200 baud rate.
+	 */
+	ret = clk_get_set_enable("uart1_core_clk", 7372800, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set uart1_core_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
 }
diff --git a/platform/copper/clock.c b/platform/copper/clock.c
new file mode 100644
index 0000000..7fd15bb
--- /dev/null
+++ b/platform/copper/clock.c
@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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 Code Aurora 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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
+
+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,
+};
+
+
+/* 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     = 600000000,
+		.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,  15,   1,   2),
+	F( 25000000,  gpll0,  12,   1,   2),
+	F( 50000000,  gpll0,  12,   0,   0),
+	F(100000000,  gpll0,   6,   0,   0),
+	F(200000000,  gpll0,   3,   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,
+	},
+};
+
+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,
+	},
+};
+
+/* UART Clocks */
+static struct clk_freq_tbl ftbl_gcc_blsp1_2_uart1_6_apps_clk[] =
+{
+	F( 3686400,  gpll0,    1,  96,  15625),
+	F( 7372800,  gpll0,    1, 192,  15625),
+	F(14745600,  gpll0,    1, 384,  15625),
+	F(16000000,  gpll0,    5,   2,     15),
+	F(19200000,    cxo,    1,   0,      0),
+	F(24000000,  gpll0,    5,   1,      5),
+	F(32000000,  gpll0,    1,   4,     75),
+	F(40000000,  gpll0,   15,   0,      0),
+	F(46400000,  gpll0,    1,  29,    375),
+	F(48000000,  gpll0, 12.5,   0,      0),
+	F(51200000,  gpll0,    1,  32,    375),
+	F(56000000,  gpll0,    1,   7,     75),
+	F(58982400,  gpll0,    1, 1536, 15625),
+	F(60000000,  gpll0,   10,   0,      0),
+	F_END
+};
+
+static struct rcg_clk blsp1_uart1_apps_clk_src =
+{
+	.cmd_reg      = (uint32_t *) BLSP1_UART1_APPS_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) BLSP1_UART1_APPS_CFG_RCGR,
+	.m_reg        = (uint32_t *) BLSP1_UART1_APPS_M,
+	.n_reg        = (uint32_t *) BLSP1_UART1_APPS_N,
+	.d_reg        = (uint32_t *) BLSP1_UART1_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_uart1_apps_clk",
+		.ops      = &clk_ops_rcg_mnd,
+	},
+};
+
+static struct rcg_clk blsp1_uart3_apps_clk_src =
+{
+	.cmd_reg      = (uint32_t *) BLSP1_UART3_APPS_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) BLSP1_UART3_APPS_CFG_RCGR,
+	.m_reg        = (uint32_t *) BLSP1_UART3_APPS_M,
+	.n_reg        = (uint32_t *) BLSP1_UART3_APPS_N,
+	.d_reg        = (uint32_t *) BLSP1_UART3_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_uart3_apps_clk",
+		.ops      = &clk_ops_rcg_mnd,
+	},
+};
+
+static struct branch_clk gcc_blsp1_uart1_apps_clk =
+{
+	.cbcr_reg     = (uint32_t *) BLSP1_UART1_APPS_CBCR,
+	.parent       = &blsp1_uart1_apps_clk_src.c,
+
+	.c = {
+		.dbg_name = "gcc_blsp1_uart1_apps_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+static struct branch_clk gcc_blsp1_uart3_apps_clk =
+{
+	.cbcr_reg     = (uint32_t *) BLSP1_UART3_APPS_CBCR,
+	.parent       = &blsp1_uart3_apps_clk_src.c,
+
+	.c = {
+		.dbg_name = "gcc_blsp1_uart3_apps_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+/* USB Clocks */
+static struct clk_freq_tbl ftbl_gcc_usb_hs_system_clk[] =
+{
+	F(75000000,  gpll0,   8,   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,
+	},
+};
+
+
+/* Clock lookup table */
+static struct clk_lookup msm_clocks_8974[] =
+{
+	CLK_LOOKUP("sdc1_iface_clk", gcc_sdcc1_ahb_clk.c),
+	CLK_LOOKUP("sdc1_core_clk",  gcc_sdcc1_apps_clk.c),
+
+	CLK_LOOKUP("uart1_core_clk", gcc_blsp1_uart1_apps_clk.c),
+	CLK_LOOKUP("uart3_core_clk", gcc_blsp1_uart3_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),
+};
+
+
+void platform_clock_init(void)
+{
+	clk_init(msm_clocks_8974, ARRAY_SIZE(msm_clocks_8974));
+}
diff --git a/platform/copper/include/platform/clock.h b/platform/copper/include/platform/clock.h
index 179d281..0aa8604 100644
--- a/platform/copper/include/platform/clock.h
+++ b/platform/copper/include/platform/clock.h
@@ -26,12 +26,19 @@
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/* Included temporarily  for compilation.
- * Needs to be changed later for the
- * correct clock rate
- */
-#define UART_DM_CLK_RX_TX_BIT_RATE        0xFF
+#ifndef __COPPER_CLOCK_H
+#define __COPPER_CLOCK_H
+
+#include <clock.h>
+#include <clock_lib2.h>
+
+#define UART_DM_CLK_RX_TX_BIT_RATE 0xFF
+
+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);
+
+#endif
diff --git a/platform/copper/include/platform/iomap.h b/platform/copper/include/platform/iomap.h
index 135a4fe..176cc2c 100644
--- a/platform/copper/include/platform/iomap.h
+++ b/platform/copper/include/platform/iomap.h
@@ -51,6 +51,11 @@
 #define MSM_SDC2_BASE               (PERIPH_SS_BASE + 0x000A4000)
 #define MSM_SDC4_BASE               (PERIPH_SS_BASE + 0x000E4000)
 #define BLSP1_UART0_BASE            (PERIPH_SS_BASE + 0x0011D000)
+#define BLSP1_UART1_BASE            (PERIPH_SS_BASE + 0x0011E000)
+#define BLSP1_UART2_BASE            (PERIPH_SS_BASE + 0x0011F000)
+#define BLSP1_UART3_BASE            (PERIPH_SS_BASE + 0x00120000)
+#define BLSP1_UART4_BASE            (PERIPH_SS_BASE + 0x00121000)
+#define BLSP1_UART5_BASE            (PERIPH_SS_BASE + 0x00122000)
 #define MSM_USB_BASE                (PERIPH_SS_BASE + 0x00255000)
 
 #define CLK_CTL_BASE                0xFC400000
@@ -60,4 +65,44 @@
 #define GPIO_IN_OUT_ADDR(x)         (TLMM_BASE_ADDR + 0x1004 + (x)*0x10)
 
 #define MPM2_MPM_CTRL_BASE          0xFC4A1000
+
+
+/* Clock control registers */
+
+/* GPLL */
+#define GPLL0_STATUS                (CLK_CTL_BASE + 0x001C)
+#define APCS_GPLL_ENA_VOTE          (CLK_CTL_BASE + 0x1480)
+
+/* SDCC */
+#define SDCC1_BCR                   (CLK_CTL_BASE + 0x4C0) /* block reset */
+#define SDCC1_APPS_CBCR             (CLK_CTL_BASE + 0x4C4) /* branch control */
+#define SDCC1_AHB_CBCR              (CLK_CTL_BASE + 0x4C8)
+#define SDCC1_INACTIVITY_TIMER_CBCR (CLK_CTL_BASE + 0x4CC)
+#define SDCC1_CMD_RCGR              (CLK_CTL_BASE + 0x4D0) /* cmd */
+#define SDCC1_CFG_RCGR              (CLK_CTL_BASE + 0x4D4) /* cfg */
+#define SDCC1_M                     (CLK_CTL_BASE + 0x4D8) /* m */
+#define SDCC1_N                     (CLK_CTL_BASE + 0x4DC) /* n */
+#define SDCC1_D                     (CLK_CTL_BASE + 0x4E0) /* d */
+
+/* UART */
+#define BLSP1_UART1_APPS_CBCR       (CLK_CTL_BASE + 0x684)
+#define BLSP1_UART1_APPS_CMD_RCGR   (CLK_CTL_BASE + 0x68C)
+#define BLSP1_UART1_APPS_CFG_RCGR   (CLK_CTL_BASE + 0x690)
+#define BLSP1_UART1_APPS_M          (CLK_CTL_BASE + 0x694)
+#define BLSP1_UART1_APPS_N          (CLK_CTL_BASE + 0x698)
+#define BLSP1_UART1_APPS_D          (CLK_CTL_BASE + 0x69C)
+
+#define BLSP1_UART3_APPS_CBCR       (CLK_CTL_BASE + 0x784)
+#define BLSP1_UART3_APPS_CMD_RCGR   (CLK_CTL_BASE + 0x78C)
+#define BLSP1_UART3_APPS_CFG_RCGR   (CLK_CTL_BASE + 0x790)
+#define BLSP1_UART3_APPS_M          (CLK_CTL_BASE + 0x794)
+#define BLSP1_UART3_APPS_N          (CLK_CTL_BASE + 0x798)
+#define BLSP1_UART3_APPS_D          (CLK_CTL_BASE + 0x79C)
+
+/* USB */
+#define USB_HS_SYSTEM_CBCR          (CLK_CTL_BASE + 0x484)
+#define USB_HS_AHB_CBCR             (CLK_CTL_BASE + 0x488)
+#define USB_HS_SYSTEM_CMD_RCGR      (CLK_CTL_BASE + 0x490)
+#define USB_HS_SYSTEM_CFG_RCGR      (CLK_CTL_BASE + 0x494)
+
 #endif
diff --git a/platform/copper/platform.c b/platform/copper/platform.c
index 56076b9..b8c7279 100644
--- a/platform/copper/platform.c
+++ b/platform/copper/platform.c
@@ -33,11 +33,12 @@
 #include <platform/iomap.h>
 #include <qgic.h>
 #include <qtimer.h>
+#include <platform/clock.h>
 
-#define MB (1024*1024)
 
 void platform_early_init(void)
 {
+	platform_clock_init();
 	qgic_init();
 	qtimer_init();
 }
diff --git a/platform/copper/rules.mk b/platform/copper/rules.mk
index 5e0c78a..94c64ac 100644
--- a/platform/copper/rules.mk
+++ b/platform/copper/rules.mk
@@ -8,7 +8,7 @@
 
 MMC_SLOT         := 1
 
-DEFINES += PERIPH_BLK_BLSP=1 
+DEFINES += PERIPH_BLK_BLSP=1
 DEFINES += WITH_CPU_EARLY_INIT=0 WITH_CPU_WARM_BOOT=0 \
 	   MMC_SLOT=$(MMC_SLOT)
 
@@ -17,6 +17,7 @@
 OBJS += \
 	$(LOCAL_DIR)/platform.o \
 	$(LOCAL_DIR)/acpuclock.o \
+	$(LOCAL_DIR)/clock.o \
 	$(LOCAL_DIR)/gpio.o
 
 LINKER_SCRIPT += $(BUILDDIR)/system-onesegment.ld
diff --git a/platform/msm_shared/clock_lib2.c b/platform/msm_shared/clock_lib2.c
new file mode 100644
index 0000000..0aa405c
--- /dev/null
+++ b/platform/msm_shared/clock_lib2.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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 Code Aurora 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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>
+
+
+/*=============== CXO clock ops =============*/
+int cxo_clk_enable(struct clk *clk)
+{
+	/* Nothing to do. */
+	return 0;
+}
+
+void cxo_clk_disable(struct clk *clk)
+{
+	/* Nothing to do. */
+	return;
+}
+
+
+/*=============== Branch clock ops =============*/
+
+/* Branch clock enable */
+int clock_lib2_branch_clk_enable(struct clk *clk)
+{
+	int rc = 0;
+	uint32_t cbcr_val;
+	struct branch_clk *bclk = to_branch_clk(clk);
+
+	cbcr_val  = readl(bclk->cbcr_reg);
+	cbcr_val |= CBCR_BRANCH_ENABLE_BIT;
+	writel(cbcr_val, bclk->cbcr_reg);
+
+	/* wait until status shows it is enabled */
+	while(readl(bclk->cbcr_reg) & CBCR_BRANCH_OFF_BIT);
+
+	return rc;
+}
+
+/* Branch clock disable */
+void clock_lib2_branch_clk_disable(struct clk *clk)
+{
+	uint32_t cbcr_val;
+	struct branch_clk *bclk = to_branch_clk(clk);
+
+	cbcr_val  = readl(bclk->cbcr_reg);
+	cbcr_val &= ~CBCR_BRANCH_ENABLE_BIT;
+	writel(cbcr_val, bclk->cbcr_reg);
+
+	/* wait until status shows it is disabled */
+	while(!(readl(bclk->cbcr_reg) & CBCR_BRANCH_OFF_BIT));
+}
+
+/* Branch clock set rate */
+int clock_lib2_branch_set_rate(struct clk *c, unsigned rate)
+{
+	struct branch_clk *branch = to_branch_clk(c);
+
+	if (!branch->has_sibling)
+		return clk_set_rate(branch->parent, rate);
+
+	return -1;
+}
+
+
+/*=============== Root clock ops =============*/
+
+/* Root enable */
+int clock_lib2_rcg_enable(struct clk *c)
+{
+	/* Hardware feedback from branch enable results in root being enabled.
+	 * Nothing to do here.
+	 */
+
+	return 0;
+}
+
+/* Root set rate:
+ * Find the entry in the frequecy table corresponding to the requested rate.
+ * Enable the source clock required for the new frequency.
+ * Call the set_rate function defined for this particular root clock.
+ */
+int clock_lib2_rcg_set_rate(struct clk *c, unsigned rate)
+{
+	struct rcg_clk *rclk = to_rcg_clk(c);
+	struct clk_freq_tbl *nf; /* new freq */
+	int rc = 0;
+
+	/* ck if new freq is in table */
+	for (nf = rclk->freq_tbl; nf->freq_hz != FREQ_END
+			&& nf->freq_hz != rate; nf++)
+		;
+
+	/* Frequency not found in the table */
+	if (nf->freq_hz == FREQ_END)
+		return ERR_INVALID_ARGS;
+
+	/* Check if frequency is actually changed. */
+	if (nf == rclk->current_freq)
+		return rc;
+
+	/* First enable the source clock for this freq. */
+	clk_enable(nf->src_clk);
+
+	/* Perform clock-specific frequency switch operations. */
+	ASSERT(rclk->set_rate);
+	rclk->set_rate(rclk, nf);
+
+	/* update current freq */
+	rclk->current_freq = nf;
+
+	return rc;
+}
+
+/* root update config: informs h/w to start using the new config values */
+static void clock_lib2_rcg_update_config(struct rcg_clk *rclk)
+{
+	uint32_t cmd;
+
+	cmd  = readl(rclk->cmd_reg);
+	cmd |= CMD_UPDATE_BIT;
+	writel(cmd, rclk->cmd_reg);
+
+	/* Wait for frequency to be updated. */
+	while(readl(rclk->cmd_reg) & CMD_UPDATE_MASK);
+}
+
+/* root set rate for clocks with half integer and MND divider */
+void clock_lib2_rcg_set_rate_mnd(struct rcg_clk *rclk, struct clk_freq_tbl *freq)
+{
+	uint32_t cfg;
+
+	/* Program MND values */
+	writel(freq->m_val, rclk->m_reg);
+	writel(freq->n_val, rclk->n_reg);
+	writel(freq->d_val, rclk->d_reg);
+
+	/* setup src select and divider */
+	cfg  = readl(rclk->cfg_reg);
+	cfg &= ~(CFG_SRC_SEL_MASK | CFG_SRC_DIV_MASK | CFG_MODE_MASK);
+	cfg |= freq->div_src_val;
+	if(freq->n_val !=0)
+	{
+		cfg |= (CFG_MODE_DUAL_EDGE << CFG_MODE_OFFSET);
+	}
+	writel(cfg, rclk->cfg_reg);
+
+	/* Inform h/w to start using the new config. */
+	clock_lib2_rcg_update_config(rclk);
+}
+
+/* root set rate for clocks with half integer divider */
+void clock_lib2_rcg_set_rate_hid(struct rcg_clk *rclk, struct clk_freq_tbl *freq)
+{
+	uint32_t cfg;
+
+	/* setup src select and divider */
+	cfg  = readl(rclk->cfg_reg);
+	cfg &= ~(CFG_SRC_SEL_MASK | CFG_SRC_DIV_MASK);
+	cfg |= freq->div_src_val;
+	writel(cfg, rclk->cfg_reg);
+
+	clock_lib2_rcg_update_config(rclk);
+}
diff --git a/platform/msm_shared/include/clock.h b/platform/msm_shared/include/clock.h
index 13b62ac..8f1fd11 100644
--- a/platform/msm_shared/include/clock.h
+++ b/platform/msm_shared/include/clock.h
@@ -71,6 +71,7 @@
  */
 struct clk {
 	uint32_t flags;
+	uint32_t rate;
 	struct clk_ops *ops;
 	const char *dbg_name;
 	unsigned count;
diff --git a/platform/msm_shared/include/clock_lib2.h b/platform/msm_shared/include/clock_lib2.h
new file mode 100644
index 0000000..0b6dbae
--- /dev/null
+++ b/platform/msm_shared/include/clock_lib2.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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 Code Aurora 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 __CLOCK_LIB2_H
+#define __CLOCK_LIB2_H
+
+/*
+ * Bit manipulation macros
+ */
+#define BIT(n)              (1 << (n))
+#define BM(msb, lsb)        (((((uint32_t)-1) << (31-msb)) >> (31-msb+lsb)) << lsb)
+#define BVAL(msb, lsb, val) (((val) << lsb) & BM(msb, lsb))
+
+#define container_of(ptr, type, member) \
+        ((type *)((addr_t)(ptr) - offsetof(type, member)))
+
+/* Frequency Macros */
+#define FREQ_END        (UINT_MAX-1)
+#define F_END \
+        { \
+                .freq_hz = FREQ_END, \
+        }
+
+/* F(frequency, source, div, m, n) */
+#define F(f, s, div, m, n) \
+        { \
+                .freq_hz = (f), \
+                .src_clk = &s##_clk_src.c, \
+                .m_val   = (m), \
+                .n_val   = ~((n)-(m)), \
+                .d_val   = ~(n),\
+                .div_src_val = BVAL(4, 0, (int)(2*(div) - 1)) \
+                              | BVAL(10, 8, s##_source_val), \
+        }
+
+
+/* Branch Clock Bits */
+#define CBCR_BRANCH_ENABLE_BIT  BIT(0)
+#define CBCR_BRANCH_OFF_BIT     BIT(31)
+
+/* Root Clock Bits */
+#define CMD_UPDATE_BIT          BIT(0)
+#define CMD_UPDATE_MASK         1
+
+#define CFG_SRC_DIV_OFFSET      0
+#define CFG_SRC_DIV_MASK        (0x1F << CFG_SRC_DIV_OFFSET)
+
+#define CFG_SRC_SEL_OFFSET      8
+#define CFG_SRC_SEL_MASK        (0x3 << CFG_SRC_SEL_OFFSET)
+
+#define CFG_MODE_DUAL_EDGE      0x2
+
+#define CFG_MODE_OFFSET         12
+#define CFG_MODE_MASK           (0x3 << CFG_MODE_OFFSET)
+
+
+/*
+ * Generic frequency-definition structs and macros
+ */
+struct clk_freq_tbl {
+
+	const uint32_t  freq_hz;
+	struct clk     *src_clk;
+	const uint32_t  div_src_val;
+
+	/* TODO: find out if sys_vdd is needed. */
+
+	const uint32_t  m_val;
+	const uint32_t  n_val; /* not_n_minus_m_val */
+	const uint32_t  d_val; /* not_2d_val        */
+};
+
+/* Fixed clock */
+struct fixed_clk {
+	struct clk c;
+};
+
+/* Branch clock */
+struct branch_clk {
+
+	uint32_t *const bcr_reg;
+	uint32_t *const cbcr_reg;
+
+	void   (*set_rate)(struct branch_clk *, struct clk_freq_tbl *);
+
+	struct clk *parent;
+	struct clk  c;
+
+	int      has_sibling;
+	uint32_t cur_div;
+	uint32_t max_div;
+	uint32_t halt_check;
+};
+
+/* Root Clock */
+struct rcg_clk {
+
+	/* RCG registers for this clock */
+
+	uint32_t *const cmd_reg; /* Command reg */
+	uint32_t *const cfg_reg; /* Config  reg */
+	uint32_t *const m_reg;   /*       m     */
+	uint32_t *const n_reg;   /* not (n-m)   */
+	uint32_t *const d_reg;   /* not (2d)    */
+
+	/* set rate function for this clock */
+	void   (*set_rate)(struct rcg_clk *, struct clk_freq_tbl *);
+
+	/* freq table */
+	struct clk_freq_tbl *const freq_tbl;
+	struct clk_freq_tbl *current_freq;
+
+	struct clk c;
+};
+
+static inline struct rcg_clk *to_rcg_clk(struct clk *clk)
+{
+	return container_of(clk, struct rcg_clk, c);
+}
+
+static inline struct branch_clk *to_branch_clk(struct clk *clk)
+{
+	return container_of(clk, struct branch_clk, c);
+}
+
+/* RCG clock functions */
+int  clock_lib2_rcg_enable(struct clk *c);
+int  clock_lib2_rcg_set_rate(struct clk *c, unsigned rate);
+void clock_lib2_rcg_set_rate_mnd(struct rcg_clk *rclk, struct clk_freq_tbl *freq);
+void clock_lib2_rcg_set_rate_hid(struct rcg_clk *rclk, struct clk_freq_tbl *freq);
+
+/* CXO clock functions */
+int  cxo_clk_enable(struct clk *clk);
+void cxo_clk_disable(struct clk *clk);
+
+/* Branch clock functions */
+int  clock_lib2_branch_clk_enable(struct clk *clk);
+void clock_lib2_branch_clk_disable(struct clk *clk);
+int  clock_lib2_branch_set_rate(struct clk *c, unsigned rate);
+
+#endif
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index 3feea2a..8abd230 100644
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -62,6 +62,9 @@
 			$(LOCAL_DIR)/qtimer.o \
 			$(LOCAL_DIR)/qtimer_cp15.o \
 			$(LOCAL_DIR)/interrupts.o \
+			$(LOCAL_DIR)/clock.o \
+			$(LOCAL_DIR)/clock_pll.o \
+			$(LOCAL_DIR)/clock_lib2.o \
 			$(LOCAL_DIR)/uart_dm.o
 endif
 
diff --git a/target/copper/init.c b/target/copper/init.c
index 0ec02ac..2630ad1 100644
--- a/target/copper/init.c
+++ b/target/copper/init.c
@@ -1,7 +1,5 @@
 /*
- * Copyright (c) 2009, Google Inc.
- * All rights reserved.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -36,6 +34,7 @@
 #include <target.h>
 #include <platform.h>
 #include <uart_dm.h>
+#include <mmc.h>
 
 static unsigned int target_id;
 extern void dmb(void);
@@ -49,7 +48,7 @@
 
 void target_early_init(void)
 {
-
+	uart_dm_init(0, 0, BLSP1_UART0_BASE);
 }
 
 void target_init(void)
@@ -57,7 +56,6 @@
 	uint32_t base_addr;
 	uint8_t slot;
 
-	uart_dm_init(0, 0, BLSP1_UART0_BASE);
 
 	dprintf(INFO, "target_init()\n");
 
@@ -77,7 +75,6 @@
 			ASSERT(0);
 		}
 	}
-
 }
 
 unsigned board_machtype(void)