From 04c7379ac585d1e79fd454cf860a8592db25c67f Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Mon, 9 Feb 2009 10:02:38 +0000 Subject: Onda VX747: commit some parts to get apps/ to compile (more will follow) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19954 a1c6a512-1295-4272-9138-f99709370657 --- firmware/target/mips/ingenic_jz47xx/app.lds | 144 +++++++++ firmware/target/mips/ingenic_jz47xx/ata-jz4740.c | 104 ------ firmware/target/mips/ingenic_jz47xx/boot.lds | 83 ++--- firmware/target/mips/ingenic_jz47xx/crt0.S | 54 ++-- firmware/target/mips/ingenic_jz47xx/debug-jz4740.c | 131 ++++++++ firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c | 4 + firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c | 15 + firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c | 4 + .../target/mips/ingenic_jz47xx/system-jz4740.c | 353 ++++++++++----------- .../target/mips/ingenic_jz47xx/system-target.h | 5 +- 10 files changed, 539 insertions(+), 358 deletions(-) create mode 100644 firmware/target/mips/ingenic_jz47xx/app.lds delete mode 100644 firmware/target/mips/ingenic_jz47xx/ata-jz4740.c create mode 100644 firmware/target/mips/ingenic_jz47xx/debug-jz4740.c (limited to 'firmware/target') diff --git a/firmware/target/mips/ingenic_jz47xx/app.lds b/firmware/target/mips/ingenic_jz47xx/app.lds new file mode 100644 index 0000000000..dd539b0d41 --- /dev/null +++ b/firmware/target/mips/ingenic_jz47xx/app.lds @@ -0,0 +1,144 @@ +#include "config.h" +#undef mips + +OUTPUT_FORMAT("elf32-littlemips") +OUTPUT_ARCH(MIPS) +ENTRY(_start) +STARTUP(target/mips/ingenic_jz47xx/crt0.o) + +#ifdef DEBUG +#define STUBOFFSET 0x10000 +#else +#define STUBOFFSET 0 +#endif + +#define PLUGINSIZE PLUGIN_BUFFER_SIZE +#define CODECSIZE CODEC_SIZE + +#define DRAMSIZE ((MEMORYSIZE * 0x100000) - STUBOFFSET - PLUGINSIZE - CODECSIZE) + +#define DRAMORIG 0x80004000 +#define IRAMORIG 0x80000000 +#define IRAMSIZE (16K-0x220) + +/* End of the audio buffer, where the codec buffer starts */ +#define ENDAUDIOADDR (DRAMORIG + DRAMSIZE) + +/* Where the codec buffer ends, and the plugin buffer starts */ +#define ENDADDR (ENDAUDIOADDR + CODECSIZE) + +MEMORY +{ + DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE + IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE +} + +SECTIONS +{ + . = DRAMORIG; + + .text : + { + loadaddress = .; + *(.init.text); + *(.text*); + } > DRAM + + . = ALIGN(4); + + .rodata : + { + *(.rodata); /* problems without this, dunno why */ + *(.rodata*); + *(.rodata.str1.1); + *(.rodata.str1.4); + } > DRAM + + . = ALIGN(4); + + .data : + { + *(.data*); + *(.sdata*); + *(.rel.dyn); + } > DRAM + + . = ALIGN(4); + + .stack (NOLOAD): + { + *(.stack); + stackbegin = .; + . += 0x2000; + stackend = .; + } > DRAM + + . = ALIGN(4); + + .iram IRAMORIG: + { + _iramstart = .; + *(.vectors.1); + . = 0x100; + *(.vectors.2); + . = 0x180; + *(.vectors.3); + . = 0x200; + *(.vectors.4); + *(.vectors); + + *(.icode); + *(.irodata); + *(.idata); + KEEP(*(.vectors)) + *(.vectors); + _iramend = .; + } > IRAM AT> DRAM + _iramcopy = LOADADDR(.iram); + + . = ALIGN(4); + + .bss (NOLOAD): + { + _edata = .; + *(.sbss*); + *(.bss*); + *(COMMON); + *(.scommon*); + _end = .; + } > DRAM + + . = ALIGN(4); + + .ibss (NOLOAD) : + { + _iedata = .; + *(.ibss*); + _iend = .; + } > IRAM + + .audiobuf ALIGN(4) : + { + audiobuffer = .; + } > DRAM + + .audiobufend ENDAUDIOADDR: + { + audiobufend = .; + } > DRAM + + .codec ENDAUDIOADDR: + { + codecbuf = .; + } + + .plugin ENDADDR: + { + pluginbuf = .; + } + + /DISCARD/ : + { + *(.eh_frame); + } +} diff --git a/firmware/target/mips/ingenic_jz47xx/ata-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-jz4740.c deleted file mode 100644 index 4c177d8ded..0000000000 --- a/firmware/target/mips/ingenic_jz47xx/ata-jz4740.c +++ /dev/null @@ -1,104 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 "ata.h" -#include "ata-sd-target.h" -#include "ata-nand-target.h" -#include "panic.h" - -int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int count, void* buf) -{ - switch(drive) - { - case 0: - return nand_read_sectors(start, count, buf); - case 1: - return _sd_read_sectors(start, count, buf); - default: - panicf("ata_read_sectors: Drive %d unhandled!", drive); - return -1; - } -} - -int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const void* buf) -{ - switch(drive) - { - case 0: - return nand_write_sectors(start, count, buf); - case 1: - return _sd_write_sectors(start, count, buf); - default: - panicf("ata_write_sectors: Drive %d unhandled!", drive); - return -1; - } -} - -int ata_init(void) -{ - if(_sd_init() != 0) - return -1; - if(nand_init() != 0) - return -2; - - return 0; -} - -void ata_spindown(int seconds) -{ - /* null */ - (void)seconds; -} - -bool ata_disk_is_active(void) -{ - /* null */ - return false; -} - -void ata_sleep(void) -{ - /* null */ -} - -void ata_spin(void) -{ - /* null */ -} - -int ata_hard_reset(void) -{ - /* null */ - return 0; -} - -int ata_soft_reset(void) -{ - /* null */ - return 0; -} - -void ata_enable(bool on) -{ - /* null - flash controller is enabled/disabled as needed. */ - (void)on; -} diff --git a/firmware/target/mips/ingenic_jz47xx/boot.lds b/firmware/target/mips/ingenic_jz47xx/boot.lds index b6f3e169fb..40fd29cdd9 100644 --- a/firmware/target/mips/ingenic_jz47xx/boot.lds +++ b/firmware/target/mips/ingenic_jz47xx/boot.lds @@ -6,9 +6,9 @@ OUTPUT_ARCH(MIPS) ENTRY(_start) STARTUP(target/mips/ingenic_jz47xx/crt0.o) -#define DRAMSIZE (MEMORYSIZE * 0x100000) +#define DRAMSIZE ((MEMORYSIZE-4) * 0x100000) -#define DRAMORIG 0x80004000 +#define DRAMORIG 0x80404000 #define IRAMORIG 0x80000000 #define IRAMSIZE 16K @@ -24,20 +24,9 @@ SECTIONS .text : { - loadaddress = .; _loadaddress = .; *(.init.text); *(.text*); - *(.glue_7); - *(.glue_7t); - *(.rel.dyn); - } > DRAM - - .vectors : - { - _vectorsstart = .; - KEEP(*(.vectors)) - *(.vectors); } > DRAM . = ALIGN(4); @@ -48,71 +37,67 @@ SECTIONS *(.rodata*); *(.rodata.str1.1); *(.rodata.str1.4); - . = ALIGN(0x4); - - /* Pseudo-allocate the copies of the data sections */ - _datacopy = .; } > DRAM + + . = ALIGN(4); .data : { - *(.icode); - *(.irodata); - *(.idata); *(.data*); *(.sdata*); - . = ALIGN(0x4); - _dataend = . ; + *(.rel.dyn); } > DRAM - _gp = ALIGN(16); - .got : + . = ALIGN(4); + + .iram IRAMORIG: { - *(.got*) - } > DRAM + _iramstart = .; + *(.vectors.1); + . = 0x100; + *(.vectors.2); + . = 0x180; + *(.vectors.3); + . = 0x200; + *(.vectors.4); + *(.vectors); + + *(.icode); + *(.irodata); + *(.idata); + KEEP(*(.vectors*)) + _iramend = .; + } > IRAM AT> DRAM + _iramcopy = LOADADDR(.iram); . = ALIGN(4); - - .bss : + + .bss (NOLOAD): { _edata = .; *(.sbss*); *(.bss*); - *(.ibss); - *(COMMON) + *(COMMON); *(.scommon*); _end = .; } > DRAM - .iram IRAMORIG: - { - . = 0x220; /* Vectors take in 0x80000000 -> 0x80000220 */ - _iramstart = .; - *(.icode) - *(.irodata) - *(.idata) - . = ALIGN(0x4); - _iramend = .; - } > IRAM AT> DRAM - - _iramcopy = LOADADDR(.iram); - + _bootend = .; + .ibss (NOLOAD) : { _iedata = .; - *(.ibss) - . = ALIGN(0x4); + *(.ibss*) _iend = .; } > IRAM - .stack : + . = ALIGN(4); + + .stack (NOLOAD): { *(.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 5cfd49141a..e619022fc8 100644 --- a/firmware/target/mips/ingenic_jz47xx/crt0.S +++ b/firmware/target/mips/ingenic_jz47xx/crt0.S @@ -52,6 +52,17 @@ #ifdef BOOTLOADER .word 0 /* Unknown */ .word 0 /* Filesize */ + + /* Relocate bootloader */ + la t0, (_loadaddress-0x400000) + la t1, _loadaddress + la t2, _bootend +_relocate_loop: + lw t3, 0(t0) + sw t3, 0(t1) + addiu t1, 4 + bne t1, t2, _relocate_loop + addiu t0, 4 #endif _start: @@ -119,7 +130,6 @@ _init_bss_loop: bne t0, t1, _init_bss_loop addiu t0, 4 -#ifndef BOOTLOADER /* ---------------------------------------------------- clear IBSS section @@ -146,7 +156,6 @@ _init_iram_loop: addiu t1, 4 bne t1, t2, _init_iram_loop addiu t0, 4 -#endif /* ---------------------------------------------------- @@ -167,23 +176,35 @@ _init_stack_loop: nop - .section .vectors, "ax", %progbits - .extern real_exception_handler - .global except_common_entry - .type except_common_entry,@function -except_common_entry: + /* + * 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) + */ + + + .section .vectors.1, "ax", %progbits + la k0, tlb_refill_handler + jr k0 + nop + + .section .vectors.2, "ax", %progbits la k0, real_exception_handler jr k0 nop + + .section .vectors.3, "ax", %progbits + la k0, real_exception_handler + jr k0 nop - nop - .fill 0x20 - .extern _int - .extern _exception - .global real_exception_handler - .type real_exception_handler,@function - .set noreorder + .section .vectors.4, "ax", %progbits + la k0, real_exception_handler + jr k0 + nop + + .section .vectors, "ax", %progbits real_exception_handler: addiu sp, -0x80 sw ra, 0(sp) @@ -241,8 +262,6 @@ real_exception_handler: j _exception nop - .global _int - .type _int,@function _int: jal intr_handler nop @@ -298,9 +317,6 @@ _int: eret # Exception Return nop - .extern _exception_handler - .global _exception - .type _exception,@function _exception: add a0, sp, $0 mfc0 a1, C0_CAUSE # C0_CAUSE of last exception diff --git a/firmware/target/mips/ingenic_jz47xx/debug-jz4740.c b/firmware/target/mips/ingenic_jz47xx/debug-jz4740.c new file mode 100644 index 0000000000..648d410cd6 --- /dev/null +++ b/firmware/target/mips/ingenic_jz47xx/debug-jz4740.c @@ -0,0 +1,131 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 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 "jz4740.h" + +/* + * Clock Generation Module + */ +#define TO_MHZ(x) ((x)/1000000), ((x)%1000000)/10000 +#define TO_KHZ(x) ((x)/1000), ((x)%1000)/10 + +static void display_clocks(void) +{ + unsigned int cppcr = REG_CPM_CPPCR; /* PLL Control Register */ + unsigned int cpccr = REG_CPM_CPCCR; /* Clock Control Register */ + unsigned int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; + unsigned int od[4] = {1, 2, 2, 4}; + + printf("CPPCR : 0x%08x", cppcr); + printf("CPCCR : 0x%08x", cpccr); + printf("PLL : %s", (cppcr & CPM_CPPCR_PLLEN) ? "ON" : "OFF"); + printf("m:n:o : %d:%d:%d", + __cpm_get_pllm() + 2, + __cpm_get_plln() + 2, + od[__cpm_get_pllod()] + ); + printf("C:H:M:P : %d:%d:%d:%d", + div[__cpm_get_cdiv()], + div[__cpm_get_hdiv()], + div[__cpm_get_mdiv()], + div[__cpm_get_pdiv()] + ); + printf("U:L:I:P:M : %d:%d:%d:%d:%d", + __cpm_get_udiv() + 1, + __cpm_get_ldiv() + 1, + __cpm_get_i2sdiv()+1, + __cpm_get_pixdiv()+1, + __cpm_get_mscdiv()+1 + ); + printf("PLL Freq: %3d.%02d MHz", TO_MHZ(__cpm_get_pllout())); + printf("CCLK : %3d.%02d MHz", TO_MHZ(__cpm_get_cclk())); + printf("HCLK : %3d.%02d MHz", TO_MHZ(__cpm_get_hclk())); + printf("MCLK : %3d.%02d MHz", TO_MHZ(__cpm_get_mclk())); + printf("PCLK : %3d.%02d MHz", TO_MHZ(__cpm_get_pclk())); + printf("LCDCLK : %3d.%02d MHz", TO_MHZ(__cpm_get_lcdclk())); + printf("PIXCLK : %6d.%02d KHz", TO_KHZ(__cpm_get_pixclk())); + printf("I2SCLK : %3d.%02d MHz", TO_MHZ(__cpm_get_i2sclk())); + printf("USBCLK : %3d.%02d MHz", TO_MHZ(__cpm_get_usbclk())); + printf("MSCCLK : %3d.%02d MHz", TO_MHZ(__cpm_get_mscclk())); + printf("EXTALCLK: %3d.%02d MHz", TO_MHZ(__cpm_get_extalclk())); + printf("RTCCLK : %3d.%02d KHz", TO_KHZ(__cpm_get_rtcclk())); +} + +static void display_enabled_clocks(void) +{ + unsigned long lcr = REG_CPM_LCR; + unsigned long clkgr = REG_CPM_CLKGR; + + printf("Low Power Mode : %s", + ((lcr & CPM_LCR_LPM_MASK) == CPM_LCR_LPM_IDLE) ? + "IDLE" : (((lcr & CPM_LCR_LPM_MASK) == CPM_LCR_LPM_SLEEP) ? "SLEEP" : "HIBERNATE") + ); + + printf("Doze Mode : %s", + (lcr & CPM_LCR_DOZE_ON) ? "ON" : "OFF"); + if (lcr & CPM_LCR_DOZE_ON) + printf(" duty : %d", (int)((lcr & CPM_LCR_DOZE_DUTY_MASK) >> CPM_LCR_DOZE_DUTY_BIT)); + + printf("IPU : %s", + (clkgr & CPM_CLKGR_IPU) ? "stopped" : "running"); + printf("DMAC : %s", + (clkgr & CPM_CLKGR_DMAC) ? "stopped" : "running"); + printf("UHC : %s", + (clkgr & CPM_CLKGR_UHC) ? "stopped" : "running"); + printf("UDC : %s", + (clkgr & CPM_CLKGR_UDC) ? "stopped" : "running"); + printf("LCD : %s", + (clkgr & CPM_CLKGR_LCD) ? "stopped" : "running"); + printf("CIM : %s", + (clkgr & CPM_CLKGR_CIM) ? "stopped" : "running"); + printf("SADC : %s", + (clkgr & CPM_CLKGR_SADC) ? "stopped" : "running"); + printf("MSC : %s", + (clkgr & CPM_CLKGR_MSC) ? "stopped" : "running"); + printf("AIC1 : %s", + (clkgr & CPM_CLKGR_AIC1) ? "stopped" : "running"); + printf("AIC2 : %s", + (clkgr & CPM_CLKGR_AIC2) ? "stopped" : "running"); + printf("SSI : %s", + (clkgr & CPM_CLKGR_SSI) ? "stopped" : "running"); + printf("I2C : %s", + (clkgr & CPM_CLKGR_I2C) ? "stopped" : "running"); + printf("RTC : %s", + (clkgr & CPM_CLKGR_RTC) ? "stopped" : "running"); + printf("TCU : %s", + (clkgr & CPM_CLKGR_TCU) ? "stopped" : "running"); + printf("UART1 : %s", + (clkgr & CPM_CLKGR_UART1) ? "stopped" : "running"); + printf("UART0 : %s", + (clkgr & CPM_CLKGR_UART0) ? "stopped" : "running"); +} + +bool __dbg_ports(void) +{ + return false; +} + +bool __dbg_hw_info(void) +{ + return false; +} + diff --git a/firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c b/firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c index 1fbf1fc19e..456542064c 100644 --- a/firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c @@ -238,3 +238,7 @@ W_timeout: __i2c_send_stop(); return -1; } + +void i2c_init(void) +{ +} diff --git a/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c b/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c index 317da8413e..071adbd63e 100644 --- a/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c @@ -69,6 +69,7 @@ bool lcd_enabled(void) /* Update a fraction of the display. */ void lcd_update_rect(int x, int y, int width, int height) { +x=0;y=0;width=LCD_WIDTH;height=LCD_HEIGHT; mutex_lock(&lcd_mtx); __cpm_start_lcd(); @@ -135,3 +136,17 @@ void lcd_update(void) lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); } + +void lcd_blit_yuv(unsigned char * const src[3], + int src_x, int src_y, int stride, + int x, int y, int width, int height) +{ + (void)src; + (void)src_x; + (void)src_y; + (void)stride; + (void)x; + (void)y; + (void)width; + (void)height; +} diff --git a/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c b/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c index c97ef13533..1ed36cd312 100644 --- a/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c @@ -142,6 +142,10 @@ void pcm_play_dma_pause(bool pause) play_start_pcm(); } +void audiohw_close(void) +{ +} + #ifdef HAVE_RECORDING /* TODO */ void pcm_rec_dma_init(void) diff --git a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c index 052ea64495..c0f39a4933 100644 --- a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c @@ -397,7 +397,7 @@ void mdelay(unsigned int msec) } /* Core-level interrupt masking */ -void cli(void) +void clear_interrupts(void) { register unsigned int t; t = read_c0_status(); @@ -410,7 +410,7 @@ unsigned int mips_get_sr(void) return read_c0_status(); } -void sti(void) +void store_interrupts(void) { register unsigned int t; t = read_c0_status(); @@ -525,13 +525,6 @@ void tlb_refill_handler(void) panicf("TLB refill handler at 0x%08lx! [0x%x]", read_c0_epc(), read_c0_badvaddr()); } -static void tlb_call_refill(void) -{ - asm("la $8, tlb_refill_handler \n" - "jr $8 \n" - ); -} - static int dma_count = 0; void dma_enable(void) { @@ -559,191 +552,178 @@ void dma_disable(void) } } -static inline void pll_convert(unsigned int pllin, unsigned int *pll_cfcr, unsigned int *pll_plcr1) +/* PLL output clock = EXTAL * NF / (NR * NO) + * + * NF = FD + 2, NR = RD + 2 + * NO = 1 (if OD = 0), NO = 2 (if OD = 1 or 2), NO = 4 (if OD = 3) + */ +static void pll_init(void) ICODE_ATTR; +static void pll_init(void) { register unsigned int cfcr, plcr1; + int n2FR[33] = { + 0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 9 + }; int div[5] = {1, 3, 3, 3, 3}; /* divisors of I:S:P:L:M */ - int nf; + int nf, pllout2; + + cfcr = CPM_CPCCR_CLKOEN | + CPM_CPCCR_PCS | + (n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) | + (n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) | + (n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) | + (n2FR[div[3]] << CPM_CPCCR_MDIV_BIT) | + (n2FR[div[4]] << CPM_CPCCR_LDIV_BIT) | + CPM_CPCCR_CE; /* Perform clock divisions immediately */ - cfcr = CPM_CPCCR_CLKOEN | - (div[0] << CPM_CPCCR_CDIV_BIT) | - (div[1] << CPM_CPCCR_HDIV_BIT) | - (div[2] << CPM_CPCCR_PDIV_BIT) | - (div[3] << CPM_CPCCR_MDIV_BIT) | - (div[4] << CPM_CPCCR_LDIV_BIT); + pllout2 = (cfcr & CPM_CPCCR_PCS) ? CPU_FREQ : (CPU_FREQ / 2); - //nf = pllin * 2 / CFG_EXTAL; - nf = pllin * 2 / 375299969; + /* Init USB Host clock, pllout2 must be n*48MHz */ + REG_CPM_UHCCDR = pllout2 / 48000000 - 1; + + nf = CPU_FREQ * 2 / CFG_EXTAL; plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */ - (0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */ - (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */ - (0xa << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */ - CPM_CPPCR_PLLEN; /* enable PLL */ - + (0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */ + (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */ + (0x20 << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */ + CPM_CPPCR_PLLEN; /* enable PLL */ + /* init PLL */ - *pll_cfcr = cfcr; - *pll_plcr1 = plcr1; + REG_CPM_CPCCR = cfcr; + REG_CPM_CPPCR = plcr1; } -static inline void sdram_convert(unsigned int pllin, unsigned int *sdram_freq) -{ - register unsigned int ns, tmp; - - ns = 1000000000 / pllin; - tmp = 15625 / ns; - - /* Set refresh registers */ +// SDRAM paramters +#define CFG_SDRAM_BW16 0 /* Data bus width: 0-32bit, 1-16bit */ +#define CFG_SDRAM_BANK4 1 /* Banks each chip: 0-2bank, 1-4bank */ +#define CFG_SDRAM_ROW 12 /* Row address: 11 to 13 */ +#define CFG_SDRAM_COL 8 /* Column address: 8 to 12 */ +#define CFG_SDRAM_CASL 2 /* CAS latency: 2 or 3 */ + +// SDRAM Timings, unit: ns +#define CFG_SDRAM_TRAS 45 /* RAS# Active Time */ +#define CFG_SDRAM_RCD 20 /* RAS# to CAS# Delay */ +#define CFG_SDRAM_TPC 20 /* RAS# Precharge Time */ +#define CFG_SDRAM_TRWL 7 /* Write Latency Time */ +#define CFG_SDRAM_TREF 7812 /* Refresh period: 8192 refresh cycles/64ms */ + +/* + * Init SDRAM memory. + */ +static void sdram_init(void) ICODE_ATTR; +static void sdram_init(void) +{ + register unsigned int dmcr0, dmcr, sdmode, tmp, cpu_clk, mem_clk, ns; + + unsigned int cas_latency_sdmr[2] = { + EMC_SDMR_CAS_2, + EMC_SDMR_CAS_3, + }; + + unsigned int cas_latency_dmcr[2] = { + 1 << EMC_DMCR_TCL_BIT, /* CAS latency is 2 */ + 2 << EMC_DMCR_TCL_BIT /* CAS latency is 3 */ + }; + + int div[] = { 1, 2, 3, 4, 6, 8, 12, 16, 24, 32 }; + + cpu_clk = CPU_FREQ; + mem_clk = cpu_clk * div[__cpm_get_cdiv()] / div[__cpm_get_mdiv()]; + + //REG_EMC_BCR = 0; /* Disable bus release */ + REG_EMC_RTCSR = 0; /* Disable clock for counting */ + REG_EMC_RTCOR = 0; + REG_EMC_RTCNT = 0; + + /* Fault DMCR value for mode register setting */ +#define SDRAM_ROW0 11 +#define SDRAM_COL0 8 +#define SDRAM_BANK40 0 + + dmcr0 = ((SDRAM_ROW0 - 11) << EMC_DMCR_RA_BIT) | + ((SDRAM_COL0 - 8) << EMC_DMCR_CA_BIT) | + (SDRAM_BANK40 << EMC_DMCR_BA_BIT) | + (CFG_SDRAM_BW16 << EMC_DMCR_BW_BIT) | + EMC_DMCR_EPIN | cas_latency_dmcr[((CFG_SDRAM_CASL == 3) ? 1 : 0)]; + + /* Basic DMCR value */ + dmcr = ((CFG_SDRAM_ROW - 11) << EMC_DMCR_RA_BIT) | + ((CFG_SDRAM_COL - 8) << EMC_DMCR_CA_BIT) | + (CFG_SDRAM_BANK4 << EMC_DMCR_BA_BIT) | + (CFG_SDRAM_BW16 << EMC_DMCR_BW_BIT) | + EMC_DMCR_EPIN | cas_latency_dmcr[((CFG_SDRAM_CASL == 3) ? 1 : 0)]; + + /* SDRAM timimg */ + ns = 1000000000 / mem_clk; + tmp = CFG_SDRAM_TRAS / ns; + if (tmp < 4) + tmp = 4; + if (tmp > 11) + tmp = 11; + dmcr |= ((tmp - 4) << EMC_DMCR_TRAS_BIT); + tmp = CFG_SDRAM_RCD / ns; + if (tmp > 3) + tmp = 3; + dmcr |= (tmp << EMC_DMCR_RCD_BIT); + tmp = CFG_SDRAM_TPC / ns; + if (tmp > 7) + tmp = 7; + dmcr |= (tmp << EMC_DMCR_TPC_BIT); + tmp = CFG_SDRAM_TRWL / ns; + if (tmp > 3) + tmp = 3; + dmcr |= (tmp << EMC_DMCR_TRWL_BIT); + tmp = (CFG_SDRAM_TRAS + CFG_SDRAM_TPC) / ns; + if (tmp > 14) + tmp = 14; + dmcr |= (((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT); + + /* SDRAM mode value */ + sdmode = EMC_SDMR_BT_SEQ | + EMC_SDMR_OM_NORMAL | + EMC_SDMR_BL_4 | cas_latency_sdmr[((CFG_SDRAM_CASL == 3) ? 1 : 0)]; + + /* Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0 */ + REG_EMC_DMCR = dmcr; + REG8(EMC_SDMR0 | sdmode) = 0; + + /* Wait for precharge, > 200us */ + tmp = (cpu_clk / 1000000) * 1000; + while (tmp--); + + /* Stage 2. Enable auto-refresh */ + REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH; + + tmp = CFG_SDRAM_TREF / ns; tmp = tmp / 64 + 1; - - if(tmp > 0xff) + if (tmp > 0xff) tmp = 0xff; - - *sdram_freq = tmp; -} + REG_EMC_RTCOR = tmp; + REG_EMC_RTCNT = 0; + REG_EMC_RTCSR = EMC_RTCSR_CKS_64; /* Divisor is 64, CKO/64 */ -static inline void set_cpu_freq(unsigned int pllin, unsigned int div) -{ - unsigned int sdram_freq; - unsigned int pll_cfcr, pll_plcr1; - int div_preq[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; - - if(pllin < 25000000 || pllin > 420000000) - panicf("PLL should be >25000000 and <420000000 !"); - - unsigned long t = read_c0_status(); - write_c0_status(t & ~1); - - pll_convert(pllin, &pll_cfcr, &pll_plcr1); + /* Wait for number of auto-refresh cycles */ + tmp = (cpu_clk / 1000000) * 1000; + while (tmp--); - sdram_convert(pllin / div_preq[div], &sdram_freq); - - REG_CPM_CPCCR &= ~CPM_CPCCR_CE; - - REG_CPM_CPCCR = pll_cfcr; - REG_CPM_CPPCR = pll_plcr1; - - REG_EMC_RTCOR = sdram_freq; - REG_EMC_RTCNT = sdram_freq; - - REG_CPM_CPCCR |= CPM_CPCCR_CE; - - detect_clock(); - - write_c0_status(t); -} + /* Stage 3. Mode Register Set */ + REG_EMC_DMCR = dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET; + REG8(EMC_SDMR0 | sdmode) = 0; -static void OF_init_clocks(void) -{ - unsigned long t = read_c0_status(); - write_c0_status(t & ~1); - - unsigned int prog_entry = ((unsigned int)OF_init_clocks >> 5) << 5; - unsigned int i, prog_size = 1024; - - for(i = prog_entry; i < prog_entry + prog_size; i += 32) - __asm__ __volatile__("cache 0x1c, 0x00(%0) \n" - : - : "r" (i) - ); - - /* disable PLL clock */ - REG_CPM_CPPCR &= ~CPM_CPPCR_PLLEN; - REG_CPM_CPCCR |= CPM_CPCCR_CE; - - unsigned long old_clocks = REG_CPM_CLKGR; - /* - REG_CPM_CLKGR = ~( CPM_CLKGR_UART0 | CPM_CLKGR_TCU | - CPM_CLKGR_RTC | CPM_CLKGR_SADC | - CPM_CLKGR_LCD ); - */ - - unsigned long old_scr = REG_CPM_SCR; - REG_CPM_SCR &= ~CPM_SCR_OSC_ENABLE; /* O1SE: 12M oscillator is disabled in Sleep mode */ - - REG_EMC_DMCR |= (EMC_DMCR_RMODE | EMC_DMCR_RFSH); /* self refresh + refresh is performed */ - REG_EMC_DMCR = (REG_EMC_DMCR & ~EMC_DMCR_RMODE) | 1; /* -> RMODE = auto refresh - -> CAS mode = 2 cycles */ - __asm__ __volatile__("wait \n"); - - REG_CPM_CLKGR = old_clocks; - REG_CPM_SCR = old_scr; - - for(i=0; i<90; i++); - - set_cpu_freq(336000000, 1); - - for(i=0; i<60; i++); - - write_c0_status(t); -} + /* Set back to basic DMCR value */ + REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET; -static void my_init_clocks(void) -{ - unsigned long t = read_c0_status(); - write_c0_status(t & ~1); - - unsigned int prog_entry = ((unsigned int)my_init_clocks / 32 - 1) * 32; - unsigned int i, prog_size = 1024; - - for(i = prog_entry; i < prog_entry + prog_size; i += 32) - __asm__ __volatile__("cache 0x1c, 0x00(%0) \n" - : - : "r" (i) - ); - - unsigned int sdram_freq, plcr1, cfcr; - - sdram_convert(336000000/3, &sdram_freq); - - cfcr = CPM_CPCCR_CLKOEN | - (6 << CPM_CPCCR_UDIV_BIT) | - CPM_CPCCR_UCS | - CPM_CPCCR_PCS | - (0 << CPM_CPCCR_CDIV_BIT) | - (1 << CPM_CPCCR_HDIV_BIT) | - (1 << CPM_CPCCR_PDIV_BIT) | - (1 << CPM_CPCCR_MDIV_BIT) | - (1 << CPM_CPCCR_LDIV_BIT); - - plcr1 = (54 << CPM_CPPCR_PLLM_BIT) | /* FD */ - (0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */ - (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */ - (0x20 << CPM_CPPCR_PLLST_BIT)| /* PLL stable time */ - CPM_CPPCR_PLLEN; /* enable PLL */ - - REG_CPM_CPCCR &= ~CPM_CPCCR_CE; - - REG_CPM_CPCCR = cfcr; - REG_CPM_CPPCR = plcr1; - - REG_EMC_RTCOR = sdram_freq; - REG_EMC_RTCNT = sdram_freq; - - REG_CPM_CPCCR |= CPM_CPCCR_CE; - - REG_CPM_LPCDR = (REG_CPM_LPCDR & ~CPM_LPCDR_PIXDIV_MASK) | (11 << CPM_LPCDR_PIXDIV_BIT); - - write_c0_status(t); + /* everything is ok now */ } extern int main(void); -extern void except_common_entry(void); - +void system_main(void) ICODE_ATTR; void system_main(void) { int i; - - /* - * 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_call_refill, 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(); @@ -755,27 +735,22 @@ void system_main(void) tlb_init(); + //pll_init(); + //sdram_init(); + detect_clock(); /* Disable unneeded clocks, clocks are enabled when needed */ __cpm_stop_all(); __cpm_suspend_usbhost(); -#if 0 - my_init_clocks(); - //OF_init_clocks(); - /*__cpm_stop_udc(); - REG_CPM_CPCCR |= CPM_CPCCR_UCS; - REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_UDIV_MASK) | (3 << CPM_CPCCR_UDIV_BIT); - __cpm_start_udc();*/ -#endif - /* Enable interrupts at core level */ - sti(); + store_interrupts(); main(); /* Shouldn't return */ - while(1); + while(1) + core_idle(); } void system_reboot(void) @@ -812,3 +787,13 @@ void power_off(void) while(1); } + +void system_init(void) +{ +} + +int system_memory_guard(int newmode) +{ + (void)newmode; + return 0; +} diff --git a/firmware/target/mips/ingenic_jz47xx/system-target.h b/firmware/target/mips/ingenic_jz47xx/system-target.h index 39782a3222..6b505d6178 100644 --- a/firmware/target/mips/ingenic_jz47xx/system-target.h +++ b/firmware/target/mips/ingenic_jz47xx/system-target.h @@ -87,6 +87,7 @@ static inline void restore_interrupt(int status) #define swap32(x) (((x) & 0xff) << 24 | ((x) & 0xff00) << 8 | ((x) & 0xff0000) >> 8 | ((x) >> 24) & 0xff) #define UNCACHED_ADDRESS(addr) ((unsigned int)(addr) | 0xA0000000) +#define UNCACHED_ADDR(x) UNCACHED_ADDRESS((x)) #define PHYSADDR(x) ((x) & 0x1fffffff) void __dcache_writeback_all(void); @@ -95,8 +96,8 @@ void __icache_invalidate_all(void); void __flush_dcache_line(unsigned long addr); void dma_cache_wback_inv(unsigned long addr, unsigned long size); void system_enable_irq(unsigned int irq); -void sti(void); -void cli(void); +void store_interrupts(void); +void clear_interrupts(void); void udelay(unsigned int usec); void mdelay(unsigned int msec); void power_off(void); -- cgit v1.2.3