aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/musb/rda.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/musb/rda.c')
-rw-r--r--drivers/usb/musb/rda.c212
1 files changed, 212 insertions, 0 deletions
diff --git a/drivers/usb/musb/rda.c b/drivers/usb/musb/rda.c
new file mode 100644
index 0000000000..db2dbf52af
--- /dev/null
+++ b/drivers/usb/musb/rda.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2009 Wind River Systems, Inc.
+ * Tom Rix <Tom.Rix@windriver.com>
+ *
+ * This is file is based on
+ * repository git.gitorious.org/u-boot-omap3/mainline.git,
+ * branch omap3-dev-usb, file drivers/usb/host/omap3530_usb.c
+ *
+ * This is the unique part of its copyright :
+ *
+ * ------------------------------------------------------------------------
+ *
+ * Copyright (c) 2009 Texas Instruments
+ *
+ * ------------------------------------------------------------------------
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+#include "rda.h"
+#include <asm/arch/reg_sysctrl.h>
+#include <asm/arch/hwcfg.h>
+#include <asm/arch/rda_sys.h>
+#include "musb_core.h"
+
+#define MONITOR_REG (MUSB_BASE + 0x80)
+#define MONITOR_TRIG_REG (MUSB_BASE + 0x84)
+#define UDC_PHY_CLK_REG (MUSB_BASE + 0x8c)
+
+struct musb_config musb_cfg = {
+ .regs = (struct musb_regs *)MUSB_BASE,
+ .timeout = RDA_FPGA_USB_TIMEOUT,
+ .musb_speed = 0,
+};
+
+static void udc_soft_reset(void)
+{
+ serial_printf("reset musb otg core...\n");
+ hwp_sysCtrlAp->AHB1_Rst_Set = SYS_CTRL_AP_SET_AHB1_RST_USBC;
+ udelay(1000);
+ hwp_sysCtrlAp->AHB1_Rst_Clr = SYS_CTRL_AP_CLR_AHB1_RST_USBC;
+}
+/*
+static void set_udc_monitor(int testcase)
+{
+ u32 value;
+
+ serial_printf("monitor trigger offset :%x \n", MONITOR_TRIG_REG);
+ value = 0x100 | (testcase & 0xff);
+ serial_printf("monitor trigger value :%x \n", value);
+ writel(value, MONITOR_TRIG_REG);
+
+ serial_printf("monitor offset :%x, result : %x\n", MONITOR_REG, readl(MONITOR_REG));
+}
+*/
+void udc_power_on(void)
+{
+}
+
+void udc_power_off(void)
+{
+}
+
+/*
+ udc maybe initialized by other module,always by ROM code
+ */
+int udc_is_initialized(void)
+{
+ /* some hacks for 8850E U02 USB issue, remove them in future. */
+#if defined(CONFIG_MACH_RDA8850E)
+ /* pdl1 always do hardware usb init */
+#if defined(CONFIG_SPL_BUILD) && \
+ defined(CONFIG_RDA_PDL)
+ return 0;
+#endif
+ /* u-boot calib/autocall/pdl2 mode, need to do hardware usb init */
+#ifndef CONFIG_RDA_PDL
+ return 0;
+#endif
+#endif
+
+ return rda_bm_is_download();
+}
+
+static void udc_setup_pll(void)
+{
+ unsigned mask;
+ unsigned locked;
+ int cnt = 10; //timeout is in ms;
+
+ hwp_sysCtrlAp->Cfg_Pll_Ctrl[3] =
+ SYS_CTRL_AP_AP_PLL_ENABLE_ENABLE |
+ SYS_CTRL_AP_AP_PLL_LOCK_RESET_NO_RESET |
+ SYS_CTRL_AP_AP_PLL_LOCK_NUM_LOW(6)
+ | SYS_CTRL_AP_AP_PLL_LOCK_NUM_HIGH(30);
+
+ mask = SYS_CTRL_AP_PLL_LOCKED_USB_MASK;
+
+ locked = SYS_CTRL_AP_PLL_LOCKED_USB_LOCKED;
+
+ while (((hwp_sysCtrlAp->Sel_Clock & mask) != locked) && cnt) {
+ mdelay(1);
+ cnt--;
+ }
+ if (cnt == 0)
+ printf("ERROR, cannot lock usb pll\n");
+}
+
+static void musb_phy_init(void)
+{
+ udc_setup_pll();
+ /*
+ if (rda_metal_id_get() == 0) {
+ writel(0xf001, UDC_PHY_CLK_REG);
+ } else if (rda_metal_id_get() == 1) {
+ writel(0x5900f000, UDC_PHY_CLK_REG);
+ }
+ */
+}
+
+int musb_platform_init(void)
+{
+ udc_soft_reset();
+ musb_phy_init();
+
+ return 0;
+}
+
+void musb_platform_deinit(void)
+{
+ /* noop */
+}
+
+void print_reg(void)
+{
+ u8 power;
+ u8 testmode;
+ u8 devctl;
+ musbr = musb_cfg.regs;
+ power = readb(&musbr->power);
+ testmode = readb(&musbr->testmode);
+ devctl = readb(&musbr->devctl);
+ printf("usb power: %x \n",power);
+ printf("usb testmode: %x \n",testmode);
+ printf("usb devctl: %x \n",devctl);
+}
+
+int do_usb_test(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
+{
+ u8 devctl;
+ u8 test;
+ if (argc < 2 || argc > 3)
+ return CMD_RET_USAGE;
+ if (argc == 2) {
+ if (strcmp(argv[1],"init") == 0) {
+ musbr = musb_cfg.regs;
+ musb_platform_init();
+ musb_start();
+ devctl = readb(&musbr->devctl);
+ devctl |= MUSB_DEVCTL_SESSION;
+ writeb(devctl,&musbr->devctl);
+ printf("usb init finish\n");;
+ } else if (strcmp(argv[1],"j") == 0) {
+ test = readb(&musbr->testmode);
+ test &= ~(MUSB_TEST_K | MUSB_TEST_J);
+ test |= MUSB_TEST_J;
+ writeb(test,&musbr->testmode);
+ printf("usb test_j finish\n");
+ } else if (strcmp(argv[1],"k") == 0) {
+ test = readb(&musbr->testmode);
+ test &= ~(MUSB_TEST_K | MUSB_TEST_J);
+ test |= MUSB_TEST_K;
+ writeb(test,&musbr->testmode);
+ printf("usb test_k finish\n");
+ } else if (strcmp(argv[1],"host") == 0) {
+ writeb(MUSB_POWER_HSENAB,&musbr->power);
+ test = MUSB_TEST_FORCE_HOST | MUSB_TEST_FORCE_HS;
+ writeb(test,&musbr->testmode);
+ printf("usb force host finish\n");
+ } else {
+ printf("error argument!\n");
+ return CMD_RET_USAGE;
+ }
+#ifdef USB_TEST_DEBUG
+ print_reg();
+#endif
+ }
+ return 0;
+}
+
+U_BOOT_CMD(
+ usb_test, 2, 1, do_usb_test,
+ "rda usb slave test",
+ "[init, j, k, host]\n"
+ " -init: USB INIT\n"
+ " -j: TEST_J\n"
+ " -k: TEST_k\n"
+ " -host: FORCE_HOST\n"
+);