summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorMaurus Cuelenaere <mcuelenaere@gmail.com>2008-08-26 21:48:49 +0000
committerMaurus Cuelenaere <mcuelenaere@gmail.com>2008-08-26 21:48:49 +0000
commit62c4a2838eea24dc41a65e4fc567e386f07c32e4 (patch)
tree47bd1e837c3f3da5e9cd4156f2fff98526e5b90a /firmware
parent753350154ea04c8369225b9c1dc1840dc6fcd1d4 (diff)
Onda VX747:
* Overall cleanup (still needs work) * Add preliminary USB support * Add power off support * Add preliminary MMU handling git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18348 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/SOURCES1
-rw-r--r--firmware/export/mipsregs.h2
-rw-r--r--firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c4
-rw-r--r--firmware/target/mips/ingenic_jz47xx/boot.lds48
-rw-r--r--firmware/target/mips/ingenic_jz47xx/crt0.S85
-rw-r--r--firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c8
-rw-r--r--firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c2
-rw-r--r--firmware/target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c101
-rw-r--r--firmware/target/mips/ingenic_jz47xx/system-jz4740.c175
-rw-r--r--firmware/target/mips/ingenic_jz47xx/system-target.h2
-rw-r--r--firmware/target/mips/ingenic_jz47xx/usb-jz4740.c1037
-rw-r--r--firmware/target/mips/ingenic_jz47xx/usb-target.h (renamed from firmware/target/mips/ingenic_jz47xx/onda_vx747/usb-target.h)7
12 files changed, 1354 insertions, 118 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 17545b99a6..24be9e58ae 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -1084,6 +1084,7 @@ target/mips/ingenic_jz47xx/ata-nand-jz4740.c
target/mips/ingenic_jz47xx/lcd-jz4740.c
target/mips/ingenic_jz47xx/kernel-jz4740.c
target/mips/ingenic_jz47xx/system-jz4740.c
+target/mips/ingenic_jz47xx/usb-jz4740.c
drivers/nand_id.c
#endif
diff --git a/firmware/export/mipsregs.h b/firmware/export/mipsregs.h
index 1247261e69..2ac5202ed6 100644
--- a/firmware/export/mipsregs.h
+++ b/firmware/export/mipsregs.h
@@ -706,6 +706,8 @@ do { \
#define read_c0_cache() __read_32bit_c0_register($7, 0) /* TX39xx */
#define write_c0_cache(val) __write_32bit_c0_register($7, 0, val)
+#define read_c0_badvaddr() __read_32bit_c0_register($8, 0)
+
#define read_c0_count() __read_32bit_c0_register($9, 0)
#define write_c0_count(val) __write_32bit_c0_register($9, 0, val)
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c
index c6eb55f0b9..20a7256f82 100644
--- a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c
@@ -42,7 +42,9 @@
#define NANDFLASH_ALE 0x00010000 //PA[16]
#define NANDFLASH_BASE 0xB8000000
-#define REG_NAND_DATA (*((volatile unsigned char *)NANDFLASH_BASE))
+#define REG_NAND_DATA8 (*((volatile unsigned char *)NANDFLASH_BASE))
+#define REG_NAND_DATA16 (*((volatile unsigned short *)NANDFLASH_BASE))
+#define REG_NAND_DATA REG_NAND_DATA8
#define REG_NAND_CMD (*((volatile unsigned char *)(NANDFLASH_BASE + NANDFLASH_CLE)))
#define REG_NAND_ADDR (*((volatile unsigned char *)(NANDFLASH_BASE + NANDFLASH_ALE)))
diff --git a/firmware/target/mips/ingenic_jz47xx/boot.lds b/firmware/target/mips/ingenic_jz47xx/boot.lds
index e3ff0c0cd7..0ea8877714 100644
--- a/firmware/target/mips/ingenic_jz47xx/boot.lds
+++ b/firmware/target/mips/ingenic_jz47xx/boot.lds
@@ -31,6 +31,10 @@ SECTIONS
*(.glue_7);
*(.glue_7t);
*(.rel.dyn);
+ } > DRAM
+
+ .vectors :
+ {
_vectorsstart = .;
KEEP(*(.vectors))
*(.vectors);
@@ -69,18 +73,6 @@ SECTIONS
. = ALIGN(4);
- .stack :
- {
- *(.stack)
- _stackbegin = .;
- stackbegin = .;
- . += 0x2000;
- _stackend = .;
- stackend = .;
- } > DRAM
-
- . = ALIGN(4);
-
.bss :
{
_edata = .;
@@ -91,4 +83,36 @@ SECTIONS
*(.scommon*);
_end = .;
} > DRAM
+
+ .iram IRAMORIG:
+ {
+ . = 0x220; /* Vectors take in 0x80000000 -> 0x80000220 */
+ _iramstart = .;
+ *(.icode)
+ *(.irodata)
+ *(.idata)
+ . = ALIGN(0x4);
+ _iramend = .;
+ } > IRAM AT> DRAM
+
+ _iramcopy = LOADADDR(.iram);
+
+ .ibss (NOLOAD) :
+ {
+ _iedata = .;
+ *(.ibss)
+ . = ALIGN(0x4);
+ _iend = .;
+ } > IRAM
+
+ .stack :
+ {
+ *(.stack)
+ . = ALIGN(0x4);
+ _stackbegin = .;
+ stackbegin = .;
+ . += 0x2000;
+ _stackend = .;
+ stackend = .;
+ } > IRAM
}
diff --git a/firmware/target/mips/ingenic_jz47xx/crt0.S b/firmware/target/mips/ingenic_jz47xx/crt0.S
index b9ffde3b65..f079b940a1 100644
--- a/firmware/target/mips/ingenic_jz47xx/crt0.S
+++ b/firmware/target/mips/ingenic_jz47xx/crt0.S
@@ -40,7 +40,7 @@
.text
- .set mips3
+ .set mips32
.extern system_main
@@ -53,28 +53,36 @@
.word 0 /* HACK */
.word 0 /* HACK */
#endif
+
_start:
la ra, _start
- //----------------------------------------------------
- // init cp0 registers.
- //----------------------------------------------------
+ /*
+ ----------------------------------------------------
+ init cp0 registers.
+ ----------------------------------------------------
+ */
mtc0 zero, C0_WATCHLO
mtc0 zero, C0_WATCHHI
li t0, (M_StatusBEV | M_StatusIM7 | M_StatusIM6 \
| M_StatusIM5 | M_StatusIM4 | M_StatusIM3 \
- | M_StatusIM2 | M_StatusERL)
- // BEV = Enable Boot Exception Vectors
- // IMx = Interrupt mask
- // ERL = Denotes error level
+ | M_StatusIM2 | M_StatusERL | M_StatusSM)
+ /*
+ BEV = Enable Boot Exception Vectors
+ IMx = Interrupt mask
+ ERL = Denotes error level
+ SM = Supervisor Mode
+ */
mtc0 t0, C0_STATUS
li t1, M_CauseIV
mtc0 t1, C0_CAUSE
- //----------------------------------------------------
- // init caches, assumes a 4way*128set*32byte i/d cache
- //----------------------------------------------------
+ /*
+ ----------------------------------------------------
+ init caches, assumes a 4way*128set*32byte i/d cache
+ ----------------------------------------------------
+ */
li t0, 3 // enable cache for kseg0 accesses
mtc0 t0, C0_CONFIG // CONFIG reg
la t0, 0x80000000 // an idx op should use a unmappable address
@@ -82,35 +90,70 @@ _start:
mtc0 zero, C0_TAGLO // TAGLO reg
mtc0 zero, C0_TAGHI // TAGHI reg
-_init_cache_loop:
+_init_cache_loop:
cache 0x8, 0(t0) // index store icache tag
cache 0x9, 0(t0) // index store dcache tag
bne t0, t1, _init_cache_loop
addiu t0, t0, 0x20 // 32 bytes per cache line
nop
- //----------------------------------------------------
- // Invalidate BTB
- //----------------------------------------------------
+ /*
+ ----------------------------------------------------
+ Invalidate BTB
+ ----------------------------------------------------
+ */
mfc0 t0, C0_CONFIG
nop
ori t0, 2
mtc0 t0, C0_CONFIG
nop
- //----------------------------------------------------
- // clear BSS section
- //----------------------------------------------------
+ /*
+ ----------------------------------------------------
+ clear BSS section
+ ----------------------------------------------------
+ */
la t0, _edata
la t1, _end
_init_bss_loop:
sw zero, 0(t0)
bne t0, t1, _init_bss_loop
addiu t0, 4
+
+#ifndef BOOTLOADER
+ /*
+ ----------------------------------------------------
+ clear IBSS section
+ ----------------------------------------------------
+ */
+ la t0, _iedata
+ la t1, _iend
+_init_ibss_loop:
+ sw zero, 0(t0)
+ bne t0, t1, _init_ibss_loop
+ addiu t0, 4
+
+ /*
+ ----------------------------------------------------
+ copy IRAM section
+ ----------------------------------------------------
+ */
+ la t0, _iramcopy
+ la t1, _iramstart
+ la t2, _iramend
+_init_iram_loop:
+ lw t3, 0(t0)
+ sw t3, 0(t1)
+ addiu t1, 4
+ bne t1, t2, _init_iram_loop
+ addiu t0, 4
+#endif
- //----------------------------------------------------
- // setup stack, jump to C code
- //----------------------------------------------------
+ /*
+ ----------------------------------------------------
+ setup stack, jump to C code
+ ----------------------------------------------------
+ */
la sp, stackend
la t0, stackbegin
li t1, 0xDEADBEEF
diff --git a/firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c b/firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c
index 29b581dd6b..62176cee24 100644
--- a/firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c
@@ -35,6 +35,11 @@ void tick_start(unsigned int interval_in_ms)
__tcu_stop_counter(0);
__tcu_disable_pwm_output(0);
+ __tcu_stop_counter(1);
+ __tcu_disable_pwm_output(1);
+ __tcu_stop_counter(2);
+ __tcu_disable_pwm_output(2);
+ __tcu_clear_full_match_flag(2);
__tcu_mask_half_match_irq(0);
__tcu_unmask_full_match_irq(0);
@@ -58,12 +63,13 @@ void tick_start(unsigned int interval_in_ms)
__tcu_start_counter(0);
system_enable_irq(IRQ_TCU0);
-
}
/* Interrupt handler */
void TCU0(void)
{
+ __tcu_clear_full_match_flag(0);
+
int i;
/* Run through the list of tick tasks */
diff --git a/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c b/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c
index ca082781aa..6bb7db8d9b 100644
--- a/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c
@@ -64,7 +64,7 @@ void lcd_update_rect(int x, int y, int width, int height)
REG_DMAC_DTAR(0) = 0x130500B0; /* SLCD_FIFO */
REG_DMAC_DTCR(0) = width*height;
- REG_DMAC_DCMD(0) = (DMAC_DCMD_SAI | DMAC_DCMD_RDIL_2 | DMAC_DCMD_SWDH_32 /* (1 << 23) | (0 << 16) | (0 << 14) */
+ REG_DMAC_DCMD(0) = (DMAC_DCMD_SAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 /* (1 << 23) | (0 << 16) | (0 << 14) */
| DMAC_DCMD_DWDH_16 | DMAC_DCMD_DS_16BIT); /* | (2 << 12) | (3 << 8) */
REG_DMAC_DCCSR(0) = (DMAC_DCCSR_NDES | DMAC_DCCSR_EN); /* (1 << 31) | (1 << 0) */
diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c b/firmware/target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c
index e937c90bd3..0f11782d3f 100644
--- a/firmware/target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c
+++ b/firmware/target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c
@@ -36,7 +36,7 @@
#define TS_AD_COUNT 5
#define M_SADC_CFG_SNUM ((TS_AD_COUNT - 1) << SADC_CFG_SNUM_BIT)
-#define SADC_CFG_INIT ( \
+#define SADC_CFG_INIT ( \
(2 << SADC_CFG_CLKOUT_NUM_BIT) | \
SADC_CFG_XYZ1Z2 | \
M_SADC_CFG_SNUM | \
@@ -109,6 +109,7 @@ int button_read_device(int *data)
unsigned int key = ~(__gpio_get_port(3));
int ret = 0;
+
if(key & BTN_MASK)
{
if(key & BTN_VOL_DOWN)
@@ -132,10 +133,33 @@ int button_read_device(int *data)
return ret;
}
+/*
+static enum touchpad_mode current_mode = TOUCHPAD_POINT;
+
+static bool touch_available = false;
+
+static int touchpad_buttons[3][3] =
+{
+ {BUTTON_TOPLEFT, BUTTON_TOPMIDDLE, BUTTON_TOPRIGHT},
+ {BUTTON_MIDLEFT, BUTTON_CENTER, BUTTON_MIDRIGHT},
+ {BUTTON_BOTTOMLEFT, BUTTON_BOTTOMMIDDLE, BUTTON_BOTTOMRIGHT}
+};
+
+void touchpad_set_mode(enum touchpad_mode mode)
+{
+ current_mode = mode;
+}
+
+enum touchpad_mode touchpad_get_mode(void)
+{
+ return current_mode;
+}
+
void button_set_touch_available(void)
{
- return;
+ touch_available = true;
}
+*/
/* Interrupt handler */
void SADC(void)
@@ -167,51 +191,50 @@ void SADC(void)
}
if(state & SADC_CTRL_TSRDYM)
{
- unsigned int dat;
- unsigned short xData, yData;
- short tsz1Data, tsz2Data;
-
- dat = REG_SADC_TSDAT;
-
- xData = (dat >> 0) & 0xfff;
- yData = (dat >> 16) & 0xfff;
-
- dat = REG_SADC_TSDAT;
+ unsigned int dat;
+ unsigned short xData, yData;
+ short tsz1Data, tsz2Data;
+
+ dat = REG_SADC_TSDAT;
+
+ xData = (dat >> 0) & 0xfff;
+ yData = (dat >> 16) & 0xfff;
+
+ dat = REG_SADC_TSDAT;
tsz1Data = (dat >> 0) & 0xfff;
- tsz2Data = (dat >> 16) & 0xfff;
+ tsz2Data = (dat >> 16) & 0xfff;
+
+ if(!pendown_flag)
+ return ;
- if(!pendown_flag)
- return ;
-
- tsz1Data = tsz2Data - tsz1Data;
-
- if((tsz1Data > 15) || (tsz1Data < -15))
+ tsz1Data = tsz2Data - tsz1Data;
+
+ if((tsz1Data > 15) || (tsz1Data < -15))
{
- if(x_pos == -1)
- x_pos = xData;
- else
- x_pos = (x_pos + xData) / 2;
-
- if(y_pos == -1)
- y_pos = yData;
- else
- y_pos = (y_pos + yData) / 2;
+ if(x_pos == -1)
+ x_pos = xData;
+ else
+ x_pos = (x_pos + xData) / 2;
+
+ if(y_pos == -1)
+ y_pos = yData;
+ else
+ y_pos = (y_pos + yData) / 2;
}
datacount++;
-
- if(datacount > TS_AD_COUNT - 1)
- {
- if(x_pos != -1)
- {
+
+ if(datacount > TS_AD_COUNT - 1)
+ {
+ if(x_pos != -1)
+ {
stable_x_pos = x_pos;
stable_y_pos = y_pos;
- x_pos = -1;
- y_pos = -1;
- }
-
- datacount = 0;
- }
+ x_pos = -1;
+ y_pos = -1;
+ }
+ datacount = 0;
+ }
}
if(state & SADC_CTRL_PBATRDYM)
{
diff --git a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
index 25b14106c4..8f1c3f5c1a 100644
--- a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
@@ -269,25 +269,15 @@ static void dis_irq(unsigned int irq)
static void ack_irq(unsigned int irq)
{
- __intc_ack_irq(irq);
if ((irq >= IRQ_GPIO_0) && (irq <= IRQ_GPIO_0 + NUM_GPIO))
{
__intc_ack_irq(IRQ_GPIO0 - ((irq - IRQ_GPIO_0)>>5));
__gpio_ack_irq(irq - IRQ_GPIO_0);
}
else if ((irq >= IRQ_DMA_0) && (irq <= IRQ_DMA_0 + NUM_DMA))
- {
__intc_ack_irq(IRQ_DMAC);
- }
else if (irq < 32)
- {
__intc_ack_irq(irq);
- /* TODO: check if really needed */
- if (irq == IRQ_TCU0)
- {
- __tcu_clear_full_match_flag(0);
- }
- }
}
static unsigned long ipl;
@@ -296,7 +286,7 @@ static int get_irq_number(void)
register int irq = 0;
ipl |= REG_INTC_IPR;
-
+
if (ipl == 0)
return -1;
@@ -341,8 +331,6 @@ void intr_handler(void)
ack_irq(irq);
if(irq > 0)
irqvector[irq-1]();
-
- return;
}
#define EXC(x,y) if(_cause == (x)) return (y);
@@ -386,7 +374,6 @@ static void detect_clock(void)
cfcr = REG_CPM_CPCCR;
pllout = (__cpm_get_pllm() + 2)* JZ_EXTAL / (__cpm_get_plln() + 2);
iclk = pllout / FR2n[__cpm_get_cdiv()];
- /*printf("EXTAL_CLK = %dM PLL = %d iclk = %d\r\n",EXTAL_CLK / 1000 /1000,pllout,iclk);*/
}
void udelay(unsigned int usec)
@@ -450,11 +437,11 @@ void sti(void)
#define SYNC_WB() __asm__ __volatile__ ("sync")
-#define cache_op(op,addr) \
+#define __CACHE_OP(op, addr) \
__asm__ __volatile__( \
" .set noreorder \n" \
" .set mips32\n\t \n" \
- " cache %0, %1 \n" \
+ " cache %0, %1 \n" \
" .set mips0 \n" \
" .set reorder \n" \
: \
@@ -462,7 +449,7 @@ void sti(void)
void __flush_dcache_line(unsigned long addr)
{
- cache_op(Hit_Writeback_Inv_D, addr);
+ __CACHE_OP(Hit_Writeback_Inv_D, addr);
SYNC_WB();
}
@@ -470,6 +457,7 @@ void __icache_invalidate_all(void)
{
unsigned int i;
+/*
do
{
unsigned long __k0_addr;
@@ -484,17 +472,19 @@ void __icache_invalidate_all(void)
: "r" (0x20000000)
);
} while(0);
+*/
asm volatile (".set noreorder \n"
".set mips32 \n"
- "mtc0 $0,$28 \n"
- "mtc0 $0,$29 \n"
+ "mtc0 $0, $28 \n" /* TagLo */
+ "mtc0 $0, $29 \n" /* TagHi */
".set mips0 \n"
".set reorder \n"
);
for(i=KSEG0; i<KSEG0+CACHE_SIZE; i+=CACHE_LINE_SIZE)
- cache_op(Index_Store_Tag_I, i);
+ __CACHE_OP(Index_Store_Tag_I, i);
+/*
do
{
unsigned long __k0_addr;
@@ -507,16 +497,17 @@ void __icache_invalidate_all(void)
: "=&r" (__k0_addr)
);
} while(0);
+*/
do
{
unsigned long tmp;
__asm__ __volatile__(
".set mips32 \n"
- "mfc0 %0, $16, 7 \n"
+ "mfc0 %0, $16, 7 \n" /* Config */
"nop \n"
"ori %0, 2 \n"
- "mtc0 %0, $16, 7 \n"
+ "mtc0 %0, $16, 7 \n" /* Config */
"nop \n"
".set mips0 \n"
: "=&r" (tmp));
@@ -529,20 +520,20 @@ void __dcache_invalidate_all(void)
asm volatile (".set noreorder \n"
".set mips32 \n"
- "mtc0 $0,$28 \n"
- "mtc0 $0,$29 \n"
+ "mtc0 $0, $28 \n"
+ "mtc0 $0, $29 \n"
".set mips0 \n"
".set reorder \n"
);
for (i=KSEG0; i<KSEG0+CACHE_SIZE; i+=CACHE_LINE_SIZE)
- cache_op(Index_Store_Tag_D, i);
+ __CACHE_OP(Index_Store_Tag_D, i);
}
void __dcache_writeback_all(void)
{
unsigned int i;
for(i=KSEG0; i<KSEG0+CACHE_SIZE; i+=CACHE_LINE_SIZE)
- cache_op(Index_Writeback_Inv_D, i);
+ __CACHE_OP(Index_Writeback_Inv_D, i);
SYNC_WB();
}
@@ -559,37 +550,129 @@ void dma_cache_wback_inv(unsigned long addr, unsigned long size)
a = addr & ~(dc_lsize - 1);
end = (addr + size - 1) & ~(dc_lsize - 1);
- while (1)
- {
+ for(; a < end; a += dc_lsize)
__flush_dcache_line(a); /* Hit_Writeback_Inv_D */
- if (a == end)
- break;
- a += dc_lsize;
- }
}
}
extern int main(void);
-extern unsigned int _vectorsstart; /* see boot.lds/app.lds */
+extern void except_common_entry(void);
+
+#define mtc0_tlbw_hazard() \
+ __asm__ __volatile__( \
+ " .set noreorder \n" \
+ " nop \n" \
+ " nop \n" \
+ " nop \n" \
+ " nop \n" \
+ " nop \n" \
+ " nop \n" \
+ " .set reorder \n");
+
+#define tlbw_use_hazard() \
+ __asm__ __volatile__( \
+ " .set noreorder \n" \
+ " nop \n" \
+ " nop \n" \
+ " nop \n" \
+ " nop \n" \
+ " nop \n" \
+ " nop \n" \
+ " .set reorder \n");
+
+
+#define PAGE_SHIFT PL_4K
+#define PM_DEFAULT_MASK PM_4K
+#define UNIQUE_ENTRYHI(idx) (A_K0BASE + ((idx) << (PAGE_SHIFT + 1)))
+static void local_flush_tlb_all(void)
+{
+ unsigned long old_ctx;
+ int entry;
+ unsigned int old_irq = disable_irq_save();
+
+ /* Save old context and create impossible VPN2 value */
+ old_ctx = read_c0_entryhi();
+ write_c0_entrylo0(0);
+ write_c0_entrylo1(0);
+
+ /* Blast 'em all away. */
+ for(entry = read_c0_wired(); entry < 32; entry++)
+ {
+ /* Make sure all entries differ. */
+ write_c0_entryhi(UNIQUE_ENTRYHI(entry));
+ write_c0_index(entry);
+ mtc0_tlbw_hazard();
+ tlb_write_indexed();
+ }
+ tlbw_use_hazard();
+ write_c0_entryhi(old_ctx);
+
+ restore_irq(old_irq);
+}
+
+
+static void tlb_init(void)
+{
+ write_c0_pagemask(PM_DEFAULT_MASK);
+ write_c0_wired(0);
+ write_c0_framemask(0);
+
+ local_flush_tlb_all();
+}
+
+static void tlb_refill_handler(void)
+{
+#if 1
+ panicf("TLB refill handler! [0x%x] [0x%x]", read_c0_badvaddr(), read_c0_epc());
+#else
+ __asm__ __volatile__(
+ "mfc0 k0, C0_BADVADDR\n"
+ "lui k1, pgdc\n"
+ "lw k1, pgdc>>16(k0)\n"
+ "srl k0, k0, 22\n"
+ "sll k0, k0, 2\n"
+ "addu k1, k1, k0\n"
+ "mfc0 k0, C0_CONTEXT\n"
+ "lw k1, 0(k1)\n"
+ "andi k0, k0, 0xFFC\n"
+ "addu k1, k1, k0\n"
+ "lw k0, 0(k1)\n"
+ "nop\n"
+ "mtc0 k0, C0_ENTRYLO0\n"
+ "mfc0 k1, C0_EPC\n"
+ "tlbwr\n"
+ "jr k1\n"
+ "rfe\n"
+ );
+#endif
+}
void system_main(void)
{
int i;
- cli();
- write_c0_status(1 << 28 | 1 << 10); /* Enable CP | Mask interrupt 2 */
-
- memcpy((void *)A_K0BASE, (void *)&_vectorsstart, 0x20);
- memcpy((void *)(A_K0BASE + 0x180), (void *)&_vectorsstart, 0x20);
- memcpy((void *)(A_K0BASE + 0x200), (void *)&_vectorsstart, 0x20);
+ /*
+ * 0x0 - Simple TLB refill handler
+ * 0x100 - Cache error handler
+ * 0x180 - Exception/Interrupt handler
+ * 0x200 - Special Exception Interrupt handler (when IV is set in CP0_CAUSE)
+ */
+ memcpy((void *)A_K0BASE, (void *)&tlb_refill_handler, 0x20);
+ memcpy((void *)(A_K0BASE + 0x100), (void *)&except_common_entry, 0x20);
+ memcpy((void *)(A_K0BASE + 0x180), (void *)&except_common_entry, 0x20);
+ memcpy((void *)(A_K0BASE + 0x200), (void *)&except_common_entry, 0x20);
__dcache_writeback_all();
__icache_invalidate_all();
+ write_c0_status(1 << 28 | 1 << 10 | 1 << 3); /* Enable CP | Mask interrupt 2 | Supervisor mode */
+
/* Disable all interrupts */
for(i=0; i<IRQ_MAX; i++)
dis_irq(i);
+ tlb_init();
+
sti();
detect_clock();
@@ -609,3 +692,17 @@ void system_reboot(void)
while (1);
}
+
+void power_off(void)
+{
+ /* Put system into hibernate mode */
+ __rtc_clear_alarm_flag();
+ __rtc_clear_hib_stat_all();
+ //__rtc_set_scratch_pattern(0x12345678);
+ __rtc_enable_alarm_wakeup();
+ __rtc_set_hrcr_val(0xfe0);
+ __rtc_set_hwfcr_val((0xFFFF << 4));
+ __rtc_power_down();
+
+ while(1);
+}
diff --git a/firmware/target/mips/ingenic_jz47xx/system-target.h b/firmware/target/mips/ingenic_jz47xx/system-target.h
index 7d4c28756a..01ba176dd2 100644
--- a/firmware/target/mips/ingenic_jz47xx/system-target.h
+++ b/firmware/target/mips/ingenic_jz47xx/system-target.h
@@ -99,6 +99,8 @@ void sti(void);
void cli(void);
void udelay(unsigned int usec);
void mdelay(unsigned int msec);
+void power_off(void);
+void system_reboot(void);
#endif /* __SYSTEM_TARGET_H_ */
diff --git a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c
new file mode 100644
index 0000000000..92a2f3b801
--- /dev/null
+++ b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c
@@ -0,0 +1,1037 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2008 by Maurus Cuelenaere
+ *
+ * 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 "config.h"
+#include "system.h"
+#include "usb_ch9.h"
+#include "usb_drv.h"
+#include "usb_core.h"
+#include "jz4740.h"
+#include "thread.h"
+
+#if 0
+
+#define EP1_INTR_BIT 2
+#define EP_FIFO_NOEMPTY 2
+
+#define GPIO_UDC_DETE_PIN (32 * 3 + 6)
+#define GPIO_UDC_DETE GPIO_UDC_DETE_PIN
+#define IRQ_GPIO_UDC_DETE (IRQ_GPIO_0 + GPIO_UDC_DETE)
+
+#define IS_CACHE(x) (x < 0xa0000000)
+
+bool usb_drv_connected(void)
+{
+ return (__gpio_get_pin(GPIO_UDC_DETE)==1);
+}
+
+int usb_detect(void)
+{
+ if(__gpio_get_pin(GPIO_UDC_DETE)==1)
+ return USB_INSERTED;
+ else
+ return USB_EXTRACTED;
+}
+
+void usb_init_device(void)
+{
+ system_enable_irq(IRQ_UDC);
+ __gpio_as_input(GPIO_UDC_DETE_PIN);
+ return;
+}
+
+void usb_enable(bool on)
+{
+ if(on)
+ usb_core_init();
+ else
+ usb_core_exit();
+}
+
+void usb_drv_init(void)
+{
+ /* Set this bit to allow the UDC entering low-power mode when
+ * there are no actions on the USB bus.
+ * UDC still works during this bit was set.
+ */
+ //__cpm_stop_udc();
+
+ __cpm_start_udc();
+
+ /* Enable the USB PHY */
+ REG_CPM_SCR |= CPM_SCR_USBPHY_ENABLE;
+
+ /* Disable interrupts */
+ REG_USB_REG_INTRINE = 0;
+ REG_USB_REG_INTROUTE = 0;
+ REG_USB_REG_INTRUSBE = 0;
+
+ /* Enable interrupts */
+ REG_USB_REG_INTRINE |= USB_INTR_EP0;
+ REG_USB_REG_INTRUSBE |= USB_INTR_RESET;
+
+ /* Enable SUSPEND */
+ /* usb_setb(USB_REG_POWER, USB_POWER_SUSPENDM); */
+
+ /* Enable HS Mode */
+ REG_USB_REG_POWER |= USB_POWER_HSENAB;
+
+ /* Let host detect UDC:
+ * Software must write a 1 to the PMR:USB_POWER_SOFTCONN bit to turn this
+ * transistor on and pull the USBDP pin HIGH.
+ */
+ REG_USB_REG_POWER |= USB_POWER_SOFTCONN;
+}
+
+void usb_drv_exit(void)
+{
+ /* Disable interrupts */
+ REG_USB_REG_INTRINE = 0;
+ REG_USB_REG_INTROUTE = 0;
+ REG_USB_REG_INTRUSBE = 0;
+
+ /* Disable DMA */
+ REG_USB_REG_CNTL1 = 0;
+ REG_USB_REG_CNTL2 = 0;
+
+ /* Disconnect from usb */
+ REG_USB_REG_POWER &= ~USB_POWER_SOFTCONN;
+
+ /* Disable the USB PHY */
+ REG_CPM_SCR &= ~CPM_SCR_USBPHY_ENABLE;
+
+ __cpm_stop_udc();
+}
+
+void usb_drv_set_address(int address)
+{
+ REG_USB_REG_FADDR = address;
+}
+
+/* Interrupt handler */
+void UDC(void)
+{
+
+}
+
+#else
+
+//------------------------------------------
+#ifndef u8
+#define u8 unsigned char
+#endif
+
+#ifndef u16
+#define u16 unsigned short
+#endif
+
+#ifndef u32
+#define u32 unsigned int
+#endif
+
+#ifndef s8
+#define s8 char
+#endif
+
+#ifndef s16
+#define s16 short
+#endif
+
+#ifndef s32
+#define s32 int
+#endif
+
+extern int usbdebug;
+
+enum USB_ENDPOINT_TYPE
+{
+ ENDPOINT_TYPE_CONTROL,
+ /* Typically used to configure a device when attached to the host.
+ * It may also be used for other device specific purposes, including
+ * control of other pipes on the device.
+ */
+ ENDPOINT_TYPE_ISOCHRONOUS,
+ /* Typically used for applications which need guaranteed speed.
+ * Isochronous transfer is fast but with possible data loss. A typical
+ * use is audio data which requires a constant data rate.
+ */
+ ENDPOINT_TYPE_BULK,
+ /* Typically used by devices that generate or consume data in relatively
+ * large and bursty quantities. Bulk transfer has wide dynamic latitude
+ * in transmission constraints. It can use all remaining available bandwidth,
+ * but with no guarantees on bandwidth or latency. Since the USB bus is
+ * normally not very busy, there is typically 90% or more of the bandwidth
+ * available for USB transfers.
+ */
+ ENDPOINT_TYPE_INTERRUPT
+ /* Typically used by devices that need guaranteed quick responses
+ * (bounded latency).
+ */
+};
+
+
+enum USB_STANDARD_REQUEST_CODE {
+ GET_STATUS,
+ CLEAR_FEATURE,
+ SET_FEATURE = 3,
+ SET_ADDRESS = 5,
+ GET_DESCRIPTOR,
+ SET_DESCRIPTOR,
+ GET_CONFIGURATION,
+ SET_CONFIGURATION,
+ GET_INTERFACE,
+ SET_INTERFACE,
+ SYNCH_FRAME
+};
+
+
+enum USB_DESCRIPTOR_TYPE {
+ DEVICE_DESCRIPTOR = 1,
+ CONFIGURATION_DESCRIPTOR,
+ STRING_DESCRIPTOR,
+ INTERFACE_DESCRIPTOR,
+ ENDPOINT_DESCRIPTOR,
+ DEVICE_QUALIFIER_DESCRIPTOR,
+ OTHER_SPEED_CONFIGURATION_DESCRIPTOR,
+ INTERFACE_POWER1_DESCRIPTOR
+};
+
+
+enum USB_FEATURE_SELECTOR {
+ ENDPOINT_HALT,
+ DEVICE_REMOTE_WAKEUP,
+ TEST_MODE
+};
+
+enum USB_CLASS_CODE {
+ CLASS_DEVICE,
+ CLASS_AUDIO,
+ CLASS_COMM_AND_CDC_CONTROL,
+ CLASS_HID,
+ CLASS_PHYSICAL = 0x05,
+ CLASS_STILL_IMAGING,
+ CLASS_PRINTER,
+ CLASS_MASS_STORAGE,
+ CLASS_HUB,
+ CLASS_CDC_DATA,
+ CLASS_SMART_CARD,
+ CLASS_CONTENT_SECURITY = 0x0d,
+ CLASS_VIDEO,
+ CLASS_DIAGNOSTIC_DEVICE = 0xdc,
+ CLASS_WIRELESS_CONTROLLER = 0xe0,
+ CLASS_MISCELLANEOUS = 0xef,
+ CLASS_APP_SPECIFIC = 0xfe,
+ CLASS_VENDOR_SPECIFIC = 0xff
+};
+
+
+typedef struct {
+ u8 bmRequestType;
+ u8 bRequest;
+ u16 wValue;
+ u16 wIndex;
+ u16 wLength;
+} __attribute__ ((packed)) USB_DeviceRequest;
+
+
+typedef struct {
+ u8 bLength;
+ u8 bDescriptorType;
+ u16 bcdUSB;
+ u8 bDeviceClass;
+ u8 bDeviceSubClass;
+ u8 bDeviceProtocol;
+ u8 bMaxPacketSize0;
+ u16 idVendor;
+ u16 idProduct;
+ u16 bcdDevice;
+ u8 iManufacturer;
+ u8 iProduct;
+ u8 iSerialNumber;
+ u8 bNumConfigurations;
+} __attribute__ ((packed)) USB_DeviceDescriptor;
+
+
+typedef struct {
+ u8 bLength;
+ u8 bDescriptorType;
+ u16 bcdUSB;
+ u8 bDeviceClass;
+ u8 bDeviceSubClass;
+ u8 bDeviceProtocol;
+ u8 bMaxPacketSize0;
+ u8 bNumConfigurations;
+ u8 bReserved;
+} __attribute__ ((packed)) USB_DeviceQualifierDescriptor;
+
+
+typedef struct {
+ u8 bLength;
+ u8 bDescriptorType;
+ u16 wTotalLength;
+ u8 bNumInterfaces;
+ u8 bConfigurationValue;
+ u8 iConfiguration;
+ u8 bmAttributes;
+ u8 MaxPower;
+} __attribute__ ((packed)) USB_ConfigDescriptor;
+
+
+typedef struct {
+ u8 bLength;
+ u8 bDescriptorType;
+ u16 wTotalLength;
+ u8 bNumInterfaces;
+ u8 bConfigurationValue;
+ u8 iConfiguration;
+ u8 bmAttributes;
+ u8 bMaxPower;
+} __attribute__ ((packed)) USB_OtherSpeedConfigDescriptor;
+
+
+typedef struct {
+ u8 bLength;
+ u8 bDescriptorType;
+ u8 bInterfaceNumber;
+ u8 bAlternateSetting;
+ u8 bNumEndpoints;
+ u8 bInterfaceClass;
+ u8 bInterfaceSubClass;
+ u8 bInterfaceProtocol;
+ u8 iInterface;
+} __attribute__ ((packed)) USB_InterfaceDescriptor;
+
+
+typedef struct {
+ u8 bLegth;
+ u8 bDescriptorType;
+ u8 bEndpointAddress;
+ u8 bmAttributes;
+ u16 wMaxPacketSize;
+ u8 bInterval;
+} __attribute__ ((packed)) USB_EndPointDescriptor;
+
+
+typedef struct {
+ u8 bLength;
+ u8 bDescriptorType;
+ u16 SomeDesriptor[1];
+} __attribute__ ((packed)) USB_StringDescriptor;
+//------------------------------------------
+#define MAX_EP0_SIZE 64
+#define MAX_EP1_SIZE 512
+
+#define USB_HS 0
+#define USB_FS 1
+#define USB_LS 2
+
+//definitions of EP0
+#define USB_EP0_IDLE 0
+#define USB_EP0_RX 1
+#define USB_EP0_TX 2
+/* Define maximum packet size for endpoint 0 */
+#define M_EP0_MAXP 64
+/* Endpoint 0 status structure */
+
+static __inline__ void usb_setb(u32 port, u8 val)
+{
+ volatile u8 *ioport = (volatile u8 *)(port);
+ *ioport = (*ioport) | val;
+}
+
+static __inline__ void usb_clearb(u32 port, u8 val)
+{
+ volatile u8 *ioport = (volatile u8 *)(port);
+ *ioport = (*ioport) & ~val;
+}
+
+static __inline__ void usb_setw(u32 port, u16 val)
+{
+ volatile u16 *ioport = (volatile u16 *)(port);
+ *ioport = (*ioport) | val;
+}
+
+static __inline__ void usb_clearw(u32 port, u16 val)
+{
+ volatile u16 *ioport = (volatile u16 *)(port);
+ *ioport = (*ioport) & ~val;
+}
+//---------------------------------
+#define BULK_OUT_BUF_SIZE 0x20000 //buffer size :
+#define BULK_IN_BUF_SIZE 0x20000 // too
+
+enum UDC_STATE
+{
+ IDLE,
+ BULK_IN,
+ BULK_OUT
+};
+
+enum USB_JZ4740_REQUEST //add for USB_BOOT
+{
+ VR_GET_CUP_INFO = 0,
+ VR_SET_DATA_ADDERSS,
+ VR_SET_DATA_LENGTH,
+ VR_FLUSH_CACHES,
+ VR_PROGRAM_START1,
+ VR_PROGRAM_START2,
+ VR_NOR_OPS,
+ VR_NAND_OPS,
+ VR_SDRAM_OPS,
+ VR_CONFIGRATION
+};
+
+enum NOR_OPS_TYPE
+{
+ NOR_INIT = 0,
+ NOR_QUERY,
+ NOR_WRITE,
+ NOR_ERASE_CHIP,
+ NOR_ERASE_SECTOR
+};
+
+enum NOR_FLASH_TYPE
+{
+ NOR_AM29 = 0,
+ NOR_SST28,
+ NOR_SST39x16,
+ NOR_SST39x8
+};
+
+enum NAND_OPS_TYPE
+{
+ NAND_QUERY = 0,
+ NAND_INIT,
+ NAND_MARK_BAD,
+ NAND_READ_OOB,
+ NAND_READ_RAW,
+ NAND_ERASE,
+ NAND_READ,
+ NAND_PROGRAM,
+ NAND_READ_TO_RAM
+};
+
+enum SDRAM_OPS_TYPE
+{
+ SDRAM_LOAD,
+
+};
+
+enum DATA_STRUCTURE_OB
+{
+ DS_flash_info ,
+ DS_hand
+};
+
+
+/*typedef enum _USB_BOOT_STATUS
+{
+ USB_NO_ERR =0 ,
+ GET_CPU_INFO_ERR,
+ SET_DATA_ADDRESS_ERR,
+ SET_DATA_LENGTH_ERR,
+ FLUSH_CAHCES_ERR,
+ PROGRAM_START1_ERR,
+ PROGRAM_START2_ERR,
+ NOR_OPS_ERR,
+ NAND_OPS_ERR,
+ NOR_FLASHTYPE_ERR,
+ OPS_NOTSUPPORT_ERR
+}USB_BOOT_STATUS;*/
+
+enum OPTION
+{
+ OOB_ECC,
+ OOB_NO_ECC,
+ NO_OOB,
+};
+//-------------------------
+static inline void jz_writeb(u32 address, u8 value)
+{
+ *((volatile u8 *)address) = value;
+}
+
+static inline void jz_writew(u32 address, u16 value)
+{
+ *((volatile u16 *)address) = value;
+}
+
+static inline void jz_writel(u32 address, u32 value)
+{
+ *((volatile u32 *)address) = value;
+}
+
+static inline u8 jz_readb(u32 address)
+{
+ return *((volatile u8 *)address);
+}
+
+static inline u16 jz_readw(u32 address)
+{
+ return *((volatile u16 *)address);
+}
+
+static inline u32 jz_readl(u32 address)
+{
+ return *((volatile u32 *)address);
+}
+//---------------------------
+
+#define TXFIFOEP0 USB_FIFO_EP0
+
+u32 Bulk_in_buf[BULK_IN_BUF_SIZE];
+u32 Bulk_out_buf[BULK_OUT_BUF_SIZE];
+u32 Bulk_in_size,Bulk_in_finish,Bulk_out_size;
+u16 handshake_PKT[4]={0,0,0,0};
+u8 udc_state;
+
+static u32 rx_buf[32];
+static u32 tx_buf[32];
+static u32 tx_size, rx_size, finished,fifo;
+static u8 ep0state,USB_Version;
+
+static u32 fifoaddr[] =
+{
+ TXFIFOEP0, TXFIFOEP0+4 ,TXFIFOEP0+8
+};
+
+static u32 fifosize[] = {
+ MAX_EP0_SIZE, MAX_EP1_SIZE
+};
+
+static void udcReadFifo(u8 *ptr, int size)
+{
+ u32 *d = (u32 *)ptr;
+ int s;
+ s = (size + 3) >> 2;
+ while (s--)
+ *d++ = REG32(fifo);
+}
+
+static void udcWriteFifo(u8 *ptr, int size)
+{
+ u32 *d = (u32 *)ptr;
+ u8 *c;
+ int s, q;
+
+ if (size > 0) {
+ s = size >> 2;
+ while (s--)
+ REG32(fifo) = *d++;
+ q = size & 3;
+ if (q) {
+ c = (u8 *)d;
+ while (q--)
+ REG8(fifo) = *c++;
+ }
+ }
+}
+
+void HW_SendPKT(int ep, const u8 *buf, int size)
+{
+ fifo = fifoaddr[ep];
+
+ if (ep!=0)
+ {
+ Bulk_in_size = size;
+ Bulk_in_finish = 0;
+ jz_writeb(USB_REG_INDEX, ep);
+ if (Bulk_in_size - Bulk_in_finish <= fifosize[ep])
+ {
+ udcWriteFifo((u8 *)((u32)buf+Bulk_in_finish),
+ Bulk_in_size - Bulk_in_finish);
+ usb_setb(USB_REG_INCSR, USB_INCSR_INPKTRDY);
+ Bulk_in_finish = Bulk_in_size;
+ } else
+ {
+ udcWriteFifo((u8 *)((u32)buf+Bulk_in_finish),
+ fifosize[ep]);
+ usb_setb(USB_REG_INCSR, USB_INCSR_INPKTRDY);
+ Bulk_in_finish += fifosize[ep];
+ }
+ }
+ else //EP0
+ {
+ tx_size = size;
+ finished = 0;
+ memcpy((void *)tx_buf, buf, size);
+ ep0state = USB_EP0_TX;
+ }
+}
+
+void HW_GetPKT(int ep, const u8 *buf, int size)
+{
+ memcpy((void *)buf, (u8 *)rx_buf, size);
+ fifo = fifoaddr[ep];
+ if (rx_size > size)
+ rx_size -= size;
+ else {
+ size = rx_size;
+ rx_size = 0;
+ }
+ memcpy((u8 *)rx_buf, (u8 *)((u32)rx_buf+size), rx_size);
+}
+
+static USB_DeviceDescriptor devDesc =
+{
+ sizeof(USB_DeviceDescriptor),
+ DEVICE_DESCRIPTOR, //1
+ 0x0200, //Version 2.0
+ 0xff, //Vendor spec class
+ 0xff,
+ 0xff,
+ 64, /* Ep0 FIFO size */
+ 0x601a, //vendor ID
+ 0xDEAD, //Product ID
+ 0xffff,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x01
+};
+
+#define CONFIG_DESCRIPTOR_LEN (sizeof(USB_ConfigDescriptor) + \
+ sizeof(USB_InterfaceDescriptor) + \
+ sizeof(USB_EndPointDescriptor) * 2)
+
+static struct {
+ USB_ConfigDescriptor configuration_descriptor;
+ USB_InterfaceDescriptor interface_descritor;
+ USB_EndPointDescriptor endpoint_descriptor[2];
+} __attribute__ ((packed)) confDesc = {
+ {
+ sizeof(USB_ConfigDescriptor),
+ CONFIGURATION_DESCRIPTOR,
+ CONFIG_DESCRIPTOR_LEN,
+ 0x01,
+ 0x01,
+ 0x00,
+ 0xc0, // Self Powered, no remote wakeup
+ 0x64 // Maximum power consumption 2000 mA
+ },
+ {
+ sizeof(USB_InterfaceDescriptor),
+ INTERFACE_DESCRIPTOR,
+ 0x00,
+ 0x00,
+ 0x02, /* ep number */
+ 0xff,
+ 0xff,
+ 0xff,
+ 0x00
+ },
+ {
+ {
+ sizeof(USB_EndPointDescriptor),
+ ENDPOINT_DESCRIPTOR,
+ (1 << 7) | 1,// endpoint 2 is IN endpoint
+ 2, /* bulk */
+ 512,
+ 16
+ },
+ {
+ sizeof(USB_EndPointDescriptor),
+ ENDPOINT_DESCRIPTOR,
+ (0 << 7) | 1,// endpoint 5 is OUT endpoint
+ 2, /* bulk */
+ 512, /* OUT EP FIFO size */
+ 16
+ }
+ }
+};
+
+void sendDevDescString(int size)
+{
+ u16 str_ret[13] = {
+ 0x031a,//0x1a=26 byte
+ 0x0041,
+ 0x0030,
+ 0x0030,
+ 0x0041,
+ 0x0030,
+ 0x0030,
+ 0x0041,
+ 0x0030,
+ 0x0030,
+ 0x0041,
+ 0x0030,
+ 0x0030
+ };
+ if(size >= 26)
+ size = 26;
+ str_ret[0] = (0x0300 | size);
+ HW_SendPKT(0, (u8 *)str_ret,size);
+}
+
+void sendDevDesc(int size)
+{
+ switch (size) {
+ case 18:
+ HW_SendPKT(0, (u8 *)&devDesc, sizeof(devDesc));
+ break;
+ default:
+ HW_SendPKT(0, (u8 *)&devDesc, 8);
+ break;
+ }
+}
+
+void sendConfDesc(int size)
+{
+ switch (size) {
+ case 9:
+ HW_SendPKT(0, (u8 *)&confDesc, 9);
+ break;
+ case 8:
+ HW_SendPKT(0, (u8 *)&confDesc, 8);
+ break;
+ default:
+ HW_SendPKT(0, (u8 *)&confDesc, sizeof(confDesc));
+ break;
+ }
+}
+
+void EP0_init(u32 out, u32 out_size, u32 in, u32 in_size)
+{
+ confDesc.endpoint_descriptor[0].bEndpointAddress = (1<<7) | in;
+ confDesc.endpoint_descriptor[0].wMaxPacketSize = in_size;
+ confDesc.endpoint_descriptor[1].bEndpointAddress = (0<<7) | out;
+ confDesc.endpoint_descriptor[1].wMaxPacketSize = out_size;
+}
+
+static void udc_reset(void)
+{
+ //data init
+ ep0state = USB_EP0_IDLE;
+ Bulk_in_size = 0;
+ Bulk_in_finish = 0;
+ Bulk_out_size = 0;
+ udc_state = IDLE;
+ tx_size = 0;
+ rx_size = 0;
+ finished = 0;
+ /* Enable the USB PHY */
+// REG_CPM_SCR |= CPM_SCR_USBPHY_ENABLE;
+ /* Disable interrupts */
+ jz_writew(USB_REG_INTRINE, 0);
+ jz_writew(USB_REG_INTROUTE, 0);
+ jz_writeb(USB_REG_INTRUSBE, 0);
+ jz_writeb(USB_REG_FADDR,0);
+ jz_writeb(USB_REG_POWER,0x60); //High speed
+ jz_writeb(USB_REG_INDEX,0);
+ jz_writeb(USB_REG_CSR0,0xc0);
+ jz_writeb(USB_REG_INDEX,1);
+ jz_writew(USB_REG_INMAXP,512);
+ jz_writew(USB_REG_INCSR,0x2048);
+ jz_writeb(USB_REG_INDEX,1);
+ jz_writew(USB_REG_OUTMAXP,512);
+ jz_writew(USB_REG_OUTCSR,0x0090);
+ jz_writew(USB_REG_INTRINE,0x3); //enable intr
+ jz_writew(USB_REG_INTROUTE,0x2);
+ jz_writeb(USB_REG_INTRUSBE,0x4);
+
+ if ((jz_readb(USB_REG_POWER)&0x10)==0)
+ {
+ jz_writeb(USB_REG_INDEX,1);
+ jz_writew(USB_REG_INMAXP,64);
+ jz_writew(USB_REG_INCSR,0x2048);
+ jz_writeb(USB_REG_INDEX,1);
+ jz_writew(USB_REG_OUTMAXP,64);
+ jz_writew(USB_REG_OUTCSR,0x0090);
+ USB_Version=USB_FS;
+ fifosize[1]=64;
+ EP0_init(1,64,1,64);
+ }
+ else
+ {
+ jz_writeb(USB_REG_INDEX,1);
+ jz_writew(USB_REG_INMAXP,512);
+ jz_writew(USB_REG_INCSR,0x2048);
+ jz_writeb(USB_REG_INDEX,1);
+ jz_writew(USB_REG_OUTMAXP,512);
+ jz_writew(USB_REG_OUTCSR,0x0090);
+ USB_Version=USB_HS;
+ fifosize[1]=512;
+ EP0_init(1,512,1,512);
+ }
+
+}
+
+void usbHandleStandDevReq(u8 *buf)
+{
+ USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf;
+ switch (dreq->bRequest) {
+ case GET_DESCRIPTOR:
+ if (dreq->bmRequestType == 0x80) /* Dev2Host */
+ switch(dreq->wValue >> 8)
+ {
+ case DEVICE_DESCRIPTOR:
+ sendDevDesc(dreq->wLength);
+ break;
+ case CONFIGURATION_DESCRIPTOR:
+ sendConfDesc(dreq->wLength);
+ break;
+ case STRING_DESCRIPTOR:
+ if (dreq->wLength == 0x02)
+ HW_SendPKT(0, "\x04\x03", 2);
+ else
+ sendDevDescString(dreq->wLength);
+ //HW_SendPKT(0, "\x04\x03\x09\x04", 2);
+ break;
+ }
+ ep0state=USB_EP0_TX;
+
+ break;
+ case SET_ADDRESS:
+ jz_writeb(USB_REG_FADDR,dreq->wValue);
+ break;
+ case GET_STATUS:
+ switch (dreq->bmRequestType) {
+ case 80: /* device */
+ HW_SendPKT(0, "\x01\x00", 2);
+ break;
+ case 81: /* interface */
+ case 82: /* ep */
+ HW_SendPKT(0, "\x00\x00", 2);
+ break;
+ }
+ ep0state=USB_EP0_TX;
+ break;
+ case CLEAR_FEATURE:
+ case SET_CONFIGURATION:
+ case SET_INTERFACE:
+ case SET_FEATURE:
+ break;
+ }
+}
+
+extern char printfbuf[256];
+
+int GET_CUP_INFO_Handle()
+{
+ HW_SendPKT(0, printfbuf, 64);
+ udc_state = IDLE;
+ return 0;
+}
+
+void usbHandleVendorReq(u8 *buf)
+{
+ int ret_state;
+ USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf;
+ switch (dreq->bRequest) {
+ case 0xAB:
+ ret_state=GET_CUP_INFO_Handle();
+ break;
+ case 0x12:
+ HW_SendPKT(0, "TEST", 4);
+ udc_state = IDLE;
+ break;
+ }
+}
+
+void Handshake_PKT(void)
+{
+ if (udc_state!=IDLE)
+ {
+ HW_SendPKT(1,(u8 *)handshake_PKT,sizeof(handshake_PKT));
+ udc_state = IDLE;
+ }
+}
+
+void usbHandleDevReq(u8 *buf)
+{
+ switch ((buf[0] & (3 << 5)) >> 5) {
+ case 0: /* Standard request */
+ usbHandleStandDevReq(buf);
+ break;
+ case 1: /* Class request */
+ break;
+ case 2: /* Vendor request */
+ usbHandleVendorReq(buf);
+ break;
+ }
+}
+
+void EP0_Handler (void)
+{
+ u8 byCSR0;
+
+/* Read CSR0 */
+ jz_writeb(USB_REG_INDEX, 0);
+ byCSR0 = jz_readb(USB_REG_CSR0);
+
+/* Check for SentStall
+ if sendtall is set ,clear the sendstall bit*/
+ if (byCSR0 & USB_CSR0_SENTSTALL)
+ {
+ jz_writeb(USB_REG_CSR0, (byCSR0 & ~USB_CSR0_SENDSTALL));
+ ep0state = USB_EP0_IDLE;
+ return;
+ }
+
+/* Check for SetupEnd */
+ if (byCSR0 & USB_CSR0_SETUPEND)
+ {
+ jz_writeb(USB_REG_CSR0, (byCSR0 | USB_CSR0_SVDSETUPEND));
+ ep0state = USB_EP0_IDLE;
+ return;
+ }
+/* Call relevant routines for endpoint 0 state */
+ if (ep0state == USB_EP0_IDLE)
+ {
+ if (byCSR0 & USB_CSR0_OUTPKTRDY) //There are datas in fifo
+ {
+ USB_DeviceRequest *dreq;
+ fifo=fifoaddr[0];
+ udcReadFifo((u8 *)rx_buf, sizeof(USB_DeviceRequest));
+ usb_setb(USB_REG_CSR0, 0x48);//clear OUTRD bit
+ dreq = (USB_DeviceRequest *)rx_buf;
+ usbHandleDevReq((u8 *)rx_buf);
+ }
+ rx_size = 0;
+ }
+
+ if (ep0state == USB_EP0_TX)
+ {
+ fifo=fifoaddr[0];
+ if (tx_size - finished <= 64)
+ {
+ udcWriteFifo((u8 *)((u32)tx_buf+finished),
+ tx_size - finished);
+ finished = tx_size;
+ usb_setb(USB_REG_CSR0, USB_CSR0_INPKTRDY);
+ usb_setb(USB_REG_CSR0, USB_CSR0_DATAEND); //Set dataend!
+ ep0state=USB_EP0_IDLE;
+ } else
+ {
+ udcWriteFifo((u8 *)((u32)tx_buf+finished), 64);
+ usb_setb(USB_REG_CSR0, USB_CSR0_INPKTRDY);
+ finished += 64;
+ }
+ }
+ return;
+}
+
+void EPIN_Handler(u8 EP)
+{
+ jz_writeb(USB_REG_INDEX, EP);
+ fifo = fifoaddr[EP];
+
+ if (Bulk_in_size-Bulk_in_finish==0)
+ {
+ Handshake_PKT();
+ return;
+ }
+
+ if (Bulk_in_size - Bulk_in_finish <= fifosize[EP])
+ {
+ udcWriteFifo((u8 *)((u32)Bulk_in_buf+Bulk_in_finish),
+ Bulk_in_size - Bulk_in_finish);
+ usb_setw(USB_REG_INCSR, USB_INCSR_INPKTRDY);
+ Bulk_in_finish = Bulk_in_size;
+ } else
+ {
+ udcWriteFifo((u8 *)((u32)Bulk_in_buf+Bulk_in_finish),
+ fifosize[EP]);
+ usb_setw(USB_REG_INCSR, USB_INCSR_INPKTRDY);
+ Bulk_in_finish += fifosize[EP];
+ }
+}
+
+void EPOUT_Handler(u8 EP)
+{
+ u32 size;
+ jz_writeb(USB_REG_INDEX, EP);
+ size = jz_readw(USB_REG_OUTCOUNT);
+ fifo = fifoaddr[EP];
+ udcReadFifo((u8 *)((u32)Bulk_out_buf+Bulk_out_size), size);
+ usb_clearb(USB_REG_OUTCSR,USB_OUTCSR_OUTPKTRDY);
+ Bulk_out_size += size;
+}
+
+void UDC(void)
+{
+ u8 IntrUSB;
+ u16 IntrIn;
+ u16 IntrOut;
+/* Read interrupt registers */
+ IntrUSB = jz_readb(USB_REG_INTRUSB);
+ IntrIn = jz_readw(USB_REG_INTRIN);
+ IntrOut = jz_readw(USB_REG_INTROUT);
+
+ if ( IntrUSB == 0 && IntrIn == 0 && IntrOut == 0)
+ return;
+
+ if (IntrIn & 2)
+ {
+ EPIN_Handler(1);
+ }
+ if (IntrOut & 2)
+ {
+ EPOUT_Handler(1);
+ }
+ if (IntrUSB & USB_INTR_RESET)
+ {
+ udc_reset();
+ }
+
+/* Check for endpoint 0 interrupt */
+ if (IntrIn & USB_INTR_EP0)
+ {
+ EP0_Handler();
+ }
+
+ IntrIn = jz_readw(USB_REG_INTRIN);
+ return;
+}
+
+void __udc_start(void)
+{
+ udc_reset();
+
+ ep0state = USB_EP0_IDLE;
+ Bulk_in_size = 0;
+ Bulk_in_finish = 0;
+ Bulk_out_size = 0;
+ udc_state = IDLE;
+ tx_size = 0;
+ rx_size = 0;
+ finished = 0;
+
+ if ((jz_readb(USB_REG_POWER)&0x10)==0)
+ {
+ USB_Version=USB_FS;
+ fifosize[1]=64;
+ EP0_init(1,64,1,64);
+ }
+ else
+ {
+ USB_Version=USB_HS;
+ fifosize[1]=512;
+ EP0_init(1,512,1,512);
+ }
+
+ USB_Version=USB_HS;
+ system_enable_irq(IRQ_UDC);
+}
+
+void usb_init_device(void){}
+
+#endif
diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx747/usb-target.h b/firmware/target/mips/ingenic_jz47xx/usb-target.h
index 30893aaaa3..ec700de892 100644
--- a/firmware/target/mips/ingenic_jz47xx/onda_vx747/usb-target.h
+++ b/firmware/target/mips/ingenic_jz47xx/usb-target.h
@@ -18,9 +18,8 @@
* KIND, either express or implied.
*
****************************************************************************/
-#ifndef USB_TARGET_H
-#define USB_TARGET_H
+#include <stdbool.h>
+int usb_detect(void);
void usb_init_device(void);
-
-#endif
+bool usb_drv_connected(void);