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)