From 22cfbee27489d3658ab2155c65bcdfedce7e750c Mon Sep 17 00:00:00 2001 From: Amaury Pouly Date: Tue, 18 May 2010 09:58:52 +0000 Subject: as3525v2: add usb driver stub, enable usb phy&core init clip+: add USBOTG_ define and enable usb stack git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26132 a1c6a512-1295-4272-9138-f99709370657 --- firmware/target/arm/as3525/usb-drv-as3525v2.c | 261 ++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 firmware/target/arm/as3525/usb-drv-as3525v2.c (limited to 'firmware/target/arm/as3525/usb-drv-as3525v2.c') diff --git a/firmware/target/arm/as3525/usb-drv-as3525v2.c b/firmware/target/arm/as3525/usb-drv-as3525v2.c new file mode 100644 index 0000000000..9afe8255e5 --- /dev/null +++ b/firmware/target/arm/as3525/usb-drv-as3525v2.c @@ -0,0 +1,261 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright © 2010 Amaury Pouly + * + * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "usb.h" +#include "usb_drv.h" +#include "as3525v2.h" +#include "clock-target.h" +#include "ascodec.h" +#include "as3514.h" +#include +#include "panic.h" +#define LOGF_ENABLE +#include "logf.h" +#include "usb-drv-as3525v2.h" + +struct usb_endpoint +{ + void *buf; + unsigned int len; + union + { + unsigned int sent; + unsigned int received; + }; + bool wait; + bool busy; +}; + +static struct usb_endpoint endpoints[USB_NUM_ENDPOINTS*2]; + +void usb_attach(void) +{ + usb_enable(true); +} + +static void usb_delay(void) +{ + int i = 0; + while(i < 0x300) + i++; +} + +static void as3525v2_connect(void) +{ + logf("usb: init as3525v2"); + /* 1) enable usb core clock */ + CGU_PERI |= CGU_USB_CLOCK_ENABLE; + usb_delay(); + /* 2) enable usb phy clock */ + CGU_USB |= 0x20; + usb_delay(); + /* 3) clear "stop pclk" */ + USB_PCGCCTL &= ~0x1; + usb_delay(); + /* 4) clear "power clamp" */ + USB_PCGCCTL &= ~0x4; + usb_delay(); + /* 5) clear "reset power down module" */ + USB_PCGCCTL &= ~0x8; + usb_delay(); + /* 6) set "power on program done" */ + USB_DCTL |= 0x800; + usb_delay(); + /* 7) core soft reset */ + USB_GRSTCTL |= USB_GRSTCTL_csftrst; + usb_delay(); + /* 8) hclk soft reset */ + USB_GRSTCTL |= USB_GRSTCTL_hsftrst; + usb_delay(); + /* 9) flush and reset everything */ + USB_GRSTCTL |= 0x3f; + usb_delay(); + /* 10) force device mode*/ + USB_GUSBCFG &= ~0x20000000; + USB_GUSBCFG |= 0x40000000; + usb_delay(); + /* 11) Do something that is probably CCU related but undocumented*/ + CCU_USB_THINGY &= ~0x1000; + usb_delay(); + /* 12) reset usb core parameters (dev addr, speed, ...) */ + USB_DCFG = 0; + usb_delay(); +} + +static void core_reset(void) +{ + unsigned int i = 0; + /* Wait for AHB master IDLE state. */ + while((USB_GRSTCTL & USB_GRSTCTL_ahbidle) == 0); + { + /*udelay(10);*/ + sleep(1); + } + /* Core Soft Reset */ + USB_GRSTCTL |= USB_GRSTCTL_csftrst; + /* Waits for the hardware to clear reset bit */ + while(USB_GRSTCTL & USB_GRSTCTL_csftrst && i < 0x300) + i++; + + if(USB_GRSTCTL & USB_GRSTCTL_csftrst) + logf("oops, usb core soft reset hang :("); + + /* Wait for 3 PHY Clocks */ + /*mdelay(100);*/ + sleep(1); + + logf("%ld endpoints", USB_GHWCFG2_NUM_EP); + for(i = 0; i < USB_GHWCFG2_NUM_EP; i++) + logf(" EP%d: IN=%ld OUT=%ld", i, USB_GHWCFG1_IN_EP(i), USB_GHWCFG1_OUT_EP(i)); + logf("hwcfg1: %08lx", USB_GHWCFG1); + logf("hwcfg2: %08lx", USB_GHWCFG2); + logf("hwcfg3: %08lx", USB_GHWCFG3); + logf("hwcfg4: %08lx", USB_GHWCFG4); + + logf("%ld in ep", USB_GHWCFG4_NUM_IN_EP); + logf("tot fifo sz: %ld", USB_GHWCFG3_DFIFO_LEN); + logf("rx fifo sz: %ld", USB_GRXFSIZ); + logf("tx fifo sz: %ld", USB_GNPTXFSIZ >> 16); /* there is no perio ep so print only non-perio */ +} + +static void core_init(void) +{ + /* Reset the Controller */ + core_reset(); + + /* Setup phy for high speed */ + /* 1) select utmi */ + /* fixme: the clip+ hardware support utmi only, this is useless */ + //USB_GUSBCFG &= ~USB_GUSBCFG_ulpi_utmi_sel; + /* 2) select utmi 16-bit wide bus */ + USB_GUSBCFG |= USB_GUSBCFG_phy_if; + /* 3) core reset */ + /* fixme: linux patch says the phy parameters survive the soft reset so + * perhaps this part can be done only one type but I don't know + * what happened when phy goes to standby mode and clock are disabled */ + core_reset(); + + /* fixme: at this point, the linux patch sets ulpi bits to 0 on utmi selection + * but the clip+ hardware does not support it so don't bother with + * that */ + + /* fixme: the current code is for internal DMA only, the clip+ architecture + * define the internal DMA model */ + /* Set burstlen */ + USB_GAHBCFG |= USB_GAHBCFG_INT_DMA_BURST_INCR << USB_GAHBCFG_hburstlen_bit_pos; + /* Enable DMA */ + USB_GAHBCFG |= USB_GAHBCFG_dma_enable; + /* Disable HNP and SRP, not sure it's useful because we already forced dev mode */ + USB_GUSBCFG &= ~(USB_GUSBCFG_SRP_cap | USB_GUSBCFG_HNP_cap); +} + +void usb_drv_init(void) +{ + logf("usb_drv_init"); + as3525v2_connect(); + + logf("usb: synopsis id: %lx", USB_GSNPSID); + + core_init(); +} + +void usb_drv_exit(void) +{ + logf("usb_drv_exit"); +} + +int usb_drv_port_speed(void) +{ + return 0; +} + +int usb_drv_request_endpoint(int type, int dir) +{ + (void) type; + (void) dir; + return -1; +} + +void usb_drv_release_endpoint(int ep) +{ + (void) ep; +} + +void usb_drv_cancel_all_transfers(void) +{ +} + +int usb_drv_recv(int ep, void *ptr, int len) +{ + (void) ep; + (void) ptr; + (void) len; + return -1; +} + +int usb_drv_send(int ep, void *ptr, int len) +{ + (void) ep; + (void) ptr; + (void) len; + return -1; +} + +int usb_drv_send_nonblocking(int ep, void *ptr, int len) +{ + (void) ep; + (void) ptr; + (void) len; + return -1; +} + +/* interrupt service routine */ +void INT_USB(void) +{ + panicf("USB interrupt !"); +} + +/* (not essential? , not implemented in usb-tcc.c) */ +void usb_drv_set_test_mode(int mode) +{ + (void) mode; +} + +void usb_drv_set_address(int address) +{ + (void) address; +} + +void usb_drv_stall(int ep, bool stall, bool in) +{ + (void) ep; + (void) stall; + (void) in; +} + +bool usb_drv_stalled(int ep, bool in) +{ + (void) ep; + (void) in; + return true; + return true; +} + -- cgit v1.2.3