diff options
author | Maurus Cuelenaere <mcuelenaere@gmail.com> | 2008-12-31 01:11:04 +0000 |
---|---|---|
committer | Maurus Cuelenaere <mcuelenaere@gmail.com> | 2008-12-31 01:11:04 +0000 |
commit | 9ac7af749bceb67916b3179a3b7c7eee6ee6443a (patch) | |
tree | dcc9c594eaeed65015d6dab3fa04da5d1734314d | |
parent | 5d3a035cb3714028a659ecd8abbad034666b7b3c (diff) | |
download | rockbox-9ac7af749bceb67916b3179a3b7c7eee6ee6443a.tar.gz rockbox-9ac7af749bceb67916b3179a3b7c7eee6ee6443a.zip |
Ingenic players:
* Further implement USB driver
* Add preliminary clock setup
* Fix USB VID/PID
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19618 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | firmware/export/config-ondavx747.h | 4 | ||||
-rw-r--r-- | firmware/export/jz4740.h | 68 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/onda_vx747/lcd-onda_vx747.c | 2 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/system-jz4740.c | 171 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/usb-jz4740.c | 294 |
5 files changed, 444 insertions, 95 deletions
diff --git a/firmware/export/config-ondavx747.h b/firmware/export/config-ondavx747.h index 2856e7e16d..2fe0564e71 100644 --- a/firmware/export/config-ondavx747.h +++ b/firmware/export/config-ondavx747.h | |||
@@ -158,7 +158,7 @@ | |||
158 | 158 | ||
159 | #define CONFIG_USBOTG USBOTG_JZ4740 | 159 | #define CONFIG_USBOTG USBOTG_JZ4740 |
160 | #define HAVE_USBSTACK | 160 | #define HAVE_USBSTACK |
161 | #define USB_VENDOR_ID 0x041e | 161 | #define USB_VENDOR_ID 0x07C4 |
162 | #define USB_PRODUCT_ID 0x4133 | 162 | #define USB_PRODUCT_ID 0xA4A5 |
163 | 163 | ||
164 | #endif | 164 | #endif |
diff --git a/firmware/export/jz4740.h b/firmware/export/jz4740.h index e63228ff70..7fbfba283f 100644 --- a/firmware/export/jz4740.h +++ b/firmware/export/jz4740.h | |||
@@ -260,28 +260,29 @@ | |||
260 | #define CPM_LCR_LPM_SLEEP (0x1 << CPM_LCR_LPM_BIT) | 260 | #define CPM_LCR_LPM_SLEEP (0x1 << CPM_LCR_LPM_BIT) |
261 | 261 | ||
262 | /* Clock Gate Register */ | 262 | /* Clock Gate Register */ |
263 | #define CPM_CLKGR_UART1 (1 << 15) | 263 | #define CPM_CLKGR_UART1 (1 << 15) |
264 | #define CPM_CLKGR_UHC (1 << 14) | 264 | #define CPM_CLKGR_UHC (1 << 14) |
265 | #define CPM_CLKGR_IPU (1 << 13) | 265 | #define CPM_CLKGR_IPU (1 << 13) |
266 | #define CPM_CLKGR_DMAC (1 << 12) | 266 | #define CPM_CLKGR_DMAC (1 << 12) |
267 | #define CPM_CLKGR_UDC (1 << 11) | 267 | #define CPM_CLKGR_UDC (1 << 11) |
268 | #define CPM_CLKGR_LCD (1 << 10) | 268 | #define CPM_CLKGR_LCD (1 << 10) |
269 | #define CPM_CLKGR_CIM (1 << 9) | 269 | #define CPM_CLKGR_CIM (1 << 9) |
270 | #define CPM_CLKGR_SADC (1 << 8) | 270 | #define CPM_CLKGR_SADC (1 << 8) |
271 | #define CPM_CLKGR_MSC (1 << 7) | 271 | #define CPM_CLKGR_MSC (1 << 7) |
272 | #define CPM_CLKGR_AIC1 (1 << 6) | 272 | #define CPM_CLKGR_AIC1 (1 << 6) |
273 | #define CPM_CLKGR_AIC2 (1 << 5) | 273 | #define CPM_CLKGR_AIC2 (1 << 5) |
274 | #define CPM_CLKGR_SSI (1 << 4) | 274 | #define CPM_CLKGR_SSI (1 << 4) |
275 | #define CPM_CLKGR_I2C (1 << 3) | 275 | #define CPM_CLKGR_I2C (1 << 3) |
276 | #define CPM_CLKGR_RTC (1 << 2) | 276 | #define CPM_CLKGR_RTC (1 << 2) |
277 | #define CPM_CLKGR_TCU (1 << 1) | 277 | #define CPM_CLKGR_TCU (1 << 1) |
278 | #define CPM_CLKGR_UART0 (1 << 0) | 278 | #define CPM_CLKGR_UART0 (1 << 0) |
279 | 279 | ||
280 | /* Sleep Control Register */ | 280 | /* Sleep Control Register */ |
281 | #define CPM_SCR_O1ST_BIT 8 | 281 | #define CPM_SCR_O1ST_BIT 8 |
282 | #define CPM_SCR_O1ST_MASK (0xff << CPM_SCR_O1ST_BIT) | 282 | #define CPM_SCR_O1ST_MASK (0xff << CPM_SCR_O1ST_BIT) |
283 | #define CPM_SCR_USBHOST_SUSPEND (1 << 7) | ||
283 | #define CPM_SCR_USBPHY_ENABLE (1 << 6) | 284 | #define CPM_SCR_USBPHY_ENABLE (1 << 6) |
284 | #define CPM_SCR_OSC_ENABLE (1 << 4) | 285 | #define CPM_SCR_OSC_ENABLE (1 << 4) |
285 | 286 | ||
286 | /* Hibernate Control Register */ | 287 | /* Hibernate Control Register */ |
287 | #define CPM_HCR_PD (1 << 0) | 288 | #define CPM_HCR_PD (1 << 0) |
@@ -2419,7 +2420,7 @@ | |||
2419 | #define USB_INTR_OUTEP1 0x0002 | 2420 | #define USB_INTR_OUTEP1 0x0002 |
2420 | #define USB_INTR_OUTEP2 0x0004 | 2421 | #define USB_INTR_OUTEP2 0x0004 |
2421 | 2422 | ||
2422 | #define USB_INTR_EP(n) (n*2) | 2423 | #define USB_INTR_EP(n) ((n)==0 ? 1 : ((n)*2)) |
2423 | 2424 | ||
2424 | /* CSR0 bit masks */ | 2425 | /* CSR0 bit masks */ |
2425 | #define USB_CSR0_OUTPKTRDY 0x01 | 2426 | #define USB_CSR0_OUTPKTRDY 0x01 |
@@ -3282,56 +3283,59 @@ do { \ | |||
3282 | #define __cpm_sleep_mode() \ | 3283 | #define __cpm_sleep_mode() \ |
3283 | (REG_CPM_LCR = (REG_CPM_LCR & ~CPM_LCR_LPM_MASK) | CPM_LCR_LPM_SLEEP) | 3284 | (REG_CPM_LCR = (REG_CPM_LCR & ~CPM_LCR_LPM_MASK) | CPM_LCR_LPM_SLEEP) |
3284 | 3285 | ||
3285 | #define __cpm_stop_all() (REG_CPM_CLKGR = 0xffff) | 3286 | #define __cpm_stop_all() (REG_CPM_CLKGR = 0xffff) |
3286 | #define __cpm_stop_uart1() (REG_CPM_CLKGR |= CPM_CLKGR_UART1) | 3287 | #define __cpm_stop_uart1() (REG_CPM_CLKGR |= CPM_CLKGR_UART1) |
3287 | #define __cpm_stop_uhc() (REG_CPM_CLKGR |= CPM_CLKGR_UHC) | 3288 | #define __cpm_stop_uhc() (REG_CPM_CLKGR |= CPM_CLKGR_UHC) |
3288 | #define __cpm_stop_ipu() (REG_CPM_CLKGR |= CPM_CLKGR_IPU) | 3289 | #define __cpm_stop_ipu() (REG_CPM_CLKGR |= CPM_CLKGR_IPU) |
3289 | #define __cpm_stop_dmac() (REG_CPM_CLKGR |= CPM_CLKGR_DMAC) | 3290 | #define __cpm_stop_dmac() (REG_CPM_CLKGR |= CPM_CLKGR_DMAC) |
3290 | #define __cpm_stop_udc() (REG_CPM_CLKGR |= CPM_CLKGR_UDC) | 3291 | #define __cpm_stop_udc() (REG_CPM_CLKGR |= CPM_CLKGR_UDC) |
3291 | #define __cpm_stop_lcd() (REG_CPM_CLKGR |= CPM_CLKGR_LCD) | 3292 | #define __cpm_stop_lcd() (REG_CPM_CLKGR |= CPM_CLKGR_LCD) |
3292 | #define __cpm_stop_cim() (REG_CPM_CLKGR |= CPM_CLKGR_CIM) | 3293 | #define __cpm_stop_cim() (REG_CPM_CLKGR |= CPM_CLKGR_CIM) |
3293 | #define __cpm_stop_sadc() (REG_CPM_CLKGR |= CPM_CLKGR_SADC) | 3294 | #define __cpm_stop_sadc() (REG_CPM_CLKGR |= CPM_CLKGR_SADC) |
3294 | #define __cpm_stop_msc() (REG_CPM_CLKGR |= CPM_CLKGR_MSC) | 3295 | #define __cpm_stop_msc() (REG_CPM_CLKGR |= CPM_CLKGR_MSC) |
3295 | #define __cpm_stop_aic1() (REG_CPM_CLKGR |= CPM_CLKGR_AIC1) | 3296 | #define __cpm_stop_aic1() (REG_CPM_CLKGR |= CPM_CLKGR_AIC1) |
3296 | #define __cpm_stop_aic2() (REG_CPM_CLKGR |= CPM_CLKGR_AIC2) | 3297 | #define __cpm_stop_aic2() (REG_CPM_CLKGR |= CPM_CLKGR_AIC2) |
3297 | #define __cpm_stop_ssi() (REG_CPM_CLKGR |= CPM_CLKGR_SSI) | 3298 | #define __cpm_stop_ssi() (REG_CPM_CLKGR |= CPM_CLKGR_SSI) |
3298 | #define __cpm_stop_i2c() (REG_CPM_CLKGR |= CPM_CLKGR_I2C) | 3299 | #define __cpm_stop_i2c() (REG_CPM_CLKGR |= CPM_CLKGR_I2C) |
3299 | #define __cpm_stop_rtc() (REG_CPM_CLKGR |= CPM_CLKGR_RTC) | 3300 | #define __cpm_stop_rtc() (REG_CPM_CLKGR |= CPM_CLKGR_RTC) |
3300 | #define __cpm_stop_tcu() (REG_CPM_CLKGR |= CPM_CLKGR_TCU) | 3301 | #define __cpm_stop_tcu() (REG_CPM_CLKGR |= CPM_CLKGR_TCU) |
3301 | #define __cpm_stop_uart0() (REG_CPM_CLKGR |= CPM_CLKGR_UART0) | 3302 | #define __cpm_stop_uart0() (REG_CPM_CLKGR |= CPM_CLKGR_UART0) |
3302 | 3303 | ||
3303 | #define __cpm_start_all() (REG_CPM_CLKGR = 0x0) | 3304 | #define __cpm_start_all() (REG_CPM_CLKGR = 0x0) |
3304 | #define __cpm_start_uart1() (REG_CPM_CLKGR &= ~CPM_CLKGR_UART1) | 3305 | #define __cpm_start_uart1() (REG_CPM_CLKGR &= ~CPM_CLKGR_UART1) |
3305 | #define __cpm_start_uhc() (REG_CPM_CLKGR &= ~CPM_CLKGR_UHC) | 3306 | #define __cpm_start_uhc() (REG_CPM_CLKGR &= ~CPM_CLKGR_UHC) |
3306 | #define __cpm_start_ipu() (REG_CPM_CLKGR &= ~CPM_CLKGR_IPU) | 3307 | #define __cpm_start_ipu() (REG_CPM_CLKGR &= ~CPM_CLKGR_IPU) |
3307 | #define __cpm_start_dmac() (REG_CPM_CLKGR &= ~CPM_CLKGR_DMAC) | 3308 | #define __cpm_start_dmac() (REG_CPM_CLKGR &= ~CPM_CLKGR_DMAC) |
3308 | #define __cpm_start_udc() (REG_CPM_CLKGR &= ~CPM_CLKGR_UDC) | 3309 | #define __cpm_start_udc() (REG_CPM_CLKGR &= ~CPM_CLKGR_UDC) |
3309 | #define __cpm_start_lcd() (REG_CPM_CLKGR &= ~CPM_CLKGR_LCD) | 3310 | #define __cpm_start_lcd() (REG_CPM_CLKGR &= ~CPM_CLKGR_LCD) |
3310 | #define __cpm_start_cim() (REG_CPM_CLKGR &= ~CPM_CLKGR_CIM) | 3311 | #define __cpm_start_cim() (REG_CPM_CLKGR &= ~CPM_CLKGR_CIM) |
3311 | #define __cpm_start_sadc() (REG_CPM_CLKGR &= ~CPM_CLKGR_SADC) | 3312 | #define __cpm_start_sadc() (REG_CPM_CLKGR &= ~CPM_CLKGR_SADC) |
3312 | #define __cpm_start_msc() (REG_CPM_CLKGR &= ~CPM_CLKGR_MSC) | 3313 | #define __cpm_start_msc() (REG_CPM_CLKGR &= ~CPM_CLKGR_MSC) |
3313 | #define __cpm_start_aic1() (REG_CPM_CLKGR &= ~CPM_CLKGR_AIC1) | 3314 | #define __cpm_start_aic1() (REG_CPM_CLKGR &= ~CPM_CLKGR_AIC1) |
3314 | #define __cpm_start_aic2() (REG_CPM_CLKGR &= ~CPM_CLKGR_AIC2) | 3315 | #define __cpm_start_aic2() (REG_CPM_CLKGR &= ~CPM_CLKGR_AIC2) |
3315 | #define __cpm_start_ssi() (REG_CPM_CLKGR &= ~CPM_CLKGR_SSI) | 3316 | #define __cpm_start_ssi() (REG_CPM_CLKGR &= ~CPM_CLKGR_SSI) |
3316 | #define __cpm_start_i2c() (REG_CPM_CLKGR &= ~CPM_CLKGR_I2C) | 3317 | #define __cpm_start_i2c() (REG_CPM_CLKGR &= ~CPM_CLKGR_I2C) |
3317 | #define __cpm_start_rtc() (REG_CPM_CLKGR &= ~CPM_CLKGR_RTC) | 3318 | #define __cpm_start_rtc() (REG_CPM_CLKGR &= ~CPM_CLKGR_RTC) |
3318 | #define __cpm_start_tcu() (REG_CPM_CLKGR &= ~CPM_CLKGR_TCU) | 3319 | #define __cpm_start_tcu() (REG_CPM_CLKGR &= ~CPM_CLKGR_TCU) |
3319 | #define __cpm_start_uart0() (REG_CPM_CLKGR &= ~CPM_CLKGR_UART0) | 3320 | #define __cpm_start_uart0() (REG_CPM_CLKGR &= ~CPM_CLKGR_UART0) |
3320 | 3321 | ||
3321 | #define __cpm_get_o1st() \ | 3322 | #define __cpm_get_o1st() \ |
3322 | ((REG_CPM_SCR & CPM_SCR_O1ST_MASK) >> CPM_SCR_O1ST_BIT) | 3323 | ((REG_CPM_SCR & CPM_SCR_O1ST_MASK) >> CPM_SCR_O1ST_BIT) |
3323 | #define __cpm_set_o1st(v) \ | 3324 | #define __cpm_set_o1st(v) \ |
3324 | (REG_CPM_SCR = (REG_CPM_SCR & ~CPM_SCR_O1ST_MASK) | ((v) << (CPM_SCR_O1ST_BIT))) | 3325 | (REG_CPM_SCR = (REG_CPM_SCR & ~CPM_SCR_O1ST_MASK) | ((v) << (CPM_SCR_O1ST_BIT))) |
3325 | #define __cpm_suspend_usbphy() (REG_CPM_SCR |= CPM_SCR_USBPHY_SUSPEND) | 3326 | #define __cpm_suspend_usbphy() (REG_CPM_SCR |= CPM_SCR_USBPHY_SUSPEND) |
3327 | #define __cpm_suspend_usbhost() (REG_CPM_SCR |= CPM_SCR_USBHOST_SUSPEND) | ||
3326 | #define __cpm_enable_osc_in_sleep() (REG_CPM_SCR |= CPM_SCR_OSC_ENABLE) | 3328 | #define __cpm_enable_osc_in_sleep() (REG_CPM_SCR |= CPM_SCR_OSC_ENABLE) |
3327 | 3329 | ||
3328 | 3330 | ||
3331 | #define CFG_EXTAL 12000000 | ||
3332 | |||
3329 | #ifdef CFG_EXTAL | 3333 | #ifdef CFG_EXTAL |
3330 | #define JZ_EXTAL CFG_EXTAL | 3334 | #define JZ_EXTAL CFG_EXTAL |
3331 | #else | 3335 | #else |
3332 | #define JZ_EXTAL 3686400 | 3336 | #define JZ_EXTAL 3686400 |
3333 | #endif | 3337 | #endif |
3334 | #define JZ_EXTAL2 32768 /* RTC clock */ | 3338 | #define JZ_EXTAL2 32768 /* RTC clock */ |
3335 | 3339 | ||
3336 | /* PLL output frequency */ | 3340 | /* PLL output frequency */ |
3337 | static __inline__ unsigned int __cpm_get_pllout(void) | 3341 | static __inline__ unsigned int __cpm_get_pllout(void) |
diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx747/lcd-onda_vx747.c b/firmware/target/mips/ingenic_jz47xx/onda_vx747/lcd-onda_vx747.c index 40d9bb6106..faed5ecda2 100644 --- a/firmware/target/mips/ingenic_jz47xx/onda_vx747/lcd-onda_vx747.c +++ b/firmware/target/mips/ingenic_jz47xx/onda_vx747/lcd-onda_vx747.c | |||
@@ -203,7 +203,7 @@ static void _set_lcd_clock(void) | |||
203 | 203 | ||
204 | __cpm_stop_lcd(); | 204 | __cpm_stop_lcd(); |
205 | pll_div = ( REG_CPM_CPCCR & CPM_CPCCR_PCS ); /* clock source, 0:pllout/2 1: pllout */ | 205 | pll_div = ( REG_CPM_CPCCR & CPM_CPCCR_PCS ); /* clock source, 0:pllout/2 1: pllout */ |
206 | pll_div = pll_div ? 1 : 2 ; | 206 | pll_div = pll_div ? 1 : 2; |
207 | val = ( __cpm_get_pllout()/pll_div ) / __cpm_get_pclk(); | 207 | val = ( __cpm_get_pllout()/pll_div ) / __cpm_get_pclk(); |
208 | val--; | 208 | val--; |
209 | if ( val > 0x1ff ) | 209 | if ( val > 0x1ff ) |
diff --git a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c index 48fb192810..c741d9f311 100644 --- a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c | |||
@@ -663,6 +663,168 @@ void dma_disable(void) | |||
663 | } | 663 | } |
664 | } | 664 | } |
665 | 665 | ||
666 | static inline void pll_convert(unsigned int pllin, unsigned int *pll_cfcr, unsigned int *pll_plcr1) | ||
667 | { | ||
668 | register unsigned int cfcr, plcr1; | ||
669 | int div[5] = {1, 3, 3, 3, 3}; /* divisors of I:S:P:L:M */ | ||
670 | int nf; | ||
671 | |||
672 | cfcr = CPM_CPCCR_CLKOEN | | ||
673 | (div[0] << CPM_CPCCR_CDIV_BIT) | | ||
674 | (div[1] << CPM_CPCCR_HDIV_BIT) | | ||
675 | (div[2] << CPM_CPCCR_PDIV_BIT) | | ||
676 | (div[3] << CPM_CPCCR_MDIV_BIT) | | ||
677 | (div[4] << CPM_CPCCR_LDIV_BIT); | ||
678 | |||
679 | //nf = pllin * 2 / CFG_EXTAL; | ||
680 | nf = pllin * 2 / 375299969; | ||
681 | plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */ | ||
682 | (0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */ | ||
683 | (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */ | ||
684 | (0xa << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */ | ||
685 | CPM_CPPCR_PLLEN; /* enable PLL */ | ||
686 | |||
687 | /* init PLL */ | ||
688 | *pll_cfcr = cfcr; | ||
689 | *pll_plcr1 = plcr1; | ||
690 | } | ||
691 | |||
692 | static inline void sdram_convert(unsigned int pllin, unsigned int *sdram_freq) | ||
693 | { | ||
694 | register unsigned int ns, tmp; | ||
695 | |||
696 | ns = 1000000000 / pllin; | ||
697 | tmp = 15625 / ns; | ||
698 | |||
699 | /* Set refresh registers */ | ||
700 | tmp = tmp / 64 + 1; | ||
701 | |||
702 | if(tmp > 0xff) | ||
703 | tmp = 0xff; | ||
704 | |||
705 | *sdram_freq = tmp; | ||
706 | } | ||
707 | |||
708 | static inline void set_cpu_freq(unsigned int pllin, unsigned int div) | ||
709 | { | ||
710 | unsigned int sdram_freq; | ||
711 | unsigned int pll_cfcr, pll_plcr1; | ||
712 | int div_preq[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; | ||
713 | |||
714 | if(pllin < 25000000 || pllin > 420000000) | ||
715 | panicf("PLL should be >25000000 and <420000000 !"); | ||
716 | |||
717 | unsigned long t = read_c0_status(); | ||
718 | write_c0_status(t & ~1); | ||
719 | |||
720 | pll_convert(pllin, &pll_cfcr, &pll_plcr1); | ||
721 | |||
722 | sdram_convert(pllin / div_preq[div], &sdram_freq); | ||
723 | |||
724 | REG_CPM_CPCCR &= ~CPM_CPCCR_CE; | ||
725 | |||
726 | REG_CPM_CPCCR = pll_cfcr; | ||
727 | REG_CPM_CPPCR = pll_plcr1; | ||
728 | |||
729 | REG_EMC_RTCOR = sdram_freq; | ||
730 | REG_EMC_RTCNT = sdram_freq; | ||
731 | |||
732 | REG_CPM_CPCCR |= CPM_CPCCR_CE; | ||
733 | |||
734 | detect_clock(); | ||
735 | |||
736 | write_c0_status(t); | ||
737 | } | ||
738 | |||
739 | static void OF_init_clocks(void) | ||
740 | { | ||
741 | unsigned int prog_entry = ((unsigned int)OF_init_clocks >> 5) << 5; | ||
742 | unsigned int i, prog_size = 1024; | ||
743 | |||
744 | for(i = prog_entry; i < prog_entry + prog_size; i += 32) | ||
745 | __asm__ __volatile__("cache 0x1c, 0x00(%0) \n" | ||
746 | : | ||
747 | : "r" (i) | ||
748 | ); | ||
749 | |||
750 | /* disable PLL clock */ | ||
751 | REG_CPM_CPPCR &= ~CPM_CPPCR_PLLEN; | ||
752 | REG_CPM_CPCCR |= CPM_CPCCR_CE; | ||
753 | |||
754 | unsigned long old_clocks = REG_CPM_CLKGR; | ||
755 | /* | ||
756 | REG_CPM_CLKGR = ~( CPM_CLKGR_UART0 | CPM_CLKGR_TCU | | ||
757 | CPM_CLKGR_RTC | CPM_CLKGR_SADC | | ||
758 | CPM_CLKGR_LCD ); | ||
759 | */ | ||
760 | |||
761 | unsigned long old_scr = REG_CPM_SCR; | ||
762 | REG_CPM_SCR &= ~CPM_SCR_OSC_ENABLE; /* O1SE: 12M oscillator is disabled in Sleep mode */ | ||
763 | |||
764 | REG_EMC_DMCR |= (EMC_DMCR_RMODE | EMC_DMCR_RFSH); /* self refresh + refresh is performed */ | ||
765 | REG_EMC_DMCR = (REG_EMC_DMCR & ~EMC_DMCR_RMODE) | 1; /* -> RMODE = auto refresh | ||
766 | -> CAS mode = 2 cycles */ | ||
767 | __asm__ __volatile__("wait \n"); | ||
768 | |||
769 | REG_CPM_CLKGR = old_clocks; | ||
770 | REG_CPM_SCR = old_scr; | ||
771 | |||
772 | for(i=0; i<90; i++); | ||
773 | |||
774 | set_cpu_freq(336000000, 1); | ||
775 | |||
776 | for(i=0; i<60; i++); | ||
777 | } | ||
778 | |||
779 | static void my_init_clocks(void) | ||
780 | { | ||
781 | unsigned long t = read_c0_status(); | ||
782 | write_c0_status(t & ~1); | ||
783 | |||
784 | unsigned int prog_entry = ((unsigned int)my_init_clocks / 32 - 1) * 32; | ||
785 | unsigned int i, prog_size = 1024; | ||
786 | |||
787 | for(i = prog_entry; i < prog_entry + prog_size; i += 32) | ||
788 | __asm__ __volatile__("cache 0x1c, 0x00(%0) \n" | ||
789 | : | ||
790 | : "r" (i) | ||
791 | ); | ||
792 | |||
793 | unsigned int sdram_freq, plcr1, cfcr; | ||
794 | |||
795 | sdram_convert(336000000/3, &sdram_freq); | ||
796 | |||
797 | cfcr = CPM_CPCCR_CLKOEN | | ||
798 | (6 << CPM_CPCCR_UDIV_BIT) | | ||
799 | CPM_CPCCR_UCS | | ||
800 | CPM_CPCCR_PCS | | ||
801 | (0 << CPM_CPCCR_CDIV_BIT) | | ||
802 | (2 << CPM_CPCCR_HDIV_BIT) | | ||
803 | (2 << CPM_CPCCR_PDIV_BIT) | | ||
804 | (2 << CPM_CPCCR_MDIV_BIT) | | ||
805 | (2 << CPM_CPCCR_LDIV_BIT); | ||
806 | |||
807 | plcr1 = (54 << CPM_CPPCR_PLLM_BIT) | /* FD */ | ||
808 | (0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */ | ||
809 | (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */ | ||
810 | (0x20 << CPM_CPPCR_PLLST_BIT)| /* PLL stable time */ | ||
811 | CPM_CPPCR_PLLEN; /* enable PLL */ | ||
812 | |||
813 | REG_CPM_CPCCR &= ~CPM_CPCCR_CE; | ||
814 | |||
815 | REG_CPM_CPCCR = cfcr; | ||
816 | REG_CPM_CPPCR = plcr1; | ||
817 | |||
818 | REG_EMC_RTCOR = sdram_freq; | ||
819 | REG_EMC_RTCNT = sdram_freq; | ||
820 | |||
821 | REG_CPM_CPCCR |= CPM_CPCCR_CE; | ||
822 | |||
823 | REG_CPM_LPCDR = (REG_CPM_LPCDR & ~CPM_LPCDR_PIXDIV_MASK) | (11 << CPM_LPCDR_PIXDIV_BIT); | ||
824 | |||
825 | write_c0_status(t); | ||
826 | } | ||
827 | |||
666 | extern int main(void); | 828 | extern int main(void); |
667 | extern void except_common_entry(void); | 829 | extern void except_common_entry(void); |
668 | 830 | ||
@@ -696,6 +858,15 @@ void system_main(void) | |||
696 | 858 | ||
697 | /* Disable unneeded clocks, clocks are enabled when needed */ | 859 | /* Disable unneeded clocks, clocks are enabled when needed */ |
698 | __cpm_stop_all(); | 860 | __cpm_stop_all(); |
861 | __cpm_suspend_usbhost(); | ||
862 | |||
863 | #if 0 | ||
864 | my_init_clocks(); | ||
865 | /*__cpm_stop_udc(); | ||
866 | REG_CPM_CPCCR |= CPM_CPCCR_UCS; | ||
867 | REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_UDIV_MASK) | (3 << CPM_CPCCR_UDIV_BIT); | ||
868 | __cpm_start_udc();*/ | ||
869 | #endif | ||
699 | 870 | ||
700 | /* Enable interrupts at core level */ | 871 | /* Enable interrupts at core level */ |
701 | sti(); | 872 | sti(); |
diff --git a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c index f06e796e05..eda3fb3b88 100644 --- a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c | |||
@@ -34,11 +34,12 @@ | |||
34 | #define USB_EP0_RX 1 | 34 | #define USB_EP0_RX 1 |
35 | #define USB_EP0_TX 2 | 35 | #define USB_EP0_TX 2 |
36 | 36 | ||
37 | #define EP_BUF_LEFT(ep) (ep->length - ep->sent) | 37 | #define EP_BUF_LEFT(ep) ((ep)->length - (ep)->sent) |
38 | #define EP_PTR(ep) ((void*)((unsigned int)ep->buf + ep->sent)) | 38 | #define EP_PTR(ep) ((void*)((unsigned int)(ep)->buf + (ep)->sent)) |
39 | #define EP_NUMBER(ep) (((int)ep - (int)&endpoints[0])/sizeof(struct usb_endpoint)) | 39 | #define EP_NUMBER(ep) (((int)(ep) - (int)&endpoints[0])/sizeof(struct usb_endpoint)) |
40 | #define EP_NUMBER2(ep) (EP_NUMBER((ep))/2) | ||
40 | #define TOTAL_EP() (sizeof(endpoints)/sizeof(struct usb_endpoint)) | 41 | #define TOTAL_EP() (sizeof(endpoints)/sizeof(struct usb_endpoint)) |
41 | #define EP_IS_IN(ep) (EP_NUMBER(ep)%2) | 42 | #define EP_IS_IN(ep) (EP_NUMBER((ep))%2) |
42 | 43 | ||
43 | enum ep_type | 44 | enum ep_type |
44 | { | 45 | { |
@@ -66,11 +67,11 @@ static unsigned char ep0_rx_buf[64]; | |||
66 | static unsigned char ep0state = USB_EP0_IDLE; | 67 | static unsigned char ep0state = USB_EP0_IDLE; |
67 | static struct usb_endpoint endpoints[] = | 68 | static struct usb_endpoint endpoints[] = |
68 | { | 69 | { |
69 | /* buf length sent type use_dma fifo_addr fifo_size */ | 70 | /* buf length sent type use_dma fifo_addr fifo_size */ |
70 | {&ep0_rx_buf, 0, {0}, ep_control, false, USB_FIFO_EP0, 64 }, | 71 | {&ep0_rx_buf, 0, {0}, ep_control, false, USB_FIFO_EP0, 64 }, |
71 | {NULL, 0, {0}, ep_control, false, USB_FIFO_EP0, 64 }, | 72 | {NULL, 0, {0}, ep_control, false, USB_FIFO_EP0, 64 }, |
72 | {NULL, 0, {0}, ep_bulk, true, USB_FIFO_EP1, 512}, | 73 | {NULL, 0, {0}, ep_bulk, false, USB_FIFO_EP1, 512}, |
73 | {NULL, 0, {0}, ep_bulk, true, USB_FIFO_EP1, 512}, | 74 | {NULL, 0, {0}, ep_bulk, false, USB_FIFO_EP1, 512}, |
74 | {NULL, 0, {0}, ep_interrupt, false, USB_FIFO_EP2, 64 } | 75 | {NULL, 0, {0}, ep_interrupt, false, USB_FIFO_EP2, 64 } |
75 | }; | 76 | }; |
76 | 77 | ||
@@ -81,7 +82,7 @@ static inline void select_endpoint(int ep) | |||
81 | 82 | ||
82 | static void readFIFO(struct usb_endpoint *ep, unsigned int size) | 83 | static void readFIFO(struct usb_endpoint *ep, unsigned int size) |
83 | { | 84 | { |
84 | logf("readFIFO(EP%d, %d)", EP_NUMBER(ep), size); | 85 | logf("readFIFO(EP%d, %d)", EP_NUMBER2(ep), size); |
85 | 86 | ||
86 | register unsigned char *ptr = (unsigned char*)EP_PTR(ep); | 87 | register unsigned char *ptr = (unsigned char*)EP_PTR(ep); |
87 | register unsigned int *ptr32 = (unsigned int*)ptr; | 88 | register unsigned int *ptr32 = (unsigned int*)ptr; |
@@ -117,19 +118,19 @@ static void readFIFO(struct usb_endpoint *ep, unsigned int size) | |||
117 | 118 | ||
118 | static void writeFIFO(struct usb_endpoint *ep, unsigned int size) | 119 | static void writeFIFO(struct usb_endpoint *ep, unsigned int size) |
119 | { | 120 | { |
120 | logf("writeFIFO(EP%d, %d)", EP_NUMBER(ep), size); | 121 | //logf("writeFIFO(EP%d, %d)", EP_NUMBER2(ep), size); |
121 | 122 | ||
122 | register unsigned int *d = (unsigned int *)EP_PTR(ep); | 123 | register unsigned int *d = (unsigned int *)EP_PTR(ep); |
123 | register unsigned char *c; | 124 | register unsigned char *c; |
124 | register int s; | 125 | register int s; |
125 | 126 | ||
126 | if (size > 0) | 127 | if(size > 0) |
127 | { | 128 | { |
128 | s = size >> 2; | 129 | s = size >> 2; |
129 | while (s--) | 130 | while (s--) |
130 | REG32(ep->fifo_addr) = *d++; | 131 | REG32(ep->fifo_addr) = *d++; |
131 | 132 | ||
132 | if ( (s = size & 3) ) | 133 | if( (s = size & 3) ) |
133 | { | 134 | { |
134 | c = (unsigned char *)d; | 135 | c = (unsigned char *)d; |
135 | while (s--) | 136 | while (s--) |
@@ -140,18 +141,43 @@ static void writeFIFO(struct usb_endpoint *ep, unsigned int size) | |||
140 | REG32(ep->fifo_addr) = 0; | 141 | REG32(ep->fifo_addr) = 0; |
141 | } | 142 | } |
142 | 143 | ||
144 | static void flushFIFO(struct usb_endpoint *ep) | ||
145 | { | ||
146 | //logf("flushFIFO(%d)", EP_NUMBER(ep)); | ||
147 | |||
148 | switch (ep->type) | ||
149 | { | ||
150 | case ep_control: | ||
151 | break; | ||
152 | |||
153 | case ep_bulk: | ||
154 | case ep_interrupt: | ||
155 | if(EP_IS_IN(ep)) | ||
156 | REG_USB_REG_INCSR |= USB_INCSR_FF; | ||
157 | else | ||
158 | REG_USB_REG_OUTCSR |= USB_OUTCSR_FF; | ||
159 | break; | ||
160 | } | ||
161 | } | ||
162 | |||
143 | static void EP0_send(void) | 163 | static void EP0_send(void) |
144 | { | 164 | { |
145 | register struct usb_endpoint* ep = &endpoints[1]; | 165 | register struct usb_endpoint* ep = &endpoints[1]; |
146 | register unsigned int length; | 166 | register unsigned int length; |
147 | 167 | ||
168 | if(ep->length == 0) | ||
169 | { | ||
170 | select_endpoint(0); | ||
171 | REG_USB_REG_CSR0 |= (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND); | ||
172 | return; | ||
173 | } | ||
174 | |||
148 | if(ep->sent == 0) | 175 | if(ep->sent == 0) |
149 | length = (ep->length <= ep->fifo_size ? ep->length : ep->fifo_size); | 176 | length = (ep->length <= ep->fifo_size ? ep->length : ep->fifo_size); |
150 | else | 177 | else |
151 | length = (EP_BUF_LEFT(ep) <= ep->fifo_size ? EP_BUF_LEFT(ep) : ep->fifo_size); | 178 | length = (EP_BUF_LEFT(ep) <= ep->fifo_size ? EP_BUF_LEFT(ep) : ep->fifo_size); |
152 | 179 | ||
153 | select_endpoint(0); | 180 | select_endpoint(0); |
154 | |||
155 | writeFIFO(ep, length); | 181 | writeFIFO(ep, length); |
156 | ep->sent += length; | 182 | ep->sent += length; |
157 | 183 | ||
@@ -166,6 +192,7 @@ static void EP0_send(void) | |||
166 | 192 | ||
167 | static void EP0_handler(void) | 193 | static void EP0_handler(void) |
168 | { | 194 | { |
195 | logf("EP0_handler"); | ||
169 | register unsigned char csr0; | 196 | register unsigned char csr0; |
170 | 197 | ||
171 | /* Read CSR0 */ | 198 | /* Read CSR0 */ |
@@ -208,46 +235,127 @@ static void EP0_handler(void) | |||
208 | EP0_send(); | 235 | EP0_send(); |
209 | } | 236 | } |
210 | 237 | ||
238 | static void EPIN_handler(unsigned int endpoint) | ||
239 | { | ||
240 | logf("EPIN_handler(%d)", endpoint); | ||
241 | struct usb_endpoint* ep = &endpoints[endpoint*2+1]; | ||
242 | unsigned int length, csr; | ||
243 | |||
244 | select_endpoint(endpoint); | ||
245 | csr = REG_USB_REG_INCSR; | ||
246 | |||
247 | if(ep->length == 0) | ||
248 | { | ||
249 | REG_USB_REG_INCSR = csr | USB_INCSR_INPKTRDY; | ||
250 | return; | ||
251 | } | ||
252 | |||
253 | if(csr & USB_INCSR_SENTSTALL) | ||
254 | { | ||
255 | REG_USB_REG_INCSR = csr & ~USB_INCSR_SENTSTALL; | ||
256 | return; | ||
257 | } | ||
258 | |||
259 | if(ep->sent == 0) | ||
260 | length = (ep->length <= ep->fifo_size ? ep->length : ep->fifo_size); | ||
261 | else | ||
262 | length = (EP_BUF_LEFT(ep) <= ep->fifo_size ? EP_BUF_LEFT(ep) : ep->fifo_size); | ||
263 | |||
264 | writeFIFO(ep, length); | ||
265 | ep->sent += length; | ||
266 | |||
267 | REG_USB_REG_INCSR = csr | USB_INCSR_INPKTRDY; | ||
268 | if(ep->sent >= ep->length) | ||
269 | usb_core_transfer_complete(endpoint|USB_DIR_IN, USB_DIR_IN, 0, ep->sent); | ||
270 | } | ||
271 | |||
272 | static void EPOUT_handler(unsigned int endpoint) | ||
273 | { | ||
274 | logf("EPOUT_handler(%d)", endpoint); | ||
275 | struct usb_endpoint* ep = &endpoints[endpoint*2]; | ||
276 | unsigned int size, csr; | ||
277 | |||
278 | select_endpoint(endpoint); | ||
279 | csr = REG_USB_REG_OUTCSR; | ||
280 | |||
281 | if(ep->buf == NULL && ep->length == 0) | ||
282 | { | ||
283 | REG_USB_REG_OUTCSR = csr & ~USB_OUTCSR_OUTPKTRDY; | ||
284 | return; | ||
285 | } | ||
286 | |||
287 | if(csr & USB_OUTCSR_SENTSTALL) | ||
288 | { | ||
289 | REG_USB_REG_OUTCSR = csr & ~USB_OUTCSR_SENTSTALL; | ||
290 | return; | ||
291 | } | ||
292 | |||
293 | size = REG_USB_REG_OUTCOUNT; | ||
294 | ep->received += size; | ||
295 | |||
296 | readFIFO(ep, size); | ||
297 | |||
298 | REG_USB_REG_OUTCSR = csr & ~USB_OUTCSR_OUTPKTRDY; | ||
299 | |||
300 | logf("received: %d length: %d", ep->received, ep->length); | ||
301 | |||
302 | //if(ep->received >= ep->length) | ||
303 | usb_core_transfer_complete(endpoint|USB_DIR_OUT, USB_DIR_OUT, 0, ep->received); | ||
304 | } | ||
305 | |||
211 | static void setup_endpoint(struct usb_endpoint *ep) | 306 | static void setup_endpoint(struct usb_endpoint *ep) |
212 | { | 307 | { |
308 | int csr; | ||
213 | ep->sent = 0; | 309 | ep->sent = 0; |
214 | ep->length = 0; | 310 | ep->length = 0; |
215 | 311 | ||
312 | select_endpoint(EP_NUMBER2(ep)); | ||
313 | |||
314 | if(ep->type == ep_bulk) | ||
315 | { | ||
316 | if(REG_USB_REG_POWER & USB_POWER_HSMODE) | ||
317 | ep->fifo_size = 512; | ||
318 | else | ||
319 | ep->fifo_size = 64; | ||
320 | } | ||
321 | |||
216 | if(EP_IS_IN(ep)) | 322 | if(EP_IS_IN(ep)) |
217 | { | 323 | { |
218 | if(ep->type == ep_bulk) | 324 | REG_USB_REG_INMAXP = ep->fifo_size; |
219 | { | 325 | csr = (USB_INCSR_FF | USB_INCSR_CDT | USB_INCSRH_MODE); |
220 | register int size; | 326 | if(ep->use_dma) |
221 | 327 | csr |= (USB_INCSRH_DMAREQENAB | USB_INCSRH_AUTOSET); | |
222 | if((REG_USB_REG_POWER & USB_POWER_HSMODE) == 0) | ||
223 | size = 64; | ||
224 | else | ||
225 | size = 512; | ||
226 | |||
227 | REG_USB_REG_INMAXP = size; | ||
228 | ep->fifo_size = size; | ||
229 | } | ||
230 | else | 328 | else |
231 | REG_USB_REG_INMAXP = ep->fifo_size; | 329 | REG_USB_REG_INTRINE |= USB_INTR_EP(EP_NUMBER2(ep)); |
232 | 330 | ||
233 | REG_USB_REG_INCSR = (USB_INCSR_FF | USB_INCSR_CDT | USB_INCSRH_MODE); | 331 | REG_USB_REG_INCSR = csr; |
234 | REG_USB_REG_INTRINE |= USB_INTR_EP(EP_NUMBER(ep)); | ||
235 | } | 332 | } |
236 | else | 333 | else |
237 | { | 334 | { |
238 | REG_USB_REG_OUTMAXP = ep->fifo_size; | 335 | REG_USB_REG_OUTMAXP = ep->fifo_size; |
239 | REG_USB_REG_OUTCSR = (USB_OUTCSR_FF | USB_OUTCSR_CDT); | 336 | csr = (USB_OUTCSR_FF | USB_OUTCSR_CDT); |
240 | REG_USB_REG_INTROUTE |= USB_INTR_EP(EP_NUMBER(ep)); | 337 | |
338 | if(ep->type == ep_interrupt) | ||
339 | csr |= USB_OUTCSRH_DNYT; | ||
340 | |||
341 | if(ep->use_dma) | ||
342 | csr |= (USB_OUTCSRH_DMAREQENAB | USB_OUTCSRH_AUTOCLR | USB_OUTCSRH_DMAREQMODE); | ||
343 | else | ||
344 | REG_USB_REG_INTROUTE |= USB_INTR_EP(EP_NUMBER2(ep)); | ||
345 | |||
346 | csr = REG_USB_REG_OUTCSR; | ||
241 | } | 347 | } |
348 | |||
349 | //flushFIFO(ep); | ||
242 | } | 350 | } |
243 | 351 | ||
244 | static void udc_reset(void) | 352 | static void udc_reset(void) |
245 | { | 353 | { |
246 | logf("udc_reset"); | 354 | logf("udc_reset()"); |
247 | 355 | ||
248 | register unsigned int i; | 356 | register unsigned int i; |
249 | 357 | ||
250 | /* data init */ | 358 | /* EP0 init */ |
251 | ep0state = USB_EP0_IDLE; | 359 | ep0state = USB_EP0_IDLE; |
252 | 360 | ||
253 | /* Disable interrupts */ | 361 | /* Disable interrupts */ |
@@ -261,19 +369,20 @@ static void udc_reset(void) | |||
261 | 369 | ||
262 | /* Reset address */ | 370 | /* Reset address */ |
263 | REG_USB_REG_FADDR = 0; | 371 | REG_USB_REG_FADDR = 0; |
264 | //REG_USB_REG_POWER = (USB_POWER_SOFTCONN | USB_POWER_HSENAB); /* High speed and softconnect */ | 372 | |
373 | /* High speed and softconnect */ | ||
374 | //REG_USB_REG_POWER = (USB_POWER_SOFTCONN | USB_POWER_HSENAB); | ||
265 | REG_USB_REG_POWER = USB_POWER_SOFTCONN; | 375 | REG_USB_REG_POWER = USB_POWER_SOFTCONN; |
376 | |||
266 | /* Enable SUSPEND */ | 377 | /* Enable SUSPEND */ |
267 | /* REG_USB_REG_POWER |= USB_POWER_SUSPENDM; */ | 378 | /* REG_USB_REG_POWER |= USB_POWER_SUSPENDM; */ |
268 | 379 | ||
380 | /* Reset EP0 */ | ||
269 | select_endpoint(0); | 381 | select_endpoint(0); |
270 | REG_USB_REG_CSR0 = (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_SVDSETUPEND); | 382 | REG_USB_REG_CSR0 = (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_SVDSETUPEND); |
271 | 383 | ||
272 | for(i=2; i<TOTAL_EP(); i++) /* Skip EP0 */ | 384 | for(i=2; i<TOTAL_EP(); i++) /* Skip EP0 */ |
273 | { | ||
274 | select_endpoint(i); | ||
275 | setup_endpoint(&endpoints[i]); | 385 | setup_endpoint(&endpoints[i]); |
276 | } | ||
277 | 386 | ||
278 | /* Enable interrupts */ | 387 | /* Enable interrupts */ |
279 | REG_USB_REG_INTRINE |= USB_INTR_EP0; | 388 | REG_USB_REG_INTRINE |= USB_INTR_EP0; |
@@ -297,19 +406,31 @@ void UDC(void) | |||
297 | /* EPIN & EPOUT are all handled in DMA */ | 406 | /* EPIN & EPOUT are all handled in DMA */ |
298 | if(intrIn & USB_INTR_EP0) | 407 | if(intrIn & USB_INTR_EP0) |
299 | EP0_handler(); | 408 | EP0_handler(); |
409 | if(intrIn & USB_INTR_INEP1) | ||
410 | EPIN_handler(1); | ||
411 | if(intrIn & USB_INTR_INEP2) | ||
412 | EPIN_handler(2); | ||
413 | if(intrOut & USB_INTR_OUTEP1) | ||
414 | EPOUT_handler(1); | ||
415 | if(intrOut & USB_INTR_OUTEP2) | ||
416 | EPOUT_handler(2); | ||
300 | if(intrUSB & USB_INTR_RESET) | 417 | if(intrUSB & USB_INTR_RESET) |
301 | udc_reset(); | 418 | udc_reset(); |
302 | if(intrUSB & USB_INTR_SUSPEND); | 419 | //if(intrUSB & USB_INTR_SUSPEND); |
303 | if(intrUSB & USB_INTR_RESUME); | 420 | //if(intrUSB & USB_INTR_RESUME); |
304 | if(intrDMA & USB_INTR_DMA_BULKIN) | 421 | if(intrDMA & USB_INTR_DMA_BULKIN) |
305 | { | 422 | { |
306 | logf("DMA_BULKIN %d", ((REG_USB_REG_CNTL1 >> 4) & 0xF)); | 423 | logf("DMA_BULKIN %d", ((REG_USB_REG_CNTL1 >> 4) & 0xF)); |
307 | usb_core_transfer_complete(((REG_USB_REG_CNTL1 >> 4) & 0xF) | USB_DIR_IN, USB_DIR_IN, 0, 0); | 424 | usb_core_transfer_complete(1 | USB_DIR_IN, USB_DIR_IN, 0, 0); |
308 | } | 425 | } |
309 | if(intrDMA & USB_INTR_DMA_BULKOUT) | 426 | if(intrDMA & USB_INTR_DMA_BULKOUT) |
310 | { | 427 | { |
311 | logf("DMA_BULKOUT %d", ((REG_USB_REG_CNTL2 >> 4) & 0xF)); | 428 | logf("DMA_BULKOUT %d", ((REG_USB_REG_CNTL2 >> 4) & 0xF)); |
312 | usb_core_transfer_complete(((REG_USB_REG_CNTL2 >> 4) & 0xF) | USB_DIR_OUT, USB_DIR_OUT, 0, 0); | 429 | |
430 | select_endpoint(1); | ||
431 | REG_USB_REG_OUTCSR &= ~(USB_OUTCSRH_DMAREQENAB | USB_OUTCSR_OUTPKTRDY); | ||
432 | |||
433 | usb_core_transfer_complete(1 | USB_DIR_OUT, USB_DIR_OUT, 0, 0); | ||
313 | } | 434 | } |
314 | } | 435 | } |
315 | 436 | ||
@@ -317,7 +438,7 @@ bool usb_drv_stalled(int endpoint, bool in) | |||
317 | { | 438 | { |
318 | logf("usb_drv_stalled(%d, %s)", endpoint, in?"IN":"OUT"); | 439 | logf("usb_drv_stalled(%d, %s)", endpoint, in?"IN":"OUT"); |
319 | 440 | ||
320 | select_endpoint(endpoint); | 441 | select_endpoint(endpoint & 0x7F); |
321 | 442 | ||
322 | if(endpoint == 0) | 443 | if(endpoint == 0) |
323 | return (REG_USB_REG_CSR0 & USB_CSR0_SENDSTALL) != 0; | 444 | return (REG_USB_REG_CSR0 & USB_CSR0_SENDSTALL) != 0; |
@@ -332,7 +453,7 @@ bool usb_drv_stalled(int endpoint, bool in) | |||
332 | 453 | ||
333 | void usb_drv_stall(int endpoint, bool stall, bool in) | 454 | void usb_drv_stall(int endpoint, bool stall, bool in) |
334 | { | 455 | { |
335 | logf("usb_drv_stall(%d,%s,%s)", endpoint, stall?"y":"n", in?"IN":"OUT"); | 456 | logf("usb_drv_stall(%d,%s,%s)", endpoint, stall?"Y":"N", in?"IN":"OUT"); |
336 | 457 | ||
337 | select_endpoint(endpoint); | 458 | select_endpoint(endpoint); |
338 | 459 | ||
@@ -350,14 +471,14 @@ void usb_drv_stall(int endpoint, bool stall, bool in) | |||
350 | if(stall) | 471 | if(stall) |
351 | REG_USB_REG_INCSR |= USB_INCSR_SENDSTALL; | 472 | REG_USB_REG_INCSR |= USB_INCSR_SENDSTALL; |
352 | else | 473 | else |
353 | REG_USB_REG_INCSR &= ~USB_INCSR_SENDSTALL; | 474 | REG_USB_REG_INCSR = (REG_USB_REG_INCSR & ~USB_INCSR_SENDSTALL) | USB_INCSR_CDT; |
354 | } | 475 | } |
355 | else | 476 | else |
356 | { | 477 | { |
357 | if(stall) | 478 | if(stall) |
358 | REG_USB_REG_OUTCSR |= USB_OUTCSR_SENDSTALL; | 479 | REG_USB_REG_OUTCSR |= USB_OUTCSR_SENDSTALL; |
359 | else | 480 | else |
360 | REG_USB_REG_OUTCSR &= ~USB_OUTCSR_SENDSTALL; | 481 | REG_USB_REG_OUTCSR = (REG_USB_REG_OUTCSR & ~USB_OUTCSR_SENDSTALL) | USB_OUTCSR_CDT; |
361 | } | 482 | } |
362 | } | 483 | } |
363 | } | 484 | } |
@@ -388,12 +509,13 @@ void usb_enable(bool on) | |||
388 | 509 | ||
389 | void usb_drv_init(void) | 510 | void usb_drv_init(void) |
390 | { | 511 | { |
512 | logf("usb_drv_init()"); | ||
513 | |||
391 | /* Set this bit to allow the UDC entering low-power mode when | 514 | /* Set this bit to allow the UDC entering low-power mode when |
392 | * there are no actions on the USB bus. | 515 | * there are no actions on the USB bus. |
393 | * UDC still works during this bit was set. | 516 | * UDC still works during this bit was set. |
394 | */ | 517 | */ |
395 | //__cpm_stop_udc(); | 518 | //__cpm_stop_udc(); |
396 | |||
397 | __cpm_start_udc(); | 519 | __cpm_start_udc(); |
398 | 520 | ||
399 | /* Enable the USB PHY */ | 521 | /* Enable the USB PHY */ |
@@ -404,6 +526,8 @@ void usb_drv_init(void) | |||
404 | 526 | ||
405 | void usb_drv_exit(void) | 527 | void usb_drv_exit(void) |
406 | { | 528 | { |
529 | logf("usb_drv_exit()"); | ||
530 | |||
407 | /* Disable interrupts */ | 531 | /* Disable interrupts */ |
408 | REG_USB_REG_INTRINE = 0; | 532 | REG_USB_REG_INTRINE = 0; |
409 | REG_USB_REG_INTROUTE = 0; | 533 | REG_USB_REG_INTROUTE = 0; |
@@ -413,7 +537,7 @@ void usb_drv_exit(void) | |||
413 | REG_USB_REG_CNTL1 = 0; | 537 | REG_USB_REG_CNTL1 = 0; |
414 | REG_USB_REG_CNTL2 = 0; | 538 | REG_USB_REG_CNTL2 = 0; |
415 | 539 | ||
416 | /* Disconnect from usb */ | 540 | /* Disconnect from USB */ |
417 | REG_USB_REG_POWER &= ~USB_POWER_SOFTCONN; | 541 | REG_USB_REG_POWER &= ~USB_POWER_SOFTCONN; |
418 | 542 | ||
419 | /* Disable the USB PHY */ | 543 | /* Disable the USB PHY */ |
@@ -431,32 +555,71 @@ void usb_drv_set_address(int address) | |||
431 | 555 | ||
432 | int usb_drv_send(int endpoint, void* ptr, int length) | 556 | int usb_drv_send(int endpoint, void* ptr, int length) |
433 | { | 557 | { |
434 | logf("usb_drv_send(%d, 0x%x, %d)", endpoint, (int)ptr, length); | 558 | int flags; |
435 | 559 | endpoint &= 0x7F; | |
436 | if(endpoint == EP_CONTROL && ptr == NULL && length == 0) /* ACK request */ | ||
437 | return 0; | ||
438 | 560 | ||
561 | logf("usb_drv_send(%d, 0x%x, %d)", endpoint, (int)ptr, length); | ||
562 | |||
439 | if(endpoint == EP_CONTROL) | 563 | if(endpoint == EP_CONTROL) |
440 | { | 564 | { |
565 | flags = disable_irq_save(); | ||
441 | endpoints[1].buf = ptr; | 566 | endpoints[1].buf = ptr; |
442 | endpoints[1].sent = 0; | 567 | endpoints[1].sent = 0; |
443 | endpoints[1].length = length; | 568 | endpoints[1].length = length; |
444 | ep0state = USB_EP0_TX; | 569 | ep0state = USB_EP0_TX; |
445 | EP0_send(); | 570 | EP0_send(); |
571 | |||
572 | restore_irq(flags); | ||
446 | return 0; | 573 | return 0; |
447 | } | 574 | } |
448 | else | 575 | else if(endpoint == 1) |
576 | { | ||
577 | #if 0 | ||
578 | select_endpoint(endpoint); | ||
579 | |||
580 | REG_USB_REG_ADDR2 = ((unsigned long)ptr) & 0x7fffffff; | ||
581 | REG_USB_REG_COUNT2 = length; | ||
582 | REG_USB_REG_CNTL2 = 1; | ||
583 | #else | ||
584 | flags = disable_irq_save(); | ||
585 | endpoints[3].buf = ptr; | ||
586 | endpoints[3].sent = 0; | ||
587 | endpoints[3].length = length; | ||
588 | EPIN_handler(1); | ||
589 | restore_irq(flags); | ||
590 | #endif | ||
449 | return 0; | 591 | return 0; |
592 | } | ||
593 | else | ||
594 | return -1; | ||
595 | } | ||
596 | |||
597 | int usb_drv_send_nonblocking(int endpoint, void* ptr, int length) | ||
598 | { | ||
599 | return usb_drv_send(endpoint, ptr, length); | ||
450 | } | 600 | } |
451 | 601 | ||
452 | int usb_drv_recv(int endpoint, void* ptr, int length) | 602 | int usb_drv_recv(int endpoint, void* ptr, int length) |
453 | { | 603 | { |
604 | int flags; | ||
605 | endpoint &= 0x7F; | ||
606 | |||
454 | logf("usb_drv_recv(%d, 0x%x, %d)", endpoint, (int)ptr, length); | 607 | logf("usb_drv_recv(%d, 0x%x, %d)", endpoint, (int)ptr, length); |
455 | 608 | ||
456 | if(endpoint == EP_CONTROL && ptr == NULL && length == 0) /* ACK request */ | 609 | if(endpoint == EP_CONTROL && ptr == NULL && length == 0) |
610 | return 0; /* ACK request, handled by the USB controller */ | ||
611 | else if(endpoint == 1) | ||
612 | { | ||
613 | logf("EP1 handled: %d", length); | ||
614 | flags = disable_irq_save(); | ||
615 | endpoints[2].buf = ptr; | ||
616 | endpoints[2].received = 0; | ||
617 | endpoints[2].length = length; | ||
618 | restore_irq(flags); | ||
457 | return 0; | 619 | return 0; |
458 | 620 | } | |
459 | return -1; | 621 | else |
622 | return -1; | ||
460 | } | 623 | } |
461 | 624 | ||
462 | void usb_drv_set_test_mode(int mode) | 625 | void usb_drv_set_test_mode(int mode) |
@@ -492,13 +655,18 @@ void usb_drv_cancel_all_transfers(void) | |||
492 | { | 655 | { |
493 | logf("usb_drv_cancel_all_transfers()"); | 656 | logf("usb_drv_cancel_all_transfers()"); |
494 | 657 | ||
495 | unsigned int i; | 658 | unsigned int i, flags; |
659 | flags = disable_irq_save(); | ||
660 | |||
496 | for(i=0; i<TOTAL_EP(); i++) | 661 | for(i=0; i<TOTAL_EP(); i++) |
497 | { | 662 | { |
498 | endpoints[i].sent = 0; | 663 | endpoints[i].sent = 0; |
499 | endpoints[i].length = 0; | 664 | endpoints[i].length = 0; |
500 | /* TODO: flush FIFO's ? */ | 665 | |
666 | select_endpoint(i/2); | ||
667 | flushFIFO(&endpoints[i]); | ||
501 | } | 668 | } |
669 | restore_irq(flags); | ||
502 | 670 | ||
503 | ep0state = USB_EP0_IDLE; | 671 | ep0state = USB_EP0_IDLE; |
504 | } | 672 | } |
@@ -512,8 +680,14 @@ void usb_drv_release_endpoint(int ep) | |||
512 | 680 | ||
513 | int usb_drv_request_endpoint(int dir) | 681 | int usb_drv_request_endpoint(int dir) |
514 | { | 682 | { |
515 | logf("usb_drv_request_endpoint(%d)", dir); | 683 | logf("usb_drv_request_endpoint(%s)", dir == USB_DIR_IN ? "IN" : "OUT"); |
516 | 684 | ||
517 | (void)dir; | 685 | /* There are only 3+2 endpoints, so hardcode this ... */ |
518 | return -1; | 686 | /* Currently only BULK endpoints ... */ |
687 | if(dir == USB_DIR_OUT) | ||
688 | return (1 | USB_DIR_OUT); | ||
689 | else if(dir == USB_DIR_IN) | ||
690 | return (1 | USB_DIR_IN); | ||
691 | else | ||
692 | return -1; | ||
519 | } | 693 | } |