summaryrefslogtreecommitdiff
path: root/firmware/target
diff options
context:
space:
mode:
authorMaurus Cuelenaere <mcuelenaere@gmail.com>2008-12-20 01:48:46 +0000
committerMaurus Cuelenaere <mcuelenaere@gmail.com>2008-12-20 01:48:46 +0000
commitc983e3b1d25503e71d0d7cba7c921b16c216770b (patch)
treee0c0b53295106e144be44f93817c961d57e41174 /firmware/target
parent0301ed559451ba4561b21e438d29b9ee29e31353 (diff)
Ingenic targets:
* LCD rework * Dynamic DMA enabling * PCM cleanup * USB: replace printf() with logf() * System: get rid of in_interrupt_mode() * Backlight: add support for software PWM git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19495 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target')
-rw-r--r--firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c8
-rw-r--r--firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c18
-rw-r--r--firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c91
-rw-r--r--firmware/target/mips/ingenic_jz47xx/onda_vx747/backlight-onda_vx747.c100
-rw-r--r--firmware/target/mips/ingenic_jz47xx/onda_vx747/backlight-target.h1
-rw-r--r--firmware/target/mips/ingenic_jz47xx/onda_vx747/lcd-onda_vx747.c6
-rw-r--r--firmware/target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c2
-rw-r--r--firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c41
-rw-r--r--firmware/target/mips/ingenic_jz47xx/system-jz4740.c104
-rw-r--r--firmware/target/mips/ingenic_jz47xx/system-target.h5
-rw-r--r--firmware/target/mips/ingenic_jz47xx/usb-jz4740.c40
11 files changed, 251 insertions, 165 deletions
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c
index 979a9067d3..a4b4a86a55 100644
--- a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c
@@ -138,6 +138,8 @@ static void jz_nand_write_dma(void *source, unsigned int len, int bw)
if(((unsigned int)source < 0xa0000000) && len)
dma_cache_wback_inv((unsigned long)source, len);
+
+ dma_enable();
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = 0;
REG_DMAC_DSAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)source);
@@ -151,6 +153,8 @@ static void jz_nand_write_dma(void *source, unsigned int len, int bw)
while( REG_DMAC_DTCR(DMA_NAND_CHANNEL) )
yield();
+ dma_disable();
+
mutex_unlock(&nand_mtx);
}
@@ -161,6 +165,8 @@ static void jz_nand_read_dma(void *target, unsigned int len, int bw)
if(((unsigned int)target < 0xa0000000) && len)
dma_cache_wback_inv((unsigned long)target, len);
+ dma_enable();
+
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = 0;
REG_DMAC_DSAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)NAND_DATAPORT);
REG_DMAC_DTAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)target);
@@ -172,6 +178,8 @@ static void jz_nand_read_dma(void *target, unsigned int len, int bw)
while( REG_DMAC_DTCR(DMA_NAND_CHANNEL) )
yield();
+ dma_disable();
+
mutex_unlock(&nand_mtx);
}
diff --git a/firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c b/firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c
index dcfdfd6a38..431af490da 100644
--- a/firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c
@@ -24,38 +24,26 @@
#include "kernel.h"
#include "jz4740.h"
-#define USE_RTC_CLOCK 0
void tick_start(unsigned int interval_in_ms)
{
- unsigned int tps = interval_in_ms;
unsigned int latch;
+
__cpm_start_tcu();
__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);
-#if USE_RTC_CLOCK
- __tcu_select_rtcclk(0);
- __tcu_select_clk_div1(0);
- latch = (__cpm_get_rtcclk() + (tps>>1)) / tps;
-#else
__tcu_select_extalclk(0);
__tcu_select_clk_div4(0);
- latch = (JZ_EXTAL / 4 + (tps>>1)) / tps;
-#endif
+ latch = (JZ_EXTAL / 4 + (interval_in_ms>>1)) / interval_in_ms;
+
REG_TCU_TCNT(0) = 0;
REG_TCU_TDFR(0) = latch;
REG_TCU_TDHR(0) = latch;
- //REG_TCU_TDHR(0) = 0;
__tcu_clear_full_match_flag(0);
__tcu_start_counter(0);
diff --git a/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c b/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c
index 1401bf8a3f..996731c0cd 100644
--- a/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c
@@ -25,9 +25,16 @@
#include "lcd-target.h"
#include "system.h"
#include "kernel.h"
+#include "backlight-target.h"
+
+/*
+ Warning: code behaviour is unpredictable when threads get switched in IRQ mode!
+ So don't update the LCD in an interrupt handler!
+ */
static volatile bool lcd_is_on = false;
static struct mutex lcd_mtx;
+static struct wakeup lcd_wkup;
/* LCD init */
void lcd_init_device(void)
@@ -35,6 +42,8 @@ void lcd_init_device(void)
lcd_init_controller();
lcd_is_on = true;
mutex_init(&lcd_mtx);
+ wakeup_init(&lcd_wkup);
+ system_enable_irq(DMA_IRQ(DMA_LCD_CHANNEL));
}
void lcd_enable(bool state)
@@ -55,73 +64,75 @@ bool lcd_enabled(void)
return lcd_is_on;
}
-/* Don't switch threads when in interrupt mode! */
-static inline void lcd_lock(void)
-{
- if(LIKELY(!in_interrupt_mode()))
- mutex_lock(&lcd_mtx);
- else
- while( !(REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_TT));
-}
-
-static inline void lcd_unlock(void)
-{
- if(LIKELY(!in_interrupt_mode()))
- mutex_unlock(&lcd_mtx);
-}
-
-static inline void lcd_wait(void)
-{
- if(LIKELY(!in_interrupt_mode()))
- {
- while( !(REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_TT) )
- yield();
- }
- else
- while( !(REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_TT));
-}
-
/* Update a fraction of the display. */
void lcd_update_rect(int x, int y, int width, int height)
{
- lcd_lock();
+#if 1
+ /* This is an ugly HACK until partial LCD drawing works.. */
+ width = LCD_WIDTH;
+ height = LCD_HEIGHT;
+ x = 0;
+ y = 0;
+#endif
+
+ mutex_lock(&lcd_mtx);
lcd_set_target(x, y, width, height);
- REG_DMAC_DCCSR(DMA_LCD_CHANNEL) = 0;
+ dma_enable();
+
+ REG_DMAC_DCCSR(DMA_LCD_CHANNEL) = DMAC_DCCSR_NDES;
REG_DMAC_DRSR(DMA_LCD_CHANNEL) = DMAC_DRSR_RS_SLCD; /* source = SLCD */
- REG_DMAC_DSAR(DMA_LCD_CHANNEL) = ((unsigned int)&lcd_framebuffer[y][x]) & 0x1FFFFFFF;
- REG_DMAC_DTAR(DMA_LCD_CHANNEL) = 0x130500B0; /* SLCD_FIFO */
+ REG_DMAC_DSAR(DMA_LCD_CHANNEL) = PHYSADDR((unsigned long)&lcd_framebuffer[y][x]);
+ REG_DMAC_DTAR(DMA_LCD_CHANNEL) = PHYSADDR(SLCD_FIFO);
REG_DMAC_DTCR(DMA_LCD_CHANNEL) = width*height;
REG_DMAC_DCMD(DMA_LCD_CHANNEL) = ( DMAC_DCMD_SAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32
| DMAC_DCMD_DWDH_16 | DMAC_DCMD_DS_16BIT );
- REG_DMAC_DCCSR(DMA_LCD_CHANNEL) = DMAC_DCCSR_NDES;
- __dcache_writeback_all(); /* Size of framebuffer is way bigger than cache size;
- we need to find a way to make the framebuffer uncached, so this statement can get removed. */
+ __dcache_writeback_all(); /* Size of framebuffer is way bigger than cache size.
+ We need to find a way to make the framebuffer uncached, so this statement can get removed. */
while(REG_SLCD_STATE & SLCD_STATE_BUSY);
+ REG_SLCD_CTRL |= SLCD_CTRL_DMA_EN; /* Enable SLCD DMA support */
- REG_SLCD_CTRL |= SLCD_CTRL_DMA_EN;
- REG_DMAC_DCCSR(DMA_LCD_CHANNEL) |= DMAC_DCCSR_EN;
+ REG_DMAC_DCCSR(DMA_LCD_CHANNEL) |= DMAC_DCCSR_EN; /* Enable DMA channel */
+ REG_DMAC_DCMD(DMA_LCD_CHANNEL) |= DMAC_DCMD_TIE; /* Enable DMA interrupt */
- lcd_wait();
+ wakeup_wait(&lcd_wkup, TIMEOUT_BLOCK);
+
+ REG_DMAC_DCCSR(DMA_LCD_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */
- REG_DMAC_DCCSR(DMA_LCD_CHANNEL) &= ~DMAC_DCCSR_EN;
+ dma_disable();
while(REG_SLCD_STATE & SLCD_STATE_BUSY);
+ REG_SLCD_CTRL &= ~SLCD_CTRL_DMA_EN; /* Disable SLCD DMA support */
- REG_SLCD_CTRL &= ~SLCD_CTRL_DMA_EN;
+ mutex_unlock(&lcd_mtx);
+}
+
+void DMA_CALLBACK(DMA_LCD_CHANNEL)(void)
+{
+ if (REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_HLT)
+ REG_DMAC_DCCSR(DMA_LCD_CHANNEL) &= ~DMAC_DCCSR_HLT;
+
+ if (REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_AR)
+ REG_DMAC_DCCSR(DMA_LCD_CHANNEL) &= ~DMAC_DCCSR_AR;
+
+ if (REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_CT)
+ REG_DMAC_DCCSR(DMA_LCD_CHANNEL) &= ~DMAC_DCCSR_CT;
+
+ if (REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_TT)
+ REG_DMAC_DCCSR(DMA_LCD_CHANNEL) &= ~DMAC_DCCSR_TT;
- lcd_unlock();
+ wakeup_signal(&lcd_wkup);
}
/* Update the display.
This must be called after all other LCD functions that change the display. */
void lcd_update(void)
{
- if (!lcd_is_on)
+ if (!lcd_is_on || !backlight_enabled())
return;
lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx747/backlight-onda_vx747.c b/firmware/target/mips/ingenic_jz47xx/onda_vx747/backlight-onda_vx747.c
index 501a90551e..208236ef95 100644
--- a/firmware/target/mips/ingenic_jz47xx/onda_vx747/backlight-onda_vx747.c
+++ b/firmware/target/mips/ingenic_jz47xx/onda_vx747/backlight-onda_vx747.c
@@ -23,60 +23,119 @@
#include "jz4740.h"
#include "backlight-target.h"
-#define PWM_CHN 7 /* PWM_CHN7 == GPIO(32*3 + 31) */
-#define __gpio_as_PWM_CHN __gpio_as_pwm7
+/* PWM_CHN7 == GPIO(32*3 + 31) */
+#define BACKLIGHT_GPIO (32*3+31)
+#define BACKLIGHT_PWM 7
+#define SW_PWM 1
+
+#if SW_PWM
+
+static bool backlight_on;
+
+static void set_backlight(int val)
+{
+(void)val;
+}
+
+bool _backlight_init(void)
+{
+ __gpio_as_output(BACKLIGHT_GPIO);
+ __gpio_set_pin(BACKLIGHT_GPIO);
+
+ backlight_on = true;
+
+ return true;
+}
+
+bool backlight_enabled(void)
+{
+ return backlight_on;
+}
+
+void _backlight_on(void)
+{
+ __gpio_set_pin(BACKLIGHT_GPIO);
+ backlight_on = true;
+}
+
+void _backlight_off(void)
+{
+ __gpio_clear_pin(BACKLIGHT_GPIO);
+ backlight_on = false;
+}
+
+#else
+
+static int old_val;
static void set_backlight(int val)
{
+ if(val == old_val)
+ return;
+
/* Taken from the OF */
int tmp;
tmp = (val/2 + __cpm_get_rtcclk()) / val;
if(tmp > 0xFFFF)
tmp = 0xFFFF;
- __tcu_set_half_data(PWM_CHN, (tmp * val * 1374389535) >> 5);
- __tcu_set_full_data(PWM_CHN, tmp);
+ __tcu_set_half_data(BACKLIGHT_PWM, (tmp * val * 1374389535) >> 5);
+ __tcu_set_full_data(BACKLIGHT_PWM, tmp);
+
+ old_val = val;
}
static void set_backlight_on(void)
{
- __tcu_start_timer_clock(PWM_CHN);
+ if(old_val == MAX_BRIGHTNESS_SETTING)
+ return;
+
+ __tcu_start_timer_clock(BACKLIGHT_PWM);
set_backlight(MAX_BRIGHTNESS_SETTING);
- __tcu_set_count(PWM_CHN, 0);
- __tcu_start_counter(PWM_CHN);
+ __tcu_set_count(BACKLIGHT_PWM, 0);
+ __tcu_start_counter(BACKLIGHT_PWM);
- __tcu_enable_pwm_output(PWM_CHN);
+ __tcu_enable_pwm_output(BACKLIGHT_PWM);
}
static void set_backlight_off(void)
{
- __tcu_stop_counter(PWM_CHN);
- __tcu_disable_pwm_output(PWM_CHN);
- __tcu_stop_timer_clock(PWM_CHN);
+ __tcu_stop_counter(BACKLIGHT_PWM);
+ __tcu_disable_pwm_output(BACKLIGHT_PWM);
+ __tcu_stop_timer_clock(BACKLIGHT_PWM);
+
+ old_val = -1;
}
bool _backlight_init(void)
{
- __gpio_as_PWM_CHN();
- __tcu_start_timer_clock(PWM_CHN);
+ __gpio_as_pwm(BACKLIGHT_PWM);
+ __tcu_start_timer_clock(BACKLIGHT_PWM);
- __tcu_stop_counter(PWM_CHN);
- __tcu_disable_pwm_output(PWM_CHN);
+ __tcu_stop_counter(BACKLIGHT_PWM);
+ __tcu_disable_pwm_output(BACKLIGHT_PWM);
- __tcu_init_pwm_output_low(PWM_CHN);
- __tcu_select_rtcclk(PWM_CHN);
- __tcu_select_clk_div1(PWM_CHN);
+ __tcu_init_pwm_output_low(BACKLIGHT_PWM);
+ __tcu_select_rtcclk(BACKLIGHT_PWM);
+ __tcu_select_clk_div1(BACKLIGHT_PWM);
- __tcu_mask_half_match_irq(PWM_CHN);
- __tcu_mask_full_match_irq(PWM_CHN);
+ __tcu_mask_half_match_irq(BACKLIGHT_PWM);
+ __tcu_mask_full_match_irq(BACKLIGHT_PWM);
+
+ old_val = -1;
set_backlight_on();
return true;
}
+bool backlight_enabled(void)
+{
+ return old_val > -1 ? true : false;
+}
+
void _backlight_on(void)
{
set_backlight_on();
@@ -86,6 +145,7 @@ void _backlight_off(void)
{
set_backlight_off();
}
+#endif /* !SW_PWM */
#ifdef HAVE_BACKLIGHT_BRIGHTNESS
void _backlight_set_brightness(int brightness)
diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx747/backlight-target.h b/firmware/target/mips/ingenic_jz47xx/onda_vx747/backlight-target.h
index 4170f96cc0..f3f17f024e 100644
--- a/firmware/target/mips/ingenic_jz47xx/onda_vx747/backlight-target.h
+++ b/firmware/target/mips/ingenic_jz47xx/onda_vx747/backlight-target.h
@@ -33,5 +33,6 @@ bool _backlight_init(void);
void _backlight_on(void);
void _backlight_off(void);
void _backlight_set_brightness(int brightness);
+bool backlight_enabled(void);
#endif /* BACKLIGHT_TARGET_H */
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 f7c6a137fc..40d9bb6106 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
@@ -204,7 +204,7 @@ static void _set_lcd_clock(void)
__cpm_stop_lcd();
pll_div = ( REG_CPM_CPCCR & CPM_CPCCR_PCS ); /* clock source, 0:pllout/2 1: pllout */
pll_div = pll_div ? 1 : 2 ;
- val = ( __cpm_get_pllout()/pll_div ) / 336000000;
+ val = ( __cpm_get_pllout()/pll_div ) / __cpm_get_pclk();
val--;
if ( val > 0x1ff )
val = 0x1ff; /* CPM_LPCDR is too large, set it to 0x1ff */
@@ -235,8 +235,8 @@ void lcd_set_target(short x, short y, short width, short height)
SLCD_SEND_COMMAND(REG_RAM_VADDR_START, x); /* x_start */
SLCD_SEND_COMMAND(REG_RAM_VADDR_END, x+width-1); /* x_end */
#endif
- SLCD_SEND_COMMAND(REG_RAM_HADDR_SET, x); /* set cursor at x_start */
- SLCD_SEND_COMMAND(REG_RAM_VADDR_SET, y); /* set cursor at y_start */
+ SLCD_SEND_COMMAND(REG_RAM_HADDR_SET, y); /* set cursor at x_start */
+ SLCD_SEND_COMMAND(REG_RAM_VADDR_SET, x); /* set cursor at y_start */
SLCD_SET_COMMAND(REG_RW_GRAM); /* write data to GRAM */
}
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 0271fd1b96..95c2f84a7e 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
@@ -47,7 +47,7 @@
BTN_MENU | BTN_VOL_UP)
-#define TS_AD_COUNT 5
+#define TS_AD_COUNT 3
#define SADC_CFG_SNUM ((TS_AD_COUNT - 1) << SADC_CFG_SNUM_BIT)
#define SADC_CFG_INIT ( \
diff --git a/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c b/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c
index dce989d81f..c97ef13533 100644
--- a/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c
@@ -41,17 +41,12 @@ void pcm_postinit(void)
__i2s_set_oss_sample_size(16);
}
-const void * pcm_play_dma_get_peak_buffer(int *count)
-{
- /* TODO */
- *count = 0;
- return NULL;
-}
-
void pcm_play_dma_init(void)
{
/* TODO */
+ system_enable_irq(DMA_IRQ(DMA_AIC_TX_CHANNEL));
+
/* Initialize default register values. */
audiohw_init();
}
@@ -59,11 +54,6 @@ void pcm_play_dma_init(void)
void pcm_dma_apply_settings(void)
{
/* TODO */
-
- /*
- __i2s_set_oss_sample_size(pcm_sampr);
- i2s_codec_set_samplerate(pcm_sampr);
- */
}
static void play_start_pcm(void)
@@ -72,33 +62,47 @@ static void play_start_pcm(void)
__i2s_enable_replay();
REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) |= DMAC_DCCSR_EN;
+ REG_DMAC_DCMD(DMA_AIC_TX_CHANNEL) |= DMAC_DCMD_TIE;
}
static void play_stop_pcm(void)
{
REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) = (REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) | DMAC_DCCSR_HLT) & ~DMAC_DCCSR_EN;
+ dma_disable();
+
__i2s_disable_transmit_dma();
__i2s_disable_replay();
}
void pcm_play_dma_start(const void *addr, size_t size)
{
+ dma_enable();
+
REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) = DMAC_DCCSR_NDES;
REG_DMAC_DSAR(DMA_AIC_TX_CHANNEL) = PHYSADDR((unsigned long)addr);
REG_DMAC_DTAR(DMA_AIC_TX_CHANNEL) = PHYSADDR((unsigned long)AIC_DR);
REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL) = size;
REG_DMAC_DRSR(DMA_AIC_TX_CHANNEL) = DMAC_DRSR_RS_AICOUT;
- REG_DMAC_DCMD(DMA_AIC_TX_CHANNEL) = ( DMAC_DCMD_SAI| DMAC_DCMD_SWDH_32 | DMAC_DCMD_DS_32BIT | DMAC_DCMD_DWDH_32
- | DMAC_DCMD_TIE);
+ REG_DMAC_DCMD(DMA_AIC_TX_CHANNEL) = (DMAC_DCMD_SAI| DMAC_DCMD_SWDH_32 | DMAC_DCMD_DS_32BIT | DMAC_DCMD_DWDH_32);
play_start_pcm();
}
void DMA_CALLBACK(DMA_AIC_TX_CHANNEL)(void)
{
- if( REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) & DMAC_DCCSR_TT )
+ if (REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) & DMAC_DCCSR_AR)
+ REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) &= ~DMAC_DCCSR_AR;
+
+ if (REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) & DMAC_DCCSR_CT)
+ REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) &= ~DMAC_DCCSR_CT;
+
+ if (REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) & (DMAC_DCCSR_TT | DMAC_DCCSR_HLT))
+ {
+ REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) &= ~(DMAC_DCCSR_TT | DMAC_DCCSR_HLT);
+ REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) &= ~DMAC_DCCSR_EN;
__aic_disable_transmit_dma();
+ }
}
size_t pcm_get_bytes_waiting(void)
@@ -106,6 +110,13 @@ size_t pcm_get_bytes_waiting(void)
return REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL);
}
+const void * pcm_play_dma_get_peak_buffer(int *count)
+{
+ /* TODO */
+ *count = REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL)>>2;
+ return NULL;
+}
+
void pcm_play_dma_stop(void)
{
play_stop_pcm();
diff --git a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
index f733582d70..22d35d93de 100644
--- a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
@@ -24,8 +24,8 @@
#include "mips.h"
#include "mipsregs.h"
#include "panic.h"
-#include "system-target.h"
-#include <string.h>
+#include "system.h"
+#include "string.h"
#include "kernel.h"
#define NUM_DMA 6
@@ -322,53 +322,45 @@ static int get_irq_number(void)
return irq;
}
-static bool intr_mode = false;
-
-bool in_interrupt_mode(void)
-{
- return intr_mode;
-}
-
void intr_handler(void)
{
int irq = get_irq_number();
- if(irq < 0)
+ if(UNLIKELY(irq < 0))
return;
ack_irq(irq);
- if(irq > 0)
- {
- intr_mode = true;
+ if(LIKELY(irq > 0))
irqvector[irq-1]();
- intr_mode = false;
- }
}
-#define EXC(x,y) if(_cause == (x)) return (y);
+#define EXC(x,y) case (x): return (y);
static char* parse_exception(unsigned int cause)
{
- unsigned int _cause = cause & M_CauseExcCode;
- EXC(EXC_INT, "Interrupt");
- EXC(EXC_MOD, "TLB Modified");
- EXC(EXC_TLBL, "TLB Exception (Load or Ifetch)");
- EXC(EXC_ADEL, "Address Error (Load or Ifetch)");
- EXC(EXC_ADES, "Address Error (Store)");
- EXC(EXC_TLBS, "TLB Exception (Store)");
- EXC(EXC_IBE, "Instruction Bus Error");
- EXC(EXC_DBE, "Data Bus Error");
- EXC(EXC_SYS, "Syscall");
- EXC(EXC_BP, "Breakpoint");
- EXC(EXC_RI, "Reserved Instruction");
- EXC(EXC_CPU, "Coprocessor Unusable");
- EXC(EXC_OV, "Overflow");
- EXC(EXC_TR, "Trap Instruction");
- EXC(EXC_FPE, "Floating Point Exception");
- EXC(EXC_C2E, "COP2 Exception");
- EXC(EXC_MDMX, "MDMX Exception");
- EXC(EXC_WATCH, "Watch Exception");
- EXC(EXC_MCHECK, "Machine Check Exception");
- EXC(EXC_CacheErr, "Cache error caused re-entry to Debug Mode");
- return NULL;
+ switch(cause & M_CauseExcCode)
+ {
+ EXC(EXC_INT, "Interrupt");
+ EXC(EXC_MOD, "TLB Modified");
+ EXC(EXC_TLBL, "TLB Exception (Load or Ifetch)");
+ EXC(EXC_ADEL, "Address Error (Load or Ifetch)");
+ EXC(EXC_ADES, "Address Error (Store)");
+ EXC(EXC_TLBS, "TLB Exception (Store)");
+ EXC(EXC_IBE, "Instruction Bus Error");
+ EXC(EXC_DBE, "Data Bus Error");
+ EXC(EXC_SYS, "Syscall");
+ EXC(EXC_BP, "Breakpoint");
+ EXC(EXC_RI, "Reserved Instruction");
+ EXC(EXC_CPU, "Coprocessor Unusable");
+ EXC(EXC_OV, "Overflow");
+ EXC(EXC_TR, "Trap Instruction");
+ EXC(EXC_FPE, "Floating Point Exception");
+ EXC(EXC_C2E, "COP2 Exception");
+ EXC(EXC_MDMX, "MDMX Exception");
+ EXC(EXC_WATCH, "Watch Exception");
+ EXC(EXC_MCHECK, "Machine Check Exception");
+ EXC(EXC_CacheErr, "Cache error caused re-entry to Debug Mode");
+ default:
+ return NULL;
+ }
}
void exception_handler(void* stack_ptr, unsigned int cause, unsigned int epc)
@@ -644,18 +636,31 @@ static void tlb_call_refill(void)
);
}
-static void dma_init(void)
+static int dma_count = 0;
+void dma_enable(void)
{
- __cpm_start_dmac();
-
- REG_DMAC_DCCSR(0) = 0;
- REG_DMAC_DCCSR(1) = 0;
- REG_DMAC_DCCSR(2) = 0;
- REG_DMAC_DCCSR(3) = 0;
- REG_DMAC_DCCSR(4) = 0;
- REG_DMAC_DCCSR(5) = 0;
-
- REG_DMAC_DMACR = (DMAC_DMACR_PR_012345 | DMAC_DMACR_DMAE);
+ if(++dma_count == 1)
+ {
+ __cpm_start_dmac();
+
+ REG_DMAC_DCCSR(0) = 0;
+ REG_DMAC_DCCSR(1) = 0;
+ REG_DMAC_DCCSR(2) = 0;
+ REG_DMAC_DCCSR(3) = 0;
+ REG_DMAC_DCCSR(4) = 0;
+ REG_DMAC_DCCSR(5) = 0;
+
+ REG_DMAC_DMACR = (DMAC_DMACR_PR_012345 | DMAC_DMACR_DMAE);
+ }
+}
+
+void dma_disable(void)
+{
+ if(--dma_count == 0)
+ {
+ REG_DMAC_DMACR &= ~DMAC_DMACR_DMAE;
+ __cpm_stop_dmac();
+ }
}
extern int main(void);
@@ -686,7 +691,6 @@ void system_main(void)
dis_irq(i);
tlb_init();
- dma_init();
detect_clock();
diff --git a/firmware/target/mips/ingenic_jz47xx/system-target.h b/firmware/target/mips/ingenic_jz47xx/system-target.h
index a8133140fa..39782a3222 100644
--- a/firmware/target/mips/ingenic_jz47xx/system-target.h
+++ b/firmware/target/mips/ingenic_jz47xx/system-target.h
@@ -101,7 +101,8 @@ void udelay(unsigned int usec);
void mdelay(unsigned int msec);
void power_off(void);
void system_reboot(void);
-bool in_interrupt_mode(void);
+void dma_enable(void);
+void dma_disable(void);
#define DMA_LCD_CHANNEL 0
#define DMA_NAND_CHANNEL 1
@@ -111,4 +112,6 @@ bool in_interrupt_mode(void);
#define XDMA_CALLBACK(n) DMA ## n
#define DMA_CALLBACK(n) XDMA_CALLBACK(n)
+#define DMA_IRQ(n) (IRQ_DMA_0 + n)
+
#endif /* __SYSTEM_TARGET_H_ */
diff --git a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c
index 16965159f6..f06e796e05 100644
--- a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c
@@ -20,6 +20,8 @@
****************************************************************************/
#include "config.h"
+#define LOGF_ENABLE
+#include "logf.h"
#include "system.h"
#include "usb_ch9.h"
#include "usb_drv.h"
@@ -28,12 +30,6 @@
#include "jz4740.h"
#include "thread.h"
-#if 1
-#define DEBUGF printf
-#else
-#define DEBUGF(...)
-#endif
-
#define USB_EP0_IDLE 0
#define USB_EP0_RX 1
#define USB_EP0_TX 2
@@ -85,7 +81,7 @@ static inline void select_endpoint(int ep)
static void readFIFO(struct usb_endpoint *ep, unsigned int size)
{
- DEBUGF("readFIFO(EP%d, %d)", EP_NUMBER(ep), size);
+ logf("readFIFO(EP%d, %d)", EP_NUMBER(ep), size);
register unsigned char *ptr = (unsigned char*)EP_PTR(ep);
register unsigned int *ptr32 = (unsigned int*)ptr;
@@ -121,7 +117,7 @@ static void readFIFO(struct usb_endpoint *ep, unsigned int size)
static void writeFIFO(struct usb_endpoint *ep, unsigned int size)
{
- DEBUGF("writeFIFO(EP%d, %d)", EP_NUMBER(ep), size);
+ logf("writeFIFO(EP%d, %d)", EP_NUMBER(ep), size);
register unsigned int *d = (unsigned int *)EP_PTR(ep);
register unsigned char *c;
@@ -140,6 +136,8 @@ static void writeFIFO(struct usb_endpoint *ep, unsigned int size)
REG8(ep->fifo_addr) = *c++;
}
}
+ else
+ REG32(ep->fifo_addr) = 0;
}
static void EP0_send(void)
@@ -152,6 +150,8 @@ static void EP0_send(void)
else
length = (EP_BUF_LEFT(ep) <= ep->fifo_size ? EP_BUF_LEFT(ep) : ep->fifo_size);
+ select_endpoint(0);
+
writeFIFO(ep, length);
ep->sent += length;
@@ -243,7 +243,7 @@ static void setup_endpoint(struct usb_endpoint *ep)
static void udc_reset(void)
{
- DEBUGF("udc_reset");
+ logf("udc_reset");
register unsigned int i;
@@ -303,19 +303,19 @@ void UDC(void)
if(intrUSB & USB_INTR_RESUME);
if(intrDMA & USB_INTR_DMA_BULKIN)
{
- DEBUGF("DMA_BULKIN %d", ((REG_USB_REG_CNTL1 >> 4) & 0xF));
+ logf("DMA_BULKIN %d", ((REG_USB_REG_CNTL1 >> 4) & 0xF));
usb_core_transfer_complete(((REG_USB_REG_CNTL1 >> 4) & 0xF) | USB_DIR_IN, USB_DIR_IN, 0, 0);
}
if(intrDMA & USB_INTR_DMA_BULKOUT)
{
- DEBUGF("DMA_BULKOUT %d", ((REG_USB_REG_CNTL2 >> 4) & 0xF));
+ logf("DMA_BULKOUT %d", ((REG_USB_REG_CNTL2 >> 4) & 0xF));
usb_core_transfer_complete(((REG_USB_REG_CNTL2 >> 4) & 0xF) | USB_DIR_OUT, USB_DIR_OUT, 0, 0);
}
}
bool usb_drv_stalled(int endpoint, bool in)
{
- DEBUGF("usb_drv_stalled(%d, %s)", endpoint, in?"IN":"OUT");
+ logf("usb_drv_stalled(%d, %s)", endpoint, in?"IN":"OUT");
select_endpoint(endpoint);
@@ -332,7 +332,7 @@ bool usb_drv_stalled(int endpoint, bool in)
void usb_drv_stall(int endpoint, bool stall, bool in)
{
- DEBUGF("usb_drv_stall(%d,%s,%s)", endpoint, stall?"y":"n", in?"IN":"OUT");
+ logf("usb_drv_stall(%d,%s,%s)", endpoint, stall?"y":"n", in?"IN":"OUT");
select_endpoint(endpoint);
@@ -424,14 +424,14 @@ void usb_drv_exit(void)
void usb_drv_set_address(int address)
{
- DEBUGF("set adr: 0x%x", address);
+ logf("set adr: %d", address);
REG_USB_REG_FADDR = address;
}
int usb_drv_send(int endpoint, void* ptr, int length)
{
- DEBUGF("usb_drv_send(%d, 0x%x, %d)", endpoint, (int)ptr, length);
+ logf("usb_drv_send(%d, 0x%x, %d)", endpoint, (int)ptr, length);
if(endpoint == EP_CONTROL && ptr == NULL && length == 0) /* ACK request */
return 0;
@@ -451,7 +451,7 @@ int usb_drv_send(int endpoint, void* ptr, int length)
int usb_drv_recv(int endpoint, void* ptr, int length)
{
- DEBUGF("usb_drv_recv(%d, 0x%x, %d)", endpoint, (int)ptr, length);
+ logf("usb_drv_recv(%d, 0x%x, %d)", endpoint, (int)ptr, length);
if(endpoint == EP_CONTROL && ptr == NULL && length == 0) /* ACK request */
return 0;
@@ -461,7 +461,7 @@ int usb_drv_recv(int endpoint, void* ptr, int length)
void usb_drv_set_test_mode(int mode)
{
- DEBUGF("usb_drv_set_test_mode(%d)", mode);
+ logf("usb_drv_set_test_mode(%d)", mode);
switch(mode)
{
@@ -490,7 +490,7 @@ int usb_drv_port_speed(void)
void usb_drv_cancel_all_transfers(void)
{
- DEBUGF("usb_drv_cancel_all_transfers()");
+ logf("usb_drv_cancel_all_transfers()");
unsigned int i;
for(i=0; i<TOTAL_EP(); i++)
@@ -505,14 +505,14 @@ void usb_drv_cancel_all_transfers(void)
void usb_drv_release_endpoint(int ep)
{
- //DEBUGF("usb_drv_release_endpoint(%d)", ep);
+ //logf("usb_drv_release_endpoint(%d)", ep);
(void)ep;
}
int usb_drv_request_endpoint(int dir)
{
- DEBUGF("usb_drv_request_endpoint(%d)", dir);
+ logf("usb_drv_request_endpoint(%d)", dir);
(void)dir;
return -1;