diff --git a/apps/plugins/plugin.lds b/apps/plugins/plugin.lds index 0c5c1e87d3..66433c13e9 100644 --- a/apps/plugins/plugin.lds +++ b/apps/plugins/plugin.lds @@ -6,8 +6,12 @@ OUTPUT_FORMAT(elf32-m68k) #elif defined(CPU_ARM) OUTPUT_FORMAT(elf32-littlearm) -#else +#elif defined(CPU_SH) OUTPUT_FORMAT(elf32-sh) +#elif defined(CPU_MIPS) +OUTPUT_FORMAT(elf32-littlemips) +#else +#error Unknown CPU architecture #endif #ifdef DEBUG @@ -99,6 +103,10 @@ OUTPUT_FORMAT(elf32-sh) #endif #define DRAMORIG 0x30000000 +#elif CONFIG_CPU == JZ4732 +#define DRAMORIG 0x80004000 + STUBOFFSET +#define IRAMORIG 0x80000000 +#define IRAMSIZE 0x4000 #else #define DRAMORIG 0x09000000 + STUBOFFSET #endif @@ -182,6 +190,9 @@ SECTIONS /DISCARD/ : { *(.eh_frame) +#ifdef CPU_MIPS + *(.rel.dyn) +#endif } #if defined(IRAMSIZE) && IRAMSIZE != 0 diff --git a/bootloader/ondavx747.c b/bootloader/ondavx747.c index 0bd17e59c9..354cae42ec 100755 --- a/bootloader/ondavx747.c +++ b/bootloader/ondavx747.c @@ -19,135 +19,144 @@ * ****************************************************************************/ -#include -#include -#include #include "config.h" #include "jz4740.h" #include "backlight.h" #include "font.h" #include "lcd.h" -#include "ata.h" #include "usb.h" #include "system.h" #include "button.h" -#include "timefuncs.h" -#include "rtc.h" #include "common.h" -#include "mipsregs.h" #include "storage.h" +#include "disk.h" +#include "string.h" +#include "rockboxlogo.h" -#ifdef ONDA_VX747P - #define ONDA_VX747 -#endif +static void show_splash(int timeout, const char *msg) +{ + reset_screen(); + lcd_putsxy( (LCD_WIDTH - (SYSFONT_WIDTH * strlen(msg))) / 2, + (LCD_HEIGHT - SYSFONT_HEIGHT) / 2, msg); + lcd_update(); + + sleep(timeout); +} + +extern int line; +static void show_logo(void) +{ + lcd_bitmap(rockboxlogo, 0, 0, BMPWIDTH_rockboxlogo, BMPHEIGHT_rockboxlogo); + line += BMPHEIGHT_rockboxlogo/SYSFONT_HEIGHT + 1; +} + +static void usb_mode(void) +{ + int button; + + /* Init backlight */ + backlight_init(); + + /* Init USB */ + usb_init(); + usb_start_monitoring(); + + /* Wait for threads to connect */ + show_splash(HZ/2, "Waiting for USB"); + + while (1) + { + button = button_get_w_tmo(HZ/2); + + if (button == SYS_USB_CONNECTED) + break; /* Hit */ + } + + if (button == SYS_USB_CONNECTED) + { + /* Got the message - wait for disconnect */ + show_splash(0, "Bootloader USB mode"); + + usb_acknowledge(SYS_USB_CONNECTED_ACK); + + while (1) + { + button = button_get(true); + if (button == SYS_USB_DISCONNECTED) + { + usb_acknowledge(SYS_USB_DISCONNECTED_ACK); + break; + } + } + } + + reset_screen(); +} + +static void boot_of(void) +{ + /* Init backlight */ + backlight_init(); +} int main(void) { + int rc; + void (*kernel_entry)(void); + kernel_init(); lcd_init(); font_init(); lcd_setfont(FONT_SYSFIXED); button_init(); - rtc_init(); - usb_init(); - - backlight_init(); - -#if 0 /* Enable this when multi storage works */ storage_init(); -#else - ata_init(); -#endif - usb_start_monitoring(); - - int touch, btn; - char datetime[30]; reset_screen(); - printf("Rockbox bootloader v0.0001"); - printf("REG_EMC_SACR0: 0x%x", REG_EMC_SACR0); - printf("REG_EMC_SACR1: 0x%x", REG_EMC_SACR1); - printf("REG_EMC_SACR2: 0x%x", REG_EMC_SACR2); - printf("REG_EMC_SACR3: 0x%x", REG_EMC_SACR3); - printf("REG_EMC_SACR4: 0x%x", REG_EMC_SACR4); - printf("REG_EMC_DMAR0: 0x%x", REG_EMC_DMAR0); - unsigned int cpu_id = read_c0_prid(); - printf("CPU_ID: 0x%x", cpu_id); - printf(" * Company ID: 0x%x", (cpu_id >> 16) & 7); - printf(" * Processor ID: 0x%x", (cpu_id >> 8) & 7); - printf(" * Revision ID: 0x%x", cpu_id & 7); - unsigned int config_data = read_c0_config(); - printf("C0_CONFIG: 0x%x", config_data); - printf(" * Architecture type: 0x%x", (config_data >> 13) & 3); - printf(" * Architecture revision: 0x%x", (config_data >> 10) & 7); - printf(" * MMU type: 0x%x", (config_data >> 7) & 7); - printf("C0_CONFIG1: 0x%x", read_c0_config1()); - if(read_c0_config1() & (1 << 0)) printf(" * FP available"); - if(read_c0_config1() & (1 << 1)) printf(" * EJTAG available"); - if(read_c0_config1() & (1 << 2)) printf(" * MIPS-16 available"); - if(read_c0_config1() & (1 << 4)) printf(" * Performace counters available"); - if(read_c0_config1() & (1 << 5)) printf(" * MDMX available"); - if(read_c0_config1() & (1 << 6)) printf(" * CP2 available"); - printf("C0_STATUS: 0x%x", read_c0_status()); - lcd_puts_scroll(0, 25, "This is a very very long scrolling line.... VERY LONG VERY LONG VERY LONG VERY LONG VERY LONG VERY LONG!!!!!"); - - while(1) - { -#ifdef ONDA_VX747 -#if 1 - btn = button_get(false); - touch = button_get_data(); -#else /* button_get() has performance issues */ - btn = button_read_device(&touch); -#endif +#ifdef HAVE_TOUCHSCREEN + rc = button_read_device(NULL); #else - btn = button_read_device(); -#endif /* ONDA_VX747 */ -#define KNOP(x,y) lcd_set_foreground(LCD_BLACK); \ - if(btn & x) \ - lcd_set_foreground(LCD_WHITE); \ - lcd_putsxy(LCD_WIDTH-SYSFONT_WIDTH*strlen(#x), SYSFONT_HEIGHT*y, #x); - KNOP(BUTTON_VOL_UP, 0); - KNOP(BUTTON_VOL_DOWN, 1); - KNOP(BUTTON_MENU, 2); - KNOP(BUTTON_POWER, 3); - lcd_set_foreground(LCD_WHITE); - if(button_hold()) - printf("BUTTON_HOLD"); - if(btn & BUTTON_POWER) - power_off(); -#ifdef ONDA_VX747 - if(btn & BUTTON_TOUCH) - { - lcd_set_foreground(LCD_RGBPACK(touch & 0xFF, (touch >> 8)&0xFF, (touch >> 16)&0xFF)); - lcd_fillrect((touch>>16)-5, (touch&0xFFFF)-5, 5, 5); - lcd_update(); - lcd_set_foreground(LCD_WHITE); - } + rc = button_read_device(); #endif - snprintf(datetime, 30, "%02d/%02d/%04d %02d:%02d:%02d", get_time()->tm_mday, get_time()->tm_mon, get_time()->tm_year, - get_time()->tm_hour, get_time()->tm_min, get_time()->tm_sec); - lcd_putsxy(LCD_WIDTH-SYSFONT_WIDTH*strlen(datetime), LCD_HEIGHT-SYSFONT_HEIGHT, datetime); - snprintf(datetime, 30, "%d", current_tick); - lcd_putsxy(LCD_WIDTH-SYSFONT_WIDTH*strlen(datetime), LCD_HEIGHT-SYSFONT_HEIGHT*2, datetime); - snprintf(datetime, 30, "X: %03d Y: %03d", touch>>16, touch & 0xFFFF); - lcd_putsxy(LCD_WIDTH-SYSFONT_WIDTH*strlen(datetime), LCD_HEIGHT-SYSFONT_HEIGHT*3, datetime); - snprintf(datetime, 30, "PIN3: 0x%08x", REG_GPIO_PXPIN(3)); - lcd_putsxy(LCD_WIDTH-SYSFONT_WIDTH*strlen(datetime), LCD_HEIGHT-SYSFONT_HEIGHT*4, datetime); - snprintf(datetime, 30, "PIN2: 0x%08x", REG_GPIO_PXPIN(2)); - lcd_putsxy(LCD_WIDTH-SYSFONT_WIDTH*strlen(datetime), LCD_HEIGHT-SYSFONT_HEIGHT*5, datetime); - snprintf(datetime, 30, "PIN1: 0x%08x", REG_GPIO_PXPIN(1)); - lcd_putsxy(LCD_WIDTH-SYSFONT_WIDTH*strlen(datetime), LCD_HEIGHT-SYSFONT_HEIGHT*6, datetime); - snprintf(datetime, 30, "PIN0: 0x%08x", REG_GPIO_PXPIN(0)); - lcd_putsxy(LCD_WIDTH-SYSFONT_WIDTH*strlen(datetime), LCD_HEIGHT-SYSFONT_HEIGHT*7, datetime); - snprintf(datetime, 30, "BadVAddr: 0x%08x", read_c0_badvaddr()); - lcd_putsxy(LCD_WIDTH-SYSFONT_WIDTH*strlen(datetime), LCD_HEIGHT-SYSFONT_HEIGHT*8, datetime); - snprintf(datetime, 30, "ICSR: 0x%08x", REG_INTC_ISR); - lcd_putsxy(LCD_WIDTH-SYSFONT_WIDTH*strlen(datetime), LCD_HEIGHT-SYSFONT_HEIGHT*9, datetime); - lcd_update(); - yield(); + + if(rc & BUTTON_VOL_UP) + usb_mode(); + else if(button_hold()) + boot_of(); + else if(rc) + verbose = true; + + if(verbose) + backlight_init(); + + show_logo(); + printf(MODEL_NAME" Rockbox Bootloader"); + printf("Version "APPSVERSION); + + rc = storage_init(); + if(rc) + error(EATA, rc); + + rc = disk_mount_all(); + if (rc <= 0) + error(EDISK,rc); + + printf("Loading firmware"); + rc = load_firmware((unsigned char *)CONFIG_SDRAM_START, BOOTFILE, 0x400000); + if(rc < 0) + printf("Error: %s", strerror(rc)); + + if (rc == EOK) + { + printf("Starting Rockbox..."); + disable_interrupt(); + kernel_entry = (void*) CONFIG_SDRAM_START; + kernel_entry(); } + /* Halt */ + while (1) + core_idle(); + return 0; } diff --git a/firmware/SOURCES b/firmware/SOURCES index 0073b41f9f..a9a0b17632 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -1215,10 +1215,10 @@ drivers/qt1106.c #endif /* MEIZU_M3 */ #if CONFIG_CPU==JZ4732 -target/mips/ingenic_jz47xx/ata-jz4740.c target/mips/ingenic_jz47xx/ata-nand-jz4740.c target/mips/ingenic_jz47xx/ata-sd-jz4740.c target/mips/ingenic_jz47xx/codec-jz4740.c +target/mips/ingenic_jz47xx/debug-jz4740.c target/mips/ingenic_jz47xx/kernel-jz4740.c target/mips/ingenic_jz47xx/i2c-jz4740.c target/mips/ingenic_jz47xx/lcd-jz4740.c diff --git a/firmware/drivers/rtc/rtc_jz4740.c b/firmware/drivers/rtc/rtc_jz4740.c index 4bc5d5e5cc..77e0860cd2 100644 --- a/firmware/drivers/rtc/rtc_jz4740.c +++ b/firmware/drivers/rtc/rtc_jz4740.c @@ -154,6 +154,11 @@ int rtc_read_datetime(unsigned char* buf) return 1; } +int rtc_write_datetime(unsigned char* buf) +{ + (void)buf; +} + #if 0 void get_rtc_alm_time(struct rtc_time *alm_tm) { diff --git a/firmware/export/config-ondavx747.h b/firmware/export/config-ondavx747.h index 3646156ede..a7df97068c 100644 --- a/firmware/export/config-ondavx747.h +++ b/firmware/export/config-ondavx747.h @@ -31,13 +31,13 @@ #define MODEL_NAME "Onda VX747" /* For Rolo and boot loader */ -#define MODEL_NUMBER 35 +#define MODEL_NUMBER 45 //#define HAVE_ATA_SD //#define HAVE_HOTSWAP //#define CONFIG_STORAGE (STORAGE_NAND | STORAGE_SD) -#define CONFIG_STORAGE STORAGE_NAND /* Multivolume currently handled at firmware/target/ level */ +#define CONFIG_STORAGE STORAGE_SD /* Multivolume currently handled at firmware/target/ level */ #define CONFIG_NAND NAND_CC @@ -115,10 +115,10 @@ SAMPR_CAP_11)*/ #define BATTERY_CAPACITY_DEFAULT 1250 /* default battery capacity */ -#define BATTERY_CAPACITY_MIN 500 /* min. capacity selectable */ -#define BATTERY_CAPACITY_MAX 2500 /* max. capacity selectable */ -#define BATTERY_CAPACITY_INC 100 /* capacity increment */ -#define BATTERY_TYPES_COUNT 1 /* only one type */ +#define BATTERY_CAPACITY_MIN 500 /* min. capacity selectable */ +#define BATTERY_CAPACITY_MAX 2500 /* max. capacity selectable */ +#define BATTERY_CAPACITY_INC 100 /* capacity increment */ +#define BATTERY_TYPES_COUNT 1 /* only one type */ /* Hardware controlled charging with monitoring */ #define CONFIG_CHARGING CHARGING_MONITOR @@ -132,7 +132,8 @@ #define HAVE_POWEROFF_WHILE_CHARGING /* Define this to the CPU frequency */ -#define CPU_FREQ 3686400 +#define CPU_FREQ 336000000 /* CPU clock: 336 MHz */ +#define CFG_EXTAL 12000000 /* EXT clock: 12 Mhz */ /* define this if you have a flash memory storage */ #define HAVE_FLASH_STORAGE @@ -151,6 +152,7 @@ /* Define this if you have adjustable CPU frequency */ /* #define HAVE_ADJUSTABLE_CPU_FREQ */ +#define CPUFREQ_NORMAL 336000000 /* CPU clock: 336 MHz */ #define BOOTFILE_EXT "vx747" #define BOOTFILE "rockbox." BOOTFILE_EXT diff --git a/firmware/export/config-ondavx747p.h b/firmware/export/config-ondavx747p.h index 2cd06d3323..bb16a6a53f 100644 --- a/firmware/export/config-ondavx747p.h +++ b/firmware/export/config-ondavx747p.h @@ -132,7 +132,8 @@ #define HAVE_POWEROFF_WHILE_CHARGING /* Define this to the CPU frequency */ -#define CPU_FREQ 3686400 +#define CPU_FREQ 336000000 /* CPU clock: 336 MHz */ +#define CFG_EXTAL 12000000 /* EXT clock: 12 Mhz */ /* define this if you have a flash memory storage */ #define HAVE_FLASH_STORAGE diff --git a/firmware/export/config-ondavx767.h b/firmware/export/config-ondavx767.h index cb44de9e6e..1f481432f2 100644 --- a/firmware/export/config-ondavx767.h +++ b/firmware/export/config-ondavx767.h @@ -130,7 +130,8 @@ #define HAVE_POWEROFF_WHILE_CHARGING /* Define this to the CPU frequency */ -#define CPU_FREQ 3686400 +#define CPU_FREQ 336000000 /* CPU clock: 336 MHz */ +#define CFG_EXTAL 12000000 /* EXT clock: 12 Mhz */ /* define this if you have a flash memory storage */ #define HAVE_FLASH_STORAGE diff --git a/firmware/export/jz4740.h b/firmware/export/jz4740.h index 8f308fdb8f..5642dc8464 100644 --- a/firmware/export/jz4740.h +++ b/firmware/export/jz4740.h @@ -3365,15 +3365,13 @@ do { \ #define __cpm_suspend_usbhost() (REG_CPM_SCR |= CPM_SCR_USBHOST_SUSPEND) #define __cpm_enable_osc_in_sleep() (REG_CPM_SCR |= CPM_SCR_OSC_ENABLE) - -#define CFG_EXTAL (12000000) - #ifdef CFG_EXTAL #define JZ_EXTAL CFG_EXTAL #else -#define JZ_EXTAL (3686400) +#define JZ_EXTAL 3686400 +#warning Default EXTCLK is used! #endif -#define JZ_EXTAL2 (32768) /* RTC clock */ +#define JZ_EXTAL2 32768 /* RTC clock */ /* PLL output frequency */ static __inline__ unsigned int __cpm_get_pllout(void) @@ -3487,7 +3485,7 @@ static __inline__ unsigned int __cpm_get_rtcclk(void) /* * Output 24MHz for SD and 16MHz for MMC. */ -static inline void __cpm_select_msc_clk(int sd) +static __inline__ void __cpm_select_msc_clk(int sd) { unsigned int pllout2 = __cpm_get_pllout2(); unsigned int div = 0; @@ -3503,7 +3501,7 @@ static inline void __cpm_select_msc_clk(int sd) /* * Output 48MHz for SD and 16MHz for MMC. */ -static inline void __cpm_select_msc_hs_clk(int sd) +static __inline__ void __cpm_select_msc_hs_clk(int sd) { unsigned int pllout2 = __cpm_get_pllout2(); unsigned int div = 0; diff --git a/firmware/export/mipsregs.h b/firmware/export/mipsregs.h index 8898bbd478..0ae9bce4d7 100644 --- a/firmware/export/mipsregs.h +++ b/firmware/export/mipsregs.h @@ -13,29 +13,6 @@ #ifndef _ASM_MIPSREGS_H #define _ASM_MIPSREGS_H -//#include -//#include - -/* - * The following macros are especially useful for __asm__ - * inline assembler. - */ -#ifndef __STR -#define __STR(x) #x -#endif -#ifndef STR -#define STR(x) __STR(x) -#endif - -/* - * Configure language - */ -#ifdef __ASSEMBLY__ -#define _ULCAST_ -#else -#define _ULCAST_ (unsigned long) -#endif - /* * Coprocessor 0 register names */ 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 - - .data : - { - *(.icode); - *(.irodata); - *(.idata); - *(.data*); - *(.sdata*); - . = ALIGN(0x4); - _dataend = . ; - } > DRAM - - _gp = ALIGN(16); - .got : - { - *(.got*) } > DRAM . = ALIGN(4); - .bss : + .data : + { + *(.data*); + *(.sdata*); + *(.rel.dyn); + } > DRAM + + . = ALIGN(4); + + .iram IRAMORIG: + { + _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 (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 - nop - nop - .fill 0x20 - .extern _int - .extern _exception - .global real_exception_handler - .type real_exception_handler,@function - .set noreorder + .section .vectors.3, "ax", %progbits + la k0, real_exception_handler + jr k0 + nop + + .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 | - (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); + 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 */ - //nf = pllin * 2 / CFG_EXTAL; - nf = pllin * 2 / 375299969; + pllout2 = (cfcr & CPM_CPCCR_PCS) ? CPU_FREQ : (CPU_FREQ / 2); + + /* 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; -} - -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 */ - tmp = tmp / 64 + 1; - - if(tmp > 0xff) - tmp = 0xff; - - *sdram_freq = tmp; -} - -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); - - 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); -} - -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); -} - -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); +} + +// 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) + tmp = 0xff; + REG_EMC_RTCOR = tmp; + REG_EMC_RTCNT = 0; + REG_EMC_RTCSR = EMC_RTCSR_CKS_64; /* Divisor is 64, CKO/64 */ + + /* Wait for number of auto-refresh cycles */ + tmp = (cpu_clk / 1000000) * 1000; + while (tmp--); + + /* Stage 3. Mode Register Set */ + REG_EMC_DMCR = dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET; + REG8(EMC_SDMR0 | sdmode) = 0; + + /* Set back to basic DMCR value */ + REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET; + + /* 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); diff --git a/tools/configure b/tools/configure index 9ea5f9f739..d92fab8118 100755 --- a/tools/configure +++ b/tools/configure @@ -298,7 +298,7 @@ arm1136jfscc () { mipselcc () { prefixtools mipsel-elf- - GCCOPTS="$CCOPTS -march=mips32 -mno-mips16 -mno-abicalls -mlong-calls" + GCCOPTS="$CCOPTS -march=mips32 -mtune=r4600 -mno-mips16 -mno-abicalls -mlong-calls" GCCOPTIMIZE="-fomit-frame-pointer" GCCOPTS="$GCCOPTS -fno-pic -fno-builtin -fno-exceptions -ffunction-sections -msoft-float -G 0" endian="little" @@ -1933,14 +1933,14 @@ fi target_id=44 modelname="ondavx747" target="-DONDA_VX747" - memory=16 #FIXME + memory=16 mipselcc - tool="cp" + tool="$rootdir/tools/scramble -add=x747" bmp2rb_mono="$rootdir/tools/bmp2rb -f 0" bmp2rb_native="$rootdir/tools/bmp2rb -f 4" output="rockbox.vx747" appextra="recorder:gui" - plugins="no" #FIXME + plugins="" #FIXME swcodec="yes" toolset=$genericbitmaptools boottool="cp" @@ -1962,7 +1962,7 @@ fi bmp2rb_native="$rootdir/tools/bmp2rb -f 4" output="rockbox.vx767" appextra="recorder:gui" - plugins="no" #FIXME + plugins="" #FIXME swcodec="yes" toolset=$genericbitmaptools boottool="cp" @@ -1984,7 +1984,7 @@ fi bmp2rb_native="$rootdir/tools/bmp2rb -f 4" output="rockbox.vx747p" appextra="recorder:gui" - plugins="no" #FIXME + plugins="" #FIXME swcodec="yes" toolset=$genericbitmaptools boottool="cp" diff --git a/tools/scramble.c b/tools/scramble.c index 9fea89ce30..0efb8e2631 100644 --- a/tools/scramble.c +++ b/tools/scramble.c @@ -295,6 +295,8 @@ int main (int argc, char** argv) modelnum = 43; else if (!strcmp(&argv[1][5], "c2v2")) modelnum = 44; + else if (!strcmp(&argv[1][5], "x747")) + modelnum = 45; else { fprintf(stderr, "unsupported model: %s\n", &argv[1][5]); return 2;