mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-09 05:05:20 -05:00
as3525v2-usb:
- use uncached address to access setup packet - implement driver exit - stop forcing full speed - change fifo sizes on init - don't call invalid_dache() on setup packet because it makes everything fail git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28027 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
5a329ded5c
commit
025112fc7b
1 changed files with 35 additions and 56 deletions
|
|
@ -99,7 +99,10 @@ enum ep0state
|
||||||
/* endpoints[ep_num][DIR_IN/DIR_OUT] */
|
/* endpoints[ep_num][DIR_IN/DIR_OUT] */
|
||||||
static struct usb_endpoint endpoints[USB_NUM_ENDPOINTS][2];
|
static struct usb_endpoint endpoints[USB_NUM_ENDPOINTS][2];
|
||||||
/* setup packet for EP0 */
|
/* setup packet for EP0 */
|
||||||
static struct usb_ctrlrequest ep0_setup_pkt __attribute__((aligned(32)));
|
static struct usb_ctrlrequest __ep0_setup_pkt __attribute__((aligned(32)));
|
||||||
|
static struct usb_ctrlrequest *_ep0_setup_pkt = AS3525_UNCACHED_ADDR(&__ep0_setup_pkt);
|
||||||
|
|
||||||
|
#define ep0_setup_pkt (*_ep0_setup_pkt)
|
||||||
/* state of EP0 */
|
/* state of EP0 */
|
||||||
static enum ep0state ep0_state;
|
static enum ep0state ep0_state;
|
||||||
|
|
||||||
|
|
@ -126,10 +129,11 @@ static void as3525v2_connect(void)
|
||||||
bitset32(&CGU_PERI, CGU_USB_CLOCK_ENABLE);
|
bitset32(&CGU_PERI, CGU_USB_CLOCK_ENABLE);
|
||||||
usb_delay();
|
usb_delay();
|
||||||
/* 2) enable usb phy clock */
|
/* 2) enable usb phy clock */
|
||||||
|
CCU_USB = (CCU_USB & ~(3<<24)) | (1 << 24); /* ?? */
|
||||||
/* PHY clock */
|
/* PHY clock */
|
||||||
CGU_USB = 1<<5 /* enable */
|
CGU_USB = 1<<5 /* enable */
|
||||||
| (CLK_DIV(AS3525_PLLA_FREQ, 60000000)) << 2
|
| 0 << 2
|
||||||
| 1; /* source = PLLA */
|
| 0; /* source = PLLA */
|
||||||
usb_delay();
|
usb_delay();
|
||||||
/* 3) clear "stop pclk" */
|
/* 3) clear "stop pclk" */
|
||||||
PCGCCTL &= ~0x1;
|
PCGCCTL &= ~0x1;
|
||||||
|
|
@ -168,6 +172,10 @@ static void as3525v2_connect(void)
|
||||||
|
|
||||||
static void as3525v2_disconnect(void)
|
static void as3525v2_disconnect(void)
|
||||||
{
|
{
|
||||||
|
/* Disable clock */
|
||||||
|
CGU_USB = 0;
|
||||||
|
usb_delay();
|
||||||
|
bitclr32(&CGU_PERI, CGU_USB_CLOCK_ENABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void enable_device_interrupts(void)
|
static void enable_device_interrupts(void)
|
||||||
|
|
@ -201,27 +209,12 @@ static void flush_tx_fifos(int nums)
|
||||||
udelay(1);
|
udelay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flush_rx_fifo(void)
|
|
||||||
{
|
|
||||||
unsigned int i = 0;
|
|
||||||
|
|
||||||
GRSTCTL = GRSTCTL_rxfflsh_flush;
|
|
||||||
while(GRSTCTL & GRSTCTL_rxfflsh_flush && i < 0x300)
|
|
||||||
i++;
|
|
||||||
if(GRSTCTL & GRSTCTL_rxfflsh_flush)
|
|
||||||
panicf("usb-drv: hang of flush rx fifo");
|
|
||||||
/* wait 3 phy clocks */
|
|
||||||
udelay(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void prepare_setup_ep0(void)
|
static void prepare_setup_ep0(void)
|
||||||
{
|
{
|
||||||
logf("usb-drv: prepare EP0");
|
logf("usb-drv: prepare EP0");
|
||||||
/* setup DMA */
|
/* setup DMA */
|
||||||
//memset(&ep0_setup_pkt, 0, sizeof ep0_setup_pkt);
|
clean_dcache_range((void*)&ep0_setup_pkt, sizeof ep0_setup_pkt); /* force write back */
|
||||||
//clean_dcache_range((void*)&ep0_setup_pkt, sizeof ep0_setup_pkt); /* force write back */
|
DOEPDMA(0) = (unsigned long)AS3525_PHYSICAL_ADDR(&__ep0_setup_pkt); /* virtual address=physical address */
|
||||||
clean_dcache();
|
|
||||||
DOEPDMA(0) = (unsigned long)AS3525_PHYSICAL_ADDR(&ep0_setup_pkt); /* virtual address=physical address */
|
|
||||||
|
|
||||||
/* Setup EP0 OUT with the following parameters:
|
/* Setup EP0 OUT with the following parameters:
|
||||||
* packet count = 1
|
* packet count = 1
|
||||||
|
|
@ -319,8 +312,6 @@ static void reset_endpoints(void)
|
||||||
/* 64 bytes packet size, active endpoint */
|
/* 64 bytes packet size, active endpoint */
|
||||||
DOEPCTL(0) = (DEPCTL_MPS_64 << DEPCTL_mps_bitp) | DEPCTL_usbactep | DEPCTL_snak;
|
DOEPCTL(0) = (DEPCTL_MPS_64 << DEPCTL_mps_bitp) | DEPCTL_usbactep | DEPCTL_snak;
|
||||||
DIEPCTL(0) = (DEPCTL_MPS_64 << DEPCTL_mps_bitp) | DEPCTL_usbactep | DEPCTL_snak;
|
DIEPCTL(0) = (DEPCTL_MPS_64 << DEPCTL_mps_bitp) | DEPCTL_usbactep | DEPCTL_snak;
|
||||||
|
|
||||||
prepare_setup_ep0();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cancel_all_transfers(bool cancel_ep0)
|
static void cancel_all_transfers(bool cancel_ep0)
|
||||||
|
|
@ -354,7 +345,7 @@ static void core_dev_init(void)
|
||||||
/* Restart the phy clock */
|
/* Restart the phy clock */
|
||||||
PCGCCTL = 0;
|
PCGCCTL = 0;
|
||||||
/* Set phy speed : high speed */
|
/* Set phy speed : high speed */
|
||||||
DCFG = (DCFG & ~bitm(DCFG, devspd)) | DCFG_devspd_hs_phy_fs;
|
DCFG = (DCFG & ~bitm(DCFG, devspd)) | DCFG_devspd_hs_phy_hs;
|
||||||
|
|
||||||
/* Check hardware capabilities */
|
/* Check hardware capabilities */
|
||||||
if(extract(GHWCFG2, arch) != GHWCFG2_ARCH_INTERNAL_DMA)
|
if(extract(GHWCFG2, arch) != GHWCFG2_ARCH_INTERNAL_DMA)
|
||||||
|
|
@ -391,6 +382,10 @@ static void core_dev_init(void)
|
||||||
panicf("usb-drv: EP%d is no OUT or BIDIR", ep);
|
panicf("usb-drv: EP%d is no OUT or BIDIR", ep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Setup FIFOs */
|
||||||
|
GRXFSIZ = 1024;
|
||||||
|
GNPTXFSIZ = MAKE_FIFOSIZE_DATA(1024, 1024);
|
||||||
|
|
||||||
/* Setup interrupt masks for endpoints */
|
/* Setup interrupt masks for endpoints */
|
||||||
/* Setup interrupt masks */
|
/* Setup interrupt masks */
|
||||||
DOEPMSK = DOEPINT_setup | DOEPINT_xfercompl | DOEPINT_ahberr;
|
DOEPMSK = DOEPINT_setup | DOEPINT_xfercompl | DOEPINT_ahberr;
|
||||||
|
|
@ -399,6 +394,8 @@ static void core_dev_init(void)
|
||||||
|
|
||||||
reset_endpoints();
|
reset_endpoints();
|
||||||
|
|
||||||
|
prepare_setup_ep0();
|
||||||
|
|
||||||
/* enable USB interrupts */
|
/* enable USB interrupts */
|
||||||
enable_device_interrupts();
|
enable_device_interrupts();
|
||||||
}
|
}
|
||||||
|
|
@ -485,9 +482,7 @@ static void handle_ep_int(int ep, bool dir_in)
|
||||||
logf("len=%d reg=%ld xfer=%d", endpoint->len,
|
logf("len=%d reg=%ld xfer=%d", endpoint->len,
|
||||||
(DIEPTSIZ(ep) & DEPTSIZ_xfersize_bits),
|
(DIEPTSIZ(ep) & DEPTSIZ_xfersize_bits),
|
||||||
transfered);
|
transfered);
|
||||||
//invalidate_dcache_range(endpoint->buffer, transfered);
|
invalidate_dcache_range(endpoint->buffer, transfered);
|
||||||
invalidate_dcache();
|
|
||||||
//DIEPCTL(ep) |= DEPCTL_snak;
|
|
||||||
/* handle EP0 state if necessary,
|
/* handle EP0 state if necessary,
|
||||||
* this is a ack if length is 0 */
|
* this is a ack if length is 0 */
|
||||||
if(ep == 0)
|
if(ep == 0)
|
||||||
|
|
@ -505,7 +500,6 @@ static void handle_ep_int(int ep, bool dir_in)
|
||||||
endpoint->status = 1;
|
endpoint->status = 1;
|
||||||
/* for safety, act as if no bytes as been transfered */
|
/* for safety, act as if no bytes as been transfered */
|
||||||
endpoint->len = 0;
|
endpoint->len = 0;
|
||||||
//DIEPCTL(ep) |= DEPCTL_snak;
|
|
||||||
usb_core_transfer_complete(ep, USB_DIR_IN, 1, 0);
|
usb_core_transfer_complete(ep, USB_DIR_IN, 1, 0);
|
||||||
wakeup_signal(&endpoint->complete);
|
wakeup_signal(&endpoint->complete);
|
||||||
}
|
}
|
||||||
|
|
@ -529,14 +523,11 @@ static void handle_ep_int(int ep, bool dir_in)
|
||||||
logf("len=%d reg=%ld xfer=%d", endpoint->len,
|
logf("len=%d reg=%ld xfer=%d", endpoint->len,
|
||||||
(DOEPTSIZ(ep) & DEPTSIZ_xfersize_bits),
|
(DOEPTSIZ(ep) & DEPTSIZ_xfersize_bits),
|
||||||
transfered);
|
transfered);
|
||||||
//invalidate_dcache_range(endpoint->buffer, transfered);
|
invalidate_dcache_range(endpoint->buffer, transfered);
|
||||||
invalidate_dcache();
|
|
||||||
/* handle EP0 state if necessary,
|
/* handle EP0 state if necessary,
|
||||||
* this is a ack if length is 0 */
|
* this is a ack if length is 0 */
|
||||||
if(ep == 0)
|
if(ep == 0)
|
||||||
handle_ep0_complete(endpoint->len == 0);
|
handle_ep0_complete(endpoint->len == 0);
|
||||||
//else
|
|
||||||
// DOEPCTL(ep) |= DEPCTL_snak;
|
|
||||||
usb_core_transfer_complete(ep, USB_DIR_OUT, 0, transfered);
|
usb_core_transfer_complete(ep, USB_DIR_OUT, 0, transfered);
|
||||||
wakeup_signal(&endpoint->complete);
|
wakeup_signal(&endpoint->complete);
|
||||||
}
|
}
|
||||||
|
|
@ -553,13 +544,10 @@ static void handle_ep_int(int ep, bool dir_in)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//DOEPCTL(ep) |= DEPCTL_snak;
|
|
||||||
/* handle the set address here because of a bug in the usb core */
|
|
||||||
//invalidate_dcache_range((void*)&ep0_setup_pkt, sizeof ep0_setup_pkt);
|
|
||||||
invalidate_dcache();
|
|
||||||
/* handle EP0 state */
|
/* handle EP0 state */
|
||||||
handle_ep0_setup();
|
handle_ep0_setup();
|
||||||
logf(" rt=%x r=%x", ep0_setup_pkt.bRequestType, ep0_setup_pkt.bRequest);
|
logf(" rt=%x r=%x", ep0_setup_pkt.bRequestType, ep0_setup_pkt.bRequest);
|
||||||
|
/* handle set address */
|
||||||
if(ep0_setup_pkt.bRequestType == USB_TYPE_STANDARD &&
|
if(ep0_setup_pkt.bRequestType == USB_TYPE_STANDARD &&
|
||||||
ep0_setup_pkt.bRequest == USB_REQ_SET_ADDRESS)
|
ep0_setup_pkt.bRequest == USB_REQ_SET_ADDRESS)
|
||||||
usb_drv_set_address(ep0_setup_pkt.wValue);
|
usb_drv_set_address(ep0_setup_pkt.wValue);
|
||||||
|
|
@ -605,13 +593,16 @@ void INT_USB(void)
|
||||||
|
|
||||||
/* Flush FIFOs */
|
/* Flush FIFOs */
|
||||||
flush_tx_fifos(0x10);
|
flush_tx_fifos(0x10);
|
||||||
flush_rx_fifo();
|
|
||||||
|
|
||||||
reset_endpoints();
|
/* Flush the Learning Queue */
|
||||||
|
GRSTCTL = GRSTCTL_intknqflsh;
|
||||||
|
|
||||||
/* Reset Device Address */
|
/* Reset Device Address */
|
||||||
DCFG &= ~bitm(DCFG, devadr);
|
DCFG &= ~bitm(DCFG, devadr);
|
||||||
|
|
||||||
|
reset_endpoints();
|
||||||
|
prepare_setup_ep0();
|
||||||
|
|
||||||
usb_core_bus_reset();
|
usb_core_bus_reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -624,19 +615,6 @@ void INT_USB(void)
|
||||||
logf("usb-drv: HS");
|
logf("usb-drv: HS");
|
||||||
else
|
else
|
||||||
logf("usb-drv: FS");
|
logf("usb-drv: FS");
|
||||||
|
|
||||||
/* fixme: change EP0 mps here */
|
|
||||||
prepare_setup_ep0();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(sts & GINTMSK_usbsuspend)
|
|
||||||
{
|
|
||||||
logf("usb-drv: suspend");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(sts & GINTMSK_wkupintr)
|
|
||||||
{
|
|
||||||
logf("usb-drv: wake up");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sts & GINTMSK_otgintr)
|
if(sts & GINTMSK_otgintr)
|
||||||
|
|
@ -721,9 +699,6 @@ static int usb_drv_transfer(int ep, void *ptr, int len, bool dir_in, bool blocki
|
||||||
if(endpoint->busy)
|
if(endpoint->busy)
|
||||||
logf("usb-drv: EP%d %s is already busy", ep, dir_in ? "IN" : "OUT");
|
logf("usb-drv: EP%d %s is already busy", ep, dir_in ? "IN" : "OUT");
|
||||||
|
|
||||||
if(dir_in)
|
|
||||||
logf("GNPTXSTS=%lx", GNPTXSTS);
|
|
||||||
|
|
||||||
endpoint->busy = true;
|
endpoint->busy = true;
|
||||||
endpoint->len = len;
|
endpoint->len = len;
|
||||||
endpoint->wait = blocking;
|
endpoint->wait = blocking;
|
||||||
|
|
@ -732,12 +707,16 @@ static int usb_drv_transfer(int ep, void *ptr, int len, bool dir_in, bool blocki
|
||||||
int nb_packets = (len + mps - 1) / mps;
|
int nb_packets = (len + mps - 1) / mps;
|
||||||
|
|
||||||
if(len == 0)
|
if(len == 0)
|
||||||
|
{
|
||||||
|
DEPDMA = 0x10000000;
|
||||||
DEPTSIZ = 1 << DEPTSIZ_pkcnt_bitp;
|
DEPTSIZ = 1 << DEPTSIZ_pkcnt_bitp;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
DEPTSIZ = (nb_packets << DEPTSIZ_pkcnt_bitp) | len;
|
{
|
||||||
//clean_dcache_range(ptr, len);
|
clean_dcache_range(ptr, len);
|
||||||
clean_dcache();
|
|
||||||
DEPDMA = (unsigned long)AS3525_PHYSICAL_ADDR(ptr);
|
DEPDMA = (unsigned long)AS3525_PHYSICAL_ADDR(ptr);
|
||||||
|
DEPTSIZ = (nb_packets << DEPTSIZ_pkcnt_bitp) | len;
|
||||||
|
}
|
||||||
|
|
||||||
logf("pkt=%d dma=%lx", nb_packets, DEPDMA);
|
logf("pkt=%d dma=%lx", nb_packets, DEPDMA);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue