mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-09 13:15:18 -05:00
as3525v2-usb: add support to derive usb clock from pllb, correct endpoint listing, simplify a few things.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27031 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
7d46f4e251
commit
2a25910541
2 changed files with 58 additions and 23 deletions
|
|
@ -81,6 +81,29 @@ static void usb_delay(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if AS3525_MCLK_SEL != AS3525_CLK_PLLB
|
||||||
|
static inline void usb_enable_pll(void)
|
||||||
|
{
|
||||||
|
CGU_COUNTB = CGU_LOCK_CNT;
|
||||||
|
CGU_PLLB = AS3525_PLLB_SETTING;
|
||||||
|
CGU_PLLBSUP = 0; /* enable PLLB */
|
||||||
|
while(!(CGU_INTCTRL & CGU_PLLB_LOCK)); /* wait until PLLB is locked */
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void usb_disable_pll(void)
|
||||||
|
{
|
||||||
|
CGU_PLLBSUP = CGU_PLL_POWERDOWN;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline void usb_enable_pll(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void usb_disable_pll(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif /* AS3525_MCLK_SEL != AS3525_CLK_PLLB */
|
||||||
|
|
||||||
static void as3525v2_connect(void)
|
static void as3525v2_connect(void)
|
||||||
{
|
{
|
||||||
logf("usb: init as3525v2");
|
logf("usb: init as3525v2");
|
||||||
|
|
@ -88,7 +111,15 @@ static void as3525v2_connect(void)
|
||||||
CGU_PERI |= CGU_USB_CLOCK_ENABLE;
|
CGU_PERI |= CGU_USB_CLOCK_ENABLE;
|
||||||
usb_delay();
|
usb_delay();
|
||||||
/* 2) enable usb phy clock */
|
/* 2) enable usb phy clock */
|
||||||
CGU_USB |= 0x20;
|
/* PHY clock */
|
||||||
|
#if 0
|
||||||
|
usb_enable_pll();
|
||||||
|
CGU_USB = 1<<5 /* enable */
|
||||||
|
| (CLK_DIV(AS3525_PLLB_FREQ, 48000000) / 2) << 2
|
||||||
|
| 2; /* source = PLLB */
|
||||||
|
#else
|
||||||
|
CGU_USB = 0x20;
|
||||||
|
#endif
|
||||||
usb_delay();
|
usb_delay();
|
||||||
/* 3) clear "stop pclk" */
|
/* 3) clear "stop pclk" */
|
||||||
PCGCCTL &= ~0x1;
|
PCGCCTL &= ~0x1;
|
||||||
|
|
@ -144,9 +175,8 @@ static void flush_tx_fifos(int nums)
|
||||||
{
|
{
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
|
|
||||||
GRSTCTL = (GRSTCTL & ~bitm(GRSTCTL, txfnum))
|
GRSTCTL = (nums << GRSTCTL_txfnum_bitp)
|
||||||
| (nums << GRSTCTL_txfnum_bitp)
|
| GRSTCTL_txfflsh_flush;
|
||||||
| GRSTCTL_txfflsh_flush;
|
|
||||||
while(GRSTCTL & GRSTCTL_txfflsh_flush && i < 0x300)
|
while(GRSTCTL & GRSTCTL_txfflsh_flush && i < 0x300)
|
||||||
i++;
|
i++;
|
||||||
if(GRSTCTL & GRSTCTL_txfflsh_flush)
|
if(GRSTCTL & GRSTCTL_txfflsh_flush)
|
||||||
|
|
@ -178,8 +208,8 @@ static void reset_endpoints(void)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DOEPTSIZ(0) = (1 << DEPTSIZ0_supcnt_bitp)
|
DOEPTSIZ(0) = (1 << DEPTSIZ0_supcnt_bitp)
|
||||||
| (1 << DEPTSIZ0_pkcnt_bitp)
|
| (1 << DEPTSIZ0_pkcnt_bitp)
|
||||||
| 8;
|
| 8;
|
||||||
|
|
||||||
/* setup DMA */
|
/* setup DMA */
|
||||||
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 */
|
||||||
|
|
@ -187,11 +217,11 @@ static void reset_endpoints(void)
|
||||||
|
|
||||||
/* Enable endpoint, clear nak */
|
/* Enable endpoint, clear nak */
|
||||||
DOEPCTL(0) = DEPCTL_epena | DEPCTL_cnak | DEPCTL_usbactep
|
DOEPCTL(0) = DEPCTL_epena | DEPCTL_cnak | DEPCTL_usbactep
|
||||||
| (DEPCTL_MPS_8 << DEPCTL_mps_bitp);
|
| (DEPCTL_MPS_64 << DEPCTL_mps_bitp);
|
||||||
|
|
||||||
/* 64 bytes packet size, active endpoint */
|
/* 64 bytes packet size, active endpoint */
|
||||||
DIEPCTL(0) = (DEPCTL_MPS_8 << DEPCTL_mps_bitp)
|
DIEPCTL(0) = (DEPCTL_MPS_64 << DEPCTL_mps_bitp)
|
||||||
| DEPCTL_usbactep;
|
| DEPCTL_usbactep;
|
||||||
|
|
||||||
DCTL = DCTL_cgnpinnak | DCTL_cgoutnak;
|
DCTL = DCTL_cgnpinnak | DCTL_cgoutnak;
|
||||||
}
|
}
|
||||||
|
|
@ -236,13 +266,20 @@ static void core_dev_init(void)
|
||||||
num_out_ep = 0;
|
num_out_ep = 0;
|
||||||
for(i = 0; i < extract(GHWCFG2, num_ep); i++)
|
for(i = 0; i < extract(GHWCFG2, num_ep); i++)
|
||||||
{
|
{
|
||||||
if(GHWCFG1 & GHWCFG1_IN_EP(i))
|
bool in = false, out = false;
|
||||||
|
switch((GHWCFG1 >> GHWCFG1_epdir_bitp(i)) & GHWCFG1_epdir_bits)
|
||||||
|
{
|
||||||
|
case GHWCFG1_EPDIR_BIDIR: in = out = true; break;
|
||||||
|
case GHWCFG1_EPDIR_IN: in = true; break;
|
||||||
|
case GHWCFG1_EPDIR_OUT: out = true; break;
|
||||||
|
default: panicf("usb: invalid epdir");
|
||||||
|
}
|
||||||
|
/* don't count EP0 which is special and always bidirectional */
|
||||||
|
if(in && i != 0)
|
||||||
num_in_ep++;
|
num_in_ep++;
|
||||||
if(GHWCFG1 & GHWCFG1_OUT_EP(i))
|
if(out && i != 0)
|
||||||
num_out_ep++;
|
num_out_ep++;
|
||||||
logf(" EP%d: IN=%s OUT=%s", i,
|
logf(" EP%d: IN=%s OUT=%s", i, in ? "yes" : "no", out ? "yes" : "no");
|
||||||
GHWCFG1 & GHWCFG1_IN_EP(i) ? "yes" : "no",
|
|
||||||
GHWCFG1 & GHWCFG1_OUT_EP(i) ? "yes" : "no");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(num_in_ep != extract(GHWCFG4, num_in_ep))
|
if(num_in_ep != extract(GHWCFG4, num_in_ep))
|
||||||
|
|
@ -317,8 +354,6 @@ static void core_dev_init(void)
|
||||||
logf(" rx_thr_len: %lu", extract(DTHRCTL, rx_thr_len));
|
logf(" rx_thr_len: %lu", extract(DTHRCTL, rx_thr_len));
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DTHRCTL = 0;
|
|
||||||
|
|
||||||
/* enable USB interrupts */
|
/* enable USB interrupts */
|
||||||
enable_device_interrupts();
|
enable_device_interrupts();
|
||||||
}
|
}
|
||||||
|
|
@ -386,9 +421,6 @@ static bool handle_reset(void)
|
||||||
/* Flush FIFOs */
|
/* Flush FIFOs */
|
||||||
flush_tx_fifos(0x10);
|
flush_tx_fifos(0x10);
|
||||||
|
|
||||||
/* Flush the Learning Queue */
|
|
||||||
GRSTCTL = GRSTCTL_intknqflsh;
|
|
||||||
|
|
||||||
reset_endpoints();
|
reset_endpoints();
|
||||||
|
|
||||||
/* Reset Device Address */
|
/* Reset Device Address */
|
||||||
|
|
|
||||||
|
|
@ -169,9 +169,12 @@
|
||||||
#define GSNPSID BASE_REG(0x040)
|
#define GSNPSID BASE_REG(0x040)
|
||||||
|
|
||||||
/** User HW Config1 Register */
|
/** User HW Config1 Register */
|
||||||
#define GHWCFG1 BASE_REG(0x044)
|
#define GHWCFG1 BASE_REG(0x044)
|
||||||
#define GHWCFG1_IN_EP(ep) (1 << (2 * (ep))) /** 1 if EP(ep) has in cap */
|
#define GHWCFG1_epdir_bitp(ep) (2 * (ep))
|
||||||
#define GHWCFG1_OUT_EP(ep) (1 << (1 + 2 * (ep))) /** same for out */
|
#define GHWCFG1_epdir_bits 0x3
|
||||||
|
#define GHWCFG1_EPDIR_BIDIR 0
|
||||||
|
#define GHWCFG1_EPDIR_IN 1
|
||||||
|
#define GHWCFG1_EPDIR_OUT 2
|
||||||
|
|
||||||
/** User HW Config2 Register */
|
/** User HW Config2 Register */
|
||||||
#define GHWCFG2 BASE_REG(0x048)
|
#define GHWCFG2 BASE_REG(0x048)
|
||||||
|
|
@ -449,7 +452,7 @@
|
||||||
/**
|
/**
|
||||||
* Parameters
|
* Parameters
|
||||||
*/
|
*/
|
||||||
#define USE_CUSTOM_FIFO_LAYOUT
|
//#define USE_CUSTOM_FIFO_LAYOUT
|
||||||
|
|
||||||
#ifdef USE_CUSTOM_FIFO_LAYOUT
|
#ifdef USE_CUSTOM_FIFO_LAYOUT
|
||||||
/* Data fifo: includes RX fifo, non period TX fifo and periodic fifos
|
/* Data fifo: includes RX fifo, non period TX fifo and periodic fifos
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue